Hacker News new | ask | show | jobs
by varun_chopra 615 days ago
This post comes at a great time. I've been looking into what the "perfect" stack would be for me (I'm OK with Python but haven't done any frontend work).

Is anyone actually using FastAPI in a commercial, large scale app? Would you prefer using...say Django or Flask + Gevent (since they're more mature) over FastAPI?

I recently found this thread[1] about FastAPI. It's somewhat old now but reviews are mixed. I'm wondering if the landscape has improved now. Additionally, OP is using NextJS for the frontend and even that isn't without complaints[2]. What's odd for me is that the React website also asks you to pick between either Next.js or Remix[3].

[1] https://www.reddit.com/r/Python/comments/y4xuxb/fastapi_stab...

[2] https://www.reddit.com/r/nextjs/comments/1g18xgu/nextjs_is_h...

[3] https://react.dev/learn/start-a-new-react-project#production...

7 comments

Indeed, we use FastAPI in quite a large scale! I would not trade FastAPI for anything else at this point. Before the typing module became ubiquitous there used to be a lot of "magic" frameworks that made heavy use of Python's dynamic nature; both Django and Flask fall within this category: I am not a fan of untyped Python, at all.

There's some gotchas in the way FastAPI works, mostly due to its usage of thread pools and the GIL. I would recommend anyone starting a project to exclusively use asynchronous I/O (SQLAlchemy supports async with asyncpg), as FastAPI is very clearly meant as a pure ASGI framework, despite what they claim.

How is your experience with async SQLAlchemy with FastAPI?Ive experienced a handful of nasty bugs, specifically around how connection pooling is handled.
Yup, I use FastAPI for some large services, handling a few million requests per day. Great experience overall, and speed of development is significantly improved. You can feel confident something is going to work after writing code. With flask and django I was always second guessing if things are hooked together properly. One pitfall I would avoid though is mixing both sync and asyncio together. Ive found there are a lot of footguns in that type of setup. Use one or the other, but not both
Hello, could you elaborate on the footgun with mixing sync and asyncio ? I am currently devellopin one app with both kind of endpoint + websocket and I prefer not discover too late this problems .
I've found that when mixing the two types of routes, it can be quite easy to accidentally introduce blocking paths which freeze up the main event loop, especially if mixing async dependencies with sync ones.

When a route is async, it gets scheduled on the main event loop, meaning that any blocking calls can block all requests in flight, and block unexpected things like start up and teardown of api handlers. `asyncio.to_thread()` can help here, but it's easy to forget (and there's no warnings in case you forget).

If you do mix the two, I would be very careful to monitor the timings of your requests to detect early if blocking is occurring. For adding these metrics, I suggest using something like statsd or open-telemetry libraries for adding reporting to the endpoints, which you can feed into telemetry dashboards.

Basically, you want anything that has any kind of IO (network, disk, etc.) or which is very slow to compute to be fully async. If you have a function that returns almost instantly, like computing the hash of something, you can keep that sync.

If you're forced to use a slower sync function (say, something from a library that you can't easily change), then you can use asyncio.to_thread() so that it can run in a separate thread without blocking your main event loop. If you don't do that, then you sort of defeat the whole purpose of the architecture because everything would stop while you're waiting for that slow sync function to return.

Django/DRF are fine for API's particularly with DRF Spectacular to generate the Open API specs. DRF couples tightly to the ORM and plays nicely with the Django DB models.

FastAPI will have more boilerplate, but I'm not sure that's an issue anymore in the age of AI coding assistants.

HTMX is also wonderful for both. It's a nice tech for lightweight SPAs. If you're going to go deeper into the JS side you can look at some of the more mature frameworks. I've been kinda partial to Vue.js.

And if you really want to go crazy there's pyscript from anaconda.

DRF's serializers make it really easy to generate N+1 queries and it's a very opinionated framework that doesn't share many opinions with other frameworks. There is also no plan to bring async support to DRF, even though it's already present in Django itself.

If you want to make a Django API these days I'd lean towards django-ninja which essentially bolts Pydantic onto Django, in a similar fashion to how FastAPI leverages Pydantic ontop of an async flask-like framework.

I personally would just use FastAPI but I understand lots of folks have invested heavily in (or prefer) Django's ORM to raw SQL or Alchemy.

There's a lot to like about the Django ORM. And Django still has it's place.

What I'd like is a SQL that creates and consumes a JSON structure as output/input, and then there wouldn't really be a need to serialize/deserialize anything. Python would be a lightweight wrapper for authentication, error handling, logging, and data processing that couldn't be easily done with SQL.

I mean people are trying this, but SQL feels so arcane. If you have tabular data and working with spreadsheets, SQL is great. And the JSON support in postgres is a badly bolted on design choice to force tree style data into tabular data.

Instead they should modify SQL to process tree style data as tree style data.

There is a JSON column type in SQLite now, and it's supported by SQLModel/SQLalchemy:

https://www.sqlite.org/json1.html

There's a JSONB column type in postgres for a while now too with the arrow syntax.

I think my point is that the structure of the data in a relational database is tree-like. Yet we can only get tabular data out of the queries.

FastAPI automatically generates the openapi.json file for you, which is how it's able to also give you the Swagger page "for free" once you've defined the route structure. It's very convenient.
I have grown to believe that python is not appropriate for any organization where multiple teams will work in the same codebase / repo. The system is prone to disorder and should be in the same category as perl for similar reasons.

Programming is a team sport and static types is just too useful and the bolted on typing is insufficient. We are burning, literally, millions of dollars in salaries to make python work at our org. It has been the same now at the four shops I've been a staff/principal level. Dynamic languages lend towards less maintainable code because the compiler offloads work to your squishy human working memory.

I tend to agree, the flexibility that non-statically typed languages (i.e. Python) offer on smaller-scale projects (very) quickly diverges to chaos on larger-scale. With scale, rules and rigidity provide structure, without they provide verbosity and bureaucratic obstacles. Unfortunately “scale” is a gradient, not discrete, so there’s no “right answer” - hence the waste you experience. Ultimately, waste is in the eye of the beholder… “One person’s waste is another’s GDP.”
mypy helps, but I generally agree. Similar thing on the node side.. Typescript is great but it's still a lot harder to scale an application. It can be done in dynamic languages obviously (PHP: Slack, Typescript: VSCode) but IMO it's harder.

Despite having a big Django/DRF and FastAPI footprint, our backends in-development are using C#/aspnet.

> where multiple teams will work in the same codebase / repo

This is a bad idea in general and leads to all sorts of problems.

Statements like these are usually too general to apply to every such case. But I think you are 100% right
Yeah, but python services can work if they communicate by api with other services anyway.

In essence

solo dev: python is ok Tight teams: python not ok big corps where you literally can't even share code: python ok again.

> Is anyone actually using FastAPI in a commercial, large scale app? Would you prefer using...say Django or Flask + Gevent (since they're more mature) over FastAPI?

Django and FastAPI are two different things. The former is a huge and opinionated MVC-like web framework and the latter is a simple library to make HTTP endpoints. I prefer FastAPI but it really depends of what you are building and how many people are going to work on that API.

> What's odd for me is that the React website also asks you to pick between either Next.js or Remix[3].

It's indeed very odd, they made this change with the new doc. I would not recommend to pick any of those and just start your project with vite.js, so you can focus on React and keep it simple. You can use react-router for the routes and react-query to call your backend. You don't really need anything else.

Django with DRF will get you a very maintainable API, and you can have as little or as much boilerplate as you want. For example, you can inherit all of the model’s fields, or you can choose to specify them all, or somewhere in between, add additional fields, etc. You can have it generate pagination or certain filters. It’s got plenty of hooks for overriding functionality.

If you see performance issues or situations where youre hitting the n+1 query issue, you can optimize by using the orm’s prefetch_related, select_related, or just drop into raw sql.

Im obviously a fanperson, but have yet to find a framework combo that I like more than those two. It’s not very fashionable, but you’ll end up with an app thats quick to develop and thats reasonably secure by default.

I'd start with a pure server side stack like Flask or Django and forego the complexity of front-end JS.