{"id":21839093,"url":"https://github.com/illuin-tech/configue-cli","last_synced_at":"2026-04-11T21:42:40.236Z","repository":{"id":149898817,"uuid":"621734990","full_name":"illuin-tech/configue-cli","owner":"illuin-tech","description":"A configue extension that adds the ability to dynamically configure your application via the command line.","archived":false,"fork":false,"pushed_at":"2023-04-01T22:07:33.000Z","size":27,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-01T03:05:48.058Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/illuin-tech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-31T09:18:02.000Z","updated_at":"2023-06-08T08:45:33.000Z","dependencies_parsed_at":"2023-06-18T20:34:50.252Z","dependency_job_id":null,"html_url":"https://github.com/illuin-tech/configue-cli","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/illuin-tech/configue-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuin-tech%2Fconfigue-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuin-tech%2Fconfigue-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuin-tech%2Fconfigue-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuin-tech%2Fconfigue-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/illuin-tech","download_url":"https://codeload.github.com/illuin-tech/configue-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/illuin-tech%2Fconfigue-cli/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265878850,"owners_count":23843026,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-27T21:15:54.313Z","updated_at":"2026-04-11T21:42:35.169Z","avatar_url":"https://github.com/illuin-tech.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Configue CLI\n\nA [configue](https://github.com/illuin-tech/configue) extension that adds the ability to dynamically configure your application via the command line.\n\nConfigue CLI overlaps in functionality with [Hydra](https://hydra.cc/) but without all the unnecessary boilerplate and with the benefit of being compatible with `configue`.\n\n#### Table of contents\n\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [Inspection of the configuration state](#inspection-of-the-configuration-state)\n- [Configuration from the command line](#configuration-from-the-command-line)\n- [Configuration with YAML files](#configuration-with-yaml-files)\n- [Exporting the final configuration](#exporting-the-final-configuration)\n- [Unstructured configuration](#unstructured-configuration)\n- [Configuring the logging](#configuring-the-logging)\n- [Integration with Skypilot](#integration-with-skypilot)\n\n## Installation\n\nTo install the library, use\n\n```shell\npip install configue-cli\n```\n\nTo develop locally, clone the repository and use\n\n```shell\npip install -r requirements-dev.txt\n```\n\n## Quick start\n\nWith `configue-cli`, configurations are defined with structured and arbitrarily nested Python objects (both native dataclasses and `attr` dataclasses are supported and can be nested).\n\n```python\nimport dataclasses\nimport attrs\n\n\n@dataclasses.dataclass\nclass DatasetConfig:\n    name: str\n    n_samples: int = 10_000\n\n\n@dataclasses.dataclass\nclass OptimizerConfig:\n    learning_rate: float = 0.001\n    weight_decay: float = 1e-2\n\n\n@attrs.define\nclass ModelConfig:\n    name: str\n    batch_size: int = 12\n    optimizer: OptimizerConfig = attrs.Factory(\n        lambda self: OptimizerConfig(learning_rate=0.001 * self.batch_size), takes_self=True\n    )\n\n\n@dataclasses.dataclass\nclass ExperimentConfig:\n    model: ModelConfig\n    dataset: DatasetConfig\n```\n\nThese objects are injected at configuration time in your application entrypoint by the `inject_from_cli` decorator. To use `configue-cli`, simply wrap a [click](https://github.com/pallets/click) entrypoint with the `configue_cli.click.inject_from_cli` decorator and provide a target type to be injected.\n\n```python\nimport click\nfrom configue_cli.click import inject_from_cli\n\n@click.command()\n@inject_from_cli(ExperimentConfig)\ndef main(config: ExperimentConfig) -\u003e None:\n    print(\"Passed configuration: \", config)\n\n\nif __name__ == \"__main__\":\n    main()\n```\n\nTo display a help message, use the following:\n\n```shell\npython main.py --help\n```\n\n## Inspection of the configuration state\n\nTo visually inspect your application configuration state, use the following command:\n\n```shell\n$ python main.py --dry-run\n\n╭─ Configuration helper ────────────────────────────────╮\n│                                                       │\n│  model                                                │\n│  ├── (): __main__.ModelConfig                         │\n│  ├── name: Missing                                    │\n│  ├── batch_size: 12                                   │\n│  └── optimizer                                        │\n│      ├── (): __main__.OptimizerConfig                 │\n│      ├── learning_rate: 0.012                         │\n│      └── weight_decay: 0.01                           │\n│                                                       │\n│  dataset                                              │\n│  ├── (): __main__.DatasetConfig                       │\n│  ├── name: Missing                                    │\n│  └── n_samples: 10000                                 │\n│                                                       │\n╰───────────────────────────────────────────────────────╯\n```\n\nThis is useful to quickly identify which parameters are not yet defined (those marked with a `Missing`) and which values are used in the other parameters without inspecting the code.\n\n## Configuration from the command line\n\nParameters can be specified from the command line using dotted notation.\n\n```shell\n$ python main.py model.name=camembert-base dataset.name=fquad model.batch_size=48\n\n╭─ Configuration ───────────────────────────────────────────────────────────────────────────╮\n│                                                                                           │\n│  model                                                                                    │\n│  ├── (): __main__.ModelConfig                                                             │\n│  ├── name: camembert-base                                                                 │\n│  ├── batch_size: 48                                                                       │\n│  └── optimizer                                                                            │\n│      ├── (): __main__.OptimizerConfig                                                     │\n│      ├── learning_rate: 0.048                                                             │\n│      └── weight_decay: 0.01                                                               │\n│                                                                                           │\n│  dataset                                                                                  │\n│  ├── (): __main__.DatasetConfig                                                           │\n│  ├── name: fquad                                                                          │\n│  └── n_samples: 10000                                                                     │\n│                                                                                           │\n╰───────────────────────────────────────────────────────────────────────────────────────────╯\nPassed configuration: ExperimentConfig(model=ModelConfig(name='camembert-base', batch_size=48, optimizer=OptimizerConfig(learning_rate=0.048, weight_decay=0.01)), dataset=DatasetConfig(name='fquad', n_samples=10000))\n```\n\nAny missing required parameter at configuration time will result in an exception:\n\n```shell\n$ python main.py model.batch_size=3\n\nTraceback (most recent call last):\n  ...\nconfigue_cli.core.exceptions.MissingMandatoryValueError: Missing mandatory value: dataset.name\n```\n\n## Configuration with YAML files\n\nAny parameter can be overridden using a `configue` compliant YAML file. Suppose the model is configured in the following `model.yml` file:\n\n```yaml\nmodel:\n  (): __main__.ModelConfig\n  name: camembert-large\n  batch_size: 72\n  optimizer:\n    (): __main__.OptimizerConfig\n    learning_rate: 0.01\n    weight_decay: 0.0\n```\n\nThis configuration file can be loaded from the CLI using the `-c` flag:\n\n```shell\n$ python main.py -c model.yml --dry-run\n\n╭─ Configuration helper ────────────────────────────────────╮\n│                                                           │\n│  model                                                    │\n│  ├── (): __main__.ModelConfig                             │\n│  ├── name: camembert-large                                │\n│  ├── batch_size: 72                                       │\n│  └── optimizer                                            │\n│      ├── (): __main__.OptimizerConfig                     │\n│      ├── learning_rate: 0.01                              │\n│      └── weight_decay: 0.0                                │\n│                                                           │\n│  dataset                                                  │\n│  ├── (): __main__.DatasetConfig                           │\n│  ├── name: Missing                                        │\n│  └── n_samples: 10000                                     │\n│                                                           │\n╰───────────────────────────────────────────────────────────╯\n```\n\nMultiple configuration files can be used simultaneously, the final configuration is assembled by merging all files in the order they are provided. For instance, let's suppose we have the following `large_batch.yml` file:\n\n```yaml\nmodel:\n  batch_size: 512\n```\n\nThis file can be merged into our previous configuration using the following:\n\n```shell\n$ python main.py -c model.yml -c large_batch.yml --dry-run \n\n╭─ Configuration helper ────────────────────────────────────╮\n│                                                           │\n│  model                                                    │\n│  ├── (): __main__.ModelConfig                             │\n│  ├── name: camembert-large                                │\n│  ├── batch_size: 512                                      │\n│  └── optimizer                                            │\n│      ├── (): __main__.OptimizerConfig                     │\n│      ├── learning_rate: 0.01                              │\n│      └── weight_decay: 0.0                                │\n│                                                           │\n│  dataset                                                  │\n│  ├── (): __main__.DatasetConfig                           │\n│  ├── name: Missing                                        │\n│  └── n_samples: 10000                                     │\n│                                                           │\n╰───────────────────────────────────────────────────────────╯\n```\n\nParameters specified with the command line take precedence over the ones specified in YAML files:\n\n```shell\n$ python main.py model.batch_size=32 -c model.yml -c large_batch.yml --dry-run\n\n╭─ Configuration helper ────────────────────────────────────╮\n│                                                           │\n│  model                                                    │\n│  ├── (): __main__.ModelConfig                             │\n│  ├── name: camembert-large                                │\n│  ├── batch_size: 32                                       │\n│  └── optimizer                                            │\n│      ├── (): __main__.OptimizerConfig                     │\n│      ├── learning_rate: 0.01                              │\n│      └── weight_decay: 0.0                                │\n│                                                           │\n│  dataset                                                  │\n│  ├── (): __main__.DatasetConfig                           │\n│  ├── name: Missing                                        │\n│  └── n_samples: 10000                                     │\n│                                                           │\n╰───────────────────────────────────────────────────────────╯\n```\n\nThis feature encourages a modular configuration pattern where different subparts of the application (the model and the dataset in this example) are configured in separate YAML files and are dynamically assembled at configuration time. Different variations of these subparts can easily be assembled. All arguments can be overridden using the command line without having to edit the config files.\n\n## Exporting the final configuration\n\nTo ease reproducibility, the final configuration used for the run can be exported by using the `-o` flag and specifying an output YAML file:\n\n```shell\n$ python main.py dataset.name=hello-world -c model.yml -c large_batch.yml -o output.yml\n\n╭─ Configuration ───────────────────────────────────────────╮\n│                                                           │\n│  model                                                    │\n│  ├── (): __main__.ModelConfig                             │\n│  ├── name: camembert-large                                │\n│  ├── batch_size: 512                                      │\n│  └── optimizer                                            │\n│      ├── (): __main__.OptimizerConfig                     │\n│      ├── learning_rate: 0.01                              │\n│      └── weight_decay: 0.0                                │\n│                                                           │\n│  dataset                                                  │\n│  ├── (): __main__.DatasetConfig                           │\n│  ├── name: hello-world                                    │\n│  └── n_samples: 10000                                     │\n│                                                           │\n╰───────────────────────────────────────────────────────────╯\nPassed configuration ExperimentConfig(model=ModelConfig(name='camembert-large', batch_size=512, optimizer=OptimizerConfig(learning_rate=0.01, weight_decay=0.0)), dataset=DatasetConfig(name='hello-world', n_samples=10000))\n\n$ cat output.yml\nmodel:\n  (): __main__.ModelConfig\n  name: camembert-large\n  batch_size: 512\n  optimizer:\n    (): __main__.OptimizerConfig\n    learning_rate: 0.01\n    weight_decay: 0.0\ndataset:\n  (): __main__.DatasetConfig\n  name: hello-world\n  n_samples: 10000\n```\n\n## Unstructured configuration\n\nIt is possible to use the `inject_from_cli` decorator without specifying a target type:\n\n```python\n@click.command()\n@inject_from_cli()\ndef main(config: configue_cli.core.dict_config.DictConfig) -\u003e None:\n    ...\n```\n\nIn that case, the wrapped entrypoint will be passed a `configue_cli.core.dict_config.DictConfig` object upon injection.\n\n## Configuring the logging\n\nTo load a [logging configuration](https://docs.python.org/3/library/logging.config.html) located under the `\"logging\"` key in your final configuration, use the following:\n\n```python\n@click.command()\n@inject_from_cli(ExperimentConfig, logging_config_path=\"logging\")\ndef main(config: ExperimentConfig) -\u003e None:\n    ...\n```\n\n## Integration with Skypilot\n\n[SkyPilot](https://github.com/skypilot-org/skypilot) is a framework for easily running jobs on any cloud through a unified interface. Any function decorated with `inject_from_cli` can easily be executed remotely by providing a Skypilot configuration.\n\nThe following configuration defines a job to be executed in a SkyPilot cluster named `test-cluster`. The job is defined under the `task` key, we refer to the [SkyPilot YAML specification](https://skypilot.readthedocs.io/en/latest/reference/yaml-spec.html) for more details on this section.\n\nThe Python command and all its arguments are captured and interpolated inside the `run` command, respectively in a `{command}` and `{parameters}` placeholder.\n\n```yaml\n# skypilot.yml\nskypilot:\n  cluster-name: test-cluster\n  task:\n    resources:\n      cloud: gcp\n      accelerators: K80:1\n    workdir: .\n    setup: |\n      echo 'Setup the job...'\n    run: |\n      set -e\n      cd ~/sky_workdir\n      {command} {parameters}\n```\n\nTo load the SkyPilot configuration in your final configuration, use the following:\n\n```python\n@click.command()\n@inject_from_cli(ExperimentConfig, skypilot_config_path=\"skypilot\")\ndef main(config: ExperimentConfig) -\u003e None:\n    ...\n```\n\nAs with the other arguments, all SkyPilot configuration arguments can be redefined on the fly:\n\n```shell\npython main.py -c skypilot.yml skypilot.cluster-name=another-cluster\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filluin-tech%2Fconfigue-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filluin-tech%2Fconfigue-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filluin-tech%2Fconfigue-cli/lists"}