A Python backend that tracks England's 2026 World Cup campaign in real time. Fixtures, squad, group standings and live scores — automatically refreshed throughout the tournament.
Live API: (https://england-wc-2026-live-api.onrender.com/docs)
The API ingests live match data from football-data.org and stores it in a PostgreSQL database. A scheduled cron job triggers a full data refresh every 6 hours, keeping scores, standings and fixture statuses up to date throughout the tournament.
| Layer | Technology |
|---|---|
| Framework | FastAPI |
| Database | PostgreSQL |
| ORM | SQLAlchemy 2.0 |
| Migrations | Alembic |
| Validation | Pydantic v2 |
| HTTP Client | httpx |
| Task Queue | Celery + Redis |
| Testing | pytest + FastAPI TestClient |
| Deployment | Render |
| Data Source | football-data.org API |
┌─────────────────┐
│ football-data │
│ .org API │
└────────┬────────┘
│ httpx
┌────────▼────────┐
│ Ingest Service │ ◄── Cron Job (every 6hrs)
│ ingest.py │ ◄── POST /ingest/trigger
└────────┬────────┘
│ SQLAlchemy upsert
┌────────▼────────┐
│ PostgreSQL │
│ fixtures │
│ squad_players │
│ group_standing │
└────────┬────────┘
│
┌────────▼────────┐
│ FastAPI App │
│ REST Endpoints │
└─────────────────┘
| Method | Endpoint | Description |
|---|---|---|
| GET | /fixtures |
All England fixtures. Filter by ?status=TIMED or ?status=FINISHED |
| GET | /fixtures/{id} |
Single fixture by ID |
| GET | /fixtures/next |
England's next upcoming match |
| GET | /fixtures/form |
Last 5 results with scorelines |
| GET | /squad |
Full England squad |
| GET | /standings |
Group L table |
| POST | /ingest/trigger |
Manually trigger a data refresh |
Full interactive documentation available at /docs.
Prerequisites: Python 3.11+, Docker Desktop
1. Clone the repo
git clone https://github.com/Shane-Libera7/england-wc2026-api
cd england-wc2026-api2. Create and activate a virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate3. Install dependencies
pip install -r requirements.txt4. Set up environment variables
cp .env.example .env
# Add your football-data.org API key to .env5. Start PostgreSQL and Redis
docker compose up -d6. Run database migrations
alembic upgrade head7. Seed initial data
python -m app.services.ingest8. Start the API
uvicorn app.main:app --reloadVisit http://localhost:8000/docs for the interactive API documentation.
Run tests
pytest -vUpsert over insert — all ingest operations use PostgreSQL's ON CONFLICT DO UPDATE so re-running the ingest never produces duplicates, only updates.
Lean schema — tables only store the columns that endpoints actually return. No unused data, no premature optimisation.
Celery architecture — background jobs are built with Celery + Redis. In a paid production environment this enables switching to 60-second polling during live matches. On the free tier, a cron job replaces the beat scheduler.
Test isolation — the test suite uses an in-memory SQLite database with dependency injection overrides, keeping tests fast and completely isolated from production data.
Match data is provided by football-data.org free tier. Live scores have an approximate 2–5 minute delay.
Shane Libera — self-taught backend developer based in London.