Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for generator factories #28

Closed
cfxegbert opened this issue Jul 31, 2024 · 5 comments
Closed

Add support for generator factories #28

cfxegbert opened this issue Jul 31, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@cfxegbert
Copy link

I want to do something like the following:

@service
def create_transaction() -> Iterator[Transaction]:
    transaction = Transaction()
    try:
        yield transaction
    finally:
        transaction.commit()

and also an async version:

@service
async def create_transaction() -> AsyncIterator[Transaction]:
    transaction = Transaction()
    try:
        yield transaction
    finally:
        await transaction.commit()
@maldoinc
Copy link
Owner

maldoinc commented Aug 3, 2024

Hi @cfxegbert, generator factories are not currently supported.
Coincidentally I have an experimental branch which accomplishes exactly what you're describing at least for the sync version.

In the meantime what you're describing can be accomplished in the following way:

@service
class TransactionManager:
    # pull whatever dependencies to create transaction
    def __init__(self) -> None:
        pass

    @contextlib.contextmanager
    def create_transaction(self) -> Iterator[Transaction]:
        transaction = Transaction()
        try:
            yield transaction
        finally:
            transaction.commit()

    @contextlib.asynccontextmanager
    async def create_async_transaction() -> AsyncIterator[Transaction]:
        transaction = Transaction()
        try:
            yield transaction
        finally:
            await transaction.commit()


@container.autowire  # may be omitted if using flask or fastapi integrations
def some_view(txn_manager: TransactionManager):
    with txn_manager.create_transaction() as txn:
        txn...

@cfxegbert
Copy link
Author

That will work at the method level but for my situation I need it for the class/service level. You were correct in that my example was a per request example. My real situation is a singleton with an application lifetime. There are other ways to implement it but it just does not feel as clean.

@maldoinc
Copy link
Owner

Yeah, I understand what you're trying to do. The issue right now is that even tough the container can inject async functions it cannot create things that require async directly given that the container is synchronous.

It's definitely on the radar and something that will come in the near future.

@maldoinc maldoinc added the enhancement New feature or request label Aug 11, 2024
@maldoinc
Copy link
Owner

@cfxegbert If this is still relevant for you, support for this has landed in master.

For now supports only sync factories (async coming soon) and works for both singletons and transient scopes. I'll do some more tests and perform a release.

In the meanwhile you can test the development version by using pip install git+https://github.com/maldoinc/wireup.git.

@maldoinc
Copy link
Owner

Closing this as v0.12.0 supports async generators as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants