Support multipart HTML5 forms
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-17 12:41:50 +03:00
parent 940d7e884b
commit 2e6fee5fc7
4 changed files with 40 additions and 0 deletions
+1
View File
@@ -28,6 +28,7 @@ dependencies = [
"sfera-ui-semantics",
"smbprotocol>=1.15",
"uvicorn>=0.30",
"python-multipart>=0.0.20",
]
[tool.uv]
@@ -6,6 +6,14 @@ from fastapi import Request
async def html5_form_data(request: Request) -> dict[str, list[str]]:
content_type = request.headers.get("content-type", "")
if content_type.startswith("multipart/form-data"):
parsed = await request.form()
form: dict[str, list[str]] = {}
for key, value in parsed.multi_items():
text = getattr(value, "filename", None) if not isinstance(value, str) else value
form.setdefault(key, []).append(str(text or ""))
return form
body = (await request.body()).decode("utf-8")
return parse_qs(body, keep_blank_values=True)
+20
View File
@@ -484,6 +484,26 @@ def test_html5_project_index_creates_project_with_fragment():
assert deleted_setup.json()["status"] == "NOT_CONFIGURED"
def test_html5_project_create_accepts_multipart_browser_form():
client = TestClient(app)
project_id = f"html5-multipart-{uuid4()}"
created = client.post(
"/html5/projects",
files={
"project_id": (None, project_id),
"name": (None, "HTML5 Multipart"),
},
)
assert created.status_code == 200
assert_html5_response_contract(created, project_id, "HTML5 Multipart")
setup = client.get(f"/html5/projects/{project_id}/setup")
assert setup.status_code == 200
assert_html5_response_contract(setup, "data-html5-page=\"setup\"", "HTML5 Multipart", full_page=True)
def test_html5_object_context_fragment(tmp_path: Path):
project_id = f"html5-object-context-{uuid4()}"
(tmp_path / "metadata.xml").write_text(