Simple API with FastAPI

Hey guys I’m Gealber, and I will be tinkering with new technologies related to backend. This time I’ll start with FastAPI. This is my first post, so any suggestion will be well-received.

FastAPI is a modern, fast (high-performance), web framework for building APIs with Pyton 3.6+ based on standard Pyton type hints. Taken from the GitHub repository.

As a personal note, what I really like about FastAPI, is how well documented it is. Only looking at the doc_sr folder on the GitHub repository, you can start working with it, no additional resource.

This article will be focus on a simple use of FastAPI. I will building an API with four endpoints:

  1. /register
  2. /login
  3. /echo
  4. /send

As a tech stack will be dealing with:

  1. FastAPI
  2. python-multipart

Documentation

First, before we start coding, we need to define the documentation related to the API. In case we were writing an API for a real world application, writing the documentation first, will give us, at least, two advantages. One is that, you as a backend developer, will have a broader view of what you want to build. And second, the frontend developers will have information to work with, so they will not need to wait for you to end the whole development.

For the documentation of the API will be using OpenAPI

Let’s create the openapi.yaml file for the documentation. So let’s explore this file at first.

Endpoint to register user

  • /register
schema:
  type: object
  properties:
    data:
      type: object
      properties:
        name:
          type: string
          description: Name of user.
        email:
          type: string
          description: Email of user.
        password:
          type: string
          description: password of the user.

This endpoint as the name suggested, will create the user on the database. On this tutorial will just store the users on a list, for simplicity.

Endpoint to login user

  • /login
schema:
  type: object
  properties:
    data:
      type: object
      properties:
        name:
          type: string
          description: Name of user.
        password:
          type: string
          description: password of the user.

Endpoint to echo

  • /echo

This endpoint will be just a GET request that will return as response a text “Hello Gealber!”. No need for authentication for this endpoint.

Endpoint to send image

  • /send

This endpoint is the more tricky(Or at least I thought it would be) given that the server will take an image and extract the filename.

schema:
  type: object
  properties:
    name:
      type: string
      description: >
        Name of the image to upload.
    file:
      type: string
      format: binary
      description: File to upload
  required:
    - file

In this case we’ll be sending the file as a multipart/form request. To be able to do this we will need to install python-multipart, otherwise, none of the multipart requests will be working.

Coding

Now comes the interesting part guys. First let’s install all the necessary requirements.

$ pip install fastapi

We will need an ASGI server, on this case we’ll go with Uvicorn.

  • Uvicorn
$ pip install uvicorn

pip install python-multipart

All right let’s code then

  • /echo

The easiest endpoint to start with is the “echo” endpoint. As described on the #Documentation section, this will be a GET method without parameters:

All the code will be on a main.py file


from fastapi import FastAPI

app = FastAPI()

@app.get("/echo")
def echo():
    return "Hello Gealber!"

And that’s all for this useless endpoint, but here we can notice how clean and simple is to use FastAPI.

  • /register

Now let’s jump to the register endpoint. As I said before I won’t be using any database to store the users, instead I’ll just use a simple list with dictionaries as elements.

fake_storage = []

@app.post("/register")
def register(user: User):
    id = generate_id()
    fake_storage.append({
        "id": id,
        "name": user.name,
        "email": user.email,
        "password": user.password,
    })
    return {"id": id}

Here we make use of a helper function to fake the generation of an id for the user

from string import ascii_letters
import random


def generate_id():
    return "".join(random.sample(ascii_letters, 10))
  • /login

Now looking for the login method.


@app.post("/login")
def login(info: LoginInfo):
    email = info.email
    for user in fake_storage:
        if user["email"] == email:
            return "Ok, 200"
    return "403, Forbidden"

  • /send

Now comes the tricky part, first you will need to install python-multipart to be able to upload a file with FastAPI.

pip install python-multipart After that the code comes pretty easy let me tell you, @tiangolo made a very good job with this one.


from fastapi import File, UploadFile

@app.post("/send")
async def send(file: UploadFile = File(...)):
    return {"filename": file.filename}

How to run it?

Well that’s also very simple indeed

uvicorn main:app --reload

The --reload flag is to be able to recover on failure, very useful.

That’s all folks.I definitely need to improve my writing skills in the meanwhile I’ll keep practicing.