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.
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.
Shouldn't it be ASGIApp instead of Starlette?
There was a problem hiding this comment.
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.
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.
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} |
|
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.