Programming Blog

Jeremy Morgan

Mostly Coherent Ramblings of a Silicon Forest Software Developer

How to Build a REST API With Python

By: Jeremy Morgan






In this article I will describe the process I used to create a new endpoint for my Raspberry Pi weather station, and how I set it up to to use Python and MariaDB for storage. I set this up as an endpoint for one of my IoT projects and thought I’d share the results.

Background

If you’ve been following my Raspberry Pi Weather Station tutorials, I set the first one up to use Firebase as a data store. I found it somewhat clunky to work with and I wasn’t very happy with my options. I’m not sure this is the type of data best suited for Firebase. So in the second iteration I used a .Net Web API on a Windows Azure website and had it store to a MS-SQL database. This was a really good solution.

I started getting a flood of emails with people asking for a more open source endpoint. Granted ASP.Net is open source, but some complained about the cost of hosting it. If you wanted to keep the database in house you’d have to pay for windows license and a SQL server for instance. Another issue was some people were developing in Linux or Mac, which makes interfacing with ASP.Net difficult (though they are working on that). Long story short I decided to create a Linux friendly solution and decided upon Python/Flask with MariaDB.

Why Python? Why MariaDB?

I chose Python because I’ve always loved the language from my first line of code. It’s simple, elegant and does a lot of things very well. I had never written a Web API with it, so I thought I’d give it a shot.

MariaDB is a fork of MySQL that is maintained by the founder, and superior to the original in many ways. Since it’s a drop in replacement I can still use the MySQL tools I’m familiar with. It seemed like a good fit.

Get Started

Get your Linux server ready. For this task I chose to use a Digital Ocean Server running Debian. If you must use Ubuntu, put “sudo” in front of everything.

The first thing you’ll want to do is update everything:

1
2
apt-get update
apt-get upgrade

Next we’ll get the database set up.

1. Install MariaDB

As I mentioned, MariaDB is a drop in replacement (upgrade really) of MySQL. You’ll need to add the repository:

1
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db

Then add it to your sources:

1
nano /etc/apt/sources.list

And add the following to it:

1
2
3
# MariaDB 5.5 repository list
deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/debian wheezy main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.5/debian wheezy main

save and close the file

Now run the following:

1
apt-get install mariadb-server

You will see a screen like this that will ask to set your root password:

How to build a REST API With Python

To add some additional security settings, run

1
/usr/bin/mysql_secure_installation

After that you can log into your MariaDB server:

1
mysql -u root -p

How to build a REST API With Python

To make it accessible from outside the server, you’ll need to make a change to my.cnf:

1
nano /etc/mysql/my.cnf

Look for “bind-address” and change it:

1
bind-address = 0.0.0.0

Save the file and close it.

Now restart the server:

1
service mysql restart

You should now be able to connect to your server from the outside.

2. PYTHON / SQL Connection

In order to connect to MariaDB you’ll need to install a couple things:

1
apt-get install libmariadbclient-dev libssl-dev python-mysqldb

You’ll also need to download the mysql connector.

1
2
3
wget http://ftp.kaist.ac.kr/mysql/Downloads/Connector-Python/mysql-connector-python_2.1.3-1debian8.2_all.deb

dpkg -i mysql-connector-python_2.1.3-1debian8.2_all.deb

This will install it the proper files to use the MySQL connector module.

3. Set up Python Flask

Next, we’re going to use Python Flask for the REST interface. Flask is written in Python and a very fast, powerful and stable way to connect.

1
2
3
4
5
6
7
8
9
10
11
12
mkdir source
cd source

apt-get install curl

curl -O http://peak.telecommunity.com/dist/ez_setup.py

python ez_setup.py

easy_install pip

pip install flask

This will set up Flask on your machine. Now let’s build a sample API to test it out.

4. Set up a test endpoint

We will want to add a web user (or whatever you want to name it) to set up this application.

I would like to give a shout to Miguel Grinberg for all the work that he’s done setting this up! I learned a lot from his tutorials.

1
2
3
4
5
6
7
8
9
adduser web

su web

cd ~

mkdir weather-api

cd weather-api

Now we want to create a file called app.py and make it look like this:

1
2
3
4
5
6
7
8
9
10
11
12
#!flask/bin/python
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
  return "Hello, World!"

if __name__ == '__main__':

  app.run(debug=True)

Next, we’ll want to set it to be executable, then execute it.

1
2
chmod a+x app.py
./app.py

Now create a new SSH session and type the following:

1
curl 127.0.0.1:5000

You will see a hello world message:

How to build a REST API With Python

Next, change it to have some actions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   #!flask/bin/python
  from flask import Flask, jsonify

  app = Flask(__name__)

  tasks = [
      {
          'id': 1,
          'title': u'Buy groceries',
          'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
          'done': False
      },
      {
          'id': 2,
          'title': u'Learn Python',
          'description': u'Need to find a good Python tutorial on the web',
          'done': False
      }
  ]

  @app.route('/todo/api/v1.0/tasks', methods=['GET'])
  def get_tasks():
      return jsonify({'tasks': tasks})

  if __name__ == '__main__':
      app.run(host='0.0.0.0')

Notice at the bottom I put in

1
app.run(host=0.0.0.0)

This will allow your API to be accessed from the outside.

Now, get POSTMAN or something similar and point it at your URL. Send it a GET:

{YOUR IP}/todo/api/v1.0/tasks

and it should look like this:

How to build a REST API With Python

Congrats, you have Flask working. For security you should install and implement httpauth later down the road.

1
pip install flask-httpauth

5. Set up MariaDB for the Weather Station

Now we will set up a database for the weather station endpoint.

1
2
3
4
CREATE DATABASE weather;
GRANT ALL PRIVILEGES ON weather.* TO web@'%' IDENTIFIED BY 'secretpassword';
FLUSH PRIVILEGES;
quit

Log in as that web user:

1
mysql -u web -p

You will be created with an SQL prompt. Type the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use weather;

CREATE TABLE `weather`.`reading` (
  `readingID` INT NOT NULL AUTO_INCREMENT COMMENT '',
  `TempSensor1` DECIMAL(20,10) NULL COMMENT '',
  `TempSensor2` DECIMAL(20,10) NULL COMMENT '',
  `TempSensor3` DECIMAL(20,10) NULL COMMENT '',
  `TempSensorAvg` DECIMAL(20,10) NULL COMMENT '',
  `Humidity` DECIMAL(20,10) NULL COMMENT '',
  `Pressure` DECIMAL(20,10) NULL COMMENT '',
  `Altitude` DECIMAL(20,10) NULL COMMENT '',
  `SeaLevelPressure` DECIMAL(20,10) NULL COMMENT '',
  `Lux` DECIMAL(20,10) NULL COMMENT '',
  `TimeStamp` VARCHAR(45) NULL COMMENT '',
  PRIMARY KEY (`readingID`)  COMMENT '');

This creates your MariaDB database for storing items.

6. Set up Flask for the Weather Station

For this rather than dump the code on this page, just check out the endpoint from my github repo:

1
git clone https://github.com/JeremyMorgan/Raspberry_Pi_Weather_Station_PY_API

You’ll need to change the values in datastore.py to match your credentials.

start it up as you did before:

1
./app.py

Note, if you want to run as a service in the background:

1
nohup ./app.py &

()I’ve had mine up for about 2 weeks now without crashing)

Now, you can add a new reading like this:

1
curl -i -H "Content-Type: application/json" -X PUT -d '{"TempSensor1":"23"}' http://localhost:5000/weather/api/v1/readings

But how do we add this as an endpoint for the Rasperry Pi Weather Station project? Easy! Just point it to your Linux endpoint instead of the Azure/.Net one in readings.py:

1
url = '[YOUR URL]'

And you’re set! All your results will be stored by the minute in a MariaDB database:

How to build a REST API With Python

Conclusion

While this is specific to an endpoint I created for my project it’s a good outline for building a REST API with Python in Linux. It’s a very stable and performant way to collect data. The work on Flask has made it incredibly easy to get an API up and going quickly. I hope to do more cool stuff with it in the future and I hope you do too.




Do you like articles like this?

I’m constantly hacking on stuff and writing about happenings in the programmer world. You can subscribe to my feed here, or you can get the hacker newsletter 100% spam free!

You can also follow my projects on GitHub:

Comments