https://twittercommunity.com/t/announcing-the-deprecation-of-v1-1-statuses-filter-endpoint/182960
+++ /dev/null
-.. _asyncstream_reference:
-
-.. currentmodule:: tweepy.asynchronous
-
-********************
-:class:`AsyncStream`
-********************
-
-.. autoclass:: AsyncStream
- :members:
- :inherited-members:
- :member-order: bysource
.. literalinclude:: ../examples/API_v1/rate_limit_handling.py
- .. tab:: Streaming
-
- .. literalinclude:: ../examples/API_v1/streaming.py
-
.. tab:: API v2
.. tabs::
identifying the inclusive start and exclusive end of the displayable content
of the Tweet.
-Streaming
-=========
-
-By default, the Status objects from streams may contain an ``extended_tweet``
-attribute representing the equivalent field in the raw data/payload for the
-Tweet. This attribute/field will only exist for extended Tweets, containing a
-dictionary of sub-fields. The ``full_text`` sub-field/key of this dictionary
-will contain the full, untruncated text of the Tweet, and the ``entities``
-sub-field/key will contain the full set of entities. If there are extended
-entities, the ``extended_entities`` sub-field/key will contain the full set of
-those. Additionally, the ``display_text_range`` sub-field/key will contain an
-array of two Unicode code point indices, identifying the inclusive start and
-exclusive end of the displayable content of the Tweet.
-
Handling Retweets
=================
itself a Status object, the ``full_text`` attribute of the Retweeted Status
object can be used instead.
-This also applies similarly to Status objects/payloads that are Retweets from
-streams. The dictionary from the ``extended_tweet`` attribute/field contains a
-``full_text`` sub-field/key that may be truncated with an ellipsis character.
-Instead, the ``extended_tweet`` attribute/field of the Retweeted Status (from
-the ``retweeted_status`` attribute/field) can be used.
-
Examples
========
If ``status`` is a Retweet, ``status.full_text`` could be truncated.
-This Status event handler for a :class:`Stream` prints the full text of the
-Tweet, or if it's a Retweet, the full text of the Retweeted Tweet::
-
- def on_status(self, status):
- if hasattr(status, "retweeted_status"): # Check if Retweet
- try:
- print(status.retweeted_status.extended_tweet["full_text"])
- except AttributeError:
- print(status.retweeted_status.text)
- else:
- try:
- print(status.extended_tweet["full_text"])
- except AttributeError:
- print(status.text)
-
-If ``status`` is a Retweet, it will not have an ``extended_tweet`` attribute,
-and ``status.text`` could be truncated.
-
.. rubric:: Footnotes
.. [#] https://twittercommunity.com/t/upcoming-changes-to-simplify-replies-and-links-in-tweets/67497
--------------------------------------------------------------
If you have Essential access to the Twitter API, you won't be able to access
-Twitter API v1.1. This includes all :class:`API` methods and :class:`Stream`.
+Twitter API v1.1. This includes all :class:`API` methods.
You can use Twitter API v2 with :class:`Client` or apply for Elevated access.
Instead, you can use :meth:`API.verify_credentials`.
-Where did ``StreamListener`` go?
---------------------------------
-
-If you're attempting to import ``StreamListener`` with Tweepy v4, you'll get an
-:class:`AttributeError` about ``tweepy`` not having a ``StreamListener``
-attribute.
-
-This is because :ref:`Tweepy v4.0.0 <Version 4.0.0 (2021-09-25)>` merged
-``StreamListener`` into :class:`Stream`.
-
-To use Tweepy v4, you'll need to update your code to subclass :class:`Stream`
-instead.
-
Twitter API v2
==============
:caption: Twitter API v1.1 Reference
api.rst
- stream.rst
- asyncstream.rst
exceptions.rst
v1_models.rst
v1_pagination.rst
+++ /dev/null
-.. _stream_reference:
-
-.. currentmodule:: tweepy
-
-***************
-:class:`Stream`
-***************
-
-.. autoclass:: Stream
- :members:
- :inherited-members:
- :member-order: bysource
throughput. For further information, see
https://developer.twitter.com/en/docs/tutorials/consuming-streaming-data
-:class:`Stream` allows `filtering <v1.1 filtering_>`_ and
-`sampling <v1.1 sampling_>`_ of realtime Tweets using Twitter API v1.1.
+The Twitter API v1.1 streaming endpoints, `statuses/filter`_ and
+`statuses/sample`_, have been deprecated and retired.
:class:`StreamingClient` allows `filtering <v2 filtering_>`_ and
`sampling <v2 sampling_>`_ of realtime Tweets using Twitter API v2.
-.. _v1.1 filtering: https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/overview
-.. _v1.1 sampling: https://developer.twitter.com/en/docs/twitter-api/v1/tweets/sample-realtime/overview
+.. _statuses/filter: https://twittercommunity.com/t/announcing-the-deprecation-of-v1-1-statuses-filter-endpoint/182960
+.. _statuses/sample: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
.. _v2 filtering: https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/introduction
.. _v2 sampling: https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/introduction
-Using :class:`Stream`
-=====================
-
-To use :class:`Stream`, an instance of it needs to be initialized with Twitter
-API credentials (Consumer Key, Consumer Secret, Access Token, Access Token
-Secret)::
-
- import tweepy
-
- stream = tweepy.Stream(
- "Consumer Key here", "Consumer Secret here",
- "Access Token here", "Access Token Secret here"
- )
-
-Then, :meth:`Stream.filter` or :meth:`Stream.sample` can be used to connect to
-and run a stream::
-
- stream.filter(track=["Tweepy"])
-
-Data received from the stream is passed to :meth:`Stream.on_data`. This method
-handles sending the data to other methods based on the message type. For
-example, if a Tweet is received from the stream, the raw data is sent to
-:meth:`Stream.on_data`, which constructs a :class:`Status` object and passes it
-to :meth:`Stream.on_status`. By default, the other methods, besides
-:meth:`Stream.on_data`, that receive the data from the stream, simply log the
-data received, with the :ref:`logging level <python:levels>` dependent on the
-type of the data.
-
-To customize the processing of the stream data, :class:`Stream` needs to be
-subclassed. For example, to print the IDs of every Tweet received::
-
- class IDPrinter(tweepy.Stream):
-
- def on_status(self, status):
- print(status.id)
-
-
- printer = IDPrinter(
- "Consumer Key here", "Consumer Secret here",
- "Access Token here", "Access Token Secret here"
- )
- printer.sample()
-
Using :class:`StreamingClient`
==============================
Threading
=========
-:meth:`Stream.filter`, :meth:`Stream.sample`, :meth:`StreamingClient.filter`,
-and :meth:`StreamingClient.sample` all have a ``threaded`` parameter. When set
-to ``True``, the stream will run in a separate
+:meth:`StreamingClient.filter` and :meth:`StreamingClient.sample` have a
+``threaded`` parameter. When set to ``True``, the stream will run in a separate
:ref:`thread <python:thread-objects>`, which is returned by the call to the
method. For example::
- thread = stream.filter(follow=[1072250532645998596], threaded=True)
-
-or::
-
thread = streaming_client.sample(threaded=True)
Handling Errors
===============
-Both :class:`Stream` and :class:`StreamingClient` have multiple methods to
-handle errors during streaming.
+:class:`StreamingClient` has multiple methods to handle errors during
+streaming.
-:meth:`Stream.on_closed` / :meth:`StreamingClient.on_closed` is called when the
-stream is closed by Twitter.
+:meth:`StreamingClient.on_closed` is called when the stream is closed by
+Twitter.
-:meth:`Stream.on_connection_error` /
:meth:`StreamingClient.on_connection_error` is called when the stream
encounters a connection error.
-:meth:`Stream.on_request_error` / :meth:`StreamingClient.on_request_error` is
-called when an error is encountered while trying to connect to the stream.
+:meth:`StreamingClient.on_request_error` is called when an error is encountered
+while trying to connect to the stream.
When these errors are encountered and ``max_retries``, which defaults to
-infinite, hasn't been exceeded yet, the :class:`Stream` /
-:class:`StreamingClient` instance will attempt to reconnect the stream after an
-appropriate amount of time. By default, both versions of all three of these
-methods log an error. To customize that handling, they can be overridden in a
-subclass::
-
- class ConnectionTester(tweepy.Stream):
-
- def on_connection_error(self):
- self.disconnect()
-
-::
+infinite, hasn't been exceeded yet, the :class:`StreamingClient` instance will
+attempt to reconnect the stream after an appropriate amount of time. By
+default, all three of these methods log an error. To customize that handling,
+they can be overridden in a subclass::
class ConnectionTester(tweepy.StreamingClient):
def on_connection_error(self):
self.disconnect()
-:meth:`Stream.on_request_error` / :meth:`StreamingClient.on_request_error` is
-also passed the HTTP status code that was encountered. The HTTP status codes
-reference for the Twitter API can be found at
+:meth:`StreamingClient.on_request_error` is also passed the HTTP status code
+that was encountered. The HTTP status codes reference for the Twitter API can
+be found at
https://developer.twitter.com/en/support/twitter-api/error-troubleshooting.
-:meth:`Stream.on_exception` / :meth:`StreamingClient.on_exception` is called
-when an unhandled exception occurs. This is fatal to the stream, and by
-default, an exception is logged.
+:meth:`StreamingClient.on_exception` is called when an unhandled exception
+occurs. This is fatal to the stream, and by default, an exception is logged.
+++ /dev/null
-import tweepy
-
-
-consumer_key = ""
-consumer_secret = ""
-access_token = ""
-access_token_secret = ""
-
-# Subclass Stream to print IDs of Tweets received
-class IDPrinter(tweepy.Stream):
-
- def on_status(self, status):
- print(status.id)
-
-# Initialize instance of the subclass
-printer = IDPrinter(
- consumer_key, consumer_secret,
- access_token, access_token_secret
-)
-
-# Filter realtime Tweets by keyword
-printer.filter(track=["Twitter"])
from tweepy.poll import Poll
from tweepy.space import Space
from tweepy.streaming import (
- Stream, StreamingClient, StreamResponse, StreamRule
+ StreamingClient, StreamResponse, StreamRule
)
from tweepy.tweet import ReferencedTweet, Tweet
from tweepy.user import User
from tweepy.asynchronous.client import AsyncClient
from tweepy.asynchronous.pagination import AsyncPaginator
-from tweepy.asynchronous.streaming import AsyncStream, AsyncStreamingClient
+from tweepy.asynchronous.streaming import AsyncStreamingClient
import traceback
import aiohttp
-from oauthlib.oauth1 import Client as OAuthClient
-from yarl import URL
import tweepy
from tweepy.asynchronous.client import AsyncBaseClient
from tweepy.client import Response
from tweepy.errors import TweepyException
-from tweepy.models import Status
from tweepy.streaming import StreamResponse, StreamRule
from tweepy.tweet import Tweet
log.error("Stream encountered HTTP Error: %d", status_code)
-class AsyncStream(AsyncBaseStream):
- """Stream realtime Tweets asynchronously with Twitter API v1.1
-
- .. deprecated:: 4.13
- `The Twitter API v1.1 streaming statuses/filter endpoint that`_
- :class:`AsyncStream` `uses has a formal deprecation date of
- March 9, 2023.`_
-
- .. note::
-
- New Twitter Developer Apps created on or after April 29, 2022 `will not
- be able to gain access to v1.1 statuses/filter`_, the Twitter API v1.1
- endpoint that :class:`AsyncStream` uses. Twitter API v2 can be used
- instead with :class:`AsyncStreamingClient`.
-
- .. versionadded:: 4.0
-
- .. versionchanged:: 4.13
- Removed ``sample``, ``on_delete``, ``on_scrub_geo``,
- ``on_status_withheld``, and ``on_user_withheld`` methods, as `the
- Twitter API v1.1 statuses/sample endpoint and compliance messages on
- the Twitter API v1.1 statuses/filter endpoint have been retired`_
-
- Parameters
- ----------
- consumer_key: str
- Twitter API Consumer Key
- consumer_secret: str
- Twitter API Consumer Secret
- access_token: str
- Twitter API Access Token
- access_token_secret: str
- Twitter API Access Token Secret
- max_retries: int | None
- Number of times to attempt to (re)connect the stream.
- proxy: str | None
- URL of the proxy to use when connecting to the stream
-
- Attributes
- ----------
- session : aiohttp.ClientSession | None
- Aiohttp client session used to connect to the API
- task : asyncio.Task | None
- The task running the stream
- user_agent : str
- User agent used when connecting to the API
-
-
- .. _will not be able to gain access to v1.1 statuses/filter: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
- .. _the Twitter API v1.1 statuses/sample endpoint and compliance messages
- on the Twitter API v1.1 statuses/filter endpoint have been retired: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
- .. _The Twitter API v1.1 streaming statuses/filter endpoint that: https://twittercommunity.com/t/announcing-the-deprecation-of-v1-1-statuses-filter-endpoint/182960
- .. _uses has a formal deprecation date of March 9, 2023.: https://twittercommunity.com/t/announcing-the-deprecation-of-v1-1-statuses-filter-endpoint/182960
- """
-
- def __init__(self, consumer_key, consumer_secret, access_token,
- access_token_secret, **kwargs):
- """__init__( \
- consumer_key, consumer_secret, access_token, access_token_secret, \
- *, max_retries=inf, proxy=None \
- )
- """
- self.consumer_key = consumer_key
- self.consumer_secret = consumer_secret
- self.access_token = access_token
- self.access_token_secret = access_token_secret
- super().__init__(**kwargs)
-
- async def _connect(
- self, method, endpoint, params={}, headers=None, body=None
- ):
- oauth_client = OAuthClient(self.consumer_key, self.consumer_secret,
- self.access_token, self.access_token_secret)
- url = f"https://stream.twitter.com/1.1/{endpoint}.json"
- url = str(URL(url).with_query(sorted(params.items())))
- await super()._connect(
- method, url, headers=headers, body=body, oauth_client=oauth_client,
- timeout=90
- )
-
- def filter(self, *, follow=None, track=None, locations=None,
- filter_level=None, languages=None, stall_warnings=False):
- """Filter realtime Tweets
-
- .. deprecated:: 4.10
- `The delivery of compliance messages through the Twitter API v1.1
- endpoint this method uses has been deprecated, and they will stop
- being delivered beginning October 29, 2022.`_ Twitter API v2 can be
- used instead with :meth:`AsyncStreamingClient.filter` and/or
- :class:`AsyncClient` :ref:`batch compliance <Batch compliance>`
- methods.
-
- Parameters
- ----------
- follow: list[int | str] | None
- A list of user IDs, indicating the users to return statuses for in
- the stream. See https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/guides/basic-stream-parameters
- for more information.
- track: list[str] | None
- Keywords to track. Phrases of keywords are specified by a list. See
- https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters
- for more information.
- locations: list[float] | None
- Specifies a set of bounding boxes to track. See
- https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters
- for more information.
- filter_level : str | None
- Setting this parameter to one of none, low, or medium will set the
- minimum value of the filter_level Tweet attribute required to be
- included in the stream. The default value is none, which includes
- all available Tweets.
-
- When displaying a stream of Tweets to end users (dashboards or live
- feeds at a presentation or conference, for example) it is suggested
- that you set this value to medium.
- languages : list[str] | None
- Setting this parameter to a comma-separated list of `BCP 47`_
- language identifiers corresponding to any of the languages listed
- on Twitter’s `advanced search`_ page will only return Tweets that
- have been detected as being written in the specified languages. For
- example, connecting with language=en will only stream Tweets
- detected to be in the English language.
- stall_warnings: bool | None
- Specifies whether stall warnings should be delivered. See
- https://developer.twitter.com/en/docs/tweets/filter-realtime/guides/basic-stream-parameters
- for more information.
-
- Raises
- ------
- TweepyException
- When the stream is already connected or when the number of location
- coordinates is not a multiple of 4
-
- Returns
- -------
- asyncio.Task
- The task running the stream
-
- References
- ----------
- https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/api-reference/post-statuses-filter
-
- .. _BCP 47: https://tools.ietf.org/html/bcp47
- .. _advanced search: https://twitter.com/search-advanced
- .. _The delivery of compliance messages through the Twitter API v1.1
- endpoint this method uses has been deprecated, and they will stop
- being delivered beginning October 29, 2022.: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
- """
- if self.task is not None and not self.task.done():
- raise TweepyException("Stream is already connected")
-
- endpoint = "statuses/filter"
- headers = {"Content-Type": "application/x-www-form-urlencoded"}
-
- body = {}
- if follow is not None:
- body["follow"] = ','.join(map(str, follow))
- if track is not None:
- body["track"] = ','.join(map(str, track))
- if locations is not None:
- if len(locations) % 4:
- raise TweepyException(
- "Number of location coordinates should be a multiple of 4"
- )
- body["locations"] = ','.join(
- f"{location:.4f}" for location in locations
- )
- if filter_level is not None:
- body["filter_level"] = filter_level
- if languages is not None:
- body["language"] = ','.join(map(str, languages))
- if stall_warnings:
- body["stall_warnings"] = "true"
-
- self.task = asyncio.create_task(
- self._connect("POST", endpoint, headers=headers, body=body or None)
- )
- # Use name parameter when support for Python 3.7 is dropped
- return self.task
-
- async def on_data(self, raw_data):
- """|coroutine|
-
- This is called when raw data is received from the stream.
- This method handles sending the data to other methods, depending on the
- message type.
-
- Parameters
- ----------
- raw_data : JSON
- The raw data from the stream
-
- References
- ----------
- https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/guides/streaming-message-types
- """
- data = json.loads(raw_data)
-
- if "in_reply_to_status_id" in data:
- status = Status.parse(None, data)
- return await self.on_status(status)
- if "disconnect" in data:
- return await self.on_disconnect_message(data["disconnect"])
- if "limit" in data:
- return await self.on_limit(data["limit"]["track"])
- if "warning" in data:
- return await self.on_warning(data["warning"])
-
- log.warning("Received unknown message type: %s", raw_data)
-
- async def on_status(self, status):
- """|coroutine|
-
- This is called when a status is received.
-
- Parameters
- ----------
- status : Status
- The Status received
- """
- log.debug("Received status: %d", status.id)
-
- async def on_disconnect_message(self, message):
- """|coroutine|
-
- This is called when a disconnect message is received.
-
- Parameters
- ----------
- message : JSON
- The disconnect message
- """
- log.warning("Received disconnect message: %s", message)
-
- async def on_limit(self, track):
- """|coroutine|
-
- This is called when a limit notice is received.
-
- Parameters
- ----------
- track : int
- Total count of the number of undelivered Tweets since the
- connection was opened
- """
- log.debug("Received limit notice: %d", track)
-
- async def on_warning(self, notice):
- """|coroutine|
-
- This is called when a stall warning message is received.
-
- Parameters
- ----------
- warning : JSON
- The stall warning
- """
- log.warning("Received stall warning: %s", notice)
-
-
class AsyncStreamingClient(AsyncBaseClient, AsyncBaseStream):
"""Stream realtime Tweets asynchronously with Twitter API v2
from typing import NamedTuple
import requests
-from requests_oauthlib import OAuth1
import urllib3
import tweepy
from tweepy.client import BaseClient, Response
from tweepy.errors import TweepyException
-from tweepy.models import Status
from tweepy.tweet import Tweet
log = logging.getLogger(__name__)
log.error("Stream encountered HTTP error: %d", status_code)
-class Stream(BaseStream):
- """Filter realtime Tweets with Twitter API v1.1
-
- .. deprecated:: 4.13
- `The Twitter API v1.1 streaming statuses/filter endpoint that`_
- :class:`Stream` `uses has a formal deprecation date of March 9, 2023.`_
-
- .. note::
-
- New Twitter Developer Apps created on or after April 29, 2022 `will not
- be able to gain access to v1.1 statuses/filter`_, the Twitter API v1.1
- endpoint that :class:`Stream` uses. Twitter API v2 can be used instead
- with :class:`StreamingClient`.
-
- .. versionchanged:: 4.13
- Removed ``sample``, ``on_delete``, ``on_scrub_geo``,
- ``on_status_withheld``, and ``on_user_withheld`` methods, as `the
- Twitter API v1.1 statuses/sample endpoint and compliance messages on
- the Twitter API v1.1 statuses/filter endpoint have been retired`_
-
- Parameters
- ----------
- consumer_key : str
- Twitter API Consumer Key
- consumer_secret : str
- Twitter API Consumer Secret
- access_token: str
- Twitter API Access Token
- access_token_secret : str
- Twitter API Access Token Secret
- chunk_size : int
- The default socket.read size. Default to 512, less than half the size
- of a Tweet so that it reads Tweets with the minimal latency of 2 reads
- per Tweet. Values higher than ~1kb will increase latency by waiting for
- more data to arrive but may also increase throughput by doing fewer
- socket read calls.
- daemon : bool
- Whether or not to use a daemon thread when using a thread to run the
- stream
- max_retries : int
- Max number of times to retry connecting the stream
- proxy : str | None
- URL of the proxy to use when connecting to the stream
- verify : bool | str
- Either a boolean, in which case it controls whether to verify the
- server’s TLS certificate, or a string, in which case it must be a path
- to a CA bundle to use.
-
- Attributes
- ----------
- running : bool
- Whether there's currently a stream running
- session : :class:`requests.Session`
- Requests Session used to connect to the stream
- thread : :class:`threading.Thread` | None
- Thread used to run the stream
- user_agent : str
- User agent used when connecting to the stream
-
-
- .. _will not be able to gain access to v1.1 statuses/filter: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
- .. _the Twitter API v1.1 statuses/sample endpoint and compliance messages
- on the Twitter API v1.1 statuses/filter endpoint have been retired: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
- .. _The Twitter API v1.1 streaming statuses/filter endpoint that: https://twittercommunity.com/t/announcing-the-deprecation-of-v1-1-statuses-filter-endpoint/182960
- .. _uses has a formal deprecation date of March 9, 2023.: https://twittercommunity.com/t/announcing-the-deprecation-of-v1-1-statuses-filter-endpoint/182960
- """
-
- def __init__(self, consumer_key, consumer_secret, access_token,
- access_token_secret, **kwargs):
- """__init__( \
- consumer_key, consumer_secret, access_token, access_token_secret, \
- chunk_size=512, daemon=False, max_retries=inf, proxy=None, \
- verify=True \
- )
- """
- self.consumer_key = consumer_key
- self.consumer_secret = consumer_secret
- self.access_token = access_token
- self.access_token_secret = access_token_secret
- super().__init__(**kwargs)
-
- def _connect(self, method, endpoint, **kwargs):
- auth = OAuth1(self.consumer_key, self.consumer_secret,
- self.access_token, self.access_token_secret)
- url = f"https://stream.twitter.com/1.1/{endpoint}.json"
- super()._connect(method, url, auth=auth, timeout=90, **kwargs)
-
- def filter(self, *, follow=None, track=None, locations=None,
- filter_level=None, languages=None, stall_warnings=False,
- threaded=False):
- """Filter realtime Tweets
-
- .. deprecated:: 4.9
- `The delivery of compliance messages through the Twitter API v1.1
- endpoint this method uses has been deprecated, and they will stop
- being delivered beginning October 29, 2022.`_ Twitter API v2 can be
- used instead with :meth:`StreamingClient.filter` and/or
- :class:`Client` :ref:`batch compliance <Batch compliance>` methods.
-
- Parameters
- ----------
- follow : list[int | str] | None
- User IDs, indicating the users to return statuses for in the stream
- track : list[str] | None
- Keywords to track
- locations : list[float] | None
- Specifies a set of bounding boxes to track
- filter_level : str | None
- Setting this parameter to one of none, low, or medium will set the
- minimum value of the filter_level Tweet attribute required to be
- included in the stream. The default value is none, which includes
- all available Tweets.
-
- When displaying a stream of Tweets to end users (dashboards or live
- feeds at a presentation or conference, for example) it is suggested
- that you set this value to medium.
- languages : list[str] | None
- Setting this parameter to a comma-separated list of `BCP 47`_
- language identifiers corresponding to any of the languages listed
- on Twitter’s `advanced search`_ page will only return Tweets that
- have been detected as being written in the specified languages. For
- example, connecting with language=en will only stream Tweets
- detected to be in the English language.
- stall_warnings : bool
- Specifies whether stall warnings should be delivered
- threaded : bool
- Whether or not to use a thread to run the stream
-
- Raises
- ------
- TweepyException
- When the stream is already connected or when the number of location
- coordinates is not a multiple of 4
-
- Returns
- -------
- threading.Thread | None
- The thread if ``threaded`` is set to ``True``, else ``None``
-
- References
- ----------
- https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/api-reference/post-statuses-filter
-
- .. _BCP 47: https://tools.ietf.org/html/bcp47
- .. _advanced search: https://twitter.com/search-advanced
- .. _The delivery of compliance messages through the Twitter API v1.1
- endpoint this method uses has been deprecated, and they will stop
- being delivered beginning October 29, 2022.: https://twittercommunity.com/t/deprecation-announcement-removing-compliance-messages-from-statuses-filter-and-retiring-statuses-sample-from-the-twitter-api-v1-1/170500
- """
- if self.running:
- raise TweepyException("Stream is already connected")
-
- method = "POST"
- endpoint = "statuses/filter"
- headers = {"Content-Type": "application/x-www-form-urlencoded"}
-
- body = {}
- if follow:
- body["follow"] = ','.join(map(str, follow))
- if track:
- body["track"] = ','.join(map(str, track))
- if locations and len(locations) > 0:
- if len(locations) % 4:
- raise TweepyException(
- "Number of location coordinates should be a multiple of 4"
- )
- body["locations"] = ','.join(f"{l:.4f}" for l in locations)
- if filter_level:
- body["filter_level"] = filter_level
- if languages:
- body["language"] = ','.join(map(str, languages))
- if stall_warnings:
- body["stall_warnings"] = stall_warnings
-
- if threaded:
- return self._threaded_connect(method, endpoint, headers=headers,
- body=body)
- else:
- self._connect(method, endpoint, headers=headers, body=body)
-
- def on_data(self, raw_data):
- """This is called when raw data is received from the stream.
- This method handles sending the data to other methods based on the
- message type.
-
- Parameters
- ----------
- raw_data : JSON
- The raw data from the stream
-
- References
- ----------
- https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/guides/streaming-message-types
- """
- data = json.loads(raw_data)
-
- if "in_reply_to_status_id" in data:
- status = Status.parse(None, data)
- return self.on_status(status)
- if "disconnect" in data:
- return self.on_disconnect_message(data["disconnect"])
- if "limit" in data:
- return self.on_limit(data["limit"]["track"])
- if "warning" in data:
- return self.on_warning(data["warning"])
-
- log.error("Received unknown message type: %s", raw_data)
-
- def on_status(self, status):
- """This is called when a status is received.
-
- Parameters
- ----------
- status : Status
- The Status received
- """
- log.debug("Received status: %d", status.id)
-
- def on_disconnect_message(self, message):
- """This is called when a disconnect message is received.
-
- Parameters
- ----------
- message : JSON
- The disconnect message
- """
- log.warning("Received disconnect message: %s", message)
-
- def on_limit(self, track):
- """This is called when a limit notice is received.
-
- Parameters
- ----------
- track : int
- Total count of the number of undelivered Tweets since the
- connection was opened
- """
- log.debug("Received limit notice: %d", track)
-
- def on_warning(self, warning):
- """This is called when a stall warning message is received.
-
- Parameters
- ----------
- warning : JSON
- The stall warning
- """
- log.warning("Received stall warning: %s", warning)
-
-
class StreamingClient(BaseClient, BaseStream):
"""Filter and sample realtime Tweets with Twitter API v2