diff options
author | Romain Gonçalves <me@rgoncalves.se> | 2022-10-08 14:08:16 +0200 |
---|---|---|
committer | Romain Gonçalves <me@rgoncalves.se> | 2022-10-08 14:08:16 +0200 |
commit | 037ab915bd455cccf46391f02f61949e5c84f1c3 (patch) | |
tree | 65a93d90a540a6e53fc6e618a9904529060964ca | |
parent | e667cd7e2dd0a7ac14ac30db38ca630ec0c5409b (diff) | |
download | pydanclick-037ab915bd455cccf46391f02f61949e5c84f1c3.tar.gz |
wip: saturday fixup
-rw-r--r-- | README.md | 53 | ||||
-rw-r--r-- | pydanclick/_logging.py | 12 | ||||
-rw-r--r-- | pydanclick/core.py | 6 | ||||
-rw-r--r-- | pydanclick/examples/__main__.py | 15 | ||||
-rw-r--r-- | pyproject.toml | 3 |
5 files changed, 85 insertions, 4 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..01a8ac0 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +Leverage the power of `pydantic` to create `click` command line applications! + +# Getting started + +Invoke the example module: + +``` +$ python -m pydanclick.examples --help +``` + +# Architecture + +``` +┌─────────────────────────────────────────────────┐ +│ Pydantic Schema │ +├─────────────────────────────────────────────────┤ +│ class MainArguments(BaseModel): │ +│ verbose: bool │ +│ name: str = Field(description="Service name.")│ +│ ... │ +└──┬──▲───────────────────────────────────────────┘ + │ │ + │ │ + │ │ Reads schema + │ │ + generate click interface + │ ┌┴────────────────────────┐ + │ │ Pydanclick decorator ├─────────────────────────────┐ + │ ├─────────────────────────┤ │ + │ │ pydanclick.core.command │ │ + │ │ pydanclick.core.group │ │ + │ └─────────────────────────┘ │ + │ │ +┌──▼───────────────────────────────────────────────────────┐ │ +│ Click Interface │ │ +├──────────────────────────────────────────────────────────┤ │ +│ click.Option("--verbose", required=True, type=click.BOOL)│ │ +│ type=click.BOOL) │ │ +│ click.Option("--name", required=True, │ │ +│ type=click.STR, │ │ +│ help="Service Name.") │ │ +└──────────────────────────────────────────────────────────┘ │ + │ +┌────────────────────────────────────┐ │ +│ Entrypoint invocation │◄──────────────────────┘ +├────────────────────────────────────┤ Read annotation(s) +│ @command() │ + invoke with arguments +│ def main(parameter: MainArguments):│ from click +│ ... │ +│ │ +│ if __name__ == "__main__": │ +│ main() │ +└────────────────────────────────────┘ +``` diff --git a/pydanclick/_logging.py b/pydanclick/_logging.py new file mode 100644 index 0000000..c90d8d1 --- /dev/null +++ b/pydanclick/_logging.py @@ -0,0 +1,12 @@ +import logging + +config = { + "version": 1, + "loggers": { + "__main__": { + "handlers": ["default"], + "level": logging.INFO, + "propagate": True, + } + }, +} diff --git a/pydanclick/core.py b/pydanclick/core.py index a513852..6eb2280 100644 --- a/pydanclick/core.py +++ b/pydanclick/core.py @@ -2,6 +2,7 @@ from __future__ import annotations import click import inspect +import logging from typing import Any from pydantic import BaseModel @@ -9,6 +10,8 @@ from typing import Callable, Type from pydanclick.schemas import CliSchema, OptionArgumentsSchema +logger = logging.getLogger(__name__) + class Command(click.Command): """ @@ -88,8 +91,6 @@ def get_option_arguments( schema: CliSchema, parameter: CliSchema.PropertySchema, key: str, - *args, - **kwargs ) -> OptionArgumentsSchema: """ Generate the option information only of a click.Command. @@ -118,6 +119,7 @@ def get_option_arguments( arguments.type = bool arguments.is_flag = True + logger.debug(f"Generated arguments: {dict(arguments)}") return arguments diff --git a/pydanclick/examples/__main__.py b/pydanclick/examples/__main__.py index 012f110..ee2e881 100644 --- a/pydanclick/examples/__main__.py +++ b/pydanclick/examples/__main__.py @@ -1,11 +1,21 @@ +import logging + from enum import Enum from pydantic import BaseModel, Field from pydanclick.decorators import command, group +logger = logging.getLogger() +handler = logging.StreamHandler() +handler.setLevel(logging.DEBUG) +logger.addHandler(handler) +logger.setLevel(logging.DEBUG) +handler.setFormatter( + logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +) -class MainArguments(BaseModel): +class MainArguments(BaseModel): class NetworkEnum(str, Enum): dhcp = "dhcp" static = "static" @@ -19,7 +29,7 @@ class MainArguments(BaseModel): ) force_download: bool = Field( default=False, - description="Force the download on a different API version" + description="Force the download on a different API version", ) network_type: NetworkEnum @@ -42,4 +52,5 @@ main.add_command(show) if __name__ == "__main__": + logger.debug("AAAAAAAAAAAAA") main() diff --git a/pyproject.toml b/pyproject.toml index 619f2a8..0e901b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,9 @@ show_missing = true fail_under = 100 exclude_lines = ["pragma: no cover"] +[tool.black] +line-length = 80 + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" |