From 027fae65a477b50f416d36edd84ad3bdcb71cede Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Thu, 5 Mar 2026 01:18:16 -0500 Subject: [PATCH] perf(cses): cache API token across submits Problem: every `:CP submit` on CSES ran the full 5-request login flow (~1.5 s overhead) even when the token from a previous submit was still valid. Solution: persist the API token in credentials via a `credentials` ndjson event. On subsequent submits, validate the cached token with a single GET before falling back to the full login. --- scrapers/cses.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/scrapers/cses.py b/scrapers/cses.py index b2e845a..2c2c2ce 100644 --- a/scrapers/cses.py +++ b/scrapers/cses.py @@ -342,6 +342,19 @@ class CSESScraper(BaseScraper): return None return token + async def _check_token( + self, client: httpx.AsyncClient, token: str + ) -> bool: + try: + r = await client.get( + f"{API_URL}/login", + headers={"X-Auth-Token": token, **HEADERS}, + timeout=TIMEOUT_S, + ) + return r.status_code == 200 + except Exception: + return False + async def submit( self, contest_id: str, @@ -356,11 +369,30 @@ class CSESScraper(BaseScraper): return self._submit_error("Missing credentials. Use :CP login cses") async with httpx.AsyncClient(follow_redirects=True) as client: - print(json.dumps({"status": "logging_in"}), flush=True) + token = credentials.get("token") + + if token: + print(json.dumps({"status": "checking_login"}), flush=True) + if not await self._check_token(client, token): + token = None - token = await self._web_login(client, username, password) if not token: - return self._submit_error("Login failed (bad credentials?)") + print(json.dumps({"status": "logging_in"}), flush=True) + token = await self._web_login(client, username, password) + if not token: + return self._submit_error("Login failed (bad credentials?)") + print( + json.dumps( + { + "credentials": { + "username": username, + "password": password, + "token": token, + } + } + ), + flush=True, + ) print(json.dumps({"status": "submitting"}), flush=True)