A Python library for the Discourse API

Overview

pydiscourse

Build Status Check out the Docs

A Python library for working with Discourse.

This is a fork of the original Tindie version. It was forked to include fixes, additional functionality, and to distribute a package on PyPI.

Goals

  • Exceptional documentation
  • Support all supported Python versions
  • Provide functional parity with the Discourse API, for the currently supported version of Discourse (something of a moving target)

The order here is important. The Discourse API is itself poorly documented so the level of documentation in the Python client is critical.

Installation

pip install pydiscourse

Examples

Create a client connection to a Discourse server:

from pydiscourse import DiscourseClient
client = DiscourseClient(
        'http://example.com',
        api_username='username',
        api_key='areallylongstringfromdiscourse')

Get info about a user:

user = client.user('eviltrout')
print user

user_topics = client.topics_by('johnsmith')
print user_topics

Create a new user:

user = client.create_user('The Black Knight', 'blacknight', '[email protected]', 'justafleshwound')

Implement SSO for Discourse with your Python server:

@login_required
def discourse_sso_view(request):
    payload = request.GET.get('sso')
    signature = request.GET.get('sig')
    nonce = sso_validate(payload, signature, SECRET)
    url = sso_redirect_url(nonce, SECRET, request.user.email, request.user.id, request.user.username)
    return redirect('http://discuss.example.com' + url)

Command line

To help experiment with the Discourse API, pydiscourse provides a simple command line client:

export DISCOURSE_API_KEY=your_master_key
pydiscoursecli --host-http://yourhost --api-user-system latest_topics
pydiscoursecli --host-http://yourhost --api-user-system topics_by johnsmith
pydiscoursecli --host-http://yourhost --api-user-system user eviltrout
Comments
  • pydiscourse.exceptions.DiscourseClientError: Payload Too Large

    pydiscourse.exceptions.DiscourseClientError: Payload Too Large

    Hi! I've been trying to get various methods from the library to work to no avail:

    from pydiscourse import DiscourseClient
    client = DiscourseClient(host='https://forums.mywebsite.com', api_username='username_of_admin', api_key='key')
    print(client.users())
    

    I get the same exception each time:

    Traceback (most recent call last):
      File "test_discourse.py", line 3, in <module>
        print(client.users())
      File "C:\Python37\lib\site-packages\pydiscourse\client.py", line 449, in users
        return self._get("/admin/users/list/{0}.json".format(filter), **kwargs)
      File "C:\Python37\lib\site-packages\pydiscourse\client.py", line 1298, in _get
        return self._request(GET, path, params=kwargs, override_request_kwargs=override_request_kwargs)
      File "C:\Python37\lib\site-packages\pydiscourse\client.py", line 1424, in _request
        raise DiscourseClientError(msg, response=response)
    pydiscourse.exceptions.DiscourseClientError: Payload Too Large
    

    Running pip freeze | grep discourse gives me pydiscourse==1.1.0. If I access the /admin/users/list/{0}.json endpoint directly in my browser I get the expected result, however, what seems to happen through the library is that an error HTML page is returned instead. Any pointers?

    opened by dkgv 8
  • pass params in data

    pass params in data

    Send request params in the request body instead of the query string. This avoid a pydiscourse.exceptions.DiscourseClientError: Request-URI Too Large error when updating large amounts of data.

    I tested this on update_post which is where I was running into this error but didn't test any additional methods.

    opened by jdorweiler 8
  • questions about accessing categories and topics via the api

    questions about accessing categories and topics via the api

    HI There @bennylope !! this tool is really fantastic. I"m playing around with it and trying to understand the discourse api. This:

    https://github.com/bennylope/pydiscourse/blob/master/pydiscourse/client.py#L481

    seems to be the way to grab a list of categories and topics.

    Questions For You

    1. How do i get a list of categories AND subcategories? i can get a list of categories using

    client.categories()

    But this doesn't return the subcategories from what i can tell.

    1. Id like to get a list of topics within each category. When i run client.category_topics(10) (10 is the ID for the category that i'm interested in) I get:

    DiscourseError: Invalid Response, expecting "application/json; charset=utf-8" got "text/html; charset=utf-8"

    i've played with providing it the slug and the category name and it doesn't seem to work

    just curious if you can help me sort this out. i'm happy to update docstrings and docs if i can figure this out if that is of interest / welcome!

    bug question 
    opened by lwasser 6
  • add watch_topic

    add watch_topic

    Summary of changes

    adds api call for: user gets notifications about a topic.

    Checklist

    • [x] Changes represent a discrete update
    • [x] Commit messages are meaningful and descriptive
    • [x] Changeset does not include any extraneous changes unrelated to the discrete change
    enhancement 
    opened by glanzel 5
  • Handle HTTP 429, rate limiting

    Handle HTTP 429, rate limiting

    Per the announcement on Discourse meta, global API rate limits have been introduced to the Discourse API. This change adds a new DiscourseRateLimitedError class and a retry mechanism on receipt of a 429.

    https://meta.discourse.org/t/global-rate-limits-in-discourse/78612

    Closes: #11

    I do have one question: Should the 'settings' (retry_{count,backof}) be defined somewhere easier to change?

    opened by goetzk 5
  • Discourse API throttling.

    Discourse API throttling.

    In the last month or so Discourse implemented API throttling.

    I don't have a lot of detail yet but I was told

    We recently added rate limiting to api calls which is why you are now running in to some issues. [...] You are allowed 60 requests per minute, so you shouldn’t have to slow things down too much.
    

    Are you open to building the throttling directly in to _request or would you prefer library users handled it individually? https://github.com/bennylope/pydiscourse/blob/master/pydiscourse/client.py#L1186

    At the moment an error along these lines is raised (this is what caused me to ask Discourse).

     pydiscourse.exceptions.DiscourseClientError: We have a daily limit on how many times that action can be taken. Please wait 5 seconds before trying again.
    

    thanks, kk

    opened by goetzk 5
  • Please merge features added by Alvaro Molina Alvarez

    Please merge features added by Alvaro Molina Alvarez

    Hi, I'm currently using your packages from pip (thanks!), but I've had to write a bunch of code to work around missing functionality - mainly related to json . Alvaro Molina Alvarez (@amolinaalvarez) has added a number of features including json support that I'm hoping you will be willing to merge. The diff is substantial but easy to follow and includes support for API calls currently not provided in your tree.

    https://github.com/bennylope/pydiscourse/compare/master...amolinaalvarez:master

    thanks, kk

    opened by goetzk 4
  • Bump pypi 1.1.3 ?

    Bump pypi 1.1.3 ?

    Hello!

    Thank you for this module.

    Is it possible to update the pypi version to include the latest change in master ? Notably, I would need the category_latest_topics.

    Thanks again!

    enhancement 
    opened by weber-s 3
  • Allow redirects for requests

    Allow redirects for requests

    Are you aware of any issues when supporting redirects from the Discourse server? In your call to requests.request() you explicitly set allow_redirects to False. This prevents topic lookup by path only (omitting the ID).

    I think a number of functions could make ID optional using the server redirect to resolve as needed.

    opened by gar1t 3
  • new release timeline?

    new release timeline?

    Hey there,

    v0.7.0 on PyPI is super-old, and there are a bunch of goodies in the master branch here I'd love to have access to. Any idea when there's a plan for an updated PyPI package?

    opened by benswift 3
  • SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)

    SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)

    I tried to follow the instructions provided to connect to my https website. It is failing with **SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852) **

    Here is the sample code as per the instructions provided.

    from pydiscourse import DiscourseClient client = DiscourseClient( 'https://discuss.itversity.com', api_username='dgadiraju', api_key='api_key_with_single_user_and_global_permissions')

    question 
    opened by dgadiraju 2
  • Rate limit improvements

    Rate limit improvements

    Summary of changes

    Two changes here, happy to split if you would prefer.

    • First, with my Discourse instance (v2.8.13 on nginx, in case it makes a difference), I encountered rate-limited responses that did not have a Content-Type header. The first commit makes it so that the code takes these in stride.
    • The second commit includes information from the Discourse-Rate-Limit-Error-Code, which makes it easier to debug which limit is encountered. Also, logging happens before waiting, to provide feedback on what is happening.

    Checklist

    • [x] Changes represent a discrete update (-ish)
    • [x] Commit messages are meaningful and descriptive
    • [x] Changeset does not include any extraneous changes unrelated to the discrete change
    opened by inducer 0
  • Does not seem to fetch more than 20 posts per topic

    Does not seem to fetch more than 20 posts per topic

    Hi, So the client.posts(topic_id) function seems to fetch only the first 20 posts. Is there a way to get all the posts? My code (without the confidential data) is as below:

    client = DiscourseClient('http://example.com', api_username='username', api_key='areallylongstringfromdiscourse')

    print(len(client.posts(topic_id).get('post_stream').get('posts'))) - This prints out 20 and returns only 20 posts for all topics with > 20 posts. Where the number of posts is < 20, it prints out that correct number.

    help wanted question first time contributor opportunity 
    opened by gandharvbakshi 1
  • Users: Handle the case there are more than 100 results

    Users: Handle the case there are more than 100 results

    My apologies if it is already handled, but I didn't found how to do it in the code.

    When I want my discourse users, client.users() only gives me the first 100 users whereas I have more than 100.

    I've looked at the doc and it seems that the API doesn't tell that there are more users, but we can use the "page" param to get the next ones.

    I guess the solution would be to loop on the pages until the call gives an empty list as a result.

    I'll try to do a PR if I manage to find a solution.

    enhancement help wanted question 
    opened by werdeil 2
Releases(v1.3.0)
  • v1.3.0(Jul 29, 2022)

  • v1.2.0(Apr 18, 2022)

    What's Changed

    Adds support for Python 3.10, officially drops support for Python 2.7, 3.4, and 3.5.

    Also a bunch of new feature support from underappreciated contributors!

    • Update client.py by @kirstaylo in https://github.com/bennylope/pydiscourse/pull/40
    • Implement new routes by @gnuletik in https://github.com/bennylope/pydiscourse/pull/49
    • fix(errors): handle data-explorer responses by @gnuletik in https://github.com/bennylope/pydiscourse/pull/50
    • Add post_action_users to see who liked a post by @inducer in https://github.com/bennylope/pydiscourse/pull/53
    • Update supported Python versions by @bennylope in https://github.com/bennylope/pydiscourse/pull/54
    • Add option to fetch all categories including subcategories by @Sebastian2023 in https://github.com/bennylope/pydiscourse/pull/59
    • Fix getting category details by @Sebastian2023 in https://github.com/bennylope/pydiscourse/pull/58

    New Contributors

    • @kirstaylo made their first contribution in https://github.com/bennylope/pydiscourse/pull/40
    • @gnuletik made their first contribution in https://github.com/bennylope/pydiscourse/pull/49
    • @inducer made their first contribution in https://github.com/bennylope/pydiscourse/pull/53
    • @Sebastian2023 made their first contribution in https://github.com/bennylope/pydiscourse/pull/59

    Full Changelog: https://github.com/bennylope/pydiscourse/compare/v1.1.2...v1.2.0

    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Nov 10, 2020)

  • v1.1.1(Aug 18, 2020)

    This release contains fixes for a couple of bugs:

    • Fix call to get group info by name
    • Fix 413 response from Discourse due to empty dict passed as json
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Aug 12, 2020)

    The first full release for some time includes the following enhancements over its predecessor 0.8:

    • Rate limiting and user activation
    • Replace parameterised auth with header auth
    • Add support for following redirects
    • Expanded methods for handling topics
    • Support for inviting users
    • Plus other changes to enhance features or maintain Discourse compatibility
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Sep 9, 2016)

  • v0.3.0(Apr 8, 2016)

Owner
Ben Lopatin
I leverage synergies.
Ben Lopatin
A anti-repostbot script for reddit, runs u/ThisIsARepostBotBot

ThisIsARepostBotBot So you found a repost bot, now what? This is a bot to reply to all posts of a repost bot with a message urging users to report and

3 May 23, 2022
WakeNote is a tool that hides notifications from you until you confirm you want to read them, with technology to help prevent the reading of depressing messages first thing in the morning.

By: Seanpm2001, Et; Al. Top README.md Read this article in a different language Sorted by: A-Z Sorting options unavailable ( af Afrikaans Afrikaans |

Sean P. Myrick V19.1.7.2 3 Oct 21, 2022
OAN Music - Highly advanced User Music Bot

ཧᜰ꙰ꦿ➢𝐎𝐀𝐍༒☛ 🎧 Advanced 𝐎𝐀𝐍 Music bot. 🔗 𝐏𝐨𝐰𝐞𝐫𝐞𝐝 𝐛𝐲 : ➢𝐀ttitude

Attitude king 5 Feb 25, 2022
A Telegram Bot to return Youtube Video Tags Using YoutubeTags API

YouTube-TagFind-Bot A Telegram Bot to return Youtube Video Tags Using YoutubeTags API YoutubeTags API Wrapper YoutubeTags is a python third-party api

Nuhman Pk 9 Aug 25, 2022
Auto-Rollnumber-sender - Auto Rollnumber sender with python

Auto-Rollnumber-sender The above code fits better on my system but it can vary s

Riya Tripathi 2 Feb 14, 2022
Battle Pass farming tft bot

Tft bot Bot para farmar pontos do Passe de Batalha do TFT Descrição A cada partida de tft jogada você ganha 100 pontos no passe, porém você não precis

Leonardo Gonçalves 4 Jan 27, 2022
🖥️ Python - P1 Monitor API Asynchronous Python Client

🖥️ Asynchronous Python client for the P1 Monitor

Klaas Schoute 9 Dec 12, 2022
A Superfast SMS & Call bomber for Linux And Termux

PSKR_BOMBER 💣 📱 💀 A Superfast SMS & Call bomber for Linux And Termux ! Disclaimer This tool is for educational purposes only ! Don't use this to ta

1 Dec 20, 2021
VC-Music , Playing music without bot.

VC-Userbot A Telegram Userbot to play or streaming Audio and Video songs / files in Telegram Voice Chats. It's made with PyTgCalls and Pyrogram Requir

RioProjectX 8 Aug 04, 2022
Deezer client for python

Deezer Python Client A friendly Python wrapper around the Deezer API. Installation The package is published on PyPI and can be installed by running: p

Bruno Alla 103 Dec 19, 2022
A discord bot made by the community (uses python)

discord community bot context: this is a discord bot made by the community by community i mean people adding commands to the bot or changing the bot b

TR ASH 0 Oct 11, 2022
Este programa tem como objetivo o cadastro dos usuários. Assim, caso a autenticação seja feita, permitir que o usuário entre em determinado sistema ou programa.

LoginPy Este programa tem como objetivo o cadastro dos usuários. Assim, caso a autenticação seja feita, permitir que o usuário entre em determinado si

Jonas Carvalho 4 Dec 23, 2021
Block Telegram's new

Telegram Channel Blocker Bot Channel go away! This bot is used to delete and ban message sent by channel How this appears? The reason this appears ple

16 Feb 15, 2022
Astro Bot With Golang

Astro-Bot Features: Astronomy Picture of the day Horoscope People In Space How we built it Our team was broken, one person didn't do anything the othe

Vaarun Sinha 1 Nov 21, 2021
SystemSix is an e-Ink "desk accessory" running on a Raspberry Pi. It is a bit of nostalgia that can function as a calendar, display the weather

SystemSix is an e-Ink "desk accessory" running on a Raspberry Pi. It is a bit of nostalgia that can function as a calendar, display the weather, the c

John Calhoun 372 Jan 02, 2023
A minimal open source mtg-like tcg game made in python that can be played on a terminal emulator using a keyboard.

TCG-TERM Project state: 🔧 🚧 🚧 🚧 Incomplete, In development 🚧 🚧 🚧 👷 (Keep in mind that at the moment, This project is currently undone, and wil

Amos 3 Aug 29, 2021
A simple use library for bot discord.py developers

Discord Bot Template It's a simple use library for bot discord.py developers. Ob

Tir Omar 0 Oct 16, 2022
Programa capaz de gerar QR Code a partir do link inserido.

QrCodePy Programa capaz de gerar QR Code, a partir do link inserido, em forma de imagem e salvar localmente. Exemplo de saída: Requisitos Pure Python

Jonas Carvalho 4 Sep 09, 2021
google-resumable-media Apache-2google-resumable-media (🥉28 · ⭐ 27) - Utilities for Google Media Downloads and Resumable.. Apache-2

google-resumable-media Utilities for Google Media Downloads and Resumable Uploads See the docs for examples and usage. Experimental asyncio Support Wh

Google APIs 36 Nov 22, 2022
An API wrapper for the file.io web service.

🗃️ File.io An API wrapper for the file.io web service. Install $ pip3 install fileio or

nkot56297 1 Dec 18, 2021