Comments (5)
@melvinkcx Setting in_req_res_cycle
to False
is how I am currently getting around this and, while a bit hacky, it does work quite well.
My wrapper for dispatch()
looks something like this:
@contextmanager
def _force_fastapi_events_dispatch_as_task() -> Generator:
token: ContextVarToken = in_req_res_cycle.set(False)
yield
in_req_res_cycle.reset(token)
def dispatch(
event_name: Union[str, Enum],
payload: Optional[Any] = None,
validate_payload: bool = True,
payload_schema_cls_dict_args: Optional[Dict[str, Any]] = None,
payload_schema_registry: Optional[BaseEventPayloadSchemaRegistry] = None,
middleware_id: Optional[int] = None
as_task: bool = False,
) -> None:
if as_task:
with _force_fastapi_events_dispatch_as_task():
fastapi_events_dispatch(
event_name=event_name,
payload=payload,
validate_payload=validate_payload,
payload_schema_cls_dict_args=payload_schema_cls_dict_args,
payload_schema_registry=payload_schema_registry,
)
else:
fastapi_events_dispatch(
event_name=event_name,
payload=payload,
validate_payload=validate_payload,
payload_schema_cls_dict_args=payload_schema_cls_dict_args,
payload_schema_registry=payload_schema_registry,
)
from fastapi-events.
Hi @smithk86, thank you for reporting the issue and for your patience. I've been thinking about this issue.
When you said the actual work being done in an asyncio.Task
, do you mean you're create a task manually using asyncio.create_task()
?
from fastapi-events.
Do you know if there is any good way to tell when contextvars are being copied? Would you mind sharing it or pointing me to the resource? 🙏 thanks
from fastapi-events.
Below is a brief example of the route handler I was working on when I found this issue. The goal was to have the request start a long-running process but not have the client wait on the work being done. The results of the work would be published as an event.
To answer your question, the context (with contextvars) are being copied when asyncio.create_task()
is run. The context is used for the duration of the coroutine being called. Because of this, fastapi-events
believes it is executing within the context of a request when the request is actually done.
Cheers
Kyle
def add_data(data: DataModel):
"""
This function may take a while to complete
"""
dispatch("add_data_start", payload={"message": "starting"})
try:
await database.insert(data)
await app.reload_data()
except:
dispatch("add_data_error", payload={"message": "an error occurred"})
else:
dispatch("add_data_done", payload={"message": "complete"})
@app.post("/addData")
async def uuid(
data: DataModel,
):
"""
This request will return immediately for the client and then do the work in the background.
Events will be dispatched within the function/task once the work is complete.
"""
asyncio.create_task(add_data(data))
return {"detail": "add_data has been started"}
from fastapi-events.
thank you for the code sample. I can't think of a good general solution so far.
I would imagine a function that wraps asyncio.create_task
that would also unset is_req_res_cycle
at the same time, but that's not the best solution. 🤔
from fastapi-events.
Related Issues (20)
- Add a SNS Handler HOT 2
- Proposal - use asyncio for events management (Supporting Event Chaining) HOT 5
- Add GCP Cloud PubSub handler
- Catching exceptions of dispatched events HOT 1
- Trigger an event at startup HOT 3
- Add OpenTelemetry (OTEL) Support
- Providing AWS Credentials HOT 2
- Add Python 3.11 HOT 1
- Introduces NullHandler
- Support for Depends() HOT 8
- Starlette-Specific Test Cases Failing Since Starlette 0.24
- pydantic v2 import errors HOT 6
- pydantic v2 Warnings: The `dict` method is deprecated; use `model_dump` instead HOT 3
- Register event payload class and event in 1 HOT 8
- Update tox configuration to check compatibility with Python 3.12
- Pydantic models dumped to dict with deprecated method `dict` with pydantic v2 HOT 1
- Do not always dump pydantic models to dict
- docs: Update README with public API HOT 1
- TypeError with Synchronous Function in Dependencies When Using Local Handler HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fastapi-events.