#Code Reviews
1 messages ยท Page 2 of 1
And another one to make our glorious tooling happy ๐
Disable the ASGI server integration tests introduced in #3039 by default, as they are only meant to run as part of the extended CI workflow.
should I try run this build-jobs again ? https://github.com/litestar-org/litestar/actions/runs/7713696655/job/21024211657?pr=3048
build docs
Yeah
im so lost in github
Love the commit history ๐
๐ all what I advocate not to do at work, but it is squashed is it ?
Yeah, squashed and cleaned, so no one will know your misery when they read the commit messages ๐
given this sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 140702725436992 and this is thread id 140702742218304. it looks like there is common creation of objects not closed and used subsequently in other parts of the tests, it's just a thought I dont know the codebase enough
No description provided.
Fixes #2979.
- Implement a new
DIPluginclass that allows the generation of signatures for arbitrary types where their signature cannot be extracted from the type's__init__method - Implement
PydanticDIPluginandMsgspecDIPluginclasses to allow using Pydantic and Msgspec enabled classes as dependency providers
Codecov stopped supporting uploads without tokens. This PR provides the token explicitly.
This PR disable the tracking of statements that alter the column projections on the following functions:
- count
- list_and_count (basic & window)
This statement was causing errors when re-using lambdas for multiple queries.
This PR renames ConflictError to IntegrityError
ConflictError will be removed in v1.0.0
This was a beast to track down
Fix a regression introduced in #2751 that would wrongfully assume the state key is always present within the ASGI Scope. This is only the case when the Litestar root application is invoked first, since we enforce such a key there, but the presence of that key is not actually guaranteed by the ASGI spec and some servers, such as hypercorn, do not provide it.
Once this is merged we can do the release
Actually, we need to wait until #general message is resolved
Fix a regression introduced in #3070 while fixing another regression.
This now leaves the scope["state"] handling functionally untouched, to preserve behaviour. The behaviour is still not entirely correct, but it's not something we can fix without introducing breaking changes.
Alright, I reverted the functionality to what it was before the patch, with the fix for the previous regression still intact
That should fix @severe onyx's problem but I can't say for sure yet because I haven't been able to reproduce
@severe onyx, if you have the time, could you check out the patch and confirm if that fixes it?
The find_spec function fails to find rich-click. It should be rich_click
Ha! Reviewed before you even posted it ๐
oh nice ๐
I answered in the PR, dont revert, I think it's an issue with me using LifesnaManager from asgi-lifespan, it's that which breaks sessions between 2.5.4 and 2.5.5, I'm on a shitty wifi train connection so hopefully tomorrow I'll have a clearer view
Anyone free for a quick review of this?
Description
- Fix the parsing of the constraints from union types for Pydantic v2 modelsโ- Before there used to be special handling of optional types, but that's not needed since optional types are also unions and so optional types should also be handled the same way as union types where we just ignore
NoneType. This makes the change the same as that ofFieldMeta.from_type(as changed in[ #491](https://github.com/litestar-org/polyfactory/issues/491)). - Fix the way the annotated types are handled when calling
FieldMeta.from-typeby using the actual type that is annotated rather thanAnnotated[type, ...]โ- Due to the change inFieldMeta.type_argsin[ #491](https://github.com/litestar-org/polyfactory/issues/491),Annotated[List[str], MinLen(10)]now returnsList[str]whereas before it would have returnedstras the child. This results in the children for theFieldMetacorresponding to the annotationAnnotated[List[str], MinLen(10)]to beList[str]instead ofstr. Unwrapping the annotation to get the actual underlying type fixes this problem since nowFieldMeta.type_argswill returnstrin this case instead ofList[str].
Close Issue(s)
https://github.com/litestar-org/litestar/pull/3089
Fixes an issue in our docs generation.
Currently, the importing of LitestarExtensionGroup occurs before running rich_click_patch. This causes an issue due to rich_click_patch monkeypatching click.Group, click.Command etc. For example, consider the following code:
from click import Command, Group
from click.core import Command as CCommand
from click.core import Group as CGroup
from litestar.cli import litestar_group
print(isinstance(litestar_group, (Group, Command))) # False
print(isinstance(litestar_group, (CGroup, CCommand))) # True
# These fail.
assert Group is CGroup
assert Command is CCommand
The reason for this behavior is that LitestarExtensionGroup is not a subclass of RichGroup, but a subclass of click.Group if it gets imported before rich_click gets a chance to do its patching. Then by the time we do the isinstance check, click.Group is patched to become rich_click.RichGroup and so the isinstance(litestar_group, click.Group fails.
This causes issues in the documentation generation using sphinx-click which does a isinstance which is why this CI is failing in #3087.
To fix this, we simply ensure that we run the rich_click patching before we any imports from click.
@rare merlin re: https://github.com/litestar-org/litestar/pull/3091/files why the outer while loop for 100? how is that different from a for loop for 10000?
You mean the existing for loop? That for loop doesn't result in the port being changed. That is to wait for the application subprocess to start and for uvicorn to do whatever it needs to do as part of startup.
let me type it out
it will be dumb, but here I go
proc = multiprocessing.Process(target=run)
proc.start()
try:
for _ in range(10000):
try:
httpx.get(f"http://127.0.0.1:{port}", timeout=0.1)
break
except httpx.TransportError:
time.sleep(0.1)
else:
raise StartupError(f"App {path} failed to come online")
yield port
finally:
proc.kill()
AVAILABLE_PORTS.append(port)
port = _get_available_port()
time.sleep(0.2)
no dont reply
I realized how dumb I am
That for loop doesn't result in the port being changed
thanks, yet one more use case where python needs labeled breaks
but we dont :/
Yeah, that'd be really nice.
Actually, I just realized I did something stupid. I don't actually catch the StartupError which means even though the finally block gets run, we won't actually retry....
Okay fixed it.
https://github.com/litestar-org/litestar/pull/3091 (ready for review now :))
There are a lot of cases where the examples fail to come online resulting in the building of the docs to fail as seen here. This is due to the port that is being used to run the application ends up being used by another example during sphinx's parallel build. While we get the available port before creating the app in run_app, by the time we actually create the subprocess and get uvicorn to run the application, the port might already be in use by another example.
To work around this, we simply keep on retrying with a different port until the application comes online or we exceed an upper limit on the number of retries.
not a review action at all, was wondering why we don't do this https://stackoverflow.com/q/2838244/12502959 seems like the OS would do the heavy lifting for us
either way IIUC the link and the current litestar implementation are not thread / process safe
I think we'd still have this retry logic with different ports (since it's not process safe like you said), but this is probably a better implementation of _get_available_port than the one we have now.
I guess it only saves the append and pop logic then
pop(0) is bad any 1337coder will ask you to use deque
Yeah, but why bother with us doing it when we can get the OS to do it ๐
@wicked abyss do you have time to make that PR? If not, it's fine. I can do it in the evening when I'll get some free time.
I could try how do you actually test this?
do i just run a litestar app and try to run this ?
I just ran make docs repeatedly ๐
I don't think we actually need to test it since it's not part of our main codebase or anything.
I meant manually testing if the loop works, not an actual test
.
Oh...yeah just building the docs should work
mine gets stuck at reading sources... [ 93%] usage/openapi .. usage/stores
is it because I did something wrong with the port stuff or is my setup borked?
edit: idts, I stashed my changes, it still gets stuck at the latest main
Are you still facing this or were you able to figure out what went wrong?
i tried in 3.11 and 3.12, it was always stuck here, the world github actions is my playground so I yolo'ed it
I think something is really wrong with my setup, if run pre-commit, it affects 29 files, some being rst files (none of which are files I edited)
@rare merlin https://github.com/litestar-org/litestar/pull/3092/files#r1484995862 are you suggesting to remove finally and make it like so?
except StartupError:
time.sleep(0.2)
count += 1
proc.kill()
port = _get_available_port()
I am in dumb mode today, proc.kill would be the only expression in finally right?
except StartupError:
time.sleep(0.2)
count += 1
port = _get_available_port()
finally:
proc.kill()
Yupp this is what I meant.
Hm...that's weird
Are you running pre commit on all files?
yes pre-commit run --all
This PR ensures that make lint runs correctly against the base branch. The latest version of blacken-docs applies a few additional changes that need to be updated.
at some point we had some custom middleware tests that showed you could use Starlette middlewares with Litestar. However, it looks like the type signature for Starlette middleware changed towards the end of last year
is anyone seeing this test failure?
FAILED tests/unit/test_middleware/test_middleware_handling.py::test_custom_middleware_processing[middleware1] - ValueError: too many values to unpack (expected 2)
FAILED tests/unit/test_middleware/test_middleware_handling.py::test_custom_middleware_processing[middleware2] - ValueError: too many values to unpack (expected 2)
I'm also seeing this failure locally. It's an issue because the content type is returned as text/xml instead of application/xml
/home/oracle/Code/Starlite/litestar/tests/unit/test_template/test_template.py::test_media_type_inferred[.xml-application/xml] failed: extension = '.xml', expected_type = <MediaType.XML: 'application/xml'>
tmp_path = PosixPath('/tmp/pytest-of-oracle/pytest-161/test_media_type_inferred__xml_0')
@pytest.mark.parametrize(
"extension,expected_type",
[
(".json", MediaType.JSON),
(".html", MediaType.HTML),
(".html.other", MediaType.HTML),
(".css", MediaType.CSS),
(".xml", MediaType.XML),
(".xml.other", MediaType.XML),
(".txt", MediaType.TEXT),
(".unknown", MediaType.TEXT),
("", MediaType.TEXT),
],
)
@pytest.mark.skipif(sys.platform == "win32", reason="mimetypes.guess_types is unreliable on windows")
def test_media_type_inferred(extension: str, expected_type: MediaType, tmp_path: Path) -> None:
tpl_name = f"hello{extension}"
(tmp_path / tpl_name).write_text("hello")
@get("/")
def index() -> Template:
return Template(template_name=tpl_name)
with create_test_client(
[index], template_config=TemplateConfig(directory=tmp_path, engine=JinjaTemplateEngine)
) as client:
res = client.get("/")
assert res.status_code == 200
> assert res.headers["content-type"].startswith(expected_type.value)
E AssertionError: assert False
E + where False = <built-in method startswith of str object at 0x7f2bb5a18da0>('application/xml')
E + where <built-in method startswith of str object at 0x7f2bb5a18da0> = 'text/xml; charset=utf-8'.startswith
E + and 'application/xml' = <MediaType.XML: 'application/xml'>.value
tests/unit/test_template/test_template.py:126: AssertionError
Is my local install broken or are others getting these errors too?
I'm guessing this to_asgi_response in Template may be guessing the wrong type?
for suffix in suffixes:
if _type := guess_type(f"name{suffix}")[0]:
media_type = _type
break
else:
media_type = MediaType.TEXT
yeah, media_type is set to text/xml instead of application/xml
in the standard python mimetypes module, .xml is mapped to text/xml
I'm not sure what a fix for this would look like? Any ideas? Adding XML_TEXT to our MediaTypes enum? Change the existing XML to text/xml?
For reference, here's the MediaType enum:
class MediaType(str, Enum):
"""An Enum for ``Content-Type`` header values."""
JSON = "application/json"
MESSAGEPACK = "application/x-msgpack"
HTML = "text/html"
TEXT = "text/plain"
CSS = "text/css"
XML = "application/xml"
For now, i've updated the test case so it's looking for text/xml instead.
Well, let me walk all of this back. This appears to be a difference between python versions
Hiya, opened a small PR in https://github.com/litestar-org/litestar/pull/3098. My first contribution here, so navigating in a bit of an uncharted territory ๐
Fixes #3069
Explicitly declaring responses={...: ResponseSpec(None)} used to generate OpenAPI content, when it should be omitted.
Another one: https://github.com/litestar-org/litestar/pull/3100
Fixes #3068
Allows to define custom examples for the responses via ResponseSpec.
The examples set this way are always generated locally, for each response:
{
"paths": {
"/": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {...},
"examples": ...
Examples that go within the schema definition cannot be set by this.
Fixes the currently failing platform compat tests on main
We should run those on develop as well so this doesn't happen ๐
I'm sorry I mabe didnt folow well the tooling changes, but I checkout either from main or develop and just add a docs stuff, run pre-commit and get like 50ish files changed, so I might be doing something silly ?
Which hook is doing the changing?
โฏ git checkout main ๎ผ 3.11.7 ๎ผ litestar at ๏ 14:15:51
Your branch is up to date with 'origin/main'.
โฏ git branch --delete 3083
Deleted branch 3083 (was 1e42fa273).branch --delete 3083 ๎ผ 3.11.7 ๎ผ litestar at ๏ 14:15:53
โฏ git fetch upstream
โฏ git merge upstream/main
Already up to date.n ๏ ๏ฆ main โฏ git merge upstream/main ๎ผ 3.11.7 ๎ผ litestar at ๏ 14:16:07
โฏ git checkout -b 3083
Switched to a new branch '3083'
โฏ pre-commit run --all-files
i think so
I'll try recreate my venv anyways should code on 3.8
docs wont run on 3.8 :p
at least I had to yolo and run docs on 3.11, test on 3.8
think this did it, sorry I'm not using pre-commit so little lost ๐
I blame the data-scientists I'm working with, they're bleeding on me
pre-commit clean?
I just reinstalled pre-commit and now I'm getting a change from prettier as well. It's just one file though
Why do we even have that? Can't we just remove it? ๐
Remove prettier from pre-commit.
It doesn't add a lot of value and has been quite flaky recently, breaking CI and pre-commit in unexpected ways for contributors.
@woven tundra just a little question, before I try this PR that would close the RedisStore automatically, is there a place in the current code I can look at to get a sense what bits I should look at or that's unchartered territory ? I just dont know well enough all the code and often looking at already existing things is for me a way to not fuck up everything or reinvent the wheel in a bad manner ๐
You could take a look at the ChannelsPlugin: https://github.com/litestar-org/litestar/blob/main/litestar/channels/plugin.py#L33
litestar/channels/plugin.py line 33
class ChannelsPlugin(InitPluginProtocol, AbstractAsyncContextManager):
It implements the async contextmanager protocol and then adds itself to the app's lifespan handlers
Since stores aren't really plugins though you won't have that immediately available though
I can see two ways of handling this:
- Make the stores inherit from
InitPluginProtocoland have special casing in the app init that adds them to the installed plugins - Add dedicated
on_startup/on_shutdownmethods to the plugins (or a contextmanager) which then gets special casing in the app's init where the stores are added to the app's lifespan managers
ok makes sense reading that, hard part will be to figure it out for real ๐
Lmk if something seems to cumbersome. Maybe we'll need to come up with a deeper fix somewhere else then
well I'll try and see if that is above my league I'll let you know ! I know I'm pretty bad usually on abstractions so I take it as a challenge 
Gracefully handle malformed request bodies during parsing when using struclog. Instead of erroring out and returning a 500, simply use the raw body.
Fixes #3063.
sending a draft PR that doesnt work, I think it should work but I dont get why so I'd need a nudge
I left 2 comments that should help fix the issues! ๐
Fix an issue where msgspec constraints set in msgspec.Meta would not be honoured by the DTO.
In the given example, the min_length=3 constraint would be ignored by the model generated by MsgspecDTO.
from typing import Annotated
import msgspec
from litestar import post, Litestar
from litestar.dto import MsgspecDTO
class Request(msgspec.Struct):
foo: Annotated[str, msgspec.Meta(min_length=3)]
@post("/example/", dto=MsgspecDTO[Request])
async def example(data: Request) -> Request:
return data
Constraints like these are now transferred.
Two things to note are:
- For DTOs with
DTOConfig(partial=True)we cannot transfer the length constraints as they are only supported on fields that as subtypes ofstr,bytesor a collection type, butpartial=Truesets all fields asT | UNSET - For the PiccoloDTO, fields which are not required will also drop the length constraints. A warning about this will be raised here.
Closes #3026
just to understand the big-picture of the test suite, especially the redis side of things, it uses docker compose if I get it corretly ? I'm not very familiar with github, but it doesn't seem to use what would be the gilab equivalent ie services (https://docs.gitlab.com/ee/ci/services/redis.html). Just to understand how to bring it alive in a test
ok this is it, will come up with "fixing" the tests, imho there is some inconsitency in the redis_client fixture
yes, this is how it works, I kinda did some changes a while back to make sure stores use a real redis instance to test instead of a mock, so if you are seeing inconsistencies yours truly messed it up ๐
Well, I may have been too fast in saying that, I keep posted
this is what I meant by inconsistencies: https://github.com/litestar-org/litestar/pull/3111/commits/570ac9bb760711459badc690d9d7805d95c704a3
in this fixture a sync redis instance is created, it flushall, but it is never closed
so I put the flushall in the finally and just uses the async instance
makes more sense to me, this keeps the test suite intact I think
ohh you mean in the fixture itself, I thought you just had issues with the stores test, when I modified the tests the fixture was already there
But it does the flushall() call after the close()
Also, reason it has a flushall() in the beginning is because that means we don't have to rely on the previous test having completed its cleanup properly
I can try a PR with that single change to test if you want, it ends up being the same imho, the 1st time you get the redis_client fixture you ave a clean redis instance anyways, so I think forcing it in the finally ends up doing the same, while not having a dangling sync Redis client
I'm thinking more what if one test crashes and doesn't do the cleanup? That could then affect other tests. Not a super big issue, but can make it a bit more cumbersome to debug
I'm not clear enough but shouldn't the finally make it a garantee ?
I mean flushall in the finally
Ah
I see the confusion now
The finally clause does not guard the yield
It only guards the await client.aclose()
So the current logic calls client.flushall() after the client has been close, regardless of whether that operation succeeded
The reason why the await client.aclose() is within a try/except clause to begin with though was that there had been some funky stuff going on with the async Redis client regarding that close() call, where it would sometimes manage to schedule an operation that would run after the event loop had already been closed, due to it not cleaning up all resources properly (iirc)
I haven't checked this issue in a while so it might actually have been fixed in the meantime and we can get rid of the whole exception handling shennanigans there and just do
yield client
await client.flushall()
await client.aclose()
yep, agree, will try in a seperate PR, also I pointed out there is one test where with_client and passing the fixture are used in the same test and I think that is an issue because the with_client one doesnt close
with_client not patched I should add
Actually this should be even better
async with AsyncRedis(host=docker_ip, port=6397) as client:
yield client
await client.flushall()
I'll have to take a look at that
Ah, gotcha
Yeah, I agree. That should probably also be mocked. Or it could just use the store as a context manager and ensure that it closes properly that way
I think I'd even prefer that because it uses less mocking
Fix a failing test for structlog on windows with tty.
This PR checks for the impl property before default to type.python_type.
This is the documented way to use the sqlalchemy.types.TypeDecorator
Too slow. Thanks @woven tundra
I was faster ๐
This PR addresses an issue with type hints when uuid-utils is not installed.
https://github.com/litestar-org/litestar/pull/3125
Added docs and tests too.
nice, I think you missed adding them to the test client functions ๐
But clients have request_class param already.
good night!
Do you think that exposing websocket_class to other layers could be beneficial? I could take care of this.
Yeah, I think it could.
Is it currently exposed at any layer?
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 98.26%. Comparing base (
d109098) to head (e6188ff).
Report is 2 commits behind head on main.
@@ Coverage Diff @@
## main #3131 +/- ##
=======================================
Coverage 98.26% 98.26%
=======================================
Files 320 320
Lines 14401 14404 +3
Branches 2316 2317 +1
=======================================
+ Hits 14151 14154 +3
Misses 109 109
Partials 141 141
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
that's kinda cool
?
The preview showing the codecov I think because it was the last comment on that PR at the time
But the preview looks cool
Oh no that was because the link was for that specific comment. I edited the link to make it the same as the PR after that.
Could you check this one guys? https://github.com/litestar-org/litestar/pull/3125
Reviewed. Thanks for this!
good monday all, I think this https://github.com/litestar-org/litestar/pull/3111 should be ready now
Description
WIP, it doesn't pass the test I added from the mvce in the issue (this one could certainly be simplified) so my impleentation has obviously an issue.
I made the RedisStore an async context manager, I can see the _on_shutdon method being hit, but the _redis client is still not closed or it doesnt exists.
from your comment here:
#1152626430295933060 message
Closes
Fixes #3083
hey all! Have a relatively simple PR that allows examples for the request body.
https://github.com/litestar-org/litestar/pull/3128
Wondering if that's going in the right direction/applicable. Building a tool that uses litestar and its been awesome! Allowing examples for users will let me reach feature parity w/FastAPI and use litestar going forward ๐ Thanks!
Fix a bug that caused a NameError when trying to resolve forward references in Pydantic private fields.
Although we respected private fields in Pydantic and didn't include them in the schema, we still tried to extract their type annotation. This was fixed by not relying on typing.get_type_hints to get the type information, but instead using Pydantic's own APIs, allowing us to only extract information about the types of fields we're interested in.
Fixes #3150.
Exposing websocket_class to other layers https://github.com/litestar-org/litestar/pull/3152
There could be possible conflicts between this PR and https://github.com/litestar-org/litestar/pull/3125/commits
Description
Expose websocket_class to other layers
Yeah, but they seem to be minor ๐
Description
- Fix the parsing of the constraints from union types for Pydantic v2 modelsโ- Before there used to be special handling of optional types, but that's not needed since optional types are also unions and so optional types should also be handled the same way as union types where we just ignore
NoneType. This makes the change the same as that ofFieldMeta.from_type(as changed in[ #491](https://github.com/litestar-org/polyfactory/issues/491)). - Fix the way the annotated types are handled when calling
FieldMeta.from-typeby using the actual type that is annotated rather thanAnnotated[type, ...]โ- Due to the change inFieldMeta.type_argsin[ #491](https://github.com/litestar-org/polyfactory/issues/491),Annotated[List[str], MinLen(10)]now returnsList[str]whereas before it would have returnedstras the child. This results in the children for theFieldMetacorresponding to the annotationAnnotated[List[str], MinLen(10)]to beList[str]instead ofstr. Unwrapping the annotation to get the actual underlying type fixes this problem since nowFieldMeta.type_argswill returnstrin this case instead ofList[str].
Close Issue(s)
Description
When importing PyObject from pydantic, if it's v2 then a warning is raised due to it being deprecated in favor of ImportString. The expected ImportError doesn't occur until after the import of PyObject takes place hence any user that's using pydantic v2 would see the warning. This ensures that PyObject is imported last so that the warning is not raised.
Some small fix to keep consistency with type_encoders which are initialized directly in the layers.
https://github.com/litestar-org/litestar/pull/3153/
Wasn't sure where to put test module. response package is wrong IMO but the type_encoders tests are there.
Also not so sure about the fix: prefix.
Tell me what to do.
Description
- added
type_decodersto__init__method for handler, routers and decorators to keep consistency withtype_encodersparameter - added test for resolving type decoders
You're on a roll ๐
Also not so sure about the fix: prefix.
It should be a feature and go intodevelop!
Sir yes sir!
Will be fixed.
https://github.com/litestar-org/litestar/pull/3154 Fixed small "smell" in the docs.
https://github.com/litestar-org/litestar/pull/3162
Fixed one place I've missed yesterday. Found a bug by mistake but fixed it on purpose!
Description
- pass
type_decodersto parent's__init__inWebsocketListenerRouteHandlerinit, otherwisetype_decoderswill beNone - add tests and baby refactor request and response class resolution tests
- replace params order in docs,
__init__(decodersbeforeencoders)
Description
- Added
enable_error_code = "ignore-without-code"to mypy config
just for my understanding, how is this not an error?
https://github.com/litestar-org/litestar/pull/3163/files#diff-1ed399a8b90172d603e33ffaddd8a115c5adf2283f260217db4e954f6b0c3af6R6
@formal drum
this is cool
I will investigate it later. Based on mypy errors I wrote a script to refactor ignored lines.
I think the mypy config does not include docs during run. I guess I replaced this single example by a hand before using the script.
If you are OK with this I will include docs in mypy config in separate PR. What do you think?
From the other hand putting type checkers comments will make the examples code less readable.
https://github.com/litestar-org/litestar/pull/3164 Fixed time should handle this baby -> https://github.com/litestar-org/litestar/issues/1258
mm I tried to rebase and target on develop and now have like 120 file changes, not sure what fucked up: https://github.com/litestar-org/litestar/pull/3145
Description
- This PR allows for the random seed used for generating the examples in the OpenAPI schema (when
create_examplesis set toTrue) to be configured by the user.
Closes
This is related to #3059 however whether this PR is enough to close that issue or not is not confirmed.
Due to my lack of git-foo, this is what I would do ๐
๐ my git foo on this is crap
Btw, @severe onyx on a completely unrelated note, is your profile picture the MC from Tower of God?
definitely YEAH
BAAM
Ohh it's been a long time since I've read it (the manga).
it's been a while too, I loved it so much
dont delete this branch, I want to learn sth from this
I want to try sth (not saying I will fix :p)
it's weird because when I diff locally I have only the correct set of changes, I must have fucked up soething
https://github.com/litestar-org/litestar/compare/develop..._flash?expand=1
is this correct or wrong?
my got-foo solved it ๐
I do not intend to raise a PR
I checkout upstream/develop into develop locally and merged it into flash branch
dont ask me why this worked ๐
ahh ok, I did the same except I did git rebase develop
I think you'll need to foo a bit again ๐
Needs a rebase ๐
@severe onyx i added another pr to that again, feel free to ignore though. Just wanted to get API docs in
Ok I'll check on that later, it helps to get this structure though,
rooo you're too fast I thought the todo spots were for me to add and now they're all filled ๐
they kinda were but then i squirreled and did them by accident :\
honestly it's way better than what I would have done ๐
love the "Oh no! I've been flashed!"
I've made initial draft for https://github.com/litestar-org/litestar/issues/3147 here https://github.com/litestar-org/litestar/pull/3171/files
I have few questions:
- I pass additional parameters to V1
dicttoo . It was not mentioned in the issue but it seems to be appropriate to support both pydantic versions, right? - I don't use
modeit does not make sense for me. Do we agree? - What about
round_tripandwarnings_parameters? Only V2 supports them and frankly speaking and don't see a point support them too. What do you think about it? - There are
_model_dumpand_model_dump_jsonfunctions inpydantic.__init__They're used in examples and tests. Should I also allow to pass additional params there?
Description
- This PR ensuress that the insertion into the
Components.schemasdictionary of the OpenAPI spec will be in alphabetical order (based on the normalized name of theSchema).
Closes
Closes #3059.
is the siganture_types needed there?
Yupp due to the use of __from__ future import annotations. get_type_hints can only resolve stuff that's in the global namespace of the module the class was defined in.
TIL, I thought the dataclasses are available in runtime and it should be able to detect
nit :p sync_to_thread ignored for others
Oops that's what I get for not copy pasting ๐
Description
- from our discussion here https://discord.com/channels/919193495116337154/1213242966592856164 it appears that javascript clients dont "see" an event that has no data, while we explicitly test for this and that httpx-sse receives the event fine in that case.
- the spec https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream is not that clear to me as to whether or not an event without data is ok.
- Considering the EventSource "client" is not ok with it, and that it's so easy DX-wise to make the mistake not explicitely sending it we fix it by defaulting to the empty-string
The added app is just to manually test the fix works, I dont know how we could incorporate it in our test suite given it involves running a server and checkin if the html page yields the event fine, maybe in e2e testing ?
and looking at it, it seems like it is often on the channels psycopg backend
now I'm no expert, but briefly looking at it, it seems to me (at least vs the asyncpg backend) that the underlying connection is not closed in the shutdown, is that correct ?
imho this would make sense to do that, but I dont know the channels stuff:
diff --git a/litestar/channels/backends/psycopg.py b/litestar/channels/backends/psycopg.py
index 14b53bcd1..40db0f610 100644
--- a/litestar/channels/backends/psycopg.py
+++ b/litestar/channels/backends/psycopg.py
@@ -25,6 +25,7 @@ class PsycoPgChannelsBackend(ChannelsBackend):
await self._exit_stack.enter_async_context(self._listener_conn)
async def on_shutdown(self) -> None:
+ await self._listener_conn.close()
await self._exit_stack.aclose()
async def publish(self, data: bytes, channels: Iterable[str]) -> None:
~
~
well i did a large PR for this
https://github.com/litestar-org/litestar/pull/3177
Description
- the underlying connection is not closed which might (or not) b a reason for those flaky runs
Closes
nothing, trying to help on flaky tests
on a side note, a bot runnning through all actions to detect failed tests and make some sort of summary, especially those marked as flaky (which is often to me a patch to "avoid" fixing lifetime ressources issues) would be very helpful
Hello ๐
I worked on https://github.com/litestar-org/litestar/compare/main...jderrien:litestar:logging-queue-listener-handler?expand=1 to fix the queue_listener handler for Python 3.12, but I have also tried to fix some tests, then I had to refactor logging config... and I finally added a logging_module property to LoggingConfig (which might break some setups).
I guess it became a bit biggy and maybe I should break up this in multiple commits and PR... what do you think?
(Posted in #general this morning, I'm already working on a smaller one... anyway any feedback welcome)
Hi guys,
I''ve finally found some time to finish PR (my team transfered me from a bench to the project again ๐ฆ )
https://github.com/litestar-org/litestar/pull/3171
Will be glad if anyone more familiar with pydantic can check this out.
Description
- Add support for additional V1
model_dumpand V2dictparameters inPydanticPlugin
Closes #3147
Added tests for examples in docs.
I've missed them last week.
BTW - there are many not covered examples. I will try to cover them in the free time.
https://github.com/litestar-org/litestar/pull/3184
Description
- Add tests for
request_classandwebsocket_classdoc examples
Closes
is https://github.com/litestar-org/litestar/pull/3145/checks?check_run_id=22487972984 somehting I can sleep on or I need to fix it ?
i say slap a # pragma: no cover on it and merge that puppy, but since its bound for 2.8 (~4 weeks from now) there is no rush either way
done, it has been broken-winded
This PR adds additional configuration to the web controller to better handle client side routing.
Speed up the database testing service.
This PR:
- Refactor test framework code into separate files
- Add
SKIP_DOCKER_COMPOSEoption to tests - Updated
Makefileand Github Actions to start the database services before tests
Latest test run in ~45 seconds
auto merge just bit me/us ๐ฆ
Will need to revert, that PR needed rebasing it looks like. It brought over a bunch of commits
Description
- This specifies the
spec-urlandapiDescriptionUrlof Rapidoc, and Stoplight Elements as absolute paths relative to the root of the site. This ensures that both of the send the request for the JSON of the OpenAPI schema to the right endpoint.
Closes
Fixes #3047.
how does one test this?
Manually ๐
I think we will have to setup playwright or something as @woven tundra had mentioned before for the openapi portion. There tends to be a lot of issues related to the rendering (which we don't test) that we face.
not sure if this is nit or "conventions" but I don't think we use Final[type] over just Final?
Wouldn't mypy complain if we don't specify the generic type?
I trust this random person https://github.com/litestar-org/litestar/commit/d5adc177d61cd950ab7d67485cfd84a5cefd0a29 :p
I think it must be able to infer
Ooh considering that the random person knows a thing or two about mypy and type checking, we'll go with that ๐
seems it does, from the PR
Finalwill not only infer theLiteraltype for you (so, no code duplication), but also provide new safety features.
Yupp I just checked. pyright resolves that into a Literal['whever the value is'].
@wicked abyss did you get a chance to manually test that it works? I did test it, but it wouldn't hurt for one more person to test ๐
I will try it now
schema/rapidoc vs schema/rapidoc/ right? if so, that works
Can someone give me some more feedback on why this one was rolled back? https://github.com/litestar-org/litestar/pull/3195
Reverts litestar-org/litestar#3193
This may need more thought about why the patch was necessary in the first place.
I'm curious why we'd roll this back
I added the wrong stack trace from the user to the issue
here's the correct one
And it does look like a msgspec error. I also have reproduced the error in the test cases
@dusky lance @woven tundra
Further, all of these tests raise an exception without this in place: https://github.com/litestar-org/litestar/pull/3193/files
im not sure on this one but https://github.com/litestar-org/litestar/pull/3180 needs reverted as well I think
why?
it looks like it merged in a bunch of unrelated commits and so needs a rebase
ok, I don't know if i have time to do that until this evening
Why move it to _utils?
it's only called once during launch. We also may want to expose this as a CLI option soon
thats just what all the others seemed to do and then use that in the other files
I rolled it back because it looked like it needed more thought based on the TB that was in the issue. Granted that was the incorrect one, but I didn't have that info at the time. Also, as @woven tundra mentioned, msgspec should handle Enums natively, and given that I'd like to see a reproducer so I can fully understand the issue. Its my bad for not questioning these things upfront - but even after reading the thread in #1064114019373432912 I don't know how to reproduce that original issue.
I linked the wrong stack trace.
Iโve updated it on the GitHub PR. Sorry for the confusion. the tests I added do reproduce it.
I donโt know how it happened in-application though.
yeh that's the thing I'd hope to understand - as its coming out of serialization of the openapi schema, can we create a repro that fails in the same way - I might be able to find some time today to try
I got a problem in https://github.com/litestar-org/litestar/pull/3204 - the test I added fails on Python 3.9 and I don't see the issue. I tried reproducing locally on the same Python version, but it passes on my machine. Fails to:
with create_test_client([handler]) as client:
response = client.get("/schema/openapi.json")
> assert response.status_code == 200, response.text
E AssertionError:
E assert 404 == 200
E + where 404 = <Response [404 Not Found]>.status_code
https://github.com/litestar-org/litestar/actions/runs/8287151261/job/22678795367?pr=3204
First it failed on Python 3.11, then after splitting one test into two it now passes on 3.11 but fails on 3.9. Uh... anyone mind taking a look?
Description
This adds sort of a backdoor for modifying the generated OpenAPI spec.
The value is given as dict[str, Any] where the key must match with the
keyword parameter name in Schema.
The values are added at main level, without recursive merging (because we're
adjusting Schema object and not a dictionary). Recursive merge would be much
more work.
Chose not to implement the same for ResponseSpec because response models are
generated as schema components, while ResponseSpec can be locally different.
Handling the logic of creating new components when schema_extra is passed in
ResponseSpec would be extra effort, and isn't probably as important as being
able to adjust the inbound parameters, which are actually validated (and for
which the documentation is even more important, than for the response).
Closes
#3022
https://github.com/litestar-org/litestar/pull/3190 click's envvar is nice
Description
- Added precedence of CLI parameters over envs
- โ Add docs
- โ Add tests for envs
- โ Refactor
Closes #3188
https://github.com/litestar-org/litestar/pull/3205 before this one next was iterating over layers with every request. With this enhancement iteration will happens only once ๐ only on the first time.
Description
- Use memoized
request_classvalue
Closes
if you need CI, you can run it on your own fork
this is in reply to your comment
how I can run the test suite multiple times on Github Actions to check if everything is fine..
Thank you!
(I'm not familiar with Github Actions, never used it before ;))
you would have to turn it on in your forked repo, and you must be able to run the CI
https://github.com/jderrien/litestar/settings/actions I think this is it
Thanks ๐ I'll take a look later today (hopefully), I have to go
No description provided.
CI against develop currently failing because of this ๐
Enable the codegen backend for DTOs introduced in #2388 by default. We have initially hidden this behind a feature flag to see how it works out in production. It's been smooth sailing for about 6 months now so I think we can enable it by default. This gives us enough time to decide if we want to remove the regular backend entirely in 3.0.
I think this class isn't being documented in the advanced-alchemy docs b/c it isn't referenced in __all__ in the advanced_alchemy.config.common module. Is that intentional? If that was added there I think that would make the class available via intersphinx and this ignore not necessary. (a lot of "i think"'s here because often what I think would fix these docs builds doesn't)..
Should classes that aren't directly used by the user be added to the mapping?
@dusky lance re: this https://github.com/jolt-org/advanced-alchemy/pull/138
After @wicked abyss and I handle the comments, are you good with us merging?
Yes, ofc.
Description
- The path parameters were only skipped for field definitions which resulted in an error being raised if path parameters were included as part of layered parameters. This fixes that by skipping path parameters in the validation step when creating
KwargsModel.
Closes
Fixes #3197.
Update: Got around this. The same doesn't pop up in CI ๐คทโโ๏ธ
I'm getting Mypy errors on latest main:
=> Running mypy
tests/e2e/test_pydantic.py:11: error: Function is missing a type annotation [no-untyped-def]
tests/unit/test_contrib/test_pydantic/test_schema_plugin.py:73: error: Function is missing a type annotation [no-untyped-def]
Found 2 errors in 2 files (checked 691 source files)
Is it just me?
Description
- Add
LITESTAR_prefix beforeWEB_CONCURRENCYenv option
wouldnt this be considered breaking?
Nope.
nvm
I've opened a few PRs:
https://github.com/litestar-org/litestar/pull/3204 (already 1 approval)
https://github.com/litestar-org/litestar/pull/3224
https://github.com/litestar-org/litestar/pull/3225
Have a look when you have time, thanks ๐
Can we get a fresh approval over here? https://github.com/jolt-org/advanced-alchemy/pull/138
@signal linden @woven tundra
Do we have a draft PR for 3.0 in thew works?
Description
This PR documents the behavior of guards placed at the controller and app level being executed for OPTIONS requests.
I don't know if linking to the GitHub issue is the best way to go about this. I'm open to any ideas on how to document this behavior better.
Closes
This is related to #2314, but doesn't fix the underlying issue. Instead it documents the issue as well as provides a link to the issue where the users can find a workaround for it.
EDIT: Reword to make sure GitHub doesn't consider the linked issue as being fixed by this PR.
I updated https://github.com/litestar-org/litestar/pull/3185 after the comment from @woven tundra
TL;DR
- Default logging doesn't work on the
mainbranch for Python >= 3.12 and there is a breaking change onlitestar.logging.standard.QueueListenerHandler(the constructor signature is not the same anymore) - With the last commit, this PR will fix the logging issue, revert the breaking change on
QueueListenerHandler, and document its incompatibility with Python >= 3.12 due to thelogging.config.dictConfig()update
Doc preview: https://litestar-org.github.io/litestar-docs-preview/3185/reference/logging/standard.html
I still have a typing issue https://github.com/litestar-org/litestar/pull/3185#discussion_r1529323696 :/
mypy was returning:
litestar/logging/standard.py:45: error: Argument 1 to "LoggingQueueListener" has incompatible type "_QueueLike[Any]"; expected "Queue[LogRecord]" [arg-type]
I don't know if I could do something better here. It seems I cannot import _QueueLike.
On https://github.com/litestar-org/litestar/pull/3185
I fixed a small doc format issue and rebased the branch. Waiting for @coffee input, I guess. Thanks! ๐
Description
- Fix the
queue_listenerhandler for Python 3.12
Python 3.12 introduced a new way to configure QueueHandler and QueueListener via logging.config.dictConfig(). This described here.
The listener still needs to be started & stopped, as previously. To do so, I've introduced LoggingQueueListener.
And as stated in the doc:
Any custom queue handler and listener classes will need to be defined with the same initialization signatures as QueueHandler and QueueListener.
Closes
Closes #2954
Description
- release 2.7.1
Closes
Simple doc fix: https://github.com/litestar-org/litestar/pull/3245
Description
- Add missing layered parameters
Closes
https://github.com/litestar-org/litestar/pull/3256 (pointed ping to @rare merlin but ofc open for all to criticize review) @severe onyx is already fast and left a comment even before I linked here ๐
Description
This PR cherry picks @guacs' commit from #3223 that fixes the way we construct the exception message when there is a kwarg ambiguity detected for path parameters.
Closes
Description
- Adds
developbranch docs build - Adds
v3.0branch docs build
Closes
Description
This PR moves running slotscheck from within pre-commit to its own job in ci (same as we've done with other tools that require the configured environment to run).
This partially fixes an issue identified in #3251 where the litestar package was inadvertently excluded from this check due to an incorrect regex pattern.
Applies fixes for issues identified by the tool.
Co-authored-by: ariebovenberg [email protected]
@snow sapphire I'd love to know if you have any thoughts on this ๐
Ha! Joke's on you, I was already reviewing it! ๐
foiled again!
@snow sapphire @dusky lance I've addressed some of the low hanging fruits wrt the import time
https://github.com/litestar-org/polyfactory/pull/517 edit: ignore for now. Some issues on testing still to resolve
As discussed in https://github.com/litestar-org/litestar/pull/3280#issuecomment-2026878325, we want to warn about, and eventually disallow specifying parameter defaults in two places.
To achieve this, 2 warnings are added:
- A deprecation warning if a default is specified when using
Annotated:param: Annotated[int, Parameter(..., default=1)]instead ofparam: Annotated[int, Parameter(...)] = 1 - An additional warning in the above case if two default values are specified which do not match in value:
param: Annotated[int, Parameter(..., default=1)] = 2
In a future version, the first one should result in an exception at startup, preventing both of these scenarios.
When using a non-JSON media type (e.g. text/plain), ValidationExceptions wouldn't get serialised properly because they would ignore custom type_encoders.
The example below would result in a SerializationException:
class Foo:
def __init__(self, value: str) -> None:
self.value = value
@get(media_type=MediaType.TEXT)
def handler() -> None:
raise ValidationException(extra={"foo": Foo("bar")})
app = Litestar([handler], type_encoders={Foo: lambda f: f.value})
Looks like it's already been merged, but why the change here? Wouldn't it be better to not raise an exception at all? https://github.com/litestar-org/polyfactory/pull/513/files#diff-276d60e74101901f8f9a39361d7316afeac822ecd4b997c46428ce4873411a5cR132-R135
Also, why would we favor the SA type over what the user has in the impl type?. NM - I see the linked issue.
I think that this may have some odd side effects
My bad on missing the additional request for review here! On raising the exception, for Python type I think it needs to be done this way as it's a property so can't just check for existance of the attribute. Or do you mean for detected impl?
OK, fair point. I missed this on a quick review from my phone. I guess my main question now is: In what cases is the python_type not populated but the impl.python_type is?
I can imagine a user defined type omitting this. For the UUID type, this is explicitly added but can imagine a case where TypeDecorator.python_type is omitted e.g. like the examples in the docs https://docs.sqlalchemy.org/en/20/core/custom_types.html#sqlalchemy.types.TypeDecorator. I may be missing some internal processing that would populate this
Sorry for being slow on this one. I think you are correct. TypeDecorator inherits this: https://github.com/sqlalchemy/sqlalchemy/blob/a124a593c86325389a92903d2b61f40c34f6d6e2/lib/sqlalchemy/sql/type_api.py#L607
lib/sqlalchemy/sql/type_api.py line 607
def python_type(self) -> Type[Any]:
Which raises NotImplemented by default
ExternalType also does not implement anything here: https://github.com/sqlalchemy/sqlalchemy/blob/a124a593c86325389a92903d2b61f40c34f6d6e2/lib/sqlalchemy/sql/type_api.py#L1108
lib/sqlalchemy/sql/type_api.py line 1108
class ExternalType(TypeEngineMixin):
So, in that case, nice work @peak monolith. Sorry for coming in after the fact on the review.
No problem. Good to clarify and confirm! I find some of the types (hierarchies) in SQLA a bit confusing
No doubt. I am constantly learning something new from that library.
Fix a bug that would prevent default values for dataclasses and msgspec.Struct`s to be included in the OpenAPI schema.
@dataclass
class SomeModel:
field_a: str = "default_a"
field_b: str = dataclasses.field(default="default_b")
and
class SomeModel(msgspec.Struct, kw_only=True):
field_a: str = "default_a"
field_b: str = msgspec.field(default="default_b")
now generate correct schemas in all cases.
Fix #3201.
Fix a bug that would cause a TypeError when non-Pydantic errors are raised during Pydantic's validation process while using DTOs.
This is the case for example when using field_validator:
class User(BaseModel):
user_id: int
@field_validator("user_id")
@classmethod
def validate_user_id(cls, user_id: int) -> None:
raise ValueError("user id must be greater than 0")
The exception on our side occurs because Pydantic v2 includes the raw error objects in their error report, which we in turn use to generate our error responses.
I've added a simple fix that stringifies the errors here. This does not address the root issue though, which is how we currently handle the different ways libraries throw errors at us. We should aim for a more permanent fix, but this is unfortunately not possible without introducing breaking changes in how Litestar reports errors and therefore must be shelved until v3.
Closes #2365.
Fix outdated usage of the channels.subscribe method; The channel.start_subscription method should be used instead.
Add the TRACE HTTP method to HttpMethod enum
Fix a bug that would cause no OpenAPI schema to be generated for paths with path parameters that only differ on the path parameter type.
Essentially, /{param:int} and /{param:str} (that is, two paths with the same path parameter name but a different path parmeter type) could not coexist in the same application. Defining them as /{param:int} and /{other_param:str} or /{param:int} and /{param:int} (i.e. different names or same type) would result in the correct behaviour.
Closes #2700.
This was caused by the way Litestar handles routing of these; A single route can have multiple route handlers, but requires that all path parameters, if existent, be of the same type. Litestar can also handle routing with parameters of different types, but creates separate routes for this. Since this representation is only internal (for OpenAPI, they are still the same path), one OpenAPI path generated for one such route would be overwritten by the next route for that path.
Fix a bug where path parameters not consumed by route handlers would not be included in the OpenAPI schema.
from litestar import Litestar, get
@get("/{param:str}")
async def handler() -> None:
pass
This could would not include the {param} in the schema, yet it is still required to be passed when calling the path.
Fix #3290.
Description
This PR simplifies the type that we apply to transfer models for pydantic field types in specific circumstances.
JsonValue: this field type is an instance ofTypeAliasTypeat runtime, and contains recursive type definitions. Pydantic allowlist,dict,str,bool,int,floatandNone, and the value types oflistanddictare allowed to be the same. We type this asAnyon the transfer models as this is basically the same thing for msgspec (ref).EmailStr. These are typed asEmailStrwhich is a class at runtime which is not astr, however they are a string andif TYPE_CHECKINGis used to get type checkers to play along. If we return astrfrom a msgspec decode hook for the type, msgspec fails input validation. So we must tell msgspec its a string. This also works well with encoding because it is one.- IP/Network/Interface types. These are represented by types such as
IPvAnyAddress, but they are actually parsed into instances of stdlib types such asIPv4Addressand others from theipaddressmodule. Given that an instance ofIPvAnyAddresscannot be meaningfully returned from a decoding hook, we have to tell msgspec that these are strings on the transfer models and let pydantic do the disambiguation. Encoding the stdlib ip types to str is natively handled by msgspec.
There are other types that can adequately be handled by defining type encoders/decoders for them, so I've left them as out of scope for these changes.
Also the Json type is tricky as it accepts a string and is parsed into builtin types by pydantic, however by default pydantic doesn't serialize that back into a string unless explicitly asked to do a round trip. For the DTO transfer models, this means we'd probably have to type it as str, but then we don't have a way to encode the decoded values back into a str b/c msgspec won't call an encoding hook for builtin types. So I've left this out of scope.
Closes
Closes #2334
Description
This PR removes all deprecated elements of OpenAPIConfig and the OpenAPIController, removes any obsolete tests and refactors tests that were parametrized to test both OpenAPIController and the router-based approach.
Supersedes #3271
Closes
This PR adds an exception handler around the create_all startup.
Without this, this setting is only useful the first time you are deploying an environment. Future startup will raise an exception if the tables already exist.
I've added a "What's New in V3" document to this PR and included the migration notes for OpenAPIController -> OpenAPI plugins here: https://github.com/litestar-org/litestar/pull/3297
This PR removes the implicit optional default for parameters for v3: https://github.com/litestar-org/litestar/pull/3300
It is based on the openapi one b/c it also modifies the what's new document which doesn't yet exist in v3 branch
https://github.com/litestar-org/litestar/pull/3171 I have removed changes connected to OpenAPI, after merge I will create a ticket for this one
Description
- Add support for additional V1
model_dumpand V2dictparameters inPydanticPlugin
Closes #3147
Hey all! I have this PR which was more or less done but had some typing issues to resolve. Would appreciate someone taking a look and advising how to proceed, thanks! ๐
https://github.com/litestar-org/litestar/pull/3222#issuecomment-2032288536
I'll let @woven tundra chime in on the breaking change. But worst case, you can target the v3.0 branch
Thanks! I feel out of my element now, and sadly haven't kept up ๐
is the v3.0 similar to develop?
Yeah. Same thing just for version 3.0
You should be able to rebase your branch onto develop and then change the branch in GH to v3.0 (hopefully) without conflicts
awesome, I will give it a shot! I'm not a rebaser, so just want to ask ๐
Is that correct? Despite the warning?
I'd recommend rebasing against the develop in your own fork
Given that it's up-to-date of course ๐
so update my develop, then do rebase 'schema-examples' onto 'develop' ? It still gives me that duplicate warning, do I rebase anyways?
Uh
Not sure, never had this warning ๐
You should be able to just do git rebase develop if you're on the schema-examples branch
What tool are you using here?
I'm using Pycharm, I can just run the commands tho and see what happens ๐
git rebase --pray
โฆ to NULL
This change allows for sending a dict with None as values; the model will then be updated to NULL for those fields. The existing handling in model_from_dict will drop dict keys if they're set to None.
Pull Request Checklist
- โ New code has 100% test coverage
- โป๏ธ (If applicable) The prose documentation has been updated to reflect the changes introduced by this PR
- โป๏ธ (If applicable) The reference documentation has been updated to reflect the changes introduced by this PR
- โ Pre-Commit Checks were ran and passed
- โป๏ธ Tests were ran and passed
Description
- Allows for sending a dict with
Noneas values tomodel_from_dict; the model will then be updated toNULLfor those fields. This changes the existing behavior ofmodel_from_dict, which will drop dict keys if they're set toNone, causing the record's field to be unchanged.
Does exclude_none as a name make sense here?
basically if you pass in data as a dictionary and the key is missing, then we do nothing with the value in the model. If this exclude_none is set to False, then all missing keys are set to NULL
unset_is_null, maybe? exclude_unset keeps a bit of parity with Pydantic, so it's familiar
https://github.com/jolt-org/advanced-alchemy/pull/156 is partially ready, mostly just some tinkering left
I'm resurrecting https://github.com/litestar-org/litestar/pull/3225#issuecomment-2036828214 a bit with some questions about the feasibility of re-doing the JSON schema generation vs just letting the libraries (ie. Pydantic, MsgSpec) do it. Also related to https://github.com/litestar-org/litestar/issues/3202#issuecomment-2035795800 / https://github.com/litestar-org/litestar/pull/3308.
@guacs @peterschutt @JacobCoffee Hey, sorry for taking so long here.
I'm looking into it again, and I don't see how converting the json_schema_extra: dict into Schema object could happen conveniently:
- Can't just use
setattr()because manySchemaobject fields are also custom types (e.g.Schema.any_ofand friends) - Can't easily merge nested structures, because I'd have to first convert them to right type
- Recursively merging (not sure how Pydantic does that, but I assume recursively) would require extra logic
Properly supporting it would add a lot of (unjustified) bloat. I don't think it makes sense. (All that to just get converted back to dict again.)
Do you have better suggestions? Maybe passing extra as separate argument, if it cannot live in Schema, or sub-classing Schema for this special case?
The scope of this topic is actually wider. Pydantic also supports:
I had an idea here, to only support the callable format and do something like:
class MyBody(pydantic_v2.BaseModel):
def _add_examples(self, schema):
schema.examples = [{"foo": "hello"}]
model_config = pydantic_v2.ConfigDict(json_schema_extra=_add_examples)
foo: str
...but Pydantic defines json_schema_extra as:
JsonSchemaExtraCallable: TypeAlias = Union[
Callable[[JsonDict], None],
Callable[[JsonDict, Type[Any]], None],
]
class ConfigDict(TypedDict):
json_schema_extra: JsonDict | JsonSchemaExtraCallable | None
So we would be a bit breaking that API as in this case typing would be for Callable[[Schema], None] (and not JsonDict)... maybe not too bad, but still.
Finally, that WithJsonSchema is something Litestar doesn't support at all now (AFAIK).
I'm still wondering about the rationale to re-write the whole OpenAPI spec parsing when you could just call BaseModel.model_json_schema and let Pydantic (and MsgSpec, et al) generate it. It would automatically support the bells and whistles seen here, plus any that they might add/alter in the future. And you'd save a lot of extra code, rather than trying to play the catch up game?
I find this a little confusing:
I think that would (should) be considered a hack and is definitely not an intentional public API for this ๐
It is in contrast to the reality of what we actually do. We pull anything out of the metadata for a type that we parse and add it to a ParameterDefinition instance for the type as long as it has the right attributes:
In general, Litestar doesn't try to enhance the support of the modelling library you chose beyond what it offers out of the box.
Yet we have a unit test checking that annotated-types is supported on a dataclass definition for schema generation:
So for the following application:
from dataclasses import dataclass
import annotated_types
from typing_extensions import Annotated
from litestar import Litestar, post
@dataclass
class Foo:
foo: Annotated[str, annotated_types.MaxLen(3)]
@post()
async def post_handler(data: Foo) -> None:
...
app = Litestar([post_handler])
We do render the constraint:
.. yet it is not enforced:
However, add a DTO into the mix:
@post(dto=DataclassDTO[Foo])
async def post_handler(data: Foo) -> None:
...
And now those constraints are enforced:
This is all a by-product of the way that we indiscriminately parse anything out of type metadata if it smells like a thing that declares schema constraints, immediately upon parsing the type. And once we have the constraint parsed, the DTOs will convert it into msgspec.Meta for the transfer model.
It also opens us up to weird issues like this app failing on schema generation:
from dataclasses import dataclass
from typing_extensions import Annotated
from litestar import Litestar, post
@dataclass
class Foo:
foo: Annotated[str, "totally unrelated metadata"]
@post()
async def post_handler(data: Foo) -> None:
...
app = Litestar([post_handler], debug=True)
This occurs because the string "totally unrelated metadata" has a title attribute that has nothing to do with ...
Very, very, very small enhancement: https://github.com/litestar-org/litestar/pull/3314
Description
- Expose
pathparameter atLitestarapplication class level
At this moment if we want use prefixed path for all routes in the application we have to create
dedicated router. E.g:
from litestar import Litestar, Router, get
@get("/")
async def index() -> str:
return "Hello, world!"
router = Router(path="/path", route_handlers=[index])
app = Litestar(route_handlers=[router])
This PR allows to set path on the Litestar application level.
Thanks to this we don't need additional Router class.
from litestar import Litestar, get
@get("/")
async def index() -> str:
return "Hello, world!"
app = Litestar(path="/path", route_handlers=[index])
Nice
I only made this bc I didn't want to fight with the elasticsearch config right now ๐
Sometimes a break from it is all you ned as well.
@dusky lance @rare merlin @wicked abyss you were missing here too ๐ฆ
https://github.com/litestar-org/litestar.dev/pull/21
Pull Request Checklist
- โป๏ธ New code has 100% test coverage
- โป๏ธ (If applicable) The prose documentation has been updated to reflect the changes introduced by this PR
- โป๏ธ (If applicable) The reference documentation has been updated to reflect the changes introduced by this PR
- โป๏ธ Pre-Commit Checks were ran and passed
- โป๏ธ Tests were ran and passed
Description
- Update maintainers list
Close Issue(s)
@signal linden you are super fast with merging.
dont feed his ego
You are faster @wicked abyss ๐
Description
- changelog for 2.8
Closes
special attention pls on anything we can cross-link with intersphinx or python glossary
and also the summation of content because some things were quite long and had coce blocks
revieweded
thx i fixededed
Removes the "Validate PR target" workflow, as it's no longer needed due to the removal of the develop branch.
https://github.com/litestar-org/litestar/pull/3328 decrementing issues from GH
this is ready for a looksie: https://github.com/litestar-org/litestar/pull/3322/files
Looksie given
@rare merlin thats a 3.10 change
https://docs.python.org/3/library/functions.html#isinstance
classinfo can be a Union Type.
Aah I really liked that. Feels more intuitive.
Move the creation of the KwargsModel from the routes to the route handlers. Since this operates on the handlers almost exclusively, it makes more sense to have it in there.
This also would like a looksie ๐
(is that an established slang term for "review" now? ๐)
I took some time to update the fastapi example for the ucoming AA release. https://github.com/jolt-org/advanced-alchemy/blob/8b65dd594b0c74e5fec4f3545d3e47bfac69678f/examples/fastapi.py
it's very similar to the litestar usage now
Removes the customization in favor of the bundled AA abstractions
it also fixes an issue where there was a warning about the event loop being closed printed during 2 tests
they weren't failures but it was annoying to see in the output screen
it also swaps to pytest-databses instead of the built in docker fixtures
oh, and uses the new render_plugins for open API
Liteatar maintainers are top models now!
is this a reference to my shades? ๐
Do I also need a profile picture with sunglasses now?! ๐
Should we make that mandatory? ๐
"Maintainer requirements: Must look at least this cool with sunglasses" 
That would be super cool. I guess the number od sponsors would increase rapidly...
OK, new glasses pic
"code review" > "glasses review"
I even added a banner pic
done
@signal linden wins
Vouge - "Litestar is the most sexyf and hot framework - Interview with Janek and Cofin"
Good idea. I feel like promoting a framework as "fast" has become old
"During the night I wear only Lightstar" - Victoria "Posh" Beckham
Love it!
"Is FastAPI out of fashion? Check out the Litestar!"
I mean, I have a cool Litestar hoodie
Lock it in. Looksie please: https://github.com/litestar-org/litestar/pull/3333
Done
Ta!
Putting out a spot fire: https://github.com/litestar-org/litestar/pull/3335
we'll need a point release for this too if there's anyone around who knows what they are doing on that front
no need for tests?
Well, we don't have a test environment that only has pydantic v1 in it, do we?
We should probably have one if not - but I'd like to get this out
This is where I think thereโs a case for using Hatch
sorry I just realized this, yes it was removed (because of pydantic v2 has v1 thing?)
sure, it would also be easy enough to setup as a special case in GH actions
but are we going pydantic v2 only in 3.0??
Code cov agrees with you ๐
no glasses pic, also force pushing
bad ๐ซ
haha - I'm actually wearing my sunnies right now b/c I was heading out the door to go for a run before I saw the issue ๐
There you go @wicked abyss
peer pressure always works ๐
~~beats @signal linden ~~
I'll do a release after work this afternoon if no one beats me to it - haven't done one in a while though but I assume the instructions are all there in contributing?
yes it was just updated by Coffee https://docs.litestar.dev/2/contribution-guide.html#creating-a-new-release
tbh idk how much of this applies bc of everything going into main
we still havent finished the cherry-pick-release-ifier
hmm, so do I need to create a new branch from the 2.8 tag and cherry pick the patch and tag/release that as 2.8.1?
i think that would work
will wait a bit to see if I get a response from https://github.com/litestar-org/litestar/issues/3337
Nice!
hmm, we do in the release pipeline - wonder how that didn't catch that bug..
this passed on release of v2.8.0 - I feel like it should have failed given that bug
https://github.com/litestar-org/litestar/pull/3341 - adds the changelog and version bump from v2.8.1 into main
We're going to need some realistic expectations now ๐
https://github.com/litestar-org/litestar/pull/3323 - problem details plugin
Description
A plugin to enable usage of problem details as the response.
The way this works is by injecting an exception handler into the app level exception handlers to convert ProblemDetailsException into a response following the specification as per RFC 9457.
Users can pass in a mapping of exception types to callables that will convert those exception types into ProblemDetailsException for handling specific exceptions such as pydantic's ValidationError. That converted ProblemDetailsException will then be used to create the response. This should allow for flexibility when needed.
Closes
Closes #3199.
area/plugins, pr/internal, size: small, type/feat
This needs to be reviewed, but it has exposed an issue we have when pydantic v1.10 users update to the latest of that minor series. We rely on v1 not being in the pydantic namespace to ascertain if we have v1 installed or v2 installed. This is no longer valid as they've added v1 namespace into v1
In that PR I've moved those minimal example/environment tests into normal CI b/c they don't take long to run and surely its better to find out about these issues well before we are about to cut a release.. right?
Could we do anything with https://docs.github.com/en/actions/using-jobs/using-concurrency to speed up some of these
https://github.com/litestar-org/litestar/pull/3352 - just removes some redundant comments
Description
Changelog and version bump from v2.8.2 release branch.
Closes
area/dependencies, area/docs, pr/internal, size: small
Removes the deprecated static_files_config and friends.
(please don't merge yet, this needs some docs and a better description :slightly_smiling_face:)
do not merge
First big one for v3.0 ๐
This has been rebased and still waiting for approval: https://github.com/litestar-org/litestar/pull/3297
Description
This PR removes all deprecated elements of OpenAPIConfig and the OpenAPIController, removes any obsolete tests and refactors tests that were parametrized to test both OpenAPIController and the router-based approach.
Supersedes #3271
Closes
it contains a "What's new in v3" doc which will be useful for subsequent v3 PRs
the breaking docs PR has this if it helps we can merge some of that
yea
if you get that merged I'll cherry pick the openapi controller on onto that and redo the docs part
OK this is dependent on the docs one: https://github.com/litestar-org/litestar/pull/3360
and this one https://github.com/litestar-org/litestar/pull/3361
How do you think we should proceed with the docs one @signal linden - I notice the ci builds based off it are failing b/c of changes to depenedency groups?
Its a weird one as I don't see any changes in the pyproject.toml that should change the groups but in the lock file it drops all of the groups except "default"and "docs"
i think the theme in litestar-sphinx-theme#15 is very close so when that is done we should be able to merge most of that. idk about the lock file maybe its busted but we can delete and regen
err litestar-sphinx-theme#15
Regenerating the lock helped, now I have groups = ["default", "dev", "dev-contrib", "docs", "linting", "test"]
but still get:
(litestar-3.8) peter@pop-os:~/PycharmProjects/litestar$ pdm install -G:all
[PdmUsageError]: Requested groups not in lockfile: full,jinja,attrs,piccolo,pydantic,redis,cli,mako,jwt,picologging,annotated-types,standard,structlog,opentelemetry,cryptography,brotli,minijinja,prometheus,sqlalchemy
(litestar-3.8) peter@pop-os:~/PycharmProjects/litestar$
Ahh pdm lock -G:all
Do you mind if I push that lockfile into that branch @signal linden ?
anytime
I'd like to merge the docs overhaul into v3 but it has tons of things its bringing with it.
https://github.com/litestar-org/litestar/pull/3363 is for that (i think)
Pull Request Checklist
- โ New code has 100% test coverage
- โ (If applicable) The prose documentation has been updated to reflect the changes introduced by this PR
- โ (If applicable) The reference documentation has been updated to reflect the changes introduced by this PR
- โ Pre-Commit Checks were ran and passed
- โ Tests were ran and passed
Description
- Add Elasticsearch support
TODO:
- โ More tests
- โ Mor accurate tests :)
- โ Replace tests with async ones
https://github.com/litestar-org/litestar/pull/3377 what is going on with these CI jobs errors?
Description
- Add tests for
defining_dtos_on_layers.pydocs example
Closes
Triage Required :hospital:, area/docs, pr/external, size: small
this must be an issue with forks
So, what to do? ๐ฆ
We can ignore them for now, i dont really understand which thing is failing and where ebcause it is indeed still labeling them even though it cusses at us
maybe the permissions are wrong for that token
ill try to fix it when i get through with some work
Thanks Coffe
Documentation preview will be available shortly at https://litestar-org.github.io/litestar-docs-preview/3378
I noticed this test was breaking when executed standalone or in a particular order. It turns that the test case (added in #1917) never worked in the first place and was only passing because invalid results of the _get_field_names classmethod were saved on the class.
Since the caching isn't really needed for performance here I have just removed it and fixed the test.
area/datastructures, pr/internal, size: small, type/bug
Remove the deprecated app parameter of Response.to_asgi_response; Its usage has been replaced internally by request.app, and custom response classes can follow the same pattern.
Refactor routes and route handlers in an attempt to simplify configuration.
The two general goals here are:
- Routes should not be concerned with any logic pertaining to handlers
- Routing layers (e.g. app/router instances) should not perform any manual handler setup
In general I'd like to restrict the routes to an internal part of the ASGI routing, only taking care of mapping a path > route handler(s), and establishing the connection. Everything else should be taken care of by the handlers.
What this currently does:
- Remove the
handler_namesproperty fromHTTPRoute - Move the
OPTIONShandler creation from theHTTPRouteto the route registration process - Remove the
methodsattribute fromBaseRoute; It does not make sense on the asgi/websocket routes - Move the creation of the
KwargsModelfrom the routes to the handlers and remove the outside mutation of the handlers - Move the mapping of route > handler > kwargsmodel to the handler itself
- Move the actual route handling to the handler
- Establish
ASGIConnection/WebSocket/Requestin the routes and pass them to handlers instead of raw ASGI objects (scope,receive,send) - Some minor refactorings that were enabled by these things
Todo:
- โป๏ธ Add section in "what's new"
- โป๏ธ Add deprecations to the 2.x line for removed things
area/docs, area/handlers, area/openapi, area/private-api, area/router, do not merge, pr/internal, size: large
This is also ready to go I think
There's more to be done here, but I don't want to blow up the PR unnecessarily ๐
another one that removes deprecated things: https://github.com/litestar-org/litestar/pull/3394
dumb Q, but what does "Deprecated scope state utilities" mean in a "whats new" for 3.0. It's removed so why is it under a section for deprecated stuff?
shouldnt it be "Removed scope state utilities"
yes
Already been reviewed but I've changed it fairly substantially: https://github.com/litestar-org/litestar/pull/3389
the change stores the exceptions handlers in the scope state so that the handler middleware can access from there. This means that we never require the middle exception handler wrapper as the outer one can now access the exception handlers resolved from the handler.
https://github.com/litestar-org/litestar/pull/3395 - changes to our CORS handling - there's two commits in this one that maybe should be split up, so perhaps good to look at each commit individually, as the 2nd one is just something I noticed while working on the first. That is, we have a dependency on the CORSMiddleware in the ExceptionHandlerMiddleware, so that we can wrap the send() coro with the CORS middleware send wrapper if CORS is configured. So, why not just make the CORSMiddleware the outermost middleware in this case so that the send() coro received by the exception handler middleware is already the wrapped one, if CORS is configured?
Description
Applies two refactors to our CORS handling:
- Move pre-flight response generation from the generated OPTIONS handlers to the CORS middleware.
- Make CORS outermost middleware.
Fixes case where pre-flight response not applied to mounted ASGI apps. Previously, we would only generate OPTIONS handlers for HTTP routes, not mounts, so pre-flight requests would be passed through to the mounted ASGI app.
Fixes the case where a user defined OPTIONS handler may not include CORS logic. In fact, this is they only way we can be sure that we honor CORS pre-flight if the config object is provided.
Remove ExceptionHandlerMiddleware's dependence on CORSMiddleware by making CORSMiddleware the outermost middleware in the stack if the app has CORS configured. This makes responses sent via the exception middleware pass through the CORS middleware send wrapper if CORS is configured, which is behaviourally equal to the current behavior of wrapping the send coro inside the exception handler middleware with the CORS middleware send wrapper.
Closes
area/middleware, pr/internal, size: small
Also, I'm uncertain whether we should consider the first commit a breaking change. It removes our reliance on the auto-generated OPTIONS handlers for generating the pre-flight response, but it is feasible that someone is supplying a custom OPTIONS handler specifically to handle the pre-flight response. However, the counter to this is that there is no documented requirement that a custom OPTIONS handler must handle the CORS pre-flight response, which could result in pre-flight requests not being handled where there is a CORS config on the app, but a custom OPTIONS handler defined for a route. This is because we only conditionally generate the OPTIONS handler with the CORS pre-flight logic in it if there is not already an OPTIONS handler on the route.
OK I broke the CORS pr up into 3 separate ones. They all chain off eachother but in order:
- litestar#3400 - this changes the way we build the asgi stack when cors is enabled. Instead of wrapping the stack with
ExceptionHandlerMiddlewarewe wrap it inCORSMiddlewarewhich removes the need forExceptionHandlerMiddlewareto depend onCORSMiddleware. - litestar#3401 - this moves the logic of generating CORS pre-flight responses from the generated OPTIONS handlers to
CORSMiddlewareitself. This fixes an issue where we aren't applying CORS to mounted apps. - litestar#3404 - deprecate CORS middleware from our public API - its pointless being there b/c our use of it is hardcoded so it cannot be subclassed, we need it to be the outermost layer of the asgi stack and it is configured by the
CORSConfigobject, not by adding a middleware to the application.
Wow fancy @wicked abyss
Anyone around for a quick review? I need to get out a point release if possible: https://github.com/litestar-org/pytest-databases/pull/31
Fix #3407.
A Sequence[UploadFile] | None would not pass validation when a single value was provided for a structured type, e.g. dataclass.
area/kwargs, area/private-api, size: small, type/bug
why did the linter not catch the type errors before?
Because of the dynamic types I added
Thatโs new, which prevents mypy from correctly inferring the type there
litestar#3418
Triage Required :hospital:, area/plugins, pr/external, size: small, type/bug
ready for a final rubber stamp if anyone available: https://github.com/litestar-org/litestar/pull/3389
it has been reviewed before, but materially changed since then.
the crux of it is that instead of storing the exception handlers resolved for each handler on the ExceptionHandlerMiddleware instances in the asgi stack, we store them in scope once routing has completed and access them from the EHMs if needed. This reduces the need for 1 instance of EHM in the stack in all cases.
It also adds an optimization to not add the inner-most EHM instance (that wraps route.handle) if there is no middleware in the stack.
Lastly, it deprecates the EHM from public API, as similar to CORS, we have specific hard-coded use of the type in our internals, so making it public doesn't make any sense b/c users cannot customize it.
This is amazing @dusky lance!
thanks! It just got a slight bit larger as I recalled that create_exception_response() and create_debug_response() are used downstream in apps like fullstack, so I've moved them into exceptions.responses real estate, and documented them.
on both, establishes v3 docs for these new libs and moved them from jolt, updates license year, some housekeeping
Thanks for doing that @signal linden!
np
idk why the builds failing but
almost there
Seems its a new thing https://github.com/sphinx-doc/sphinx/pull/12203
Description
- Remove deprecated module
litestar.middleware.exceptions - Remove deprecated
appparam ofExceptionHandlerMiddleware - Remove deprecated
exception_handlersparam ofExceptionHandlerMiddleware
Closes
Breaking ๐จ, area/asgi, area/docs, area/private-api, pr/internal, size: small, type/feat
Any ideas how to pass these failed jobs?
https://github.com/litestar-org/litestar/pull/3377
Description
- Add tests for
defining_dtos_on_layers.pydocs example
Closes
Triage Required :hospital:, area/docs, pr/external, pr/internal, size: small
can you try with your branch in the org instead of fork?
Update intersphinx link for advances-alchemy
Make route handler decorators functional decorators.
This gets rids of the __call__ method having to mutate internal state and lets us clean up things a bit.
It also makes for a nicer syntax and improved type/runtime checking of the handler classes, because they can now receive a fn as a required keyword argument, which gets rid of the HandlerClass("/")(handler_fn) pattern.
area/channels, area/controller, area/docs, area/handlers, area/private-api, area/testing, area/types, pr/internal, size: large, type/feat
Second round of route handler refactorings
Fix about 900 warnings in our test suite when running on 3.12.
https://github.com/litestar-org/litestar/pull/3420 final I think
Description
- Copy mutable values to avoid instance being reused between created instances
- Using hashability for as test, as done with dataclasses
Closes
can I close 3411 in favor of 3408 ?
looks the same to me
but I am not 100% sure
not sure if Sequence | None vs NotASequence | None are different
mmm just seeing the last and 1st lol commit I merged and the CI seems to have failed on macos: https://github.com/litestar-org/litestar/actions/runs/8875851706/job/24370524221
Friendly bump. <@&919261960921546815>, this needs some eyes ๐
The old nemesis ๐ฌ
Iโll have time to go over it today ๐
Thanks @severe onyx - btw I tagged you in that issue as I know youโve been looking at this stuff lately and figured you might have an opinion (in case that was weird ๐)
I felt pressure to be fair

https://github.com/litestar-org/litestar/pull/3453 add few tests for dto examples (part 1) with subtle refactor
Description
- Add tests for dto examples part 1
Closes
Triage Required :hospital:, area/docs, pr/external, size: medium
edited my comment a couple times there, so if you are responding, refresh it ๐
anyone wanting to review the ci issue here, each time i fix one thing a new thing pops up but it all passes locally... 
https://github.com/litestar-org/polyfactory/pull/533
pre-commit is passing locally?
it says so, maybe i need to pre-commit clean first
Hm..weird
Yeah after clean i get a ton.. ones not even showing on github ci
mypy.....................................................................Failed
- hook id: mypy
- exit code: 1
polyfactory/value_generators/constrained_dates.py:41: error: Redundant cast to "date" [redundant-cast]
polyfactory/factories/base.py:508: error: Argument 1 to "UUID" has incompatible type "bytes | str | UUID"; expected "str | None" [arg-type]
tests/test_random_configuration.py:68: error: Redundant cast to "int" [redundant-cast]
polyfactory/factories/pydantic_factory.py:546: error: Incompatible return value type (got "dict[Any, object]", expected "dict[Any, Callable[[], Any]]") [return-value]
tests/test_recursive_models.py:56: error: Non-overlapping identity check (left operand type: "PydanticNode", right operand type: "type[_Sentinel]") [comparison-overlap]
docs/examples/decorators/test_example_1.py:19: error: Returning Any from function declared to return "datetime" [no-any-return]
docs/examples/decorators/test_example_1.py:19: error: Redundant cast to "timedelta" [redundant-cast]
polyfactory/factories/beanie_odm_factory.py:32: error: Unused "type: ignore" comment [unused-ignore]
Found 8 errors in 7 files (checked 129 source files)
If its okay i was going to merge because making any changes would be pretty out of scope
its probably from a mypy version bump if i had to guess
Yeah that's fine. Could you create an issue for this as well so we can fix it?
well so
weI can fix it?I = you
Oh look at Alc volunteering to fix it ๐
want me to wait until your resolve the conflicts to approve?
aww man howd that happen
oh i did a bad out of scope thing that then also was changed in this pr because it bugged me
bad
fixed
Is this the recommended way going forward? branch instead of forks? Facing same issues with https://github.com/litestar-org/litestar/pull/3467
Description
- Updated
SignatureModel's_build_error_messagemethod to accept an optional error dict and add it to the message. - This can be used to propagate the original error object to the error handlers.
Closes #3466
Triage Required :hospital:, area/private-api, area/signature, pr/external, size: small, type/feat
they are an org member which is why I sugegsted them that
@rare merlin Is this the correct type hint? https://github.com/litestar-org/litestar-asyncpg/pull/7
how do you use the connection in those hooks if it's not a parameter?
Pull Request Checklist
- โป๏ธ New code has 100% test coverage
- โป๏ธ (If applicable) The prose documentation has been updated to reflect the changes introduced by this PR
- โป๏ธ (If applicable) The reference documentation has been updated to reflect the changes introduced by this PR
- โ Pre-Commit Checks were ran and passed
- โป๏ธ Tests were ran and passed
Description
- correct the type hint for the
setupandinitinPoolConfig
Aah because setup and init doesn't take in a coroutine but rather a callable that returns a coroutine which doesn't return or yield anything. So the correct type hints for those would be the following I think:
from asyncpg import Connection
from asyncpg.pool import PoolConnectionProxy
setup: Callable[[PoolConnectionProxy], Coroutine[None, None, None]]
init: Callable[[Connection], Coroutine[None, None, None]]
Btw, we should probably add asyncpg-stubs as a dev dependency so that the type checkers will catch all this.
ah, I see. yep, I agree with you re: asyncpg-stubs
I think Callable[[Connection], Awaitable[None]] would be preferable, as it's more generic
Doesn't really have to be a coroutine function; As long as it's a callable that returns something that can be awaited, it's fine
this didnt work, pyright was complaining
pretty much this, Callable[[Connection[Record]], Coroutine[Any, Any, None]]
Documentation preview will be available shortly at https://litestar-org.github.io/litestar-docs-preview/3476
Huh, what? What was pyright saying?
Argument of type "(Connection[Record]) -> Awaitable[None]" cannot be assigned to parameter "init" of type "_InitCallback[Record] | None" in function "create_pool"
Type "(Connection[Record]) -> Awaitable[None]" is incompatible with type "_InitCallback[Record] | None"
Type "(Connection[Record]) -> Awaitable[None]" is incompatible with type "(__con: Connection[Record], /) -> Coroutine[Any, Any, None]"
Function return type "Awaitable[None]" is incompatible with type "Coroutine[Any, Any, None]"
"Awaitable[None]" is incompatible with "Coroutine[Any, Any, None]"
"function" is incompatible with "None"
#1152626430295933060 message ๐
But that was Awaitable[None]
I'm saying pyright failing here is correct because Coroutine[Any, Any, None] is indeed not compatible with Awaitable[None]
But if Awaitable[None] fails, Coroutine[None, None, None] should also fail
the first arg in the generics must match?
The first arg of Coroutine is the return type
Equivalent to the generic arg to Awaitable
Coroutine[T, Any, Any] matches Awaitable[T]
what I understood, but phrased poorly
litestar#3478 litestar#3479 litestar#3480
https://github.com/litestar-org/polyfactory/pull/540. This should unblock some of the CI issues
https://github.com/litestar-org/litestar/pull/3483/files if needed we can add emails
Are you guys happy if I merge https://github.com/litestar-org/litestar/pull/3484 without satisfying the code-coverage requirement? I don't want to add a pragma for no cover there, but I also don't want to have to write a test to hit that branch of coverage as a part of this PR. It is just that after the ruff update, we were able to remove a # noqa for a line that was otherwise already uncovered.
No issues from me.
yep
thanks!
litestar#3486 - DTO data transfer when dto type is nested within a mapping annotation
Pull Request Checklist
- โป๏ธ New code has 100% test coverage
- โป๏ธ (If applicable) The prose documentation has been updated to reflect the changes introduced by this PR
- โป๏ธ (If applicable) The reference documentation has been updated to reflect the changes introduced by this PR
- โ Pre-Commit Checks were ran and passed
- โป๏ธ Tests were ran and passed
Description
- correct the type hint for the
setupandinitinPoolConfig
Description
This PR unpins Advanced Alchemy.
This allows version 0.9.3 to be installed with teh litestar[sqlalchemy] command group.
This enables the following:
- A numebr of repository and service optimizations and fixes
- SQLAlchemyQueryRepository from advanced alchemy
to_schemafrom theServiceused there (see the fullstack repository for usage details)
However, this AA release also had to integrate it's own copies of the Litesatr OffsetPagination dataclass. Litestar will attempt to use this version of the dataclass when a supported version is installed. This is implemented similar to how the filters in filters.py work currently.
Closes
area/dependencies, pr/internal, size: small
I guess I can approve this. It's not my PR. Sorry, @rare merlin I just took this thing over and didn't ask. ๐คฆโโ๏ธ
Description
This PR addresses a type hint compatibility issue for Python 3.8
Closes
I'll get a patch release out once this is merged
approved
https://github.com/litestar-org/advanced-alchemy/pull/192
You can now pass default joins into the repo without having to use a custom statement. There's a load parameter that will accept a Load type (selectin,joined, etc..) , This will also accept the instrumented attribute you want to join. It will inspect the relationship and automatically choose between a joined or selectin load. Lastly, this will also accept a * to default to a joined load.
@mental quarry
@woven tundra @dusky lance this is one of the last "big" features I had on my list for 1.0
Here are a few examples from the tests for reference:
class Country(UUIDBase):
name: Mapped[str]
states: Mapped[List[State]] = relationship(back_populates="country", uselist=True)
class State(UUIDBase):
name: Mapped[str]
country_id: Mapped[UUID] = mapped_column(ForeignKey(Country.id))
country: Mapped[Country] = relationship(uselist=False, back_populates="states", lazy="raise")
country_repo = CountryRepository(session=db_session, load=[selectinload(Country.states)])
usa_country = await country_repo.get_one(name="United States of America") # selectin load
assert len(usa_country.states) == 2
country_repo = CountryRepository(session=db_session)
usa_country = await country_repo.get_one(name="United States of America", load=Country.states) # automatic selectin load based on `uselist` in relationship
assert len(usa_country.states) == 2
repo = USStateRepository(session=db_session, load=State.country)
string_california = await repo.get_one(name="California") # automatic joined load based on `uselist` in relationship
assert string_california.id == california.id
repo = USStateRepository(session=db_session, load="*") # joined load & unique() added to execute
star_california = await repo.get_one(name="California")
assert star_california.country.name == "United States of America"
I love it! Noticed that we can pass a Load to the getter methods as well, awesome work
Description
Property that indicates whether None can be assigned to the annotation.
Closes
not a meta typing expert, no tests needed here? is it trivial?
absolutely needs tests ๐ตโ๐ซ
that test suite takes like a minute to complete ๐ฅน
AA test suite takes that long to setup :p
15-20 min test runs for the full thing
yeh but its not running type checkers I don't think
i gotta sort that
still hoping for < 20 min though ๐
Description
Add mypy, pyright and slotscheck to CI.
Closes
Hello ๐
https://github.com/litestar-org/litestar/pull/3507 (almost done, but need some feedback & have some questions)
Description
Currently we're logging the exceptions twice: the full one and a truncated one.
This PR tries to improve this, which implies small breaking changes.
Almost finished but still a WIP, I need some feedback please!
Summary
โ ๏ธ The former code has been introduced to solve #1294, unfortunately I haven't been able to reproduce the issue. It's not clear in which cases it happened, or if the PR (#1296) fixed the original issue (I don't think so because exception are logged twice in the end).
โ TODO Anyway, to solve the original issue (#1294), truncating the request's body would have been a better solution. I'd be happy to dig a little bit more here. Any idea about how to reproduce the issue? (I already tried to write a test with a file upload, but the request's body doesn't get printed)
โ ๏ธ Type ExceptionLoggingHandler and signature of handle_exception_logging() get updated by this PR, seems better and more flexible this way.
Logging
โ
Behavior is still the same, just slightly changed how we count the lines to display (see the code and the test test_traceback_truncate_default_logging).
โ
Ability to set traceback_line_limit to None.
โ ๏ธ Default value for traceback_line_limit is None, I don't think we should truncate stacktraces by default.
โ Maybe we could deprecate traceback_line_limit to keep things in sync with Structlog. And if it's really something wanted by users, they can bring it back easily via a custom exception_logging_handler.
โน๏ธ Updated log messages to get something similar to structlog.
StructLog
โ
Fixed a bug with pretty_print_tty (as a separated commit).
โ
When pretty_print_tty=True, we don't log the stacktrace twice and the remaining one gets truncated automatically by structlog (see below).
โ
When pretty_print_tty=False, exception gets logged as json. The stacktrace is not truncated anymore. It should not be a problem because the full stacktrace was also logged, so with this PR we're reducing the global log size. It's still possible to parse the JSON after, with some tools, to limit the lines displayed. If needed, the full stacktrace is still available.
โ TODO: If it's fine on your side, can I mark traceback_line_limit as deprecated and document it?
Extras
โ ๏ธ Note: A few tests use structlog.testing.capture_logs. When using it to capture the logging.exception() output, the traceback is not yet rendered. That's something to keep in mind.
โ What about turning log_exceptions to always by default? (Hiding errors by default seems a bad choice according to my sysadmin background).
Structlog: before & after
__With `pret...
Breaking ๐จ, Triage Required :hospital:, area/logging, area/types, pr/external, size: small, type/bug
Oh, yeah, I wrote a long (but full) description... ๐
did they leave you alone in the hotel and go to pycon? why are you still doing PRs
I mean, enjoy 
I did opt out on the evening's activities - wasn't feeling 100%
I sat at the same table as Guido at the typing summit today ๐คฏ
now i dont feel bad they left you out
haha - the guys were off to an astral/ruff party tonight
did you see the update I wrote in #1240662108979597342 message
yes, I am just looking at that
Description
- Remove deprecated module
litestar.middleware.exceptions - Remove deprecated
appparam ofExceptionHandlerMiddleware - Remove deprecated
exception_handlersparam ofExceptionHandlerMiddleware
Closes
Breaking ๐จ, area/asgi, area/docs, area/private-api, pr/internal, size: small, type/feat
@snow sapphire
Looking good. If you hate the copywrite Linter error, I think we can remove it. I needed to start using it on something else, so I was testing it out there.
make lint should give you the same output as the 3.12 test
What's the reason for having it like that instead of single license file?
is there an advantage or something?
I don't think I understand how this projects build system is set up
Why are there 3 requirements.txt in addition to the dependencies in pyproject.toml? And how do I update them? And the makefile also doesn't seem to actually have a way to install the dependencies? But it did when I ran make install?
I'm lost ๐ฆ
make upgrade
It's a requirement for my G projects. Every file has to have it
and I wanted to find a way to lint for it.
That just changed the pre-commit ๐
Hmm, it's supposed to refresh the lock file using hatch-pip-compile
Ah, I see. hatch-pip-compile wasn't installed when I ran make install for some reason
ah, you already had hatch installed
I had to do make install-hatch
๐
Interesting
Hello ๐
I'm wondering if I should continue working on https://github.com/litestar-org/litestar/pull/3507 or just close the PR
Hey! Sorry, I've not had a chance to think about this one too much since coming back from PyCon. I'll dig into a bit, but, on the surface, some of these changes sound great. Maybe there's a way to bring in a few of the non-breaking things; potentially an opt-in configuration might work as well
there's already a section for enabling features in experimental_features, so perhaps this is something that could be used there.
Ho, I understand ๐ Thank you
Re: this:
โ What about turning log_exceptions to always by default? (Hiding errors by default seems a bad choice according to my sysadmin background).
I think this is is a good idea. We have too many times had to recommend enabled DEBUG mode. I have it enabled in my config most of the time.
Great work on this PR detail! This is super helpful.
Am I correct in my understanding that this is the only breaking change as of the current state of the discussion?
Update of type ExceptionLoggingHandler and signature of handle_exception_logging() might break custom exception_logging_handler. This is the main breaking change. This might be reverted
ah, and the None
I think the None addition should only expand the type signature, so it is probably non-breaking re: the API?
It depends what we call breaking change, tbh I'm not 100% sure ^^'
If strictly talking about the API, or other usages
I'm in favor of getting PR merged; we may have to phase in some of the clean-up over time (exception_logging_handler signature & traceback removal) though.
Current signature of exception_logging_handler can be kept for now, it won't affect other changes (I guess)
Thanks for spending time on this one, btw. We need some polish to logging.
Note I have another branch around logging improvements (as stated in the PR)
we might want to release as much as possible
(or not, I'm entirely sure)
I would prefer we do this as well. We can target the breaking changes to the 3.0 branch.
I mean outside of the major breaking changes
Or for example, would you wait 3.0 for traceback removal? I'd think it should be released in the 2.0 branch (considering it's a duplicate of the exception, increasing log size, and so it might have a production impact)
Also, I've been told that LoggingConfig might disappear/be deprecated in v3... so adding breaking changes and at the same time deprecating seems weird to me
I think my inclusion of the tracebook in structlog is a bug. In fact, it was on my list to track down for a while.
Yes, I agree with with this in principle. It would also like to get some of these things fixed prior to a 3.0 release.
I'm not sure I have a good feel for what a no LoggingConfig setup would look like yet though.
traceback = a truncated stacktrace, but exception is already here and contains the entire one
I'd have removed it though if I'd realized I left it in. I much prefer the better formatted output
I guess, this would be just passing a logger install to Litestar, and that's it.
And document best logging practices in the docs.
Yep, in fact there is the structlog dev mode (pretty tty) and the production mode (json).
I feel like changing the dev mode isn't a big thing, but the json might have an impact on how people monitor in production (like how they configured some tooling).
But I feel like the outcome of reducing log size worth it
(for a v2.x release, I mean)
I 100% agree here.
@snow sapphire Would you have any input about https://github.com/litestar-org/litestar/issues/1294 ? I'm mainly wondering how to reproduce the error
I think you can use the static asset handler and serve a large file
with the body logged in the response
I tried that, but the request is not logged, at least with a default setup
is there an option for that?
src/app/config/app.py line 131
response_log_fields=["status_code"],
I mean, if users log the response, they have to make sure to remove binary form data by themselves (?)
Oh, I see
IIRC, there's a flag that only logs the response when it's above a certain size
and it only shows if you also log the body of the response
Thank you for pointing this
I think this is the biggest gripe I have with our logging. It's spread out too far
There's the config, middleware, request logging, etc...
I grew to like the LoggingConfig in a weirdly ironic way. It roughly mirrors the standard logging config components. (I'm not opposed to it going away though)
Yep, that's not easy to understand when you start
Yep, it's not that bad because you can configure as you want, it just needs some small fixes
But having to support standard logging/picologging, structlog, and then people might want to add support for other logging libs
and then it becomes bigger & bigger
yeah, this is where it gets out of control
litestar/middleware/logging.py line 204
if key == "body" and response_body_compressed:
Thank you very much!
It's been a while since i looked at this, but I vaguely remember there being a size check to this as well. I'm not seeing it now though
these are the valid values you can log:
"status_code",
"cookies",
"headers",
"body",
you can also reproduce this error on the request side
if you upload a large file and enable body on the request
I'll dig a little bit in the coming days (I'm in the CEST timezone, so going to disconnect soon)
But it was very helpful
cheers. btw, I'm not always active on github issues, but I'm generally available here if you need anything.
Remove redundant pull_request trigger that makes the job run twice and fail for PRs on forks.
area/ci, size: small
Make our CI not fail on forks all the time ๐
Port the fix for the https://github.com/litestar-org/litestar/security/advisories/GHSA-83pv-qr33-2vcf path traversal vulnerability to 3.0
size: small, type/bug
@dusky lance if you have the time to look at this ๐
Remove Controller specific logic needed during registration by converting controllers into Router instances first.
area/controller, area/router, pr/internal, size: small
Some more routing refactoring
for my understanding, was it a bad idea if it was Router.from_controller(controller) instead of controller.as_router()?
A bit. Router.from_controller requires the router to have knowledge about the controller's internals
Controller.as_router keeps all of that contained within the controller, and just uses the Router's public API
Remove the deprecation warnings when subclassing route handler decorators introduced in #3439.
pr/internal, size: small
Description
The flash messages plugin requires a valid session configuration. This PR adds a basic configuration to the examples. Previously, an exception would be raised when executing the examples.
Closes
Description
This PR updates the signature for the flash function. Currently, I recent a pyright warning when importing because the signature is partially unknown.
Closes
area/plugins, pr/internal, size: small, type/bug
@woven tundra re: this https://github.com/litestar-org/litestar/pull/3507
The addition of traceback is an unfortunate bug that I left in. I meant to remove this before since there's already a nicely formatted exception. The user who created this PR dropped into chat the other day as well.
Oh, so this is a bug? In that case, removing it wouldn't be breaking
It was definitely not intentional that I print 2 tracebacks with structlog. I noticed it was doing this, made a mental note to fix this, and totally bailed on fixing it.
I don't think this would be breaking because you have the same data printed twice. When the terminal is not in tty mode, they both serialize to json as well. However, the correct one has a bit more detail.
So we can safely remove the traceback?
Can you comment that on the PR as well, so it's documented? ๐
Hello ๐
I've updated my PR and answered on https://github.com/litestar-org/litestar/pull/3507#issuecomment-2134018565
- No more breaking change in the API.
traceback_line_limitis ignored for both standard logging & structlog.- I have a codecov error (https://github.com/litestar-org/litestar/pull/3507/files#diff-110e498a2e71333ae98121de712e741ce2410c899c7929ac88be1a12f3978c59R108), I should add a dummy test to fix that?
TBH, I don't think so. It has been introduced per https://github.com/litestar-org/litestar/pull/1296/commits/1d509994872f8e7434d846b2693c240bcecef576#diff-589fea37e41f4742ba6e6fa99a839c0e2e709d56f49ed132b135e53d8ebee5afR100
But according to me, it's still a bug.
Description
- Pre-commits not updated as done in previous PR
Closes
Hey, any feedback? In particular for the coverage part.
And if it's "mergeable", I'd also like to rebase the branch (to merge some commits and update commit messages).
I'll take a look now
Seems to be all good @umbral furnace!
Hi @woven tundra ๐
Just seen your message
Thank you for taking a look, I'm adding a test for the coverage warning
You won't be able to get the coverage warning away
You have removed tests, which is intended
(I'm also squashing commits and removing the ! from the commit message)
So no need to do anything about that coverage
It's just an artifact of how that is measured
I thought the cov warning is because I haven't tested a condition ๐ค
Well, let's see
Oh
Yeah, you're right! Disregard my previous messages ๐
I was looking at the wrong thing ๐ฌ
I did the final cleanup โ
merged ๐
I'd like to open another (and last, at least for now) PR to improve LoggingConfig.
I've seen a few things to fix anyway, but I'd also like to add a new option logging_module: https://github.com/litestar-org/litestar/issues/3536
Would you accept a PR for this? It implies updating a few tests, so I'd prefer having an approval before opening a PR.
Summary
It would permit to switch from picologging to logging without having to hack around or uninstall picologging.
It would be useful in tests but also in production (vs having to update a requirements file and rebuild an artifact).
This option would be optional. The default behavior would be the same as today (use picologging if the lib is installed).
Basic Example
std_logging_config = LoggingConfig(logging_module="logging")
picologging_logging_config = LoggingConfig(logging_module="picologging")
Drawbacks and Impact
No response
Unresolved questions
No response
[!NOTE]
While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.Check out all issues funded or available for funding on our Polar.sh dashboard
- If you would like to see an issue prioritized, make a pledge towards it!
- We receive the pledge once the issue is completed & verified
- This, along with engagement in the community, helps us know which features are a priority to our users.
Enhancement
This one is now passing all tests. https://github.com/litestar-org/advanced-alchemy/pull/204
and I'm ok if I never see another lambda_stmt again.
Okay, I understand what this does, but can you explain why this fixes the issue?
Yeah. But I can't explain why LambdaStatement behaves like this.
It's got to do with the way the lambda statement does caching of the actual lambda. Prior to this, we convert to a lambda statement right as we initialize the repository. This caused issues with caching when passing in options after the initial instantiation of the repo.
The fix was to store the initial statement as a Select instead of a lambda on init. Then we construct the lambda on each repo call before appending the filters/query changes to it.
The other issue was that we had statement caching disable in a few places because it seemed correct (count and list_and_count for instance)
however, when you do this, it messes up statement caching in subsequent calls
so, the last piece of the fix was to remove all lambda_stmt cache customizations by default.
This has the secondary benefit of fixing the issue that was opened 5 days ago that I never even saw
Oh wow
This sounds like a mess tbh ๐ฌ
Maybe it's worth it to open an issue on the SQLA repo to get confirmation that this is actually working as intended? ๐
yeah, I intended to. There are significant performance improvements when using the statement caching, but it's crazy complex
it makes it sometimes hard to tell if I'm using it incorrectly or if it's intended
Mike Bayer has hinted at reworking/deprecating lambda statements at some point, I posted that somewhere
Yeah, I'm sure there'll be a replacement first though. The benefits appear to be quite significant
speaking of which, I think i ran across a fix for your open issue
I just need to go find it again
lol
for this
I was just thinking that this PR will likely fix that? Maybe not
@listens_for(Session, "do_orm_execute")
def _do_orm_execute(orm_execute_state):
"""Modifies queries globally based on rulesets."""
# this rule ensures that records won't load if they're soft-deleted
# unless execution options are set otherwise
if (
orm_execute_state.is_select
and not orm_execute_state.is_column_load
and not orm_execute_state.is_relationship_load
and not orm_execute_state.execution_options.get("include_deleted", False)
):
orm_execute_state.statement = orm_execute_state.statement.options(
with_loader_criteria(SoftDeleteMixin, lambda cls: cls.is_deleted.is_(False), include_aliases=True)
)
I'm not 100% sure if the latest release will fix this