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
Allow passing of json argument to service call #319
base: dev
Are you sure you want to change the base?
Conversation
This PR is a bit quick and dirty and is to be treated as a RFC, but it shows the issue I'm trying to solve, and a simple fix for it. Please comment about other ways you might want to tackle this issue. |
74ff2a9
to
10cade8
Compare
I grok the incentive, initially I actually wanted the --arguments / to_arguments() function to support nested structures but didn't get around to it. but if we are going to allow json we should consider supporting yaml too and possibly as a piped/redirected format. That should be easy to do as one is a subset of the other; maybe just have --arguments-raw or --arguments-data take something that will be loaded with yaml load always ? --arguments-raw=- would be read from stdin wdyt? |
--arg=- for stdin and --arg=@filename for read data from file is ok for me, and semi-standard and what ex. curl uses, so I'm just fine with that. --arguments-raw sort of makes sense, and is what the underlying HA api uses, but I really don't think we need to expose that to the user. It also turns things into a guessing game if its yaml the user provides, or if its json. I'd rather go for --arguments-json and --arguments-yaml and let the user be explicit about that it provides, and let the different options be conflicting, so the tool errors out if you provide more than one of --arguments, --arguments-json or --arguments-yaml. I think json is way easier to write on cmdline than yaml, but I much rather write yaml in a file and provide that than writing json in a file. With some sane design of the code we can support all the permutations and let the user decide what they like. |
makes sense! Would you like to update your PR to get that done ? |
Just saw that I'll hammer out a variant. It's easy to change the name later, before merging this. |
good point! +1 for consistency. |
10cade8
to
3aeca23
Compare
3aeca23
to
cb0fe08
Compare
4fb74dd
to
a3e7560
Compare
hurm. Only one of the typing issues is "mine", and I'm sort of confused by how that code is written.
diff --git i/tests/test_service.py w/tests/test_service.py
index bb7b52f..447afb2 100644
--- i/tests/test_service.py
+++ w/tests/test_service.py
@@ -8,7 +8,7 @@ import requests_mock
import homeassistant_cli.autocompletion as autocompletion
import homeassistant_cli.cli as cli
from homeassistant_cli.config import Configuration
-from homeassistant_cli.yaml import dumpyaml
+from homeassistant_cli.yaml import yaml, dumpyaml
def test_service_list(default_services) -> None:
@@ -218,7 +218,7 @@ def test_service_call_with_yaml_file(default_services) -> None:
"test": True,
}
- open_yaml_file = mock_open(read_data=dumpyaml(None, data=data))
+ open_yaml_file = mock_open(read_data=dumpyaml(yaml(), data=data))
runner = CliRunner()
with patch('builtins.open', open_yaml_file) as mocked_open: Would you like me to do that, or should we fix the dumpyaml function instead? |
do the fix you think is right. |
a3e7560
to
b66a3bc
Compare
Codecov Report
@@ Coverage Diff @@
## dev #319 +/- ##
==========================================
+ Coverage 75.25% 75.43% +0.18%
==========================================
Files 22 22
Lines 1560 1592 +32
==========================================
+ Hits 1174 1201 +27
- Misses 386 391 +5
Continue to review full report at Codecov.
|
b66a3bc
to
8f6b8a6
Compare
The current typing failure is in ruamel.yaml==0.16.6 which was released yesterday (2020-01-20) and is definitely out of scope for this PR. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
8f6b8a6
to
cc527c0
Compare
'--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 comment
The reason will be displayed to describe this comment to others. Learn more.
undefined name 'argument_callback'
'--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 comment
The reason will be displayed to describe this comment to others. Learn more.
undefined name 'argument_callback'
'--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 comment
The reason will be displayed to describe this comment to others. Learn more.
undefined name 'argument_callback'
homeassistant_cli/plugins/service.py
Outdated
@@ -11,6 +13,7 @@ | |||
from homeassistant_cli.config import Configuration | |||
from homeassistant_cli.helper import format_output, to_attributes | |||
import homeassistant_cli.remote as api | |||
from homeassistant_cli.yaml import yaml |
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.
'homeassistant_cli.yaml.yaml' imported but unused
homeassistant_cli/plugins/service.py
Outdated
@@ -3,6 +3,8 @@ | |||
import re as reg | |||
import sys | |||
from typing import Any, Dict, List, Pattern # noqa: F401 | |||
import json | |||
import io |
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.
'io' imported but unused
homeassistant_cli/plugins/service.py
Outdated
@@ -3,6 +3,8 @@ | |||
import re as reg | |||
import sys | |||
from typing import Any, Dict, List, Pattern # noqa: F401 | |||
import json |
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.
'json' imported but unused
homeassistant_cli/plugins/raw.py
Outdated
@pass_context | ||
def post(ctx: Configuration, method, json): | ||
def post(ctx: Configuration, method, 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.
Do not use mutable data structures for argument defaults. They are created during function definition time. All calls to the function reuse this one instance of that data structure, persisting changes between them.
_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 comment
The reason will be displayed to describe this comment to others. Learn more.
undefined name 'io'
|
||
if value == '-': # read from stdin | ||
_LOGGING.debug("Loading value from stdin") | ||
value = sys.stdin |
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'
cc527c0
to
2788a8a
Compare
2788a8a
to
9e21b96
Compare
I've just refreshed this one, could someone take a look at it and hopefully merge it? |
When calling service who needs arguments which are other things than strings, ex nested dicts, its easiest done by being able to pass a json or yaml argument, for example when calling html5.dismis: hass-cli service call html5.dismiss --json '{"target": "DEVICE", "data": {"tag": "TAG"}}' As requested in review, this also adds support for passing in @filename or - for reading arguments from stdin or from a file. Signed-off-by: Anton Lundin <glance@acc.umu.se>
This is to simplify re-use outside service calls.
This re-uses the --yaml and --json argument parsers from services to allow passing from stdin and files. One awesome use case is: hass-cli raw ws lovelace/config > ui-lovelace.yaml $EDITOR ui-lovelace.yaml , replacing the status fields, up until result: with config:, and then, hass-cli raw ws lovelace/config/save --yaml @ui-lovelace.yaml
9e21b96
to
ee7e69f
Compare
When calling service who needs arguments which are other things than
strings, ex nested dicts, its easiest done by being able to pass a json
string as argument, for example when calling html5.dismis:
hass-cli service call html5.dismiss --arguments-json '{"target": "DEVICE", "data": {"tag": "TAG"}}'
Signed-off-by: Anton Lundin glance@acc.umu.se