Why you should start using FastAPI right now

Hello, Khabrovites! On the eve of the start of classes in the groups of basic and advanced courses "Python Developer" , we have prepared another useful translation for you.












Python has always been popular for developing lightweight web applications thanks to awesome frameworks like Flask, Django, Falcon, and more. Because of Python's leading position as a machine learning language, it is especially useful for packaging models and providing them as a service.



For years Flask has been the primary tool for such tasks, but in case you haven't heard yet, a new contender has emerged in its place. FastAPI is a relatively new Python framework inspired by its predecessors. It improves their functionality and fixes many flaws. FastAPI was built on top of Starlette and has a ton of awesome features.



Recently, he has gained a lot of popularity, and after the last 8 months I have been working with him every day, I can confidently say that all the hype around him is fully justified. If you haven't tried it yet, I've put together five reasons for you why you should still get to know it.



Nice simple interface



All frameworks are forced to balance between functionality and freedom for the developer. Django is powerful, but too stubborn. On the other hand, Flask is high-level enough to provide freedom of action, but much is left to the user. FastAPI is closer to Flask in this regard, but manages to achieve an even healthier balance.



For example, let's see how FastAPI defines an endpoint.



from fastapi import FastAPI
from pydantic import BaseModel


class User(BaseModel):
    email: str
    password: str


app = FastAPI()


@app.post("/login")
def login(user: User):
    # ...
    # do some magic
    # ...
    return {"msg": "login successful"}


It uses Pydantic to define the schema, which is an equally awesome Python library for data validation. Looks simple enough, but there's a lot going on under the hood. Responsibility for validating input data is delegated to FastAPI. If an incorrect request is sent, for example, the e-mail field contains a value of the type int, the corresponding error code will be returned, but the application will not crash, throwing an Internal Server Error (500). And it's all almost free.



Simple example application with uvicorn:



uvicorn main:app


The application can now accept requests. In this case, the request will look like this:



curl -X POST "http://localhost:8000/login" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"email\":\"string\",\"password\":\"string\"}"


The icing on the cake is the automatic generation of documentation according to OpenAPI using the Swagger interactive interface.





Swagger interface for FastAPI application



Async



One of the biggest drawbacks of Python WSGI web frameworks compared to their counterparts in Node.js or Go was the inability to process requests asynchronously. Since the inception of ASGI, this is no longer a problem, and FastAPI fully implements this capability. All you have to do is simply declare the endpoints using the async keyword like this:



@app.post("/")
async def endpoint():
    # ...
    # call async functions here with `await`
    # ...
    return {"msg": "FastAPI is awesome!"}


Dependency injection



FastAPI has a really cool way to manage dependencies. Although developers are not forced to use embedded injection to handle dependencies on endpoints, this is highly recommended.



For example, let's create an endpoint where users can comment on specific articles.



from fastapi import FastAPI, Depends
from pydantic import BaseModel


class Comment(BaseModel):
    username: str
    content: str


app = FastAPI()


database = {
    "articles": {
        1: {
            "title": "Top 3 Reasons to Start Using FastAPI Now",
            "comments": []
        }
    }
}


def get_database():
    return database


@app.post("/articles/{article_id}/comments")
def post_comment(article_id: int, comment: Comment, database = Depends(get_database)):
    database["articles"][article_id]["comments"].append(comment)
    return {"msg": "comment posted!"}


FastAPI get_database at runtime when calling the endpoint, so you can use the return value as you see fit. There are (at least) two good reasons for this.



  1. You can globally override dependencies by modifying the dictionary app.dependency_overrides. This will make testing easier and mocking objects.
  2. The dependency (in our case get_database) can perform more complex checks and allows you to decouple them from the business logic. The matter is greatly simplified. For example, so you can easily implement user authentication.


Easy integration with databases



Whatever you choose, be it SQL, MongoDB, Redis, or anything else, FastAPI won't force you to build your application around a database. If you've ever worked with MongoDB through Django, you know how painful it can be. With FastAPI, you don't need to do an extra hook, since adding the database to the stack is as painless as possible. (Or more accurately, the amount of work will be dictated by the database you choose, not the complexity that comes with using a particular framework.)



Seriously, look at this beauty.



from fastapi import FastAPI, Depends

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker


engine = create_engine("sqlite:///./database.db")
Session = sessionmaker(bind=engine)


def get_db():
    return Session()


app = FastAPI()


@app.get("/")
def an_endpoint_using_sql(db = Depends(get_db)):
    # ...
    # do some SQLAlchemy
    # ...
    return {"msg": "an exceptionally successful operation!"}


Voila! I can already see you typing



pip install fastapi


in the terminal on your computer.



GraphQL support



When you are working with a complex data model, REST can be a major hurdle. It's not really cool when the slightest change on the front requires an endpoint schema update. In such cases, GraphQL saves you. While GraphQL support is nothing new to Python web frameworks, Graphene and FastAPI work well together. There is no need to additionally install any extensions, for example graphene_djangofor Django, everything will just work from the very beginning.



+1: Excellent documentation



Of course, a framework cannot be great if it has poor documentation. Django, Flask, and others have done well at this, and FastAPI is keeping up with them. Of course, since he is much younger, there is not a single book about him yet, but it's only a matter of time.



If you want to see FastAPI in action, I have a great guide for you. I've written a detailed tutorial with which you can deploy your ML model to Docker, Docker Compose, and GitHub Actions!



To summarize, whether you're looking for a fast and lightweight framework for working with your deep learning model or something more complex, FastAPI is your option. I'm pretty sure it will work for you.






Learn more about courses






All Articles