Search code examples
pythongoogle-sheetstweepygspread

Modified tweepy stream class


I have a project to practice my Python skills:

  1. To extract some tweets coordinates with Tweepy Stream
  2. To put them into a Google spreadsheet
  3. Then use the Google spreadsheet to create a map in CartoDB

I am already able to do all these things independently. Now, the challenge is to make everything work together! :)

To update my Google Spreadsheet, I am using gspread.

However, to update a cell, I need to indicate the row and column of the cell like this:

worksheet.update_acell('B1', 'Bingo!')

I am trying to have a counter in my script extracting the tweets. The goal is to have B1 to change to B2, then B3, then B4, each time a tweet is found.

But it's not working... The coordinates are printed out on my Terminal, but that's it.

I guess I am not using the class as I am supposed to. But I don't understand where is my error!

Help?

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tweepy
import gspread
import time

CONSUMER_KEY, CONSUMER_SECRET = 'SECRET', 'SECRET'
USER_KEY, USER_SECRET = 'SECRET', 'SECRET'

class MyStream(tweepy.StreamListener):
    def __init__(self):
        tweepy.StreamListener.__init__(self)

        # I added this to have a counter.
        self.n = 2

    def on_status(self, tweet):
        try:
            longitude = str(tweet.coordinates['coordinates'][0])
            latitude =  str(tweet.coordinates['coordinates'][1])
            print longitude
            print latitude

            # I added this to update my google spreadsheet with the coordinates
            self.wks.update_acell(('A' + str(n)), longitude)
            self.wks.update_acell(('B' + str(n)), latitude)
            print "Spreadsheet updated!"

            # This is for my counter
            self.n += 1

        except:
            pass


def main():

    #I added these two lines to connect to my google spreadsheet
    gc = gspread.login('EMAIL', 'PASSWORD')
    wks = gc.open('SPREADSHEET_NAME').sheet1

    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(USER_KEY, USER_SECRET)
    stream = tweepy.Stream(auth, MyStream(), timeout=50)
    stream.filter(locations=[-74.00,45.40,-73.41,45.72])

if __name__ == "__main__":
    main()

Solution

  • I'm having trouble testing this myself (mostly because I'm not familiar with how tweepy.Stream works, I think), but it looks like your MyStream instance never gets its wks attribute set in the first place.

    This means that when you refer to self.wks, it likely raises an AttributeError, but you never see it because of your try/except block. (Incidentally, this is why except: pass tends to be so hard to troubleshoot.)

    You'll probably want to make MyStream take an additional wks argument, something like so:

    def __init__(self, wks):
        tweepy.StreamListener.__init__(self)
    
        # Store the worksheet on this instance.
        self.wks = wks
    
        # I added this to have a counter.
        self.n = 2
    

    And then change the line where you instantiate MyStream so you now pass that worksheet as an argument:

    stream = tweepy.Stream(auth, MyStream(wks), timeout=50)