mirror of
https://github.com/httpie/cli.git
synced 2024-11-24 08:22:22 +02:00
Changed default --print to "b" if stdout piped.
If the output is piped to another program or redirected to a file, the new default behaviour is to only print the response body. (It can still be overriden via the ``--print`` flag.)
This commit is contained in:
parent
7d82b853ae
commit
57fc606f6b
@ -143,13 +143,13 @@ case it will be used with no further processing::
|
||||
That can be used for **piping services together**. The following example
|
||||
``GET``-s JSON data from the Github API and ``POST``-s it to httpbin.org::
|
||||
|
||||
http -b GET https://api.github.com/repos/jkbr/httpie | http POST httpbin.org/post
|
||||
http GET https://api.github.com/repos/jkbr/httpie | http POST httpbin.org/post
|
||||
|
||||
The above can be further simplified by omitting ``GET`` and ``POST`` because
|
||||
they are both default here. The first command has no request data, whereas
|
||||
the second one does via ``stdin``::
|
||||
|
||||
http -b https://api.github.com/repos/jkbr/httpie | http httpbin.org/post
|
||||
http https://api.github.com/repos/jkbr/httpie | http httpbin.org/post
|
||||
|
||||
An alternative to ``stdin`` is to pass a file name whose content will be used
|
||||
as the request body. It has the advantage that the ``Content-Type`` header
|
||||
@ -284,6 +284,9 @@ Changelog
|
||||
---------
|
||||
|
||||
* `0.2.6dev <https://github.com/jkbr/httpie/compare/0.2.5...master>`_
|
||||
* If the output is piped to another program or redirected to a file,
|
||||
the new default behaviour is to only print the response body.
|
||||
(It can still be overriden via the ``--print`` flag.)
|
||||
* Improved highlighing of HTTP headers.
|
||||
* Added query string parameters (param=:value).
|
||||
* Added support for terminal colors under Windows.
|
||||
|
@ -117,11 +117,14 @@ def main(args=None,
|
||||
stdin=sys.stdin, stdin_isatty=sys.stdin.isatty(),
|
||||
stdout=sys.stdout, stdout_isatty=sys.stdout.isatty()):
|
||||
parser = cli.parser
|
||||
|
||||
args = parser.parse_args(
|
||||
args=args if args is not None else sys.argv[1:],
|
||||
stdin=stdin,
|
||||
stdin_isatty=stdin_isatty
|
||||
stdin_isatty=stdin_isatty,
|
||||
stdout_isatty=stdout_isatty,
|
||||
)
|
||||
|
||||
response = _get_response(args)
|
||||
output = _get_output(args, stdout_isatty, response)
|
||||
output_bytes = output.encode('utf8')
|
||||
|
@ -72,15 +72,16 @@ prettify.add_argument(
|
||||
|
||||
output_options = parser.add_mutually_exclusive_group(required=False)
|
||||
output_options.add_argument('--print', '-p', dest='output_options',
|
||||
default=cliparse.OUT_RESP_HEADERS + cliparse.OUT_RESP_BODY,
|
||||
help=_('''
|
||||
String specifying what should the output contain.
|
||||
"{request_headers}" stands for the request headers and
|
||||
String specifying what the output should contain:
|
||||
"{request_headers}" stands for the request headers, and
|
||||
"{request_body}" for the request body.
|
||||
"{response_headers}" stands for the response headers and
|
||||
"{response_body}" for response the body.
|
||||
Defaults to "hb" which means that the whole response
|
||||
(headers and body) is printed.
|
||||
The default behaviour is "hb" (i.e., the response
|
||||
headers and body is printed), if standard output is not redirected.
|
||||
If the output is piped to another program or to a file,
|
||||
then only the body is printed by default.
|
||||
'''.format(
|
||||
request_headers=cliparse.OUT_REQ_HEADERS,
|
||||
request_body=cliparse.OUT_REQ_BODY,
|
||||
@ -212,7 +213,7 @@ parser.add_argument(
|
||||
A key-value pair whose type is defined by the
|
||||
separator used. It can be an HTTP header (header:value),
|
||||
a data field to be used in the request body (field_name=value),
|
||||
a raw JSON data field (field_name:=value),
|
||||
a raw JSON data field (field_name:=value),
|
||||
a query parameter (name=:value),
|
||||
or a file field (field_name@/path/to/file).
|
||||
You can use a backslash to escape a colliding
|
||||
|
@ -52,11 +52,12 @@ class Parser(argparse.ArgumentParser):
|
||||
|
||||
def parse_args(self, args=None, namespace=None,
|
||||
stdin=sys.stdin,
|
||||
stdin_isatty=sys.stdin.isatty()):
|
||||
stdin_isatty=sys.stdin.isatty(),
|
||||
stdout_isatty=sys.stdout.isatty()):
|
||||
|
||||
args = super(Parser, self).parse_args(args, namespace)
|
||||
|
||||
self._validate_output_options(args)
|
||||
self._process_output_options(args, stdout_isatty)
|
||||
self._validate_auth_options(args)
|
||||
self._guess_method(args, stdin_isatty)
|
||||
self._parse_items(args)
|
||||
@ -120,7 +121,8 @@ class Parser(argparse.ArgumentParser):
|
||||
|
||||
def _parse_items(self, args):
|
||||
"""
|
||||
Parse `args.items` into `args.headers`, `args.data`, `args.queries`, and `args.files`.
|
||||
Parse `args.items` into `args.headers`,
|
||||
`args.data`, `args.queries`, and `args.files`.
|
||||
|
||||
"""
|
||||
args.headers = CaseInsensitiveDict()
|
||||
@ -129,8 +131,11 @@ class Parser(argparse.ArgumentParser):
|
||||
args.files = OrderedDict()
|
||||
args.queries = CaseInsensitiveDict()
|
||||
try:
|
||||
parse_items(items=args.items, headers=args.headers,
|
||||
data=args.data, files=args.files, queries=args.queries)
|
||||
parse_items(items=args.items,
|
||||
headers=args.headers,
|
||||
data=args.data,
|
||||
files=args.files,
|
||||
queries=args.queries)
|
||||
except ParseError as e:
|
||||
if args.traceback:
|
||||
raise
|
||||
@ -157,7 +162,13 @@ class Parser(argparse.ArgumentParser):
|
||||
content_type = '%s; charset=%s' % (mime, encoding)
|
||||
args.headers['Content-Type'] = content_type
|
||||
|
||||
def _validate_output_options(self, args):
|
||||
def _process_output_options(self, args, stdout_isatty):
|
||||
if not args.output_options:
|
||||
if stdout_isatty:
|
||||
args.output_options = OUT_RESP_HEADERS + OUT_RESP_BODY
|
||||
else:
|
||||
args.output_options = OUT_RESP_BODY
|
||||
|
||||
unknown = set(args.output_options) - set(OUTPUT_OPTIONS)
|
||||
if unknown:
|
||||
self.error(
|
||||
@ -270,7 +281,11 @@ class AuthCredentialsType(KeyValueType):
|
||||
|
||||
|
||||
def parse_items(items, data=None, headers=None, files=None, queries=None):
|
||||
"""Parse `KeyValueType` `items` into `data`, `headers`, `files`, and `queries`."""
|
||||
"""
|
||||
Parse `KeyValueType` `items` into `data`, `headers`, `files`,
|
||||
and `queries`.
|
||||
|
||||
"""
|
||||
if headers is None:
|
||||
headers = {}
|
||||
if data is None:
|
||||
|
@ -34,9 +34,19 @@ def http(*args, **kwargs):
|
||||
"""
|
||||
http_kwargs = {
|
||||
'stdin_isatty': True,
|
||||
'stdout_isatty': False
|
||||
'stdout_isatty': True
|
||||
}
|
||||
http_kwargs.update(kwargs)
|
||||
|
||||
command_line = ' '.join(args)
|
||||
if ('stdout_isatty' not in kwargs
|
||||
and '--pretty' not in command_line
|
||||
and '--ugly' not in command_line):
|
||||
# Make ugly default for testing purposes unless we're
|
||||
# being explicit about it. It's so that we can test for
|
||||
# strings in the response without having to always pass --ugly.
|
||||
args = ['--ugly'] + list(args)
|
||||
|
||||
stdout = http_kwargs.setdefault('stdout', tempfile.TemporaryFile())
|
||||
__main__.main(args=args, **http_kwargs)
|
||||
stdout.seek(0)
|
||||
@ -168,6 +178,14 @@ class AutoContentTypeAndAcceptHeadersTest(BaseTestCase):
|
||||
self.assertIn('HTTP/1.1 200', r)
|
||||
self.assertIn('"Content-Type": "application/xml"', r)
|
||||
|
||||
def test_print_only_body_when_stdout_redirected_by_default(self):
|
||||
r = http('GET', 'httpbin.org/get', stdout_isatty=False)
|
||||
self.assertNotIn('HTTP/', r)
|
||||
|
||||
def test_print_overridable_when_stdout_redirected(self):
|
||||
r = http('--print=h', 'GET', 'httpbin.org/get', stdout_isatty=False)
|
||||
self.assertIn('HTTP/1.1 200', r)
|
||||
|
||||
|
||||
class ImplicitHTTPMethodTest(BaseTestCase):
|
||||
|
||||
@ -203,7 +221,7 @@ class PrettyFlagTest(BaseTestCase):
|
||||
r = http('GET', 'http://httpbin.org/get', stdout_isatty=True)
|
||||
self.assertIn(TERMINAL_COLOR_PRESENCE_CHECK, r)
|
||||
|
||||
def test_pretty_enabled_by_default_unless_stdin_redirected(self):
|
||||
def test_pretty_enabled_by_default_unless_stdout_redirected(self):
|
||||
r = http('GET', 'http://httpbin.org/get', stdout_isatty=False)
|
||||
self.assertNotIn(TERMINAL_COLOR_PRESENCE_CHECK, r)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user