I’ve been playing around with ‘Twilio‘ recently, it’s a cloud communications provider that allows developers access to a platform that lets them send and receive SMS, calls and more. Since they also provide some nice Python bindings around their API, I decided to sign up and give it a go.

After signing up you get a trial account that lets you send SMS and calls to a verified number (i.e. one that you can prove you own). Additionally they seem to provide you with a fair amount of free SMS messages out of the box to play with. If you want to get serious, you can add some funds and start sending more messages/calls to unverified numbers as well. Once signed up, you get access to your own ‘Dashboard’ on their website that provides you with all the help and documentation you need. You’ll also get an allocated phone number, accound SID and auth token that will allow you to talk to their API, and with these in hand you’re ready to begin.

I’m a recent virtualenv/pip convert, so I’m using those to manage my isolated python environment and to install dependencies. So, in my fresh virtualenv environment, the first thing to do is to use pip to grab  the Twilio package we need:

venv>> pip install Twilio

After we’ve got the Twilio package we need, we can write our dead simple python app that will send an SMS:

Pretty simple! We import the TwilioRestClient, which is how we’ll communicate with their API, we specify our account number and token (grabbed from your Twilio Dashboard), construct an instance of the TwilioRestClient, then I just have one simple method that sends the message to my phone.

Now lets gets fancy- if we bring Flask  into the mix, we can start crafting a simple web page that can accept some user input then send a message. If you haven’t heard of Flask, its a dead simple web framework for python. Let’s continue with the previous code and start by installing Flask into our virtualenv:

>>pip install Flask

With this done, we can add Flask to our previous code:

So, all I have done here is pull in the Flask package, render_template (we’ll use it later) and request (again, we’ll use this later).  On line 4 I create an instance of the Flask class, passing it the name of the module, which it needs to know in order to look for html files etc. (which we’re not currently using). On line 16, I’ve removed the explicit function call and replaced it with ‘app.run()’, specifying the address to listen to requests on, and a port number. When this line is invoked it starts a local server with our app.

Once running, any web requests to the address we’ve specified will be routed to our application, so we have to make one other change in order to be able to handle the requests; on line 9 I use the Flask route decorator to tell Flask what URL should trigger this function; in this case the ‘/’ I’ve used handles any requests to our application at With all this done, we can now run the app from the command line:

>>python TwilioApp.py
* Running on

And that’s it. If we open a browser and navigate to the app should send a message to my phone and return the text “Success”.

Let’s get even more clever now, and set up a couple of static HTML pages – one to accept some text from a user, and another to replace our boring “Success” text. The two files we’ll use, form.html and success.html are below:

Nothing fancy here, just a form with a single text box and a button that will invoke a POST back to our app. Once you have these two files, chuck them in a folder named ‘templates’ next to the python code (it’s where Flask will look for them). Next, we do one final update to our previous code to use the new HTML files:

Nothing too clever here, our previous @app.route(‘/’) on line 9 now uses the Flask render_template call to return our first form, and then we have another Flask decorator on line 13 that responds to POST actions; this one pulls the text out of the request.form field ‘Message’ and uses it in the SMS request to Twilio. Run the app again, navigate to and you should see the following:


And after entering some text and hitting ‘Send’, you should receive the message and be presented with the following screen: