You've already forked httpie-cli
mirror of
https://github.com/httpie/cli.git
synced 2026-06-20 11:32:56 +02:00
Allow embeding text (=@) and JSON (:=@) files content into request data fields.
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@ HTTPie - a CLI, cURL-like tool for humans.
|
||||
|
||||
"""
|
||||
__author__ = 'Jakub Roztocil'
|
||||
__version__ = '0.7.1'
|
||||
__version__ = '0.8.0-dev'
|
||||
__licence__ = 'BSD'
|
||||
|
||||
|
||||
|
||||
+12
-4
@@ -15,7 +15,7 @@ from .plugins import plugin_manager
|
||||
from .sessions import DEFAULT_SESSIONS_DIR
|
||||
from .output import AVAILABLE_STYLES, DEFAULT_STYLE
|
||||
from .input import (Parser, AuthCredentialsArgType, KeyValueArgType,
|
||||
SEP_PROXY, SEP_CREDENTIALS, SEP_GROUP_ITEMS,
|
||||
SEP_PROXY, SEP_CREDENTIALS, SEP_GROUP_ALL_ITEMS,
|
||||
OUT_REQ_HEAD, OUT_REQ_BODY, OUT_RESP_HEAD,
|
||||
OUT_RESP_BODY, OUTPUT_OPTIONS, OUTPUT_OPTIONS_DEFAULT,
|
||||
PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY, SessionNameValidator)
|
||||
@@ -94,7 +94,7 @@ positional.add_argument(
|
||||
'items',
|
||||
metavar='REQUEST ITEM',
|
||||
nargs=ZERO_OR_MORE,
|
||||
type=KeyValueArgType(*SEP_GROUP_ITEMS),
|
||||
type=KeyValueArgType(*SEP_GROUP_ALL_ITEMS),
|
||||
help=r"""
|
||||
Optional key-value pairs to be included in the request. The separator used
|
||||
determines the type:
|
||||
@@ -112,13 +112,21 @@ positional.add_argument(
|
||||
|
||||
name=HTTPie language=Python description='CLI HTTP client'
|
||||
|
||||
':=' Non-string JSON data fields (only with --json, -j):
|
||||
|
||||
awesome:=true amount:=42 colors:='["red", "green", "blue"]'
|
||||
|
||||
'@' Form file fields (only with --form, -f):
|
||||
|
||||
cs@~/Documents/CV.pdf
|
||||
|
||||
':=' Non-string JSON data fields (only with --json, -j):
|
||||
'=@' A data field like '=', but takes a file path and embeds its content:
|
||||
|
||||
awesome:=true amount:=42 colors:='["red", "green", "blue"]'
|
||||
essay=@Documents/essay.txt
|
||||
|
||||
':=@' A raw JSON field like ':=', but takes a file path and embeds its content:
|
||||
|
||||
package:=@./package.json
|
||||
|
||||
You can use a backslash to escape a colliding separator in the field name:
|
||||
|
||||
|
||||
+37
-14
@@ -37,22 +37,40 @@ SEP_PROXY = ':'
|
||||
SEP_DATA = '='
|
||||
SEP_DATA_RAW_JSON = ':='
|
||||
SEP_FILES = '@'
|
||||
SEP_DATA_EMBED_FILE = '=@'
|
||||
SEP_DATA_EMBED_RAW_JSON_FILE = ':=@'
|
||||
SEP_QUERY = '=='
|
||||
|
||||
# Separators that become request data
|
||||
SEP_GROUP_DATA_ITEMS = frozenset([
|
||||
SEP_DATA,
|
||||
SEP_DATA_RAW_JSON,
|
||||
SEP_FILES
|
||||
SEP_FILES,
|
||||
SEP_DATA_EMBED_FILE,
|
||||
SEP_DATA_EMBED_RAW_JSON_FILE
|
||||
])
|
||||
|
||||
# Separators for items whose value is a filename to be embedded
|
||||
SEP_GROUP_DATA_EMBED_ITEMS = frozenset([
|
||||
SEP_DATA_EMBED_FILE,
|
||||
SEP_DATA_EMBED_RAW_JSON_FILE,
|
||||
])
|
||||
|
||||
# Separators for raw JSON items
|
||||
SEP_GROUP_RAW_JSON_ITEMS = frozenset([
|
||||
SEP_DATA_RAW_JSON,
|
||||
SEP_DATA_EMBED_RAW_JSON_FILE,
|
||||
])
|
||||
|
||||
# Separators allowed in ITEM arguments
|
||||
SEP_GROUP_ITEMS = frozenset([
|
||||
SEP_GROUP_ALL_ITEMS = frozenset([
|
||||
SEP_HEADERS,
|
||||
SEP_QUERY,
|
||||
SEP_DATA,
|
||||
SEP_DATA_RAW_JSON,
|
||||
SEP_FILES
|
||||
SEP_FILES,
|
||||
SEP_DATA_EMBED_FILE,
|
||||
SEP_DATA_EMBED_RAW_JSON_FILE,
|
||||
])
|
||||
|
||||
|
||||
@@ -257,7 +275,7 @@ class Parser(ArgumentParser):
|
||||
# Parse the URL as an ITEM and store it as the first ITEM arg.
|
||||
self.args.items.insert(
|
||||
0,
|
||||
KeyValueArgType(*SEP_GROUP_ITEMS).__call__(self.args.url)
|
||||
KeyValueArgType(*SEP_GROUP_ALL_ITEMS).__call__(self.args.url)
|
||||
)
|
||||
|
||||
except ArgumentTypeError as e:
|
||||
@@ -558,9 +576,7 @@ def parse_items(items, data=None, headers=None, files=None, params=None):
|
||||
params = ParamDict()
|
||||
|
||||
for item in items:
|
||||
|
||||
value = item.value
|
||||
key = item.key
|
||||
|
||||
if item.sep == SEP_HEADERS:
|
||||
target = headers
|
||||
@@ -572,21 +588,28 @@ def parse_items(items, data=None, headers=None, files=None, params=None):
|
||||
value = (os.path.basename(value),
|
||||
BytesIO(f.read()))
|
||||
except IOError as e:
|
||||
raise ParseError(
|
||||
'Invalid argument "%s": %s' % (item.orig, e))
|
||||
raise ParseError('"%s": %s' % (item.orig, e))
|
||||
target = files
|
||||
|
||||
elif item.sep in [SEP_DATA, SEP_DATA_RAW_JSON]:
|
||||
if item.sep == SEP_DATA_RAW_JSON:
|
||||
elif item.sep in SEP_GROUP_DATA_ITEMS:
|
||||
|
||||
if item.sep in SEP_GROUP_DATA_EMBED_ITEMS:
|
||||
try:
|
||||
value = json.loads(item.value)
|
||||
except ValueError:
|
||||
raise ParseError('"%s" is not valid JSON' % item.orig)
|
||||
with open(os.path.expanduser(value), 'rb') as f:
|
||||
value = f.read()
|
||||
except IOError as e:
|
||||
raise ParseError('%s": %s' % (item.orig, e))
|
||||
|
||||
if item.sep in SEP_GROUP_RAW_JSON_ITEMS:
|
||||
try:
|
||||
value = json.loads(value)
|
||||
except ValueError as e:
|
||||
raise ParseError('"%s": %s' % (item.orig, e))
|
||||
target = data
|
||||
|
||||
else:
|
||||
raise TypeError(item)
|
||||
|
||||
target[key] = value
|
||||
target[item.key] = value
|
||||
|
||||
return headers, data, files, params
|
||||
|
||||
Reference in New Issue
Block a user