Skip to content

Instantly share code, notes, and snippets.

@SF-300
Last active February 15, 2023 11:45
Show Gist options
  • Save SF-300/7877b73e32e285f3ceae57b93aa2b734 to your computer and use it in GitHub Desktop.
Save SF-300/7877b73e32e285f3ceae57b93aa2b734 to your computer and use it in GitHub Desktop.
Mounting ASGI subapps through FastAPI's router
import unittest.mock
from fastapi import FastAPI as _FastAPI, APIRouter as _APIRouter, routing
__all__ = "FastAPI", "APIRouter"
class APIRouter(_APIRouter):
def include_router(self, router, **kwargs) -> None:
prefix = kwargs.get("prefix", "")
super().include_router(router, **kwargs)
# NOTE(zeronineseven): FastAPI does not handle ASGI subapps mounted to routers - they get simply ignored when
# downstream router's routes get copied into the upstream. So this is a simple hack to
# actually copy them too.
for mount in (r for r in router.routes if isinstance(r, routing.Mount)):
self.mount(prefix + mount.path, mount.app, mount.name)
class FastAPI(_FastAPI):
def __init__(self, *args, **kwargs):
called = False
def create_router(*args_, **kwargs_):
nonlocal called
called = True
return APIRouter(*args_, **kwargs_)
with unittest.mock.patch("fastapi.routing.APIRouter", create_router):
super().__init__(*args, **kwargs)
if not called:
raise AssertionError("Patching failed! Seems like something has changed in recent FastAPI versions...")
@SF-300
Copy link
Author

SF-300 commented Jan 9, 2023

A (rather hack-ish) workaround for this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment