Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from fastapi import APIRouter, Depends, HTTPException | |
| from sqlmodel import Session | |
| from tracker.config import load_config | |
| from tracker.config_updates import patch_active_program_id | |
| from tracker.db import get_session | |
| from tracker.training_schemas import ( | |
| AddProgramExerciseInput, | |
| CreateProgramInput, | |
| DisplaySettingsResponse, | |
| ExerciseResponse, | |
| HistoryResponse, | |
| LogRunInput, | |
| LogWorkoutInput, | |
| ProgramDetailResponse, | |
| ProgramExerciseDetail, | |
| ProgramSummary, | |
| RunLogEntry, | |
| SetActiveProgramInput, | |
| TodayResponse, | |
| UpdateProgramExerciseInput, | |
| WeightInput, | |
| ) | |
| from tracker.training_service import ( | |
| add_exercise_to_program, | |
| create_program_from_input, | |
| fetch_active_program_detail, | |
| fetch_history, | |
| fetch_runs, | |
| fetch_today, | |
| list_exercise_catalog, | |
| list_program_summaries, | |
| log_body_weight, | |
| log_running_session, | |
| log_workout_session, | |
| remove_program_exercise, | |
| update_program_exercise, | |
| ) | |
| router = APIRouter(prefix="/api") | |
| def get_display_settings() -> DisplaySettingsResponse: | |
| cfg = load_config() | |
| return DisplaySettingsResponse( | |
| weight_unit=cfg.display_weight_unit, | |
| distance_unit=cfg.display_distance_unit, | |
| ) | |
| def get_today( | |
| day_label: str, | |
| program_id: int | None = None, | |
| session: Session = Depends(get_session), | |
| ) -> TodayResponse: | |
| cfg = load_config() | |
| data, err = fetch_today(session, cfg, day_label, program_id) | |
| if err is not None: | |
| raise HTTPException(status_code=404, detail=err) | |
| if data is None: | |
| raise HTTPException(status_code=404, detail="No program found") | |
| return data | |
| def log_workout( | |
| body: LogWorkoutInput, | |
| session: Session = Depends(get_session), | |
| ) -> dict[str, int]: | |
| logged_count = log_workout_session(session, body) | |
| return {"logged": logged_count} | |
| def log_weight( | |
| body: WeightInput, | |
| session: Session = Depends(get_session), | |
| ) -> dict[str, float]: | |
| weight_kg = log_body_weight(session, body) | |
| return {"weight_kg": weight_kg} | |
| def get_history( | |
| days: int = 30, | |
| session: Session = Depends(get_session), | |
| ) -> HistoryResponse: | |
| return fetch_history(session, days) | |
| def log_run( | |
| body: LogRunInput, | |
| session: Session = Depends(get_session), | |
| ) -> dict[str, int]: | |
| run_log_id, err = log_running_session(session, body) | |
| if err is not None: | |
| raise HTTPException(status_code=404, detail=err) | |
| if run_log_id is None: | |
| raise HTTPException(status_code=500, detail="Run log failed") | |
| return {"run_log_id": run_log_id} | |
| def get_runs( | |
| days: int = 30, | |
| program_id: int | None = None, | |
| day_label: str | None = None, | |
| session: Session = Depends(get_session), | |
| ) -> list[RunLogEntry]: | |
| return fetch_runs(session, days, program_id, day_label) | |
| def list_programs( | |
| session: Session = Depends(get_session), | |
| ) -> list[ProgramSummary]: | |
| return list_program_summaries(session) | |
| def create_program( | |
| body: CreateProgramInput, | |
| session: Session = Depends(get_session), | |
| ) -> ProgramSummary: | |
| return create_program_from_input(session, body) | |
| def get_active_program( | |
| session: Session = Depends(get_session), | |
| ) -> ProgramDetailResponse: | |
| cfg = load_config() | |
| data, err = fetch_active_program_detail(session, cfg) | |
| if err is not None: | |
| raise HTTPException(status_code=404, detail=err) | |
| if data is None: | |
| raise HTTPException(status_code=404, detail="No program found") | |
| return data | |
| def set_active_program(body: SetActiveProgramInput) -> dict[str, int | None]: | |
| patch_active_program_id(body.program_id) | |
| return {"active_program_id": body.program_id} | |
| def list_exercises( | |
| session: Session = Depends(get_session), | |
| ) -> list[ExerciseResponse]: | |
| return list_exercise_catalog(session) | |
| def add_program_exercise( | |
| program_id: int, | |
| body: AddProgramExerciseInput, | |
| session: Session = Depends(get_session), | |
| ) -> ProgramExerciseDetail: | |
| data, err = add_exercise_to_program(session, program_id, body) | |
| if err is not None: | |
| raise HTTPException(status_code=404, detail=err) | |
| if data is None: | |
| raise HTTPException(status_code=404, detail="Not found") | |
| return data | |
| def remove_program_exercise_route( | |
| program_id: int, | |
| exercise_id: int, | |
| day_label: str, | |
| session: Session = Depends(get_session), | |
| ) -> dict[str, str]: | |
| err = remove_program_exercise(session, program_id, exercise_id, day_label) | |
| if err is not None: | |
| raise HTTPException(status_code=404, detail=err) | |
| return {"removed": f"exercise {exercise_id} from day {day_label}"} | |
| def update_program_exercise_route( | |
| program_id: int, | |
| exercise_id: int, | |
| day_label: str, | |
| body: UpdateProgramExerciseInput, | |
| session: Session = Depends(get_session), | |
| ) -> ProgramExerciseDetail: | |
| data, err = update_program_exercise(session, program_id, exercise_id, day_label, body) | |
| if err is not None: | |
| raise HTTPException(status_code=404, detail=err) | |
| if data is None: | |
| raise HTTPException(status_code=404, detail="Not found") | |
| return data | |