main.py
Class: FastAPI Application (app)
Purpose: Entry point and HTTP interface for the Piggyback Learning platform. Configures routes, mounts static directories, integrates admin/expert APIs, and exposes TTS and video management endpoints.
Fields:
- app: FastAPI — Main ASGI application instance (global singleton, required for server startup)
Methods:
-
home_page(request: Request): HTMLResponse — Renders the main home page. Preconditions:
- Templates directory must be configured correctly. Postconditions:
- Returns rendered
home.html. Throws: - Template-related exceptions if template is missing. Example:
- GET
/
-
home_redirect(request: Request): HTMLResponse — Alternative route for home page. Preconditions:
- Templates configured correctly. Postconditions:
- Returns rendered
home.html. Throws: - Template-related exceptions if template is missing. Example:
- GET
/home
-
children_page(request: Request): HTMLResponse — Renders children learning interface (no password required). Preconditions:
- Templates configured correctly. Postconditions:
- Returns rendered
children.html. Example: - GET
/children
-
verify_password(user_type: str, password: str): JSONResponse — Validates admin or expert password. Preconditions:
user_typemust be"admin"or"expert".passwordmust be provided via form submission. Postconditions:- Returns JSON
{ success: True, redirect: <route> }if valid. - Returns JSON
{ success: False }if invalid. Throws: - No explicit exceptions (handled via JSON failure response). Example:
- POST
/api/verify-password
-
expert_preview(request: Request, file: Optional[str], video: Optional[str], mode: Optional[str]): HTMLResponse — Renders expert preview interface. Preconditions:
- Preview data must be buildable via
build_expert_preview_data. Postconditions: - Returns rendered
expert_preview.htmlwith:- Video preview data
- Question type options Throws:
- Exceptions from preview data builder if input invalid. Example:
- GET
/expert-preview?video=abc123&mode=review
- Preview data must be buildable via
-
save_expert_annotation(payload: Dict[str, Any]): JSONResponse — Persists expert annotation payload. Preconditions:
- JSON body must match expected annotation schema. Postconditions:
- Returns result from
save_expert_annotation_payload. Throws: - Service-layer validation exceptions wrapped in response. Example:
- POST
/api/expert-annotations
-
list_videos(): JSONResponse — Lists downloaded videos with metadata and question counts. Preconditions:
DOWNLOADS_DIRmust exist or be accessible. Postconditions:- Returns JSON:
{
success: bool,
videos: [
{
id,
title,
thumbnail,
duration,
videoUrl,
questionCount
}
]
}
Throws:
- Returns failure JSON if filesystem or parsing error occurs. Example:
- GET
/api/videos-list
-
get_expert_questions(video_id: str): JSONResponse — Retrieves saved expert questions for a video. Preconditions:
video_idmust exist. Postconditions:- Returns JSON payload with appropriate status code. Throws:
- Propagates status from
get_expert_questions_payload. Example: - GET
/api/expert-questions/{video_id}
-
save_expert_question(payload: Dict[str, Any]): JSONResponse — Saves a single expert question. Preconditions:
- JSON body must match expected question schema. Postconditions:
- Returns service-layer result with status code. Throws:
- Validation or persistence errors via service response. Example:
- POST
/api/expert-questions
-
save_final_questions(payload: Dict[str, Any]): JSONResponse — Persists finalized set of questions for a video. Preconditions:
- JSON body must match expected schema. Postconditions:
- Returns service-layer result with status code. Throws:
- Validation or persistence errors via service response. Example:
- POST
/api/save-final-questions
-
synthesize_tts(payload: Dict[str, Any]): JSONResponse — Generates text-to-speech audio using OpenAI TTS. Preconditions:
textfield must be present and non-empty.- Optional fields:
voice,speed,format. Postconditions: - Returns JSON:
{
success: True,
audio: <base64-encoded audio>,
format: "mp3",
voice: <voice_used>
} - On failure returns:
{
success: False,
message: <error message>
}
Throws:
- Returns HTTP 400 if
textmissing. - Returns HTTP 502 if TTS generation fails. Behavior:
- Clamps speed to range [0.25, 4.0].
- Attempts fallback voice
"alloy"if requested voice fails. - Runs blocking OpenAI call in thread using
asyncio.to_thread. Example: - POST
/api/tts{
"text": "Hello world",
"voice": "sage",
"speed": 1.0,
"format": "mp3"
}
Additional Configuration:
-
Router Registration:
- Includes video quiz routes under
/api - Includes admin pages under
/admin - Includes admin APIs under
/api - Includes admin WebSocket routes
- Includes video quiz routes under
-
Static Mounts:
/downloads→ serves video files fromDOWNLOADS_DIR/assets→ serves public assets if directory exists/static→ serves static frontend resources
Invariants:
appmust be instantiated exactly once.- Mounted directories must remain accessible during runtime.
- Service-layer functions handle business logic; this module only orchestrates HTTP layer.