initial commit after split
This commit is contained in:
73
src/govoplan_core/server/config.py
Normal file
73
src/govoplan_core/server/config.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Callable, Iterable, Mapping, Sequence
|
||||
from dataclasses import dataclass, field
|
||||
from importlib import import_module
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, FastAPI
|
||||
|
||||
from govoplan_core.core.modules import ModuleManifest
|
||||
from govoplan_core.core.registry import PlatformRegistry
|
||||
from govoplan_core.server.fastapi import LifespanFactory
|
||||
|
||||
ManifestFactory = Callable[[], ModuleManifest]
|
||||
RouterEnabled = Callable[[object | None, PlatformRegistry], bool]
|
||||
AppConfigurator = Callable[[FastAPI, PlatformRegistry, object | None], None]
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RouterContribution:
|
||||
router: APIRouter
|
||||
required_module: str | None = None
|
||||
enabled: RouterEnabled | None = None
|
||||
|
||||
def should_include(self, settings: object | None, registry: PlatformRegistry) -> bool:
|
||||
if self.required_module and not registry.has_module(self.required_module):
|
||||
return False
|
||||
if self.enabled is not None and not self.enabled(settings, registry):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class GovoplanServerConfig:
|
||||
title: str = "GovOPlaN Server"
|
||||
version: str = "0.1.0"
|
||||
settings: object | None = None
|
||||
enabled_modules: str | Iterable[str] = ("access",)
|
||||
api_prefix: str = "/api/v1"
|
||||
base_routers: Sequence[APIRouter] = ()
|
||||
post_module_routers: Sequence[APIRouter] = ()
|
||||
extra_routers: Sequence[RouterContribution] = ()
|
||||
lifespan: LifespanFactory | None = None
|
||||
cors_origins: Iterable[str] = ()
|
||||
manifest_factories: Sequence[ManifestFactory] = ()
|
||||
module_context_data: Mapping[str, Any] = field(default_factory=dict)
|
||||
app_configurators: Sequence[AppConfigurator] = ()
|
||||
|
||||
|
||||
def import_object(path: str) -> Any:
|
||||
module_name, separator, attribute = path.partition(":")
|
||||
if not separator:
|
||||
raise ValueError(f"Object path must use module:attribute syntax: {path!r}")
|
||||
module = import_module(module_name)
|
||||
value: Any = module
|
||||
for part in attribute.split("."):
|
||||
value = getattr(value, part)
|
||||
return value
|
||||
|
||||
|
||||
def load_server_config(path: str | None = None) -> GovoplanServerConfig:
|
||||
config_path = path or os.getenv("GOVOPLAN_SERVER_CONFIG") or "govoplan_core.server.default_config:get_server_config"
|
||||
try:
|
||||
loaded = import_object(config_path)
|
||||
except ModuleNotFoundError:
|
||||
if path or os.getenv("GOVOPLAN_SERVER_CONFIG"):
|
||||
raise
|
||||
return GovoplanServerConfig()
|
||||
config = loaded() if callable(loaded) else loaded
|
||||
if not isinstance(config, GovoplanServerConfig):
|
||||
raise TypeError(f"{config_path!r} did not return a GovoplanServerConfig")
|
||||
return config
|
||||
Reference in New Issue
Block a user