1
0
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:
Jakub Roztocil 2012-07-20 23:43:04 +02:00
parent 7d82b853ae
commit 57fc606f6b
5 changed files with 58 additions and 18 deletions

View File

@ -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.

View File

@ -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')

View File

@ -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

View File

@ -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:

View File

@ -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)