Skip to content

Latest commit

 

History

History
206 lines (140 loc) · 8.62 KB

File metadata and controls

206 lines (140 loc) · 8.62 KB

Glideator Backend

A brief description of the backend service for the Glideator project, built with FastAPI.

Prerequisites

  • Docker
  • Docker Compose
  • Python 3.10
  • Git

Core Technologies

  • 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

Installation

  1. Clone the repository:
    git clone <repository-url> # Replace with your repository URL
    cd glideator/backend
  2. 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

Running the Application

Using Docker Compose (Recommended)

This is the easiest way to run the application and its local dependencies for development (PostgreSQL, Redis, Celery).

Development Environment (with Hot-Reloading)

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 --build

The API will be available at http://localhost:8000.

Production / Deployment

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> down

Running Locally (Without Docker)

Ensure 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=info

Environment Variables

For 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

Feedback submissions (POST /feedback/submit)

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.

Site resources (/sites/{id}/resources)

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:

  1. Generate the export:

    cd agents/ground_crew && poetry run ground-crew export-resources -o outputs/site_resources.json
  2. 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 load app/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.

Celery Tasks

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.yml runs a combined worker and beat service.
  • The celerybeat-schedule file likely stores the periodic task schedule database (managed by Celery Beat).
  • Forecast processing triggers notification evaluation once new predictions are stored.
  • A dedicated dispatch_notifications task runs every 30 minutes to queue push notifications for users with matching rules.

Notifications and Push Subscriptions

The backend exposes authenticated endpoints under /users/me for managing notification rules and Web Push subscriptions.

  • POST /users/me/notifications creates 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}/events retrieves the most recent push payloads queued for that rule.
  • POST /users/me/push-subscriptions registers 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.

Push Delivery Configuration

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.

API Documentation

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

Database Migrations (Alembic)

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 head

In production on Render, migrations are executed during deploy/startup.

MCP Server

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