-
-
Notifications
You must be signed in to change notification settings - Fork 948
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
objects defining async __call__ not run/awaited when used in on_startup #886
Comments
not sure about that but seems like on_startup expects a list of callables, |
An instance of
Explicitly specifying |
@cjw296 An immediate workaround: wrap your callable object into a function? class Foo:
async def __call__(self):
raise Exception()
foo = Foo()
async def on_startup():
await foo()
app = Starlette(on_startup=[on_startup])
with TestClient(app) as client: # Raises `Exception`.
pass The long-term solution would be to fix the detection of async functions in the lifespan logic to something like: # In an utils module
def iscoroutinefunction(obj):
if inspect.iscoroutinefunction(obj):
return True
if hasattr(obj, '__call__') and inspect.iscoroutinefunction(obj.__call__):
return True
return False
# routing.py
if iscoroutinefunction(func):
await func()
else:
... # Sync, defer to threadpool. Not sure where that's in the codebase exactly, but it should do the trick. |
Yeah, agreed on both fronts, but this almost feels like a deficiency in python itself; it feels like there should be an |
Sure, some even wish async callable would have been defined as objects that have an |
Turns out this issue also affects partial: @tomchristie suggested Starlette should grow its own function to make these checks, once that's happened, we should see about pushing it back into CPython core. |
@cjw296 Maybe you can look at this function, it has enough judgment. https://github.com/abersheeran/index.py/blob/master/indexpy/concurrency.py#L9 |
TBH I'd be quite keen to moving Starlette towards always expecting an Users could still use sync style functions, but we'd require them to be explicitly wrapped in a threadpooling |
Always async in Starlette make sense. Handling this in apps built on top of Starlette is probably the right place, letting Starlette focus on being async, and potentially more helpfully, throwing exceptions when it gets sync stuff by mistake. @abersheeran - with that in mind, here's the function I currently have: |
@tomchristie +1 on that, Starlette is explicitly an async framework, and allowing sync functions seems wrong. We could add a decorator or something that uses |
Hi all, I am facing same issues when using BackgroundTasks object for my awaitable and callable object, so is there any enhancement for this case detection? Like the solution from @florimondmanca.
I am willing to enhance this in BackgroundTasks . |
@tomchristie wondering how you feel about this nowadays? I this moving to an async only or at least more explicit paradigm could also help with rough edges like #1258 |
Simple reproducer:
No exception is raised when it should be. This, however, raises an exception as expected:
The text was updated successfully, but these errors were encountered: