From 83c880e6ec7e75a0410f6b8fde9b501eeff4347e Mon Sep 17 00:00:00 2001 From: antazoey Date: Tue, 31 Oct 2023 11:41:08 -0500 Subject: [PATCH] feat: allow custom cli ctx obj types (#1712) --- docs/userguides/clis.md | 27 +++++++++++++++++++++++++++ src/ape/cli/__init__.py | 2 ++ src/ape/cli/options.py | 13 ++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/docs/userguides/clis.md b/docs/userguides/clis.md index aac6b7b9de..8ca3bb2a1b 100644 --- a/docs/userguides/clis.md +++ b/docs/userguides/clis.md @@ -34,6 +34,33 @@ def cmd(cli_ctx): cli_ctx.abort(f"Bad account: {account.address}") ``` +In Ape, it is easy to extend the CLI context object and use the extended version in your CLIs: + +```python +from ape.cli import ApeCliContextObject, ape_cli_context +import click + +class MyManager: + """My custom manager.""" + +class CustomContext(ApeCliContextObject): + """Add new managers to your custom context""" + my_manager: MyManager = MyManager() + + @property + def signer(self): + """Utilize existing managers in your custom context.""" + return self.account_manager.load("my_account") + +@click.command() +@ape_cli_context(obj_type=CustomContext) +def cli(cli_ctx): + # Access your manager. + print(cli_ctx.my_manager) + # Access other Ape managers. + print(cli_ctx.account_manager) +``` + ## Network Tools The `@network_option()` allows you to select an ecosystem / network / provider combination. diff --git a/src/ape/cli/__init__.py b/src/ape/cli/__init__.py index 6e5ecbab01..8204b3fcf7 100644 --- a/src/ape/cli/__init__.py +++ b/src/ape/cli/__init__.py @@ -14,6 +14,7 @@ ) from ape.cli.commands import NetworkBoundCommand from ape.cli.options import ( + ApeCliContextObject, account_option, ape_cli_context, contract_option, @@ -33,6 +34,7 @@ "Alias", "AllFilePaths", "ape_cli_context", + "ApeCliContextObject", "contract_file_paths_argument", "contract_option", "existing_alias_argument", diff --git a/src/ape/cli/options.py b/src/ape/cli/options.py index 1341c5b81b..0cf5efb0bf 100644 --- a/src/ape/cli/options.py +++ b/src/ape/cli/options.py @@ -1,4 +1,4 @@ -from typing import Callable, Dict, List, NoReturn, Optional, Union +from typing import Callable, Dict, List, NoReturn, Optional, Type, Union import click from ethpm_types import ContractType @@ -75,7 +75,9 @@ def set_level(ctx, param, value): } -def ape_cli_context(default_log_level: str = DEFAULT_LOG_LEVEL): +def ape_cli_context( + default_log_level: str = DEFAULT_LOG_LEVEL, obj_type: Type = ApeCliContextObject +): """ A ``click`` context object with helpful utilities. Use in your commands to get access to common utility features, @@ -84,11 +86,16 @@ def ape_cli_context(default_log_level: str = DEFAULT_LOG_LEVEL): Args: default_log_level (str): The log-level value to pass to :meth:`~ape.cli.options.verbosity_option`. + obj_type (Type): The context object type. Defaults to + :class:`~ape.cli.options.ApeCliContextObject`. Sub-class + the context to extend its functionality in your CLIs, + such as if you want to add additional manager classes + to the context. """ def decorator(f): f = verbosity_option(logger, default=default_log_level)(f) - f = click.make_pass_decorator(ApeCliContextObject, ensure=True)(f) + f = click.make_pass_decorator(obj_type, ensure=True)(f) return f return decorator