Tweepy: access the Twitter API

The Python script trump.py prints the most recent tweets that mention Trump.

Install a Python module.

Tweepy is the Python module for Twitter. Let’s get this module from the website PyPI, the Python Package Index. This will allow our Python script to say import tweepy. In the Microsoft Windows command prompt window, you have to say py.exe -m pip instead of pip3.

pip3 list
pip3 search tweepy
tweepy (3.8.0)             - Twitter library for python

pip3 install tweepy
pip3 list
tweepy (3.8.0)

pip3 show tweepy
Name: tweepy
Version: 3.8.0
Summary: Twitter library for python
Home-page: http://github.com/tweepy/tweepy
Author: Joshua Roesslein
Author-email: tweepy@googlegroups.com
License: MIT
Location: /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages
Requires: requests, six, requests-oauthlib, PySocks

cd /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages

ls -ld tweepy*
drwxr-xr-x  14 myname  mygroup  448 Nov 14 14:31 tweepy
drwxr-xr-x   9 myname  mygroup  288 Nov 14 14:31 tweepy-3.8.0.dist-info

The objects in our Python script trump.py

One of the files we just installed is named models.py, as you can see by saying

pip3 show --files tweepy
Files:
  tweepy/models.py
  etc.

The tweets in line 24 of trump.py is an object of class tweepy.models.SearchResults, but you can think of it as a list. And the reason you can think of it as a list is because line 293 of models.py says that an object of class tweepy.models.SearchResults can do everything that an object of class tweepy.models.ResultSet can do, and line 10 says that an object of class tweepy.models.ResultSet can do everything that an object of class list can do.

Each tweet in tweets in line 37 of trump.py is an object of class tweepy.models.Status; see lines 83 and 37 of models.py. An object of class models.Status has instance attributes named created_at, author, retweet_count, source, and text. The values of these attributes come from data in JSON format downloaded from twitter.

Get a consumer key and access token.

Go to
https://apps.twitter.com/app/new
and create a Twitter application.

Application Details
Name (at most 32 characters): INFO1-CE9990
Description (at least 10 characters): Python script
Website: doesn’t matter
Callback URL: leave it blank
☑ Yes, I have read and agree to the Twitter Developer Agreement.
Press Create your Twitter application.

Click on the Keys and Access Tokens tab. Copy the Consumer Key (API Key) and the Consumer Secret (API Secret). Farther down the page, copy the Access Token and Access Token Secret.

The Unicode BMP (Basic Multilingual Plane)

The BMP consists of the Unicode characters whose codes range from (hexadecimal) 0000 to FFFF inclusive. Characters with larger codes, such as some emojis, cause the print function to say

UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 13-13: Non-BMP character not supported in Tk
We therefore replace all larger characters with the Unicode replacement character FFFD (�).

We saw in Indexing that a Python string is immutable. Line 34 therefore changes the string into a list of characters as we did in Split. We then replace the emojis, and join the characters back into a string.

The Python script

trump.py

Created at = 2019-11-14 19:48:39
Author = Cristina Gonzalez
Screen name = crisgonz2017
Friends count = 304
Followers count = 386
Retweet count = 3028
Place = None
Source = Twitter for iPhone
Source URL = http://twitter.com/download/iphone
Length = 140
RT @dbongino: BREAKING�:
Our first guest, for my new interview series, for The Dan Bongino Show will be President Donald J. Trump.
The int…
--------------------------------------------------------------------------------
Created at = 2019-11-14 19:48:39
Author = Glenda Clark
Screen name = meridiangrambo
Friends count = 64
Followers count = 28
Retweet count = 0
Place = None
Source = Twitter for Android
Source URL = http://twitter.com/download/android
Length = 21
@TomFitton Trump 2020
--------------------------------------------------------------------------------
Created at = 2019-11-14 19:48:39
Author = Jaye Martin
Screen name = JayeMartin5
Friends count = 170
Followers count = 543
Retweet count = 330
Place = None
Source = Twitter for iPhone
Source URL = http://twitter.com/download/iphone
Length = 139
RT @mitchellvii: Obama added 10 million to food stamps. 6 million have quit food stamps since Trump became President.

How is this Obama's…
--------------------------------------------------------------------------------

Things to try

  1. The created_at instance attribute is a datetime.datetime object in UTC. See lines 95–96 of models.py and the function parse_datetime in lines 11–12 of utils.py. To change created_at to our local time (currently Standard Daylight Time, five hours behind UTC), change line 38 of trump.py from
        print(f"Created at = {tweet.created_at}")
    
    Created at = 2019-11-14 20:30:47
    
    to the following. The replace tells created_at that created_at is a UTC time. The astimezone converts created_at from UTC to our local time zone.
    import datetime
    
        created_at = tweet.created_at.replace(tzinfo = datetime.timezone.utc)
        created_at = created_at.astimezone()
        print(f"Created at = {created_at}")
    
    Created at = 2019-11-14 15:30:47-05:00
    
    To get a space before the -0500 offset,
        created_at = tweet.created_at.replace(tzinfo = datetime.timezone.utc)
        created_at = created_at.astimezone()
        print(f'Created at = {created_at.strftime("%Y-%m-%d %H:%M:%S %z")}')
    
    Created at = 2019-11-14 15:28:55 -05:00
    
  2. Package the code as an iterable object.
    """
    This module is tweet.py.
    
    This module creates class tweet.range, an iterable for looping through
    the most recent tweets whose text mentions a subject.  It automatically
    removes unprintable characters from each text.
    """
    
    import tweepy
    
    class range(object):
        """
        An iterable for looping through the count most recent tweets
        whose text mentions a subject.
        """
    
        #Class attributes:
    
        consumer_key = ""
        consumer_secret = ""
    
        access_token = ""
        access_token_secret = ""
    
        def __init__(self, s, count = 3):
            if not isinstance(s, str):
                raise TypeError(f"s must be of type str, not {type(s)}")
            if s == "":
                raise ValueError(f"s can't be empty.")
            if not isinstance(count, int):
                raise TypeError(f"count must be of type int, not {type(count)}")
            if count < 1:
                raise ValueError(f"count must be positive, not {count}")
            self.s = s
            self.count = count
    
        def __iter__(self):
            authenticationHandler = tweepy.OAuthHandler(range.consumer_key, range.consumer_secret)
            authenticationHandler.set_access_token(range.access_token, range.access_token_secret)
            api = tweepy.API(auth_handler = authenticationHandler)
            tweets = api.search(self.s, count = self.count)   #tweets is iterable.
            it = iter(tweets)
            return Iterator(it)
    
    
    class Iterator(object):
    
        def __init__(self, it):
            self.it = it
    
        def __iter__(self):
            return self
    
        def __next__(self):
            t = next(self.it)
            t.author.name = Iterator.replaceEmojis(t.author.name)
            t.text = Iterator.replaceEmojis(t.text)
            return t
    
        @staticmethod
        def replaceEmojis(s):
            """
            Return the argument string with each of its emojis (i.e., any character that
            does not belong to the BMP) replaced by the Unicode replacement character.
            """
            listOfCharacters = ["\uFFFD" if ord(c) >= 0x10000 else c for c in s]
            return "".join(listOfCharacters)   #Change the list back into a string.
    
    
    if __name__ == "__main__":
        import sys
        for t in range("Trump", count = 3):
            print(f"Created at = {t.created_at}")
            print(f"Author = {t.author.name}")
            print(t.text)
            print(80 * "-")
        sys.exit(0)
    
    """
    This file is importer.py.  It imports and demonstrates the module tweepy.py.
    """
    
    import sys
    import tweet   #I wrote this module.
    
    for t in tweet.range("Trump", count = 3):
        print(f"Created at = {t.created_at}")
        print(f"Author = {t.author.name}")
        print(t.text)
        print(80 * "-")
    
    print()
    print(80 * "=")
    print()
    
    for t in tweet.range("de Blasio", count = 2):
        print(f"Created at = {t.created_at}")
        print(f"Author = {t.author.name}")
        print(t.text)
        print(80 * "-")
    
    sys.exit(0)
    
    Created at = 2019-11-19 13:56:54
    Author = Jeff Santos Show
    RT @RevDrBarber: If Dems think they can beat Trump by being pragmatic & scared rather than visionary, revolutionary & bold, they better rem…
    --------------------------------------------------------------------------------
    Created at = 2019-11-19 13:56:54
    Author = Pam H8s Censorship �
    RT @gbroh10: COULD IT BE THAT TRUMP HAS BEEN SETTING UP THE LEFT ALL ALONG? @AmericanThinker
    
    #LockThemAllUpInGITMO
    
    "It is beginning to…
    --------------------------------------------------------------------------------
    Created at = 2019-11-19 13:56:54
    Author = Fleur Bleue
    RT @PeteButtigieg: There will come a day when Donald Trump is no longer in office.
    
    I am running to be the president who can stand on the r…
    --------------------------------------------------------------------------------
    
    ================================================================================
    
    Created at = 2019-11-19 13:56:06
    Author = Trump 30330
    RT @yogagenie: De Blasio says Bloomberg should apologize for more than stop-and-frisk https://t.co/qFHVzpfJq9
    --------------------------------------------------------------------------------
    Created at = 2019-11-19 13:55:59
    Author = Liberty
    RT @JamesEHiggins: NYC parents plead with Comrade @BilldeBlasio (D-NY) to spare Gifted and Talented classes -- one of the few NYC programs…
    --------------------------------------------------------------------------------