#Code Reviews

1 messages Β· Page 3 of 1

snow sapphire
#

but it might

#

if it doesn't, i have an idea

snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
snow sapphire
#

We need to add a wrapper around signature_types so that it doesn't raise an error when the type is already loaded.

#

I've swapped them back to signature_namespace for now so that the app starts

snow sapphire
#

Can someone approve this? It fixes the lint validation errors in main

cloud helmBOT
umbral furnace
umbral furnace
wicked abyss
wicked abyss
#

thanks

umbral furnace
wicked abyss
umbral furnace
wicked abyss
#

i think its not even using that file

#

its searching for ci.yaml and that was renamed like 4 months back to ci.yml

#

guessing here

woven tundra
cloud helmBOT
#

Fix a bug that caused the .websocket_connect methods on TestClient and AsyncTestClient to not respect the base_url set in the client's constructor, and instead would use the static ws://testerver URL as a base.

Also removes most of the test client code as it was unneeded and in the way of this fix :)

Labels

size: small, type/bug

woven tundra
#

Small PR that fixes a bug in the TestClient

#

Also removes most of the TestClient code πŸ™‚

snow sapphire
#

I was just thinking "this removed a ton of wrapping code"

woven tundra
#

Yup

#

tbh, I never really bothered to check why this code is the way it is

#

It was just copied from Starlette

#

Turns out, there's no reason for it to be like that

#

In 3.0 we can also remove the whole BaseTestClient class, but that would be breaking so I've left it out for now

woven tundra
cloud helmBOT
#

Fix #3534.

Don't call rich_click.patch if rich_click is installed, and instead use conditional imports to refer to the correct library. External libraries will still be able to make use of rich_click implicitly when it's installed by inheriting from LitestarGroup / LitestarExtensionGroup, which they will by default.

Labels

area/private-api, pr/internal, size: small, type/bug

woven tundra
#

This is still looking for a review 😒

cloud helmBOT
wicked abyss
woven tundra
#

Idk, I'm not using that weird IDE you're on πŸ˜›

#

But pyright CLI does complain about it

snow sapphire
#

I’m guessing he’s on some cool IDE like vscode πŸ˜‰

#

Where it uses pylance

#

Which is pyright + extras

woven tundra
cloud helmBOT
wicked abyss
cloud helmBOT
#

Description

  • Add support for additional V1 model_dump and V2 dict parameters in PydanticPlugin

This is a continuation of https://github.com/litestar-org/litestar/pull/3171
The last unresolved conversation is here https://github.com/litestar-org/litestar/pull/3171#discussion_r1544483848

Closes #3147

Labels

Triage Required :hospital:, area/types, pr/external, pr/internal, size: small, type/feat

umbral furnace
woven tundra
cloud helmBOT
woven tundra
#

I'd like to do a patch release once this one's merged!

snow sapphire
#

I actually looked at this from my phone over the weekend

#

I just re-reviewed and approved

woven tundra
cloud helmBOT
woven tundra
#

Okay I think I found the bug

#

But I still don't know why it just started to be triggered randomly and I can't reproduce it locally

#

Okay. I am officially 100% confuse now

#

Now it's throwing this.. Which also doesn't reproduce locally?!

#

Man. I hate debugging stuff that I can't reproduce πŸ˜„

wicked abyss
#

try -v to see verbose?

woven tundra
#

You mean in CI?

wicked abyss
#

yes

woven tundra
#

Not sure that helps. I can see why it's failing. I just don't know why it's doing that only there

#

This is so weird. It's as if it's running against a different version?

woven tundra
cloud helmBOT
woven tundra
#

πŸ™‚

wicked abyss
# cloud helm

# h ttps://github.com/litestar-org/litestar/issues/3593 πŸ™ƒ

snow sapphire
#

addressees some test issues with the new AA multi-config support

snow sapphire
cloud helmBOT
#

Description

Currently, the FlashPlugin expects the request parameter to be a type of Request. However, there's no reason it can't use the parent class ASGIConnection.

Doing this, allows for flash to be called in guards that expect an ASGIConnection instead of Request:

def requires_active_user(connection: ASGIConnection, _: BaseRouteHandler) -> None:
    if connection.user.is_active:
        return
    msg = "Your user account is inactive."
    flash(connection, msg category="error")
    raise PermissionDeniedException(msg)

Closes

Labels

area/plugins, pr/internal, size: small, type/bug

frail shore
snow sapphire
#

just reviewing the notes on the PR

#

if it's not a breaking change, we should just target main

#

Re: the second one. If you use the litestar-org/maintainers as the reviewer, i think it'll auto assign one of us

#

I think it's time for a v3 feature flag in experimental features

frail shore
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
#

Fix #3627 by properly handling the creation of FormMultiDict where multiple values are given for a single key, to make Request.form() match the behaviour of receiving form data via the data kwarg.

Before

@post("/")
async def handler(request: Request) -> Any:
    return (await request.form()).getall("foo")

with create_test_client(handler) as client:
    print(client.post("/", data={"foo": ["1", "2"]}).json()) # [["1", "2"]]

After

@post("/")
async def handler(request: Request) -> Any:
    return (await request.form()).getall("foo")

with create_test_client(handler) as client:
    print(client.post("/", data={"foo": ["1", "2"]}).json()) # ["1", "2"]

Labels

area/connection, pr/internal, size: small, type/bug

wicked abyss
woven tundra
#

The PR exists because the code that was changed during the original fix has been deleted in v3, but the behaviour hasn't

#

So the behaviour still exists outside the deleted code in v3, just in a different place

wicked abyss
woven tundra
#

It was failing after I rebase it, yes

#

And that was expected, because of the other change that deleted the code where the fix took place

wicked abyss
#

thanks

woven tundra
cloud helmBOT
woven tundra
# cloud helm

Can we get some eyes on this? <@&1084813023044173866> πŸ™‚

snow sapphire
cloud helmBOT
snow sapphire
#

most of the changes are linting or ignores, so it's not really 18 files

peak monolith
cloud helmBOT
peak monolith
cloud helmBOT
#

Description

  • Currently, tuple with fixed length and randomised collection length are not handled correctly. These are treated as arbitary length tuples.
  • Remove calls to collection extender so this type is explicitly passed to other places.

Closes

peak monolith
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
#

Some maintenance PR πŸ™‚

snow sapphire
woven tundra
cloud helmBOT
woven tundra
#

Small DTO PR

snow sapphire
cloud helmBOT
#

Description

I had some code working before upgrading litestar. The newer versions where the codegen backend is enabled by default broke some tests. Here I'm copying the code in the doc and making small adjustments to match my case, I'm assuming it will behave the same, didn't try it yet.

from __future__ import annotations

from dataclasses import dataclass, field
from uuid import UUID, uuid4

from litestar import Litestar, post
from litestar.dto import DataclassDTO, DTOConfig

@dataclass
class User:
    name: str
    email: str
    age: int
    id: UUID = field(default_factory=uuid4)
    nested_1: NestedUserAttr

@dataclass
class NestedUserAttr:
    key: int
    nested_2: AnotherNestedUserAttr

@dataclass
class AnotherNestedUserAttr:
    a_nested_key: int | None = None


class UserWriteDTO(DataclassDTO[User]):
    """Don't allow client to set the id."""
    config = DTOConfig(exclude={"id"},  max_nested_depth=4)

@post("/users", dto=UserWriteDTO, return_dto=None, sync_to_thread=False)

def create_user(data: DTOData[User]) -> User:
    """Create an user."""
    d = data.create_instance()
    return d

app = Litestar(route_handlers=[create_user])

Here is the issue: sending a proper json encoded data to the endpoint would result in a_nested_key = None. I'm not yet sure is it because of a) the default value b) the depth of nesting.

The behaviour isn't the same with experimental_codegen_backend=False.

URL to code causing the issue

No response

MCVE

# Your MCVE code here

Steps to reproduce

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

Screenshots

"![SCREENSHOT_DESCRIPTION](SCREENSHOT_LINK.png)"

Logs

No response

Litestar Version

main branch

Platform

  • ◻️ Linux
  • ◻️ Mac
  • ◻️ Windows
  • ◻️ Other (Please specify in the description above)

[!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.
Labels

Bug :bug:

woven tundra
#

No, this is something else unfortunately πŸ™‚

cloud helmBOT
#

This PR adresses the abandoned/obsolete python package: python-jose.
This package has not been maintained since 2021.

looking at several issues on that project there are a couple CVE's im not comfortable with.
I went looking for a "drop-in" replacement and found pyjwt. (project last updated 3 weeks ago).

This pull requests addresses that problem.

hope you agree with this.

kind regards.

Labels

Triage Required :hospital:, area/dependencies, pr/external, pr/internal, size: small, type/feat

woven tundra
#

I'm leaning towards accepting this over the other PR, as it's the cleaner implementation and would allow us to get a release with this shipped more quickly

#

It also doesn't seem to have the issues the other PR has, which I think is good, as PyJWT should be a drop-in replacement

snow sapphire
#

i'll merge this guy's PR

#

(or you can?)

woven tundra
#

Already on it πŸ™‚

snow sapphire
#

can we get that OpenTelemetry one as well?

cloud helmBOT
#

Description

This PR addresses an issue with exception handling and span creation in the LiteStar application when using OpenTelemetry for observability. The problem occurred when exceptions were raised before the OpenTelemetry middleware was invoked, resulting in those exceptions not being captured under the current request span. This led to incomplete traces, making it difficult to monitor and debug the full lifecycle of requests.

Solution

To solve this, I reordered the middleware chain to ensure that the OpenTelemetry middleware wraps the entire request lifecycle, including exception handling. The new order is as follows:

Initial ExceptionHandler Middleware -> OpenTelemetry Middleware -> ASGIRouter -> Middleware n -> Exception Handler Middleware -> Route Handler

This ensures that spans are created as early as possible in the request lifecycle and that any exceptions, regardless of where they occur, are logged within the appropriate span. However, this will only occur if the OpenTelemetry middleware is included in the middleware stack.

Closes

#3663

Labels

Triage Required :hospital:, area/docs, area/plugins, pr/external, pr/internal, size: small, type/bug

woven tundra
#

I'm reviewing that next

snow sapphire
#

awesome

#

thx

woven tundra
#

There's still some issues with it we'll need to fix πŸ‘€

#

Let me see if I can make a PR into that PR with fixes πŸ˜„

snow sapphire
#

I have one more PR for otel as well

#

let me see if you think it can be merged

cloud helmBOT
#

Description

When using OpenTelemetryConfig, during the application launch the logs get spammed with messages like:

An instrument with name http.server.duration, type Histogram, unit ms and description measures the duration of the inbound HTTP request has been created already.
An instrument with name http.server.response.size, type Histogram, unit By and description measures the size of HTTP response messages (compressed). has been created already.
An instrument with name http.server.request.size, type Histogram, unit By and description Measures the size of HTTP request messages (compressed). has been created already.
An instrument with name http.server.active_requests, type UpDownCounter, unit requests and description measures the number of concurrent HTTP requests that are currently in-flight has been created already.
...repeats...

This is because the underlying OpenTelemetryMiddleware (from opentelemetry-instrumentation-asgi) constructs metrics objects in init.

The metrics are added to the global registry, so re-doing the same will throw a warning as they already exist there.

A separate middleware instance is created per route. Is there way to avoid that? I don't see why it would be needed. When the middleware is specified at the application level (ie. Litestar(middleware=[...])) wouldn't a single instance do?

Is there a way around?

MCVE

This is sufficient, because `OpenAPIController` is initialized by default, and the middleware wraps also it:


import uvicorn
from litestar import Litestar
from litestar.contrib.opentelemetry import OpenTelemetryConfig
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider

metric_provider = MeterProvider()
metrics.set_meter_provider(metric_provider)

otel = OpenTelemetryConfig()

app = Litestar(middleware=[otel.middleware])

uvicorn.run(app)

Steps to reproduce

1. `python app.py`
2. See error

Litestar Version

2.5.1

Platform

  • βœ… Linux
  • ◻️ Mac
  • ◻️ Windows
  • ◻️ Other (Please specify in the description above)

[!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 t...
Labels

Upstream

woven tundra
#

Okay, I got something working, but it's really hacky, and I'm not sure if it's actually any better. I'll sleep on this and get back tomorrow

#

This would be another one of those things solved by middleware priorities quite neatly though @snow sapphire

#

I think I'll try to get to that soon

snow sapphire
cloud helmBOT
snow sapphire
#

if anyone is around for a quick review

#

i'm trying to unpin AA in the main litestar repo and this is a failure that is hitting the tests

woven tundra
cloud helmBOT
woven tundra
#

It's not the best solution, but I think it's the best compromise we can make to achieve all the things we want at the moment

snow sapphire
woven tundra
#

Yup, good point. I've changed it

woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
#

Set forbid_unkown_fields=True for PydanticDTOs where the Pydantic model has an extra="forbid" config.

  • Add a new get_config_for_model_type method to AbstractDTO, that allows to customise the base config defined on the DTO factory for a specific model type
  • Use get_config_for_model_type to set forbid_unkown_fields=True for Pydantic models that use the `extra="forbid" config

Depends on #3690. Don't merge before that one :)

Labels

do not merge, pr/internal

woven tundra
#

Some DTO enhancements, allowing to configure how unknown fields are handled, model specific dynamic configuration, and support for Pydantic's extra="forbidden" config flag

#

@supple ferry I think you're going to like this πŸ™‚

wicked abyss
woven tundra
#

Yeah. Well.. It's not that big of a deal, but it would be nice

cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
#

@snow sapphire Started working in improving the JWT situation

#

More is coming

#

Keeping it backwards compatible for now, working with what we have, but I'm hoping to be able to introduce a more comprehensive JWT plugin that simplifies stuff before 3.0, so we can deprecate the old stuff

snow sapphire
wicked abyss
#

I asked that as a question πŸ™‚ not as a review item

but my understanding is, "sig types if its a guarded (TYPE_CHECKING) import"

the linked code sends a message that, this (sig types) is always needed

snow sapphire
woven tundra
snow sapphire
woven tundra
#

Great! I'll check it out

snow sapphire
cloud helmBOT
#

It's currently difficult to use the simpler signature_types syntax in plugins due to the potential of there being an exception raised during startup.

We should consider removing this entire section to keep the behavior consistent between signature_namespace and signature_types.

https://github.com/litestar-org/litestar/blob/238d26bab30afa1f852ef0d88830077aab77ba35/tests/unit/test_utils/test_signature.py#L159-L168

[!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.
Labels

Bug :bug:, Good First Issue, Refactor, area/signature

woven tundra
#

What exactly is the error behaviour here?

#

Or rather, why is it different between the two methods, and why does that make signature_types unusable?

snow sapphire
#

let's say that in advanced alchemy, I add UUID to the signature namespace (which we do). It's done as a helper to make it easier to use for the user

woven tundra
#

Oh

snow sapphire
#

but, let's say the user goes to do this again

woven tundra
#

Okay, I get it πŸ˜„

#

Yeah, makes sense

snow sapphire
#

I do this in quite a few places, actually

#

to make it so the user doesn't ahve to remember to add something to the namespace

woven tundra
#

How about we don't remove the check, but make it so that it doesn't check for the presence only, but checks if the name is present, but the value is different?

#

And only raises in that case

snow sapphire
#

But, even that is different behavior from signature_namespace, right?

#

it's an override when using signature_namespace

#

there's no way to get an exception when using it

woven tundra
#

I would expect there to be an error as well πŸ‘€

#

Wait, let me try something real quick

#

Hm. I can't seem to reproduce this behaviour? Can you share a snippet that raises the exception / shows the inconsistency?

#

Not that I don't believe you, I just want to understand what's going on, and I feel like I'm currently not 😬

snow sapphire
#

sure. gimme a few

woven tundra
#

Ah. I think I understand now

#

Hm. I guess to make it behave consistently we'd have to remove the exception when doing add_to_signature_namespace, and perform the check in resolve_signature_namespace

#

Altough I'm not sure if that's a good behaviour

snow sapphire
# woven tundra Ah. I think I understand now

from typing import Dict
from litestar import Litestar, get
from litestar.config.app import AppConfig
from litestar.plugins import InitPluginProtocol


class MyService:
    """My Service"""


@get("/", sync_to_thread=False)
def route_handler(name: str) -> Dict[str, str]:
    return {"hello": name}


class CLIPlugin(InitPluginProtocol):
    def on_app_init(self, app_config: AppConfig) -> AppConfig:
        app_config.signature_types.append(MyService)
        return app_config


app = Litestar(plugins=[CLIPlugin()], signature_namespace={"MyService": MyService}, route_handlers=[route_handler])
#

The app will not start configured like this

woven tundra
woven tundra
snow sapphire
#

I actually quite like the layering ability here

woven tundra
#

We remove the check from add_to_signature_namespace, and instead check in resolve_signature_namespace that, if an override exists, it's the same value?

snow sapphire
#

what is the reason for limiting the ability to just change the type totally on a controller if needed?

woven tundra
#

Same reason we have for the providers I guess? To prevent hard to track down bugs where something is implicitly overwritten

snow sapphire
#

yeah, it could definitely cause bugs

#

maybe we could just warn if it's different?

#

instead of raising an exception

woven tundra
woven tundra
snow sapphire
#

it's how I noticed the issue

woven tundra
#

😬

snow sapphire
#
  File "/home/cody/Code/Litestar/litestar/litestar/router.py", line 192, in __init__
    self.signature_namespace = add_types_to_signature_namespace(
  File "/home/cody/Code/Litestar/litestar/litestar/utils/signature.py", line 266, in add_types_to_signature_namespace
    raise ImproperlyConfiguredException(f"Type '{name}' is already defined in the signature namespace")
litestar.exceptions.http_exceptions.ImproperlyConfiguredException: 500: Type 'MyService' is already defined in the signature namespace
#

is the error you get

woven tundra
#

okay so: Warning in resolve_signature_namespace if you overwrite a name with a different type?

snow sapphire
snow sapphire
wicked abyss
snow sapphire
woven tundra
cloud helmBOT
woven tundra
#

@severe onyx πŸ™‚

severe onyx
woven tundra
#

That was the intention, yes πŸ˜›

#

Can't think of a good use case for adding a middleware and then completely disabling it, so I think the warning is reasonable, right?

severe onyx
#

yes definitely

woven tundra
#

Feel free to review an approve if you think it can go in πŸ™‚

severe onyx
#

ha I though I did it

#

ok done

woven tundra
#

πŸ™‚

severe onyx
#

back on track with my SessionAuth protecting myself like it should

snow sapphire
#

@woven tundra re: the logger message. I feel like the warning is more than likely incorrect in these cases. I think having a logger message draw attention to it allows for proper debugging, but doesn't pollute the production logs

snow sapphire
cloud helmBOT
#

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.

Labels

area/docs, area/plugins, pr/internal, size: medium, type/feat

snow sapphire
#

Can we get it merged before we release today?

woven tundra
#

If not, let's delay the release?

#

No rush there really

snow sapphire
#

Yeah, there’s no major reason to release today.

woven tundra
cloud helmBOT
woven tundra
#

Small fix for a regression introduced in a recent JWT PR

woven tundra
cloud helmBOT
#

Customise the automatic verification of JWTs.

  • βœ… Config to verify aud
  • βœ… Config to verify iss
  • βœ… Config to verify iat
  • βœ… Config to verify nbf
  • βœ… Config for strict aud verification
  • βœ… Config for required claims
  • βœ… Update ocumentation

JWT backend changes

  • Add accepted_audiences field
  • Add accepted_issuers field
  • Add require_claims field
  • Add verify_expiry field
  • Add verify_not_before field
  • Add strict_audience field

JWT middleware changes

  • Add token_audience` parameter
  • Add token_issuer parameter
  • Add require_claims parameter
  • Add verify_expiry parameter
  • Add verify_not_before parameter
  • Add strict_audience parameter

Token changes

  • Add audience parameter to Token.decode
  • Add issuer parameter to Token.decode
  • Add require_claims parameter to Token.decode
  • Add verify_exp parameter to Token.decode
  • Add verify_nbf parameter to Token.decode
  • Add strict_audience parameter to Token.decode
  • Add decode_payload method
Labels

area/docs, pr/internal, size: small, type/feat

woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
#

Fix some improperly constructed test cases, where annotated types were constructed as Annotated[str, annotated_types.LowerCase] instead of annotated_types.LowerCase[str], which lead to code that handled this incorrect case.

I stumbled across this during another refactor, where I wrote a correct test case that passed without this special code, while the old case was failing.

woven tundra
cloud helmBOT
#

Make the metadata extraction from type annotations more robust.

  • Remove "duck typing" approach of extracting metadata from arbitrary types if they have attributes that match metadata attributes we're interested in
  • Remove coupling to 3rd party libraries in core code (specifically Pydantic)
  • Fully move metadata extraction responsibilities to plugins

Supersedes #3308.
Fixes #3710.
Fixes #3656.

Labels

area/dependencies, area/dto, area/plugins, area/private-api, pr/internal, size: medium

woven tundra
#

<@&1084813023044173866> If you've got some time, please take a look at this one. It's a larger refactor of our metadata extraction / parsing logic, that cleans up some less pretty parts of our code πŸ™‚

woven tundra
cloud helmBOT
wicked abyss
woven tundra
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
#

πŸ™‚

woven tundra
# cloud helm

This lovely PR is also still looking for reviewers πŸ™‚

cloud helmBOT
#

pyproject.toml line 204

omit = ["*/tests/*", "*/litestar/plugins/sqlalchemy.py"]
wicked abyss
#

i dont think the pragma is at a file level

woven tundra
#

Ah, good point

#

Feel free to push into the branch

wicked abyss
#

not a review point, but why is that file using future imports?

woven tundra
#

idk. ruff did it? πŸ˜„

wicked abyss
#

ahh ok, I asked because there was (is?) an issue in AA where some types when imported dont work, since they are not available in runtime

woven tundra
#

Okay, then let's remove that

wicked abyss
#

i dont want to break your PR :p
I already did πŸ€¦β€β™‚οΈ

#

uhm, do we not use coverage py?

#

since we had an entry I assumed it was for that, but codecov has its own ignore list?

woven tundra
woven tundra
#

😬

#

But we don't really define stuff in there

snow sapphire
cloud helmBOT
woven tundra
cloud helmBOT
#

Allow customizing the schema key used for a component in the OpenAPI schema. The motivation is to give the user an escape hatch when we inevitably generate some less than pretty looking names for deeply nested types for the sake of uniqueness.

These supplied key are enforced to be unique, and it is checked that they won't be reused across different types.

  • Add a new schema_component_key to KwargDefinition and the Body and Parameter functions
  • Add a friendly error message when keys are not unique / reused across different types
Labels

area/openapi, area/params, area/private-api, pr/internal, size: small, type/feat

woven tundra
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
snow sapphire
cloud helmBOT
peak monolith
cloud helmBOT
snow sapphire
peak monolith
woven tundra
cloud helmBOT
wicked abyss
#

would the supress approach work?

#

you dont have to deal with the assignments

woven tundra
#

It would, but it's bad for performance, since it's inside a function that gets called very frequently

wicked abyss
#

true, its zero cost if no exception is raised, but not the other way (I think)

woven tundra
#

Even though the overhead of a single call is small in absolute numbers, since we call this for every type that has metadata attached to it, it does make a real difference

wicked abyss
woven tundra
#

You're still doing a lookup and going through the hoops of the import mechanism. Also, on <3.11, exception handlers have a non trivial overhead attached to them, even in case where the exception isn't raised

snow sapphire
cloud helmBOT
wicked abyss
peak monolith
peak monolith
snow sapphire
#

It looks like it's related to trio test using redis?

woven tundra
#

maybe it has something to do with the anyio upgrade from 4.4 to 4.5?

#

I'd remove the lockfile update from this PR

#

Probably unintentional?

snow sapphire
#

probably. I think i was trying to get my osx env working again

#

let me remove that change

#

yeah, i guess that was it

#

it solves it locally

woven tundra
#

Nice

#

Guess we'll need to check anyio compat then in a separate PR

snow sapphire
#

We also have some differences in what our version of mypy report vs the latest version

wicked abyss
snow sapphire
snow sapphire
cloud helmBOT
cloud helmBOT
snow sapphire
cloud helmBOT
peak monolith
peak monolith
peak monolith
peak monolith
snow sapphire
#

I'm trying to build docs and i'm getting this from our fix_missing_references script. Anyone have any pointers?

building [mo]: all of 0 po files
writing output... 
building [html]: all source files
updating environment: [new config] 46 added, 0 changed, 0 removed
reading sources... [100%] usage/placeholder
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
copying assets... copying static files... done
copying extra files... done
done
The name of the builder is: htmlution-guide .. reference/alembic/commands
Extension error (tools.sphinx_ext.missing_references):
Handler <function on_warn_missing_reference at 0x7ffb93e0ec00> for event 'warn-missing-reference' threw an exception (exception: module, class, method, function, traceback, frame, or code object was expected, got TypeVar)
make: *** [Makefile:139: docs] Error 2
cloud helmBOT
snow sapphire
peak monolith
cloud helmBOT
#

Description

  • Constraints should be hashable to handle downstream usage
  • Create Frozendict to hold constraints
  • Alternative approachs
    • Update to vendor in annotated-types-esque classes and change internal to support this and use factories per type to generate. This would be backwards breaking and hard to generate for a user.
    • Pass constraints separately or another way. Not sure if can do this and pass these to FieldMeta whilst not breaking exposed interface

Closes

drowsy thunder
cloud helmBOT
#

Fixes https://github.com/litestar-org/litestar/issues/3625

RateLimitMiddleware duplicate all RateLimit-* headers when handler cache is enabled because it's adding new rate limit headers to the new ones, instead of just updating their values.

Response header before

❯ curl -i http://localhost:8000/
HTTP/1.1 200 OK
date: Tue, 12 Nov 2024 06:50:18 GMT
server: uvicorn
content-type: text/plain; charset=utf-8
content-length: 2
ratelimit-policy: 10; w=60
ratelimit-limit: 10
ratelimit-remaining: -8
ratelimit-reset: -54
ratelimit-policy: 10; w=60
ratelimit-limit: 10
ratelimit-remaining: 0
ratelimit-reset: -49

Response headers after

❯ curl -i http://localhost:8000/
HTTP/1.1 200 OK
date: Tue, 12 Nov 2024 06:50:18 GMT
server: uvicorn
content-type: text/plain; charset=utf-8
content-length: 2
ratelimit-policy: 10; w=60
ratelimit-limit: 10
ratelimit-remaining: 0
ratelimit-reset: -49

Labels

Triage Required :hospital:, area/middleware, pr/external, size: small

snow sapphire
cloud helmBOT
snow sapphire
#

Finalizing a few edits now, but it should be ready to anyone to start taking a look

snow sapphire
snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
snow sapphire
wicked abyss
snow sapphire
#

Yeah. There are other fixes that can be used in the update

wicked abyss
#

I understand experimental can be features that go in without a major version
"future" can be stuff that wont

snow sapphire
wicked abyss
#

got it, I just felt having experimental and future in the same place might lead to confusion

snow sapphire
wicked abyss
#

experimental = non breaking (once stable can be in v2)
future = anything goes (once stable will be in v3)

snow sapphire
#

yeah, i think that's a cleaner explanation

wicked abyss
snow sapphire
#

it's because i changed the logic but forgot to change the test name

peak monolith
cloud helmBOT
# peak monolith Bump on https://github.com/litestar-org/polyfactory/pull/602 if anyone has time ...

Description

  • Constraints should be hashable to handle downstream usage
  • Create Frozendict to hold constraints
  • Alternative approachs
    • Update to vendor in annotated-types-esque classes and change internal to support this and use factories per type to generate. This would be backwards breaking and hard to generate for a user.
    • Pass constraints separately or another way. Not sure if can do this and pass these to FieldMeta whilst not breaking exposed interface

Closes

woven tundra
cloud helmBOT
# woven tundra WIP for a new multipart parser: https://github.com/litestar-org/litestar/pull/38...

Add a streaming multipart parser via the multipart lib.

This gives us:

  • Ability to stream large / larger-than-memory file uploads
  • Better / more correct edge case handling
  • Still good performance
Labels

area/connection, area/dependencies, area/kwargs, area/multipart, area/private-api, pr/internal, size: small, type/feat

woven tundra
#

@little valley fyi πŸ™‚

little valley
#

Nice! πŸ™‚

#

I'll have a look tomorrow

little valley
#

Nah, couldn't wait

woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
peak monolith
wicked abyss
cloud helmBOT
# wicked abyss https://github.com/litestar-org/litestar/pull/3878

Ref: ERROR: Ignored the following versions that require a different python version: 2.21.0 Requires-Python >=3.9

Labels

area/ci, pr/internal, size: small, type/bug

wicked abyss
#

This will anyways be short lived, since we are moving to UV (draft PR #3875)

woven tundra
wicked abyss
woven tundra
#

All good, just a quick rebase πŸ™‚

wicked abyss
woven tundra
#

The Python uv downloads is not equivalent to a regular CPython built

snow sapphire
#

And probably the note I left in the channel yesterday as well.

woven tundra
snow sapphire
#

The default pre-built python that it (uv), hatch, and pdm installs is built with specific optimizations that aren't available on older CPU models. This means that some x86 machines will raise an error when executing. I actually hit this on a standard cloud shape last week with 2 Intel Xeon CPUs.

woven tundra
#

Ah, that

#

Yes

wicked abyss
snow sapphire
#

It's not hatch though

wicked abyss
#

they all download from the same source?

snow sapphire
#

It's the same indygreg builds linked above

wicked abyss
snow sapphire
#

just add a nocover on that one line

woven tundra
#

The issue seems to be legit though?

snow sapphire
#

in that case, we should add some coverage?

woven tundra
#

Yup

snow sapphire
#

i was just saying that for the sake of this change. It's like 7 months old

#

but, coverage would be better

woven tundra
wicked abyss
#

not dismissing the issue, but has anyone used int enums?

woven tundra
#

Yes

#

πŸ˜›

wicked abyss
#

fair, though I havent really been using enums lately, moved to Literal

peak monolith
wicked abyss
wicked abyss
#

or move to uv? (maybe more effort to do it now)

peak monolith
#

Updated! I'd favour migrating to uv separately as this small (and admittedly short-lived) fix to fix state on main

wicked abyss
snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/litestar-htmx/pull/8

Description

There have been a number of complaints about circular dependencies with this package. This change make litestar only required for tests.

Litestar will be updated to have a minimum pin of 0.4.0 here.

Closes

Summary by Sourcery

Remove 'litestar' from the project dependencies, addressing circular dependency issues, and update the project version to '0.4.0'. Update the 'ruff-pre-commit' hook version in the pre-commit configuration.

Build:

  • Remove 'litestar' from the project dependencies in 'pyproject.toml', making it only required for tests.

Chores:

  • Update the version of the 'ruff-pre-commit' hook from 'v0.7.0' to 'v0.8.1' in the pre-commit configuration.
snow sapphire
snow sapphire
# cloud helm

I went ahead and merged this. All tests passed and we needed to get a release out with a correct LICENSE file.

peak monolith
cloud helmBOT
peak monolith
snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/307

Description

This PR allows you to resuse the existing DeclarativeBase subclasses with different metadata objects.

This enables better support for multi-database configurations with models targets for each specific database.

It:

  • Creates a singleton registry object that tracks Metadata's for models
  • uses the __bind_key__ syntax commonly found in flask-slqlalchemy and other SQLAlchemy libraries

As part of this, there are a few (minor) breaking changes:

  • The custom subclass for AlembicCommands has been removed. It is no longer required and will make things easier for fastapi integration
  • The Alembic configuration now longer has a template_metadata key

Closes

Labels

area/alembic, area/base, area/config, area/dependencies, area/docs, area/example-apps, area/litestar, pr/internal, size: medium, type/feat

cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/308

Description

This adds a configuration option to automatically enable an excpetion handler for Repository errors.

This will update the exception handler if you do not have one already configured for the RepositoryException class

Closes

Labels

area/ci, area/dependencies, area/litestar, pr/internal, size: medium, size: small, type/feat

cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/310

Description

The Litestar DTO has been enhanced with:

  • The SQLAlchemyDTOConfig's exclude, include, and rename_fields fields will now accept string or InstrumentedAttributes
  • DTO supports WriteOnlyMapped and DynamicMapped

Closes #306 and #250

Closes

Labels

area/litestar, pr/internal, size: small, type/feat

peak monolith
woven tundra
cloud helmBOT
# woven tundra Alright. This one is ready for review: https://github.com/litestar-org/litestar/...

Add a new websocket_stream route handler that supports streaming data to a WebSocket via an async generator.

@websocket_stream("/")
async def handler() -> AsyncGenerator[str, None]:
    yield str(time.time())
    await asyncio.sleep(.1)

This is roughly equivalent to (with some edge case handling omitted):

@websocket("/")
async def handler(socket: WebSocket) -> None:
  await socket.accept()

  try:
    async with anyio.task_group() as tg:
      # 'receive' in the background to catch client disconnects
      tg.start_soon(socket.receive)

      while True:
        socket.send_text(str(time.time()))
        await asyncio.sleep(.1)
  finally:
    await socket.close()

Labels

area/docs, area/handlers, area/private-api, pr/internal, size: medium, type/feat

woven tundra
cloud helmBOT
# woven tundra lil bugfix: https://github.com/litestar-org/litestar/pull/3902

Change the implementation of responses.File to be able to handle most fsspec implementation's mtime equivalent.

This is necessary because fsspec implementations do not have a standardised way to retrieve an mtime equivalent; Some report an mtime, while some may use a different key (e.g. Last-Modified) and others do not report this value at all.

Fixes #3899

Labels

area/response, size: small, type/bug

wicked abyss
woven tundra
#

Idk. It says so, but I can't actually view the report

#

re-running the workflow

wicked abyss
woven tundra
#

Got it

snow sapphire
#

New PR design

snow sapphire
cloud helmBOT
# snow sapphire I'm down to 3 remaining errors for Python 3.13 support. https://github.com/lite...

Description

This PR implements support for Python 3.13.

Note This release uses a pre-release version of msgspec built by the Litestar team. This is a drop in replacement until the official pre-built wheels are available.

Note Python 3.8 continues to be supported with the existing msgspec implementation, while all other versions perfer the pre-built litestar wheels.

Closes

Labels

area/ci, area/dependencies, area/docs, area/logging, pr/internal, size: medium, type/feat

snow sapphire
#

run this to reproduce: uv run --reinstall --python 3.13 pytest docs/examples tests -n auto

wicked abyss
#

thanks, will check

woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/3909

Remove the inclusion of the query-only properties allowEmptyValue and allowReserved in path, cookie, header parameter and response header schemas.

Fixes #3908

Labels

area/datastructures, pr/internal, size: small, type/bug

peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/625

Description

(polyfactory) ➜  polyfactory git:(perf-refactor-pydantic-imports) βœ— cat test.sh 
#!/usr/bin/env sh

.venv-fast/bin/python -m pip install -e . 
.venv-fast/bin/python -m pip install "pydantic<2.5.0"
.venv-slow/bin/python -m pip install -e . 
.venv-slow/bin/python -m pip install "pydantic==2.5.0"

.venv-slow/bin/python t.py
.venv-fast/bin/python t.py

with before and after this change

0.22203758300747722
0.1394521670008544
---
0.1482207500084769
0.13731049999478273

  • Explanation here is pydantic now performs dynamic imports in some cases so affects performance when using attrs from the module. By importing directly for common attributes we avoid this cost.

Closes

snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
peak monolith
cloud helmBOT
wicked abyss
cloud helmBOT
#

.pre-commit-config.yaml line 2

python: "3.12"
peak monolith
#

Ah hadn't saved that file so didn't commit... updated now! Good catch πŸ™‚

snow sapphire
cloud helmBOT
# snow sapphire Good news on the Python 3.13 front. https://github.com/litestar-org/litestar/pu...

Description

This PR implements support for Python 3.13.

Note

  • This release uses a pre-release version of msgspec built by the Litestar team. This is a drop in replacement until the official pre-built wheels are available.
  • Python 3.8 continues to be supported with the existing msgspec implementation, while all other versions prefer the pre-built litestar wheels.
  • There are no Python 3.13 prebuilt wheels for psycopg[binary]. If you rely on this for development, you'll need to have the postgres development libraries installed
  • picologging does not currently support Python 3.13. These tests are skipped automatically.

Closes

Labels

area/ci, area/dependencies, pr/internal, size: small, type/feat

snow sapphire
# cloud helm

@woven tundra Looks like we are good to go on the asyncio PR. I'm about opdate the dep and then i think we should be good to merge 3.13 support

woven tundra
#

Looks good to go I think

#

Approved the PR

#

Let's do a release once that's out?

snow sapphire
#

merged

woven tundra
#

Perfect

#

I don't have time to prepare the release rn, I think I can get to it on the weekend

#

But I wouldn't mind if someone else picks itup as well πŸ™‚

snow sapphire
woven tundra
#

Yeah... That doesn't work.. Obviously πŸ˜„

#

Why do we need them?

wicked abyss
snow sapphire
#

i've got a fix incoming

wicked abyss
#

wont this just fail at later point on windows though?

#

when it tries to install psycopg

cloud helmBOT
#

.github/workflows/ci.yml line 148

python-version: "3.12"
wicked abyss
#

that should be changed

#

if not, then it would just run the tests on 3.12, for which wheels are indeed present

#

unless I am misunderstanding this

snow sapphire
#

it won't fail if the tests are run from 3.12

#

it'll install the binaries

wicked abyss
#

but isnt the expectation to run the tests on the latest python version for these non ubuntu hosts?

snow sapphire
#

double check the test results. I think it shows what you want. We only want the compat test to run on 3.12 right now

wicked abyss
#

approved, will check the runner

snow sapphire
#

once more quick approval. This just installs the psotgres client libraries in osx and windows and then runs the tests for the compat against 3.13

#

I just merged this one. I'm going to have a go at preparing the release

#

@woven tundra the newer version of pytest asyncio wants us to set the default loop runtime. I think it's causing some flaky test failure right now, but. the fix is to just re-run, i think.

snow sapphire
snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/3900

Experimental branch. Very much work in progress.

Basic idea is this: Instead of mutating handlers in place, treat them as static configuration objects. Once the handler tree has been collected, reduce all the layers into a single handler by recursively merging them.

Why? The idea is that this design is much less error prone and easier to follow (e.g. a lot of things currently need to happen in a specific order, otherwise they'll break). It also supports a pattern we're using in a few places now (websocket listeners + stream), where you essentially want to replace the handler with a new one. Another benefit is that this can get rid of all the deep copying we're currently doing :)

Goals

  • βœ… "Merge" handlers instead of setting ownership layers
  • βœ… Move all routing functionality from Router to Litestar instance
  • βœ… Remove (deprecate) unnecessary resolve_ methods
  • βœ… Remove ownership layer API completely
  • βœ… Remove deepcopying of route handlers during registration
  • ◻️ Extract common handler config into config objects (dataclasses), so they're easier to merge / manipulate
  • ◻️ Make route handlers purely static by removing all in-place mutation

I've decided to strike the last two goals, as it would make a migration path forward needlessly complex. With the removal of the now deprecated functionality in 4.0, this will be a lot easier to achieve, and we're still in a much better place with this than before.

Labels

Breaking πŸ”¨, area/asgi, area/connection, area/controller, area/dependencies, area/di, area/docs, area/dto, area/handlers, area/kwargs, area/layers, area/openapi, area/private-api, area/router, area/testing, area/types, pr/internal, size: large, type/feat

woven tundra
#

<@&1084813023044173866> I've decided to go ahead with this one despite not achieving all the goals I've set. In the interest of not introducing too many breaking changes in fundamental behaviour, I think it's best if we wait with these until 4.0

drowsy thunder
cloud helmBOT
# drowsy thunder hey <@396519450905673730> can you check this? https://github.com/litestar-org/l...

Description

litestar.contrib.attrs was moved to litestar.plugins.attrswas in https://github.com/litestar-org/litestar/pull/3862 but still being used in code and gives warnings

Closes

Labels

Triage Required :hospital:, pr/external, size: small

drowsy thunder
#

Oops πŸ˜…

peak monolith
cloud helmBOT
chrome girder
cloud helmBOT
chrome girder
peak monolith
wicked abyss
peak monolith
wicked abyss
wicked abyss
peak monolith
#

By recreate, do you mean delete existing release? I think this is required to remove existing git tag

wicked abyss
#

if you do know of a different way, then do go ahead with that πŸ™‚ I don't think you have to skip a version just for this

peak monolith
wicked abyss
#

done πŸ™‚ thanks for the work you do with polyfactory πŸ”₯

wicked abyss
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/3982

While fixing #3912 I noticed we only unwrap these partially. However, I am not sure if unwrapping them at all is proper, because of a particular edge case: They can be self-referential. This is used e.g. in pydantic.JsonType.

SelfReferential = TypeAliasType("Outer", Union[Annotated[int, "meta"], list["Outer"]])

This type can be understood by e.g. mypy, but is hard to parse for our typing system since we want to extract the metadata from the Annotated, but need to keep the outer TypeAliasType, so the self-referencing works in later stages (e.g. Pydantic).

I'm not entirely sure how we should best handle this, as our typing system has fundamentally different requirements than that of the 3rd party tools we rely on.

Divergences in how self-referential types are treated by these tools further complicates things.

For example, this is fine in Pydantic:

import pydantic

type Foo = int | list[Foo]

class SomeModel(pydantic.BaseModel):
    a: Foo

SomeModel.model_validate_json('{"a": 1}')

But msgspec raises a RecursionError:

import msgspec

type Foo = int | list[Foo]

class SomeStruct(msgspec.Struct):
    a: Foo

msgspec.json.decode('{"a": 1}', type=SomeStruct)

Not really sure yet how to proceed, I'll have to think about this a bit. I'd be happy about some input though @litestar-org/members

woven tundra
#

<@&1084813023044173866> if you've got some time to spare, I'd appreciate your input on the above PR. I've hit a bit of a wall with how Litestar should handle cases described above, so I'd be happy about some external input πŸ™‚

wicked abyss
woven tundra
#

No, just me not writing the test properly πŸ™‚

peak monolith
woven tundra
cloud helmBOT
# woven tundra I've created a proposal for a new middleware pattern: https://github.com/litest...

Add a new base middleware class to facilitate easier configuration and middleware dispatching.

The new ASGIMiddleware features the same functionality as the AbstractMiddleware, but makes it easier to pass configuration directly to middleware classes without a separate configuration object, allowing to get rid of the DefineMiddleware pattern entirely.

Labels

area/docs, area/middleware, area/private-api, pr/internal, size: small, type/feat

woven tundra
woven tundra
cloud helmBOT
peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/648

Description

  • Update prettier precommit by vendoring in now archived hook and specifying prettier version here.
  • This allows specifying version to one that will be supported by runners. This does have the downside of not being updatable via pre-commit autoupdate
  • Also in this PR, update other pre-commits and linting fixes required from updates

Closes

woven tundra
cloud helmBOT
# woven tundra Small change to our CI that allows us to have a dynamic test matrix: https://git...

Add an 'aggregate' step that fails if one of the matrix jobs from the test job fail, so we can target this aggregate job as "required check" instead of the individual matrix jobs.

This allows us to e.g. have a 3.8 matrix job on one branch but not on the other, while still making the run fail if any of the matrix jobs fails.

Labels

area/ci, pr/internal, size: small

woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4025
  • Add SerializationPlugin to replace SerializationPluginProcotol
  • Add InitPlugin to replace InitPluginProtocol

These are the only ones for which the protocols don't have a non-protocol equivalent.

Following the same approach as for other plugins, they inherit their respective protocol for now, to keep type / isinstance checks compatible.

Labels

area/channels, area/docs, area/openapi, area/plugins, area/private-api, pr/internal, size: medium, type/feat

woven tundra
cloud helmBOT
woven tundra
#

Sphinx does not like the stdlib docs.. πŸ˜„

snow sapphire
woven tundra
#

Nope!

snow sapphire
#

ohh. we just removed the protocol in 3.0

woven tundra
#

We should have done this switch ages ago. CLIPlugin has been around forver πŸ˜…

snow sapphire
#

perfect

#

thx

woven tundra
snow sapphire
#

I think i need to go through all of our plugins and do this

woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4028

Remove the deprecated SerializationPluginProtocol for v3.0.

We need to do a release of 2.15 first, so we can upgrade AA accordingly to the new SerializationPlugin.

Labels

area/dependencies, area/docs, area/plugins, area/private-api, pr/internal, size: medium, size: small, type/feat

woven tundra
cloud helmBOT
woven tundra
#

Sorry for the spam, I've got a bit of time on my hands and want to move v3 forwards πŸ™‚

woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
# woven tundra Hotfix for an issue introduced in the latest release: https://github.com/litesta...

Fix a bug introduced in #3996 that would incorrectly issue a deprecation warning if a user subclassed a Litestar built-in middleware which itself subclasses AbstractMiddleware.

Fix consists of checking the mro to ensure we're only warning if the subclass has AbstractMiddleware as a direct ancestor within the user code.

Fix #4035

Labels

area/middleware, pr/internal, size: small, type/bug

woven tundra
peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/652

Description

  • This PR simplifies pytest plugin and improves ergonomics of usage
  • Current implementation returns the pytest fixture then uses a registry to expose usage.
  • The new implementation injects the fixture into the caller scope so the returned object is the factory itself. This allow direct usage of factory and simplified usage

Closes

peak monolith
cloud helmBOT
severe onyx
cloud helmBOT
chrome girder
cloud helmBOT
# chrome girder https://github.com/litestar-org/litestar/pull/4045

Description

Closes

https://github.com/litestar-org/litestar/issues/4044

Labels

Triage Required :hospital:, area/events, pr/external, size: small

snow sapphire
cloud helmBOT
snow sapphire
#

And then this one that should be merged after the one above

cloud helmBOT
# snow sapphire https://github.com/litestar-org/litestar/pull/4051

Implements a granian installation group similar to the uvicorn or standard group. This group auto-installs litestar-granian and necessary performance enhancements.

Additionally, the latest linting rules were applied after upgrading the project depedencies

Labels

area/contrib, area/dependencies, area/docs, area/private-api, pr/internal, size: medium, type/feat

snow sapphire
cloud helmBOT
snow sapphire
#

I think we have everything done for 1.0

mental quarry
peak monolith
#
GitHub

Description

See title

Closes
Fixes #658

GitHub

Description

This updates the typing of create_factory so bound is with specified model if provided
Previously bound was the factory itself only so bound of returned factory was wrong
Also adds arg...

shell wrenBOT
#

Edit this to change the output of the custom command 1!

peak monolith
woven tundra
peak monolith
peak monolith
woven tundra
woven tundra
woven tundra
woven tundra
#

@signal linden @severe onyx I finally found it!

#

That was a wild ride πŸ˜„

#

Thanks @severe onyx for setting me on the right path with this πŸ™‚

severe onyx
#

Love the method

woven tundra
#

Well sometimes you just have to do a brute-force binary search by hand! πŸ˜„

severe onyx
#

it just shows dichotomy is still powerful

peak monolith
peak monolith
peak monolith
woven tundra
snow sapphire
snow sapphire
woven tundra
snow sapphire
severe onyx
#

there is still some work for docs and stuff but I think I adressed your comments @woven tundra https://github.com/litestar-org/litestar/pull/4055 . one thing I dont like though DX-wise is that user needs to put middleware in correct orders, I need to find an example, probably when using sessions but if you pass one before the other it will fail I think, and I dont remember if we hold developper's hand enough in that case, but at least now everyting is passed through middleware=[blablabla]

GitHub

WIP
The middlewares are currently mostly based on either MiddlewareProtocol, AbstractMiddleware or AbstractAuthenticationMiddleware .
Their usage is spread around a few places:

using some kwags on...

#

well minus another coverage hit I introduced...well back on the blackboard

woven tundra
#

one thing I dont like though DX-wise is that user needs to put middleware in correct orders
Ah, so this might be a catch-22 then?

#

We need middleware priorities in order to support the PR that was, among other things, supposed to make it easier to enable middleware priorities? πŸ˜„

#

An option would be to simply merge your PR in this "brittle" state, or do some super basic middleware order checks, and then follow up with the middleware priorities?

severe onyx
#

well there is a priority right now, ie the order you passed them

#

but one can f** up and pass an outer one before

woven tundra
#

Yeah. But that's not guaranteed. Could be altered by a plugin for example. And it's something users need to be aware of

#

That's why I said brittle

severe onyx
#

yep, that's one of the reason for instance I put session in a plugin

#

it usueally requires 2 midleare and using it you're guaranteed to have it correctly

woven tundra
#

But we could, for example, do some basic sorting of the middlewares in the scope of this PR, e.g. when building the middleware stack, ensure a certain order

#

That would be kinda hacky, but at least not break things

severe onyx
#

yep, agreed

woven tundra
#

And then follow up with the proper priorities

severe onyx
#

it's so big and interleaved anyways I dont think there is a simple way to do it at once

#

at least now it's a little bit more consistent

#

or not depends on the pov lol

chrome girder
peak monolith
peak monolith
worldly onyx
snow sapphire
#

i suspect they'll run on their own, but just not as a unit

snow sapphire
cloud helmBOT
# snow sapphire This beast is ready for review finally: https://github.com/litestar-org/advanced...

Description

Implement a file data type that leverages obstore or fsspec. Supports any supported FSSpec or Obstore backend it including sftp, gcs, s3, local, and more.

Closes

Labels

area/alembic, area/base, area/config, area/dependencies, area/docs, area/exceptions, area/fastapi, area/flask, area/litestar, area/private-api, area/repositories, area/sanic, area/services, area/unit-tests, pr/internal, size: large, type/feat

snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
# snow sapphire Also, tests are passing for this one now, but i want to play around with it befo...

Description

This PR implements a "Multi-Filter" Filter type.

It allows:

  • Create a collection of filters from an input
  • Allows filters to be groups with and/or logic

It includes 3 implementations:

  • The default JSON parameter based config
  • A TanStack Table optimized class
  • An AG Grid search filter

Closes

Labels

area/filters, pr/internal, size: small, type/feat

snow sapphire
# cloud helm

This one takes a multiple filters as an input and translates to the actual filters. @summer harbor this should be a logical extension from the sample you provided long ago. I've also tried to add in TanTable and AGGrid adapters so that it automatically accepts data in those specific formats (maybe this gets pulled before merging, not sure of the value here)

snow sapphire
snow sapphire
cloud helmBOT
chrome girder
cloud helmBOT
# chrome girder https://github.com/litestar-org/litestar/pull/4086

Description

In the logger configuration, users can specify a set of status codes and exception types for which Litestar will not log the full stack trace.

Closes

#4081

Example

import uvicorn

from litestar import Litestar, get
from litestar.logging import LoggingConfig


@get("/")
def index() -> str:
    return "Hello, world!"


@get("/value-error")
def value_error() -> None:
    raise ValueError("This is a test value error.")  # not log the stack trace


@get("/name-error")
def name_error() -> None:
    raise NameError("This is a test name error.")


app = Litestar(
    route_handlers=[index, value_error, name_error],
    debug=True,
    logging_config=LoggingConfig(
        disable_stack_trace={404, ValueError}  # disable_stack_trace: set[Union[int, type[Exception]]]
    ),
)


if __name__ == "__main__":
    uvicorn.run(app=app, port=8621)


Labels

Triage Required :hospital:, area/logging, pr/external, size: small

chrome girder
summer harbor
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4089
  • Fix #4088 by handling the diverging TypeAliasType introduced in typing-extensions 4.13.0; This type is no longer backwards compatible, as it is a distinct new type from typing.TypeAliasType. We need to check for both types now
  • Add a new test job to the CI to test against known diverging versions of typing-extensions
Labels

area/ci, pr/internal, size: small, type/bug

woven tundra
cloud helmBOT
snow sapphire
cloud helmBOT
chrome girder
cloud helmBOT
cloud helmBOT
summer harbor
severe onyx
severe onyx
#
GitHub

Description

use literalinclude and move to the examples folder.
simplified the customization

page to check is https://docs.litestar.dev/latest/usage/security/abstract-authentication-middleware.ht...

GitHub

Description

this renames most /docs/examples/request_data files adding a test_ prefix
thus the make test-examples command take them into account
tests have been added

Closes
Fixes #2940

GitHub

Description

used literalinclude as well

Closes
fixes #3189

woven tundra
#

You've been busy!

snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/687 Edit: running into some bu...

Description

  • This PR automates some of the release process by create changelog and release commit
  • This adds bump-my-version to align with other litestar repos and updates git-cliff command to use gh auth to allow running without specifying token
  • Alternative approaches would be porting release script from other repos. Omitting this for now to avoid restructuring too much but happy to adopt those if preferable

Closes

peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/688

Description

  • This PR aims to simplify helpers by making deterministic. Currently there is parsing on Union within here and also in factory itself
  • This removes random throughout and deprecates these and deprecates now unused functions
  • This does change behaviour of unwrap_annotated by removing Union handling there. Is this ok or can try refactoring to keep the current behaviour until v3?

Closes

snow sapphire
cloud helmBOT
woven tundra
cloud helmBOT
woven tundra
cloud helmBOT
peak monolith
peak monolith
severe onyx
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4148

Fix a bug where a dependencies' cleanup was not guaranteed to be called would not be called if an exception was thrown:

  • Late during ASGI response rendering
  • During cleanup of another dependency when recovering from an exception

Refactor the code such that:

  • Exceptions are always caught and thrown into dependencies as long as the dependencies are alive
  • If the handler raises an exception and during dependency cleanup other exceptions are raised, the sub-exceptions are grouped into an ExceptionGroup. This behaviour is now equivalent to regular dependency cleanup
Labels

area/dependencies, area/docs, area/kwargs, area/private-api, size: small, type/bug

peak monolith
cloud helmBOT
# peak monolith Bump on this https://github.com/litestar-org/polyfactory/pull/688

Description

  • This PR aims to simplify helpers by making deterministic. Currently there is parsing on Union within here and also in factory itself
  • This removes random throughout and deprecates these and deprecates now unused functions
  • This does change behaviour of unwrap_annotated by removing Union handling there. Is this ok or can try refactoring to keep the current behaviour until v3?

Closes

woven tundra
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4160

Add a new attribute_accessor property to AbstractDTO, which can be used by both the codegen and functional backend to access attributes on an object.

This can be useful to implement DTOs for types that do not adhere to the plain protocol of obj.data_field or need to add additional checks, e.g. using obj.related_field.all() on a Django model to access related objects, while ensuring no I/O occurs.

woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4167

Add a constraints framework for middlewares. These constraints can be defined on middleware classes / instances, and will be checked once the middleware stack for a handler have been resolved.

Currently implemented checks are:

  • Any 'A' must come before any 'B'
  • Any 'A' must come after any 'B'
  • Middleware must be at the top of the stack
  • Middleware at the bottom of the stack
  • Middleware must be unique in the stack

All checks take into account the class hierarchy, so Any 'A' must come before any 'B' actually means Any type, subclass or instance of 'A' must come before any type, subclass or instance of 'B'.

Setting constraints is only supported on ASGIMiddleware, but constraints referring to other middleware, may refer to any middleware type (class, instance or factory function). In addition, constraints referring to other middleware may to so by providing a string reference, which will be resolved at runtime. ImportErrors can optionally be skipped here, making it possible for a constraint to only apply if e.g. a specific 3rd party library is installed.

Documentation and some cleanup is missing, I'm mainly looking for some early feedback.

Labels

area/handlers, area/middleware, area/types, size: small, type/feat

woven tundra
#

@severe onyx finally got something done πŸ™‚

#

Thanks for being a great sparring partner on the design of this!

severe onyx
severe onyx
#

its hard

woven tundra
#

😬

#

Well. It's one of the downsides I mention

severe onyx
#

Im kinda debating with myself for 30min on the 1st test

#

rewriting and rewriting comments ...

#

it may entirely be just me though I tend more and more to struggle on things like this

woven tundra
severe onyx
#

test_check_middleware_constraints

woven tundra
#

Oh, that one. That's the integration test. Did you go over the tests in tests/unit/test_middleware/test_constraints.py already?

severe onyx
#

intuitively I would have said this should raise

#

shouldnt

#

because M2 on app level should be automatically before M1 on handler

#

or they are evaluated from center of onion to its exterior ?

woven tundra
#

Ah

#

Okay, I see how this can be confusing

#

One detail you have to keep in mind is that the middleware stack is reversed

#

So the first middleware you define, is the last one in the stack. Because they're being wrapped, if you want the "first" one (i.e. the one closest to the handler) to apply last in the chain, you need to wrap the ASGI callable first with it

woven tundra
#

So

@get("/", middleware=[MiddlewareOne()])
async def handler() -> None:
    pass

 Litestar([handler], middleware=[MiddlewareTwo()])
``` if you ask the handler about the middleware, it will return `MiddlewareOne`, `MiddlewareTwo`
severe onyx
#

im gonna take a pen and pper

woven tundra
#

Maybe this is also an indicator that the error messages aren't that great? Looking at the code, I can see how "MiddlewareOne before MiddlewareTwo" can be ambiguous

#

Because you essentially define the middleware stack in the reverse order it's resolved

severe onyx
#

ok so befre for you is before in the resolution not in the layering which is reversed

woven tundra
#

The "before" and "after" refer to the order of the layering (i.e. the stack), not the order the middlewares are applied in

severe onyx
#

ok that's why

woven tundra
#

Yeah, it's confusing

#

Hmm

severe onyx
#

i was rewriting and rewritig

#

now it makes sense but so the naming could be better

#

resolved_after, resolved_before ?

woven tundra
#

I was too focused on the stack, didn't event think about this

severe onyx
#

I get that's why Im here palying the dumb user

woven tundra
#

The only issue with that is, then error messages become confusing

#

How about we flip the stack completely for the ordering checks? Then it would match the order the middlewares are applied in, but not the order they're wrapped (which you could argue is an implementation detail)

woven tundra
#

And maybe reword the exception, so instead of All instances of 'MiddlewareTwo' must come before any instance of 'MiddlewareOne', it would say All instances of 'MiddlewareTwo' must apply before any instance of 'MiddlewareOne'?

#

Because the "come before" could be a bit ambiguous

#

The only downside I see there is debugging. If we'd report a constraint violation of a middleware, and that it's at index 0, if you look at the resolved stack, you'd see it's actually at -1

severe onyx
#

best I can say is idk....

woven tundra
severe onyx
#

can we detect where it faults ? in that example if we say somehting like: , M2 has a before M1 contraint but handler resolves as M1, M2

#

I just mean giving an explantion is maybe the solution

woven tundra
#

We can and we do

severe onyx
#

oh ok I ran the test and didnt see

woven tundra
#

Well, we don't give the full stack back (bc it could be too big I thought), but we do report the indices of the middlewares that are in violation of the constraint(s)

#

And we do say All instances of 'MiddlewareTwo' must come before any instance of 'MiddlewareOne'

severe onyx
#

ok my bad then, it's probably just me reading the test, the match *

#

ok ok I'll get back to it more concentrated

woven tundra
#

Should probably include the rest of the message there as well now tho

severe onyx
#

I think it would be valuable

#

just forthe review, sorry

woven tundra
#

I pushed a change @severe onyx. I think that should make things easier to follow

#

You now define the stack "top down", i.e. the first middleware on the app is at 0, and the last middleware on a handler is at -1

#

I've also added more comment

severe onyx
#

Thanks, I'm going to give it another go this afternoon

woven tundra
#

Thanks for the feedback πŸ™‚

severe onyx
# woven tundra Thanks for the feedback πŸ™‚

done πŸ™‚
I think I may have some work to do once that is merged πŸ₯Έ ....if others can take a look too that would be cool to be fair, this is not that complex but still requires some concentration and some more eyes are always beneficial imho

woven tundra
#

I think I may have some work to do once that is merged
We can finally get your middleare refactoring thing in then πŸ™‚

peak monolith
cloud helmBOT
peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/703. This was satisfying to cle...

Description

  • Note target of this is new release candidate. Will aggregate changes there
  • Remove all usage of deprecated param and remove related code
  • Other changes notable
    • Add _init_model internal method. Used for rebuilding pydantic and setting check model true as some things need to be rebuilt after initialising factory but before checking.
    • Updating tests that relied on default behaviour
  • One bit now unsure of is setting SQLAlchemy.__set_association_property__ to True as default. This seems to fail with relationships so tempted to default to False.

Closes

snow sapphire
cloud helmBOT
peak monolith
peak monolith
peak monolith
cloud helmBOT
peak monolith
peak monolith
peak monolith
cloud helmBOT
peak monolith
#

I'm going to merge the above shortly to unblock the release and bugs there and these have been test. Happy to follow up with any changes if need

peak monolith
frosty slate
cloud helmBOT
frosty slate
#

ty for the review. although i guess @signal linden, the publish CI failed during changelog generation.

#

doesn't block me but just fwiw. also i'll probably try revitalizing your uv PR, as i find pdm to be rather sad

peak monolith
signal linden
peak monolith
#

Thanks!

peak monolith
frosty slate
frosty slate
#

oh dope nvm. didn't see the approval

signal linden
cloud helmBOT
woven tundra
cloud helmBOT
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/512/files

Fixed regression where service.create() method stopped handling relationship data correctly when passed SQLAlchemy model instances. Changed model_from_dict() in _util.py to use __mapper__.attrs.keys() instead of __mapper__.columns.keys() to include relationship attributes alongside column attributes.

  • Use attrs.keys() to include both columns and relationships
  • Add comprehensive tests for relationship handling in model_from_dict
  • Verify unknown attributes are still ignored
Labels

area/private-api, area/repositories, pr/internal, size: small, type/bug

snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/523

Ensure that the IdentityPrimaryKey correctly generates IDENTITY DDL across multiple database dialects, including PostgreSQL, Oracle, and SQL Server. Update dependencies and add tests to verify the functionality.

Labels

area/dependencies, area/mixins, pr/internal, size: small, type/bug

snow sapphire
cloud helmBOT
chrome girder
cloud helmBOT
cloud helmBOT
cloud helmBOT
snow sapphire
cloud helmBOT
cloud helmBOT
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4289

MethodNotAllowedException exceptions raised during routing did not include the Allow header, which must be present in a 405 Method Not Allowed response.

Fixes #4277.

Labels

area/private-api, pr/internal, size: small, type/bug

woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4291

Introduce new async-native testing utilities:

  • AsyncTestClient
  • AsyncWebSocketTestSession
  • LifespanHandler
  • TestClientTransport

And synchronhous equivalents:

  • TestClient
  • WebSocketTestSession
  • SyncTestClientTransport

The test utilities are not async-first, meaning the implementation is async, and when using the synchronous versions, they will be bridged using anyios BlockingPortal, whereby they run the async code within a new thread + event loop.

This design removes various barriers and pitfalls, mainly dealing with multiple event loops when running tests asynchronously (e.g. avoiding nested event loops). It also simplifies the code quite a bit and brings a minor speedup when running async tests.

There is currently one issue stemming from a fundamental incompatibility between pytest-asyncio and anyio.CancelScope, https://github.com/pytest-dev/pytest-asyncio/issues/1191, but I'm working on a fix towards this, with a proof-of-concept already in place, so I think it's not a blocker.

Fixes #1920

Labels

area/docs, area/private-api, area/testing, area/types, size: medium, type/feat

woven tundra
#

@severe onyx managed to get it working and I'm quite happy with the result

peak monolith
severe onyx
peak monolith
cloud helmBOT
peak monolith
cloud helmBOT
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4293

Add DTO support for union types that contain composite types and nested models, e.g. list[SomeModel] | None or SomeModel | list[SomeModel].

The limit of this support is when multiple composite types are introduced to the union, e.g. list[str] | dict[str, str] | SomeModel]. The reason for that being that it's not particularly simple to generate code that can handle these generally, and checks which case has been encountered. Doing so comes dangerously close to type checking :grimacing: So instead, we simply bail if we cannot perform our checks with a simple isinstance, type or is check.

Fixes #4273

Labels

area/dto, area/private-api, pr/internal, size: small, type/feat

snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/litestar/pull/4298

After the most recent updates to rich-click and click, CLI plugins no longer show the command in the command help text.

This is because the plugin was not loaded before rending the help text. This change ensures that the plugins are loaded prior to formatting the help output.

Labels

area/private-api, pr/internal, size: small, type/bug

snow sapphire
cloud helmBOT
# snow sapphire Third time's the charm? https://github.com/litestar-org/litestar/pull/4340

Summary

This PR completes the deprecation and migration of SQLAlchemy functionality from Litestar v3.0. Following the approach from PR #4225, both litestar.contrib.sqlalchemy and litestar.plugins.sqlalchemy modules have been completely removed. Users must now import directly from advanced_alchemy.extensions.litestar.

Related Issues/PRs

  • Closes #4163 - Second removal attempt
  • Related to #4225 - Previous near-perfect implementation (out of sync with master)
  • Related to #4069 - Initial removal attempt by @provinzkraut
  • Related to #3755 - Original deprecation PR

Breaking Changes

BREAKING CHANGE: All SQLAlchemy functionality has been removed from Litestar.

Migration Guide

  • from litestar.contrib.sqlalchemy import X β†’ from advanced_alchemy.extensions.litestar import X
  • from litestar.plugins.sqlalchemy import Y β†’ from advanced_alchemy.extensions.litestar import Y
  • from litestar.plugins.sqlalchemy.base import Z β†’ from advanced_alchemy.extensions.litestar.base import Z

Changes Made

  • Complete Module Removal:

    • Removed entire litestar/contrib/sqlalchemy/ directory tree
    • Removed litestar/plugins/sqlalchemy.py re-export file
  • Documentation Updates: Updated all example files to use advanced_alchemy.extensions.litestar imports

  • Test Updates:

    • Updated all tests to use new import paths
    • Deleted tests for deprecated functionality that no longer exists
  • Clean Architecture: No re-export layer in Litestar - direct imports from advanced-alchemy only

  • Changelog: Added breaking change entry explaining the migration

Technical Implementation

This implementation follows the cleaner approach from PR #4225:

  • No re-export layers - users import directly from advanced_alchemy.extensions.litestar
  • Complete separation of concerns - Litestar no longer maintains SQLAlchemy code
  • Single source of truth - advanced-alchemy is the sole provider of SQLAlchemy integration

Benefits

  • Cleaner separation - Litestar doesn't maintain SQLAlchemy code
  • Single source of truth - advanced-alchemy is the only place for SQLAlchemy integration
  • Easier maintenance - No need to keep re-export layers in sync
  • Clear dependency - Users know they need advanced-alchemy for SQLAlchemy support

Testing

  • βœ… All tests pass
  • βœ… Type checking pa...
Labels

Breaking πŸ”¨, area/docs, area/plugins, pr/internal, size: large, type/feat

snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/litestar/pull/4343

Summary

Adds deprecation warning for the litestar.plugins.sqlalchemy module which will be removed in v3.0.

Context

  • Related to #4340 which removes this module in v3
  • Follows deprecation policy to warn users before removal
  • Part of the ongoing migration to advanced-alchemy

Changes

  • Add module-level deprecation warning to litestar.plugins.sqlalchemy
  • Add test for deprecation warning

Migration Path

Users should update their imports:

# Old (deprecated)
from litestar.plugins.sqlalchemy import SQLAlchemyPlugin

# New
from advanced_alchemy.extensions.litestar import SQLAlchemyPlugin

Labels

area/plugins, pr/internal, size: small, type/feat

woven tundra
woven tundra
cloud helmBOT
# woven tundra https://github.com/litestar-org/litestar/pull/4372

Middlewares inheriting from ASGIMiddleware will now have zero runtime cost when they are excluded e.g. via the scope or exclude_opt_key options.

Previously, the base middleware was always being invoked for every request, evaluating the exclusion criteria, and then calling the user defined middleware functions. If a middleware had defined scopes = (ScopeType.HTTP,), it would still be called for every request, regardless of the scope type. Only for requests with the type HTTP, it would then call the user's function.

With zero cost exclusion, the exclusion is being evaluated statically. At app creation time, when route handlers are registered and their middleware stacks are being built, a middleware that is to be excluded will simply not be included in the stack.

I've marked this change as breaking, even though no runtime behaviour difference is expected. Some test cases may break though if they relied on the fact that the middleware wrapper created by ASGIMiddleware was always being called, e.g. if using a mock or trying to observe side-effects of this behaviour.

Labels

Breaking πŸ”¨, area/dependencies, area/docs, area/middleware, area/private-api, size: small, type/feat

woven tundra
snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/litestar/pull/4340 Can I get a review on this o...

Summary

This PR completes the deprecation and migration of SQLAlchemy functionality from Litestar v3.0. Following the approach from PR #4225, both litestar.contrib.sqlalchemy and litestar.plugins.sqlalchemy modules have been completely removed. Users must now import directly from advanced_alchemy.extensions.litestar.

Related Issues/PRs

  • Closes #4163 - Second removal attempt
  • Related to #4225 - Previous near-perfect implementation (out of sync with master)
  • Related to #4069 - Initial removal attempt by @provinzkraut
  • Related to #3755 - Original deprecation PR

Breaking Changes

BREAKING CHANGE: All SQLAlchemy functionality has been removed from Litestar.

Migration Guide

  • from litestar.contrib.sqlalchemy import X β†’ from advanced_alchemy.extensions.litestar import X
  • from litestar.plugins.sqlalchemy import Y β†’ from advanced_alchemy.extensions.litestar import Y
  • from litestar.plugins.sqlalchemy.base import Z β†’ from advanced_alchemy.extensions.litestar.base import Z

Changes Made

  • Complete Module Removal:

    • Removed entire litestar/contrib/sqlalchemy/ directory tree
    • Removed litestar/plugins/sqlalchemy.py re-export file
  • Documentation Updates: Updated all example files to use advanced_alchemy.extensions.litestar imports

  • Test Updates:

    • Updated all tests to use new import paths
    • Deleted tests for deprecated functionality that no longer exists
  • Clean Architecture: No re-export layer in Litestar - direct imports from advanced-alchemy only

  • Changelog: Added breaking change entry explaining the migration

Technical Implementation

This implementation follows the cleaner approach from PR #4225:

  • No re-export layers - users import directly from advanced_alchemy.extensions.litestar
  • Complete separation of concerns - Litestar no longer maintains SQLAlchemy code
  • Single source of truth - advanced-alchemy is the sole provider of SQLAlchemy integration

Benefits

  • Cleaner separation - Litestar doesn't maintain SQLAlchemy code
  • Single source of truth - advanced-alchemy is the only place for SQLAlchemy integration
  • Easier maintenance - No need to keep re-export layers in sync
  • Clear dependency - Users know they need advanced-alchemy for SQLAlchemy support

Testing

  • βœ… All tests pass
  • βœ… Type checking pa...
Labels

Breaking πŸ”¨, area/docs, area/plugins, pr/internal, size: large, type/feat

woven tundra
woven tundra
#

@snow sapphire fixed all the outstanding issues, should be good to go now. Only a weird linting blip that's not just affecting your branch..

woven tundra
snow sapphire
woven tundra
#

Yup. Big one!

#

@snow sapphire just fyi, I've put all the docs back in place (well, back and moved out of the contrib section). Dunno if you've left some of them out intentionally or not, just felt like it's the most sensible thing to do

#

We can migrate them to the AA docs at any point, we'd just have to add a redirect page into the Litestar docs then

snow sapphire
snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/pytest-databases/pull/99

Summary

Fixes a RuntimeError: generator raised StopIteration that prevented the BigQuery emulator fixture from starting Docker containers. This issue affected BigQuery tests and could potentially impact other database services under certain conditions.

Root Cause

The error occurred in _service.py:188 where next() was used without a default value inside a @contextmanager generator function:

host_port = int(
    container.ports[next(k for k in container.ports if k.startswith(str(container_port)))][0]["HostPort"]
)

When no matching port key was found, next() raised StopIteration. Since Python 3.7+, StopIteration inside a generator is converted to RuntimeError, causing the cryptic error message.

Changes

1. Enhanced retry loop (lines 178-182)

  • Before: container.reload() called after checking ports
  • After: container.reload() called before checking ports
  • Why: Ensures fresh port bindings are available on each retry iteration

2. Safe port lookup with exact-key matching (lines 187-196)

  • Before: Used next() with startswith() pattern matching
  • After: Uses explicit dict.get() with exact protocol keys ("9050/tcp", "9050/udp")
  • Benefits:
    • Eliminates StopIteration exceptions
    • Avoids false positives (e.g., "80" matching "8080/tcp")
    • Provides descriptive error messages showing available ports
    • Uses RuntimeError for consistency with fixture setup failures
snow sapphire
#

@woven tundra can you take a look? I'm having some random issues with tests hanging in some cases, and I tracked it down to this.

woven tundra
#

Fix looks reasonable, just one comment about where things should go

snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/567 i've got a few PRs qu...

Introduce a structured agent workflow and comprehensive development guides for the AI agent based development. This includes detailed instructions for agents, directory structures for requirements, and updates to existing documentation.

Labels

area/dependencies, area/docs, pr/internal, size: large

snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/574

Summary

Fixes #514 - Resolves InvalidRequestError when deleting objects with auto_expunge=True and auto_commit=True enabled.

Problem

Repository methods delete(), delete_many(), and delete_where() would fail with InvalidRequestError: Instance <Model> is not present in this Session when both auto_expunge=True and auto_commit=True were enabled.

The root cause was that the code attempted to expunge objects after they had already been deleted and committed. Once a transaction containing deletions is committed, SQLAlchemy automatically moves deleted objects to the detached state, removing them from the session. Attempting to expunge these already-detached objects raises an error.

Solution

Added a state check in the _expunge() method to skip expunge for deleted objects:

state = inspect(instance)
if state is not None and state.deleted:
    # Object will be automatically detached when transaction commits
    # Skip expunge to avoid InvalidRequestError
    return None

This fix:

  • βœ… Checks object state before attempting expunge
  • βœ… Skips expunge for deleted objects (they're auto-detached on commit)
  • βœ… Maintains backward compatibility
  • βœ… Works for all three delete methods
  • βœ… Works across all database backends
  • βœ… Includes comprehensive tests

Changes

Modified Files

  • advanced_alchemy/repository/_async.py - Added state check in _expunge() method
  • advanced_alchemy/repository/_sync.py - Auto-generated sync version
  • tests/unit/test_repository_delete_expunge.py - New unit tests validating the fix

Testing

  • 6 unit tests covering various scenarios
  • Tests for both async and sync repositories
  • Validates deleted object handling
  • Validates non-deleted object handling
  • Tests with auto_expunge enabled/disabled

Verification

# Run unit tests
uv run pytest tests/unit/test_repository_delete_expunge.py -v

# Verify lint passes
make lint

# Verify type checking passes
make type-check

Related Issues

Fixes #514

Labels

area/private-api, area/repositories, pr/internal, size: small, type/bug

snow sapphire
cloud helmBOT
# snow sapphire <@547139124667351061> https://github.com/litestar-org/advanced-alchemy/pull/569

Summary

Implements complete API parity with Alembic 1.16.5 CLI by adding 9 missing commands and completing the stamp command with all options.

Resolves #566, #568

Changes

New Commands ✨

  • check - Verify pending migrations
  • edit - Edit revision with $EDITOR
  • ensure-version - Create version table (supports --sql)
  • heads - Show current heads (supports --verbose, --resolve-dependencies)
  • history - Show revision history (supports --verbose, --rev-range, --indicate-current)
  • merge - Merge revisions (supports -m/--message, --branch-label, --rev-id, --no-prompt)
  • show - Show specific revision details
  • branches - Show branch points (supports --verbose)
  • list-templates - List available Alembic templates

Enhanced Commands πŸ”§

  • stamp - Added missing options: --sql, --tag, --purge

Testing βœ…

  • 67 total tests (25 unit + 42 integration)
  • All commands tested with edge cases
  • Both sync/async configurations
  • Multiple database backends

Documentation πŸ“š

  • Updated CLI reference with all commands
  • Added usage examples and use cases
  • Changelog entry added

Related Issues

  • #568 - Python 3.9 template compatibility (separate issue)
Labels

area/alembic, area/dependencies, area/docs, pr/internal, size: medium, type/feat

snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/573

Summary

Fixes a closure bug where multiple fields in in_fields and not_in_fields arrays resulted in only the last field working correctly. This was caused by loop variables being captured by reference rather than by value in nested function definitions.

Problem

When configuring multiple filter fields like this:

dependencies = providers.create_service_dependencies(
    MyService,
    "my_service",
    filters={
        "in_fields": [
            providers.FieldNameType("type", str),
            providers.FieldNameType("status", str),
        ],
    },
)

Result:

  • GET /api/endpoint?typeIn=value β†’ ❌ FAILED (no filter generated)
  • GET /api/endpoint?statusIn=value β†’ βœ… SUCCESS (only last field works)

This silent failure caused incorrect query results as filters were ignored.

Root Cause

Classic Python late-binding closure issue: all closures created in the loop captured the same loop variable field_def by reference. After the loop completed, all functions referenced the final value of field_def.

Solution

Uses default parameter values to capture the loop variable by value:

def create_in_filter_provider(
    field_name: FieldNameType = field_def,  # βœ… Captures by value
) -> Callable[..., Optional[CollectionFilter[Any]]]:
    ...

This ensures each closure has its own independent copy of the field definition.

Changes

Litestar Provider (advanced_alchemy/extensions/litestar/providers.py):

  • Fixed create_not_in_filter_provider closure (lines 508-512)
  • Fixed create_in_filter_provider closure (lines 537-541)

FastAPI Provider (advanced_alchemy/extensions/fastapi/providers.py):

  • Fixed create_not_in_filter_provider closure (lines 575-581)
  • Fixed create_in_filter_provider closure (lines 610-616)

Testing

βœ… Existing tests validate the fix:

  • test_litestar_openapi_schema - Tests multiple fields in both arrays
  • test_openapi_schema_comprehensive - Validates all filter parameters generated
  • test_multiple_filters_aggregation - Verifies filter combinations work

All CI checks passing (Python 3.9-3.13, mypy, pyright, SonarCloud).

Impact

  • Severity: Critical - Silent data filtering failures
  • Scope: Any user with multiple fields in in_fields or not_in_fields arrays
  • Compatibility: No breaking changes, backward compatible
  • Performance: No performance impact (fix at DI setup time)

Fixes #507

Labels

area/docs, area/litestar, pr/internal, size: small, type/bug

snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/575

Summary

Fixes #555

This PR fixes a bug in the Service layer's update() method where dict, Pydantic, msgspec, and attrs data bypassed the to_model() operation map, preventing custom to_model() implementations from being invoked during update operations.

Problem

The Service layer provides a documented pattern for customizing data transformation during CRUD operations via the to_model() method and its operation-specific hooks (to_model_on_create, to_model_on_update, etc.). However, the update() method had inconsistent implementation:

Before (Buggy):

  • Dict data: Called to_model_on_update() directly β†’ bypassed to_model()
  • Pydantic/msgspec/attrs data: Called schema_dump() β†’ bypassed both to_model() and to_model_on_update()
  • Model instance data: Correctly called to_model(data, "update") βœ“

After (Fixed):

  • ALL data types: Call to_model(data, "update") first
  • to_model() internally routes to to_model_on_update() via operation_map
  • Matches the pattern used in create() which always calls to_model(data, "create")

Changes

  • update() now calls to_model(data, "update") FIRST for ALL data types
  • Ensures custom to_model() implementations receive operation="update" parameter
  • to_model_on_update() still called via operation_map routing (backward compatible)
  • Uses SQLAlchemy inspect to only copy explicitly set attributes to existing instance
  • Preserves existing instance when item_id provided (maintains relationships and db-managed fields)
  • Both async and sync variants updated (sync auto-generated via unasyncd)

Testing

  • βœ… All existing attrs service tests pass (including partial update with NOTHING values)
  • βœ… All existing sqlquery service tests pass
  • βœ… Both async and sync variants tested
  • βœ… Linting, mypy, and pyright checks pass

Backward Compatibility

This fix is backward compatible:

  • Users with only to_model_on_update() implemented: No change (still works via operation_map)
  • Users with custom to_model() expecting operation parameter: Now works correctly (bug fixed)
  • Users who never override service methods: No change
  • Method signature unchanged
  • No breaking changes to public API

User Impact

Positive Impact:

  • Users building custom services with specialized update logic who override to_model() expecting the operation parameter will now have their code work as documented
  • Consistency across all CRUD operations (create, update, upsert, delete)
Labels

area/private-api, area/services, pr/internal, size: small, type/bug

peak monolith
cloud helmBOT
peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/720

Description

what's included

  • @adhtruong

refactor!: remove deprecated elements (https://github.com/litestar-org/polyfactory/pull/703[)f%5D(https://github.com/litestar-org/polyfactory/pull/720/commits/1eaede178ab42ea60e90b439040500ab2264ad89)

Notes

Closes

Closes https://github.com/litestar-org/polyfactory/issues/668

snow sapphire
snow sapphire
snow sapphire
snow sapphire
snow sapphire
#

Also, this is pretty much ready to merge: https://github.com/litestar-org/sqlspec/pull/128

it's a bit of a beast in terms of changes, and i've been testing it locally, so i don't think a complete review is needed. but this is just in case and an fyi

snow sapphire
snow sapphire
#

Can i get a few eyeballs on the following?

https://github.com/litestar-org/advanced-alchemy/pull/585
https://github.com/litestar-org/advanced-alchemy/pull/580

I'd like to merge them today or tomorrow if possible

GitHub

Summary
Adds support for SQLAlchemy func() expressions in filter classes to eliminate type checker errors when using database functions like func.random() or func.lower().
Closes #519
The Problem
T...

GitHub

Previously save/delete failures were only logged, so callers believed commits succeeded when storage ops had already failed.
Sync commit: processes saves sequentially, then deletes. Logs failures w...

snow sapphire
snow sapphire
#

it's a segfault somewhere, i think

#

(leaving support in, just disabling the tests)

cloud helmBOT
snow sapphire
#

well maybe that wasn't it

peak monolith
peak monolith
peak monolith
cloud helmBOT
# peak monolith https://github.com/litestar-org/polyfactory/pull/781

Description

  • This adds support to use BaseModel.model_validate(..., by_name). This unblocks use cases where the model names are not valid python identifiers
  • Set to False for backwards compatibility but may want to change this to true in future major release

Closes

snow sapphire
cloud helmBOT
peak monolith
snow sapphire
cloud helmBOT
snow sapphire
cloud helmBOT
# snow sapphire https://github.com/litestar-org/advanced-alchemy/pull/611

Summary

This PR completes the implementation of SQLAlchemy inheritance pattern support in CommonTableAttributes, enabling proper handling of Single Table Inheritance (STI), Joined Table Inheritance (JTI), and Concrete Table Inheritance (CTI).

Changes

Core Implementation (advanced_alchemy/base.py)

  • Added __init_subclass__ hook (lines 209-277):

    • Detects STI children by checking if any parent has polymorphic_on in their __mapper_args__
    • Automatically sets cls.__tablename__ = None for STI children
    • Handles both explicit (with polymorphic_identity) and implicit (without) STI children
    • Properly distinguishes between base classes and child classes
  • Enhanced @declared_attr.__tablename__() method (lines 281-386):

    • Returns None for explicitly set None values (set by __init_subclass__)
    • Provides fallback STI detection for cases where parent doesn't have explicit tablename
    • Generates snake_case table names for non-STI classes

Supported Patterns

  • βœ… Single Table Inheritance (STI):

    • Child classes with polymorphic_identity share parent's table
    • Works with both auto-generated and explicit parent table names
    • Handles edge case of children without polymorphic_identity (with warning)
  • βœ… Joined Table Inheritance (JTI):

    • Child classes with explicit __tablename__ create joined tables
    • Proper foreign key relationships maintained
  • βœ… Concrete Table Inheritance (CTI):

    • Child classes with concrete=True create independent tables
    • No foreign keys to parent table

Related Issues

Supersedes PR #600

Labels

area/base, pr/internal, size: small, type/bug

peak monolith
peak monolith
signal linden
#

πŸ€”

snow sapphire
#

I am sorry for the flood of review requests that are incoming. I'll highlight the important ones to prioritize for review.

snow sapphire
peak monolith
snow sapphire
#

If anyone is around for a quick review. I'm hitting this on a few things

snow sapphire
snow sapphire
#

@woven tundra I had to make a few tweaks on the tests to make things work with pytest 8

#

but i've retargeted mongo and yugabyte to be based off this merge

snow sapphire
snow sapphire
#

we need to merge them in the order above as the gizmosql fixtures fix some pytest 9 issues

snow sapphire
snow sapphire
snow sapphire
#

If anyone is aroudn for a quick review

#

I'm going to trigger a beta release of Advanced Alchemy soon, and this should make that much easier.

signal linden
#

i gotchu

snow sapphire
snow sapphire
snow sapphire
#

it's docs and one new ruff rule modification

snow sapphire
#

This change overhauls the docs and integrates Sybil testing for the code snippets in them

#

it also finishes the sanic, flask, starlette, litestar and fastapi docs

woven tundra
#

<@&1084813023044173866> fyi

peak monolith
chrome girder
heavy pasture
snow sapphire
snow sapphire
glad pebble
heavy pasture
snow sapphire
snow sapphire
snow sapphire
snow sapphire
snow sapphire
#

https://github.com/litestar-org/litestar/pull/4691

this fixes a deprecation warning from OTEL, moves to plugins, and updated docs. I'll create a PR to cherry pick the changes + a deprecation warning for the 2.0 branch after it merges.

GitHub

Description
This PR moves the OpenTelemetry module from litestar/contrib/opentelemetry to litestar/plugins/opentelemetry. This is part of the larger OTEL redesign (Chapter 1).
Key Changes

Module M...

snow sapphire
snow sapphire
snow sapphire
snow sapphire
snow sapphire
snow sapphire
#

Each has a follow-up issue for the a v2 deprecation followup PR.

chrome girder
snow sapphire