From 0722d52af1f2c8f71a41e5f5e4e662b301c17d82 Mon Sep 17 00:00:00 2001 From: Santiago Gallego Date: Thu, 14 Jun 2018 09:03:13 +0000 Subject: [PATCH 1/3] Add '@=' separator to pass JSON objects via CLI The current '=' separator enables to add key-value pairs as strings in a JSON object to the HTTP body. But there's no way to provide more complex JSON objects This commit introduces a new '@=' that adds a key-value pair where the right value is evaluated to a JSON object, allowing more complex structures in the HTTP body. Change-Id: I126a6c8529a6dbf9108b904b2b4d93ef60309113 --- hyper/cli.py | 16 ++++++++++++++-- test/test_cli.py | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/hyper/cli.py b/hyper/cli.py index 1d5384cd..d93a7362 100644 --- a/hyper/cli.py +++ b/hyper/cli.py @@ -28,8 +28,10 @@ SEP_HEADERS = ':' SEP_QUERY = '==' SEP_DATA = '=' +SEP_JSON = '@=' SEP_GROUP_ITEMS = [ + SEP_JSON, SEP_HEADERS, SEP_QUERY, SEP_DATA, @@ -93,9 +95,13 @@ def make_positional_argument(parser): search==hyper - '=' Data fields to be serialized into a JSON object: + '=' String data fields to be serialized into a JSON object: name=Hyper language=Python description='CLI HTTP client' + + '@=' JSON data fields + + name='{"name": "John", "surname": "Doe"}' list='[1, 2, 3]' """)) @@ -167,7 +173,13 @@ def set_url_info(args): def set_request_data(args): body, headers, params = {}, {}, {} for i in args.items: - if i.sep == SEP_HEADERS: + if i.sep == SEP_JSON: + try: + value = json.loads(i.value) + body[i.key] = value + except: + log.warning('Unable to decode JSON, ignoring it (%s)', i.value) + elif i.sep == SEP_HEADERS: if i.key: headers[i.key] = i.value else: diff --git a/test/test_cli.py b/test/test_cli.py index d545c6d3..0d42b10f 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -111,6 +111,8 @@ def test_cli_with_system_exit(argv): {'method': 'GET', 'url.path': '/?param=test'}), (['POST', 'example.com', 'data=test'], {'method': 'POST', 'body': '{"data": "test"}'}), + (['POST', 'example.com', 'data@={"json":[1,2,3]}'], + {'method': 'POST', 'body': '{"data": {"json": [1, 2, 3]}}'}), (['GET', 'example.com', ':authority:example.org'], {'method': 'GET', 'headers': { ':authority': 'example.org'}}), @@ -118,14 +120,18 @@ def test_cli_with_system_exit(argv): {'method': 'GET', 'headers': { ':authority': 'example.org', 'x-test': 'header'}}), + (['POST', 'example.com', 'data@={"invalidjson":1,2,3}'], + {'body': None}), ], ids=[ 'specified "--debug" option', 'specify host with lower get method', 'specified host and additional header', 'specified host and get parameter', 'specified host and post data', + 'specified host and post JSON data', 'specified host and override default header', 'specified host and override default header and additional header', + 'specified host and post invalid JSON data', ]) def test_parse_argument(argv, expected): args = parse_argument(argv) From f76716335d00d2dfad8cefaca338156172b86284 Mon Sep 17 00:00:00 2001 From: Santiago Gallego Date: Thu, 14 Jun 2018 15:39:01 +0000 Subject: [PATCH 2/3] Capture specific exception thrown by json.loads() Change-Id: I94612a7de6f1673703571aa41679a3268086b6ba --- hyper/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyper/cli.py b/hyper/cli.py index d93a7362..b6b2860d 100644 --- a/hyper/cli.py +++ b/hyper/cli.py @@ -177,7 +177,7 @@ def set_request_data(args): try: value = json.loads(i.value) body[i.key] = value - except: + except ValueError: log.warning('Unable to decode JSON, ignoring it (%s)', i.value) elif i.sep == SEP_HEADERS: if i.key: From 230ccf936acf601794923b2b4cb76b8c3c6fdf7d Mon Sep 17 00:00:00 2001 From: Santiago Gallego Date: Thu, 14 Jun 2018 17:34:34 +0000 Subject: [PATCH 3/3] Fix separator in CLI help example Change-Id: I09cc41bead0f1ccea0d5b0c332816d2e69b2d44d --- hyper/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hyper/cli.py b/hyper/cli.py index b6b2860d..c373cc57 100644 --- a/hyper/cli.py +++ b/hyper/cli.py @@ -101,7 +101,7 @@ def make_positional_argument(parser): '@=' JSON data fields - name='{"name": "John", "surname": "Doe"}' list='[1, 2, 3]' + name@='{"name": "John", "surname": "Doe"}' list@='[1, 2, 3]' """))