{"id":20377516,"url":"https://github.com/postpop/defoptcfg","last_synced_at":"2026-04-19T01:36:58.317Z","repository":{"id":72927197,"uuid":"141828317","full_name":"postpop/defoptcfg","owner":"postpop","description":"defopt with config files","archived":false,"fork":false,"pushed_at":"2018-07-25T06:46:22.000Z","size":47,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-04T21:44:13.076Z","etag":null,"topics":["argparse","commandline","configargparse","configuration","defopt","python","yaml"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/postpop.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2018-07-21T16:19:02.000Z","updated_at":"2019-12-23T15:45:20.000Z","dependencies_parsed_at":"2023-03-18T12:09:37.409Z","dependency_job_id":null,"html_url":"https://github.com/postpop/defoptcfg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/postpop/defoptcfg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postpop%2Fdefoptcfg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postpop%2Fdefoptcfg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postpop%2Fdefoptcfg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postpop%2Fdefoptcfg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/postpop","download_url":"https://codeload.github.com/postpop/defoptcfg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/postpop%2Fdefoptcfg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31991720,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"ssl_error","status_checked_at":"2026-04-18T20:23:29.375Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["argparse","commandline","configargparse","configuration","defopt","python","yaml"],"created_at":"2024-11-15T01:45:30.527Z","updated_at":"2026-04-19T01:36:58.300Z","avatar_url":"https://github.com/postpop.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# defoptcfg - defopt with config files\nExtends [defopt][1] to read defaults from [yaml][2] files. Inspired by (but much worse than) [configargparse][3].\n\n## Simple example\n```python\nimport defoptcfg\ndef main(greeting: str, *, name: str = 'Paul'):\n    \"\"\"Greet someone.\n\n    Args:\n        greeting: How do you want to greet someone?\n        name: Who do you want to greet?\n    \"\"\"\n    print(f\"{greeting} {name}!\")\ndefoptcfg.run(main)\n```\n[defopt][1] is used to generate a command line interface from the function signature. Type information must be provided by annotating the function definition or via doc strings (see defopt's [docs][4] for details):\n```text\npython test.py -h\nusage: test.py [-h] [-n NAME] [--cfg CFG] [greeting]\n\nGreet someone.\n\npositional arguments:\n  greeting              How do you want to greet someone?\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -n NAME, --name NAME  Who do you want to greet?\n                        (default: Paul)\n  --cfg CFG             config file for setting defaults\n```\nConfiguration can also be provided via yaml files. Arguments from config files override function defaults and are overridden by command line arguments. Keys in the config file must match the full argument name:\n```yaml\ngreeting: Salut\nname: Ringo\n```\n\n```shell\npython test.py Hello --cfg config.yml\nSalut Ringo!\n```\n```shell\npython test.py Hello --cfg config.yml -n John\nSalut John!\n```\n## Installation\nIn a terminal window run\n```shell\npip install git+http://github.com/postpop/defoptcfg.git\n```\n## More complex use case\nSay you have written a function in `train_network.py` that runs a complex machine learning task and has many, many parameters for flexibility:\n```python\nimport defoptcfg\n\ndef train_network(data_path: str, *,\n                  base_output_path: str = \"models\",\n                  run_name: str = None,\n                  data_name: str = None,\n                  x_dset: str = \"images\",\n                  y_dset: str = \"masks\",\n                  val_size: float = 0.15,\n                  filters: int = 32,\n                  rotate_angle: float = 15,\n                  epochs: int = 50,\n                  batch_size: int = 32,\n                  save_every_epoch: int = False,\n                  ):\n    pass # do something magical here\n\nif __name__ == '__main__':\n    defoptcfg.run(train_network)\n```\nThanks to [defopt][1], you automagically have a command line interface (provided you have properly [type annotated][5] or [docstring][6]'ed it, defopt's [docs][4] have all the details on how to do that) and can call the function like so:\n```shell\npython train_network.py /Volumes/share/data/exp1/data_20151021 --base-output-path /Volumes/share/networks/results --run-name test_more_filters --data-name fly-courtship --filters 64 --epochs 20 --batch_size 1\n```\nThis is long. defoptcfg extends [defopt][1] to allow you to provide arguments that rarely change via a config file, e.g. `config.yml`:\n```yaml\ndata_path: /Volumes/share/data/exp1/data_20151021_1629\nbase_output_path: /Volumes/share/networks/results\ndata-name: fly-courtship\nepochs: 20\nbatch_size: 1\n```\nresulting in a much shorter command line:\n```shell\npython train_network.py --cfg config.yml --run-name test_more_filters --filters 64\n```\n\n## String interpolation in config files\nIn addition, string interpolation facilitates the structuring of config files:\n```yaml\nroot: /Volumes/share\ndata_path: $root$/data\n```\nValues of any key in the config file can be turned into variables by surrounding with `$...$` (e.g. `$root$`). Their occurrences in any of the values will be\nreplaced by that key's value. In the above example, `$root$` in `$root$/data` will be replaced by `/Volumes/share` to become `/Volumes/share/data`.\n\n__Warning__: Take care when using this feature since the current implementation does only incompletely guard against recursion catastrophes. For instance, a config file with `root1: $root2$; root2: $root1$` will result in an endless cycle of interpolations. Current safeguard is to limit the number of cycles to 20 with the `n_iter` parameter.\n\n## Default config files\nDefault config files can be provided via\n```python\ndefoptcfg.run(main, default_config_files=['a.yml', 'b.yml'])\n```\nPrecedence is according to order in list of files. Values in `a.yml` are overridden by those in `b.yml`, which in turn are overridden by those in the config file provided via the command line.\n\n## Future plans\n- Needs much more testing. Does probably not work with defopt's advanced features (entry points, custom parsers etc)\n- Better support and more robust support for string interpolation (via jinja2?):  [here](http://dontfragment.com/using-python-yaml-and-jinja2-to-generate-config-files/), [here](https://stackoverflow.com/questions/42083616/yaml-and-jinja2-reader),\n\n[1]: https://github.com/evanunderscore/defopt\n[2]: https://pyyaml.org\n[3]: https://github.com/bw2/ConfigArgParse\n[4]: http://defopt.readthedocs.io/en/latest/\n[5]: linktopythonannotations\n[6]: linktodocstringformats\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpostpop%2Fdefoptcfg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpostpop%2Fdefoptcfg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpostpop%2Fdefoptcfg/lists"}