mirror of
https://github.com/httpie/cli.git
synced 2025-01-12 08:38:28 +01:00
parent
1f49900db6
commit
51aa0409e6
@ -2,8 +2,9 @@ language: python
|
|||||||
python:
|
python:
|
||||||
- 2.6
|
- 2.6
|
||||||
- 2.7
|
- 2.7
|
||||||
# TODO: Python 3
|
- 3.1
|
||||||
#- 3.2
|
- 3.2
|
||||||
|
- 3.3
|
||||||
script: python tests/tests.py
|
script: python tests/tests.py
|
||||||
install:
|
install:
|
||||||
- pip install requests pygments
|
- pip install requests pygments
|
||||||
|
@ -8,7 +8,7 @@ HTTPie does so by providing an ``http`` command that allows for issuing arbitrar
|
|||||||
.. image:: https://github.com/jkbr/httpie/raw/master/httpie.png
|
.. image:: https://github.com/jkbr/httpie/raw/master/httpie.png
|
||||||
:alt: HTTPie compared to cURL
|
:alt: HTTPie compared to cURL
|
||||||
|
|
||||||
Under the hood, HTTPie uses the excellent `Requests <http://python-requests.org>`_ and `Pygments <http://pygments.org/>`_ Python libraries.
|
Under the hood, HTTPie uses the excellent `Requests <http://python-requests.org>`_ and `Pygments <http://pygments.org/>`_ Python libraries. Python >= 2.6 is supported (including Python 3.x).
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from urlparse import urlparse
|
|
||||||
import requests
|
|
||||||
try:
|
try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
except ImportError:
|
except ImportError:
|
||||||
OrderedDict = dict
|
OrderedDict = dict
|
||||||
|
import requests
|
||||||
|
from requests.compat import urlparse, str
|
||||||
from requests.structures import CaseInsensitiveDict
|
from requests.structures import CaseInsensitiveDict
|
||||||
from . import cli
|
from . import cli
|
||||||
from . import pretty
|
from . import pretty
|
||||||
from . import __version__ as version
|
from . import __version__ as version
|
||||||
|
|
||||||
|
|
||||||
|
NEW_LINE = str('\n')
|
||||||
DEFAULT_UA = 'HTTPie/%s' % version
|
DEFAULT_UA = 'HTTPie/%s' % version
|
||||||
TYPE_FORM = 'application/x-www-form-urlencoded; charset=utf-8'
|
TYPE_FORM = 'application/x-www-form-urlencoded; charset=utf-8'
|
||||||
TYPE_JSON = 'application/json; charset=utf-8'
|
TYPE_JSON = 'application/json; charset=utf-8'
|
||||||
@ -40,15 +40,14 @@ def format_http_message(message, prettifier=None,
|
|||||||
bits.append(message.line)
|
bits.append(message.line)
|
||||||
bits.append(message.headers)
|
bits.append(message.headers)
|
||||||
if with_body and message.body:
|
if with_body and message.body:
|
||||||
bits.append('\n')
|
bits.append(NEW_LINE)
|
||||||
if with_body and message.body:
|
if with_body and message.body:
|
||||||
if prettifier and message.content_type:
|
if prettifier and message.content_type:
|
||||||
bits.append(prettifier.body(message.body, message.content_type))
|
bits.append(prettifier.body(message.body, message.content_type))
|
||||||
else:
|
else:
|
||||||
bits.append(message.body)
|
bits.append(message.body)
|
||||||
bits = [bit.strip() for bit in bits]
|
bits.append(NEW_LINE)
|
||||||
bits.append('')
|
return NEW_LINE.join(bit.strip() for bit in bits)
|
||||||
return '\n'.join(bits)
|
|
||||||
|
|
||||||
|
|
||||||
def make_request_message(request):
|
def make_request_message(request):
|
||||||
@ -61,9 +60,9 @@ def make_request_message(request):
|
|||||||
line='{method} {path} HTTP/1.1'.format(
|
line='{method} {path} HTTP/1.1'.format(
|
||||||
method=request.method,
|
method=request.method,
|
||||||
path=url.path or '/'),
|
path=url.path or '/'),
|
||||||
headers='\n'.join('%s: %s' % (name, value)
|
headers=NEW_LINE.join(str('%s: %s') % (name, value)
|
||||||
for name, value
|
for name, value
|
||||||
in request_headers.iteritems()),
|
in request_headers.items()),
|
||||||
body=request._enc_data,
|
body=request._enc_data,
|
||||||
content_type=request_headers.get('Content-Type')
|
content_type=request_headers.get('Content-Type')
|
||||||
)
|
)
|
||||||
@ -78,8 +77,8 @@ def make_response_message(response):
|
|||||||
line='HTTP/{version} {status} {reason}'.format(
|
line='HTTP/{version} {status} {reason}'.format(
|
||||||
version='.'.join(str(original.version)),
|
version='.'.join(str(original.version)),
|
||||||
status=original.status, reason=original.reason,),
|
status=original.status, reason=original.reason,),
|
||||||
headers=str(original.msg).decode(encoding),
|
headers=str(original.msg),
|
||||||
body=response.content.decode(encoding) if response.content else u'',
|
body=response.content.decode(encoding) if response.content else '',
|
||||||
content_type=response_headers.get('Content-Type'))
|
content_type=response_headers.get('Content-Type'))
|
||||||
|
|
||||||
|
|
||||||
@ -123,7 +122,6 @@ def main(args=None,
|
|||||||
'data (key=value) cannot be mixed.')
|
'data (key=value) cannot be mixed.')
|
||||||
data = stdin.read()
|
data = stdin.read()
|
||||||
|
|
||||||
|
|
||||||
# JSON/Form content type.
|
# JSON/Form content type.
|
||||||
if args.json or (not args.form and data):
|
if args.json or (not args.form and data):
|
||||||
if stdin_isatty:
|
if stdin_isatty:
|
||||||
@ -148,12 +146,12 @@ def main(args=None,
|
|||||||
allow_redirects=args.allow_redirects,
|
allow_redirects=args.allow_redirects,
|
||||||
)
|
)
|
||||||
except (KeyboardInterrupt, SystemExit):
|
except (KeyboardInterrupt, SystemExit):
|
||||||
sys.stderr.write('\n')
|
sys.stderr.write(NEW_LINE)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if args.traceback:
|
if args.traceback:
|
||||||
raise
|
raise
|
||||||
sys.stderr.write(str(e.message) + '\n')
|
sys.stderr.write(str(e.message) + NEW_LINE)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
prettifier = pretty.PrettyHttp(args.style) if do_prettify else None
|
prettifier = pretty.PrettyHttp(args.style) if do_prettify else None
|
||||||
@ -170,9 +168,9 @@ def main(args=None,
|
|||||||
prettifier=prettifier,
|
prettifier=prettifier,
|
||||||
with_headers=cli.OUT_REQUEST_HEADERS in args.output_options,
|
with_headers=cli.OUT_REQUEST_HEADERS in args.output_options,
|
||||||
with_body=cli.OUT_REQUEST_BODY in args.output_options
|
with_body=cli.OUT_REQUEST_BODY in args.output_options
|
||||||
).encode('utf-8'))
|
))
|
||||||
if output_response:
|
if output_response:
|
||||||
stdout.write('\n')
|
stdout.write(NEW_LINE)
|
||||||
|
|
||||||
if output_response:
|
if output_response:
|
||||||
stdout.write(format_http_message(
|
stdout.write(format_http_message(
|
||||||
@ -180,8 +178,8 @@ def main(args=None,
|
|||||||
prettifier=prettifier,
|
prettifier=prettifier,
|
||||||
with_headers=cli.OUT_RESPONSE_HEADERS in args.output_options,
|
with_headers=cli.OUT_RESPONSE_HEADERS in args.output_options,
|
||||||
with_body=cli.OUT_RESPONSE_BODY in args.output_options
|
with_body=cli.OUT_RESPONSE_BODY in args.output_options
|
||||||
).encode('utf-8'))
|
))
|
||||||
stdout.write('\n')
|
stdout.write(NEW_LINE)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -13,7 +13,7 @@ from . import solarized
|
|||||||
|
|
||||||
|
|
||||||
DEFAULT_STYLE = 'solarized'
|
DEFAULT_STYLE = 'solarized'
|
||||||
AVAILABLE_STYLES = [DEFAULT_STYLE] + STYLE_MAP.keys()
|
AVAILABLE_STYLES = [DEFAULT_STYLE] + list(STYLE_MAP.keys())
|
||||||
FORMATTER = (Terminal256Formatter
|
FORMATTER = (Terminal256Formatter
|
||||||
if '256color' in os.environ.get('TERM', '')
|
if '256color' in os.environ.get('TERM', '')
|
||||||
else TerminalFormatter)
|
else TerminalFormatter)
|
||||||
|
7
setup.py
7
setup.py
@ -36,10 +36,9 @@ setup(
|
|||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 2.6',
|
'Programming Language :: Python :: 2.6',
|
||||||
'Programming Language :: Python :: 2.7',
|
'Programming Language :: Python :: 2.7',
|
||||||
# TODO: Python 3
|
'Programming Language :: Python :: 3.1'
|
||||||
# 'Programming Language :: Python :: 3.1'
|
'Programming Language :: Python :: 3.2'
|
||||||
# 'Programming Language :: Python :: 3.2'
|
'Programming Language :: Python :: 3.3'
|
||||||
# 'Programming Language :: Python :: 3.3'
|
|
||||||
'Environment :: Console',
|
'Environment :: Console',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'Intended Audience :: System Administrators',
|
'Intended Audience :: System Administrators',
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
# coding:utf8
|
# coding:utf-8
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
import argparse
|
import argparse
|
||||||
from StringIO import StringIO
|
from requests.compat import StringIO, is_py26, str
|
||||||
|
|
||||||
|
|
||||||
TESTS_ROOT = os.path.dirname(__file__)
|
TESTS_ROOT = 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, '..')))
|
||||||
@ -12,9 +13,7 @@ from httpie import cli
|
|||||||
|
|
||||||
|
|
||||||
TEST_FILE = os.path.join(TESTS_ROOT, 'file.txt')
|
TEST_FILE = os.path.join(TESTS_ROOT, 'file.txt')
|
||||||
|
TERMINAL_COLOR_PRESENCE_CHECK = '\x1b['
|
||||||
|
|
||||||
TERMINAL_COLOR_CHECK = '\x1b['
|
|
||||||
|
|
||||||
|
|
||||||
def http(*args, **kwargs):
|
def http(*args, **kwargs):
|
||||||
@ -30,7 +29,7 @@ def http(*args, **kwargs):
|
|||||||
|
|
||||||
class BaseTest(unittest.TestCase):
|
class BaseTest(unittest.TestCase):
|
||||||
|
|
||||||
if sys.version < (2, 7):
|
if is_py26:
|
||||||
def assertIn(self, member, container, msg=None):
|
def assertIn(self, member, container, msg=None):
|
||||||
self.assert_(member in container, msg)
|
self.assert_(member in container, msg)
|
||||||
|
|
||||||
@ -88,6 +87,10 @@ class TestHTTPie(BaseTest):
|
|||||||
def test_get(self):
|
def test_get(self):
|
||||||
http('GET', 'http://httpbin.org/get')
|
http('GET', 'http://httpbin.org/get')
|
||||||
|
|
||||||
|
def test_verbose(self):
|
||||||
|
r = http('--verbose', 'GET', 'http://httpbin.org/get', 'test-header:__test__')
|
||||||
|
self.assertEqual(r.count('__test__'), 2)
|
||||||
|
|
||||||
def test_json(self):
|
def test_json(self):
|
||||||
response = http('POST', 'http://httpbin.org/post', 'foo=bar')
|
response = http('POST', 'http://httpbin.org/post', 'foo=bar')
|
||||||
self.assertIn('"foo": "bar"', response)
|
self.assertIn('"foo": "bar"', response)
|
||||||
@ -107,19 +110,19 @@ class TestPrettyFlag(BaseTest):
|
|||||||
|
|
||||||
def test_pretty_enabled_by_default(self):
|
def test_pretty_enabled_by_default(self):
|
||||||
r = http('GET', 'http://httpbin.org/get', stdout_isatty=True)
|
r = http('GET', 'http://httpbin.org/get', stdout_isatty=True)
|
||||||
self.assertIn(TERMINAL_COLOR_CHECK, r)
|
self.assertIn(TERMINAL_COLOR_PRESENCE_CHECK, r)
|
||||||
|
|
||||||
def test_pretty_enabled_by_default_unless_stdin_redirected(self):
|
def test_pretty_enabled_by_default_unless_stdin_redirected(self):
|
||||||
r = http('GET', 'http://httpbin.org/get', stdout_isatty=False)
|
r = http('GET', 'http://httpbin.org/get', stdout_isatty=False)
|
||||||
self.assertNotIn(TERMINAL_COLOR_CHECK, r)
|
self.assertNotIn(TERMINAL_COLOR_PRESENCE_CHECK, r)
|
||||||
|
|
||||||
def test_force_pretty(self):
|
def test_force_pretty(self):
|
||||||
r = http('--pretty', 'GET', 'http://httpbin.org/get', stdout_isatty=False)
|
r = http('--pretty', 'GET', 'http://httpbin.org/get', stdout_isatty=False)
|
||||||
self.assertIn(TERMINAL_COLOR_CHECK, r)
|
self.assertIn(TERMINAL_COLOR_PRESENCE_CHECK, r)
|
||||||
|
|
||||||
def test_force_ugly(self):
|
def test_force_ugly(self):
|
||||||
r = http('--ugly', 'GET', 'http://httpbin.org/get', stdout_isatty=True)
|
r = http('--ugly', 'GET', 'http://httpbin.org/get', stdout_isatty=True)
|
||||||
self.assertNotIn(TERMINAL_COLOR_CHECK, r)
|
self.assertNotIn(TERMINAL_COLOR_PRESENCE_CHECK, r)
|
||||||
|
|
||||||
|
|
||||||
class TestFileUpload(BaseTest):
|
class TestFileUpload(BaseTest):
|
||||||
|
Loading…
Reference in New Issue
Block a user