Build the API with FastAPI top of Django
Even though these two tools seem to be mutually exclusive, they are not. There is possibility to omit Django’s http server and relay all HTTP traffic to FastAPI’s ASGI application. These are the goals of the new package Django FastAPI Bridge
Wait, isn’t Django too old for FastAPI?
If you type “Django and fastapi” into Google you will get results that are simply misinformation. Speaking gently - they’re outdated or written by persons without an experience (a real plague these days):
Can you use Django with FastAPI?
Django-ORM can also be used with FastAPI but that is simply not recommended because it will be useless to use one of the oldest framework which does not use the modern features of Python, with one of the newest framework which uses the modern features like asyncio and others to provide high performance.
The brutal truth is that it is bulls*t. Let the numbers speak for themselves. The tested endpoint looks like:
# sync version
@api.get("/permissions", response_model=PermissionListResource)
def permissions_list():
queryset = Permission.objects.all()
items = [{"pk": obj.pk, "name": obj.name} for obj in queryset]
return PermissionListResource(items=items)
# async version
@api.get("/async/permissions", response_model=PermissionListResource)
async def permissions_list():
queryset = Permission.objects.all()
items = [{"pk": obj.pk, "name": obj.name} async for obj in queryset]
return PermissionListResource(items=items)
- Django + FastAPI in sync mode: 657.16 rq/sec
- Django + FastAPI in fully async mode: 1568.97 rq/sec
Both served through uvicorn. So… is this a high performance Django or not? :)
Note that there also is an A(p)I. (“artifical pseudo intelligence”) which will give you nonsense in the form of supposed knowledge. Be careful and “don’t trust the science” (a “science” is a new idol these days). Ok, enough…
What for is this hybrid?
- To have one codebase for your core (models, logic)
- To expose Django Admin panel top of it
- To use Django ORM, auth, permissions system and other tools with FastAPI
- To gain from brilliant performance and automatic documentation which comes from FastAPI
- You don’t have to rely on less known or unstable solutions
- And, if programmed in async mode in mind, gain from asynchronous features like long polling.
How it works
Django has builtin support for protections against running sync code in async context , and async emulation built on threads. So you can mix sync and async code quite safely, but with a performance loss. To gain from fully async mode you must write handlers with async in mind, which will give you the best performance on the same ASGI server.
Despite the excellent support built into Django, you should pay attention to external applications or add-ons that may be developed for synchronous mode and may lack protection and cause problems. Test your app well.
What will not work
- Django middlewares aren’t compatible because of different request object
- Wherever request is used in the code, it will not be compatible with the request object from FastAPI
- Context processors based on request object are mostly unusable
- Django’s URL routing will not work with FastAPI routing
- Sessions handling (not an issue when using external OAuth2 server)
What’s different
- authenticated user object must be injected as a dependency explicitely, i.e.
user=Depends(get_current_user)
- serialization and model updates will require additional helpers (a Pydantic models coupled with Django ORM models)
- authentication process is delegated to a separate service (OAuth2 recommended), and can be based on Django OAuth2, and share the same database (it is easier to integrate both in such case)
Alternatives? No.
- Django Rest Framework - slow, not fully async, old and not best design (which is mentioned in the docs)
- Django Ninja - however inspired by FastAPI, it is slow and shares part of not best design from DRF
Should I use FastAPI with Django?
“It’s a Frankenstein”
— random python-like developer
You can, you don’t have to. Mid-sized and big-sized projects are “Frankensteins” nowdays. Monoliths or microservices - does not matter. For such projects, where you must maintain them, it is important to have consistent and simplest stack. It is easier to support Django and FastAPI instead of tens of differrent technologies, frameworks and tools, not mentioning difficulties with hiring developers who knows A, B, C, D, E, etc frameworks or libraries. It is even a matter of team management not technology itself.
“But you broke Django!”
— probably python developer
There is no practical difference between not using features A, B, C because they are not needed, and not being able to use A, B or C for technical reasons. Also, I didn’t broke Django in any way. It’s just a mental thing. But for sure, you should be aware of the limitations.
Summing up
Django FastAPI Bridge is NOT fully compilant with Django , because it is not using Django ASGI/WSGI http server. Features based on middleware or request/response objects simply won’t work. But, with a proper separations of concerns, you are able to use your app logic codebase to run different services top of it, and you have all battle tested tools needed to get the things done. Note that in most cases when building a RESTful API (or even an entire API), you won’t miss the built-in Django middleware.
The really missing parts the Django FastAPI Bridge will try to deliver. I am considering adding an adapter for the request object, but it can be tricky and faulty.
Powiązane projekty
- Django FastAPI Bridge: Build FastAPI on top of Django project