""" Utility class for getting routes from a FastAPI app. """ from typing import Any, Dict, List, Optional from starlette.routing import BaseRoute from litellm._logging import verbose_logger class GetRoutes: @staticmethod def get_app_routes( route: BaseRoute, endpoint_route: Any, ) -> List[Dict[str, Any]]: """ Get routes for a regular route. """ routes: List[Dict[str, Any]] = [] route_info = { "path": getattr(route, "path", None), "methods": getattr(route, "methods", None), "name": getattr(route, "name", None), "endpoint": ( endpoint_route.__name__ if getattr(route, "endpoint", None) else None ), } routes.append(route_info) return routes @staticmethod def get_routes_for_mounted_app( route: BaseRoute, ) -> List[Dict[str, Any]]: """ Get routes for a mounted sub-application. """ routes: List[Dict[str, Any]] = [] mount_path = getattr(route, "path", "") sub_app = getattr(route, "app", None) if sub_app and hasattr(sub_app, "routes"): for sub_route in sub_app.routes: # Get endpoint - either from endpoint attribute or app attribute endpoint_func = getattr(sub_route, "endpoint", None) or getattr( sub_route, "app", None ) if endpoint_func is not None: sub_route_path = getattr(sub_route, "path", "") full_path = mount_path.rstrip("/") + sub_route_path route_info = { "path": full_path, "methods": getattr(sub_route, "methods", ["GET", "POST"]), "name": getattr(sub_route, "name", None), "endpoint": GetRoutes._safe_get_endpoint_name(endpoint_func), "mounted_app": True, } routes.append(route_info) return routes @staticmethod def _safe_get_endpoint_name(endpoint_function: Any) -> Optional[str]: """ Safely get the name of the endpoint function. """ try: if hasattr(endpoint_function, "__name__"): return getattr(endpoint_function, "__name__") elif hasattr(endpoint_function, "__class__") and hasattr( endpoint_function.__class__, "__name__" ): return getattr(endpoint_function.__class__, "__name__") else: return None except Exception: verbose_logger.exception( f"Error getting endpoint name for route: {endpoint_function}" ) return None