Skip to content

operations

fix_api_docs(app=None)

Fix error loading /docs when a root_path is set.

Call after declaring an app with a root_path set, for example: app = FastAPI(root_path="/some/path") fix_api_docs(app)

When a root_path is declared, the default /docs URL breaks, and returns an error: Fetch error Not Found /api/v1/openapi.json

Source code in src/red_utils/ext/fastapi_utils/operations.py
def fix_api_docs(app: FastAPI = None):
    """Fix error loading /docs when a root_path is set.

    Call after declaring an app with a root_path set, for example:
        app = FastAPI(root_path="/some/path")
        fix_api_docs(app)

    When a root_path is declared, the default /docs URL breaks, and returns
    an error:
        Fetch error
        Not Found /api/v1/openapi.json
    """
    if not app:
        raise ValueError("Missing a FastAPI app with a root_path var declared")

    if not isinstance(app, FastAPI):
        raise TypeError(
            f"Invalid type for FastAPI app: ({type(app)}). Value must be of type FastAPI."
        )

    @app.get(app.root_path + "/openapi.json", include_in_schema=False)
    def custom_swagger_ui_html():
        return app.openapi()

get_app(debug=False, cors=True, root_path='/', title='DEFAULT_TITLE', description='DEFAULT_DESCRIPTION', version='0.0.0', openapi_url=default_openapi_url, openapi_tags=tags_metadata, routers=None)

Generate a FastAPI app and return.

Source code in src/red_utils/ext/fastapi_utils/operations.py
def get_app(
    debug: bool = False,
    cors: bool = True,
    root_path: str = "/",
    title: str = "DEFAULT_TITLE",
    description: str = "DEFAULT_DESCRIPTION",
    version: str = "0.0.0",
    openapi_url: str = default_openapi_url,
    openapi_tags: list = tags_metadata,
    routers: list[APIRouter] = None,
) -> FastAPI:
    """Generate a FastAPI app and return."""
    for _var in [root_path, title, description, version, openapi_url]:
        is_str(input=_var)

    validate_openapi_tags(openapi_tags)

    if routers:
        for r in routers:
            validate_router(r, none_ok=True)

    try:
        app: FastAPI = FastAPI(
            root_path=root_path,
            title=title,
            description=description,
            version=version,
            openapi_url=openapi_url,
            openapi_tags=openapi_tags,
            debug=debug,
        )

        if cors:
            add_cors_middleware(app=app)

        if routers:
            for router in routers:
                app.include_router(router)

    except Exception as exc:
        raise Exception(f"Unhandled exception creating FastAPI App. Details: {exc}")

    return app

update_tags_metadata(tags_metadata=tags_metadata, update_metadata=None)

Update the global tags_metadata list with new values.

Import this function in another app, create a new list of tags (or a single tag dict, {"name": ..., "description": ...}), then pass both the imported tags_metadata and the new list/single instance of tag objects.

This funciton will combine them into a new tags_metadata object

Source code in src/red_utils/ext/fastapi_utils/operations.py
def update_tags_metadata(
    tags_metadata: list = tags_metadata,
    update_metadata: Union[list[dict[str, str]], dict[str, str]] = None,
):
    """Update the global tags_metadata list with new values.

    Import this function in another app, create a new list of tags (or
    a single tag dict, {"name": ..., "description": ...}), then pass both
    the imported tags_metadata and the new list/single instance of tag objects.

    This funciton will combine them into a new tags_metadata object
    """
    if not tags_metadata:
        raise ValueError("Missing value for tags_metadata")

    if not update_metadata:
        raise ValueError("Missing value for update_metadata")

    if isinstance(update_metadata, list):
        ## List of dicts was passed

        # print(f"[DEBUG] Detected list of new tags: {update_metadata}")

        tags_metadata = tags_metadata + update_metadata

        return_obj = tags_metadata

    elif isinstance(update_metadata, dict):
        ## Single tag dict was passed

        # print(f"[DEBUG] Detected single dict for new tag: {update_metadata}")

        tags_metadata.append(update_metadata)

        return_obj = tags_metadata

    else:
        raise ValueError(
            "Type of update_metadata must be one of list[dict[str,str]] or dict[str,str]"
        )

    return return_obj