-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Alternative lifespan state api #2065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alternative lifespan state api #2065
Conversation
This reverts commit da6461b.
ec2eafa to
4e5ec27
Compare
|
What you are proposing is to not add the What you mention about the PEP-696 can still be done without this PR getting in. |
4e5ec27 to
5e36c4c
Compare
Yes. I think that's pretty reasonable.
Yes it can but with the current API you can't really use a type in your lifespan which I think makes it a bit less interesting. (well you can, but you'd be doing something like |
5e36c4c to
14fd988
Compare
|
I'm against not supporting If you'd like, we can revert the two previous commits (implementation, and docs), and discuss a bit more about what we want to do. I'll personally not be in favor of removing or not supporting |
We could always add that later, with the current API... |
Kludex
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only documentation is missing here, and we can go with it. 👍
| StatelessLifespan = typing.Callable[["Starlette"], typing.AsyncContextManager[None]] | ||
| StatefulLifespan = typing.Callable[ | ||
| ["Starlette"], typing.AsyncContextManager[typing.Mapping[str, typing.Any]] | ||
| ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be ASGIApp instead of Starlette?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well we always pass in a Starlette object right? What good does it do to receive a reference to a generic ASGIApp object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about FastAPI when I asked that, when the super() is called on Router, they will have an issue over there, I guess? Also, because this module has ASGI related types.
In any case, not that important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah probably need a self: SelfType, lifespan: Lifespan[SelfType] or something. Or users can just cast it. Also I don't think there's any FastAPI specific methods they'd want to access from the lifepsan. And with this state thing there's almost no reason to even use the app argument anyway...
|
After this PR, we can deprecate
And maybe changing the name I can do this follow up, I just need this to be merged. 👍 |
|
I'm going to do a follow-up with the deprecation of @adriangb Please check #2065 (comment), and my last commit to see if you are fine with it. |
|
|
||
| async def lifespan(self) -> None: | ||
| scope = {"type": "lifespan"} | ||
| scope = {"type": "lifespan", "state": self.app_state} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@florimondmanca like this
|
It would be nice to give a way for users to have type hints on their request.state. There's an example in the Lifespan section of the starlette docs that uses a TypedDict, but inside your routes that doesn't offer you any type hints. It also doesn't make a lot of sense, since you're accessing attributes on state (state.count), which is not how you access fields of a dictionary (or TypedDict). I was just trying to give myself type hints by creating a subclass of Request, MyRequest, and using the MyState TypedDict as the type for its state attribute. This already required You could use a dataclass instead of a TypedDict, but the typing for the lifespan won't accept that. So it would be quite nice to have something like Request[MyState] which allows you to do this. |
The first commit reverts the current unreleased API, the second adds the proposed API. I can do the same thing for the docs.
I think one of the interesting things this opens up is that by having a concrete type for the user's state we could use https://peps.python.org/pep-0696/ in the future to do:
So users can fully type their use of state with minimal boilerplate:
Or if they are adding more keys to the request:
Or something like that.