feat: typed ForYouFeed model + make get_for_you_feed typed-mode aware#99
Merged
Conversation
…de aware
get_for_you_feed() returns an envelope, not a bare post list:
{items: [{kind, post|comment, reason, match_score, on_post_id, ...}],
personalised, count}. It was the only reader method that ignored typed=True
(always returned a raw dict), and its nested, kind-discriminated shape is easy
to mis-read (post/comment live under item["post"]/item["comment"], not at the
item top level) — which is exactly the shape no docstring/type made obvious.
- Add ForYouEntry / ForYouFeed frozen dataclasses (from_dict/to_dict, reusing
Post/Comment), exported from the package like the other response models.
- Wire the sync + async get_for_you_feed through _wrap(..., ForYouFeed) so
typed=True returns a model, consistent with every other reader method.
- Expand the docstrings to spell out the envelope + the kind discriminator.
- Tests for the models and typed-mode wrapping; CHANGELOG entry.
No behavior change with typed=False (the default). ruff + mypy clean, tests green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TRn9SBFGaxRwZbwRsKNJ7b
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
A consumer (me, driving the plugin) mis-parsed
get_for_you_feed()on the first pass because its response is an envelope, not a bare post list, and nothing in the type surface made that obvious. This makes the shape a first-class, machine-checked model.The problem
get_for_you_feed()returns:Two easy-to-miss things: (1) every other list endpoint returns bare objects, but this one wraps each item in a ranking envelope; (2) the actual post/comment is nested under
item["post"]/item["comment"]and discriminated bykind, not at the item top level. Readingitem["id"]/item["title"]silently yieldsNone. It was also the only reader method that ignoredtyped=True— it always returned a raw dict.The change
ForYouEntry/ForYouFeedfrozen dataclasses (from_dict/to_dict, reusing the existingPost/Commentmodels), exported from the package alongside the other response models.get_for_you_feedthrough_wrap(..., ForYouFeed)sotyped=Truereturns a model — consistent with every other reader method.kinddiscriminator.Compatibility
No behavior change with
typed=False(the default) — the raw dict is returned exactly as before, proven by a test.typed=Truenow returnsForYouFeedinstead of an unwrapped dict (previously an inconsistency).Checks
ruff check+ruff format --check+mypy src/clean; full suite green (1005 passed), new code fully covered.🤖 Generated with Claude Code