Learning Goals
By the end of this section you will:
install OurAPI on your computer
use OurAPI to host a webserver on your computer
make RESTful requests to that webserver using the built-in API functions and database
customise OurAPI by changing the database and making your own API functions
OurAPI was originally created as an educational tool. It enables quick and easy development of a RESTful JSON API, with real-time request feedback displayed through its graphical interface. Built-in GET and POST clients allow for interface testing, although any HTTP client—including a web browser—can interact with the API. It was developed by Steven Tucker and his original
We will use OurAPI’s built in database to practice using API GET and POST requests. We will then explore using our own databases and creating our own API functions.
Getting Started¶
To get started you can download OurAPI from SourceForge. OurAPI doesn’t have an installer, rather extracting the zip file will provide access to the program, so make sure you remember it. Launch OurAPI by opening it’s folder and starting the main file.
OurAPI is not working
If OurAPI doesn’t work on your computer, this sometimes happens with macOS, then you can clone my fork of OurAPI. Create a virtual environment, ensuring you tick the requirement.txt option, then run main.py.
Now you should have the following window displayed on your screen.

What you are seeing is the GUI of the application, in the background your computer is running a webserver. This webserver is hosting the API that we will be accessing. Let try it out with a simple GET request.
Function Calls¶
First call¶
The APi has a range of functions that provide access to the database. To see these functions click on the API Summary button. You should have the following dialogue pop up:

You can see there are currently 10 functions the API offers. Click on the > beside list_countries and you will see three more options. Click on all the > so you can see all the details of list_countries function.

Lets look at those details:
Args → there is no need to pass arguments
SQL → this is the SQL query that will be run on the database
Route → this is the address that executes the query
http://127.0.0.1:8000→ the address of the webserver on your computer/api/list_countriesthe route to the API function of that web server.
Copy the route, paste it into address bar of a browser, then press return. Two things should have happened:
Your browser should display a block of text – this is actual the JSON response from the web server.
the OurAPI UI should now have a heap of new details.

Test Client
Lets run that request a different way:
Click Reset Session
Click on Test Client (GET) then type list_countries
Click Run
The OurAPI GUI should display the same information as before, but lets look at the change in the GET Client dialogue.

List Countries Activity
Write a Python script that call the OurAPI list_counties function, processes and displays the returned JSON response.
Call with Argument¶
RESTful operations also allow for the API to be provided with arguments. Lets try one:
In the GET Client:
Click on Set Function → enter country_info
Click on Add Variable
Name → country
Value → Brazil
Click Run

You will notice:
The argument name and the value are part of the URL
Only one result has been returned
Close the GET Client then open the POST Client and repeat the same process.

Have a look at the POST URL. Notice that the argument name or value is not part of it? That’s because the data is sent in the body of the request—not in the URL. This means users don’t see the data in the address bar, making it more private and allowing larger amounts of information to be sent, like form details, login credentials, or file uploads.
When do I use POST
It’s better to use POST rather than GET when you are sending data to a server to create or update something, like submitting a form or logging in. POST is more secure for sensitive data (like passwords), doesn’t show information in the URL, and can handle larger amounts of data than GET. Use POST when the action changes data on the server or when the information being sent should not be visible or stored in browser history.
Requests Activities
Perform both GET requests and POST requests for all of the function in the API Functions list (via the API Summary button).
Write Python scripts that also perform all the requests.
Customising OurAPI¶
You can customise OurAPI to use different databases and create your own functions. What’s even better is that it is super easy to do this.
To udnerstand how to do this, we’re going to look a bit closer at how OurAPI works.
Exploring OurAPI¶
First, open the api_db.sqlite file using DB Browser. You will find that it just an ordinary SQLite database. You can see that there are many more tables in the database than we can access using the API functions. That is one of the security features of the REST framework. Users can only access the data you make available to them.
Next open the definitions.ini with a text editor, or in VS Code. You will find the following:
[country_info_brief]
args = country
sql = SELECT name,population
FROM Country
WHERE name = :country
[country_info]
args = country
sql = SELECT name, area, primary_language, population, currency, timezone
FROM Country
WHERE name = :country
[list_countries]
args = None
sql = SELECT name, area, population, currency, timezone, capital, largest_city, primary_language
FROM Country
ORDER BY name ASC
[country_continent]
args = country
sql = SELECT c.name AS Country, ct.name AS Continent
FROM Country AS c
INNER JOIN Continent AS ct
ON c.continent_id = ct.id
WHERE c.name = :country
[pop_greater]
args = min_pop
sql = SELECT name, population
FROM Country
WHERE population > :min_pop
ORDER BY population ASC
[continent_countries]
args = continent
sql = SELECT c.name AS Country
FROM Country AS c
INNER JOIN Continent AS ct
ON c.continent_id = ct.id
WHERE ct.name = :continent
[continent_countries_pop_greater]
args = continent,min_pop
sql = SELECT c.name, c.population
FROM Country AS c
INNER JOIN Continent AS ct
ON c.continent_id = ct.id
WHERE ct.name = :continent
AND c.population > :min_pop
ORDER BY c.population ASC
[add_vet]
args = first_name,last_name,phone,address,room,appointment_times,email
sql = INSERT INTO Vet
(first_name, last_name, phone_no, address, room_no, appointment_times, email)
VALUES(:first_name, :last_name, :phone, :address, :room, :appointment_times, :email)
[vets_list]
args = None
sql = SELECT first_name, last_name
FROM Vet
[delete_vet]
args = first_name,last_name
sql = DELETE FROM Vet
WHERE first_name = :first_name
AND last_name = :last_nameLooking at this you should recognise three things:
the text in the square brackets are the names of the API functions
the args line lists the arguments that the function needs
the sql is a Python parameterised SQL statement.
With this information, you can start creating new API functions.
New Function Activities
Create the following functions, then call them from the OurAPI UI. Use DB Browser to confirm your results.
Write a API function to return the names of all artists.
Write a API function to return all tracks that cost less than $1.
Write a API function to return all employees’ first and last names, ordered by last name.
Write a API function to return the first and last names of customers who do not have a company listed.
Write a API function to return all customer IDs with the last name provided.
Write a API function to return the names of all track performed by provided artist.
Write a API function to return the first and last names of customers who live in a provided city.
Write a API function to return all album titles along with the artist’s name.
Write a API function to return the count of how many tracks exist in the provided genre.
Write a API function to return the average invoice total for invoices from the provided country.
Making OurAPI yours¶
We have now identified the two files that provide OurAPI with the relevant information:
definitions.ini provides the structure for the API functions
api_db.sqlite provides the data for the functions
So to customise OurAPI replace these two files with your custom file:
your database needs to be called api_db.sqlite
your file containing your function details needs to be called definitions.ini
Remember the API function structure when making your own definitions.ini:
[<function_name>]
args = <argument names seperated by commas>
sql = <parameterised SQL statement>Custom OurAPI Activities
To complete the following activities We will use the Chinook Database from exercise databases we used to learn SQL. You will need to save it to your OurAPI folder.
For each of the following activities, you will need to:
create the API function in the definitions.ini
write a Python script that calls the API function and displays the returned results
Activities
Write an API function that returns the count of how many tracks are stored in the database.
Write an API function that returns the names and unit prices of the 5 most expensive tracks.
Write an API function that returns each genre and the number of tracks in that genre, ordered from most to least.
Write an API function that returns first and last names of employees whose title is “Sales Support Agent”.
Write an API function that returns the track which appears the most in invoice lines, showing its name and how many times it was sold.
Write an API function that returns the first name, last name, and city of all customers who live in the provided country.
Write an API function that returns the name and duration (in milliseconds) of tracks that are longer than the provided time (in seconds).
Write an API function that returns the titles of albums created by the provided artist.
Write an API function that returns invoice ID, customer name, and total for all customers located in the provided country.
Write an API function that returns full name and the total amount spent by the customer with the provided customer ID.