ivankorobkov / python-inject

Python dependency injection
Apache License 2.0
671 stars 77 forks source link

Creating thread local instances #99

Closed etiennepvt closed 2 months ago

etiennepvt commented 2 months ago

Hello,

Love the simplicity of the package :)

I'm trying to simulate a request/thread scope behaviour. For instance : have the same DB Session throughout the http request in FastAPI.

I used the example of threading local from the README. I might be missing something, running the snippet result in not having any instance when using inject.params. I get that I should call set_user_default somewhere. I'd rather, have inject.params work just like when using the singletons from the global injector.

Is there a way to achieve this ? Maybe with a custom provider ?

ivankorobkov commented 2 months ago

Hi! Thanks

Well, I think request scopes can be divided into two parts. Something like this.

1) Setup/tear down request local variables:


_REQ = threading.local()

def handle_request(req):
    open_req_session()
    try:
        do_something(req)
    finally:
        close_req_session()

def open_req_session():
    _REQ.session = db.open_session()

def close_req_session():
    session = _REQ.session
    _REQ.session = None
    session.close()

2) Injecting request local variables.


@inject.params
def get_user(session: db.Session):
    pass

def get_req_session():
    return _REQ.session

inject.configure(lambda binder: 
    binder.bind_to_provider(db.Session, get_req_session))
etiennepvt commented 2 months ago

Ok I see. I'll start from there.

Thanks for the tips.