Local fantasy football statistics assistant. Query seeded NFL/fantasy data through a read-only API, or chat with a local LLM for open-ended analysis.
Streamlit → RAG → FastAPI (read-only) → SQLite
RAG → Ollama → Gemma
Factual questions (stats, matchups, injuries) are answered from the database. Conversational prompts go to Gemma.
- Docker (recommended): Docker Desktop or Docker Engine with Compose v2
- Or local Python 3.11+ and Ollama with Gemma (
ollama pull gemma2:2b)
The Docker image includes R, ffanalytics, and rpy2 for the Mock Draft tab — no separate R install when using Compose.
docker compose up --buildFirst startup pulls gemma2:2b into the Ollama container (can take a few minutes). Then open:
Optional: API docs at http://localhost:8000/docs
# Stop
docker compose down
# Reset DB + models (re-seeds fantasy football sample data)
docker compose down -vServices:
| Service | Role | Host port |
|---|---|---|
ui |
Streamlit (your browser connects here) | 8501 |
api |
FastAPI read-only API | 8000 |
ollama |
Gemma inference | 11434 |
Inside the Compose network, the UI talks to http://api:8000 and http://ollama:11434.
cd StatShift
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python scripts/init_db.py# 1 — API
uvicorn api.main:app --reload
# 2 — UI
streamlit run app/streamlit_app.py
# 3 — Ollama (if not already running)
ollama serveOr use helper scripts:
chmod +x scripts/run_api.sh scripts/run_ui.sh
./scripts/run_api.sh
./scripts/run_ui.shOpen http://127.0.0.1:8501 and ask about players, weekly matchups, injuries, or PPR scoring from the seeded data.
If you previously ran an older build with different seed data, delete data/statshift.db or run docker compose down -v before re-initializing.
With the stack running (docker compose up --build), open http://localhost:8501 → Mock Draft. The player pool comes from ffanalytics (projections for Standard / Half-PPR / PPR plus ADP). R and ffanalytics are already in the ui image.
The cache lives in the statshift_data volume at /app/data/ffanalytics_players.json (24-hour TTL). It survives container restarts until you run docker compose down -v.
First visit: opening Mock Draft or clicking Refresh player pool triggers a scrape (often several minutes). Later visits use the cache.
Optional — pre-warm the cache before using the UI:
# One-off sync service (stack does not need to be up)
docker compose --profile sync run --rm ffanalytics-sync
# Or, while ui is running
docker compose exec ui python scripts/sync_ffanalytics_players.pyAfter rebuilding the image (docker compose up --build), run a sync again if ffanalytics or R packages changed.
python -m unittest discover -s tests -vCI runs the same suite on pull requests and pushes to main (ffanalytics parsing tests do not call R).
Optional .env overrides:
OLLAMA_MODEL=gemma2:2b
OLLAMA_BASE_URL=http://127.0.0.1:11434
API_BASE_URL=http://127.0.0.1:8000| Endpoint | Description |
|---|---|
GET /health |
Service + DB check |
GET /documents |
List documents |
GET /documents/{id} |
Single document |
GET /search?q=... |
FTS search for RAG |
GET /categories |
Distinct categories |
POST, PUT, PATCH, and DELETE return 405 — writes are blocked at the API layer; SQLite is opened in read-only mode for queries.
| Category | Examples |
|---|---|
player |
McCaffrey workload, Chase targets, Kelce red-zone usage |
team |
Bills pace and scoring |
matchup |
Week 12 RB defensive matchups |
injury |
Week 15 practice reports |
league |
PPR scoring, passing leaders |