Starlette is a lightweight ASGI framework, it has a impressive performance, supports async and its simplicity allow us to easily write scalable web systems.
Pydantic provides data validation and serialization using python type annotations, it enforces type hints at runtime, provides user friendly errors when data is invalid, is fast (it claims to be 12x faster than DRF).
The union of Starlette and Pydantic added to automatic OpenAPI schemas generation and swagger gives us a great toolset to quickly develop a (Fast) API. Type annotations enforcement results in an amazing developer experience.
FastAPI is database agnostic and easily integrable with any Python ORM (here enters Django ORM in this example).
Django
Advantages
Django provides a great toolbox to quickly develop a web application, as from their logo: "The web framework for perfectionists with deadlines".
Django’s ORM is simple, allow us to easily write clean code, is powerful to translate different types of queries without use of raw SQL and has a great migration control system.
Django’s admin is great tool to manage data with minimum development effort.
Disadvantages
Django Rest Framework (DRF) serializers are way slower than Pydantic validators/serializer.
Django is built based in metaclasses, this results in missing type hints in several objects you manipulate.
Django ORM is not able to operate safely in an async environment. But discussions about supporting async are active and hopefully Psycopg3 implementation will enable this support. Use of asgiref library solves this problem until this is implemented.
Uniting forces
Starlette will provide a light weight ASGI framework to server our API endpoints.
Pydantic will provide a toolset to validate and serialize our payloads, while enforcing type hints in our code base.
FastAPI’s OpenAPI support will provide a toolset to generate a nice API documentation.
Django will provide a powerful ORM, migration control system and the admin page to manage our data.
Djantic will be the bridge between Pydantic schemas and Django models.
Requirements
This tutorial expects you to have some familiarity of:
There will be endpoints for registration and authentication:
/register
/login
Schemas:
We will use Djantic to automatically generate the Pydantic schemas basing in our User model. We will also define the JWTPairSchema to serialize the JWT in the /login endpoint. Let’s keep it simple and not define the JWT refresh endpoint for now.
```python # users/views.py from django.contrib.auth import authenticate from django.db import IntegrityError from fastapi import APIRouter, Depends, HTTPException from fastapi.security import OAuth2PasswordRequestForm from rest_framework_simplejwt.tokens import RefreshToken
from .models import User from .schemas import CreateUserSchema, JWTPairSchema
@router.post("/login", response_model=JWTPairSchema) def login(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate(username=form_data.username, password=form_data.password) if user is not None: return get_jwt(user) raise HTTPException(status_code=400, detail="Incorrect username or password.")
ASGI:
Include the user views in the ASGI application:
1 2 3 4 5 6 7 8
# fastdjango/asgi/fastapi.py from fastapi import FastAPI
# utils/auth/user.py from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from rest_framework_simplejwt.authentication import JWTAuthentication
FastAPI provides better performance than Django REST Framework, enforces type hints in the code and has minimal boilerplate code. Django ORM is a great choice for abstracting database operations and managing database migrations.
Async
We didn’t cover the use of async in this tutorial, Django ORM doesn’t safely support async yet. But we can use the asgiref library to await Django DB transactions until support for async is released. FastAPI is fully compatible with async views.
Out of the shell solutions
Instead of combining FastAPI and Django in a project like in this example, there are other options like Django Ninja that has almost 3k stars in Github (as of May 2022). But I recomend directly using FastAPI because most of the code for the ASGI framework of Django Ninja is an adaptation of FastAPI’s code. FastAPI is wider adapted and will probably provide more comunity support and maintenability.