Skip to content
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

Fixed - async __call__ not run/awaited in the BackgroundTask #1256

Closed
wants to merge 13 commits into from
10 changes: 8 additions & 2 deletions starlette/background.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import asyncio
import inspect
import typing

from starlette.concurrency import run_in_threadpool


def iscoroutinefunction(obj: object) -> bool:
if inspect.iscoroutinefunction(obj):
return True
return callable(obj) and inspect.iscoroutinefunction(obj.__call__)


class BackgroundTask:
def __init__(
self, func: typing.Callable, *args: typing.Any, **kwargs: typing.Any
) -> None:
self.func = func
self.args = args
self.kwargs = kwargs
self.is_async = asyncio.iscoroutinefunction(func)
self.is_async = iscoroutinefunction(func)

async def __call__(self) -> None:
if self.is_async:
Expand Down
20 changes: 20 additions & 0 deletions tests/test_background.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ async def app(scope, receive, send):
assert TASK_COMPLETE


def test_async_callable_task(test_client_factory):
TASK_COMPLETE = False

class async_callable_task:
async def __call__(self):
nonlocal TASK_COMPLETE
TASK_COMPLETE = True

task = BackgroundTask(async_callable_task())

async def app(scope, receive, send):
response = Response("task initiated", media_type="text/plain", background=task)
await response(scope, receive, send)

client = test_client_factory(app)
response = client.get("/")
assert response.text == "task initiated"
assert TASK_COMPLETE


def test_sync_task(test_client_factory):
TASK_COMPLETE = False

Expand Down