Skip to content

Conversation

@aborem
Copy link
Collaborator

@aborem aborem commented Jul 17, 2025

Closes #4

Creates base class for transfer services. It extends OAuth2Session from requests_oauthlib, which we should use after all since it (alongside its dependency oauthlib) builds out a lot of security features and standardization in how requests are made.

Note there's no data storage baked into the class. This is on purpose since using our data stores should be optional for anyone who has their own solution. I plan on using package extras (i.e., optional-dependencies) for this.

I had to make a few decisions about how to structure the library and dev environment. I think those are all documented below (some, like pytest, are pretty self-evident so I didn't add a justification):

  • pytest for testing
  • using pylock.toml: standard that aims to replace requirements.txt, recommended by the official python packaging user guide
  • type hints (and mypy for type checking): as far as I know, this is pretty standard and makes development and onboarding way faster. I plan on adding a config file for mypy to standardize type checking (Set linting rules and add to dev environment and dependencies #13), but I'm just using the default configs for now
  • ruff for linting: using default configs for now, but still need to make config file (Type checking enforcement in dev environment #15)
  • To build the library, run commands in my virtual environment, and update pyproject.toml and pylock.toml, I've been using uv, which has been very simple and easy to use. It does maintain a platform specific lockfile (uv.lock), but it can be exported to pylock.toml super easily, which is not platform specific. Anyone else contributing to the library could ignore uv.lock and just use pylock.toml to set up their local environment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary to expose type hints when other code imports our library. The filename change is misleading: it just thinks it's the same since tests/__init.py was empty before. I deleted it since we don't need tests to be a module.

@aborem aborem marked this pull request as draft July 17, 2025 19:27
@aborem aborem marked this pull request as ready for review July 17, 2025 19:38
@aborem aborem requested a review from lisad July 17, 2025 19:38
Copy link
Member

@lisad lisad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've no objection to uv.lock, but I wonder if pylock.toml is needed if uv is supposed to make other packaging tools unneeded?

@aborem
Copy link
Collaborator Author

aborem commented Jul 18, 2025

You need to have uv installed to import from uv.lock, but several packaging tools (pip, PDM, pipenv, etc.) can now read pylock.toml so it's a bit more flexible and probably good to have!

@aborem aborem merged commit ba84cc6 into main Jul 18, 2025
@aborem aborem deleted the aborem/base-client-session-classes branch July 18, 2025 14:45
aborem added a commit that referenced this pull request Jul 25, 2025
Closes #30 and discussed in
dtinit/pardner-site#10 (comment)

* Creates stateless OAuth functions in `src/pardner/stateless/base.py`,
which are adapted from the base service transfer class and its methods
created in #24 #16 . Eventually other stateless functions will use these
to make their requests (they're essentially wrappers for these core
ones).
* Extracts common logic and helpers in tests into conftest.py. Also
needed to create new directories and modules in the test directory

This doesn't change anything about the existing classes because using a
class instance implies that you're okay with state, so making those
optionally stateless is not necessary.
aborem added a commit that referenced this pull request Aug 14, 2025
Closes #7

- There is a limit of 20 posts at a time for fetching Tumblr posts, this
PR only implements fetching the initial 20. In the future, we'll make
recurring requests to fetch more (#8).
- If we didn't get an 20X response, we raise an error with the message
that was passed in the non-20X response. This should handle most cases
for unsuccessful Tumblr responses, but I'll do a more in depth
investigation in #22.
- Finally, we do minimal parsing of the data that we send back to the
caller of the method. In the future, I'd like to have an optional
argument that enables filtering out of some data and validate it using
something like
[jsonschema](https://python-jsonschema.readthedocs.io/en/stable/) (#45).
I've included a sample of what you could expect by calling the function
below.

<details>
<summary>Sample response (it's A LOT)</summary>
<br />

```json
[
  {
    "type": "blocks",
    "original_type": "regular",
    "is_blocks_post_format": false,
    "blog_name": "sergle",
    "blog": {
      "name": "sergle",
      "title": "★",
      "description": "<b>sergleicious definition make them boys go loco </b> \n\nMy art / personal blog, may also contain traces of:\n</b>\n★ Every post I've ever laughed at\n★ Bad anime\n★ Every thought I've ever had\n★ Good anime (less often)\n★ Talking About Podcasts™\n★ Whatever I want\n</b>\n(28 / she/her / 90% hair, 10% anxiety)\n\n!my artwork is not for the consumption of terfs! get your bitch ass outta here lmao\n\n<a href=\"http://sergle.tumblr.com/tagged/sergle+art\"><img src=\"https://puu.sh/sPlyP/92408b0ec3.png\"></a>\n<a href=\"http://sergle.tumblr.com/commissions\"><img src=\"https://puu.sh/sPlJc/19c1f1c656.png\"></a>\n<a href=\"http://sergle.tumblr.com/ask\"><img src=\"https://puu.sh/sPlO8/91bd47b61d.png\"></a>\n<a href=\"http://sergle.tumblr.com/faq\"><img src=\"https://puu.sh/sPlR8/b09e4bde72.png\"></a>\n<a href=\"https://www.paypal.com/paypalme/sergleicious\"><img src=\"https://puu.sh/sPlYi/424a81efb4.png\"></a>\n<a href=\"https://www.patreon.com/sergle\"><img src=\"https://puu.sh/ERoNO/2e8a7a8213.png\"></a>\n<a href=\"https://www.etsy.com/shop/SergleShop\"><img src=\"https://puu.sh/sPmWA/ef7100d809.png\"></a>\n<a href=\"http://sergle.tumblr.com/address\"><img src=\"https://puu.sh/BKO8T/0473f9e9a5.png\"></a>",
      "url": "https://sergle.tumblr.com/",
      "uuid": "t:qQTSpN0WbpXWcfhk0hlr-w",
      "updated": 1755092025,
      "tumblrmart_accessories": {},
      "can_show_badges": true
    },
    "id": 790290378339352600,
    "id_string": "790290378339352581",
    "is_blazed": false,
    "is_blaze_pending": false,
    "can_ignite": false,
    "can_blaze": false,
    "post_url": "https://sergle.tumblr.com/post/790290378339352581/teaboot-teaboot-teaboot-teaboot-teaboot",
    "parent_post_url": "https://goodfriendo.tumblr.com/post/790265946759675905/teaboot-teaboot-teaboot-teaboot-teaboot",
    "slug": "teaboot-teaboot-teaboot-teaboot-teaboot",
    "date": "2025-07-28 05:13:56 GMT",
    "timestamp": 1753679636,
    "state": "published",
    "reblog_key": "UlJEGlIr",
    "tags": [
      "my god"
    ],
    "short_url": "https://tmblr.co/Z3Uy-xhthEbsKu05",
    "summary": "The amount of times I could have been that white girl in the horror movie could honestly be a movie in itself and it’s honestly...",
    "should_open_in_legacy": false,
    "recommended_source": null,
    "recommended_color": null,
    "followed": true,
    "liked": false,
    "note_count": 293810,
    "content": [],
    "layout": [],
    "trail": [
      {
        "content": [
          {
            "type": "text",
            "text": "The amount of times I could have been that white girl in the horror movie could honestly be a movie in itself and it’s honestly a waste that my entire life isn’t constantly recorded on film because it would be HILARIOUS"
          }
        ],
        "layout": [],
        "post": {
          "id": "177718765885"
        },
        "blog": {
          "name": "teaboot",
          "title": "I Like Yellow Now",
          "description": "♡He/Him♡<br />Canadian",
          "url": "https://www.tumblr.com/blog/view/teaboot",
          "uuid": "t:dSs_21wu8ZX8KeJqLbdZqA",
          "updated": 1755058631,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s512x512u_c1/e5208e71a445dd995cc5c55eb38d815f1e475b78.jpg",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s128x128u_c1/715c4cbfc1f238f5cd61cab9ba48227800051abd.jpg",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s96x96u_c1/c97f47d18a8b486f1df8aa94135f1f6b53a922cc.jpg",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s64x64u_c1/f9bcef2d6d7c2c93ad4411ef4fa8a67eebc131b5.jpg",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": true
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "1. That one time I decided to see what was past the old gate in the woods, but when got there it had been smashed in half and there was a decapitated sheep head with no skin just off the trail, so instead I just turned around and went home."
          },
          {
            "type": "text",
            "text": "2. That time some friends and I went camping and we found a pile of bones wrapped in a garbage bag buried under a log, but the adult supervisor told us it was nothing, so we just put it back and didn’t talk about it again."
          },
          {
            "type": "text",
            "text": "3. The time I was getting chased through the woods at night and I realized “wait it’s dark as fuck” so I just held still until the guy gave up and left."
          },
          {
            "type": "text",
            "text": "4. The time this dude said he was in love with me and so he was going to cut my head off and dump my body in a lake, so I told him to grow the hell up, but then he got caught stealing girl’s underwear a day later and I never saw him again"
          },
          {
            "type": "text",
            "text": "5. That one time in college where I was taking a shortcut on my home at night and a car followed me into a dark alley, so I stared directly into the driver’s side of the window and walked towards it to psych them out"
          },
          {
            "type": "text",
            "text": "6. The night I was out on a walk and this old guy told me he’d locked his keys in his truck and that he needed someone my size to crawl in through the back window for him, so I told him “you know that sounds super suspicious right” and told him where to find a pay phone for a tow truck instead"
          },
          {
            "type": "text",
            "text": "7. The one time this random guy on the street said he was in love with me and so he was going to follow me home on my bus, so I clapped him on the shoulder and told him that if he got that close to my bus then I was going to throw him under the wheels, but then this really nice homeless man from Nigeria told the guy to fuck off and then checked to make sure he didn’t follow me onboard"
          },
          {
            "type": "text",
            "text": "8. That big cat with yellow eyes who I found in a well and brought home who used to put rotting meat in my closet and wake me up by chewing on my face, until I put him back outside and never saw him again."
          },
          {
            "type": "text",
            "text": "9. My one cousin who used to come over for the summer who kept calling me ‘piñata’ and hitting me with sticks, until he went back home and was sent to juvie cause he finally got caught torturing animals"
          },
          {
            "type": "text",
            "text": "10. The time I got lost on the way to a meeting and wound up at a circus tent instead, and got followed by a full-out clown for three vacant street blocks"
          },
          {
            "type": "text",
            "text": "11. The pet hamster I had when I was seven who would scream all night and eventually escaped by ripping a bar out of its cage and wiggling through the hole. My mom caught it and put it back but it lived another year and a half until one night the screaming just stopped"
          },
          {
            "type": "text",
            "text": "12. The time I was whistling in the woods and something started whistling back, so I went home"
          },
          {
            "type": "text",
            "text": "13. That one night at summer camp where a group of girls got together to play ‘bloody mary’ in the lavatory and invited me to come with them so I said “no thanks” and stayed with the camp councillors and drank soup instead."
          },
          {
            "type": "text",
            "text": "14. The old abandoned house I just moved into with the door that leads into a big empty room full of dirt and empty cooking pots that I just sort of… locked up forever and never go near"
          },
          {
            "type": "text",
            "text": "15. Once when I was at an ihop I saw a coffee mug do a full 360º spin with nobody touching it, so I said ‘that was neat’ and never ate there again"
          },
          {
            "type": "text",
            "text": "16. The time I took a photo of a big old raven sitting on the crucifix on top of the old town church cause it was the most goth thing I’d ever seen, right? But then it swooped down towards me, so I apologized immediately for being rude, and I felt a little silly for a while but the car that hit me on the way home didn’t even leave a bruise so idk be nice to birds"
          }
        ],
        "layout": [],
        "post": {
          "id": "177720589930"
        },
        "blog": {
          "name": "teaboot",
          "title": "I Like Yellow Now",
          "description": "♡He/Him♡<br />Canadian",
          "url": "https://www.tumblr.com/blog/view/teaboot",
          "uuid": "t:dSs_21wu8ZX8KeJqLbdZqA",
          "updated": 1755058631,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s512x512u_c1/e5208e71a445dd995cc5c55eb38d815f1e475b78.jpg",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s128x128u_c1/715c4cbfc1f238f5cd61cab9ba48227800051abd.jpg",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s96x96u_c1/c97f47d18a8b486f1df8aa94135f1f6b53a922cc.jpg",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s64x64u_c1/f9bcef2d6d7c2c93ad4411ef4fa8a67eebc131b5.jpg",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "Sorry I know I bring this shit up a lot but sometimes im awake at night and I just. keep thinking"
          }
        ],
        "layout": [],
        "post": {
          "id": "177720622280"
        },
        "blog": {
          "name": "teaboot",
          "title": "I Like Yellow Now",
          "description": "♡He/Him♡<br />Canadian",
          "url": "https://www.tumblr.com/blog/view/teaboot",
          "uuid": "t:dSs_21wu8ZX8KeJqLbdZqA",
          "updated": 1755058631,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s512x512u_c1/e5208e71a445dd995cc5c55eb38d815f1e475b78.jpg",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s128x128u_c1/715c4cbfc1f238f5cd61cab9ba48227800051abd.jpg",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s96x96u_c1/c97f47d18a8b486f1df8aa94135f1f6b53a922cc.jpg",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s64x64u_c1/f9bcef2d6d7c2c93ad4411ef4fa8a67eebc131b5.jpg",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "YO REBLOGGING TO ADD THE PICTURE FROM #16 CAUSE I FOUND ITT",
            "formatting": [
              {
                "type": "bold",
                "start": 0,
                "end": 47
              },
              {
                "type": "link",
                "start": 47,
                "end": 59,
                "url": "https://www.tumblr.com/teaboot/159698236045/there-was-a-huge-raven-on-top-of-the-church-and?source=share"
              },
              {
                "type": "bold",
                "start": 47,
                "end": 59
              }
            ]
          },
          {
            "type": "image",
            "media": [
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 1071,
                "height": 1834,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s1280x1920/d1f5f37f7376f2368e7f6953e88c9137227e53ee.jpg",
                "has_original_dimensions": true
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 561,
                "height": 960,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s640x960/1b89f43c5f10aa1b172f11bfc13f7d75fb4c2545.jpg"
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 473,
                "height": 810,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s540x810/5f9088821f32dd3a9687b684fc66a593668cf426.jpg"
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 438,
                "height": 750,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s500x750/f0b7dea4016c49b3d258a5d2ff5fa9d5e391bc6b.jpg"
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 350,
                "height": 600,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s400x600/f30631c408f95f01f38ba01dd16e8050099010c7.jpg"
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 234,
                "height": 400,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s250x400/aee2a65ac2db7c9c7b877d93774a31cab16ba8dd.jpg"
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 100,
                "height": 171,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s100x200/e588c479204e48b6c00c817c8ad7f5535580a425.jpg"
              },
              {
                "media_key": "9483b1b98cab82d05ed1508c5d11444e:0dca277778470a2c-e8",
                "type": "image/jpeg",
                "width": 75,
                "height": 75,
                "url": "https://64.media.tumblr.com/9483b1b98cab82d05ed1508c5d11444e/0dca277778470a2c-e8/s75x75_c1/55941abb8725610e6accb0961a02782d87d2bc21.jpg",
                "cropped": true
              }
            ],
            "alt_text": "Image: Screenshot of a tumblr post by Teaboot. A grainy photo of the steeple of a church against a cloudy sky. Several feet above the crucifix, a large black bird tucks its wings to swoop down. Text below reads, \"There was a HUGE raven on top of the church and when I stopped to take a picture it swooped at me, so I figured 'oh shit I disrespected the unseelie' so I apologized as it flew away and ten minutes later I got hit by a car but like, really gently, so what I mean to say is that the Fair Folk are real and they are willing to dish out warnings\""
          }
        ],
        "layout": [],
        "post": {
          "id": "727881488397369344"
        },
        "blog": {
          "name": "teaboot",
          "title": "I Like Yellow Now",
          "description": "♡He/Him♡<br />Canadian",
          "url": "https://www.tumblr.com/blog/view/teaboot",
          "uuid": "t:dSs_21wu8ZX8KeJqLbdZqA",
          "updated": 1755058631,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s512x512u_c1/e5208e71a445dd995cc5c55eb38d815f1e475b78.jpg",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s128x128u_c1/715c4cbfc1f238f5cd61cab9ba48227800051abd.jpg",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s96x96u_c1/c97f47d18a8b486f1df8aa94135f1f6b53a922cc.jpg",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s64x64u_c1/f9bcef2d6d7c2c93ad4411ef4fa8a67eebc131b5.jpg",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "ANOTHER (#8)",
            "formatting": [
              {
                "type": "bold",
                "start": 0,
                "end": 7
              },
              {
                "type": "link",
                "start": 0,
                "end": 7,
                "url": "https://www.tumblr.com/teaboot/723346146198798336?source=share"
              }
            ]
          },
          {
            "type": "image",
            "media": [
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 1079,
                "height": 878,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s1280x1920/58daba97032845f6cbeb0ea4d541b83d4dcd80f6.jpg",
                "has_original_dimensions": true
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 640,
                "height": 521,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s640x960/a6c8725469dca04936fe507e9b4e9604b5aab83a.jpg"
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 540,
                "height": 439,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s540x810/22397cbd004b6291df4229e9edf0ed6d743a260f.jpg"
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 500,
                "height": 407,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s500x750/ced3773b61242f775e89b83e9dacf403227c7742.jpg"
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 400,
                "height": 325,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s400x600/e617cf25773ffc72a2549985f53c9f51e890ab71.jpg"
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 250,
                "height": 203,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s250x400/58fd8da297473fc37d6a816d7fdc68244b0485d2.jpg"
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 100,
                "height": 81,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s100x200/57206e21d3607ceee69c738fe0f4cddd4a82356b.jpg"
              },
              {
                "media_key": "5cb9f927d46e7f17c510f93f4bf13638:79e0240837abc7c1-30",
                "type": "image/jpeg",
                "width": 75,
                "height": 75,
                "url": "https://64.media.tumblr.com/5cb9f927d46e7f17c510f93f4bf13638/79e0240837abc7c1-30/s75x75_c1/a643da6050681189dc1c1943ab7ed98e89232eef.jpg",
                "cropped": true
              }
            ],
            "alt_text": "Screenshot: a tumblr post by Teaboot: a grey and white cat with yellow eyes chews on a grey duotang binder at the end of a pile of plankets on the floor. Text below reads \"This is the only evidence I have of the feralcat I hid in my room for 2 weeks in 2013. I found him in our well in the backyard. He rolled an open can of meat into my closet and filled my room with maggots.\""
          }
        ],
        "layout": [],
        "post": {
          "id": "727881979419328513"
        },
        "blog": {
          "name": "teaboot",
          "title": "I Like Yellow Now",
          "description": "♡He/Him♡<br />Canadian",
          "url": "https://www.tumblr.com/blog/view/teaboot",
          "uuid": "t:dSs_21wu8ZX8KeJqLbdZqA",
          "updated": 1755058631,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s512x512u_c1/e5208e71a445dd995cc5c55eb38d815f1e475b78.jpg",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s128x128u_c1/715c4cbfc1f238f5cd61cab9ba48227800051abd.jpg",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s96x96u_c1/c97f47d18a8b486f1df8aa94135f1f6b53a922cc.jpg",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s64x64u_c1/f9bcef2d6d7c2c93ad4411ef4fa8a67eebc131b5.jpg",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "Holy shit rare ancient Girl Era post"
          }
        ],
        "layout": [],
        "post": {
          "id": "790256687002058752"
        },
        "blog": {
          "name": "teaboot",
          "title": "I Like Yellow Now",
          "description": "♡He/Him♡<br />Canadian",
          "url": "https://www.tumblr.com/blog/view/teaboot",
          "uuid": "t:dSs_21wu8ZX8KeJqLbdZqA",
          "updated": 1755058631,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s512x512u_c1/e5208e71a445dd995cc5c55eb38d815f1e475b78.jpg",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s128x128u_c1/715c4cbfc1f238f5cd61cab9ba48227800051abd.jpg",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s96x96u_c1/c97f47d18a8b486f1df8aa94135f1f6b53a922cc.jpg",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/02a3a1ad457dd0a4f7bdaee5454f8ba9/23739fe02f06990d-8a/s64x64u_c1/f9bcef2d6d7c2c93ad4411ef4fa8a67eebc131b5.jpg",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      }
    ],
    "can_like": true,
    "interactability_reblog": "everyone",
    "interactability_blaze": "noone",
    "can_reblog": true,
    "can_send_in_message": true,
    "can_reply": true,
    "display_avatar": true
  },
  {
    "type": "blocks",
    "original_type": "regular",
    "is_blocks_post_format": false,
    "blog_name": "sergle",
    "blog": {
      "name": "sergle",
      "title": "★",
      "description": "<b>sergleicious definition make them boys go loco </b> \n\nMy art / personal blog, may also contain traces of:\n</b>\n★ Every post I've ever laughed at\n★ Bad anime\n★ Every thought I've ever had\n★ Good anime (less often)\n★ Talking About Podcasts™\n★ Whatever I want\n</b>\n(28 / she/her / 90% hair, 10% anxiety)\n\n!my artwork is not for the consumption of terfs! get your bitch ass outta here lmao\n\n<a href=\"http://sergle.tumblr.com/tagged/sergle+art\"><img src=\"https://puu.sh/sPlyP/92408b0ec3.png\"></a>\n<a href=\"http://sergle.tumblr.com/commissions\"><img src=\"https://puu.sh/sPlJc/19c1f1c656.png\"></a>\n<a href=\"http://sergle.tumblr.com/ask\"><img src=\"https://puu.sh/sPlO8/91bd47b61d.png\"></a>\n<a href=\"http://sergle.tumblr.com/faq\"><img src=\"https://puu.sh/sPlR8/b09e4bde72.png\"></a>\n<a href=\"https://www.paypal.com/paypalme/sergleicious\"><img src=\"https://puu.sh/sPlYi/424a81efb4.png\"></a>\n<a href=\"https://www.patreon.com/sergle\"><img src=\"https://puu.sh/ERoNO/2e8a7a8213.png\"></a>\n<a href=\"https://www.etsy.com/shop/SergleShop\"><img src=\"https://puu.sh/sPmWA/ef7100d809.png\"></a>\n<a href=\"http://sergle.tumblr.com/address\"><img src=\"https://puu.sh/BKO8T/0473f9e9a5.png\"></a>",
      "url": "https://sergle.tumblr.com/",
      "uuid": "t:qQTSpN0WbpXWcfhk0hlr-w",
      "updated": 1755092025,
      "tumblrmart_accessories": {},
      "can_show_badges": true
    },
    "id": 788333082099974100,
    "id_string": "788333082099974144",
    "is_blazed": false,
    "is_blaze_pending": false,
    "can_ignite": false,
    "can_blaze": false,
    "post_url": "https://sergle.tumblr.com/post/788333082099974144/unpretty-inkstainedchocolateeyes-unpretty",
    "parent_post_url": "https://goodfriendo.tumblr.com/post/788320176026353664/unpretty-inkstainedchocolateeyes-unpretty",
    "slug": "unpretty-inkstainedchocolateeyes-unpretty",
    "date": "2025-07-06 14:43:33 GMT",
    "timestamp": 1751813013,
    "state": "published",
    "reblog_key": "cIgqPd7W",
    "tags": [
      "I think of this post every single time I can't sleep",
      "and it's comforting to reassure myself that just laying down with my eyes closed is still Rest even if it's not Sleep"
    ],
    "short_url": "https://tmblr.co/Z3Uy-xhmkCBhGW00",
    "summary": "thank god for the mythbusters though because it used to be that whenever i knew i had insomnia i’d just kind of accept it and...",
    "should_open_in_legacy": false,
    "recommended_source": null,
    "recommended_color": null,
    "followed": true,
    "liked": false,
    "note_count": 409499,
    "content": [],
    "layout": [],
    "trail": [
      {
        "content": [
          {
            "type": "text",
            "text": "thank god for the mythbusters though because it used to be that whenever i knew i had insomnia i’d just kind of accept it and stay up doing whatever until my morning classes and spend the day feeling like shit"
          },
          {
            "type": "text",
            "text": "but then they did an episode where they established that even just fucking laying there for a half hour, not even sleeping just laying there and not even for an hour, makes a significant difference and you’ll feel way better"
          },
          {
            "type": "text",
            "text": "it has made a huge difference in my life to know that it’s okay if i can’t fall asleep, it takes a lot of the pressure off and ironically helps me fall asleep better"
          }
        ],
        "layout": [],
        "post": {
          "id": "143329251158"
        },
        "blog": {
          "name": "unpretty",
          "title": "Kitty Unpretty",
          "description": "💙 30-something 💙 She/Her 💙 Queer 💙 Latina 💙 Polyamorous 💙 Certified Dick Wizard 💙 Shit For Brains 💙 \n\nThis used to be unpretty.space but Matt Mullenweg killed it. I'm a huge bitch and I'm dumb as hell. I reblog every damn thing and write about weird monster dicks. I will not apologize to Alton Brown. Posts by me are #original. Some people seem to like #fanfic and #ficblogging. I've also got #greatest hits. Other than that, my tags are fucking useless. If you need things tagged, you're better off following me through kittyunpretty.com or unpretty@ao3.",
          "url": "https://unpretty.tumblr.com/",
          "uuid": "t:mo5Ko708Cuk7G4UgMYe71g",
          "updated": 1755096746,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s512x512u_c1/7511236c47a0f497bb7b788f4b6ea84c920d1d11.png",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s128x128u_c1/422875c1e4852bca1d6b508877b387bd3e4b65a7.png",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s96x96u_c1/591e6899e61813aa003f7618d06fc3043e9995fe.png",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s64x64u_c1/868534a10751fc955cb0bd3ec1654890748f9f28.png",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": true
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "…i did not know this, thank you"
          }
        ],
        "layout": [],
        "post": {
          "id": "143335106243"
        },
        "blog": {
          "name": "inkstainedchocolateeyes",
          "title": "Queen Space Queer",
          "description": "Emily. 30something. Bookworm. Pansexual. Introvert. Night owl. Pro-choice. Multifandom. White. Cis. She/her pronouns.",
          "url": "https://inkstainedchocolateeyes.tumblr.com/",
          "uuid": "t:F5FvMYUoVk9flb4TOyS-Uw",
          "updated": 1752367351,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/avatar_773d37d3e86d_512.png",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/avatar_773d37d3e86d_128.png",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/avatar_773d37d3e86d_96.png",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/avatar_773d37d3e86d_64.png",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      },
      {
        "content": [
          {
            "type": "text",
            "text": "If anyone wants to look it up, the episode was specifically the Deadliest Catch crossover ep, and the myth was that it’s better/safer when working a 30 hour shift to take a 20 minute nap every six hours rather than try to power through. They did an obstacle course test, one without naps and one with, and even though they couldn’t even sleep half the time the naps resulted in their scores doubling."
          },
          {
            "type": "text",
            "text": "So actually I undersold it, even if it’s 7:40 and your alarm goes off at 8 just lie down and shut your eyes and it will still be better than nothing"
          }
        ],
        "layout": [],
        "post": {
          "id": "143340686498"
        },
        "blog": {
          "name": "unpretty",
          "title": "Kitty Unpretty",
          "description": "💙 30-something 💙 She/Her 💙 Queer 💙 Latina 💙 Polyamorous 💙 Certified Dick Wizard 💙 Shit For Brains 💙 \n\nThis used to be unpretty.space but Matt Mullenweg killed it. I'm a huge bitch and I'm dumb as hell. I reblog every damn thing and write about weird monster dicks. I will not apologize to Alton Brown. Posts by me are #original. Some people seem to like #fanfic and #ficblogging. I've also got #greatest hits. Other than that, my tags are fucking useless. If you need things tagged, you're better off following me through kittyunpretty.com or unpretty@ao3.",
          "url": "https://unpretty.tumblr.com/",
          "uuid": "t:mo5Ko708Cuk7G4UgMYe71g",
          "updated": 1755096746,
          "subscribed": false,
          "can_subscribe": false,
          "followed": false,
          "avatar": [
            {
              "width": 512,
              "height": 512,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s512x512u_c1/7511236c47a0f497bb7b788f4b6ea84c920d1d11.png",
              "accessories": []
            },
            {
              "width": 128,
              "height": 128,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s128x128u_c1/422875c1e4852bca1d6b508877b387bd3e4b65a7.png",
              "accessories": []
            },
            {
              "width": 96,
              "height": 96,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s96x96u_c1/591e6899e61813aa003f7618d06fc3043e9995fe.png",
              "accessories": []
            },
            {
              "width": 64,
              "height": 64,
              "url": "https://64.media.tumblr.com/72fafc7306f2280210e1563ae1f5bb6f/9096614cb1f977bc-98/s64x64u_c1/868534a10751fc955cb0bd3ec1654890748f9f28.png",
              "accessories": []
            }
          ],
          "tumblrmart_accessories": {},
          "can_show_badges": true,
          "active": true,
          "show_follow_action": false
        }
      }
    ],
    "can_like": true,
    "interactability_reblog": "everyone",
    "interactability_blaze": "noone",
    "can_reblog": true,
    "can_send_in_message": true,
    "can_reply": true,
    "display_avatar": true
  }
]
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Base class for oauth transfer service

3 participants