-
Notifications
You must be signed in to change notification settings - Fork 77
Allow passing of json argument to service call #319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,9 @@ | |
| import logging | ||
| import shlex | ||
| from typing import Any, Dict, Generator, List, Optional, Tuple, Union, cast | ||
| from typing import TextIO | ||
| import sys | ||
| import io | ||
|
|
||
| from ruamel.yaml import YAML | ||
| from tabulate import tabulate | ||
|
|
@@ -16,7 +19,7 @@ | |
| _LOGGING = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def to_attributes(entry: str) -> Dict[str, str]: | ||
| def to_attributes(entry: Union[str, TextIO]) -> Dict[str, str]: | ||
| """Convert list of key=value pairs to dictionary.""" | ||
| if not entry: | ||
| return {} | ||
|
|
@@ -183,3 +186,46 @@ def debug_requests() -> Generator: | |
| debug_requests_on() | ||
| yield | ||
| debug_requests_off() | ||
|
|
||
|
|
||
| def argument_callback(ctx, param, value): | ||
| """Helper to parse json, yaml and key-value arguments""" | ||
| _LOGGING.debug("_argument_callback called, %s(%s)", param.name, value) | ||
|
|
||
| # We get called with value None | ||
| # for all the callbacks which aren't provided. | ||
| if value is None: | ||
| return | ||
|
|
||
| if 'data' in ctx.params and ctx.params['data'] is not None: | ||
| _LOGGING.error("You can only specify one type of the argument types!") | ||
| _LOGGING.debug(ctx.params) | ||
| ctx.exit() | ||
|
|
||
| if value == '-': # read from stdin | ||
| _LOGGING.debug("Loading value from stdin") | ||
| value = sys.stdin | ||
| elif value.startswith('@'): # read from file | ||
| _LOGGING.debug("Loading value from file: %s", value[1:]) | ||
| value = open(value[1:], 'r') | ||
| else: | ||
| _LOGGING.debug("Using value as is: %s", value) | ||
|
|
||
| if param.name == 'arguments': | ||
| result = to_attributes(value) | ||
| elif param.name == 'json': | ||
| # We need to use different json calls to load from stream or string | ||
| if isinstance(value, str): | ||
| result = json.loads(value) | ||
| else: | ||
| result = json.load(value) | ||
| elif param.name == 'yaml': | ||
| result = yaml.yaml().load(value) | ||
| else: | ||
| _LOGGING.error("Parameter name is unknown: %s", param.name) | ||
| ctx.exit() | ||
|
|
||
| if isinstance(value, io.IOBase): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'io' |
||
| value.close() | ||
|
|
||
| ctx.params['data'] = result | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,8 +9,9 @@ | |
| import homeassistant_cli.autocompletion as autocompletion | ||
| from homeassistant_cli.cli import pass_context | ||
| from homeassistant_cli.config import Configuration | ||
| from homeassistant_cli.helper import format_output, to_attributes | ||
| from homeassistant_cli.helper import format_output | ||
| import homeassistant_cli.remote as api | ||
| from homeassistant_cli.helper import argument_callback | ||
|
|
||
| _LOGGING = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -83,10 +84,28 @@ def list_cmd(ctx: Configuration, servicefilter): | |
| shell_complete=autocompletion.services, # type: ignore | ||
| ) | ||
| @click.option( | ||
| '--arguments', help="Comma separated key/value pairs to use as arguments." | ||
| '--arguments', help="""Comma separated key/value pairs to use as arguments. | ||
| if string is -, the data is read from stdin, and if it starts with the letter @ | ||
| the rest should be a filename from which the data is read""", | ||
| callback=argument_callback, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'argument_callback' |
||
| expose_value=False | ||
| ) | ||
| @click.option( | ||
| '--json', help="""Json string to use as arguments. | ||
| if string is -, the data is read from stdin, and if it starts with the letter @ | ||
| the rest should be a filename from which the data is read""", | ||
| callback=argument_callback, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'argument_callback' |
||
| expose_value=False | ||
| ) | ||
| @click.option( | ||
| '--yaml', help="""Yaml string to use as arguments. | ||
| if string is -, the data is read from stdin, and if it starts with the letter @ | ||
| the rest should be a filename from which the data is read""", | ||
| callback=argument_callback, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined name 'argument_callback' |
||
| expose_value=False | ||
| ) | ||
| @pass_context | ||
| def call(ctx: Configuration, service, arguments): | ||
| def call(ctx: Configuration, service, data=None): | ||
| """Call a service.""" | ||
| ctx.auto_output('data') | ||
| _LOGGING.debug("service call <start>") | ||
|
|
@@ -95,10 +114,7 @@ def call(ctx: Configuration, service, arguments): | |
| _LOGGING.error("Service name not following <domain>.<service> format") | ||
| sys.exit(1) | ||
|
|
||
| _LOGGING.debug("Convert arguments %s to dict", arguments) | ||
| data = to_attributes(arguments) | ||
|
|
||
| _LOGGING.debug("service call_service") | ||
| _LOGGING.debug("calling %s.%s(%s)", parts[0], parts[1], data) | ||
|
|
||
| result = api.call_service(ctx, parts[0], parts[1], data) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
undefined name 'sys'