diff --git a/app/core/config.py b/app/core/config.py new file mode 100644 index 0000000..7509702 --- /dev/null +++ b/app/core/config.py @@ -0,0 +1,49 @@ +""" +Configuration settings for the application. +""" +from pathlib import Path +from typing import List, Optional, Union + +from pydantic import AnyHttpUrl, BaseSettings, validator + + +class Settings(BaseSettings): + """ + Application settings. + """ + + PROJECT_NAME: str = "Todo API" + VERSION: str = "0.1.0" + API_V1_STR: str = "/api/v1" + + # BACKEND_CORS_ORIGINS is a comma-separated list of origins + # e.g: "http://localhost:8000,http://localhost:3000" + BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [] + + @validator("BACKEND_CORS_ORIGINS", pre=True) + def assemble_cors_origins(cls, v: Union[str, List[str]]) -> List[str]: + """ + Parse CORS origins from string or list. + """ + if isinstance(v, str) and not v.startswith("["): + return [i.strip() for i in v.split(",")] + if isinstance(v, (list, str)): + return v + raise ValueError(v) + + # Database configuration + DB_DIR: Path = Path("/app") / "storage" / "db" + SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite" + + class Config: + """ + Config class for Settings. + """ + case_sensitive = True + + +# Create settings instance +settings = Settings() + +# Ensure DB directory exists +settings.DB_DIR.mkdir(parents=True, exist_ok=True) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..62a4809 --- /dev/null +++ b/main.py @@ -0,0 +1,39 @@ +""" +Todo API main application. +""" +import uvicorn +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +from app.api.v1.api import api_router +from app.core.config import settings + +app = FastAPI( + title=settings.PROJECT_NAME, + openapi_url="/openapi.json", + version=settings.VERSION, +) + +# Set all CORS enabled origins +if settings.BACKEND_CORS_ORIGINS: + app.add_middleware( + CORSMiddleware, + allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + +app.include_router(api_router, prefix="/api/v1") + + +@app.get("/health", tags=["health"]) +async def health_check(): + """ + Health check endpoint. + """ + return {"status": "ok", "message": "Todo API is running"} + + +if __name__ == "__main__": + uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True) \ No newline at end of file