mirror of
https://github.com/httpie/cli.git
synced 2024-12-23 23:09:17 +01:00
Fixed several unicode-related issues
Closes #31 Python 3 & non-ascii arguments => UnicodeEncodeError Closes #41 Unicode response error. Closes #42 UnicodeEncodeError when piping Unicode output
This commit is contained in:
parent
29e594daaf
commit
67d6426360
@ -6,7 +6,7 @@ try:
|
||||
except ImportError:
|
||||
OrderedDict = dict
|
||||
import requests
|
||||
from requests.compat import urlparse, str
|
||||
from requests.compat import urlparse, str, is_py3
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
from . import cli
|
||||
from . import pretty
|
||||
@ -165,30 +165,35 @@ def main(args=None,
|
||||
|
||||
prettifier = pretty.PrettyHttp(args.style) if do_prettify else None
|
||||
|
||||
output_request = (cli.OUT_REQUEST_HEADERS in args.output_options
|
||||
or cli.OUT_REQUEST_BODY in args.output_options)
|
||||
do_output_request = (cli.OUT_REQ_HEADERS in args.output_options
|
||||
or cli.OUT_REQ_BODY in args.output_options)
|
||||
|
||||
output_response = (cli.OUT_RESPONSE_HEADERS in args.output_options
|
||||
or cli.OUT_RESPONSE_BODY in args.output_options)
|
||||
do_output_response = (cli.OUT_RESP_HEADERS in args.output_options
|
||||
or cli.OUT_RESP_BODY in args.output_options)
|
||||
|
||||
if output_request:
|
||||
stdout.write(format_http_message(
|
||||
output = []
|
||||
if do_output_request:
|
||||
output.append(format_http_message(
|
||||
message=make_request_message(response.request),
|
||||
prettifier=prettifier,
|
||||
with_headers=cli.OUT_REQUEST_HEADERS in args.output_options,
|
||||
with_body=cli.OUT_REQUEST_BODY in args.output_options
|
||||
with_headers=cli.OUT_REQ_HEADERS in args.output_options,
|
||||
with_body=cli.OUT_REQ_BODY in args.output_options
|
||||
))
|
||||
if output_response:
|
||||
stdout.write(NEW_LINE)
|
||||
if do_output_response:
|
||||
output.append(NEW_LINE)
|
||||
|
||||
if output_response:
|
||||
stdout.write(format_http_message(
|
||||
if do_output_response:
|
||||
output.append(format_http_message(
|
||||
message=make_response_message(response),
|
||||
prettifier=prettifier,
|
||||
with_headers=cli.OUT_RESPONSE_HEADERS in args.output_options,
|
||||
with_body=cli.OUT_RESPONSE_BODY in args.output_options
|
||||
with_headers=cli.OUT_RESP_HEADERS in args.output_options,
|
||||
with_body=cli.OUT_RESP_BODY in args.output_options
|
||||
))
|
||||
stdout.write(NEW_LINE)
|
||||
output.append(NEW_LINE)
|
||||
|
||||
output_bytes = ''.join(output).encode('utf8')
|
||||
f = (stdout.buffer if is_py3 and hasattr(stdout, 'buffer') else stdout)
|
||||
f.write(output_bytes)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -13,18 +13,20 @@ SEP_HEADERS = SEP_COMMON
|
||||
SEP_DATA = '='
|
||||
SEP_DATA_RAW_JSON = ':='
|
||||
SEP_FILES = '@'
|
||||
|
||||
|
||||
OUT_REQ_HEADERS = 'H'
|
||||
OUT_REQ_BODY = 'B'
|
||||
OUT_RESP_HEADERS = 'h'
|
||||
OUT_RESP_BODY = 'b'
|
||||
OUTPUT_OPTIONS = [OUT_REQ_HEADERS,
|
||||
OUT_REQ_BODY,
|
||||
OUT_RESP_HEADERS,
|
||||
OUT_RESP_BODY]
|
||||
|
||||
|
||||
PRETTIFY_STDOUT_TTY_ONLY = object()
|
||||
|
||||
OUT_REQUEST_HEADERS = 'H'
|
||||
OUT_REQUEST_BODY = 'B'
|
||||
OUT_RESPONSE_HEADERS = 'h'
|
||||
OUT_RESPONSE_BODY = 'b'
|
||||
|
||||
OUTPUT_OPTIONS = [OUT_REQUEST_HEADERS,
|
||||
OUT_REQUEST_BODY,
|
||||
OUT_RESPONSE_HEADERS,
|
||||
OUT_RESPONSE_BODY]
|
||||
|
||||
|
||||
class ParseError(Exception):
|
||||
pass
|
||||
@ -34,6 +36,7 @@ KeyValue = namedtuple('KeyValue', ['key', 'value', 'sep', 'orig'])
|
||||
|
||||
class KeyValueType(object):
|
||||
"""A type used with `argparse`."""
|
||||
|
||||
def __init__(self, *separators):
|
||||
self.separators = separators
|
||||
self.escapes = ['\\\\' + sep for sep in separators]
|
||||
@ -56,7 +59,6 @@ class KeyValueType(object):
|
||||
found[start] = sep
|
||||
|
||||
if not found:
|
||||
#noinspection PyExceptionInherit
|
||||
raise argparse.ArgumentTypeError(
|
||||
'"%s" is not a valid value' % string)
|
||||
|
||||
@ -160,7 +162,7 @@ group_type.add_argument(
|
||||
)
|
||||
|
||||
|
||||
# output_options options.
|
||||
# Output options.
|
||||
#############################################
|
||||
|
||||
parser.add_argument(
|
||||
@ -189,7 +191,7 @@ prettify.add_argument(
|
||||
|
||||
output_options = parser.add_mutually_exclusive_group(required=False)
|
||||
output_options.add_argument('--print', '-p', dest='output_options',
|
||||
default=OUT_RESPONSE_HEADERS + OUT_RESPONSE_BODY,
|
||||
default=OUT_RESP_HEADERS + OUT_RESP_BODY,
|
||||
help=_('''
|
||||
String specifying what should the output contain.
|
||||
"{request_headers}" stands for request headers and
|
||||
@ -199,10 +201,10 @@ output_options.add_argument('--print', '-p', dest='output_options',
|
||||
Defaults to "hb" which means that the whole response
|
||||
(headers and body) is printed.
|
||||
'''.format(
|
||||
request_headers=OUT_REQUEST_HEADERS,
|
||||
request_body=OUT_REQUEST_BODY,
|
||||
response_headers=OUT_RESPONSE_HEADERS,
|
||||
response_body=OUT_RESPONSE_BODY,
|
||||
request_headers=OUT_REQ_HEADERS,
|
||||
request_body=OUT_REQ_BODY,
|
||||
response_headers=OUT_RESP_HEADERS,
|
||||
response_body=OUT_RESP_BODY,
|
||||
))
|
||||
)
|
||||
output_options.add_argument(
|
||||
@ -215,19 +217,19 @@ output_options.add_argument(
|
||||
)
|
||||
output_options.add_argument(
|
||||
'--headers', '-t', dest='output_options',
|
||||
action='store_const', const=OUT_RESPONSE_HEADERS,
|
||||
action='store_const', const=OUT_RESP_HEADERS,
|
||||
help=_('''
|
||||
Print only the response headers.
|
||||
Shortcut for --print={0}.
|
||||
'''.format(OUT_RESPONSE_HEADERS))
|
||||
'''.format(OUT_RESP_HEADERS))
|
||||
)
|
||||
output_options.add_argument(
|
||||
'--body', '-b', dest='output_options',
|
||||
action='store_const', const=OUT_RESPONSE_BODY,
|
||||
action='store_const', const=OUT_RESP_BODY,
|
||||
help=_('''
|
||||
Print only the response body.
|
||||
Shortcut for --print={0}.
|
||||
'''.format(OUT_RESPONSE_BODY))
|
||||
'''.format(OUT_RESP_BODY))
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
|
@ -3,7 +3,8 @@ import os
|
||||
import sys
|
||||
import unittest
|
||||
import argparse
|
||||
from requests.compat import StringIO, is_py26, str
|
||||
from requests.compat import is_py26
|
||||
import tempfile
|
||||
|
||||
|
||||
TESTS_ROOT = os.path.dirname(__file__)
|
||||
@ -22,9 +23,12 @@ def http(*args, **kwargs):
|
||||
'stdout_isatty': False
|
||||
}
|
||||
http_kwargs.update(kwargs)
|
||||
stdout = http_kwargs.setdefault('stdout', StringIO())
|
||||
stdout = http_kwargs.setdefault('stdout', tempfile.TemporaryFile())
|
||||
__main__.main(args=args, **http_kwargs)
|
||||
return stdout.getvalue()
|
||||
stdout.seek(0)
|
||||
response = stdout.read().decode('utf8')
|
||||
stdout.close()
|
||||
return response
|
||||
|
||||
|
||||
class BaseTest(unittest.TestCase):
|
||||
@ -83,7 +87,7 @@ class TestItemParsing(BaseTest):
|
||||
self.assertDictEqual(data, {
|
||||
'bob:=': 'foo',
|
||||
})
|
||||
|
||||
|
||||
def test_valid_items(self):
|
||||
headers, data, files = cli.parse_items([
|
||||
self.kv('string=value'),
|
||||
|
Loading…
Reference in New Issue
Block a user