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
This is a discord token generator(requests) which works and makes 200 tokens per minute

Discord Email verified token generator Creates email verified discord accounts (unlocked) Report Bug · Discord server Features Profile pictures and na

131 Dec 10, 2022
Yandex OSINT tool

YaSeeker Description YaSeeker - an OSINT tool to get info about any Yandex account using email or login. It can find: Fullname Photo Gender Yandex UID

HowToFind 110 Jan 03, 2023
Spotify Top Lists - get the current top lists of a user from the Spotify API and display them in a Flask app

Spotify Top Lists This is a simple script that will get the current top lists of a user from the Spotify API and display them in a Flask app. Requirem

Yasin 0 Oct 16, 2022
HinamiRobot - Telegram Group Manager Bot Written In Python Using Pyrogram

✨ HINAMI CHAN ✨ Telegram Group Manager Bot Written In Python Using Pyrogram. Rea

DARK LEGEND088 2 Jan 27, 2022
Spore API wrapper written in Python

A wrapper for the Spore API that simplifies and complements its functionality

1 Nov 25, 2021
Unlimited Filter Telegram Bot 2

Mother NAther Bot Features Auto Filter Manuel Filter IMDB Admin Commands Broadcast Index IMDB search Inline Search Random pics ids and User info Stats

LɪᴏɴKᴇᴛᴛʏUᴅ 1 Oct 30, 2021
Deepak Clouds Torrent is a multipurpose Telegram Bot writen in Python for mirroring files on the Internet to our beloved Google Drive.

Deepak Clouds Torrent is a multipurpose Telegram Bot writen in Python for mirroring files on the Internet to our beloved Google Drive.

Deepak Clouds 37 Oct 28, 2022
Seth Userbot with python

SETH-USERBOT DEPLOY TO HEROKU Group Support: String Session : Stay Support 🚀 ❁ LonamiWebs and Telethon © Credits ⚡ THANK YOU VERY MUCH FOR zeinzo Zei

seth 4 Jan 10, 2022
Send embeds using your discord personal account

Welcome to Embed Sender 👋 Send embeds using your discord personal account Install pip install -r requirements.txt Usage Put your discord token in ./

SkydenFly 11 Sep 07, 2022
A basic Ubisoft API wrapper created in python.

UbisoftAPI A basic Ubisoft API wrapper created in python. I will be updating this with more endpoints as time goes on. Please note that this is my fir

Ethan 2 Oct 31, 2021
HackZ-Token-Grabber-V2 - HackZ Token Grabber V2

HackZ-Token-Grabber-V2 was made by Love ❌ code ✅ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ 🌟

! ™NightMare 2 Mar 01, 2022
This automation protect against subdomain takeover on AWS env which also send alerts on slack.

AWS_Subdomain_Takeover_Detector Purpose The purpose of this automation is to detect misconfigured Route53 entries which are vulnerable to subdomain ta

Puneet Kumar Maurya 8 May 18, 2022
A simple anti-ghostping python bot made using diskord.

Anti Ghostping A simple Anti-Ghostping python bot made with ❤ using Diskord Requirements No one will use this but, all you need for this bot is: Pytho

RyZe 2 Sep 12, 2022
Working TikTok Username Auto-Claimer/Sniper/Swapper which will autoclaim username if it´s available

TikTok-AutoClaimer Working TikTok Username Auto-Claimer/Sniper/Swapper which will autoclaim username if it´s available Usage Python 3.6 or above is re

Kevin 18 Dec 08, 2022
Creating a Python API, for the MakeMyTrip Flight Schedules.

MakeMyTripAPI Creating a Python API, for the MakeMyTrip Flight Schedules. Source: MakeMyTrip is an Indian online travel company founded in 2000. Headq

Aman Priyanshu 0 Jan 12, 2022
“ HOLA HUMANS 👋 I'M DAISYX 2.0 „ LATEST VERSION OF DAISYX.. Source Code of @Daisyxbot

DaisyX 2.0 A Powerful, Smart And Simple Group Manager ... Written with AioGram , Pyrogram and Telethon... The first AioGram based modified groupmanage

TeamDaisyX 153 Dec 06, 2022
SimpleDCABot is a simple bot that buys crypto with a dollar-cost averaging strategy.

Simple Open Dollar Cost Averaging (DCA) Bot SimpleDCABot is a simple bot that buys crypto on a selected exchange at regular intervals for a prescribed

4 Mar 28, 2022
A simple Spamming software made in python

Spam-qlk Warning!!! 'I' am not responsible for the 'damage or harm' caused by this 'Software'!!! Use at your own risk!!! Input the message. After you

Aditya kumar 1 Nov 30, 2021
A course on getting started with the Twitter API v2 for academic research

Getting started with the Twitter API v2 for academic research Welcome to this '101 course' on getting started with academic research using the Twitter

@TwitterDev 426 Jan 04, 2023
Python script to replace BTC adresses in the clipboard with similar looking ones, whose private key can be retrieved by a netcat listener or similar.

BTCStealer Python script to replace BTC adresses in the clipboard with similar looking ones, whose private key can be retrieved by a netcat listener o

Some Person 6 Jun 07, 2022