fix: fetch single event by uid directly (#137, #138)#236
Open
Olen wants to merge 10 commits into
Open
Conversation
…rs (#137, #138) `get_event()` previously routed through `_get_entity()`, which called `get_events()` (with no args) to populate a cache and then searched that cache. This had two unrelated-looking-but-shared-root-cause bugs: - Events past the `max_events=100` default were unreachable (#137). - Scheduled events (where `include_scheduled=False` is the default) were unreachable (#138). Switch `_get_entity()` for events to fetch directly from the singular `sponds/{uid}` endpoint, which has neither limit. Verified live against the Spond API: returns 200 + event JSON for real ids, 404 for unknown ids. Map 404→KeyError to preserve the existing exception contract. Group lookups are unchanged — `get_groups()` has no max/filter defaults, and the cache+search behaviour is still useful there. Notes: - The singular endpoint omits the `comments` field that the list endpoint returns; this field is not in `_event_template` and nothing internal reads it. Callers that need comments should fetch them separately. - `update_event()` also calls `_get_entity(EVENT, ...)`; this change incidentally fixes a latent same-class bug there too.
Pass `?includeComments=true` so the singular endpoint returns the `comments` field that the list endpoint includes by default. Verified live: response shape now matches the list endpoint exactly (29 keys vs 29 keys, set difference is empty). Keeps `get_event()` output a drop-in replacement for `[e for e in get_events() if ...][0]`.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes Spond.get_event(uid) so it can return events that are beyond the default max_events=100 window or marked as scheduled. Previously _get_entity() for events routed through get_events() (with default filters), making such events unreachable. The fix replaces that path with a direct call to the singular sponds/{uid} endpoint and surfaces 404s as KeyError to preserve existing semantics. update_event() benefits from the same fix transparently.
Changes:
- In
_get_entity(), route event lookups to a new_fetch_event_by_uid()helper that callsGET sponds/{uid}(withincludeComments=trueto keep response shape close to list elements); group lookups remain on the cached path. - Add a
KeyErrorguard for the empty-cache group case (the dependency from stacked PR #235). - Replace the cache-based event tests with HTTP-mocked tests covering 200/404/500 paths and add a group-empty
KeyErrortest; update the manual example to exercise the new path.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| spond/spond.py | Routes _get_entity for events through new _fetch_event_by_uid (singular endpoint, 404→KeyError, other errors→ValueError); keeps group cache path with empty-cache KeyError guard. |
| tests/test_spond.py | Replaces cached-list event tests with HTTP-mocked happy-path/404/500 tests; adds empty-groups KeyError test. |
| examples/manual_test_functions.py | Adds a get_event(events[0]["id"]) step and reuses e for the existing attendance export. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
7 tasks
Olen
added a commit
that referenced
this pull request
May 14, 2026
Four fixes raised in Copilot's review of #241: - Spond class example: guard `await s.get_groups()` with `or []` so iterating the result is safe when the account has no groups (the return type is documented as `list[JSONDict] | None`). - `get_events()` docstring: removed the forward-looking claim that `get_event(uid)` "queries the singular endpoint directly" — that's only true after #236 lands. Replaced with current behavior plus reference to #236 as the planned change. - `get_events()` `subgroup_id` parameter: docstring said `subgroupId` API parameter, but the code sends `subGroupId` (capital G, line 387). Aligned the docstring with the actual API param. - `update_event()` Returns section: was declared `JSONDict` but the method (due to known bug #239) currently returns `self.events`, a `list[JSONDict] | None`. Updated the Returns type to match the current contract, with the bug and workaround called out in Notes.
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #137 and #138 with a single root-cause fix.
get_event(uid)previously routed through_get_entity(), which fetched a list viaget_events()(with no args) and searched it. That list inheritsget_events()'s defaults:max_events=100→ events past the 100th are unreachable (Spond.get_event()may not return an event if more than 100 events are available #137)include_scheduled=False→ scheduled events are unreachable (Spond.get_event()doesn't return 'scheduled' events, i.e. where invites are set to send in the future. #138)Switch
_get_entity()for events to fetch from the singularsponds/{uid}?includeComments=trueendpoint directly. Neither limit applies. Group lookups stay on the cache+search path — they don't have these defaults.Live verification against the Spond API
Probed the endpoint before coding (and re-verified the fixed code) using credentials from
../spond-kalender:After adding
?includeComments=true, the singular response shape matches the list-endpoint element exactly: 29 keys vs 29 keys, set difference is empty.get_event()output is a drop-in replacement for[e for e in get_events() if e["id"]==uid][0].Why
?includeComments=trueinstead of a second API callInitially the plan was two calls (singular +
/sponds/{uid}/comments) and merging. Probed three options first:?includeComments=true✅ — returnscommentsinline, one call, exact list-endpoint shape/sponds/{uid}/comments✅ — works as a separate sub-resource, but requires merging/sponds/{uid}/posts❌ — 404One call with a query param is strictly cleaner.
Incidental fix
update_event()also calls_get_entity(EVENT, ...), so it had the same latent bug for events outside the cached window. Fixed automatically by this refactor.Stacked behind #235
Branched off
fix/get-entity-handles-empty-results. Merge #235 first, then this. (PR base retargeted tomainso CI fires; once #235 merges, the diff cleans up automatically.)Test plan
?includeComments=trueadds the field, bogus id returns 404get_event(real_id)works, returns 29-key dict matching list-endpoint shape,get_event(bogus_id)raises KeyErrorpytest— 22 tests passruff check— cleanruff format --check— cleanexamples/manual_test_functions.pyend-to-end before merge🤖 Generated with Claude Code