diff --git a/src/typosaurus_sandbox/__init__.py b/src/typosaurus_sandbox/__init__.py index 3bc5c04..5eb06bc 100644 --- a/src/typosaurus_sandbox/__init__.py +++ b/src/typosaurus_sandbox/__init__.py @@ -1,5 +1,7 @@ # retoor from typosaurus_sandbox.app import App +from typosaurus_sandbox.core import Config, setup_logging + +__all__ = ["App", "Config", "setup_logging"] -__all__ = ["App"] diff --git a/src/typosaurus_sandbox/__main__.py b/src/typosaurus_sandbox/__main__.py index 9eea1bc..a7d8ab3 100644 --- a/src/typosaurus_sandbox/__main__.py +++ b/src/typosaurus_sandbox/__main__.py @@ -1,7 +1,22 @@ # retoor +import logging + import uvicorn from typosaurus_sandbox.app import App +from typosaurus_sandbox.core import Config, setup_logging + +logger = logging.getLogger(__name__) + + +def main() -> None: + setup_logging() + config = Config.load() + logger.info("starting server on %s:%d", config.host, config.port) + uvicorn.run(App, host=config.host, port=config.port, log_level="info") + + +if __name__ == "__main__": + main() -uvicorn.run(App, host="127.0.0.1", port=8000, log_level="info") diff --git a/src/typosaurus_sandbox/app.py b/src/typosaurus_sandbox/app.py index 853e7ec..06f4ec3 100644 --- a/src/typosaurus_sandbox/app.py +++ b/src/typosaurus_sandbox/app.py @@ -1,15 +1,26 @@ # retoor +import logging + from fastapi import FastAPI from typosaurus_sandbox.presentation.api.v1.calculator import calculator_router +logger = logging.getLogger(__name__) + App = FastAPI(title="typosaurus-sandbox") +@App.on_event("startup") +def on_startup() -> None: + logger.info("application startup complete") + + @App.get("/health") def health() -> dict[str, str]: + logger.debug("health check requested") return {"status": "ok"} App.include_router(calculator_router) + diff --git a/src/typosaurus_sandbox/core/__init__.py b/src/typosaurus_sandbox/core/__init__.py new file mode 100644 index 0000000..36e8ce1 --- /dev/null +++ b/src/typosaurus_sandbox/core/__init__.py @@ -0,0 +1,7 @@ +# retoor + +from typosaurus_sandbox.core.config import Config +from typosaurus_sandbox.core.logging import setup_logging + +__all__ = ["Config", "setup_logging"] + diff --git a/src/typosaurus_sandbox/core/config.py b/src/typosaurus_sandbox/core/config.py new file mode 100644 index 0000000..653d871 --- /dev/null +++ b/src/typosaurus_sandbox/core/config.py @@ -0,0 +1,28 @@ +# retoor + +import json +import logging +from dataclasses import dataclass +from pathlib import Path + +logger = logging.getLogger(__name__) + + +@dataclass +class Config: + host: str = "127.0.0.1" + port: int = 8000 + + @classmethod + def load(cls) -> "Config": + config_path = Path(".env.json") + if not config_path.exists(): + logger.info("no .env.json found, using defaults") + return cls() + with config_path.open() as f: + data = json.load(f) + host = data.get("host", cls.host) + port = data.get("port", cls.port) + logger.info("loaded config from .env.json: host=%s port=%s", host, port) + return cls(host=host, port=port) + diff --git a/src/typosaurus_sandbox/core/logging.py b/src/typosaurus_sandbox/core/logging.py new file mode 100644 index 0000000..aad38cb --- /dev/null +++ b/src/typosaurus_sandbox/core/logging.py @@ -0,0 +1,23 @@ +# retoor + +import logging +import logging.handlers +from pathlib import Path + + +def setup_logging() -> None: + log_dir = Path("logs") + log_dir.mkdir(exist_ok=True) + + handler = logging.handlers.RotatingFileHandler( + log_dir / "typosaurus-sandbox.log", + maxBytes=10 * 1024 * 1024, + backupCount=5, + ) + handler.setFormatter( + logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s") + ) + + logging.basicConfig(level=logging.DEBUG, handlers=[handler]) + logging.getLogger(__name__).info("logging configured") +