import importlib import pkgutil from pathlib import Path from types import ModuleType from fastapi import FastAPI, APIRouter def auto_include_routers(app: FastAPI, package: ModuleType, full_path: bool = False): """ Automatically discover and include FastAPI routers from a given package. :param FastAPI app: FastAPI application. :param ModuleType package: Imported package. :param bool full_path: If True, prefix is built from full path. If False, prefix is only the last filename. """ package_path = Path(package.__file__).parent base_pkg_name = package.__name__.replace("_", "-") for _, name, _ in pkgutil.walk_packages(package.__path__, package.__name__ + "."): module = importlib.import_module(name) # Try to get `router` from the module router = getattr(module, "router", None) if not isinstance(router, APIRouter): continue # Build API prefix file_path = Path(module.__file__) relative_path = file_path.relative_to(package_path) parts: list[str] = list(relative_path.parts) # Remove "routers" folder(s) from prefix parts parts = [p for p in parts if p != "routers"] # Drop extension from filename parts[-1] = parts[-1].replace(".py", "") if full_path: # Use full path prefix_parts = [p.replace("_", "-") for p in parts if p != "__init__"] prefix_parts.insert(0, base_pkg_name) else: # Only use last file name prefix_parts = [parts[-1].replace("_", "-")] prefix = "/" + "/".join(prefix_parts) app.include_router(router, prefix=prefix)