73 lines
2.5 KiB
Python
73 lines
2.5 KiB
Python
"""
|
|
Mortality/Life Table API endpoints
|
|
|
|
Provides read endpoints to query life tables by age and number tables by month,
|
|
filtered by sex (M/F/A) and race (W/B/H/A).
|
|
"""
|
|
|
|
from typing import Optional
|
|
from fastapi import APIRouter, Depends, HTTPException, Query, status, Path
|
|
from pydantic import BaseModel, Field
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.database.base import get_db
|
|
from app.models.user import User
|
|
from app.auth.security import get_current_user
|
|
from app.services.mortality import get_life_values, get_number_value, InvalidCodeError
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class LifeResponse(BaseModel):
|
|
age: int
|
|
sex: str = Field(description="M, F, or A (all)")
|
|
race: str = Field(description="W, B, H, or A (all)")
|
|
le: Optional[float]
|
|
na: Optional[float]
|
|
|
|
|
|
class NumberResponse(BaseModel):
|
|
month: int
|
|
sex: str = Field(description="M, F, or A (all)")
|
|
race: str = Field(description="W, B, H, or A (all)")
|
|
na: Optional[float]
|
|
|
|
|
|
@router.get("/life/{age}", response_model=LifeResponse)
|
|
async def get_life_entry(
|
|
age: int = Path(..., ge=0, description="Age in years (>= 0)"),
|
|
sex: str = Query("A", min_length=1, max_length=1, description="M, F, or A (all)"),
|
|
race: str = Query("A", min_length=1, max_length=1, description="W, B, H, or A (all)"),
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Get life expectancy (LE) and number alive (NA) for an age/sex/race."""
|
|
try:
|
|
result = get_life_values(db, age=age, sex=sex, race=race)
|
|
except InvalidCodeError as e:
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
|
if result is None:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Age not found")
|
|
return result
|
|
|
|
|
|
@router.get("/number/{month}", response_model=NumberResponse)
|
|
async def get_number_entry(
|
|
month: int = Path(..., ge=0, description="Month index (>= 0)"),
|
|
sex: str = Query("A", min_length=1, max_length=1, description="M, F, or A (all)"),
|
|
race: str = Query("A", min_length=1, max_length=1, description="W, B, H, or A (all)"),
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Get monthly number alive (NA) for a month/sex/race."""
|
|
try:
|
|
result = get_number_value(db, month=month, sex=sex, race=race)
|
|
except InvalidCodeError as e:
|
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
|
if result is None:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Month not found")
|
|
return result
|
|
|
|
|