Why should you try FastAPI?

image Logo taken from Github FastAPI repository







FastAPI is a relatively new web framework written in the Python programming language for creating REST (and, if you try hard, then GraphQL) API based on new Python 3.6+ features, such as: type-hints, native asynchrony (asyncio ) Among other things, FastAPI integrates tightly with OpenAPI-schema and automatically generates documentation for your API through Swagger and ReDoc







FastAPI is based on Starlette and Pydantic .

Starlette is an ASGI micro-framework for writing web applications.

Pydantic - a library for parsing and validating data based on Python type-hints.







What do they say about FastAPI?



"[...] I use FastAPI very often in recent days. [...] I definitely plan to use it for all the ML services of my team at Microsoft. Some of them integrate into Windows and some Office products."

Kabir Khan - Microsoft ( ref )







"If you want to learn another framework for writing a REST API, take a look at FastAPI [...] It's fast, easy to use and learn. [...]"



"Now we use FastAPI for our APIs [...] I think you will like it! [...]"

Ines Montani - Matthew Honnibal - Explosion AI founders - spaCy creators ( ref ) - ( ref )







Minimal API created using FastAPI



I will try to show you how to create a simple, but at the same time useful API with documentation for developers. We will write a random phrase generator!







Installing prerequisites



pip install wheel -U pip install uvicorn fastapi pydantic
      
      





New module!

Uvicorn is an ASGI-compatible web server that we will use to run our application.







First, we’ll create the basis of our application.







 from fastapi import FastAPI app = FastAPI(title="Random phrase")
      
      





This application is already running and can be started.

Write this command in your terminal and open the page in the browser at http://127.0.0.1:8000/docs .







 uvicorn <__>:app
      
      





But while in our application not a single endpoint is indicated - let's fix it!







Database



Since we are writing a random phrase generator, we obviously need to store them somewhere. For this, I chose a simple python-dict



.







Create a db.py



file and start writing code.







We import the necessary modules:







 import typing import random from pydantic import BaseModel from pydantic import Field
      
      





After - we designate two models: the input phrase (the one that the user will send to us) and the "output" (the one that we will send to the user).







 class PhraseInput(BaseModel): """Phrase model""" author: str = "Anonymous" #  .    -   . text: str = Field(..., title="Text", description="Text of phrase", max_length=200) #  .   - 200 . class PhraseOutput(PhraseInput): id: typing.Optional[int] = None # ID     .
      
      





After that, create a simple class for working with the database:







 class Database: """ Our **fake** database. """ def __init__(self): self._items: typing.Dict[int, PhraseOutput] = {} # id: model def get_random(self) -> int: #    return random.choice(self._items.keys()) def get(self, id: int) -> typing.Optional[PhraseOutput]: #    ID return self._items.get(id) def add(self, phrase: PhraseInput) -> PhraseOutput: #   id = len(self._items) + 1 phrase_out = PhraseOutput(id=id, **phrase.dict()) self._items[phrase_out.id] = phrase_out return phrase_out def delete(self, id: int) -> typing.Union[typing.NoReturn, None]: #   if id in self._items: del self._items[id] else: raise ValueError("Phrase doesn't exist")
      
      





Now you can start writing the API itself.







API



Create the main.py



file and import the following modules:







 from fastapi import FastAPI from fastapi import HTTPException from db import PhraseInput from db import PhraseOutput from db import Database
      
      





We initialize our application and database:







 app = FastAPI(title="Random phrase") db = Database()
      
      





And write a simple method to get a random phrase!







 @app.get( "/get", response_description="Random phrase", description="Get random phrase from database", response_model=PhraseOutput, ) async def get(): try: phrase = db.get(db.get_random()) except IndexError: raise HTTPException(404, "Phrase list is empty") return phrase
      
      





As you can see, in the decorator I also indicate some other values ​​needed to generate more beautiful documentation :) In the official documentation you can look at all the possible parameters.







In this piece of code, we are trying to get a random phrase from the database, and if the database is empty, we return an error with code 404.







Similarly, we write other methods:







 @app.post( "/add", response_description="Added phrase with *id* parameter", response_model=PhraseOutput, ) async def add(phrase: PhraseInput): phrase_out = db.add(phrase) return phrase_out @app.delete("/delete", response_description="Result of deleting") async def delete(id: int): try: db.delete(id) except ValueError as e: raise HTTPException(404, str(e))
      
      





And that’s it! Our small but useful API is done!







Now we can launch the application using uvicorn , open the online documentation ( http://127.0.0.1/docs ) and try our API!













Useful materials



Of course, I could not tell you about all the features of FastAPI, for example, such as: smart DI system, middlewares, cookies, standard authentication methods in the API (jwt, oauth2, api-key) and much more!







But the purpose of this article is not so much an overview of all the features of this framework, but how much a push you to explore it yourself. FastAPI has great documentation with tons of examples.







Code from an article on Github

Official documentation

Github repository








All Articles