Repository navigation
fix(auth): reload token file when expiry cannot be determined - #672
Conversation
A shared token whose expires_at is missing or not Unix epoch seconds made OAuth2Token.is_expired() return None, which the token-file reload check treated as "not expired" — workers then silently kept a stale token until the backend returned 401s. Treat unknown expiry as expired so a malformed file keeps being re-read, warn in set_token when expires_at is not epoch seconds, and document that expires_at is timezone-independent epoch seconds (coordinator and workers may run in different timezones). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: lino <lino@rapidata.ai>
ReviewSolid, well-scoped fix. The core idea — only treat a token as "not expired" when A few things worth a look: 1. Please double-check the core premise against the pinned def is_expired(self, leeway=60):
expires_at = self.get('expires_at')
if not expires_at:
return None
expires_at -= leeway
return expires_at < time.time()That returns If that's the case:
Since this is the entire justification for the change, I'd suggest pinning down the actual behavior with a real unit test against the installed 2. Minor: 3. Test coverage. Nice catch overall on the |
Context
Follow-up review of the new Distributed Training docs: checked whether coordinator and workers running in different timezones can break token sharing.
The SDK-to-SDK path is timezone-safe.
expires_atis produced by authlib as Unix epoch seconds (int(time.time()) + expires_in) and checked againsttime.time()— both UTC-based regardless of local timezone. Verified empirically: a token minted underTZ=Asia/Tokyoand read underTZ=America/Los_Angelesshows exactly the same remaining validity.But the documented DIY path has a real trap. The docs say "if you produce tokens without the SDK … add
expires_atyourself" without specifying the format. If someone writes a formatted datetime string (or local wall-clock arithmetic),OAuth2Token.is_expired()returnsNone, and the reload check inrest.pytreated
Noneas "not expired", so a worker silently never re-read the token file and rode the stale token into 401s — surfacing exactly when people hand-roll timestamps across timezones.Changes
rest.py(+openapi/templates/rest.mustache, kept in sync):_reload_token_from_file_if_expirednow only skips the re-read whenis_expired()is explicitlyFalse— unknown expiry re-reads the file instead of trusting the token forever.set_tokenwarns whenexpires_atis present but not parseable as epoch seconds (numeric strings stay silent, matching authlib).docs/distributed_training.md: states thatexpires_atis timezone-independent Unix epoch seconds and showsexpires_at = time.time() + expires_infor the curl path.Verification
expires_at→ now re-read (previously never);set_tokenwarns once for ISO, silent for int and numeric string.uv run pyright src/rapidata/rapidata_client→ 0 errors.uv run --group docs mkdocs build→ success.🔗 Session: https://session-a17860c3.poseidon.rapidata.internal/
🤖 Generated with Claude Code