Skip to main content

Nyaa!! OwO what's this? *glomps you*

Project description

Tumblr-Dot-Com

OwO What's this?! Nyaa!!1

Did that big bad ewong mwsk make twittew apis cowst money :( why not come to tumbler?!

This is a quick and dirty tumblr API wrapper I have made to help with another project I am working on. Currently, a WIP but still usable.

Includes support for polls.

 ______________________________________________________________ 
/ Note: Tumblr has patched much of the wacky poll behaviour.   \
| Those zany polls that double count votes or last 50 years    |
| have sadly been zapped. Blasted from existence. Now, not to  |
| equate this with the burning of Library of Alexandria or     |
| anything but it definitely evokes some strong emotions. You  |
| can't even have more than one poll per post anymore. Read    |
| the changelog for details of how this has affected tumblr-   |
| dot-com and the types of polls you can create. And remember, |
| even if you're dusted, you may be gone. But out here in the  |
\ desert your shadow lives on without you.                     /
 -------------------------------------------------------------- 
        \   ^__^
         \  (xx)\_______
            (__)\       )\/\
             U  ||----w |
                ||     ||

Install

pip install tumblrdotcom

Usage

Provides a tumblr.Tumblr class. See https://www.tumblr.com/docs/en/api/v2 for API details relating to data formatting. Also provides a tumblr.Content class to assist in generating text post content as well as utility functions in tumblr.utils to process poll data.

Example

import os
from datetime import timedelta
from pprint import pprint

from tumblr import Content, Tumblr

tumblr = Tumblr(
    blog="pizza",  # or 'pizza.tumblr.com'
    client_key=os.getenv("CONSUMER_KEY"),
    client_secret=os.getenv("CONSUMER_SECRET"),
    oauth_key=os.getenv("OAUTH_TOKEN"),
    oauth_secret=os.getenv("OAUTH_SECRET"),
)

response = tumblr.post(
    content=(
        Content()
        .heading("Hello, World!")
        .text("Oh boy! Isn't it great to have a tumblr!")
        .row_of(
            (
                "clown_left.jpg",
                "image/jpeg",
                "A photo clown holding their right thumb up towards the camera"
            ),
            (
                "clown_right.jpg",
                "image/jpeg",
                "A photo clown holding their left thumb up towards the camera"
            )
        )
        .poll(
            "Don't you think so?",
            ["Yes", "No"],
            expire_after=timedelta(days=1),
        )
    ),
    tags=["pizza", "I can't even remember why they were deleted"],
)

pprint(response)

API

tumblr.Tumblr

def __init__(self,
             blog: str,
             client_key: str,
             client_secret: str,
             oauth_key: str,
             oauth_secret: str) -> None

Params:

  • blog – The name of the blog (one you have auth for)
  • client_key – AKA Consumer Key
  • client_secret – AKA Consumer Secret
  • oauth_key – AKA Token
  • oauth_secret – AKA Token Secret

Posting

def post(self,
         *,
         content: Content],
         tags: Iterable[str] = tuple(),
         **kwargs) -> Mapping

Params:

  • content – A content object containing the post content
  • tags – an optional list of tags
  • **kwargs – any additional arguments to be passed as post data

Returns a JSON encoded response or raises an HTTPError if the request fails

Post Info

def get_post(self,
             post_id: str | int,
             blog: str | None = None) -> Mapping

Params:

  • post_id – The ID of the post
  • blog – The blog for the post – defaults to the blog given to the tumblr object

Returns a JSON encoded response or raises an HTTPError if the request fails

Reblogging

def reblog(self,
           *,
           from_id: str | int,
           from_blog: str,
           content: list[Mapping],
           tags: Iterable[str] = tuple(),
           to_blog: str) -> Mapping

Params:

  • from_id – The ID of the post to be reblogged from
  • from_blog – The blog of the post to be reblogged from (defaults to self.blog)
  • content – A list of content block type Mappings
  • tags – an optional list of tags
  • to_blog – The blog this will be posted to (defaults to self.blog)

Returns a JSON encoded response or raises an HTTPError if the request fails

Poll Results

def poll_results(self,
                 post_id: str | int,
                 poll_id: str
                 blog: str | None = None) -> Mapping[str, Any]

Returns a result that contains a mapping of poll answer client_ids to the votes for that answer (under the key "results"). Use the utils.zip_poll_with_results function to combine this with the poll data. Use the utils.get_polls_from_post function to get the poll data (which contains the poll ID) from a post.

Params:

  • post_id – The post that contains the poll
  • poll_id – AKA the poll client_id
  • blog – The blog for the post – defaults to the blog given to the tumblr object

Returns a JSON encoded response or raises an HTTPError if the request fails

Content

Supports the creation of text post content with method chaining. Handles image files, layout, and content blocks.

Contains the following functions:

  • poll
  • ordered_list
  • unordered_list
  • image
  • read_more
  • row_of
  • text
  • heading
  • subheading
  • cursive
  • quote
  • indented
  • chat
  • ordered_list_item
  • unordered_list_item

All post types from text onward roughly translate to:

def <text_subtype>(self, content: str, **kwargs) -> Self:
    ...  # snip
    data = {
        "type": "text",
        "subtype": "<text_subtype>",
        "text": content,
        **kwargs,
    }
    ...  # snip
    return self

The other block types will be explained below.

ordered_list, and unordered_list

Each takes varargs of strings and adds a list of ordered_list_items or unordered_list_items to the content respectively.

poll

def poll(self
         question: str,
         options: list[str],
         *,
         expire_after=timedelta(days=7)) -> Self:

Adds a poll content block to the content. This is not officially documented so may be unstable.

Params:

  • question – The Poll prompt
  • options – The poll options
  • expire_after – a time delta of when the poll will close (is clamped between 1 and 7 days serverside)

read_more

Inserts a truncating "read more" block into the post.

image

def image(self,
          path: PurePath | str,
          img_type: str,
          alt_text: str,
          caption: str | None = None) -> Self

Inserts an image into the text post. The image type is the images corresponding MIME type.

row_of

Takes varargs of image data. image data can either be a mapping of image param names to values, or an iterable of the image params.

tumblr.utils

Poll Info

def get_polls_from_post(post_id: Any) -> Iterator[Mapping[str, Any]]

Params:

  • post_id – The post that contains the poll

Returns an iterator of the poll block mappings contained in the post

This function returns an iterator as, try as tumblr might, it seems multiple polls can be added to posts.

Zip Polls with Poll Results

def zip_poll_with_results(poll: Mapping[str, Any],
                          results: Mapping[str, Any]) -> Mapping[str, Any]

Utility function that combines poll data with the poll results. Returns a new mapping with a "total_votes" key mapping to the total number of votes and each poll answer has a "votes" key mapping to the number of votes for that answer.

Params:

  • poll – the poll block data
  • results – the result data (either the response or response data)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tumblrdotcom-0.1.1.tar.gz (11.0 kB view hashes)

Uploaded Source

Built Distribution

tumblrdotcom-0.1.1-py3-none-any.whl (9.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page