Skip to content

Click Integration

Dependency injection for Click is available in the wireup.integration.click module.

  • Automatic Dependency Management


    Inject dependencies in Click commands.

  • Shared business logic


    Wireup is framework-agnostic. Share the service layer between CLIs and other interfaces, such as a web application.

Initialize the integration

First, create a container.

from typing import Annotated
import click
from wireup import Inject, Injected, injectable


@click.group()
def cli():
    pass


container = wireup.create_sync_container(
    injectables=[services], config={"env": "development", "debug": True}
)

Then initialize the integration by calling wireup.integration.click.setup after adding all commands:

# Initialize the integration.
# Must be called after all commands have been added.
wireup.integration.click.setup(container, cli)

Inject in Click Commands

To inject dependencies, add the type to the command's signature and annotate with Injected[T] or Annotated[T, Inject(...)].

Click Command
@cli.command()
def random_number(random: Injected[RandomService]):
    click.echo(f"Your lucky number is: {random.get_random()}")


@cli.command()
def env_info(
    env: Annotated[str, Inject(config="env")],
    debug: Annotated[bool, Inject(config="debug")],
):
    click.echo(f"Environment: {env}")
    click.echo(f"Debug mode: {debug}")

Accessing the Container

To access the Wireup container directly, use the following:

# Get application-wide container
from wireup.integration.click import get_app_container

container = get_app_container(cli)

Testing

When testing Click commands with dependency injection, services can be swapped out in tests by overriding services before executing the Click runner.

from click.testing import CliRunner


def test_random_number_command():
    class MockRandomService:
        def get_random(self):
            return 4

    # Create test container with mocked service
    with container.override.injectable(RandomService, new=MockRandomService()):
        runner = CliRunner()
        result = runner.invoke(cli, ["random-number"])

        assert result.exit_code == 0
        assert "Your lucky number is:" in result.output

API Reference

Visit API Reference for detailed information about the Click integration module.