7.3 KiB
7.3 KiB
MTG Online Backend
A Python FastAPI application that processes Magic: The Gathering card data from MTGJSON and stores it in PostgreSQL, with Redis for caching.
Overview
This project provides a backend API for a Magic: The Gathering Online platform. It downloads and processes MTGJSON v5 dataset dumps, loads them into a PostgreSQL database, and exposes REST endpoints for card data, user authentication, deck management, and game state.
Key Features
- MTGJSON Data Pipeline — Downloads
AllPrintings.psql,AllIdentifiers.json,Keywords.json,CardTypes.json, andAllDeckFiles.zipfrom MTGJSON v5 on startup or via aPOST /refreshendpoint. - Dual PostgreSQL — Two databases:
mtgonlinefor the application (users, decks, auth) andmtgdatafor MTG card data. - Redis Caching — Used for card lookup caching and interaction pipeline state.
- Card Import Feature — Users can import their card collection (fuzzy matching enabled) for deckbuilding constraints.
- REST API —
/docs(Swagger) available at runtime.
Architecture
mtgonline/
├── backend/ # FastAPI application
│ ├── app/
│ │ ├── core/ # Settings, database engines, Redis client
│ │ ├── models/ # SQLAlchemy ORM models (app + MTG)
│ │ ├── routers/ # API route modules
│ │ ├── schemas/ # Pydantic request/response schemas
│ │ ├── services/ # Business logic (MTGJSON manager, card DB, game server)
│ │ └── main.py # FastAPI app entry point
│ ├── scripts/ # Utility scripts (downloads, migrations, checks)
│ ├── Dockerfile
│ └── requirements.txt
├── docker-compose.dev.yml # Development stack (Postgres x2, Redis, Backend)
├── docker-compose.yml # Production stack
├── scripts/ # Shared utility scripts
└── README.md
Data Flow
- On startup, the backend connects to PostgreSQL (both instances) and Redis.
- It checks
mtg_refresh_login themtgdatadatabase for existing data. - If no data exists, it downloads MTGJSON files from
https://mtgjson.com/api/v5/, unzips if needed, and upserts them intomtgdatatables (mtg_sets,mtg_cards, etc.). - The data is then available via REST endpoints.
API Endpoints
Card Import (New)
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/card-import/status |
Get current card import status |
POST |
/api/v1/card-import/ |
Import/update card collection |
DELETE |
/api/v1/card-import/ |
Delete card import |
GET |
/api/v1/card-import/summary |
Get import summary with match results |
Card Import Request Body:
{
"card_names": ["Lightning Bolt", "Shock", "Thoughtseize"]
}
Card Import Response:
{
"message": "Imported 3 cards successfully",
"card_count": 3,
"card_names": ["Lightning Bolt", "Shock", "Thoughtseize"],
"imported_at": "2026-07-24T04:12:00"
}
User Data Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/user-data/profile |
Get user profile |
PUT |
/api/v1/user-data/profile |
Update user profile |
GET |
/api/v1/user-data/collection |
Get user card collection |
GET |
/api/v1/user-data/groups |
List user groups |
GET |
/api/v1/user-data/networks |
List user networks |
GET |
/api/v1/user-data/preferences |
Get user preferences |
PUT |
/api/v1/user-data/preferences |
Update user preferences |
GET |
/api/v1/user-data/activity |
Get user activity log |
GET |
/api/v1/user-data/replays |
List user replays |
GET |
/api/v1/user-data/replays/{replay_id} |
Get replay details |
Deck Management Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/decks/ |
List user decks |
POST |
/api/v1/decks/ |
Create new deck |
GET |
/api/v1/decks/{deck_id} |
Get deck details |
PUT |
/api/v1/decks/{deck_id} |
Update deck |
DELETE |
/api/v1/decks/{deck_id} |
Delete deck |
POST |
/api/v1/decks/{deck_id}/cards |
Add card to deck |
PUT |
/api/v1/decks/{deck_id}/cards/{card_id} |
Update deck card |
DELETE |
/api/v1/decks/{deck_id}/cards/{card_id} |
Remove card from deck |
GET |
/api/v1/decks/{deck_id}/cards |
List deck cards |
POST |
/api/v1/decks/{deck_id}/finalize |
Finalize deck (DRAFT → FINAL) |
POST |
/api/v1/decks/search/cards |
Search cards for deckbuilding |
GET |
/api/v1/decks/precedents/ |
List deck precedents |
POST |
/api/v1/decks/precedents/ |
Create precedent |
GET |
/api/v1/decks/precedents/{precedent_id} |
Get precedent details |
POST |
/api/v1/decks/precedents/{precedent_id}/use |
Use/clone precedent |
GET |
/api/v1/decks/suggestions/ |
List card suggestions |
POST |
/api/v1/decks/suggestions/ |
Add card suggestion |
Quick Start
Prerequisites
- Docker and Docker Compose
Run the Stack
cd /home/wall-o/projects/mtgonline
# Start all services (Postgres x2, Redis, Backend)
docker compose -f docker-compose.dev.yml up -d
# View logs
docker compose -f docker-compose.dev.yml logs -f backend
The backend will automatically download MTGJSON data on first startup (this may take several minutes).
Access
| Service | Address |
|---|---|
| Backend API | http://localhost:5555 |
| Swagger Docs | http://localhost:5555/docs |
| Health Check | http://localhost:5555/health |
| PostgreSQL (app) | localhost:5432 |
| PostgreSQL (MTG) | localhost:5433 |
| Redis | localhost:6379 |
Manual Data Refresh
# Trigger a manual MTGJSON refresh
curl -X POST http://localhost:5555/refresh
Card Import Feature
Users can import their card collection to enable deckbuilding with owned cards. The feature includes fuzzy matching for typos.
Import Cards
curl -X POST http://localhost:5555/api/v1/card-import/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"card_names": ["Lightning Bolt", "Shock", "Thoughtseize"]
}'
Check Import Status
curl http://localhost:5555/api/v1/card-import/status \
-H "Authorization: Bearer <token>"
Get Import Summary
curl http://localhost:5555/api/v1/card-import/summary \
-H "Authorization: Bearer <token>"
Delete Import
curl -X DELETE http://localhost:5555/api/v1/card-import/ \
-H "Authorization: Bearer <token>"
Environment Variables
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
postgresql+asyncpg://mtgonline_user:mtgonline_password@postgres:5432/mtgonline |
Primary database connection |
MTG_DATABASE_URL |
postgresql+asyncpg://mtgonline_user:mtgonline_password@mtgdata:5432/mtgdata |
MTG data database connection |
REDIS_URL |
redis://redis:6379 |
Redis connection |
DATA_DIR |
/app/data |
Directory for MTGJSON files |
DEBUG |
False |
Enable debug logging |
Docker Cleanup
# Stop and remove all containers
docker compose -f docker-compose.dev.yml down
# Remove images and prune
docker system prune -a --volumes
License
MIT