Saltar al contenido principal
12 min read web development 09/01/2023

medium Python project: how to create an API using FastAPI?

practical tutorial to create a complete API with Python and FastAPI, from installation to automatic documentation.

Hello world 🤟🏻 my name is Francisco, fcoterroba on the Internet and today I bring you a post that usually goes down well here on the web. As you can see in the title, today we’re going to create an API in Python using the FastAPI library or framework.

Very interesting project to add to your developer portfolio whether backend or even front-end.

Before we start, as it couldn’t be otherwise, if you haven’t seen it yet, I strongly recommend that you go see the latest video I have on my YouTube channel where I explained, in a very simple and concise way, how to install a smart bulb 🧠 with which you can change its color, control it with your own voice and much more! You can see it here 👇🏻

Finally before we start, I wanted to communicate that I’ve been uploading videos to TikTok for a few weeks. Lately they’re about Eurovision since it’s coming up soon but I’ll leave here the latest one I made today about computing.

@fcoterroba How to make a small #game in #Python ? Like for part 2! #fyp #parati #dev #programming ♬ LoFi(860862) - skollbeats

Something I should know before starting?

Yes, several things really:

What is an API?

  • An API (abbreviation of Application Programming Interfaces), is, basically, a set of definitions and protocols that are used to develop and integrate application or web software. Thus allowing communication between two applications that are a priori totally different.
  • An API is a place where certain information about certain aspects is encompassed. The thing is that this information is not accessible and not easily readable by humans.
  • Generally, an API returns the information when requested in JSON format and it’s the developer in their new web or software who is responsible for making this information readable.
    • For example, this free API from The Simpsons, if you access the basic API, it returns a quote from one of the characters from this series.

The Simpsons API

What is Python?

  • Python is a programming language used in practically everything imaginable
  • Web development, software, AI, ML, Data Science. These are some of the tech areas where Python is widely used.
  • It offers quite good readability close to human reading.
    • In the Python category on the web you can find +8 Python projects divided by difficulty. What are you waiting for? Your API can wait.

What is FastAPI?

  • FastAPI is a framework for building APIs easily and quickly with Python.
  • In recent times it has become a very popular framework as it’s considered one of the fastest existing frameworks in Python.
  • Some benchmarks have put FastAPI much ahead of Django, Flask or Pyramid.

Performance comparison

1️⃣ FIRST STEP 1️⃣ Install what’s needed

We’ll take into account that we already have Python installed, in my case I have Python version 3.10.7 but you don’t necessarily need to have this version to follow the tutorial. It’s just recommended that it’s a Python 3 version. python 3.x.x

The first thing we need to do is install the FastAPI library, for this we’ll use the command

pip install fastapi

Finally, we’ll need the uvicorn library, an ASGI web server written for Python. We’ll need this library to check that everything is working. We can install it with this command:

pip install uvicorn

Once installed, we can really start

2️⃣ SECOND STEP 2️⃣ Hello world

The first thing and as you might already be imagining, is to import the FastAPI library, for this we import it like any other:

from fastapi import FastAPI

Then, we’ll have to create a general object that, normally, is usually called app

app = FastAPI()

FastAPI works with asynchronous functions and many getters, so we’ll have to take, to start, the root of our server and right below declare the return message:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

With this, if we visit our localhost (by default on port 8000), we’ll get the json we sent for return:

FastAPI Hello World

3️⃣ THIRD STEP 3️⃣ More functions and pages

With the previous step we’ve made great progress, we already have our web server running, waiting for queries and returning a json with what we say. It’s good, but it’s missing more substance, right?

In this case I’m going to test as if I were creating an API of the famous anime “Shin Chan”.

The first thing we’ll have to do is, somehow, store the information we want to return in the API. I’m going to store the main characters of the series in a JSON with their age, an image, name, etc. Like this:

Character JSON data

Now, let’s say we want to pass those four characters to the root of our API.

For this we simply have to convert our JSON file to a Python dictionary. We import the json library to work with it and opening it, we can pass the variable using the load function

import json

data = ""

with open('characters.json') as json_file:
    data = json.load(json_file)

Finally, in our root we pass that variable and if we visit our API we’ll get that json

@app.get("/")
async def root():
    return data

If we pass, for example, data[0] we’ll pass only the first field of the json, data[1] for the second field, etc.

API result

Now, everything we’ve done has been in the root, when accessing the main page of the API, let’s say we want each page to return a certain thing.

For this, we’ll have to create a getter with a function for each page we want.

For example, let’s say I want a page that will return a totally random character for each visit. We import the random library and use the choice function passing our dictionary AS A LIST.

import random

@app.get("/randomCharacter")
async def randomCharacter():
    return random.choice(list(data))

Another example, let’s say we have a list with all the ids we can get, for this we can pass an id to the getter and to the function, to return that record.

Keep in mind that we subtract one because the json starts at 0 but the user will write “normal”, starting at 1.

@app.get("/specificCharacter/{id}")
async def specificCharacter(id: int):
    return data[id-1]

4️⃣ FOURTH STEP 4️⃣ Main page

We’re almost almost done, we already have our basic API, our functions, our calls, everything.

But of course, our root still returns a json, it’s neither aesthetic nor simple nor has good practices. The correct thing would be to create an index.html and call that file in the root.

I’ve created this small 50-line html based on a W3Schools template.

<!DOCTYPE html>
<html>
    <head>
        <title>The Shin Chan API - @fcoterroba</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Raleway">
        <style>
        body,h1,h2{font-family: "Raleway", sans-serif}
        body, html {height: 100%}
        p {line-height: 2}
        .bgimg {
        min-height: 100%;
        background-position: center;
        background-size: cover;
        }
        .bgimg {background-image: url("https://preview.redd.it/7fx1jell8p551.png?auto=webp&s=8ff53edc7ff4752ca0262c8a58f2d0a7efbbad61")}
        </style>
    </head>
    <body>

        <header class="w3-display-container w3-wide bgimg w3-grayscale-min" id="home">
            <div class="w3-display-middle w3-text-blue w3-center" style="background-color: white;">
                <h1 class="w3-jumbo">Shin Chan API</h1>
                <h2>The free Shin Chan API</h2>
                <h2><b>Created by @fcoterroba</b></h2>
            </div>
        </header>

        <div class="w3-container w3-padding-64 w3-pale-blue w3-grayscale-min" id="us">
            <div class="w3-content">
                <h1 class="w3-center w3-text-grey"><b>Just call it</b></h1>
                <img class="w3-round" src="https://images5.alphacoders.com/116/1166283.jpg" style="width:100%;margin:32px 0">
                <p><i>Get the full name, age and picture of your favourite characters.</i>
                </p><br>
                <p class="w3-center"><a href="#" class="w3-button w3-black w3-round w3-padding-large w3-large">Documentation</a></p>
            </div>
        </div>

    </body>
</html>

Once we have the html, we simply import the FileResponse function from starlette.responses and return it using that function.

from starlette.responses import FileResponse 

@app.get("/")
async def root():
    return FileResponse('index.html')

API main page

5️⃣ FIFTH STEP 5️⃣ Generate documentation

Every API worth its salt requires custom documentation and FastAPI also gets a very good point in favor of this.

By default, this library generates two very clean and beautiful documentations

One of them is at /redoc and the other, something more classic, at /docs.

Automatic documentation

You can enter the repository of this API on my GitHub!

🏁 END OF POST 🏁

And that’s all for today. Thanks for reading until the end, I hope it was useful and you liked it. See you soon!

You can also support my work via Paypal. Any amount is truly appreciated! 🙂

I also hope you have a great week and we’ll see each other here soon! Greetings and remember to follow me on social media like Twitter, Facebook, Instagram, GitHub, LinkedIn and now also on TikTok. 🤟🏻

Sources: Xataka.com, AWS.amazon.com, sngular.com, coffeebytes.dev, w3schools.com