Skip to content

:simple-click: Click Integration

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

  • Automatic Dependency Management


    Inject dependencies in Click commands and automatically manage container lifecycle.

  • 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 sync container

import click
from wireup import Inject, Injected, service

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

container = wireup.create_sync_container(
    service_modules=[services],
    parameters={
        "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 commands' signature and annotate them as necessary. See Annotations for more details.

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(param="env")],
    debug: Annotated[bool, Inject(param="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():

    # Create test container with mocked service
    with container.override.service(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.