mirror of
https://github.com/httpie/cli.git
synced 2025-06-24 11:33:48 +02:00
Cleanup
This commit is contained in:
parent
8175366f27
commit
53caf6ae72
@ -7,7 +7,8 @@ __version__ = '0.4.0-alpha'
|
|||||||
__licence__ = 'BSD'
|
__licence__ = 'BSD'
|
||||||
|
|
||||||
|
|
||||||
class exit:
|
class ExitStatus:
|
||||||
|
"""Exit status code constants."""
|
||||||
OK = 0
|
OK = 0
|
||||||
ERROR = 1
|
ERROR = 1
|
||||||
ERROR_TIMEOUT = 2
|
ERROR_TIMEOUT = 2
|
||||||
|
@ -22,23 +22,23 @@ from pygments import __version__ as pygments_version
|
|||||||
from .cli import parser
|
from .cli import parser
|
||||||
from .client import get_response
|
from .client import get_response
|
||||||
from .models import Environment
|
from .models import Environment
|
||||||
from .output import output_stream, write, write_with_colors_win_p3k
|
from .output import build_output_stream, write, write_with_colors_win_p3k
|
||||||
from . import exit
|
from . import ExitStatus
|
||||||
|
|
||||||
|
|
||||||
def get_exist_status(code, follow=False):
|
def get_exist_status_code(code, follow=False):
|
||||||
"""Translate HTTP status code to exit status."""
|
"""Translate HTTP status code to exit status code."""
|
||||||
if 300 <= code <= 399 and not follow:
|
if 300 <= code <= 399 and not follow:
|
||||||
# Redirect
|
# Redirect
|
||||||
return exit.ERROR_HTTP_3XX
|
return ExitStatus.ERROR_HTTP_3XX
|
||||||
elif 400 <= code <= 499:
|
elif 400 <= code <= 499:
|
||||||
# Client Error
|
# Client Error
|
||||||
return exit.ERROR_HTTP_4XX
|
return ExitStatus.ERROR_HTTP_4XX
|
||||||
elif 500 <= code <= 599:
|
elif 500 <= code <= 599:
|
||||||
# Server Error
|
# Server Error
|
||||||
return exit.ERROR_HTTP_5XX
|
return ExitStatus.ERROR_HTTP_5XX
|
||||||
else:
|
else:
|
||||||
return exit.OK
|
return ExitStatus.OK
|
||||||
|
|
||||||
|
|
||||||
def print_debug_info(env):
|
def print_debug_info(env):
|
||||||
@ -54,7 +54,7 @@ def print_debug_info(env):
|
|||||||
def main(args=sys.argv[1:], env=Environment()):
|
def main(args=sys.argv[1:], env=Environment()):
|
||||||
"""Run the main program and write the output to ``env.stdout``.
|
"""Run the main program and write the output to ``env.stdout``.
|
||||||
|
|
||||||
Return exit status.
|
Return exit status code.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if env.config.default_options:
|
if env.config.default_options:
|
||||||
@ -66,12 +66,12 @@ def main(args=sys.argv[1:], env=Environment()):
|
|||||||
|
|
||||||
debug = '--debug' in args
|
debug = '--debug' in args
|
||||||
traceback = debug or '--traceback' in args
|
traceback = debug or '--traceback' in args
|
||||||
status = exit.OK
|
exit_status_code = ExitStatus.OK
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
print_debug_info(env)
|
print_debug_info(env)
|
||||||
if args == ['--debug']:
|
if args == ['--debug']:
|
||||||
sys.exit(exit.OK)
|
return exit_status_code
|
||||||
|
|
||||||
try:
|
try:
|
||||||
args = parser.parse_args(args=args, env=env)
|
args = parser.parse_args(args=args, env=env)
|
||||||
@ -79,15 +79,14 @@ def main(args=sys.argv[1:], env=Environment()):
|
|||||||
response = get_response(args, config_dir=env.config.directory)
|
response = get_response(args, config_dir=env.config.directory)
|
||||||
|
|
||||||
if args.check_status:
|
if args.check_status:
|
||||||
status = get_exist_status(response.status_code,
|
exit_status_code = get_exist_status_code(response.status_code,
|
||||||
args.follow)
|
args.follow)
|
||||||
if status and not env.stdout_isatty:
|
if exit_status_code != ExitStatus.OK and not env.stdout_isatty:
|
||||||
error('%s %s', response.raw.status, response.raw.reason)
|
error('%s %s', response.raw.status, response.raw.reason)
|
||||||
|
|
||||||
stream = output_stream(args, env, response.request, response)
|
|
||||||
|
|
||||||
write_kwargs = {
|
write_kwargs = {
|
||||||
'stream': stream,
|
'stream': build_output_stream(
|
||||||
|
args, env, response.request, response),
|
||||||
'outfile': env.stdout,
|
'outfile': env.stdout,
|
||||||
'flush': env.stdout_isatty or args.stream
|
'flush': env.stdout_isatty or args.stream
|
||||||
}
|
}
|
||||||
@ -108,16 +107,18 @@ def main(args=sys.argv[1:], env=Environment()):
|
|||||||
if traceback:
|
if traceback:
|
||||||
raise
|
raise
|
||||||
env.stderr.write('\n')
|
env.stderr.write('\n')
|
||||||
status = exit.ERROR
|
exit_status_code = ExitStatus.ERROR
|
||||||
|
|
||||||
except requests.Timeout:
|
except requests.Timeout:
|
||||||
status = exit.ERROR_TIMEOUT
|
exit_status_code = ExitStatus.ERROR_TIMEOUT
|
||||||
error('Request timed out (%ss).', args.timeout)
|
error('Request timed out (%ss).', args.timeout)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# TODO: distinguish between expected and unexpected errors.
|
# TODO: Better distinction between expected and unexpected errors.
|
||||||
# network errors vs. bugs, etc.
|
# Network errors vs. bugs, etc.
|
||||||
if traceback:
|
if traceback:
|
||||||
raise
|
raise
|
||||||
error('%s: %s', type(e).__name__, str(e))
|
error('%s: %s', type(e).__name__, str(e))
|
||||||
status = exit.ERROR
|
exit_status_code = ExitStatus.ERROR
|
||||||
|
|
||||||
return status
|
return exit_status_code
|
||||||
|
@ -78,23 +78,21 @@ def write_with_colors_win_p3k(stream, outfile, flush):
|
|||||||
outfile.flush()
|
outfile.flush()
|
||||||
|
|
||||||
|
|
||||||
def output_stream(args, env, request, response):
|
def build_output_stream(args, env, request, response):
|
||||||
"""Build and return a chain of iterators over the `request`-`response`
|
"""Build and return a chain of iterators over the `request`-`response`
|
||||||
exchange each of which yields `bytes` chunks.
|
exchange each of which yields `bytes` chunks.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Stream = make_stream(env, args)
|
|
||||||
|
|
||||||
req_h = OUT_REQ_HEAD in args.output_options
|
req_h = OUT_REQ_HEAD in args.output_options
|
||||||
req_b = OUT_REQ_BODY in args.output_options
|
req_b = OUT_REQ_BODY in args.output_options
|
||||||
resp_h = OUT_RESP_HEAD in args.output_options
|
resp_h = OUT_RESP_HEAD in args.output_options
|
||||||
resp_b = OUT_RESP_BODY in args.output_options
|
resp_b = OUT_RESP_BODY in args.output_options
|
||||||
|
|
||||||
req = req_h or req_b
|
req = req_h or req_b
|
||||||
resp = resp_h or resp_b
|
resp = resp_h or resp_b
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
|
Stream = get_stream_type(env, args)
|
||||||
|
|
||||||
if req:
|
if req:
|
||||||
output.append(Stream(
|
output.append(Stream(
|
||||||
@ -120,7 +118,7 @@ def output_stream(args, env, request, response):
|
|||||||
return chain(*output)
|
return chain(*output)
|
||||||
|
|
||||||
|
|
||||||
def make_stream(env, args):
|
def get_stream_type(env, args):
|
||||||
"""Pick the right stream type based on `env` and `args`.
|
"""Pick the right stream type based on `env` and `args`.
|
||||||
Wrap it in a partial with the type-specific args so that
|
Wrap it in a partial with the type-specific args so that
|
||||||
we don't need to think what stream we are dealing with.
|
we don't need to think what stream we are dealing with.
|
||||||
@ -147,7 +145,7 @@ def make_stream(env, args):
|
|||||||
|
|
||||||
|
|
||||||
class BaseStream(object):
|
class BaseStream(object):
|
||||||
"""Base HTTP message stream class."""
|
"""Base HTTP message output stream class."""
|
||||||
|
|
||||||
def __init__(self, msg, with_headers=True, with_body=True):
|
def __init__(self, msg, with_headers=True, with_body=True):
|
||||||
"""
|
"""
|
||||||
|
@ -56,7 +56,7 @@ from requests.compat import is_windows, is_py26, bytes, str
|
|||||||
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||||
sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..')))
|
sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..')))
|
||||||
|
|
||||||
from httpie import exit
|
from httpie import ExitStatus
|
||||||
from httpie import input
|
from httpie import input
|
||||||
from httpie.models import Environment
|
from httpie.models import Environment
|
||||||
from httpie.core import main
|
from httpie.core import main
|
||||||
@ -188,7 +188,7 @@ def http(*args, **kwargs):
|
|||||||
sys.stderr.write(env.stderr.read())
|
sys.stderr.write(env.stderr.read())
|
||||||
raise
|
raise
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
exit_status = exit.ERROR
|
exit_status = ExitStatus.ERROR
|
||||||
|
|
||||||
env.stdout.seek(0)
|
env.stdout.seek(0)
|
||||||
env.stderr.seek(0)
|
env.stderr.seek(0)
|
||||||
@ -895,7 +895,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
httpbin('/status/200')
|
httpbin('/status/200')
|
||||||
)
|
)
|
||||||
self.assertIn(OK, r)
|
self.assertIn(OK, r)
|
||||||
self.assertEqual(r.exit_status, exit.OK)
|
self.assertEqual(r.exit_status, ExitStatus.OK)
|
||||||
|
|
||||||
def test_error_response_exits_0_without_check_status(self):
|
def test_error_response_exits_0_without_check_status(self):
|
||||||
r = http(
|
r = http(
|
||||||
@ -903,7 +903,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
httpbin('/status/500')
|
httpbin('/status/500')
|
||||||
)
|
)
|
||||||
self.assertIn('HTTP/1.1 500', r)
|
self.assertIn('HTTP/1.1 500', r)
|
||||||
self.assertEqual(r.exit_status, exit.OK)
|
self.assertEqual(r.exit_status, ExitStatus.OK)
|
||||||
self.assertTrue(not r.stderr)
|
self.assertTrue(not r.stderr)
|
||||||
|
|
||||||
def test_timeout_exit_status(self):
|
def test_timeout_exit_status(self):
|
||||||
@ -912,7 +912,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
'GET',
|
'GET',
|
||||||
httpbin('/delay/1')
|
httpbin('/delay/1')
|
||||||
)
|
)
|
||||||
self.assertEqual(r.exit_status, exit.ERROR_TIMEOUT)
|
self.assertEqual(r.exit_status, ExitStatus.ERROR_TIMEOUT)
|
||||||
|
|
||||||
def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(self):
|
def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(self):
|
||||||
r = http(
|
r = http(
|
||||||
@ -923,7 +923,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
env=TestEnvironment(stdout_isatty=False,)
|
env=TestEnvironment(stdout_isatty=False,)
|
||||||
)
|
)
|
||||||
self.assertIn('HTTP/1.1 301', r)
|
self.assertIn('HTTP/1.1 301', r)
|
||||||
self.assertEqual(r.exit_status, exit.ERROR_HTTP_3XX)
|
self.assertEqual(r.exit_status, ExitStatus.ERROR_HTTP_3XX)
|
||||||
self.assertIn('301 moved permanently', r.stderr.lower())
|
self.assertIn('301 moved permanently', r.stderr.lower())
|
||||||
|
|
||||||
@skipIf(requests_version == '0.13.6',
|
@skipIf(requests_version == '0.13.6',
|
||||||
@ -937,7 +937,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
)
|
)
|
||||||
# The redirect will be followed so 200 is expected.
|
# The redirect will be followed so 200 is expected.
|
||||||
self.assertIn('HTTP/1.1 200 OK', r)
|
self.assertIn('HTTP/1.1 200 OK', r)
|
||||||
self.assertEqual(r.exit_status, exit.OK)
|
self.assertEqual(r.exit_status, ExitStatus.OK)
|
||||||
|
|
||||||
def test_4xx_check_status_exits_4(self):
|
def test_4xx_check_status_exits_4(self):
|
||||||
r = http(
|
r = http(
|
||||||
@ -946,7 +946,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
httpbin('/status/401')
|
httpbin('/status/401')
|
||||||
)
|
)
|
||||||
self.assertIn('HTTP/1.1 401', r)
|
self.assertIn('HTTP/1.1 401', r)
|
||||||
self.assertEqual(r.exit_status, exit.ERROR_HTTP_4XX)
|
self.assertEqual(r.exit_status, ExitStatus.ERROR_HTTP_4XX)
|
||||||
# Also stderr should be empty since stdout isn't redirected.
|
# Also stderr should be empty since stdout isn't redirected.
|
||||||
self.assertTrue(not r.stderr)
|
self.assertTrue(not r.stderr)
|
||||||
|
|
||||||
@ -957,7 +957,7 @@ class ExitStatusTest(BaseTestCase):
|
|||||||
httpbin('/status/500')
|
httpbin('/status/500')
|
||||||
)
|
)
|
||||||
self.assertIn('HTTP/1.1 500', r)
|
self.assertIn('HTTP/1.1 500', r)
|
||||||
self.assertEqual(r.exit_status, exit.ERROR_HTTP_5XX)
|
self.assertEqual(r.exit_status, ExitStatus.ERROR_HTTP_5XX)
|
||||||
|
|
||||||
|
|
||||||
class WindowsOnlyTests(BaseTestCase):
|
class WindowsOnlyTests(BaseTestCase):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user