Check Stock Prices with Python and Twilio SMS

June 23, 2016
Written by

gordon

In the movie Wall Street, one dimension of the main character Gordon Gecko that the film disappointingly fails to explore is his love of the outdoors.  That’s right, he loves to go camping.  Unexpected, right?

Gordon’s never going to get a data connection out there, but with a bit of Python and Twilio SMS he can still check his stock prices with only a few of those precious reception bars.  Let’s find out how.

Setup and Build

For this simple app all you need is a Twilio account and a Python development environment.  If you are new to Python it’s easy to set up sign up for a free trial.

Start by opening a terminal or command line and create a new virtual environment named ‘twilio-ticker’:

virtualenv twilio-ticker

Activate the virtualenv:

source twilio-ticker/bin/activate

The dependencies we need are requests, an HTTP client, Flask, a Python microframework and the Twilio helper library:

pip install requests flask twilio

Awesome, let’s dig into some code. Create a new file named app.py, open it in your favorite code editor and import the dependencies we just installed:

import requests

from flask import Flask, request
from twilio import twiml

Now add the code needed to create and run a new Flask app:

import requests

from flask import Flask, request
from twilio import twiml

app = Flask(__name__)

if __name__ == "__main__":
    app.debug = True
    app.run()

Next define a new route that Twilio can request via an HTTP POST when it receives an inbound text message.  That route creates a response that containing the TwiML <Message> verb which tells Twilio to send an SMS message back to the sender.

app = Flask(__name__)


@app.route('/sms', methods=['POST'])
def sms():
    response = twiml.Response()
    response.message("Hello World")
    return str(response)

if __name__ == "__main__":
    app.debug = True
    app.run()

This is a good place to make sure the basics of our app are set up and run.  Start the app by running:

python app.py

The app will start and expose the sms route on http://localhost:5000.

flask-running.png

Test the route using an HTTP client like cURL or Postman to make a request to the sms route. The response should contain the generated TwiML.

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>Hello World</Message>
</Response>

High five! With the route generating TwiML let’s modify it to let someone request the the price of a specific listing by texting in a stock symbol.

Start by grabbing the text of the incoming SMS message which Twilio includes its HTTP request as a form-encoded value named Body.  Using that symbol craft a URL for the Yahoo Finance API that we’ll request to the to get information about the listing:

@app.route('/sms', methods=['POST'])
def sms():
    symbol = request.values.get('Body')
    path = "http://finance.yahoo.com/webservice/v1/symbols/{0}/quote?format=json"
    path = path.format(symbol)

    response = twiml.Response()
    response.message("Hello World")
    return str(response)

Using requests make an HTTP GET request to the Yahoo URL.  From the response parse the price and replace the original TwiML message with a new message that contains the stock symbol and price:

@app.route('/sms', methods=['POST'])
def sms():
    symbol = request.values.get('Body')
    path = "http://finance.yahoo.com/webservice/v1/symbols/{0}/quote?format=json"
    path = path.format(symbol)
 
    response = twiml.Response()
    try:
        result = requests.get(path)
        price = result.json()['list']['resources'][0]['resource']['fields']['price']
        response.message("Current price of {0} is: {1}".format(symbol, price))
    except:
        response.message("Whoopsie doodle - could not find the information.")
  return str(response)

Restart the app and head back to your HTTP client to make a request to the sms route again this time including the form-encoded Body parameter.

<Response>
    <Message>Current price of GOOG is: 695.94</Message>
</Response>

With the app running the final step is to connect a Twilio phone number to it.  Twilio uses an HTTP request to a public URL to tell us that it has received an incoming SMS message.  We can expose the Python app running in own local environment via a public URL by using ngrok.

ngrok http 5000

Once ngrok starts grab the public URL that it assigned:

ngrok.png

Next, head over to the Phone Numbers section of the Twilio Console to select an existing number in your account buy a new number.

Configure the phone number so that when Twilio receives an incoming SMS message Twilio will make an HTTP, or “webhook”, request to your ngrok URL:

Save the phone number and give your app a try by texting your favorite stock symbol to your Twilio phone number.

Boom!  Quick stock symbol info on your phone via single simple SMS message.

Wrapup

By combining a few bits of Python and Twilio, in just a few minutes we were able to build a really fun and useful SMS app.  But the fun does not have to stop there.

The app could be made even more useful by allowing the user to request prices of multiple stocks or by using a task queue library like Celery to allow the user to set up SMS notifications for when a symbol hits a price threshold.

Let me know what you’re building with Python or Twilio.  Shoot me a tweet @devinrader.