Skip to content

Ability to change contextvars in sync dependencies #953

@smagafurov

Description

@smagafurov

Sync dependencies now run in thread pool with starlette.concurrency.run_in_threadpool.

run_in_threadpool run in the context copy (contextvars.copy_context().run(...))

async def run_in_threadpool(
    func: typing.Callable, *args: typing.Any, **kwargs: typing.Any
) -> typing.Any:
    loop = asyncio.get_event_loop()
    if contextvars is not None:  # pragma: no cover
        # Ensure we run in the same context
        child = functools.partial(func, *args, **kwargs)
        context = contextvars.copy_context()  # <------------------ here
        func = context.run
        args = (child,)
    elif kwargs:  # pragma: no cover
        # loop.run_in_executor doesn't accept 'kwargs', so bind them in here
        func = functools.partial(func, **kwargs)
    return await loop.run_in_executor(None, func, *args)

But if we change contextvars inside dependency (func), this changes are lost. We don't see this changes in route func.

But I want to see this changes :)

May be we can propagate (copy) contextvars changes to main thread contextvars after dependency finish?

https://github.com/tiangolo/fastapi/blob/d91b2b3ee8fa428544769aba664aedbf9ed6511a/fastapi/dependencies/utils.py#L521

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions