API Module¶
- class pythreads.api.API(credentials: Credentials, session: ClientSession | None = None)¶
Bases:
object
- async account(user_id: str = 'me') Any ¶
Retrieve a Threads User’s Profile Information
https://developers.facebook.com/docs/threads/threads-profiles
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async container(container_id: str)¶
Retrieve an individual Threads media object (aka container)
https://developers.facebook.com/docs/threads/threads-media#retrieve-a-single-threads-media-object
- Parameters:
container_id – The id of the container you want to retrieve
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async container_status(media_id: str) ContainerStatus ¶
Gets the container’s publishing status
https://developers.facebook.com/docs/threads/troubleshooting#publishing-does-not-return-a-media-id
- Parameters:
media_id – The id of the container you want to know the status of
- Returns:
A ContainerStatus object
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async conversation(thread_id: str, before: str | None = None, after: str | None = None)¶
Returns a paginated and flattened list of all top-level and nested replies of the requested thread_id
Applicable to specific use cases that do not focus on the knowledge of the depthness of the replies. This endpoint is only intended to be used on the root-level threads with replies. To paginate through the replies, you use the before and after cursors returned in the response to request the next page. The after value that is returned in the response can be supplied to the after argument and it will retrieve the next page in the paginated list. The reverse direction is true for the before value.
https://developers.facebook.com/docs/threads/reply-management#conversations
- Parameters:
thread_id – The id of the thread whose replies you want to retrieve
before – [optional] A before cursor for pagination that was returned from a previous request
after – [optional] An after cursor for pagination that was returned from a previous request
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async create_carousel_container(containers: List[ContainerStatus], text: str | None = None, reply_control: ReplyControl = ReplyControl.EVERYONE, reply_to_id: str | None = None) str ¶
Creates a carousel container.
- Parameters:
containers – A list of previously-created media containers that are to make up the carousel. You may provide between 2-10 media containers.
text – [optional] The thread’s text
reply_control – [optional] The ReplyControl policy to apply to the thread. Defaults to “everyone”.
reply_to_id – [optional] The id of an existing thread to make this thread in reply to.
- Returns:
The id of the published container https://developers.facebook.com/docs/threads/posts#step-2–publish-a-threads-media-container https://developers.facebook.com/docs/threads/posts#step-3–publish-the-carousel-container
- Raises:
OAuth2Error – If there was an issue with the OAuth2 authentication
ThreadsAccessTokenExpired – If the user’s token has expired
ThreadsAuthenticationError – If we receive an unexpected OAuth-related response from Threads
ThreadsResponseError – If we receive an unexpected response from Threads
ThreadsInvalidParameter – If you provide anything but 2-10 containers that are all in a state of “FINISHED”.
RuntimeError – If the session is missing
- async create_container(text: str | None = None, media: Media | None = None, reply_control: ReplyControl = ReplyControl.EVERYONE, reply_to_id: str | None = None, is_carousel_item: bool = False) str ¶
Creates a media container.
While text and media are both optional, you must provide at least one or the other.
- Parameters:
text – [optional] The thread’s text
media – [optional] The Media object
reply_control – [optional] The ReplyControl policy to apply to the thread. Defaults to ReplyControl.EVERYONE.
reply_to_id – [optional] The id of an existing thread to make this thread in reply to.
is_carousel_item – A boolean indicating whether this is a media container that will be added to a carousel container
- Returns:
The id of the published container
https://developers.facebook.com/docs/threads/posts#step-2–publish-a-threads-media-container
https://developers.facebook.com/docs/threads/posts#step-3–publish-the-carousel-container
- Raises:
OAuth2Error – If there was an issue with the OAuth2 authentication
ThreadsAccessTokenExpired – If the user’s token has expired
ThreadsAuthenticationError – If we receive an unexpected OAuth-related response from Threads
ThreadsResponseError – If we receive an unexpected response from Threads
RuntimeError – If the session is missing
- async insights(thread_id: str)¶
Retrieve the available insights metrics
Returned metrics do not capture nested replies’ metrics.
https://developers.facebook.com/docs/threads/insights#media-insights
- Parameters:
thread_id – The thread media id whose metrics you’re requesting
- Returns:
The JSON response as a dict. Requests all available metrics.
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async manage_reply(reply_id: str, hide: bool)¶
Hide/unhide any top-level replies.
This will automatically hide/unhide all the nested replies. Note: Replies nested deeper than the top-level reply cannot be targeted in isolation to be hidden/unhidden.
https://developers.facebook.com/docs/threads/reply-management#hide-replies
- Parameters:
reply_id – The id of the reply whose visibility you want to change
hide – Whether to hide the reply or not
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async publish_container(container_id: str) Dict[Any, Any] ¶
Publish a container that has already been created.
- Parameters:
container_id – The id of the container to publish. ids are returned from create_container and create_carousel_container
- Returns:
The id of the published container
https://developers.facebook.com/docs/threads/posts#step-2–publish-a-threads-media-container
https://developers.facebook.com/docs/threads/posts#step-3–publish-the-carousel-container
- Raises:
OAuth2Error – If there was an issue with the OAuth2 authentication
ThreadsAccessTokenExpired – If the user’s token has expired
ThreadsAuthenticationError – If we receive an unexpected OAuth-related response from Threads
ThreadsResponseError – If we receive an unexpected response from Threads
RuntimeError – If the session is missing
- async publishing_limit() Any ¶
The user’s current Threads API usage total
https://developers.facebook.com/docs/threads/troubleshooting#retrieve-publishing-quota-limit
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async replies(thread_id: str)¶
Returns the immediate replies of the requested thread_id
https://developers.facebook.com/docs/threads/reply-management#replies
- Parameters:
thread_id – The id of the thread whose immediate replies you want to retrieve
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- property session: ClientSession | None¶
- async thread(thread_id: str)¶
Retrieve an individual thread
https://developers.facebook.com/docs/threads/threads-media#retrieve-a-single-threads-media-object
- Parameters:
thread_id – The id of the thread you want to retrieve
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async threads(since: date | str | None = None, until: date | str | None = None, limit: int | None = None, before: str | None = None, after: str | None = None)¶
A paginated list of all threads created by the user
Returns a paginated list of threads made by the user, including reposts. The number of threads returned is controlled by limit. The window of threads being queried is controlled by since and until. To paginate through that window, you use the before and after cursors returned in the response to request the next page. The after value that is returned in the response can be supplied to the after argument and it will retrieve the next page in the paginated list. The reverse direction is true for the before value.
https://developers.facebook.com/docs/threads/threads-media#retrieve-a-list-of-all-a-user-s-threads
- Parameters:
since – [optional] The starting date of the time window you are requesting
until – [optional] The ending date of the time window you are requesting
limit – [optional] The maximum number of threads to return. Defaults to 25.
before – [optional] A before cursor for pagination that was returned from a previous request
after – [optional] An after cursor for pagination that was returned from a previous request
- Returns:
The JSON response as a dict
- Raises:
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- async user_insights(metrics: Literal['views', 'likes', 'replies', 'reposts', 'quotes', 'followers_count', 'follower_demographics'] | List[Literal['views', 'likes', 'replies', 'reposts', 'quotes', 'followers_count', 'follower_demographics']], since: datetime | None = None, until: datetime | None = None, breakdown: Literal['age', 'city', 'country', 'gender'] | None = None) Any ¶
Retrieve the available user insights metrics
https://developers.facebook.com/docs/threads/insights#user-insights
- Parameters:
metrics – The metric or metrics you want to retrieve (see linked official docs)
since – [optional] The starting datetime of the time window you are requesting
until – [optional] The ending datetime of the time window you are requesting
breakdown – [optional] Required when requesting follower_demographic metrics
- Returns:
The JSON response as a dict
- Raises:
ThreadsInvalidParameter – If you request a non-existent metric or fail to provide breakdown when required
ThreadsAccessTokenExpired – If the user’s token has expired
RuntimeError – If the session is missing
- class pythreads.api.ContainerStatus(id: str, status: pythreads.api.PublishingStatus, error: pythreads.api.PublishingError | None = None)¶
Bases:
object
- error: PublishingError | None = None¶
- id: str¶
- status: PublishingStatus¶
- class pythreads.api.Media(type: pythreads.api.MediaType, url: str)¶
Bases:
object
- url: str¶
- class pythreads.api.MediaType(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
str
,Enum
- CAROUSEL = 'CAROUSEL'¶
- IMAGE = 'IMAGE'¶
- TEXT = 'TEXT'¶
- VIDEO = 'VIDEO'¶
- class pythreads.api.PublishingError(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
str
,Enum
- FAILED_DOWNLOADING_VIDEO = 'FAILED_DOWNLOADING_VIDEO'¶
- FAILED_PROCESSING_AUDIO = 'FAILED_PROCESSING_AUDIO'¶
- FAILED_PROCESSING_VIDEO = 'FAILED_PROCESSING_VIDEO'¶
- INVALID_ASPEC_RATIO = 'INVALID_ASPEC_RATIO'¶
- INVALID_AUDIO_CHANNELS = 'INVALID_AUDIO_CHANNELS'¶
- INVALID_AUDIO_CHANNEL_LAYOUT = 'INVALID_AUDIO_CHANNEL_LAYOUT'¶
- INVALID_BIT_RATE = 'INVALID_BIT_RATE'¶
- INVALID_DURATION = 'INVALID_DURATION'¶
- INVALID_FRAME_RATE = 'INVALID_FRAME_RATE'¶
- UNKNOWN = 'UNKNOWN'¶
- class pythreads.api.PublishingStatus(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
str
,Enum
- ERROR = 'ERROR'¶
- EXPIRED = 'EXPIRED'¶
- FINISHED = 'FINISHED'¶
- IN_PROGRESS = 'IN_PROGRESS'¶
- PUBLISHED = 'PUBLISHED'¶
- class pythreads.api.ReplyControl(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
str
,Enum
- ACCOUNTS_YOU_FOLLOW = 'accounts_you_follow'¶
- EVERYONE = 'everyone'¶
- MENTIONED_ONLY = 'mentioned_only'¶
- exception pythreads.api.ThreadsInvalidParameter¶
Bases:
ValueError
- exception pythreads.api.ThreadsResponseError(response: dict)¶
Bases:
Exception
Configuration Module¶
Credentials Module¶
- class pythreads.credentials.Credentials(user_id: 'str', scopes: 'List[str]', short_lived: 'bool', access_token: 'str', expiration: 'datetime')¶
Bases:
object
- access_token: str¶
- expiration: datetime¶
- expired() bool ¶
- expires_in() int ¶
Number of seconds before these credentials’ access token expires.
- static from_json(json_str: str) Credentials ¶
- scopes: List[str]¶
- short_lived: bool¶
- to_json() str ¶
- user_id: str¶
Threads Module¶
- class pythreads.threads.Threads¶
Bases:
object
- ALL_SCOPES = ['threads_basic', 'threads_content_publish', 'threads_manage_insights', 'threads_manage_replies', 'threads_read_replies']¶
- static authorization_url(config: Configuration | None = None) Tuple[str, str] ¶
Constructs an authorization_url and opaque state value.
You must store the state value in the user’s session so that you can retrieve it later and redirect the user to the authorization_url. When the user is redirected back to your redirect_uri, you will validate the authentication using complete_authentication.
If you do not pass a Threads.Configuration instance, this method will load with the default configuration of all scopes and the THREADS_APP_ID, THREADS_API_SECRET, and THREADS_REDIRECT_URI environment variables.
- Parameters:
config – [optional] A Threads.Configuration instance
- Returns:
A tuple of (authorization_url, state), both being strings.
- Raises:
OAuth2Error – An error occured in the OAuth2 flow. Check the error and description fields for more info.
- static build_graph_api_url(path, params: dict | None = None, access_token=None, base_url=None)¶
- static complete_authorization(callback_url: str, state: str, long_lived_token: bool = True, config: Configuration | None = None) Credentials ¶
state: the state string that was returned from the authorization_url method
- static fetch_long_lived_token(access_token: str, expiration: datetime, config: Configuration | None = None) Tuple[str, datetime] ¶
- static fetch_user_id_and_token(request_url: str, state: str, config: Configuration | None = None) Tuple[str, str, datetime] ¶
Exchanges authorization code for a short-lived OAuth2 API token (valid for 1 hour).
Once you have redirected the user to the URL generated by the authorization_url method, Threads will redirect the user back to your redirect_uri, appending several request parameters to the URL. Call this method with that full request URL. It will extract the authorization code and state parameters, verify the state parameter to protect against CSRF attacks, and then call the Threads API to exchange the authorization code for a token.
- Parameters:
request_url – the full request URL made by Threads to your redirect_uri
- Returns:
A tuple of (user_id, access_token, access_token_expiration)
- Raises:
OAuth2Error – An error occured in the OAuth2 flow. Check the error and description fields for more info.
- static load_configuration(scopes: List[str] | None = None, app_id: str | None = None, api_secret: str | None = None, redirect_uri: str | None = None) Configuration ¶
- static refresh_long_lived_token(credentials: Credentials) Tuple[str, datetime] ¶
- exception pythreads.threads.ThreadsAccessTokenExpired¶
Bases:
RuntimeError
- exception pythreads.threads.ThreadsAuthenticationError¶
Bases:
RuntimeError