mirror of
https://github.com/httpie/cli.git
synced 2024-11-28 08:38:44 +02:00
Finish --quiet
This commit is contained in:
parent
2c7f24e3e5
commit
1aa1366f99
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://paypal.me/roztocil
|
||||
custom:
|
||||
|
@ -10,8 +10,8 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
|
||||
-------------------------
|
||||
* Added support for combining cookies specified on the CLI and in a session file (`#932`_).
|
||||
* Added out of the box SOCKS support with no extra installation (`#904`_).
|
||||
* Added ``--quiet, -q`` flag to enforce silent behaviour.
|
||||
* Removed Tox testing entirely (`#943`_).
|
||||
* Added a ``--quiet`` flag to enforce silent behaviour.
|
||||
|
||||
|
||||
`2.2.0`_ (2020-06-18)
|
||||
|
58
README.rst
58
README.rst
@ -1156,12 +1156,34 @@ be printed via several options:
|
||||
``--verbose, -v`` Print the whole HTTP exchange (request and response).
|
||||
This option also enables ``--all`` (see below).
|
||||
``--print, -p`` Selects parts of the HTTP exchange.
|
||||
``--quiet, -q`` Doesn't print anything. Overrides other output flags.
|
||||
``--quiet, -q`` Don't print anything to ``stdout`` and ``stderr``.
|
||||
================= =====================================================
|
||||
If ``--quiet`` is used in conjuction with ``--output`` the flag is ignored
|
||||
and ``stdout`` is still redirected. If ``--quiet`` is used with ``--download``
|
||||
file is still downloaded as usual but ``stdout`` and ``stdin`` are redirected
|
||||
to ``devnull``.
|
||||
|
||||
|
||||
What parts of the HTTP exchange should be printed
|
||||
-------------------------------------------------
|
||||
|
||||
All the other `output options`_ are under the hood just shortcuts for
|
||||
the more powerful ``--print, -p``. It accepts a string of characters each
|
||||
of which represents a specific part of the HTTP exchange:
|
||||
|
||||
========== ==================
|
||||
Character Stands for
|
||||
========== ==================
|
||||
``H`` request headers
|
||||
``B`` request body
|
||||
``h`` response headers
|
||||
``b`` response body
|
||||
========== ==================
|
||||
|
||||
Print request and response headers:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ http --print=Hh PUT httpbin.org/put hello=world
|
||||
|
||||
Verbose output
|
||||
--------------
|
||||
|
||||
``--verbose`` can often be useful for debugging the request and generating
|
||||
documentation examples:
|
||||
@ -1192,28 +1214,12 @@ documentation examples:
|
||||
[…]
|
||||
}
|
||||
|
||||
Quiet output
|
||||
------------
|
||||
|
||||
What parts of the HTTP exchange should be printed
|
||||
-------------------------------------------------
|
||||
|
||||
All the other `output options`_ are under the hood just shortcuts for
|
||||
the more powerful ``--print, -p``. It accepts a string of characters each
|
||||
of which represents a specific part of the HTTP exchange:
|
||||
|
||||
========== ==================
|
||||
Character Stands for
|
||||
========== ==================
|
||||
``H`` request headers
|
||||
``B`` request body
|
||||
``h`` response headers
|
||||
``b`` response body
|
||||
========== ==================
|
||||
|
||||
Print request and response headers:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ http --print=Hh PUT httpbin.org/put hello=world
|
||||
``--quiet`` redirects all output that would otherwise go to ``stdout``
|
||||
and ``stderr`` (except for error messages) to ``/dev/null``.
|
||||
This doesn’t affect output to a file via ``--output`` or ``--download``.
|
||||
|
||||
|
||||
Viewing intermediary requests/responses
|
||||
|
@ -35,7 +35,6 @@ class Environment:
|
||||
stdout_encoding: str = None
|
||||
stderr: IO = sys.stderr
|
||||
stderr_isatty: bool = stderr.isatty()
|
||||
_devnull = None
|
||||
colors = 256
|
||||
program_name: str = 'http'
|
||||
if not is_windows:
|
||||
@ -58,7 +57,7 @@ class Environment:
|
||||
)
|
||||
del colorama
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, devnull=None, **kwargs):
|
||||
"""
|
||||
Use keyword arguments to overwrite
|
||||
any of the class attributes for this instance.
|
||||
@ -67,6 +66,10 @@ class Environment:
|
||||
assert all(hasattr(type(self), attr) for attr in kwargs.keys())
|
||||
self.__dict__.update(**kwargs)
|
||||
|
||||
# The original STDERR unaffected by --quiet’ing.
|
||||
self._orig_stderr = self.stderr
|
||||
self._devnull = devnull
|
||||
|
||||
# Keyword arguments > stream.encoding > default utf8
|
||||
if self.stdin and self.stdin_encoding is None:
|
||||
self.stdin_encoding = getattr(
|
||||
@ -122,4 +125,4 @@ class Environment:
|
||||
|
||||
def log_error(self, msg, level='error'):
|
||||
assert level in ['error', 'warning']
|
||||
self.stderr.write(f'\n{self.program_name}: {level}: {msg}\n\n')
|
||||
self._orig_stderr.write(f'\n{self.program_name}: {level}: {msg}\n\n')
|
||||
|
@ -183,52 +183,11 @@ class TestDownloads:
|
||||
# Redirect from `/redirect/1` to `/get`.
|
||||
expected_filename = '1.json'
|
||||
orig_cwd = os.getcwd()
|
||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_test_'))
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
http('--download', httpbin.url + '/redirect/1')
|
||||
assert os.listdir('.') == [expected_filename]
|
||||
finally:
|
||||
os.chdir(orig_cwd)
|
||||
|
||||
def test_download_with_quiet_flag(self, httpbin):
|
||||
robots_txt = '/robots.txt'
|
||||
expected_body = requests.get(httpbin + robots_txt).text
|
||||
expected_filename = 'robots.txt'
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
orig_cwd = os.getcwd()
|
||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_quiet_test_'))
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
r = http('--quiet', '--download', httpbin + robots_txt, env=env)
|
||||
assert os.listdir('.') == [expected_filename]
|
||||
assert r.stderr == ''
|
||||
assert env.devnull == env.stderr
|
||||
assert env.devnull == env.stdout
|
||||
with open(expected_filename, 'r') as f:
|
||||
assert f.read() == expected_body
|
||||
finally:
|
||||
os.chdir(orig_cwd)
|
||||
|
||||
def test_download_with_quiet_and_output_flag(self, httpbin):
|
||||
robots_txt = '/robots.txt'
|
||||
expected_body = requests.get(httpbin + robots_txt).text
|
||||
expected_filename = 'test.txt'
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
orig_cwd = os.getcwd()
|
||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_quiet_test_'))
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
r = http('--quiet',
|
||||
'--download',
|
||||
'--output=' + expected_filename,
|
||||
httpbin + robots_txt,
|
||||
env=env)
|
||||
assert os.listdir('.') == [expected_filename]
|
||||
assert r.stderr == ''
|
||||
assert env.devnull == env.stderr
|
||||
assert env.devnull == env.stdout
|
||||
with open(expected_filename, 'r') as f:
|
||||
assert f.read() == expected_body
|
||||
finally:
|
||||
os.chdir(orig_cwd)
|
||||
with tempfile.TemporaryDirectory() as tmp_dirname:
|
||||
os.chdir(tmp_dirname)
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
http('--download', httpbin.url + '/redirect/1')
|
||||
assert os.listdir('.') == [expected_filename]
|
||||
finally:
|
||||
os.chdir(orig_cwd)
|
||||
|
@ -1,4 +1,6 @@
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
import mock
|
||||
import json
|
||||
import os
|
||||
@ -40,69 +42,81 @@ class TestQuietFlag:
|
||||
|
||||
@pytest.mark.parametrize('argument_name', ['--quiet', '-q'])
|
||||
def test_quiet(self, httpbin, argument_name):
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
env = MockEnvironment(
|
||||
stdin_isatty=True,
|
||||
stdout_isatty=True,
|
||||
devnull=io.BytesIO()
|
||||
)
|
||||
r = http(argument_name, 'GET', httpbin.url + '/get', env=env)
|
||||
assert env.stdout == env.devnull
|
||||
assert env.stderr == env.devnull
|
||||
assert r.stderr == ''
|
||||
assert str(r) == ''
|
||||
|
||||
@pytest.mark.parametrize('argument_name', ['--quiet', '-q'])
|
||||
def test_quiet_correct_message(self, httpbin, argument_name):
|
||||
sim_devnull = io.BytesIO()
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
env.devnull = sim_devnull
|
||||
r = http(argument_name, 'GET', httpbin.url + '/get', env=env)
|
||||
assert env.stdout == env.devnull
|
||||
assert env.stderr == env.devnull
|
||||
assert r.stderr == ''
|
||||
assert env.stdout is env.devnull
|
||||
assert env.stderr is env.devnull
|
||||
assert HTTP_OK in r.devnull
|
||||
assert str(r) == ''
|
||||
assert r == ''
|
||||
assert r.stderr == ''
|
||||
|
||||
@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
|
||||
new=lambda self, prompt: 'password')
|
||||
def test_quiet_password_prompt(self, httpbin):
|
||||
""" Tests whether httpie still prompts for password when request
|
||||
requires authetication and only username is provided"""
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
env.devnull = io.BytesIO()
|
||||
r = http('--quiet', '--auth', 'user', 'GET', httpbin.url + '/basic-auth/user/password', env=env)
|
||||
def test_quiet_with_password_prompt(self, httpbin):
|
||||
"""
|
||||
Tests whether httpie still prompts for a password when request
|
||||
requires authentication and only username is provided
|
||||
|
||||
"""
|
||||
env = MockEnvironment(
|
||||
stdin_isatty=True,
|
||||
stdout_isatty=True,
|
||||
devnull=io.BytesIO()
|
||||
)
|
||||
r = http(
|
||||
'--quiet', '--auth', 'user', 'GET',
|
||||
httpbin.url + '/basic-auth/user/password',
|
||||
env=env
|
||||
)
|
||||
assert env.stdout is env.devnull
|
||||
assert env.stderr is env.devnull
|
||||
assert HTTP_OK in r.devnull
|
||||
assert env.stdout == env.devnull
|
||||
assert env.stderr == env.devnull
|
||||
assert str(r) == ''
|
||||
assert r == ''
|
||||
assert r.stderr == ''
|
||||
|
||||
@pytest.mark.parametrize('argument_name', ['-h', '-b', '-v', '-p=hH'])
|
||||
def test_quiet_flag_overrides_other_output_options(self, httpbin, argument_name):
|
||||
def test_quiet_with_explicit_output_options(self, httpbin, argument_name):
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
r = http('--quiet', argument_name, httpbin.url + '/GET', env=env)
|
||||
assert env.stdout == env.devnull
|
||||
assert env.stderr == env.devnull
|
||||
assert str(r) == ''
|
||||
r = http('--quiet', argument_name, httpbin.url + '/get', env=env)
|
||||
assert env.stdout is env.devnull
|
||||
assert env.stderr is env.devnull
|
||||
assert r == ''
|
||||
assert r.stderr == ''
|
||||
|
||||
def test_quiet_flag_with_output_redirection(self, httpbin):
|
||||
robots_txt = '/robots.txt'
|
||||
expected_body = requests.get(httpbin + robots_txt).text
|
||||
expected_filename = 'test.txt'
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
@pytest.mark.parametrize('with_download', [True, False])
|
||||
def test_quiet_with_output_redirection(self, httpbin, with_download):
|
||||
url = httpbin + '/robots.txt'
|
||||
output_path = Path('output.txt')
|
||||
env = MockEnvironment()
|
||||
orig_cwd = os.getcwd()
|
||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_quiet_test_'))
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
r = http('--quiet',
|
||||
'--output=' + expected_filename,
|
||||
httpbin + robots_txt,
|
||||
env=env)
|
||||
assert os.listdir('.') == [expected_filename]
|
||||
assert r.stderr == ''
|
||||
assert env.devnull == env.stderr
|
||||
assert env.devnull != env.stdout
|
||||
with open(expected_filename, 'r') as f:
|
||||
assert f.read() == expected_body
|
||||
finally:
|
||||
os.chdir(orig_cwd)
|
||||
output = requests.get(url).text
|
||||
extra_args = ['--download'] if with_download else []
|
||||
with tempfile.TemporaryDirectory() as tmp_dirname:
|
||||
os.chdir(tmp_dirname)
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
r = http(
|
||||
'--quiet',
|
||||
'--output', str(output_path),
|
||||
*extra_args,
|
||||
url,
|
||||
env=env
|
||||
)
|
||||
assert os.listdir('.') == [str(output_path)]
|
||||
assert r == ''
|
||||
assert r.stderr == ''
|
||||
assert env.stderr is env.devnull
|
||||
if with_download:
|
||||
assert env.stdout is env.devnull
|
||||
else:
|
||||
assert env.stdout is not env.devnull # --output swaps stdout.
|
||||
assert output_path.read_text() == output
|
||||
finally:
|
||||
os.chdir(orig_cwd)
|
||||
|
||||
|
||||
class TestVerboseFlag:
|
||||
|
Loading…
Reference in New Issue
Block a user