python-dependency-injector
python-dependency-injector copied to clipboard
The library can't handle async generators
Based on the example FastAPI + SQLAlchemy example from the documentation i made a myself implementation for work with connections of Async SQLA Core. But I came across the fact that your library does not support working with asynchronous generators. Could you please fix it somehow? Here, here's my code:
from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine
from src.app.config import AppConfig
class Database:
def __init__(self, config: AppConfig) -> None:
self._engine: AsyncEngine = create_async_engine(config.DB_DSN)
async def get_connection(self) -> AsyncConnection:
async with self._engine.begin() as connection:
yield connection
class Container(containers.DeclarativeContainer):
wiring_config = containers.WiringConfiguration(packages=["src.api"])
config = providers.Configuration(pydantic_settings=[AppConfig(_env_file=".env")])
app_cfg = config.get_pydantic_settings()[0]
logging = providers.Resource(dictConfig, get_logging_config(app_cfg))
db = providers.Resource(Database, config=app_cfg)
language_repository = providers.Factory(
repositories.LanguageRepository,
connection=db.provided.get_connection.call(),
)
...
I expect to get AsyncConnection, when initializing language_repository, but in fact I get <async_generator object Database.get_connection at 0x7ff63b913c40> for some reason. It seems that this should not be the case. I have to additionally do await anext(self._connection) in my repositories to get a live sqla connection. I also tried doing connection=db.provided.provided.get_connection.call().provided.__anext__.call(), but for some reason I get an inactive sqla connection which is impossible to work with.
I hit this as well, and I think that this is supposed to be a feature. You can avoid it by wrapping with a class or another object that is not a coroutine
I hit this as well, and I think that this is supposed to be a feature. You can avoid it by wrapping with a class or another object that is not a coroutine
I'm not sure I understand you. Could you use my example to show how it should look like in the code?
I hit this as well, and I think that this is supposed to be a feature. You can avoid it by wrapping with a class or another object that is not a coroutine
Why do you think this it's not a bug? It's clearly a bug!
Why do you think this it's not a bug? It's clearly a bug!
it's not. If you read the code you will see that they clearly do this intentionally.
I think the reason is probably something like:
Well if you are exectuting the fetching of a dependency, its not at all clear on which event loop the asynchronous call is supposed to execute. Often, you would want it to execute on the current event loop, but that may not always be the case.