loading...

Simple API Calls with Python

hiro profile image Hiro Nishimura ・5 min read

Learning API from Zero

I am in the process of wrapping my head around the "concept" of API. For Day 1 of my API studying, I learned about venv, SQLite, Flask, and how to make basic API GET requests with a help of a Twitter friend.

I am using a Mac with Terminal for this exercise.

Installing Virtual Environment (venv)

VENV is a lightweight virtual environment for Python that can be installed into a directory (folder) on your computer where you can essentially "run a server" to run Python without the environment impacting the rest of your computer. (Kind of like a little server "living" inside one specific folder you create?)

$ pip install virtualenv // installs the Virtual Environment

Create Virtual Environment

I created a new folder on my Desktop and installed Python and Pip into the said folder using venv.

Pip is a package installer for Python, and should come with Python if installed from their official website.

$ cd Desktop // go to Desktop
$ mkdir new_folder // create a new folder on Desktop called new_folder
$ cd new_folder // change directory ("go into") the folder new_folder
$ virtualenv venv // installs Python and Pip into new_folder
$ source venv/bin/activate // activates Virtual Environment

Install Flask & JSONify

I installed Flask, Flask-SQLAlchemy, Flask-RESTful, and JSONify, as specified by this tutorial.

Flask is a Python Web Framework, and JSONify is a minimal HTML-form to JSON to HTML-form converting plugin for jQuery.

$ pip install flask flask-jsonpify flask-sqlalchemy flask-restful

Download a Sample Database

I downloaded a sample SQLite database from SQLite Tutorial HERE, and saved it in my folder on my Desktop that I created earlier (new_folder).

Unzip the folder and you should get a .db file. In this case, the file was named chinook.db.

Create a Python Script

You can create a new file in Terminal:

$ touch server.py // creates file server.py in current folder

You can use an IDE to edit the Python file, or you can edit it directly in Terminal by opening the file:

$ nano server.py // opens server.py in Terminal

To begin, you can copy and paste the script provided by the tutorial referenced above.

from flask import Flask, request
from flask_restful import Resource, Api
from sqlalchemy import create_engine
from json import dumps
from flask_jsonpify import jsonify

db_connect = create_engine('sqlite:///chinook.db')
app = Flask(__name__)
api = Api(app)

class Employees(Resource):
    def get(self):
        conn = db_connect.connect() # connect to database
        query = conn.execute("select * from employees") # This line performs query and returns json result
        return {'employees': [i[0] for i in query.cursor.fetchall()]} # Fetches first column that is Employee ID

class Tracks(Resource):
    def get(self):
        conn = db_connect.connect()
        query = conn.execute("select trackid, name, composer, unitprice from tracks;")
        result = {'data': [dict(zip(tuple (query.keys()) ,i)) for i in query.cursor]}
        return jsonify(result)

class Employees_Name(Resource):
    def get(self, employee_id):
        conn = db_connect.connect()
        query = conn.execute("select * from employees where EmployeeId =%d "  %int(employee_id))
        result = {'data': [dict(zip(tuple (query.keys()) ,i)) for i in query.cursor]}
        return jsonify(result)


api.add_resource(Employees, '/employees') # Route_1
api.add_resource(Tracks, '/tracks') # Route_2
api.add_resource(Employees_Name, '/employees/<employee_id>') # Route_3


if __name__ == '__main__':
     app.run(port='5002')

(When I used it, we couldn't get it to run properly unless I changed from flask.ext.jsonpify import jsonify to from flask_jsonpify import jsonify so I've changed it in the script above, but try both if one doesn't work.)

Exit and save the file. You can reopen server.py with nano server.py to confirm that your changes took hold.

Run Python

I found out that I could "run" a tiny Flask server right on my computer using venv and make API calls and run queries! I will be running server.py that we just created earlier.

$ python server.py // runs server.py

This command returns the following:

 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5002/ (Press CTRL+C to quit)

So now, the little server is puttering about in http://127.0.0.1. And the database (chinook.db) is also puttering about in port 5002 as was specified in server.py.

Make API Calls

We created 3 resources with the script in server.py. They are Employees, Tracks, and Employees_Name.

class Employees_Name(Resource):

For each, we also specified how each Route is accessed:

api.add_resource(Employees, '/employees') # Route_1
api.add_resource(Tracks, '/tracks') # Route_2
api.add_resource(Employees_Name, '/employees/<employee_id>') # Route_3

So to make the API call, we can open a browser and type in the server IP address and the path specified in server.py: http://127.0.0.1:5002/employees

When I accessed that "URL," the JSON-ified GET request loaded:
GET Request

On the server side, I have a GET request log of the same information:

127.0.0.1 - - [09/Mar/2019 21:42:29] "GET /employees HTTP/1.1" 200 -
127.0.0.1 - - [09/Mar/2019 21:42:29] "GET /robots.txt?1552185749512 HTTP/1.1" 404 -

I had made a GET call to this resource in server.py:

class Employees(Resource):
    def get(self):
        conn = db_connect.connect() # connect to database
        query = conn.execute("select * from employees") # This line performs query and returns json result
        return {'employees': [i[0] for i in query.cursor.fetchall()]} # Fetches first column that is Employee ID

Similar things happen when you try the other 2 resources created: Tracks and Employees_Name.

For Employees_Name, the URL that we specified is /employees/<employee_id>. This means that to make the GET request for this specific resource, you choose the Employee ID that you want to request information from (I chose 5), and you would go to http://127.0.0.1:5002/employees/5.

The requested information about Employee ID #5 will load on your browser.

CRUD

CRUD stands for Create, Read, Update, Delete. With API, you can make four different types of calls: GET, PUT, POST, and DELETE, which corresponds with the CRUD functions. You should be able to GET or Create, PUT or Read, POST or Update, and Delete (self explanatory!) resources.

Day 1

For a few hours' worth of learning, I think I got through quite a lot of content! Much thanks to a Twitter friend who led me through the whole process! Otherwise I would've been stuck at step 1, completely lost.

Articles/Tutorials

Resources

Posted on by:

hiro profile

Hiro Nishimura

@hiro

I teach Cloud Computing and AWS to non-engineers through awsnewbies.com and LinkedIn Learning. Founder & CEO of 24 Villages - an edTech and Technical Writing consulting service.

Discussion