The Standings API provides VCT (Valorant Champions Tour) standings data for a given year, scraped from vlr.gg. It returns standings grouped by circuit (e.g., North America, EMEA, Brazil, etc.), with teams ordered by total points and assigned sequential ranks.
- URL:
/api/v1/standings/{year} - Method: GET
- Parameters:
year(path, integer): The VCT year (2021 to current year)
- Response: JSON object with year and list of circuits, each containing teams with details.
{
"year": 2021,
"circuits": [
{
"region": "North America Circuit",
"teams": [
{
"name": "Sentinels",
"id": 2,
"logo": "https://owcdn.net/img/62875027c8e06.png",
"rank": 1,
"points": 775,
"country": "United States"
},
// ... more teams
]
},
// ... more circuits
]
}- Scraping: Fetches HTML from
https://www.vlr.gg/vct-{year}/standingsusing httpx and parses with BeautifulSoup. - Parsing: Extracts circuits from
div.eg-standing-group, then teams from tables within, assigning ranks sequentially. - Caching: Endpoint checks Redis cache first (
standings_{year}key). If not present, scrapes fresh data and returns it. Cache is populated daily at midnight by a cron job for the current year only. - Validation: Year must be between 2021 and current year.
- Error Handling: Returns HTTP 422 for invalid years, 500 for scraping failures.
app/constants.py: AddedSTANDINGS_URLapp/schemas/standings.py: DefinedTeamStanding,CircuitStanding,Standingsmodelsapp/services/standings.py: Implementedstandings_list()for scraping and parsingapp/api/v1/endpoints/standings.py: Created endpoint with cache-first logicapp/api/v1/api.py: Registered standings routerapp/schemas/__init__.py: Imported new schemasapp/cron.py: Addedstandings_cron()to cache current year's data daily at 00:00
- Cache Strategy: Read-only in endpoint (no cache writes on requests) to avoid slow first requests; background cron ensures cache freshness.
- Year Range: Dynamic upper bound (current year) to support future years without code changes.
- Parsing: Handles all circuits and teams, including collapsed ones in HTML.
- Cron Frequency: Daily at midnight to balance freshness and resource usage, focusing only on current year.