mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 15:19:10 +02:00
75 lines
2.9 KiB
Text
75 lines
2.9 KiB
Text
---
|
|
title: async_utils
|
|
sidebarTitle: async_utils
|
|
---
|
|
|
|
# `fastmcp.utilities.async_utils`
|
|
|
|
|
|
Async utilities for FastMCP.
|
|
|
|
## Functions
|
|
|
|
### `is_coroutine_function` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/async_utils.py#L14" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
is_coroutine_function(fn: Any) -> bool
|
|
```
|
|
|
|
|
|
Check if a callable is a coroutine function, unwrapping functools.partial.
|
|
|
|
``inspect.iscoroutinefunction`` returns ``False`` for
|
|
``functools.partial`` objects wrapping an async function on Python < 3.12.
|
|
This helper unwraps any layers of ``partial`` before checking.
|
|
|
|
|
|
### `call_sync_fn_in_threadpool` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/async_utils.py#L26" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
call_sync_fn_in_threadpool(fn: Callable[..., Any], *args: Any, **kwargs: Any) -> Any
|
|
```
|
|
|
|
|
|
Call a sync function in a threadpool to avoid blocking the event loop.
|
|
|
|
Uses anyio.to_thread.run_sync which properly propagates contextvars,
|
|
making this safe for functions that depend on context (like dependency injection).
|
|
|
|
|
|
### `gather` <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/fastmcp_slim/fastmcp/utilities/async_utils.py#L53" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
gather(awaitables: Iterable[Awaitable[T]]) -> list[T] | list[T | BaseException]
|
|
```
|
|
|
|
|
|
Run awaitables concurrently and return results in order.
|
|
|
|
Uses anyio TaskGroup for structured concurrency.
|
|
|
|
``awaitables`` is consumed lazily, one item at a time, right before each
|
|
is handed to the task group. Callers with a dynamic number of awaitables
|
|
should pass a generator expression (e.g. ``gather(f(x) for x in xs)``)
|
|
rather than a list or list comprehension: a list comprehension calls
|
|
every ``f(x)`` up front, creating a batch of coroutine objects before
|
|
this function even starts, whereas a generator expression creates each
|
|
coroutine only as this function's own scheduling loop asks for it. That
|
|
matters because coroutine creation and scheduling can be interrupted
|
|
between any two bytecode instructions by a synchronous signal handler
|
|
(for example pytest-timeout's SIGALRM-based per-test timeout). If that
|
|
happens while a whole batch of coroutines is sitting unscheduled, they
|
|
are silently abandoned and eventually trigger a "coroutine was never
|
|
awaited" warning attributed to whatever unrelated code happens to be
|
|
running when the garbage collector gets to them. Lazy consumption keeps
|
|
the window in which a created-but-unscheduled coroutine can exist as
|
|
small as possible.
|
|
|
|
**Args:**
|
|
- `awaitables`: Iterable of awaitables to run concurrently.
|
|
- `return_exceptions`: If True, exceptions are returned in results.
|
|
If False, first exception cancels all and raises.
|
|
|
|
**Returns:**
|
|
- List of results in the same order as input awaitables.
|
|
|