Coverage for src / lexigram / admin / bootstrap / factory.py: 0%
46 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-11 02:25 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-11 02:25 +0800
1"""Factory functions for creating admin applications."""
3from __future__ import annotations
5from pathlib import Path
6from typing import TYPE_CHECKING, Any
8from starlette.applications import Starlette
9from starlette.middleware import Middleware
10from starlette.middleware.sessions import SessionMiddleware
12from lexigram.admin.auth.services._cookie_config import build_session_cookie_kwargs
13from lexigram.admin.di.bundle_provider import AdminProvider
14from lexigram.admin.middleware.correlation import AdminCorrelationMiddleware
15from lexigram.admin.settings.loader import AdminConfigLoader
16from lexigram.logging import get_logger
18if TYPE_CHECKING:
19 from collections.abc import Sequence
21 from lexigram.admin.config import AdminConfig
22 from lexigram.admin.resources.base import Resource
24logger = get_logger(__name__)
27async def create_app(
28 *,
29 resources: Sequence[type | Resource] | dict[str, type | Resource] | None = None,
30 config: AdminConfig | None = None,
31 config_path: Path | str | None = None,
32 title: str = "Lexigram Admin",
33 prefix: str = "/admin",
34 debug: bool = False,
35 **kwargs: Any,
36) -> Starlette:
37 """Create a complete admin ASGI application."""
38 from lexigram.admin.config import AdminConfig as AdminConfigCls
40 if config is None and config_path is not None:
41 loader = AdminConfigLoader(yaml_path=Path(config_path))
42 config = await loader.load()
44 if config is None:
45 config = AdminConfigCls(title=title, prefix=prefix, debug=debug)
47 resources_list: list[Any] = []
48 if resources:
49 if isinstance(resources, dict):
50 resources_list = list(resources.values())
51 else:
52 resources_list = list(resources)
54 AdminProvider(config=config, resources=resources_list)
56 cookie_kwargs = build_session_cookie_kwargs(config.auth)
57 middleware = [
58 Middleware(AdminCorrelationMiddleware),
59 Middleware(SessionMiddleware, **cookie_kwargs),
60 ]
62 app = Starlette(
63 debug=debug,
64 middleware=middleware,
65 )
67 logger.info("Admin application created at %s", prefix)
68 return app
71async def create_admin_provider(
72 *,
73 resources: Sequence[type | Resource] | dict[str, type | Resource] | None = None,
74 config: AdminConfig | None = None,
75 config_path: Path | str | None = None,
76 title: str = "Lexigram Admin",
77 prefix: str = "/admin",
78 debug: bool = False,
79 **kwargs: Any,
80) -> AdminProvider:
81 """Create an AdminProvider for use with Application."""
82 from lexigram.admin.config import AdminConfig as AdminConfigCls
84 if config is None and config_path is not None:
85 loader = AdminConfigLoader(yaml_path=Path(config_path))
86 config = await loader.load()
88 if config is None:
89 config = AdminConfigCls(title=title, prefix=prefix, debug=debug)
91 resources_list: list[Any] = []
92 if resources:
93 if isinstance(resources, dict):
94 resources_list = list(resources.values())
95 else:
96 resources_list = list(resources)
98 admin = AdminProvider(config=config, resources=resources_list)
99 logger.info("AdminProvider created for prefix %s", prefix)
100 return admin
103__all__ = [
104 "create_admin_provider",
105 "create_app",
106]