typer-builder


Nametyper-builder JSON
Version 0.0.11 PyPI version JSON
download
home_page
Summary
upload_time2023-12-15 13:51:09
maintainer
docs_urlNone
authorNiklas Rosenstein
requires_python>=3.7
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # typer-builder

  [Typer]: https://typer.tiangolo.com/
  [pep585]: https://www.python.org/dev/peps/pep-0585/
  [pep604]: https://www.python.org/dev/peps/pep-0604/
  [typeapi]: https://github.com/NiklasRosenstein/python-typeapi

A framework for simplifying the development of [Typer][] based CLIs supporting modern type hints and hierarchical
dependency injection. 

__Table of Contents__

* [Introduction](#introduction)
  * [Example](#example)
* [Documentation](#documentation)
  * [New-style type hint support](#new-style-type-hint-support)
  * [Dependency injection](#dependency-injection)


## Introduction

The `build_app_from_module()` inspect a hierarchy of Python modules to build a Typer command and group structure.
Packages are treated as command groups and may define a `callback()` member. Modules are treated commands and must
define a `main()` member. Modules and packages prefixed with an underscore ( `_` ) are ignored. Help text is extracted
from the `main()` docstring or the module docstring.

In addition, we provide support for new-style type hints ([PEP 585 - Type Hinting Generics in Standard Collections][pep585]
and [PEP 604 - Union Operators][pep604]) in older versions of Python as well as adapt it for Typer (e.g. `list[str]`
and `str | None`), as well as a method of injecting dependencies to functions that are not sourced from the command-line.


### Example

```
$ tree src/mypackage/
src/mypackage/
├── __init__.py
├── __main__.py
└── commands
    ├── __init__.py
    ├── hello.py
    └── bye.py
```

```py
# src/mypackage/commands/hello.py
def main(name: str) -> None:
    print("Hello,", name)
```

```py
# src/mypackage/__main__.py
from typer_builder import build_app_from_module

if __name__ == "__main__":
    app = build_app_from_module("mypackage.commands")
    app()
```


## Documentation

### New-style type hint support

Through [`typeapi`][typeapi], we can convert new-tyle type hints such as `str | None` or `list[int]` to their corresponding
representation using `typing` before the function signature is parsed by [Typer][].

```py
# src/mypackage/commands/create_user.py
from ___future__ import annotations

def main(name: str | None = None, groups: list[str] | None = None) -> None:
    # ...
```

[`typeapi`][typeapi] also allows us to convert `list[str]` to `List[str]` and `dict[str, int]` to `Dict[str, int]` for
Python versions prior to 3.9. This is necessary because [Typer][] does not support the new-style type hints.

### Dependency injection

The `typer_builder.Dependencies` object is used to map types to concrete values or functions that provide them.
Functions wrapped with `Dependencies.bind()` will have their arguments resolved by the injector based on type
annotations. Every `build_app_from_module()` call creates a new `Dependencies` instance. Dependencies can be
injected from the outside by passing a `Dependencies` instance to `build_app_from_module()` or by providing
additional dependencies via a `callback()` function on the command group.

Note that the `Dependencies` does not understand generics with different type parameters. For example, it makes
no distinction between `MyGeneric[int]` and `MyGeneric[str]`. This is a limitation of the current implementation as well
as the Python type system.

The most common use case for dependency injection is to inject configuration managers or clients into subcommands. For
an example, you should check out the [examples/dependency-injection](./examples/dependency-injection) directory.


## License

This project is licensed under the terms of the MIT license.


            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "typer-builder",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "",
    "keywords": "",
    "author": "Niklas Rosenstein",
    "author_email": "rosensteinniklas@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/ab/0f/ee027c4f8f0c6377a0620c9e03a762a2a0e7fe58431376c3b5843c48863e/typer_builder-0.0.11.tar.gz",
    "platform": null,
    "description": "# typer-builder\n\n  [Typer]: https://typer.tiangolo.com/\n  [pep585]: https://www.python.org/dev/peps/pep-0585/\n  [pep604]: https://www.python.org/dev/peps/pep-0604/\n  [typeapi]: https://github.com/NiklasRosenstein/python-typeapi\n\nA framework for simplifying the development of [Typer][] based CLIs supporting modern type hints and hierarchical\ndependency injection. \n\n__Table of Contents__\n\n* [Introduction](#introduction)\n  * [Example](#example)\n* [Documentation](#documentation)\n  * [New-style type hint support](#new-style-type-hint-support)\n  * [Dependency injection](#dependency-injection)\n\n\n## Introduction\n\nThe `build_app_from_module()` inspect a hierarchy of Python modules to build a Typer command and group structure.\nPackages are treated as command groups and may define a `callback()` member. Modules are treated commands and must\ndefine a `main()` member. Modules and packages prefixed with an underscore ( `_` ) are ignored. Help text is extracted\nfrom the `main()` docstring or the module docstring.\n\nIn addition, we provide support for new-style type hints ([PEP 585 - Type Hinting Generics in Standard Collections][pep585]\nand [PEP 604 - Union Operators][pep604]) in older versions of Python as well as adapt it for Typer (e.g. `list[str]`\nand `str | None`), as well as a method of injecting dependencies to functions that are not sourced from the command-line.\n\n\n### Example\n\n```\n$ tree src/mypackage/\nsrc/mypackage/\n\u251c\u2500\u2500 __init__.py\n\u251c\u2500\u2500 __main__.py\n\u2514\u2500\u2500 commands\n    \u251c\u2500\u2500 __init__.py\n    \u251c\u2500\u2500 hello.py\n    \u2514\u2500\u2500 bye.py\n```\n\n```py\n# src/mypackage/commands/hello.py\ndef main(name: str) -> None:\n    print(\"Hello,\", name)\n```\n\n```py\n# src/mypackage/__main__.py\nfrom typer_builder import build_app_from_module\n\nif __name__ == \"__main__\":\n    app = build_app_from_module(\"mypackage.commands\")\n    app()\n```\n\n\n## Documentation\n\n### New-style type hint support\n\nThrough [`typeapi`][typeapi], we can convert new-tyle type hints such as `str | None` or `list[int]` to their corresponding\nrepresentation using `typing` before the function signature is parsed by [Typer][].\n\n```py\n# src/mypackage/commands/create_user.py\nfrom ___future__ import annotations\n\ndef main(name: str | None = None, groups: list[str] | None = None) -> None:\n    # ...\n```\n\n[`typeapi`][typeapi] also allows us to convert `list[str]` to `List[str]` and `dict[str, int]` to `Dict[str, int]` for\nPython versions prior to 3.9. This is necessary because [Typer][] does not support the new-style type hints.\n\n### Dependency injection\n\nThe `typer_builder.Dependencies` object is used to map types to concrete values or functions that provide them.\nFunctions wrapped with `Dependencies.bind()` will have their arguments resolved by the injector based on type\nannotations. Every `build_app_from_module()` call creates a new `Dependencies` instance. Dependencies can be\ninjected from the outside by passing a `Dependencies` instance to `build_app_from_module()` or by providing\nadditional dependencies via a `callback()` function on the command group.\n\nNote that the `Dependencies` does not understand generics with different type parameters. For example, it makes\nno distinction between `MyGeneric[int]` and `MyGeneric[str]`. This is a limitation of the current implementation as well\nas the Python type system.\n\nThe most common use case for dependency injection is to inject configuration managers or clients into subcommands. For\nan example, you should check out the [examples/dependency-injection](./examples/dependency-injection) directory.\n\n\n## License\n\nThis project is licensed under the terms of the MIT license.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "",
    "version": "0.0.11",
    "project_urls": {
        "Bug Tracker": "https://github.com/NiklasRosenstein/python-typer-builder/issues",
        "Repository": "https://github.com/NiklasRosenstein/typer-builder"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0c0fbdb530946d65b736ec13f191e8e49cfbce748a41bf6259308858de863805",
                "md5": "ded0b37df385886e26da58e861e04b80",
                "sha256": "1b185818cf7dd5873692cbb79e06a9ef878c0bd487c103251a3792e8899b639d"
            },
            "downloads": -1,
            "filename": "typer_builder-0.0.11-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ded0b37df385886e26da58e861e04b80",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 9759,
            "upload_time": "2023-12-15T13:51:07",
            "upload_time_iso_8601": "2023-12-15T13:51:07.973512Z",
            "url": "https://files.pythonhosted.org/packages/0c/0f/bdb530946d65b736ec13f191e8e49cfbce748a41bf6259308858de863805/typer_builder-0.0.11-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ab0fee027c4f8f0c6377a0620c9e03a762a2a0e7fe58431376c3b5843c48863e",
                "md5": "9d60abbbd8f3253c2b93caf75c3f5cf3",
                "sha256": "b3bb4ccf79d56f5656f69243785a527d26812db70d7b799d6eded14baad99062"
            },
            "downloads": -1,
            "filename": "typer_builder-0.0.11.tar.gz",
            "has_sig": false,
            "md5_digest": "9d60abbbd8f3253c2b93caf75c3f5cf3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 9478,
            "upload_time": "2023-12-15T13:51:09",
            "upload_time_iso_8601": "2023-12-15T13:51:09.152232Z",
            "url": "https://files.pythonhosted.org/packages/ab/0f/ee027c4f8f0c6377a0620c9e03a762a2a0e7fe58431376c3b5843c48863e/typer_builder-0.0.11.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-15 13:51:09",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NiklasRosenstein",
    "github_project": "python-typer-builder",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "typer-builder"
}
        
Elapsed time: 0.18161s