from __future__ import annotations from urllib.parse import parse_qs 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) def form_value(form: dict[str, list[str]], key: str) -> str | None: values = form.get(key) if not values: return None value = values[0].strip() return value or None def html5_metadata_payload(form: dict[str, list[str]]) -> dict: return { "object_kind": form_value(form, "object_kind") or "DOCUMENT", "name": form_value(form, "name") or "", "synonym": form_value(form, "synonym"), "attributes": html5_metadata_attributes(form_value(form, "attributes") or ""), "tabular_sections": html5_metadata_tabular_sections(form_value(form, "tabular_sections") or ""), "forms": html5_csv_values(form_value(form, "forms") or ""), "commands": html5_metadata_commands(form_value(form, "commands") or ""), "task_id": form_value(form, "task_id"), "session_id": form_value(form, "session_id"), "user_id": form_value(form, "user_id"), "_raw_attributes": form_value(form, "attributes") or "", "_raw_tabular_sections": form_value(form, "tabular_sections") or "", "_raw_forms": form_value(form, "forms") or "", "_raw_commands": form_value(form, "commands") or "", } def html5_metadata_request_payload(payload: dict) -> dict: return {key: value for key, value in payload.items() if not key.startswith("_raw_")} def html5_csv_values(raw: str) -> list[str]: return [item.strip() for item in raw.replace("\n", ",").split(",") if item.strip()] def html5_metadata_attributes(raw: str) -> list[dict]: attributes: list[dict] = [] for item in html5_csv_values(raw): name, _, type_name = item.partition(":") if name.strip(): attributes.append({"name": name.strip(), "type": type_name.strip() or "Строка"}) return attributes def html5_metadata_commands(raw: str) -> list[dict]: commands: list[dict] = [] for item in html5_csv_values(raw): name, _, handler = item.partition(":") if name.strip(): commands.append({"name": name.strip(), "handler": handler.strip() or None}) return commands def html5_metadata_tabular_sections(raw: str) -> list[dict]: sections: list[dict] = [] for item in html5_csv_values(raw): name, _, attrs = item.partition("[") if not name.strip(): continue attributes = [] for attr in attrs.rstrip("]").split(";"): attr_name, _, attr_type = attr.partition(":") if attr_name.strip(): attributes.append({"name": attr_name.strip(), "type": attr_type.strip() or "Строка"}) sections.append({"name": name.strip(), "attributes": attributes}) return sections