World class stuff.
>Fast: Very high performance, on par with NodeJS and Go.
Is a downright lie
Not sure what this has to do with the library’s quality though, it is a high quality modern python library.
With only JavaScript, Perl, Lua, PHP, Python and TypeScript enabled, fastapi is 64th and nestjs is 73rd, out of 136 libaries. They have a score that's ~10 times lower than the fastest libraries.
It is not, this benchmark is purely about speed, not about being "suitable for your next project". You're the one adding all these other constraints. You only need to deselect some filters when you're doing something like comparing dynamic languages, which you did and wasn't even the initial claim discussed. I also doubt most people would call FastAPI "suitable for your next project" compared to something like Django or Flask that is already well known and maintained.
> But again, I'm not sure what this has to do with it being a high quality modern python library.
We're in a subthread discussing a claim on the FastAPI website that it's "Fast: Very high performance, on par with NodeJS and Go.", and how it's obviously wrong for Go, and possibly wrong for NodeJS.
In the continuous benchmarks, that you can see here [1], taking the last one that has finished at the time of this post (run id 31abee0e-b0c5-414f-9288-216c48e3a70e): Fastapi is 81st, Express 107th, Gin 57th, NodeJS 63rd. In the fortunes part, plain Go is always higher than Gin but varies wildly, from ~15% to ~43%. FastAPI itself is around 7%
I think Express is still the most used JS framework, by a large margin, so claiming to be faster than NodeJS may be fair, as most people thinking about NodeJS will think Express. For Go, you have to be very generous with the "on par", to the point that it's almost meaningless in my opinion. Especially since frameworks are less popular in Go, people tend to use the standard library, which has great performance here.
Imho FastAPI's weakest point is maintenance. The Github repo has 800+ open issues and 400+ open PRs. Tiangolo is the only user that constantly makes non trivial contributions. I just can't see that being sustainable in the long term if all those items are not actively triaged.
The one thing it has going for it is much of the heavy lifting is done by starlette, maintained by encode.io, which is actively funded. It's not trying to be rails, rather it's relying on other libraries and packages to add functionality.
Check out my latest post on HN. Seemingly the creator and single maintainer is ignoring requests from developers to let other people maintain the project. I used FastAPI at work some time ago, but I can't see myself using it again anytime soon. Imho relying on someone's personal project for software that's going to be in production indefinitely is a big risk.
I didn't make that speed claim, though I am aware that tidbit is controversial.
I found Will’s codebase easy to read and reason about, making it easy to help extend.
if __name__ == "__main__": some random code
at the end of module files? Never seen that, why is it used? I understand that it's a guard that only runs when the module is executed directly, but what is the code put there? For developers to quickly visually test stuff by running the module?Here, for example https://github.com/willmcgugan/rich/blob/master/rich/color.p...
You can run some examples using the -m flag + the submodule:
python -m rich.live
python -m rich.markdown # this is actually a markdown to terminal cli
https://rich.readthedocs.io/en/stable/live.html
https://rich.readthedocs.io/en/stable/markdown.html def main() -> None:
pass
if __name__ == "__main__":
main()Static analysis doesn't care. The script can be executed directly, so it has to be treated as if it will be. The fact that the code behaves differently between prod and dev use is a smell, not a selling point.
I'm saying this in the context of writing modern Python with modern tools. In that context it's a poor practice.
FastAPI-Azure-Auth [0] is a library to do authentication and authorization through Azure AD using tokens.
ASGI—Correlation-ID[1] is a package that utilizes contextvars to store information through the asyncio stack, in order to attach correlation/request ID to every log message from a request. Django-GUID [2] does the same for both sync and async Django.
Pydantic-factories [3] is an awesome library to mock data for your pydantic models.
[0] https://github.com/Intility/fastapi-azure-auth
[1] https://github.com/snok/asgi-correlation-id
Really, django is the framework to read if you are into Python.
Much of Django's core has not changed in a very long time, so there would be no type annotations and other modern Python constructs.
FastAPI, pydantic, uvicorn, httpx would be in my list to answer OPs question.
Some of us actually prefer the "old" style of Python. Type annotations are too "Java-ish" for me, I hate source code that declares a function with signature takes more than half of the screen space, I hate making http requests with three layers of nested `async with`. If you are into static typing or RAII why not choose a real deal language instead.
I find his style to be not great, too many code-golfing one liners. Not everything has to be a list comprehension (or even, a double list comprehension). Give me a boring loop with minimal action per line, please.
In "When is Cheryl's birthday?" [1], the way he converts the problem into functional units is insane. A couple of list comprehensions shouldn't scare you. Look above and beyond the details.
[1] https://github.com/norvig/pytudes/blob/main/ipynb/Cheryl.ipy...
The other is Tornado. https://github.com/tornadoweb/tornado
I used it early on when the docs where not there (IIRC), and spent some time reading the code. Very readable. Not sure if pythonic or not.
Not perfect source code, but accomplish the task well.
- PDM: A modern Python package manager with PEP 582 support[1]
- Spleeter: Deezer source separation library including pretrained models[2]
---
- 100% test coverage (with some typical exceptions like `if __name__ == "__main__":` blocks)
- Randomises test sequence and inputs reproducibly
- Passes Pylint with max McCabe complexity of 6
- Passes `mypy --strict`
- Formatted using Black and isort
It is an incredibly complex piece of code, but is immensely rigidly structured, typed and makes heavy use of OO to remain readable and manageable.
So instead of perfect hypothetical textbook code, I think this is a very instructive realistic project.
The code is tested & known to work well
Really any recent project by Encode: https://github.com/encode
Source code is not to be read like a book. If you read it, you must do so with a goal, context and purpose.