feat(01-01): create FastAPI application structure with health endpoint
- Add FastAPI app with title 'Debate API' v1.0.0 - Configure pydantic-settings for environment-based configuration - Create /health endpoint at root level - Create /api/v1/health and /api/v1/health/ready endpoints - Disable docs/redoc in production environment
This commit is contained in:
parent
300b3ddb0a
commit
519333e598
10 changed files with 107 additions and 0 deletions
1
backend/__init__.py
Normal file
1
backend/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Debate Backend Package
|
||||
1
backend/app/__init__.py
Normal file
1
backend/app/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Debate Backend Application
|
||||
1
backend/app/api/__init__.py
Normal file
1
backend/app/api/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# API package
|
||||
1
backend/app/api/v1/__init__.py
Normal file
1
backend/app/api/v1/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# API v1 package
|
||||
1
backend/app/api/v1/endpoints/__init__.py
Normal file
1
backend/app/api/v1/endpoints/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# API v1 endpoints package
|
||||
17
backend/app/api/v1/endpoints/health.py
Normal file
17
backend/app/api/v1/endpoints/health.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
"""Health check endpoints."""
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def health_check() -> dict[str, str]:
|
||||
"""Basic health check endpoint."""
|
||||
return {"status": "healthy"}
|
||||
|
||||
|
||||
@router.get("/ready")
|
||||
async def readiness_check() -> dict[str, str]:
|
||||
"""Readiness check endpoint (DB check added in plan 01-02)."""
|
||||
return {"status": "ready"}
|
||||
9
backend/app/api/v1/router.py
Normal file
9
backend/app/api/v1/router.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"""API v1 router configuration."""
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from backend.app.api.v1.endpoints import health
|
||||
|
||||
api_router = APIRouter()
|
||||
|
||||
api_router.include_router(health.router, prefix="/health", tags=["health"])
|
||||
1
backend/app/core/__init__.py
Normal file
1
backend/app/core/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Core application components
|
||||
51
backend/app/core/config.py
Normal file
51
backend/app/core/config.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
"""Application configuration via pydantic-settings."""
|
||||
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
"""Application settings loaded from environment variables."""
|
||||
|
||||
# Database
|
||||
database_url: str = "postgresql+asyncpg://debate:debate_dev@localhost:5433/debate"
|
||||
|
||||
# Security
|
||||
secret_key: str = "change-me-in-production"
|
||||
csrf_secret_key: str = "change-me-in-production"
|
||||
|
||||
# Environment
|
||||
environment: str = "development"
|
||||
debug: bool = True
|
||||
|
||||
# CORS and trusted hosts
|
||||
allowed_hosts: str = "localhost,127.0.0.1"
|
||||
allowed_origins: str = "http://localhost:3000,http://127.0.0.1:3000"
|
||||
|
||||
# Cookie settings
|
||||
cookie_domain: str = "localhost"
|
||||
|
||||
@property
|
||||
def allowed_hosts_list(self) -> list[str]:
|
||||
"""Parse allowed hosts as a list."""
|
||||
return [h.strip() for h in self.allowed_hosts.split(",") if h.strip()]
|
||||
|
||||
@property
|
||||
def allowed_origins_list(self) -> list[str]:
|
||||
"""Parse allowed origins as a list."""
|
||||
return [o.strip() for o in self.allowed_origins.split(",") if o.strip()]
|
||||
|
||||
@property
|
||||
def is_production(self) -> bool:
|
||||
"""Check if running in production environment."""
|
||||
return self.environment == "production"
|
||||
|
||||
class Config:
|
||||
"""Pydantic settings configuration."""
|
||||
|
||||
env_file = ".env"
|
||||
env_file_encoding = "utf-8"
|
||||
extra = "ignore"
|
||||
|
||||
|
||||
# Global settings instance
|
||||
settings = Settings()
|
||||
24
backend/app/main.py
Normal file
24
backend/app/main.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
"""FastAPI application entry point."""
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
from backend.app.api.v1.router import api_router
|
||||
from backend.app.core.config import settings
|
||||
|
||||
app = FastAPI(
|
||||
title="Debate API",
|
||||
version="1.0.0",
|
||||
description="Backend API for Debate - Linux distribution customization platform",
|
||||
docs_url="/docs" if not settings.is_production else None,
|
||||
redoc_url="/redoc" if not settings.is_production else None,
|
||||
debug=settings.debug,
|
||||
)
|
||||
|
||||
# Include API routers
|
||||
app.include_router(api_router, prefix="/api/v1")
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def root_health() -> dict[str, str]:
|
||||
"""Root health check endpoint."""
|
||||
return {"status": "healthy"}
|
||||
Loading…
Add table
Reference in a new issue