This commit is contained in:
Piotr Dec 2025-10-07 00:06:04 +02:00
parent 2cde0de07a
commit b18488a6d3
Signed by: stawros
GPG key ID: 74B18A3F0F1E99C0
4 changed files with 38 additions and 27 deletions

1
app/config/__init__.py Normal file
View file

@ -0,0 +1 @@
from .settings import get_settings

28
app/config/settings.py Normal file
View file

@ -0,0 +1,28 @@
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import BaseModel
from pathlib import Path
import yaml
class AppConfig(BaseModel):
host: str = "127.0.0.1"
port: int = 8000
reload: bool = True
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="KARL_", env_nested_delimiter="__")
app: AppConfig = AppConfig()
@classmethod
def from_yaml(cls, path: Path | str = "config/config.yaml") -> "Settings":
p = Path(path)
data = {}
if p.exists():
with p.open("r", encoding="utf-8") as fh:
data = yaml.safe_load(fh) or {}
return cls(**data)
@lru_cache
def get_settings() -> Settings:
return Settings.from_yaml()

View file

@ -1,11 +1,9 @@
import os
import yaml
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from jinja2 import Environment, FileSystemLoader, select_autoescape from jinja2 import Environment, FileSystemLoader, select_autoescape
from app.api.v1 import router as api_v1_router from app.api.v1 import router as api_v1_router
from app.config import get_settings
# Inicjalizacja Jinja2 # Inicjalizacja Jinja2
templates_env = Environment( templates_env = Environment(
@ -13,26 +11,7 @@ templates_env = Environment(
autoescape=select_autoescape(["html", "xml"]), autoescape=select_autoescape(["html", "xml"]),
) )
def load_config() -> dict:
"""
Ładuje konfigurację z pliku YAML.
Domyślna ścieżka: config/config.yaml
Można nadpisać przez APP_CONFIG_FILE.
"""
config_path = os.getenv("APP_CONFIG_FILE", "config/config.yaml")
if not os.path.exists(config_path):
# Zwróć minimalną domyślną konfigurację, jeśli plik nie istnieje
return {
"app": {"host": "127.0.0.1", "port": 8000, "reload": True},
}
with open(config_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f) or {}
app = FastAPI(title="Karl", version="0.1.0") app = FastAPI(title="Karl", version="0.1.0")
# Załaduj konfigurację do stanu aplikacji
app.state.config = load_config()
# Rejestracja routera API pod /api/v1 # Rejestracja routera API pod /api/v1
app.include_router(api_v1_router, prefix="/api/v1", tags=["v1"]) app.include_router(api_v1_router, prefix="/api/v1", tags=["v1"])
@ -48,8 +27,10 @@ async def index(request: Request) -> HTMLResponse:
def run() -> None: def run() -> None:
import uvicorn import uvicorn
cfg = getattr(app.state, "config", {}) settings = get_settings()
host = cfg.get("app", {}).get("host", "127.0.0.1") uvicorn.run(
port = int(cfg.get("app", {}).get("port", 8000)) "app.main:app",
reload = bool(cfg.get("app", {}).get("reload", True)) host=settings.app.host,
uvicorn.run("app.main:app", host=host, port=port, reload=reload) port=settings.app.port,
reload=settings.app.reload,
)

View file

@ -9,6 +9,7 @@ dependencies = [
"fastapi>=0.115.0", "fastapi>=0.115.0",
"uvicorn[standard]>=0.30.0", "uvicorn[standard]>=0.30.0",
"jinja2>=3.1.4", "jinja2>=3.1.4",
"pydantic-settings>=2.4.0",
"pyyaml>=6.0.2", "pyyaml>=6.0.2",
] ]