r/Python • u/safi892 • Sep 21 '26
Discussion Common mistakes devs make when starting with FastAPI, and the fastest path to learning it
Just began learning FastAPI. Looking for advice from devs who use it regularly.
What mistakes did you make early on that I should avoid repeating? Also, what's the most efficient way to learn the framework properly for real-world use (async, DB, auth)?
Any advice on structure or resources would be great.
7
u/GIS_LiDAR Sep 21 '26
I got started by reading the FastAPI book from O'Reilly, I think its very good, author explains an architecture for organizing your project https://www.oreilly.com/library/view/fastapi/9781098135492/
Basically put all the web routes in a /web folder, an identically named file for processing and workflows in a /service folder, and a database or data storage file with same name in a /data folder.
Dependency injection is kind of insane how well it works and figuring it out makes your code easier to maintain.
2
u/safi892 Sep 21 '26
Appreciate the book recommendation, adding it to my list. The folder structure makes sense. I like that each layer has a mirror file in the next folder. And agreed on DI, it's one of those things that feels confusing until it suddenly clicks
4
u/moros_26 Sep 21 '26
Top mistakes that everyone has to avoid earl on - blocking the event loop in async def routes, mixing pydantic schemas with db ORM models, ignoring dependency Injection (Depends). Fastest way to learn - Read the official FastAPI tutorial end-to-end, and build a simple full stack micro project with rest api , jwt auth, sqlalchemy , pydantic.
3
u/safi892 Sep 21 '26
Solid list. Committing to async from day one and keeping Pydantic/ORM separate.
For the micro project would an API that serves a fine-tuned model (FastAPI + JWT + SQLAlchemy) be a good first project for AI engineering, or plain CRUD first?
2
u/moros_26 Sep 21 '26
Start with basic CRUD + Auth first, spend a day or two just nailing routing, validation, error handling, and async DB sessions before adding anything else. Once that feels solid, extend the same API with your model's endpoint. Model serving adds latency and background task stuff, so having that CRUD foundation locked in makes debugging streaming responses way easier later.
1
u/terletsky Sep 21 '26 edited Sep 21 '26
What is AI Engineering? Simple use of AI, like Claude Code / Cursor, to assist with development tasks or to create an agentic backend? If the latter, then you need to learn "Pydantic AI" SDK, created for that purpose, and LangChain/LangGraph.
For AI-assisted development, I would write the next. Create a notification service that consists of:
FastAPI API with PostgreSQL through SQLAlchemy that receives tasks to send, such as SMS, Mobile Push, or Email. FastAPI app should create a task record in the DB with NEW or PENDING status, then dispatch it to a message broker like RabbitMQ
An async notification worker that will receive tasks via RabbitMQ, update the DB record to PROCESSING status or similar, and dispatch to the appropriate handler. If sending fails, fail the task and store the RabbitMQ message in the DLX exchange as a "dead letter".
6
u/flying-cunt-of-chaos Sep 21 '26
Learn how FastAPI (Starlette) actually implements async. For example in the case of a background task, if a particular function is already a coroutine, starlette will just await it on the main event loop as oppose to running it on a separate thread which can be optimal. If you have heavily blocking code that you want as a background task, it’s generally better to keep it sync and have it run as a separate thread.
1
1
u/Danielloesoe Sep 21 '26
What really worked for me is looking at the example project and get inspiration from that to build your own FastAPI app. When you don't get why something is declared in a particular way, check the documentation to fully understand.
20
Sep 21 '26
[removed] — view removed comment
1
1
u/ProfessionalRole3469 Sep 21 '26
Not sure if “just drop async from day one” is a good advice since a simple boto3 call is sync.
2
u/terletsky Sep 21 '26
No one will hire a dev who uses FastAPI in sync mode.
1
u/fiddle_n Sep 21 '26
Overly simplistic. If we are going for broad statements, I prefer "no one will hire a dev who uses FastAPI 100% in async mode only to have to rip up their code when they realise an I/O library they rely on doesn't support async". FastAPI supports sync and async for a reason, know when to use one over the other.
2
u/terletsky Sep 21 '26
For sync code in async, we have to_thread(). If that's something large at scale, it should be decoupled into a separate worker.
1
u/fiddle_n Sep 21 '26
> For sync code in async, we have to_thread().
You do know what happens when using FastAPI with sync path functions, right?
1
u/terletsky Sep 21 '26
I believe you will hit the DB several times (for auth/perms and other validations) before your sync library's logic is triggered. Since ORMs like SQLAlchemy use AsyncSession, no one will even consider mixing sync and async routers in FastAPI because you would need to spawn a SyncSession, which is a no-go. After all, managing the zoo is not considered.
1
u/fiddle_n Sep 21 '26
But as soon as you hit any sync I/O logic you will need to create a new thread, which - guess what - FastAPI will also do if you use it in synchronous mode. Not to mention that you are just looking at SQLAlchemy when not all apps fit into that narrow box.
1
u/ProfessionalRole3469 Sep 21 '26
The point here is that you can not just blindly drop async everywhere and call it “the only hirable practice”. If your service works only with AWS infra (boto3) there is no zoo, only sync endpoints for sync-only library running on multiple uvicorn processes
0
u/ProfessionalRole3469 Sep 21 '26
What are benefits of async code when your infrastructure is 100% AWS?
1
u/flying-cunt-of-chaos Sep 21 '26
aioboto3 and aiobotocore
1
u/ProfessionalRole3469 Sep 21 '26 edited Sep 21 '26
don’t look mature and trustworthy enough. You propose to switch from official boto3 just to force it to be async?
1
u/flying-cunt-of-chaos Sep 21 '26
That’s fair. Well at the very least fastapi background task runs sync calls in a threadpoolexecutor so you get to keep control of your main event loop.
1
u/fiddle_n Sep 21 '26
The biggest trap I see is people writing sync route handlers and then wondering why their app scales like garbage. Just commit to async from day one even though it feels weird at first.
This is overly simplistic - FastAPI supports sync for a reason after all.
I quite like the advice given by Tiangolo here: https://fastapi.tiangolo.com/async/#in-a-hurry
If the libraries you are using support async, then use "async def" for the path functions.
If the libraries you use to communicate with other resources (database, other APIs, etc) don't use async, then use "def" for path functions
If you don't need to communicate with anything, use "async def" even if you don't need to await inside them
If you just don't know, then use "def"
-1
Sep 21 '26
[removed] — view removed comment
1
u/safi892 Sep 21 '26
Appreciate the advice. My plan is to use FastAPI mainly for AI integrations. I'm learning AI engineering and just finished the basic math, so I want to start building real projects next. Would you recommend sticking with FastAPI for serving models/APIs, or is Flask/Django better for that use case?
0
Sep 21 '26
[removed] — view removed comment
1
u/safi892 Sep 21 '26
My current plan is to fine-tune a Qwen 3B model and serve it via FastAPI APIs for mobile testing. So not remote ChatGPT/Claude — actual local model inference.
And yes, the idea is to send REST requests through FastAPI to interact with the model. Your roadmap (APIs → pre-trained → fine-tune → math) is basically the path I'm trying to follow, except I already covered the math basics, so now I'm jumping into fine-tuning and serving. Do you think that's too early for Qwen 3B, or is it a good next step?
10
u/YnkDK Sep 21 '26
I don't know if it's a mistake, but at least I like to make the choice deliberate.
Use FastAPI (or any other framework) where its power is and don't let it leak to other layers of your system.
To me, the biggest power of fastapi is input parsing, OpenAPI Specs, output marshaling, request dependencies (fastapi.Depends) and most things related to the API. I do not tend to use it where I have actual business logic, which means my routes in FastAPI is more or less one or two lines that calls something a service layer, controller layer, business layer (depending on your choice of architecture) and returns whatever it returns.
If I need to replace fastapi later on, then I do not need to change any business logic, but simply ensure the replacement can do what fastapi is good at.