0

I am currently trying to implement a Twitter Stream using Twitter's Streaming API and I am using Flask-SocketIO for use in Python. Now I am able to send an emit to trigger a function in Flask which calls the Twitter API based on some keyword, but I want the text from the stream back to the JavaScript front-end which hasn't been too successful. I am able to send, for instance, a message like "Hi" if I listen on 'message', but I've tried to send JSON back to no avail.

My Flask function for this is:

@socketio.on('my event')
def handle_my_custom_event(json):
    print('received json: ' + str(json))
    r = api.request('statuses/filter', json)
    for item in r.get_iterator():
        if 'text' in item:
            print(item['text'])
            json_data = {'data': item['text']}
            send(json_data, json=True)

JSON in this case is {'track':'$AAPL'} so fetches each tweet about Apple as it happens. item['text'] is the string of the tweet text. I've tried using send, also tried using emit('my response',json_data) and listened for 'my response' but I'm not sure I'm doing all of this right.

My front-end script for this currently looks like this:

$(document).ready(function() {
    var socket = io.connect('http://' + document.domain + ':' + location.port);
    socket.on('connect', function() {
        socket.emit('my event', {'track': '$'+data_prices[0]['symbol'].toString()}, function(data){
            console.log(data);
            if (data.error) 
                console.log('Something went wrong on the server');

            if (data.ok)
                console.log('Event was processed successfully');
        });
    });
});

but I receive no console logs, nothing.

What would I have to do to receive the json_data object in my front-end script and have it log to the console?

UPDATE: I've managed to get them coming in when I emit them to an event 'my response' but it only seems to log to the console when I shut down the server. Is there a way to keep this running as a stream to the console so I can use the data in the front-end?

apgsov
  • 794
  • 1
  • 8
  • 30

1 Answers1

0

I discovered that my problem was the listener for the response was not properly set up so I changed the Flask function to:

@socketio.on('my event')
def handle_my_custom_event(json):
    print('received json: ' + str(json))
    r = api.request('statuses/filter', {'track':'pizza'})
    for item in r.get_iterator():
        if 'text' in item:
            print(item['text'])
            json_data = {'data': item['text']}
            emit('my response',json_data)

then in the front-end I had:

$(document).ready(function() {
    var socket = io.connect('http://' + document.domain + ':' + location.port);
    socket.on('connect', function() {
        socket.emit('my event', {'track': '$'+data_prices[0]['symbol'].toString()}, function(data){
            console.log(data);
        });
    });
    socket.on('my response', function(data){
        console.log(data);
    });
});

The issue is that Flask is by default synchronous, and to have the messages come in as and when they happen, when creating the SocketIO app, asynchronous mode has to be explicitly defined:

socketio = SocketIO(app, async_mode="threading") 
apgsov
  • 794
  • 1
  • 8
  • 30