Ajeet Khan
Ajeet Khan

Reputation: 9190

Stop stream.filter() on button click

I am using tweepy to stream tweets and store it in a file. I am using python and flask. On a click of a button the stream start to fetch the tweets. What I want is, on a click of a button the stream should get stopped. I know the answers related to a counter variable, but I don't want specific number of tweets to fetch.

Thanks in advance

def fetch_tweet():
    page_type = "got"



    lang_list = request.form.getlist('lang') 

    print lang_list
    #return render_template("index.html",lang_list=lang_list,page_type=page_type)
    l = StdOutListener()
    auth = OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    stream = Stream(auth, l)

    with open('hashtags.txt') as hf:
        hashtag = [line.strip() for line in hf]
        print hashtag

    print request.form.getlist('fetchbtn')
    if (request.form.getlist('stopbtn')) == ['stop']:
        print "inside stop"
        stream.disconnect()
        return render_template("analyse.html")
    elif (request.form.getlist('fetchbtn')) == ['fetch']:
        stream.filter(track=lang_list, async=True)
        return render_template("fetching.html")

Upvotes: 3

Views: 1140

Answers (1)

dbernard
dbernard

Reputation: 561

So I'm assuming your initial button links to the initializing of a tweepy stream (i.e. a call to stream.filter()).

If you're going to allow your application to run while tweet collection is happening, you'll need to collect tweets asynchronously (threaded). Otherwise once you call stream.filter() it will lock your program up while it collects tweets until it either reaches some condition you have provided it or you ctrl-c out, etc.

To take advantage of tweepy's built in threading, you simply need to add the async parameter to your stream initialization, like so:

stream.filter(track=['your_terms'], async=True)

This will thread your tweet collection and allow your application to continue to run.

Finally, to stop your tweet collection, link a flask call to a function that calls disconnect() on your stream object, like so:

stream.disconnect()

This will disconnect your stream and stop tweet collection. Here is an example of this exact approach in a more object oriented design (see the gather() and stop() methods in the Pyckaxe object).


EDIT - Ok, I can see your issue now, but I'm going to leave my original answer up for others who might find this. You issue is where you are creating your stream object.

Every time fetch_tweet() gets called via flask, you are creating a new stream object, so when you call it the first time to start your stream it creates an initial object, but the second time it calls disconnect() on a different stream object. Creating a single instance of your stream will solve the issue:

l = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
stream = Stream(auth, l)

def fetch_tweet():
    with open('hashtags.txt') as hf:
        hashtag = [line.strip() for line in hf]
        print hashtag

    print request.form.getlist('fetchbtn')
    if (request.form.getlist('stopbtn')) == ['stop']:
        print "inside stop"
        stream.disconnect()
        return render_template("analyse.html")
    elif (request.form.getlist('fetchbtn')) == ['fetch']:
        stream.filter(track=lang_list, async=True)
        return render_template("fetching.html")

Long story short, you need to create your stream object outside of fetch_tweets(). Good luck!

Upvotes: 3

Related Questions