Comments (8)
Hi @melvinkcx. We are facing the same issue. The event handlers often need to have access to other services, like in this example where we want to inject sequelize session using fastapi di system.
@local_handler.register(event_name='dummy-event')
async def dummy_event_handler(event : Event, db : Session = Depends(get_db)):
# Do something with the db
return
from fastapi-events.
Thank you for your patience. I just released a new version (link) that includes the support of dependencies in local handlers. Feel free to report any potential issues 🙏
from fastapi-events.
@unkindypie @breathingcyborg Thanks for raising the request. I'm looking into the feasibility of supporting DI in LocalHandler
without introducing any breaking changes. If you already have an idea or a workaround you're currently using, feel free to share them =)
from fastapi-events.
@melvinkcx Thanks for looking into the issue.
As a workaround we created a custom decorator.
import inspect
from typing import Callable
from fastapi.dependencies.utils import get_dependant, solve_dependencies
from fastapi import Request
from contextlib import AsyncExitStack
from fastapi_events.typing import Event
from pydantic import ValidationError
def event_handler(path: str):
""" decorator to enable fastapi dependency injection
for fastapi_events event handlers
Usage Example:
@local_handler.register(event_name='event.test')
@event_handler(path='handlers.event.test.handle_test_event')
def handle_test_event(event: Optional[Event] = None, db: Session = Depends(get_db)):
# use db here
"""
def wrap(func: Callable):
async def wrap_inner(event: Event):
async with AsyncExitStack() as cm:
request = Request({
"type": "http",
"headers": [],
"query_string": "",
"fastapi_astack": cm
})
dependant = get_dependant(
path=path,
call=func
)
values, errors, _1, _2, _3 = await solve_dependencies(
request=request,
dependant=dependant
)
values['event'] = event
if errors:
raise ValidationError(errors, None)
if inspect.iscoroutinefunction(dependant.call):
result = await dependant.call(**values)
else:
result = dependant.call(**values)
return result
return wrap_inner
return wrap
And we use it like this
@local_handler.register(event_name='event.test')
@event_handler(path='handlers.event.test.handle_test_event')
def handle_test_event(event: Optional[Event] = None, db: Session = Depends(get_db)):
# use db here
pass
This is very hacky
- event must be the first argument and its value must be set to None
- and because other things like dummy request and asyncexitstack.
- also the path must be unique (not sure about this but I've read that fastapi caches dependencies)
from fastapi-events.
Thanks for your help. Although support for yield is not blocking for us, but it would be really helpful.
from fastapi-events.
Hi @unkindypie, I'm trying to understand the missing feature you're looking for here. Do you mean the events injected within the injected services are not working?
Do you mind providing a simple example of how you'd use it if it supports Depends()
? Thank you =)
from fastapi-events.
Thanks for sharing your workaround. I'm working on a PR to support Depends()
in local event handlers.
However, for the first version, there will be some limitations:
- Sub-dependencies will be supported
- Dependency caching is not supported
- Dependency override is not supported
- Dependencies using a generator (
yield
) are not supported (yet)
I figured the last point might be a blocker to some of you. Let me know if that's the case.
from fastapi-events.
Thank you @melvinkcx !
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
- Events are not received when dispatch() occurs in an asyncio.Task HOT 5
- Add Python 3.11 HOT 1
- Introduces NullHandler
- 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.