Doc and docstring updates for consistency

This commit is contained in:
Andy Piper 2022-11-13 21:42:29 +00:00
parent 1088d6a0d0
commit cf25f69446
No known key found for this signature in database
GPG Key ID: 8FBF7373AC449A7F
3 changed files with 977 additions and 859 deletions

View File

@ -43,25 +43,25 @@ To post, create an actual API instance:
access_token = 'pytooter_usercred.secret', access_token = 'pytooter_usercred.secret',
api_base_url = 'https://mastodon.social' api_base_url = 'https://mastodon.social'
) )
mastodon.toot('Tooting from python using #mastodonpy !') mastodon.toot('Tooting from Python using #mastodonpy !')
`Mastodon`_ is an ActivityPub and OStatus based twitter-like federated social `Mastodon`_ is an ActivityPub-based Twitter-like federated social
network node. It has an API that allows you to interact with its network node. It has an API that allows you to interact with its
every aspect. This is a simple python wrapper for that api, provided every aspect. This is a simple Python wrapper for that API, provided
as a single python module. By default, it talks to the as a single Python module. By default, it talks to the
`Mastodon flagship instance`_, but it can be set to talk to any `Mastodon flagship instance`_, but it can be set to talk to any
node running Mastodon by setting `api_base_url` when creating the node running Mastodon by setting `api_base_url` when creating the
api object (or creating an app). API object (or creating an app).
Mastodon.py aims to implement the complete public Mastodon API. As Mastodon.py aims to implement the complete public Mastodon API. As
of this time, it is feature complete for Mastodon version 3.0.1. Pleromas of this time, it is feature complete for Mastodon version 3.0.1. Pleroma's
Mastodon API layer, while not an official target, should also be basically Mastodon API layer, while not an official target, should also be basically
compatible, and Mastodon.py does make some allowances for behaviour that isn't compatible, and Mastodon.py does make some allowances for behaviour that isn't
strictly like Mastodons. strictly like that of Mastodon.
A note about rate limits A note about rate limits
------------------------ ------------------------
Mastodons API rate limits per user account. By default, the limit is 300 requests Mastodon's API rate limits per user account. By default, the limit is 300 requests
per 5 minute time slot. This can differ from instance to instance and is subject to change. per 5 minute time slot. This can differ from instance to instance and is subject to change.
Mastodon.py has three modes for dealing with rate limiting that you can pass to Mastodon.py has three modes for dealing with rate limiting that you can pass to
the constructor, "throw", "wait" and "pace", "wait" being the default. the constructor, "throw", "wait" and "pace", "wait" being the default.
@ -95,7 +95,7 @@ modes are not thread safe).
In "wait" mode, once a request hits the rate limit, Mastodon.py will wait until In "wait" mode, once a request hits the rate limit, Mastodon.py will wait until
the rate limit resets and then try again, until the request succeeds or an error the rate limit resets and then try again, until the request succeeds or an error
is encountered. This mode is for applications that would rather just not worry about rate limits is encountered. This mode is for applications that would rather just not worry about rate limits
much, don't poll the api all that often, and are okay with a call sometimes just taking much, don't poll the API all that often, and are okay with a call sometimes just taking
a while. a while.
In "pace" mode, Mastodon.py will delay each new request after the first one such that, In "pace" mode, Mastodon.py will delay each new request after the first one such that,
@ -117,7 +117,7 @@ in, do consider using Mastodon.py without authenticating to get the full per-IP
A note about pagination A note about pagination
----------------------- -----------------------
Many of Mastodons API endpoints are paginated. What this means is that if you request Many of Mastodon's API endpoints are paginated. What this means is that if you request
data from them, you might not get all the data at once - instead, you might only get the data from them, you might not get all the data at once - instead, you might only get the
first few results. first few results.
@ -139,7 +139,7 @@ compatible.
`limit` allows you to specify how many results you would like returned. Note that an `limit` allows you to specify how many results you would like returned. Note that an
instance may choose to return less results than you requested - by default, Mastodon instance may choose to return less results than you requested - by default, Mastodon
will return no more than 40 statues and no more than 80 accounts no matter how high will return no more than 40 statuses and no more than 80 accounts no matter how high
you set the limit. you set the limit.
The responses returned by paginated endpoints contain a "link" header that specifies The responses returned by paginated endpoints contain a "link" header that specifies
@ -155,9 +155,9 @@ a paginated request as well as for fetching all pages starting from a first page
Two notes about IDs Two notes about IDs
------------------- -------------------
Mastodons API uses IDs in several places: User IDs, Toot IDs, ... Mastodon's API uses IDs in several places: User IDs, Toot IDs, ...
While debugging, it might be tempting to copy-paste in IDs from the While debugging, it might be tempting to copy-paste IDs from the
web interface into your code. This will not work, as the IDs on the web web interface into your code. This will not work, as the IDs on the web
interface and in the URLs are not the same as the IDs used internally interface and in the URLs are not the same as the IDs used internally
in the API, so don't do that. in the API, so don't do that.
@ -184,7 +184,7 @@ Error handling
When Mastodon.py encounters an error, it will raise an exception, generally with When Mastodon.py encounters an error, it will raise an exception, generally with
some text included to tell you what went wrong. some text included to tell you what went wrong.
The base class that all mastodon exceptions inherit from is `MastodonError`. The base class that all Mastodon exceptions inherit from is `MastodonError`.
If you are only interested in the fact an error was raised somewhere in If you are only interested in the fact an error was raised somewhere in
Mastodon.py, and not the details, this is the exception you can catch. Mastodon.py, and not the details, this is the exception you can catch.
@ -199,7 +199,7 @@ of `MastodonNetworkError`, `MastodonReadTimeout`, which is thrown when a streami
API stream times out during reading. API stream times out during reading.
`MastodonAPIError` is an error returned from the Mastodon instance - the server `MastodonAPIError` is an error returned from the Mastodon instance - the server
has decided it can't fullfill your request (i.e. you requested info on a user that has decided it can't fulfil your request (i.e. you requested info on a user that
does not exist). It is further split into `MastodonNotFoundError` (API returned 404) does not exist). It is further split into `MastodonNotFoundError` (API returned 404)
and `MastodonUnauthorizedError` (API returned 401). Different error codes might exist, and `MastodonUnauthorizedError` (API returned 401). Different error codes might exist,
but are not currently handled separately. but are not currently handled separately.
@ -224,9 +224,9 @@ While you take the extra step of removing the code, please take a moment to cons
Return values Return values
------------- -------------
Unless otherwise specified, all data is returned as python dictionaries, matching Unless otherwise specified, all data is returned as Python dictionaries, matching
the JSON format used by the API. Dates returned by the API are in ISO 8601 format the JSON format used by the API. Dates returned by the API are in ISO 8601 format
and are parsed into python datetime objects. and are parsed into Python datetime objects.
To make access easier, the dictionaries returned are wrapped by a class that adds To make access easier, the dictionaries returned are wrapped by a class that adds
read-only attributes for all dict values - this means that, for example, instead of read-only attributes for all dict values - this means that, for example, instead of
@ -268,7 +268,7 @@ User / account dicts
'followers_count': # How many followers they have 'followers_count': # How many followers they have
'statuses_count': # How many statuses they have 'statuses_count': # How many statuses they have
'note': # Their bio 'note': # Their bio
'url': # Their URL; usually 'https://mastodon.social/users/<acct>' 'url': # Their URL; for example 'https://mastodon.social/users/<acct>'
'avatar': # URL for their avatar, can be animated 'avatar': # URL for their avatar, can be animated
'header': # URL for their header image, can be animated 'header': # URL for their header image, can be animated
'avatar_static': # URL for their avatar, never animated 'avatar_static': # URL for their avatar, never animated
@ -288,9 +288,9 @@ User / account dicts
mastodon.account_verify_credentials()["source"] mastodon.account_verify_credentials()["source"]
# Returns the following dictionary: # Returns the following dictionary:
{ {
'privacy': # The users default visibility setting ("private", "unlisted" or "public") 'privacy': # The user's default visibility setting ("private", "unlisted" or "public")
'sensitive': # Denotes whether user media should be marked sensitive by default 'sensitive': # Denotes whether user media should be marked sensitive by default
'note': # Plain text version of the users bio 'note': # Plain text version of the user's bio
} }
Toot dicts Toot dicts
@ -346,10 +346,10 @@ Mention dicts
.. code-block:: python .. code-block:: python
{ {
'url': # Mentioned users profile URL (potentially remote) 'url': # Mentioned user's profile URL (potentially remote)
'username': # Mentioned users user name (not including domain) 'username': # Mentioned user's user name (not including domain)
'acct': # Mentioned users account name (including domain) 'acct': # Mentioned user's account name (including domain)
'id': # Mentioned users (local) account ID 'id': # Mentioned user's (local) account ID
} }
Scheduled toot dicts Scheduled toot dicts
@ -673,10 +673,10 @@ Instance dicts
{ {
'description': # A brief instance description set by the admin 'description': # A brief instance description set by the admin
'short_description': # An even briefer instance description 'short_description': # An even briefer instance description
'email': # The admin contact e-mail 'email': # The admin contact email
'title': # The instances title 'title': # The instance's title
'uri': # The instances URL 'uri': # The instance's URL
'version': # The instances mastodon version 'version': # The instance's Mastodon version
'urls': # Additional URLs dict, presently only 'streaming_api' with the 'urls': # Additional URLs dict, presently only 'streaming_api' with the
# stream websocket address. # stream websocket address.
'stats: # A dictionary containing three stats, user_count (number of local users), 'stats: # A dictionary containing three stats, user_count (number of local users),
@ -763,7 +763,7 @@ Push notification dicts
'notification_id': # ID that can be passed to notification() to get the full 'notification_id': # ID that can be passed to notification() to get the full
# notification object, # notification object,
'notification_type': # 'mention', 'reblog', 'follow' or 'favourite' 'notification_type': # 'mention', 'reblog', 'follow' or 'favourite'
'preferred_locale': # The users preferred locale 'preferred_locale': # The user's preferred locale
'title': # Title for the notification 'title': # Title for the notification
} }
@ -776,11 +776,11 @@ Preference dicts
mastodon.preferences() mastodon.preferences()
# Returns the following dictionary # Returns the following dictionary
{ {
'posting:default:visibility': # The default visibility setting for the users posts, 'posting:default:visibility': # The default visibility setting for the user's posts,
# as a string # as a string
'posting:default:sensitive': # Boolean indicating whether the users uploads should 'posting:default:sensitive': # Boolean indicating whether the user's uploads should
# be marked sensitive by default # be marked sensitive by default
'posting:default:language': # The users default post language, if set (None if not) 'posting:default:language': # The user's default post language, if set (None if not)
'reading:expand:media': # How the user wishes to be shown sensitive media. Can be 'reading:expand:media': # How the user wishes to be shown sensitive media. Can be
# 'default' (hide if sensitive), 'hide_all' or 'show_all' # 'default' (hide if sensitive), 'hide_all' or 'show_all'
'reading:expand:spoilers': # Boolean indicating whether the user wishes to expand 'reading:expand:spoilers': # Boolean indicating whether the user wishes to expand
@ -799,7 +799,7 @@ Featured tag dicts
'id': # The featured tags id 'id': # The featured tags id
'name': # The featured tags name (without leading #) 'name': # The featured tags name (without leading #)
'statuses_count': # Number of publicly visible statuses posted with this hashtag that this instance knows about 'statuses_count': # Number of publicly visible statuses posted with this hashtag that this instance knows about
'last_status_at': # The last time a public status containing this hashtag was added to this instances database 'last_status_at': # The last time a public status containing this hashtag was added to this instance's database
# (can be None if there are none) # (can be None if there are none)
} }
@ -860,10 +860,10 @@ Admin account dicts
'username': # The users username, no leading @ 'username': # The users username, no leading @
'domain': # The users domain 'domain': # The users domain
'created_at': # The time of account creation 'created_at': # The time of account creation
'email': # For local users, the users e-mail 'email': # For local users, the user's email
'ip': # For local users, the users last known IP address 'ip': # For local users, the user's last known IP address
'role': # 'admin', 'moderator' or None 'role': # 'admin', 'moderator' or None
'confirmed': # For local users, False if the user has not confirmed their e-mail, True otherwise 'confirmed': # For local users, False if the user has not confirmed their email, True otherwise
'suspended': # Boolean indicating whether the user has been suspended 'suspended': # Boolean indicating whether the user has been suspended
'silenced': # Boolean indicating whether the user has been suspended 'silenced': # Boolean indicating whether the user has been suspended
'disabled': # For local users, boolean indicating whether the user has had their login disabled 'disabled': # For local users, boolean indicating whether the user has had their login disabled
@ -871,12 +871,12 @@ Admin account dicts
'locale': # For local users, the locale the user has set, 'locale': # For local users, the locale the user has set,
'invite_request': # If the user requested an invite, the invite request comment of that user. (TODO permanent?) 'invite_request': # If the user requested an invite, the invite request comment of that user. (TODO permanent?)
'invited_by_account_id': # Present if the user was invited by another user and set to the inviting users id. 'invited_by_account_id': # Present if the user was invited by another user and set to the inviting users id.
'account': # The users account, as a standard user dict 'account': # The user's account, as a standard user dict
} }
App registration and user authentication App registration and user authentication
---------------------------------------- ----------------------------------------
Before you can use the mastodon API, you have to register your Before you can use the Mastodon API, you have to register your
application (which gets you a client key and client secret) application (which gets you a client key and client secret)
and then log in (which gets you an access token). These functions and then log in (which gets you an access token). These functions
allow you to do those things. Additionally, it is also possible allow you to do those things. Additionally, it is also possible
@ -979,7 +979,7 @@ This function allows you to get and refresh information about polls.
Reading data: Notifications Reading data: Notifications
--------------------------- ---------------------------
This function allows you to get information about a users notifications. This function allows you to get information about a user's notifications.
.. automethod:: Mastodon.notifications .. automethod:: Mastodon.notifications
@ -1020,7 +1020,7 @@ Reading data: Follow suggestions
Reading data: Profile directory Reading data: Profile directory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. authomethod:: Mastodon.directory .. automethod:: Mastodon.directory
Reading data: Lists Reading data: Lists
------------------- -------------------
@ -1033,7 +1033,7 @@ These functions allow you to view information about lists.
Reading data: Follows Reading data: Follows
--------------------- ---------------------
.. automethod:: Mastodon.followshttps://docs.joinmastodon.org/api/rest .. automethod:: Mastodon.follows
Reading data: Favourites Reading data: Favourites
------------------------ ------------------------
@ -1078,7 +1078,7 @@ of reports filed by the logged in user. It has since been removed.
Writing data: Last-read markers Writing data: Last-read markers
-------------------------- --------------------------------
This function allows you to set get last read position for timelines. This function allows you to set get last read position for timelines.
.. automethod:: Mastodon.markers_get .. automethod:: Mastodon.markers_get
@ -1139,8 +1139,8 @@ interact with already posted statuses.
Writing data: Scheduled statuses Writing data: Scheduled statuses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mastodon allows you to schedule statuses (using `status_post()`_. Mastodon allows you to schedule statuses (using `status_post()`_).
The functions in this section allow you to update or delete thusly The functions in this section allow you to update or delete
scheduled statuses. scheduled statuses.
.. automethod:: Mastodon.scheduled_status_update .. automethod:: Mastodon.scheduled_status_update
@ -1171,7 +1171,6 @@ These functions allow you to interact with other accounts: To (un)follow and
(un)block. (un)block.
.. automethod:: Mastodon.account_follow .. automethod:: Mastodon.account_follow
.. automethod:: Mastodon.follows
.. automethod:: Mastodon.account_unfollow .. automethod:: Mastodon.account_unfollow
.. automethod:: Mastodon.account_block .. automethod:: Mastodon.account_block
.. automethod:: Mastodon.account_unblock .. automethod:: Mastodon.account_unblock
@ -1185,7 +1184,7 @@ These functions allow you to interact with other accounts: To (un)follow and
Writing data: Featured tags Writing data: Featured tags
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
These functions allow setting which tags are featured on a users profile. These functions allow setting which tags are featured on a user's profile.
.. automethod:: Mastodon.featured_tag_create .. automethod:: Mastodon.featured_tag_create
.. automethod:: Mastodon.featured_tag_delete .. automethod:: Mastodon.featured_tag_delete
@ -1240,7 +1239,7 @@ Writing data: Reports
.. automethod:: Mastodon.report .. automethod:: Mastodon.report
Writing data: Last-read markers Writing data: Last-read markers
-------------------------- -------------------------------
This function allows you to set the last read position for timelines to This function allows you to set the last read position for timelines to
allow for persisting where the user was reading a timeline between sessions allow for persisting where the user was reading a timeline between sessions
and clients / devices. and clients / devices.
@ -1348,14 +1347,14 @@ CallbackStreamListener
Push subscriptions Push subscriptions
------------------ ------------------
These functions allow you to manage webpush subscriptions and to decrypt received These functions allow you to manage webpush subscriptions and to decrypt received
pushes. Note that the intended setup is not mastodon pushing directly to a users client - pushes. Note that the intended setup is not Mastodon pushing directly to a user's client -
the push endpoint should usually be a relay server that then takes care of delivering the the push endpoint should usually be a relay server that then takes care of delivering the
(encrypted) push to the end user via some mechanism, where it can then be decrypted and (encrypted) push to the end user via some mechanism, where it can then be decrypted and
displayed. displayed.
Mastodon allows an application to have one webpush subscription per user at a time. Mastodon allows an application to have one webpush subscription per user at a time.
All crypto utilities require Mastodon.pys optional "webpush" feature dependencies All crypto utilities require Mastodon.py's optional "webpush" feature dependencies
(specifically, the "cryptography" and "http_ece" packages). (specifically, the "cryptography" and "http_ece" packages).
.. automethod:: Mastodon.push_subscription .. automethod:: Mastodon.push_subscription
@ -1403,10 +1402,10 @@ have admin: scopes attached with a lot of care, but be extra careful with those
Acknowledgements Acknowledgements
---------------- ----------------
Mastodon.py contains work by a large amount of contributors, many of which have Mastodon.py contains work by a large number of contributors, many of which have
put significant work into making it a better library. You can find some information put significant work into making it a better library. You can find some information
about who helped with which particular feature or fix in the changelog. about who helped with which particular feature or fix in the changelog.
.. _Mastodon: https://github.com/tootsuite/mastodon .. _Mastodon: https://github.com/mastodon/mastodon
.. _Mastodon flagship instance: http://mastodon.social/ .. _Mastodon flagship instance: https://mastodon.social/
.. _Official Mastodon api docs: https://docs.joinmastodon.org/api/rest .. _Official Mastodon API docs: https://docs.joinmastodon.org/client/intro/

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
""" """
Handlers for the Streaming API: Handlers for the Streaming API:
https://github.com/tootsuite/mastodon/blob/master/docs/Using-the-API/Streaming-API.md https://github.com/mastodon/documentation/blob/master/content/en/methods/timelines/streaming.md
""" """
import json import json
@ -14,6 +14,7 @@ from mastodon import Mastodon
from mastodon.Mastodon import MastodonMalformedEventError, MastodonNetworkError, MastodonReadTimeout from mastodon.Mastodon import MastodonMalformedEventError, MastodonNetworkError, MastodonReadTimeout
from requests.exceptions import ChunkedEncodingError, ReadTimeout from requests.exceptions import ChunkedEncodingError, ReadTimeout
class StreamListener(object): class StreamListener(object):
"""Callbacks for the streaming API. Create a subclass, override the on_xxx """Callbacks for the streaming API. Create a subclass, override the on_xxx
methods for the kinds of events you're interested in, then pass an instance methods for the kinds of events you're interested in, then pass an instance
@ -55,7 +56,7 @@ class StreamListener(object):
contains the resulting conversation dict.""" contains the resulting conversation dict."""
pass pass
def on_unknown_event(self, name, unknown_event = None): def on_unknown_event(self, name, unknown_event=None):
"""An unknown mastodon API event has been received. The name contains the event-name and unknown_event """An unknown mastodon API event has been received. The name contains the event-name and unknown_event
contains the content of the unknown event. contains the content of the unknown event.
@ -65,7 +66,6 @@ class StreamListener(object):
self.on_abort(exception) self.on_abort(exception)
raise exception raise exception
def handle_heartbeat(self): def handle_heartbeat(self):
"""The server has sent us a keep-alive message. This callback may be """The server has sent us a keep-alive message. This callback may be
useful to carry out periodic housekeeping tasks, or just to confirm useful to carry out periodic housekeeping tasks, or just to confirm
@ -87,7 +87,7 @@ class StreamListener(object):
event = {} event = {}
line_buffer = bytearray() line_buffer = bytearray()
try: try:
for chunk in response.iter_content(chunk_size = 1): for chunk in response.iter_content(chunk_size=1):
if chunk: if chunk:
for chunk_part in chunk: for chunk_part in chunk:
chunk_part = bytearray([chunk_part]) chunk_part = bytearray([chunk_part])
@ -95,7 +95,8 @@ class StreamListener(object):
try: try:
line = line_buffer.decode('utf-8') line = line_buffer.decode('utf-8')
except UnicodeDecodeError as err: except UnicodeDecodeError as err:
exception = MastodonMalformedEventError("Malformed UTF-8") exception = MastodonMalformedEventError(
"Malformed UTF-8")
self.on_abort(exception) self.on_abort(exception)
six.raise_from( six.raise_from(
exception, exception,
@ -117,7 +118,8 @@ class StreamListener(object):
err err
) )
except MastodonReadTimeout as err: except MastodonReadTimeout as err:
exception = MastodonReadTimeout("Timed out while reading from server."), exception = MastodonReadTimeout(
"Timed out while reading from server."),
self.on_abort(exception) self.on_abort(exception)
six.raise_from( six.raise_from(
exception, exception,
@ -150,9 +152,11 @@ class StreamListener(object):
for_stream = json.loads(event['stream']) for_stream = json.loads(event['stream'])
except: except:
for_stream = None for_stream = None
payload = json.loads(data, object_hook = Mastodon._Mastodon__json_hooks) payload = json.loads(
data, object_hook=Mastodon._Mastodon__json_hooks)
except KeyError as err: except KeyError as err:
exception = MastodonMalformedEventError('Missing field', err.args[0], event) exception = MastodonMalformedEventError(
'Missing field', err.args[0], event)
self.on_abort(exception) self.on_abort(exception)
six.raise_from( six.raise_from(
exception, exception,
@ -191,6 +195,7 @@ class StreamListener(object):
else: else:
handler(name, payload) handler(name, payload)
class CallbackStreamListener(StreamListener): class CallbackStreamListener(StreamListener):
""" """
Simple callback stream handler class. Simple callback stream handler class.
@ -198,7 +203,8 @@ class CallbackStreamListener(StreamListener):
Define an unknown_event_handler for new Mastodon API events. If not, the Define an unknown_event_handler for new Mastodon API events. If not, the
listener will raise an error on new, not handled, events from the API. listener will raise an error on new, not handled, events from the API.
""" """
def __init__(self, update_handler = None, local_update_handler = None, delete_handler = None, notification_handler = None, conversation_handler = None, unknown_event_handler = None, status_update_handler = None):
def __init__(self, update_handler=None, local_update_handler=None, delete_handler=None, notification_handler=None, conversation_handler=None, unknown_event_handler=None, status_update_handler=None):
super(CallbackStreamListener, self).__init__() super(CallbackStreamListener, self).__init__()
self.update_handler = update_handler self.update_handler = update_handler
self.local_update_handler = local_update_handler self.local_update_handler = local_update_handler
@ -233,7 +239,7 @@ class CallbackStreamListener(StreamListener):
if self.conversation_handler != None: if self.conversation_handler != None:
self.conversation_handler(conversation) self.conversation_handler(conversation)
def on_unknown_event(self, name, unknown_event = None): def on_unknown_event(self, name, unknown_event=None):
if self.unknown_event_handler != None: if self.unknown_event_handler != None:
self.unknown_event_handler(name, unknown_event) self.unknown_event_handler(name, unknown_event)
else: else: