Add Tumblr error handling, response validation, and typed SocialPostingVertical#83
Add Tumblr error handling, response validation, and typed SocialPostingVertical#83aaronjae22 wants to merge 1 commit intomainfrom
Conversation
| ) -> dict[str, Any]: | ||
| return super().fetch_token(code, authorization_response, include_client_id) | ||
|
|
||
| def _validate_user_info_response(self, data: Any) -> dict[str, Any]: |
There was a problem hiding this comment.
This is exactly what JSON Schema is for ! probably not worth it for this project, but validating a bunch of JSON in python code is a pain isn't it
| super().__init__(f'Cannot fetch data from {service_name}: {message}') | ||
|
|
||
|
|
||
| class TumblrAPIError(Exception): |
There was a problem hiding this comment.
This seems too specific if we were going to invest in many more connectors for this library. How would we handle TumblrAPIError differently from StravaAPIError? It makes it harder to write code that uses this library - new exceptions get defined when new connectors get added, and then code using this library has to get written to handle new exceptions.
Choosing how to categorize exceptions and how to group them is an interface design question which depends on how a library is going to be used, of course - might be fun to discuss tomorrow or sometime.
Closes #22
Closes #45
Closes #62
The Tumblr integration returned raw JSON, and we were not validating what Tumblr sent back, and any API failure would surface as a cryptic Python error instead of something useful. This brings it up to the same standard as Strava.
Added
TumblrAPIErrorso Tumblr failures are identifiable and have useful messages. Before, a 401 from Tumblr would just be a genericHTTPError, and a malformed response would crash with something likeAttributeError: 'NoneType' object has no attribute 'get'. Now we getTumblrAPIError: Tumblr API error: ...with the status code and a description of what went wrong.Both
user/infoanduser/dashboardresponses are now checked for the expected structure before anything tries to read from them. If Tumblr returns 200 but the payload is weird (missing keys, wrong types), it raisesTumblrAPIErrorright away instead of silently producing garbage data.Added
parse_social_posting_verticalthat turns a raw Tumblr post into aSocialPostingVerticalmodel — mapping things like post ID, URL, timestamp, tags, note count, text blocks, and media URLs into the standard schema. Same approach Strava already uses.fetch_social_posting_verticalnow returns(parsed_verticals, raw_posts)instead of just a list of dicts. Matches Strava's pattern so consumers get both structured data and raw JSON.The updated testsuite covers error wrapping, validation, and parsing.
Pagination #8 is out of scope here.
These new features don't change anything in the demoing approach.
Structured output example
{ "pardner_object_id": "e6971577c78b49c6963cabdf6cebf529", "service_object_id": "810233790391877632", "creator_user_id": "t:iE-yd_-VKiQ4tRh4kkzLeg", "data_owner_id": "", "service": "Tumblr", "vertical_name": "social_posting", "created_at": "2026-03-05 08:25:56", "url": "https://angelswouldnthelpyou.tumblr.com/post/810233790391877632/david-lynch-and-sheryl-lee-twin-peaks-fire-walk", "abstract": "David Lynch and Sheryl Lee \nTwin Peaks Fire Walk With Me 1992", "associated_media": [ { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s1280x1920/ae567fc16c7d32e5359142ead8c14c8c43225c70.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s640x960/82e3c61df944a7acdbee8da566ad5001411912b8.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s540x810/f1a2d05bade2e5d0a9e6cc17050fac2475214b49.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s500x750/d6fbe2d7c7d4746aab542717af43e8aeaabd84dc.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s400x600/9528b99630774c979fd9afe77f41a09f27eef657.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s250x400/c8b9576de6f9f79b52c5fcf5952a42115b8d2031.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s100x200/62762543123ff8cad1d4467159d8d73ad827ed05.jpg" }, { "media_type": "image", "url": "https://64.media.tumblr.com/d020bdb6ba1834edc05117b2f7ef3f84/37d16fd99f65962b-60/s75x75_c1/1e79db2eb2321ea7f1bdcdd309634206d38819b4.jpg" } ], "interaction_count": 16, "keywords": [ "twin peaks fire walk with me", "david lynch", "sheryl lee", "laura palmer", "twin peaks", "cinema" ], "shared_content": [], "status": "public", "text": "David Lynch and Sheryl Lee \n\nTwin Peaks Fire Walk With Me 1992", "title": null }