Clarify settings and app wiring
This commit is contained in:
@@ -1,16 +1,20 @@
|
|||||||
"""Environment configuration derived from environment variables."""
|
"""Environment configuration derived from environment variables."""
|
||||||
|
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
from pydantic import SecretStr # Import SecretStr for sensitive data
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
"""Application settings."""
|
"""
|
||||||
|
Application settings class using Pydantic BaseSettings.
|
||||||
|
Settings are loaded from environment variables and have default values defined here.
|
||||||
|
"""
|
||||||
|
|
||||||
service_name: str = "avaaz-backend" # Used as a functional ID
|
service_name: str = "avaaz-backend" # A unique functional identifier for the microservice
|
||||||
environment: str = "development"
|
environment: str = "development" # Defines the current deployment stage (e.g., 'development', 'staging', 'production')
|
||||||
|
|
||||||
title: str = "Avaaz Language Tutoring API"
|
title: str = "Avaaz Language Tutoring API"
|
||||||
description: str ="""
|
description: str = """
|
||||||
# Avaaz Language Tutoring API
|
# Avaaz Language Tutoring API
|
||||||
|
|
||||||
This API powers the **avaaz.ai** mobile and web applications, providing the robust backend services for our AI-driven oral language skills tutor. The platform is specifically engineered to help students achieve oral proficiency using adaptive, conversational AI agents.
|
This API powers the **avaaz.ai** mobile and web applications, providing the robust backend services for our AI-driven oral language skills tutor. The platform is specifically engineered to help students achieve oral proficiency using adaptive, conversational AI agents.
|
||||||
@@ -22,14 +26,24 @@ class Settings(BaseSettings):
|
|||||||
* **Cross-Platform Sync:** Ensures seamless learning continuity and progress synchronization across all user devices.
|
* **Cross-Platform Sync:** Ensures seamless learning continuity and progress synchronization across all user devices.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
version: str = "0.1.0"
|
version: str = "0.1.0" # The current semantic version of the API application
|
||||||
|
|
||||||
database_url: str = "postgresql+psycopg://postgres:postgres@postgres:5432/avaaz"
|
# Use SecretStr to prevent accidental logging of credentials.
|
||||||
|
# Access the actual value using settings.database_url.get_secret_value()
|
||||||
model_config = SettingsConfigDict(env_prefix="", case_sensitive=False)
|
database_url: SecretStr = SecretStr("postgresql+psycopg://postgres:postgres@postgres:5432/avaaz")
|
||||||
|
|
||||||
|
model_config = SettingsConfigDict(
|
||||||
|
env_prefix="", # Load variables without a specific prefix (e.g., `DATABASE_URL` instead of `APP_DATABASE_URL`)
|
||||||
|
case_sensitive=False # Environment variable names are treated as case-insensitive during loading
|
||||||
|
)
|
||||||
|
|
||||||
@lru_cache(maxsize=1)
|
@lru_cache(maxsize=1)
|
||||||
def get_settings() -> Settings:
|
def get_settings() -> Settings:
|
||||||
"""Return cached settings instance."""
|
"""
|
||||||
|
Return a cached singleton instance of the application settings.
|
||||||
|
|
||||||
|
This function leverages functools.lru_cache to ensure that environment variables
|
||||||
|
are read only once during the application's lifecycle, improving performance
|
||||||
|
and ensuring consistency across requests.
|
||||||
|
"""
|
||||||
return Settings()
|
return Settings()
|
||||||
|
|||||||
@@ -1,19 +1,28 @@
|
|||||||
"""Application entrypoint and router wiring."""
|
"""
|
||||||
|
API Application Entrypoint and Router Wiring.
|
||||||
|
|
||||||
|
This module initializes the core FastAPI application instance, loads
|
||||||
|
configuration, applies middleware, and wires up all defined API routers.
|
||||||
|
"""
|
||||||
|
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from typing import List
|
||||||
|
|
||||||
from api.v1.router import router as api_v1_router
|
from api.v1.router import router as api_v1_router
|
||||||
from operations.health.router import router as health_router
|
from operations.health.router import router as health_router
|
||||||
|
from core.config import get_settings, Settings # Import Settings type for clarity
|
||||||
|
|
||||||
from core.config import get_settings
|
def create_app(settings: Settings = get_settings()) -> FastAPI:
|
||||||
|
"""
|
||||||
|
Create and configure the FastAPI application instance.
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
Args:
|
||||||
"""Create and configure the FastAPI application."""
|
settings: Configuration object from core.config. Defaults to current settings.
|
||||||
|
|
||||||
settings = get_settings()
|
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A configured FastAPI application instance.
|
||||||
|
"""
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title=settings.title,
|
title=settings.title,
|
||||||
description=settings.description,
|
description=settings.description,
|
||||||
@@ -23,19 +32,25 @@ def create_app() -> FastAPI:
|
|||||||
openapi_url="/openapi.json",
|
openapi_url="/openapi.json",
|
||||||
)
|
)
|
||||||
|
|
||||||
# CORS for local dev (frontend on 3000). Tighten/override in prod.
|
# Define allowed origins dynamically based on local dev environment needs
|
||||||
|
# In a production setting, this list would typically be sourced from environment variables.
|
||||||
|
allowed_origins: List[str] = ["http://localhost:3000", "http://127.0.0.1:3000"]
|
||||||
|
|
||||||
|
# Configure CORS middleware
|
||||||
|
# TODO: Tightly restrict origins in production deployment.
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=["http://localhost:3000", "http://127.0.0.1:3000"],
|
allow_origins=allowed_origins,
|
||||||
allow_credentials=True,
|
allow_credentials=True,
|
||||||
allow_methods=["*"],
|
allow_methods=["*"],
|
||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Include API routers
|
||||||
app.include_router(health_router)
|
app.include_router(health_router)
|
||||||
app.include_router(api_v1_router, prefix="/api/v1")
|
app.include_router(api_v1_router, prefix="/api/v1")
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
# Main entry point for services like Uvicorn (e.g., `uvicorn main:app --reload`)
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|||||||
Reference in New Issue
Block a user