Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Original Repository: https://github.com/SwapnikKatkoori/sleeper-api-wrapper
4. [Notes](#notes)
5. [Dependencies](#depends)
6. [License](#license)
7. [FastAPI Web Demo](#fastapi)

<a name="roadmap"></a>
# Project Roadmap
Expand Down Expand Up @@ -50,3 +51,28 @@ This package is intended to be used by Python version 3.8 and higher. There migh
<a name="license"></a>
# License
This project is licensed under the terms of the MIT license.

<a name="fastapi"></a>
# FastAPI Web Demo

A simple FastAPI app lives under `webapp/` to showcase the wrapper in a browser for league `1257507151190958081`. It is intentionally lean but organized for extension.

### Run locally
```
pip install -e .
pip install "fastapi>=0.115" "uvicorn[standard]>=0.30" "jinja2>=3.1" "python-multipart>=0.0.9"
uvicorn webapp.main:app --reload
```

Override the league or sport via environment variables:
```
export LEAGUE_ID=YOUR_LEAGUE_ID
export SPORT=nfl
export SCORE_TYPE=pts_ppr
```

Pages:
- `/` League dashboard (standings, managers, matchups, recent transactions).
- `/rosters` Per-manager rosters with starters/bench.
- `/draft` Draft results for the league's primary draft.
- `/players` Player stats for the season; search or use trending adds/drops.
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ build-backend = "poetry.core.masonry.api"
pytest = "*"
pytest-mock = "*"
tox = "^4.31.0"
fastapi = "^0.115.0"
uvicorn = {extras = ["standard"], version = "^0.30.0"}
jinja2 = "^3.1.0"
python-multipart = "^0.0.9"
pydantic-settings = "^2.2.0"
1 change: 1 addition & 0 deletions webapp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# FastAPI proof-of-concept package for Sleeper league views.
23 changes: 23 additions & 0 deletions webapp/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from functools import lru_cache

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
"""Configuration for the FastAPI proof of concept."""

league_id: str = "1257507151190958081"
sport: str = "nfl"
score_type: str = "pts_ppr"
league_cache_ttl_seconds: int = 300
players_cache_ttl_seconds: int = 21600
stats_cache_ttl_seconds: int = 900

class Config:
env_file = ".env"


@lru_cache(maxsize=1)
def get_settings() -> Settings:
"""Returns cached settings instance."""
return Settings()
70 changes: 70 additions & 0 deletions webapp/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from fastapi import Depends, FastAPI, Query, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

from webapp.config import Settings, get_settings
from webapp.services.sleeper_client import SleeperClient, get_client

app = FastAPI(title="Sleeper League Dashboard", version="0.1.0")

templates = Jinja2Templates(directory="webapp/templates")
app.mount("/static", StaticFiles(directory="webapp/static"), name="static")


def client_dependency(settings: Settings = Depends(get_settings)) -> SleeperClient:
return get_client(settings)


@app.get("/", response_class=HTMLResponse)
def league_dashboard(
request: Request,
week: int | None = Query(default=None, description="Override week to view"),
client: SleeperClient = Depends(client_dependency),
):
data = client.league_dashboard(week=week)
return templates.TemplateResponse(
"dashboard.html", {"request": request, "title": "League Dashboard", **data}
)


@app.get("/rosters", response_class=HTMLResponse)
def rosters(
request: Request,
client: SleeperClient = Depends(client_dependency),
):
data = client.roster_view()
return templates.TemplateResponse(
"rosters.html", {"request": request, "title": "Rosters", **data}
)


@app.get("/draft", response_class=HTMLResponse)
def draft(
request: Request,
client: SleeperClient = Depends(client_dependency),
):
data = client.draft_results()
return templates.TemplateResponse(
"draft.html", {"request": request, "title": "Draft Results", **data}
)


@app.get("/players", response_class=HTMLResponse)
def players(
request: Request,
q: str | None = Query(default=None, description="Player name search"),
season: str | None = Query(default=None, description="Season year for stats"),
add_drop: str = Query(default="add", description="Trending add or drop feed"),
client: SleeperClient = Depends(client_dependency),
):
data = client.player_stats(query=q, season=season, add_drop=add_drop)
return templates.TemplateResponse(
"players.html",
{"request": request, "title": "Player Stats", "query": q, "add_drop": add_drop, **data},
)


@app.get("/health")
def health() -> dict:
return {"status": "ok"}
1 change: 1 addition & 0 deletions webapp/services/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Services for fetching and transforming Sleeper data for the web app.
Loading