Skip to main content

A simple Python wrapper for reading data from Discourse forums

Project description

discourse-reader

A typed, read-only Python client for the Discourse forum API.

Install

pip install discourse-reader

Quick start

from discourse_reader import DiscourseClient

client = DiscourseClient("https://meta.discourse.org")

# Browse categories
for cat in client.categories():
    print(f"{cat.name}: {cat.topic_count} topics")

# Get a topic with all its posts
topic = client.topics.get(12345)
print(topic.title)
print(topic.opening_post.cooked)       # the original post (HTML)
print(topic.accepted_answer)           # accepted answer or None
for reply in topic.posts.replies():
    print(reply.username, reply.cooked)

API

Site-level (flat on client)

client.about()                         # About
client.statistics()                    # SiteStatistics
client.categories()                    # list[Category]
client.tags()                          # list[TagDetail]
client.user("username")                # User
client.search("query", limit=50)       # Iterator[SearchPost]

Topics (client.topics)

client.topics.latest(limit=100)        # Iterator[Topic]
client.topics.top(period="monthly")    # Iterator[Topic]
client.topics.by_category(cat)         # Iterator[Topic]  (pass a Category)
client.topics.by_tag("tag-name")       # Iterator[Topic]
client.topics.get(topic_id)            # TopicResult

All listing methods are lazy iterators with optional limit.

TopicResult

topics.get() returns a TopicResult which delegates to TopicDetail for attributes like title, category_id, views, etc.

topic = client.topics.get(12345)
topic.title                            # str (delegated to TopicDetail)
topic.opening_post                     # Post  -- the original post
topic.accepted_answer                  # Post | None
topic.detail                           # raw TopicDetail model

Posts (topic.posts)

Discourse delivers ~20 posts with the topic detail. The rest are fetched lazily in batches when you iterate.

topic.posts.all()                      # Iterator[Post] -- everything
topic.posts.replies()                  # Iterator[Post] -- everything except OP
len(topic.posts)                       # total post count
for post in topic.posts:               # same as .all()
    ...

Single post

client.posts.get(post_id)             # Post by global ID

Extra fields

All models use extra="allow" -- core fields are typed, plugin fields land in model_extra:

topic.detail.model_extra.get("accepted_answer")   # solved plugin data
post.model_extra.get("accepted_answer")            # per-post flag

Rate limiting

Default: 4 requests/second. Configurable via constructor. Automatic 429 retry with Retry-After.

client = DiscourseClient("https://...", requests_per_second=2)    # slower
client = DiscourseClient("https://...", requests_per_second=None)  # no limit

Development

uv sync
uv run pre-commit install
uv run pre-commit run --all-files
uv run pytest

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

discourse_reader-1.0.0.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

discourse_reader-1.0.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file discourse_reader-1.0.0.tar.gz.

File metadata

  • Download URL: discourse_reader-1.0.0.tar.gz
  • Upload date:
  • Size: 38.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for discourse_reader-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5e5893c0f7495217ced61f49d608327823af3343222b0b1d8fa329fe3359a3e6
MD5 46c393042912f988e0fc438347f7d9b6
BLAKE2b-256 c80b460fd52d8482468e684a1b617f1bf1c71f7df25b13a49e1ee3d828d77c38

See more details on using hashes here.

Provenance

The following attestation bundles were made for discourse_reader-1.0.0.tar.gz:

Publisher: publish.yml on elninotech/discourse-reader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file discourse_reader-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for discourse_reader-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 54064a139afca9a255cccda55540934a2f10d73658988b99fa676e25e82f890b
MD5 cfa29d1fc96c117496a73952f299960b
BLAKE2b-256 00ccab1f423b8a93a8426f509528a61d1a70d2e224467536c5f254ccbb1686a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for discourse_reader-1.0.0-py3-none-any.whl:

Publisher: publish.yml on elninotech/discourse-reader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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