asgi/wsgi mounting implemented

This commit is contained in:
Илья Глазунов
2025-12-03 12:10:28 +03:00
parent 831eee5d01
commit 0d0d1aec80
13 changed files with 2528 additions and 7 deletions
+70 -1
View File
@@ -138,6 +138,74 @@ class MonitoringExtension(Extension):
}
class ASGIExtension(Extension):
def __init__(self, config: Dict[str, Any]):
super().__init__(config)
from .asgi_mount import ASGIMountManager, create_django_app
self.mount_manager = ASGIMountManager()
self._load_mounts(config.get("mounts", []))
def _load_mounts(self, mounts: List[Dict[str, Any]]) -> None:
from .asgi_mount import create_django_app
for mount_config in mounts:
path = mount_config.get("path", "/")
if "django_settings" in mount_config:
app = create_django_app(
settings_module=mount_config["django_settings"],
module_path=mount_config.get("module_path"),
)
if app:
self.mount_manager.mount(
path=path,
app=app,
name=mount_config.get("name", f"django:{mount_config['django_settings']}"),
strip_path=mount_config.get("strip_path", True),
)
continue
self.mount_manager.mount(
path=path,
app_path=mount_config.get("app_path"),
app_type=mount_config.get("app_type", "asgi"),
module_path=mount_config.get("module_path"),
factory=mount_config.get("factory", False),
factory_args=mount_config.get("factory_args"),
name=mount_config.get("name", ""),
strip_path=mount_config.get("strip_path", True),
)
async def process_request(self, request: Request) -> Optional[Response]:
path = request.url.path
mount = self.mount_manager.get_mount(path)
if mount is not None:
# Store mount info in request state for middleware to use
request.state.asgi_mount = mount
# Return a special marker response that middleware will intercept
return None # Will be handled by get_asgi_handler
return None
async def process_response(self, request: Request, response: Response) -> Response:
return response
def get_asgi_handler(self, request: Request) -> Optional[Any]:
path = request.url.path
return self.mount_manager.get_mount(path)
def get_metrics(self) -> Dict[str, Any]:
return {
"asgi_mounts": self.mount_manager.list_mounts(),
"asgi_mount_count": len(self.mount_manager.mounts),
}
def cleanup(self) -> None:
logger.info("Cleaning up ASGI mounts")
class ExtensionManager:
def __init__(self) -> None:
self.extensions: List[Extension] = []
@@ -145,7 +213,8 @@ class ExtensionManager:
"routing": RoutingExtension,
"security": SecurityExtension,
"caching": CachingExtension,
"monitoring": MonitoringExtension
"monitoring": MonitoringExtension,
"asgi": ASGIExtension,
}
def register_extension_type(self, name: str, extension_class: Type[Extension]) -> None: