Files
fastapi/fastapi/concurrency.py
Sebastián Ramírez 0ac9b3ee5c Re-export utils from Starlette (#1064)
*  Re-export main features used from Starlette to simplify developer's code

* ♻️ Refactor Starlette exports

* ♻️ Refactor tutorial examples to use re-exported utils from Starlette

* 📝 Add examples for all middlewares

* 📝 Add new docs for middlewares

* 📝 Add examples for custom responses

* 📝 Extend docs for custom responses

* 📝 Update docs and add notes explaining re-exports from Starlette everywhere

* 🍱 Update screenshot for HTTP status

* 🔧 Update MkDocs config with new content

* ♻️ Refactor tests to use re-exported utils from Starlette

*  Re-export WebSocketDisconnect from Starlette for tests

*  Add extra tests for extra re-exported middleware

*  Add tests for re-exported responses from Starlette

*  Add docs about mounting WSGI apps

*  Add Flask as a dependency to test WSGIMiddleware

*  Test WSGIMiddleware example
2020-03-01 21:49:20 +01:00

48 lines
1.4 KiB
Python

from typing import Any, Callable
from starlette.concurrency import iterate_in_threadpool # noqa
from starlette.concurrency import run_in_threadpool # noqa
from starlette.concurrency import run_until_first_complete # noqa
asynccontextmanager_error_message = """
FastAPI's contextmanager_in_threadpool require Python 3.7 or above,
or the backport for Python 3.6, installed with:
pip install async-generator
"""
def _fake_asynccontextmanager(func: Callable) -> Callable:
def raiser(*args: Any, **kwargs: Any) -> Any:
raise RuntimeError(asynccontextmanager_error_message)
return raiser
try:
from contextlib import asynccontextmanager # type: ignore
except ImportError:
try:
from async_generator import asynccontextmanager # type: ignore
except ImportError: # pragma: no cover
asynccontextmanager = _fake_asynccontextmanager
try:
from contextlib import AsyncExitStack # type: ignore
except ImportError:
try:
from async_exit_stack import AsyncExitStack # type: ignore
except ImportError: # pragma: no cover
AsyncExitStack = None # type: ignore
@asynccontextmanager
async def contextmanager_in_threadpool(cm: Any) -> Any:
try:
yield await run_in_threadpool(cm.__enter__)
except Exception as e:
ok = await run_in_threadpool(cm.__exit__, type(e), e, None)
if not ok:
raise e
else:
await run_in_threadpool(cm.__exit__, None, None, None)