import asyncio import json import os import re from typing import TypedDict, List, Dict, Any import httpx from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = [ "http://drafter.cadel.me", "https://drafter.cadel.me", "http://localhost", "http://localhost:1234", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) def discover_sets(): # find all set directories sets = [] for root, dirs, files in os.walk("data/sets"): for dir in dirs: sets.append(dir) return sets @app.get("/sets") def read_sets(): sets = discover_sets() return {"sets": sets} @app.get("/sets/{set_name}/cards") def read_item(set_name: str): if set_name not in discover_sets(): return {"error": "Set not found"} card_data_path = os.path.join("data", "sets", set_name, "card-data.json") with open(card_data_path) as f: card_data = json.load(f) return {"data": card_data} @app.get("/sets/{set_name}/ratings") def read_item(set_name: str): if set_name not in discover_sets(): return {"error": "Set not found"} card_ratings_path = os.path.join("data", "sets", set_name, "card-ratings-all.json") with open(card_ratings_path) as f: card_data = json.load(f) return {"data": card_data} @app.get("/sets/{set_name}") def read_item(set_name: str): if set_name not in discover_sets(): return {"error": "Set not found"} card_data_path = os.path.join("data", "sets", set_name, "card-data.json") with open(card_data_path) as f: card_data = json.load(f) card_ratings_path = os.path.join("data", "sets", set_name, "card-ratings-all.json") with open(card_ratings_path) as f: ratings_data = json.load(f) return {"code": set_name, "data": {"cards": card_data, "ratings": ratings_data}} USER_ID_REGEX = r'user_history\/(.*)\?' class DraftMeta(TypedDict): expansion: str format: str timestamp: str draft_id: str async def get_drafts_from_17lands(user_id: str) -> List[DraftMeta]: url = f"https://www.17lands.com/user/data/{user_id}" drafts = [] async with httpx.AsyncClient() as client: res = await client.get( url, headers={ "Accept": "application/json" } ) print(res) json_res = res.json() for draft in json_res["drafts"]: drafts.append({ "expansion": draft["expansion"], "format": draft["format"], "timestamp": draft["first_event_server_time"], "draft_id": draft["id"], }) return drafts async def get_draft_data(draft_id:str, client: httpx.AsyncClient): url = f"https://www.17lands.com/data/draft?draft_id={draft_id}" res = await client.get( url, headers={ "Accept": "application/json" } ) print(res) print(res.text) print(res.json()) return res.json()["picks"] async def get_all_draft_data(draft_ids: List[str]) -> Dict[str, Any]: async with httpx.AsyncClient() as client: tasks = [get_draft_data(draft_id, client) for draft_id in draft_ids] results = await asyncio.gather(*tasks) return { draft_id: {"picks": result["picks"]} for draft_id, result in zip(draft_ids, results) } @app.get("/drafts") async def read_item(history: str): user_id = re.search(USER_ID_REGEX, history).group(1) all_drafts = await get_drafts_from_17lands(user_id) all_draft_data = await get_all_draft_data([draft["draft_id"] for draft in all_drafts]) drafts = [ { "set_code" : draft["expansion"], "format" : draft["format"], "timestamp" : draft["timestamp"], "draft_data" : all_draft_data[draft["draft_id"]], } for draft in all_drafts ] print(drafts) return {"drafts":drafts}