A brief description of the backend service for the Glideator project, built with FastAPI.
- Docker
- Docker Compose
- Python 3.10
- Git
- Framework: FastAPI
- MCP Server: Model Context Protocol server (FastMCP)
- Database: PostgreSQL (using SQLAlchemy and psycopg2)
- Background Tasks: Celery (with Redis as broker/result backend in development and Render)
- Web Server: Uvicorn
- Containerization: Docker
- Clone the repository:
git clone <repository-url> # Replace with your repository URL cd glideator/backend
- Local Python Setup (Optional - Only if NOT using Docker):
- Create a virtual environment:
python -m venv env-backend source env-backend/bin/activate # On Windows use `env-backend\\Scripts\\activate`
- Install local packages first (if any updates outside Docker):
pip install ./packages/*.whl - Install dependencies:
pip install -r requirements.txt
- Create a virtual environment:
This is the easiest way to run the application and its local dependencies for development (PostgreSQL, Redis, Celery).
This uses docker-compose.dev.yml at the repository root (not inside backend/).
# From the repository root (parent of backend/)
docker-compose -f docker-compose.dev.yml up --buildThe API will be available at http://localhost:8000.
Production is deployed on Render. The legacy docker-compose.yml path has been removed because it was no longer the real production setup and had drifted badly from what Render actually runs.
If you need to inspect or change production behavior, treat the Render services and their environment/config as the source of truth.
To stop the services:
docker-compose -f <your-chosen-compose-file.yml> downEnsure PostgreSQL and Redis services are running and accessible. Set the environment variables listed below.
# Run the FastAPI application with hot-reloading
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# Run the Celery worker and beat (in separate terminals or using a process manager)
celery -A app.celery_app worker --loglevel=info
celery -A app.celery_app beat --loglevel=infoFor local development with Docker, environment variables live mainly in the repo root docker-compose.dev.yml. For local development without Docker, set them directly in your environment (for example via your shell or a .env loader if you add one):
# Example values (adjust as needed, especially for local setup)
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/glideator
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/1
Authentication required: callers must send a valid Authorization: Bearer <access_token> header (same session as other /users/me APIs). Submissions are stored in feedback_submissions with the authenticated user ID.
Redis enforces fixed-window limits per IP and per user. The client IP is taken from X-Forwarded-For (first address) when the header is set—configure your reverse proxy so this reflects the real client.
| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_FEEDBACK_WINDOW_MINUTES |
60 |
Length of each window in minutes. |
RATE_LIMIT_FEEDBACK_MAX_PER_IP |
10 |
Max submissions per IP per window. |
RATE_LIMIT_FEEDBACK_MAX_PER_USER |
10 |
Max submissions per authenticated user ID per window (in addition to the IP limit). |
If Redis is unavailable, the handler logs an error and allows the request (same tradeoff as auth rate limiting), so the API stays reachable.
The app database used by Docker Compose (repo root docker-compose.dev.yml) usually does not include the glideator_ground_crew schema. The API can serve Ground Crew data from a JSON export placed next to other static inputs:
-
Generate the export:
cd agents/ground_crew && poetry run ground-crew export-resources -o outputs/site_resources.json
-
Copy it into the backend package data directory (same location as
flight_stats.csv):cp agents/ground_crew/outputs/site_resources.json backend/app/data/site_resources.json
At runtime, if app/data/site_resources.json exists (resolved from app/crud.py’s package directory), it is loaded automatically. No env var is required.
Optional overrides:
SITE_RESOURCES_JSON_PATH— absolute path to a different JSON file (takes precedence over the bundled file).SITE_RESOURCES_FROM_APP_DATA=false— do not loadapp/data/site_resources.json; use SQL only (tests set this).
If neither a JSON file nor glideator_ground_crew is available, the endpoint returns empty resources for each site.
This project uses Celery (app.celery_app) for background tasks, with Redis as the broker/result backend in the active development and Render deployment paths.
- The
docker-compose.dev.ymlruns a combined worker and beat service. - The
celerybeat-schedulefile likely stores the periodic task schedule database (managed by Celery Beat). - Forecast processing triggers notification evaluation once new predictions are stored.
- A dedicated
dispatch_notificationstask runs every 30 minutes to queue push notifications for users with matching rules.
The backend exposes authenticated endpoints under /users/me for managing notification rules and Web Push subscriptions.
POST /users/me/notificationscreates a site-specific rule with metric, comparison operator, threshold, and optional lead time.PATCH /users/me/notifications/{notification_id}updates thresholds, comparison, lead time, or active status.GET /users/me/notifications/{notification_id}/eventsretrieves the most recent push payloads queued for that rule.POST /users/me/push-subscriptionsregisters or refreshes a Web Push endpoint (upsert on the endpoint URL).DELETE /users/me/push-subscriptions/{subscription_id}deactivates a subscription without removing its history.
When Celery processes new forecasts, or the scheduled dispatch_notifications task runs, matching rules generate notification events stored in the notification_events table. The worker immediately attempts Web Push delivery (using the VAPID keys described below), updating delivery_status to sent, failed, config_missing, or skipped based on the outcome.
To enable outbound Web Push delivery, set the following environment variables (typically on the Celery worker):
VAPID_PUBLIC_KEY=<your-public-key>
VAPID_PRIVATE_KEY=<your-private-key>
VAPID_SUBJECT=mailto:ops@example.com # Optional, defaults to mailto:admin@example.com
If the keys are omitted, notifications are still logged but marked with delivery_status=config_missing.
Since this project uses FastAPI, interactive API documentation (Swagger UI) is automatically available when the application is running. Access it at:
http://localhost:8000/docs
This project uses Alembic for schema migrations.
Common commands:
pip install -r requirements.txt
# Create the database and run migrations
export DATABASE_URL=postgresql://postgres:postgres@localhost:5432/glideator
alembic -c alembic.ini upgrade head
# Create a new revision (example)
alembic -c alembic.ini revision -m "add users and favorites"
# Apply latest migrations
alembic -c alembic.ini upgrade headIn production on Render, migrations are executed during deploy/startup.
The backend includes a Model Context Protocol (MCP) server that enables AI assistants to interact with Glideator's paragliding data through structured tools. The MCP server provides access to:
- Site Discovery: List all available paragliding sites
- Site Information: Get detailed site descriptions, facilities, and safety information
- Weather Forecasts: Access ML-powered flying predictions based on weather forecasts
- Historical Statistics: Retrieve seasonal flying patterns and statistics
- Takeoff/Landing Data: Get coordinates and details for launch and landing spots
- Trip Planning: Find optimal sites for specific date ranges with customizable filters
http://localhost:8000/mcp