reagento / dishka

Cute DI framework with agreeable API and everything you need
https://dishka.readthedocs.io
Apache License 2.0
420 stars 47 forks source link

click integration - provide options that translate into a context value #229

Open RonnyPfannschmidt opened 2 months ago

RonnyPfannschmidt commented 2 months ago

currently the click integration cannot pass options into the context easily

i'd like to be able to do something like the following (possibly with custom scopes)


import click
from dishka import make_container, from_context, Provider, 
from dishka.integrations.click import FromDishka, setup_dishka, dishka_option

UserName = NewType("Userame", str|None)

class Interactor:
   def __init__(self, user: Username):
      self.user = user
   def __call__(self):
       return self.user

class FunProvider(Provider)
   username = from_context(UserName)
   interactor = provide(Interactor)

@click.group()
@click.pass_context
def main(context: click.Context):
    container = make_container(FunProvider)
    setup_dishka(container=container, context=context, auto_inject=True)

@main.command()
@click.option("--count", default=1, help="Number of greetings.")
@dishka_option("--username", default=None, provides=UserName)
def hello(count: int, interactor: FromDishka[Interactor]):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo(f"Hello {interactor()}!")

main()
Tishka17 commented 2 months ago

Currently click integration does not enter context on command. This is done because often there is another framework with its own scopes logic.

Here username looks more like date for interactor, than something related to dependencies. But anyway, we'll think more

RonnyPfannschmidt commented 2 months ago

this could be summarized as "pass in dependency configuration for the container in some way

i realize that the inject/group hlpers pull together the whole picture

i want to be able to easily compose the Context data for entering

Tishka17 commented 2 months ago

From my current point of view groups is the place for configuration of app+container. Command - is one of the scenarios to trigger. We do not pass parsed data from web framework handlers to container, same is here.

But anyway, it is a place for improvement, though it is not yet clear in which way we should develop

Tishka17 commented 2 months ago

One of the options here is to enter nested scope manually inside command handler. You can pass context to context manager.

If you need, you can create container with scope RUNTIME, so the next scope will be APP

RonnyPfannschmidt commented 2 months ago

In my case, I'm using custom scope's anyway because it's not a webapp