test: backend

This commit is contained in:
tao.chen
2026-08-11 20:09:44 +08:00
parent a8a54f1b78
commit e1360c5c38
+13 -5
View File
@@ -25,11 +25,16 @@ def extract_notebook_path(
) -> Optional[str]: ) -> Optional[str]:
"""Pull the relative notebook path out of the original request URI. """Pull the relative notebook path out of the original request URI.
Only ``/jupyter/{workspace_id}/notebooks/*.ipynb`` requests are Match ``/jupyter/{workspace_id}/notebooks/*.ipynb`` (the legacy
subject to file-level lock checks; everything else (tree views, iframe flow) and ``/jupyter/{workspace_id}/api/contents/*.ipynb``
``/api/contents`` and WebSocket upgrades) bypasses the lock. (the Monaco-based Contents API PUT path). The caller decides
whether to actually enforce the lock — typically only on writes.
""" """
pattern = rf"^/jupyter/{re.escape(workspace_id)}/notebooks/(.+\.ipynb)" nb_pattern = rf"^/jupyter/{re.escape(workspace_id)}/notebooks/(.+\.ipynb)"
contents_pattern = (
rf"^/jupyter/{re.escape(workspace_id)}/api/contents/(.+\.ipynb)"
)
for pattern in (nb_pattern, contents_pattern):
match = re.match(pattern, uri) match = re.match(pattern, uri)
if match: if match:
return match.group(1) return match.group(1)
@@ -126,7 +131,10 @@ async def verify_jupyter_access(
await load_active_membership_or_403(session, user_id, workspace_id) await load_active_membership_or_403(session, user_id, workspace_id)
notebook_path = extract_notebook_path(original_uri, workspace_id) notebook_path = extract_notebook_path(original_uri, workspace_id)
if notebook_path and await check_notebook_is_locked( # Lock only on writes — reads (GET) stay open so anyone can still
# preview a locked notebook the way they could via the iframe before.
if notebook_path and request.method in {"PUT", "POST", "PATCH", "DELETE"}:
if await check_notebook_is_locked(
session, workspace_id, notebook_path, user_id, session, workspace_id, notebook_path, user_id,
): ):
raise HTTPException( raise HTTPException(