litestar
litestar copied to clipboard
Litestar v3 roadmap
Summary
Litestar v3 is coming soon! 🚀
We’re thrilled to announce that Litestar v3 is on the horizon, bringing a host of exciting new features, improvements, and some breaking changes to make your development experience even better. Here’s what you can expect
Things to do for v3
- [x] Remove
StaticFileConfig - [x] Drop support for implicit Optional Default Parameters
- [x] Replace OpenAPI Controller with Plugins
- Elimination of
OpenAPIControllerSubclassing - Changes to Endpoint Configuration
- Modification to
root_schema_siteHandling
- Elimination of
- [x] Remove deprecated
appparameter forResponse.to_asgi_response - [x] Remove deprecated scope state utilities
- [x] Remove deprecated utility function
is_sync_or_async_generator - [x] Remove of semantic HTTP route handler classes in favour of functional style decorators
- [x] Remove of deprecated
litestar.middleware.exceptionsmodule andExceptionHandlerMiddleware - [x] Overhaul route handler configuration (https://github.com/litestar-org/litestar/pull/3900)
- [ ] Remove
litestar.contribnamespace - [x] Improve "file system" abstractions (https://github.com/litestar-org/litestar/pull/4056)
- [ ] Remove all deprecated items scheduled for removal in 3.0
- [ ] Remove pagination
- [ ] Don't use
__future__.annotations, only use stringized annotations where strictly necessary / clean up signature namsepaces - [x] Deprecate plugin protocols in favour of abstract base classes and remove deprecated plugin protocols (https://github.com/litestar-org/litestar/pull/4025, https://github.com/litestar-org/litestar/pull/4026, https://github.com/litestar-org/litestar/pull/4027, https://github.com/litestar-org/litestar/pull/4028, https://github.com/litestar-org/litestar/pull/4026)
- [ ] Use native event loop in
AsyncTestClient(https://github.com/litestar-org/litestar/issues/1920) - [x] Drop Python 3.8 support (https://github.com/litestar-org/litestar/pull/4010)
- [ ] Improve and simplify logging interface (https://github.com/litestar-org/litestar/issues/2858)
- [ ] Update sentry integration
- [ ] Move built-in middlewares to new
ASGIMiddleware(https://github.com/litestar-org/litestar/pull/4055) - [ ] Add migration guide :)
We will update this issue with information about the release, how to prepare, upcoming pre-releases etc.
If you've got any questions, remarks or additions, this is the place to leave them :)
would it be possible to have more standardisation of acronym capitalisation rules?
@HTTPRouteHandler(..., http_method=[HttpMethod.GET, HttpMethod.POST]) kind of grinds my gears.
(my preference is for only initial caps i.e. HttpMethod because that's more easily scannable/parsable)
would it be possible to have more standardisation of acronym capitalisation rules?
@HTTPRouteHandler(..., http_method=[HttpMethod.GET, HttpMethod.POST])kind of grinds my gears.(my preference is for only initial caps i.e.
HttpMethodbecause that's more easily scannable/parsable)
Mmh. I'm not too keen on renaming things simply for optics. It's a breaking change after all, but for a relatively small benefit (specifically in this case, where you'd normally never use HTTPRouteHandler directly).
I think I'm more thinking in terms of the future - AFAIK, there currently isn't any project-wide convention for this, and it'd be good to set one.
Hi, kinda unrelated to the roadmap. But I'd like to start developping an API for a personal project. Is it ok for me to start developping on the unfinished v3.0 branch or is it better for me to stay on the v2.0 and wait for the migration.
I dont mind any breaking and refactoring if there are any evolving changes as it is a greenfield project.
I dont mind any breaking and refactoring if there are any evolving changes as it is a greenfield project.
I think you answered yourself your question, idk when v3 will be out though but given the sheer amount of tests in the suite you shouldn't have too many issues, and if you have that's cool for us, we have a beta-tester :)
Ok perfect, a pleasure to be a beta tester, I don't think I will be hitting a lot of edge cases as I wont initially be using any dependency injection or custom middleware.
Don't use future.annotations, only use stringized annotations where strictly necessary / clean up signature namsepaces
What's the reason for this decision?
Don't use
__future__.annotations, only use stringized annotations where strictly necessary / clean up signature namsepacesWhat's the reason for this decision?
To reduce the reliance on signature namespaces. The issue is that if Litestar internally uses __future__.annotations (or other stringized annotations), it has to resolve those strings again when it wants to do something with those types, which Litestar does a lot. This process however is actually not entirely deterministic, and can lead to weird bugs. It's also quite hard to get just right.
So the easier thing is, at least for Litestar itself, to just not use these. For end-user applications, the cases where this causes an issue are usually much easier to resolve.
Could it be a good opportunity to separate Parameter() into several methods like Query() Header() Cookie() and Path()?
That would be a useful addition, yes
Looks like a good list, but I was curious why this one:
Remove pagination
?
Would love it if typed SSE was in the list, or at least a way to resolve SSE output with DTOs the way returning from a regular route would work.
Or is it worth pursuing separately to v3?
I would like to see state being injected into lifespans as well. app.state is not correctly typed, which means I always have to use cast on app.state in all of my lifespans. It would be nice if it's just a parameter which I can type annotate before runtime.
Looks like a good list, but I was curious why this one:
Remove pagination
?
If you want to use pagination in the v3 of litestar, you can use Advanced Alchemy or rollout your own implementation The current implementation inherits from Advanced Alchemy but it does not have a ton of utility. Having it in both places is not a good thing
just throwing in without much thought. how painful would it be to migrate from urllib.parse altogether in a favour of ada-url/can-ada? they are much faster and besides correct and fully whatwg compliant
Why are Protocols being deprecated in favor of Abstract Base Classes? 🥺
Why are Protocols being deprecated in favor of Abstract Base Classes? 🥺
Protocols are hard / impossible to extend in a backwards compatible manner. So ABCs are just more convenient :)
it is possible to significantly minus the amount of dependency packages in v3?
it is possible to significantly minus the amount of dependency packages in v3?
Here's an overview of the currently required dependencies, and their state in v3:
| dependency | needed for | in v3 |
|---|---|---|
anyio |
core | |
click |
CLI | |
rich-click |
CLI | |
httpx |
testing | |
multidict |
core | |
polyfactory |
OpenAPI examples | moved to extra |
pyyaml |
OpenAPI yaml schema | moved to extra |
typing-extensions |
core | |
multipart |
multipart uploads | |
litestar-htmx |
HTMX support | moved to extra |
exceptiongroup (for python <3.11) |
core | |
importlib-metadata (for python <3.10) |
core | to be dropped |
importlib-resources(for python <3.9) |
core | dropped |
As you can see, there's about 7 required dependencies in v3, with another 2 required for backwards compatibility if using older Python versions. Of those 7, 4 could be made optional:
clickandrich-click: Would remove the CLI out-of-the-box. We have discussed this in the past and decided against it, since we consider the CLI a core part of Litestarhttpx: Would mean we don't get testing capabilities built-in. Could be up for discussion, but I'd guess that it wouldn't have much of an impact, as most projects using litestar probably includehttpxat least as a transitive dependencymultipart: Would either remove multipart support, or require us to implement our own multipart parser. IMO we shouldn't implement our own, because multipart is tricky, and doing it correctly and performantly even more so. Not sure whether this functionality is needed out of the box, could be discussed
@ockan is there a specific issue you have with Litestar's dependencies?
how painful would it be to migrate from urllib.parse altogether in a favour of ada-url/can-ada?
Assuming my question goes unanswered, I suppose it would be painful :)
Plus, they are binary dependencies anyway... But many modern web apps already include a few binary deps (e.g., uvloop, httptools, asyncpg, SQLAlchemy with speedups).
I fully understand that this would certainly break things, including routing, but considering that Litestar is the only ASGI framework I know of that uses a trie for routing instead of arrays (and all the trickery done in DTO codegen) I think you generally prefer performant solutions in areas where the specs are stable
clickandrich-click: Would remove the CLI out-of-the-box. We have discussed this in the past and decided against it, since we consider the CLI a core part of Litestar
doesn't this conflict with with the recommendation of NOT running the app via CLI in production deployment?
click and rich-click benefit over builtin argparse is basically just looking more fancy, which once again it doesn't matter in production.
httpx: Would mean we don't get testing capabilities built-in. Could be up for discussion, but I'd guess that it wouldn't have much of an impact, as most projects using litestar probably includehttpxat least as a transitive dependency
I agree that in most cases people might still use it, but since it is for testing and not required for actual deployment it should still be optional. If someone chooses to use different library, then suddenly they need to have both installed.
Why not do what other packages do for example uvicorn where dependencies are minimal, the recommended are under standard extra and all the documentation says to install uvicorn[standard] this way new user gets the recommended dependencies, but someone who wants to trim the fat can install only what they need.
The reason I'm pushing it is that when using litestar + few other dependencies the docker container grew to 500MB (yeah, boto3 is largest contributor, but litestar also has huge part in it)
typing-extensionscore
Is this also needed for backwards compatibility with older Python versions (<3.12)? If not what's missing/different from typing?
clickandrich-click: Would remove the CLI out-of-the-box. We have discussed this in the past and decided against it, since we consider the CLI a core part of Litestar
Is there a link to the discussion? Fwiw my only use of the CLI is the litestar run subcommand and even this is easy to replace by running uvicorn directly (and actually sometimes it's necessary for passing extra parameters that litestar run doesn't forward, e.g. --uds).
httpx: Would mean we don't get testing capabilities built-in. Could be up for discussion, but I'd guess that it wouldn't have much of an impact, as most projects using litestar probably includehttpxat least as a transitive dependency
This used to be true for one of my projects until a few months ago. Sadly httpx has performance issues in production ([1], [2], [3]), CPU usage was going through the roof and was causing serious issues to an asyncio-heavy, single-process/threaded application. Since moving to aiohttp performance improved substantially and httpx is now a transitive dependency only through litestar.
Here's an overview of the currently required dependencies, and their state in v3:
anyioclickrich-clickhttpxmultidictpolyfactorypyyamltyping-extensionsmultipartlitestar-htmxexceptiongroupimportlib-metadataimportlib-resources`
the dependency 'rich' is not in the above list
forced Type Hints of parameter and return value will be abandoned? forced Type Hints cause more surplus import statement
Definitely would like all testing libraries including httpx to be removed. It would reduce the size of my Docker builds.
Plus, they are binary dependencies anyway... But many modern web apps already include a few binary deps (e.g., uvloop, httptools, asyncpg, SQLAlchemy with speedups).
I fully understand that this would certainly break things, including routing, but considering that Litestar is the only ASGI framework I know of that uses a trie for routing instead of arrays (and all the trickery done in DTO codegen) I think you generally prefer performant solutions in areas where the specs are stable
Generally, ever since the OG maintainer left, the focus on performance is nonexistent, and we’ve returned to the “if it’s Python, it shouldn’t be fast” mantra. But I am definitely willing to write the PR and benchmarks for this even at the risk of rejection.
One issue I can think of is that if upstream forgets/stops releasing their wheels, Litestar users will have to fallback to source builds and if their build environment doesn’t have the required dependencies, it might cause some pain to users. AFAIK, ada-python is using setuptools which, unlike maturin, doesn’t automatically install a compiler if it’s not found on the environment.
One issue I can think of is that if upstream forgets/stops releasing their wheels, Litestar users will have to fallback to source builds and if their build environment doesn’t have the required dependencies, it might cause some pain to users. AFAIK,
ada-pythonis usingsetuptoolswhich, unlikematurin, doesn’t automatically install a compiler if it’s not found on the environment.
I forgot to mention that litestar itself includes binary dependencies such as msgspec and multidict, both of which using setuptools
So I think this is another topic for a discussion: should litestar have binary deps?
msgspec is written in C which, at least for most systems, would already have a compiler installed. C++ is not the same.
@abebus
how painful would it be to migrate from urllib.parse altogether in a favour of ada-url/can-ada?
Assuming my question goes unanswered, I suppose it would be painful :)
It wouldn't be all to painful, but the gains would also be minimal. We've experienced with optimised URL parsing in the past, and the performance gains there are simply negligible.
@takeda
doesn't this conflict with with the recommendation of NOT running the app via CLI in production deployment?
Not really. There's a whole bunch of other use cases for the CLI besides starting the server.
clickandrich-clickbenefit over builtinargparseis basically just looking more fancy, which once again it doesn't matter in production.
Also, no. click is vastly more ergonomic and offers much better DX. It's also the most widely used CLI library out there currently, which makes it a great fit for Litestar's extendable CLI; Users can easily plug in there, using what they already know / have in place.
Why not do what other packages do for example uvicorn where dependencies are minimal, the recommended are under standard extra and all the documentation says to install
uvicorn[standard]this way new user gets the recommended dependencies, but someone who wants to trim the fat can install only what they need.
We already do that.
The reason I'm pushing it is that when using litestar + few other dependencies the docker container grew to 500MB (yeah, boto3 is largest contributor, but litestar also has huge part in it)
Not sure what you are doing there, but you certainly won't get the majority of a 500MB install from doing pip install litestar. For comparison, here's the resulting venv size after installing various frameworks into it:
| package | size | num dependencies |
|---|---|---|
starlette |
1.5MB | 1 |
flask |
2.7MB | 6 |
fastapi |
9.5MB | 3 |
litestar v3 |
15MB | 10 |
litestar |
34MB | 12 |
django |
41MB | 2 |
fastapi[standard] |
49MB | - |
A few notes on this:
djangois the heaviest pacakge of them all, despite having only 2 dependencies (sqlparseandasgiref)litestar v3already has less than double the footprint of the current version- package size does not linearly correlate with dependencies
So yes, Litestar isn't the most lightweight package of them all, but it's also not trying to be. It has a far more rich feature set than the microframeworks included in this comparison, and it tries to avoid nih syndrome, e.g. by using the existing, well established multidict instead of implementing something from scratch. If you want or need something very minimal, Litestar probably isn't for you, as that's simply not what it's trying to be.
@gsakkis
typing-extensions core
Is this also needed for backwards compatibility with older Python versions (<3.12)? If not what's missing/different from typing?
Yes, mostly backwards compatibility.
clickandrich-click: Would remove the CLI out-of-the-box. We have discussed this in the past and decided against it, since we consider the CLI a core part of LitestarIs there a link to the discussion? Fwiw my only use of the CLI is the
litestar runsubcommand and even this is easy to replace by running uvicorn directly (and actually sometimes it's necessary for passing extra parameters that litestar run doesn't forward, e.g.--uds).
I actually don't know, at least I can't find it at the moment. Might have been an internal discussion.
httpx: Would mean we don't get testing capabilities built-in. Could be up for discussion, but I'd guess that it wouldn't have much of an impact, as most projects using litestar probably includehttpxat least as a transitive dependencyThis used to be true for one of my projects until a few months ago. Sadly
httpxhas performance issues in production ([1], [2], [3]), CPU usage was going through the roof and was causing serious issues to an asyncio-heavy, single-process/threaded application. Since moving toaiohttpperformance improved substantially andhttpxis now a transitive dependency only through litestar.
Yeah, I'm aware of the httpx performance struggles, I've been dealing with them myself. As I said, that's the one dependency I think can definitely be discussed.
@ockan
the dependency 'rich' is not in the above list
The list does not contain transitive dependencies.
forced Type Hints of parameter and return value will be abandoned? forced Type Hints cause more surplus import statement
No, they will not. Litestar is built around type annotations. Its core systems rely on type hints to provide context information and validations. If you do not like type hints, you should pick another framework that is not built upon them (e.g. starlette, django or flask)
@winstxnhdw
Generally, ever since the OG maintainer left, the focus on performance is nonexistent, and we’ve returned to the “if it’s Python, it shouldn’t be fast” mantra. But I am definitely willing to write the PR and benchmarks for this even at the risk of rejection.
What exactly gave you that impression? Some of the biggest performance improvements have been made since then, e.g. the DTO codegen. In general, we have had a steady focus on performance improvements. Just yesterday we've merged #4372, which focuses on performance. One of the biggest changes in v3 was reconstructing handler and layer registration to increase startup (and to a lesser degree runtime) performance.
To be honest, I'm not particularly fond of baseless accusations like this. If there's a specific issue you're having, e.g. a performance regression, you should open up an issue, and it will most certainly get attention.
What exactly gave you that impression? Some of the biggest performance improvements have been made since then, e.g. the DTO codegen. In general, we have had a steady focus on performance improvements. Just yesterday we've merged https://github.com/litestar-org/litestar/pull/4372, which focuses on performance. One of the biggest changes in v3 was reconstructing handler and layer registration to increase startup (and to a lesser degree runtime) performance.
You are right. I think ‘nonexistent’ was the wrong word here. Apologies for that. I wanted to convey that Litestar’s attitude on performance is nonexistent unless the resolution of performance gain can be measured in the hundreds of milliseconds.
As you said,
It wouldn't be all too painful, but the gains would also be minimal. We've experienced with optimised URL parsing in the past, and the performance gains there are simply negligible.
When Goldhizer was maintainer, he entertained most if not all performance improvement PRs, thats why we now have msgspec, our trie router, and there were even experiments on rewriting the router in Cython. The culture was different back then. Now if I want to implement an idea for improving performance in the hundreds of nanoseconds range, like removing a function call, inlining some code, or a partial rewrite in Cython, it’s likely to be rejected, because it’s slightly ‘less readable’. I think sometimes we forget that performance is not always about optimising the hot paths and the low hanging fruits, but there can also be meaningful gains from small tweaks that compound overtime that we would’ve otherwise missed in hindsight.
Regardless, thank you for maintaining Litestar. If we ever return to looking at reducing request latency again, I would like to be part of that.