substack-api

repository·master·Indexed 42 days ago

https://github.com/nhagar/substack_api

An unofficial Python client library and CLI for interacting with Substack newsletters, posts, podcasts, user profiles, and subscriber chats. It includes the SubstackAuth class for accessing paywalled content via session cookies and provides specialized modules for managing Categories, Newsletters, and Chat threads.

Tokens
21.7K
Snippets
92
Records
103
Agent score
51%

What's inside substack-api

  1. Overview of Substack API modules

    master

    The Substack API library is organized into several specialized modules for interacting with different parts of the Substack platform:

    • User: Access to Substack user profiles and subscriptions.
    • Newsletter: Access to Substack publications, posts, and podcasts.
    • Post: Access to individual Substack post content and metadata.
    • Category: Discovery of newsletters by category.
    • Chat: Access to publication subscriber chats and threads.
    • SubstackAuth: Authentication for accessing paywalled content.
  2. Common patterns in the Substack API library

    master

    When using the library, you will encounter several consistent patterns across most classes:

    1. Initialization: Objects are typically instantiated by providing an identifier such as a URL or a username.
    2. Data Retrieval: Classes provide methods specifically designed to fetch data from the Substack API.
    3. Caching: The library implements caching to minimize unnecessary API requests and improve performance.
    4. Force Refresh: To bypass the cache and fetch fresh data from the API, most methods accept a force_refresh parameter.
  3. Force refresh cached data

    master

    The library caches API responses by default to minimize requests. To bypass the cache and fetch fresh data from the server, pass force_refresh=True to relevant methods like get_metadata() or get_raw_data().

    # Force refresh of post data
    post.get_metadata(force_refresh=True)
    
    # Force refresh of user data
    user.get_raw_data(force_refresh=True)
  4. How the chat module hierarchy works

    master

    The chat module follows a hierarchical structure to navigate Substack community discussions:

    1. Chat: The entry point. It represents the entire chat room for a specific publication_id. You use this to discover threads.
    2. ChatThread: A specific discussion topic within a Chat. It contains the original post and metadata like comment_count.
    3. ChatMessage: The individual units of conversation (replies) within a ChatThread.

    To navigate, you typically instantiate a Chat, call get_threads() to get ChatThread objects, and then call get_messages() on a thread to get ChatMessage objects.

  5. Core abstractions in the Substack API

    master

    The library is organized around several main classes that represent different entities in the Substack ecosystem:

    • User: Represents a Substack user profile.
    • Newsletter: Represents a Substack publication.
    • Post: Represents an individual post on Substack.
    • Category: Represents a Substack category of newsletters.
    • Chat: Represents a publication's subscriber chat.
    • SubstackAuth: Handles authentication for accessing paywalled content.
  6. Access paywalled content with SubstackAuth

    master

    To access paywalled content that you have written or paid for, you must provide session cookies in a JSON format. Use the SubstackAuth class and pass it to Newsletter or Post instances.

    from substack_api import Newsletter, Post, SubstackAuth
    
    # Set up authentication with your cookies
    auth = SubstackAuth(cookies_path="path/to/your/cookies.json")
    
    # Use authentication with newsletters
    newsletter = Newsletter("https://example.substack.com", auth=auth)
    posts = newsletter.get_posts(limit=5)  # Can now access paywalled posts
    
    # Use authentication with individual posts
    post = Post("https://example.substack.com/p/paywalled-post", auth=auth)
    content = post.get_content()  # Can now access paywalled content
    
    # Check if a post is paywalled
    if post.is_paywalled():
        print("This post requires a subscription")
  7. Install the Substack API library

    master
    The Substack API is an unofficial Python library for interacting with Substack newsletters, users, posts, and categories. You can install it using standard Python package managers like pip or uv (refer to the installation section in the full documentation for specific commands).
  8. Use authentication with Newsletter and Post objects

    master

    Once you have a SubstackAuth instance, you can pass it to the auth parameter of Newsletter or Post objects to access restricted content.

    Authenticated Newsletter

    When creating a Newsletter with an auth object, all posts retrieved via methods like .get_posts() will automatically use those credentials to access paywalled content.

    Authenticated Post

    For a specific Post, passing the auth object allows .get_content() to retrieve the full text of paywalled articles.

    from substack_api import Newsletter, Post, SubstackAuth
    
    auth = SubstackAuth(cookies_path="cookies.json")
    
    # Using with Newsletter
    newsletter = Newsletter("https://example.substack.com", auth=auth)
    posts = newsletter.get_posts(limit=10)
    for post in posts:
        if post.is_paywalled():
            content = post.get_content()  # Accessible via auth
    
    # Using with Post
    post = Post("https://example.substack.com/p/paywalled-post", auth=auth)
    if post.is_paywalled():
        content = post.get_content()
  9. Access paywalled Substack content

    master

    To access content behind a paywall, you must provide a SubstackAuth object (initialized with a cookies_path) when creating the Post instance.

    Workflow

    1. Check if the post is paywalled using is_paywalled().
    2. If it is, instantiate SubstackAuth using your cookies.
    3. Create a new Post instance passing the auth object.
    4. Call get_content() to retrieve the HTML.
    from substack_api import Post, SubstackAuth
    
    auth = SubstackAuth(cookies_path="cookies.json")
    authenticated_post = Post("https://example.substack.com/p/paywalled-post", auth=auth)
    content = authenticated_post.get_content()