Spaces:
Runtime error
Runtime error
| """Collection of utilities for FastAPI apps.""" | |
| import inspect | |
| from typing import Any, Type | |
| from fastapi import FastAPI, Form | |
| from pydantic import BaseModel | |
| def as_form(cls: Type[BaseModel]) -> Any: | |
| """Adds an as_form class method to decorated models. | |
| The as_form class method can be used with FastAPI endpoints | |
| """ | |
| new_params = [ | |
| inspect.Parameter( | |
| field.alias, | |
| inspect.Parameter.POSITIONAL_ONLY, | |
| default=(Form(field.default) if not field.required else Form(...)), | |
| ) | |
| for field in cls.__fields__.values() | |
| ] | |
| async def _as_form(**data): # type: ignore | |
| return cls(**data) | |
| sig = inspect.signature(_as_form) | |
| sig = sig.replace(parameters=new_params) | |
| _as_form.__signature__ = sig # type: ignore | |
| setattr(cls, "as_form", _as_form) | |
| return cls | |
| def patch_fastapi(app: FastAPI) -> None: | |
| """Patch function to allow relative url resolution. | |
| This patch is required to make fastapi fully functional with a relative url path. | |
| This code snippet can be copy-pasted to any Fastapi application. | |
| """ | |
| from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html | |
| from starlette.requests import Request | |
| from starlette.responses import HTMLResponse | |
| async def redoc_ui_html(req: Request) -> HTMLResponse: | |
| assert app.openapi_url is not None | |
| redoc_ui = get_redoc_html( | |
| openapi_url="./" + app.openapi_url.lstrip("/"), | |
| title=app.title + " - Redoc UI", | |
| ) | |
| return HTMLResponse(redoc_ui.body.decode("utf-8")) | |
| async def swagger_ui_html(req: Request) -> HTMLResponse: | |
| assert app.openapi_url is not None | |
| swagger_ui = get_swagger_ui_html( | |
| openapi_url="./" + app.openapi_url.lstrip("/"), | |
| title=app.title + " - Swagger UI", | |
| oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url, | |
| ) | |
| # insert request interceptor to have all request run on relativ path | |
| request_interceptor = ( | |
| "requestInterceptor: (e) => {" | |
| "\n\t\t\tvar url = window.location.origin + window.location.pathname" | |
| '\n\t\t\turl = url.substring( 0, url.lastIndexOf( "/" ) + 1);' | |
| "\n\t\t\turl = e.url.replace(/http(s)?:\/\/[^/]*\//i, url);" # noqa: W605 | |
| "\n\t\t\te.contextUrl = url" | |
| "\n\t\t\te.url = url" | |
| "\n\t\t\treturn e;}" | |
| ) | |
| return HTMLResponse( | |
| swagger_ui.body.decode("utf-8").replace( | |
| "dom_id: '#swagger-ui',", | |
| "dom_id: '#swagger-ui',\n\t\t" + request_interceptor + ",", | |
| ) | |
| ) | |
| # remove old docs route and add our patched route | |
| routes_new = [] | |
| for app_route in app.routes: | |
| if app_route.path == "/docs": # type: ignore | |
| continue | |
| if app_route.path == "/redoc": # type: ignore | |
| continue | |
| routes_new.append(app_route) | |
| app.router.routes = routes_new | |
| assert app.docs_url is not None | |
| app.add_route(app.docs_url, swagger_ui_html, include_in_schema=False) | |
| assert app.redoc_url is not None | |
| app.add_route(app.redoc_url, redoc_ui_html, include_in_schema=False) | |
| # Make graphql realtive | |
| from starlette import graphql | |
| graphql.GRAPHIQL = graphql.GRAPHIQL.replace( | |
| "({{REQUEST_PATH}}", '("." + {{REQUEST_PATH}}' | |
| ) | |