Skip to content

Commit

Permalink
Added models.Environment().
Browse files Browse the repository at this point in the history
Refactoring and general cleanup.
  • Loading branch information
jkbrzt committed Jul 21, 2012
1 parent c271715 commit 87042f6
Show file tree
Hide file tree
Showing 8 changed files with 568 additions and 352 deletions.
134 changes: 4 additions & 130 deletions httpie/__main__.py
@@ -1,135 +1,9 @@
#!/usr/bin/env python
import sys
import json
"""
The main entry point. Invoke as `http' or `python -m httpie'.
import requests

from requests.compat import str

from . import httpmessage
from . import cliparse
from . import cli
from . import pretty



TYPE_FORM = 'application/x-www-form-urlencoded; charset=utf-8'
TYPE_JSON = 'application/json; charset=utf-8'


def _get_response(args):

auto_json = args.data and not args.form
if args.json or auto_json:
# JSON
if 'Content-Type' not in args.headers:
args.headers['Content-Type'] = TYPE_JSON

if 'Accept' not in args.headers:
# Default Accept to JSON as well.
args.headers['Accept'] = 'application/json'

if isinstance(args.data, dict):
# If not empty, serialize the data `dict` parsed from arguments.
# Otherwise set it to `None` avoid sending "{}".
args.data = json.dumps(args.data) if args.data else None

elif args.form:
# Form
if not args.files and 'Content-Type' not in args.headers:
# If sending files, `requests` will set
# the `Content-Type` for us.
args.headers['Content-Type'] = TYPE_FORM


# Fire the request.
try:
credentials = None
if args.auth:
auth_type = (requests.auth.HTTPDigestAuth
if args.auth_type == 'digest'
else requests.auth.HTTPBasicAuth)
credentials = auth_type(args.auth.key, args.auth.value)

return requests.request(
method=args.method.lower(),
url=args.url if '://' in args.url else 'http://%s' % args.url,
headers=args.headers,
data=args.data,
verify={'yes': True, 'no': False}.get(args.verify, args.verify),
timeout=args.timeout,
auth=credentials,
proxies=dict((p.key, p.value) for p in args.proxy),
files=args.files,
allow_redirects=args.allow_redirects,
params=args.queries,
)

except (KeyboardInterrupt, SystemExit):
sys.stderr.write('\n')
sys.exit(1)
except Exception as e:
if args.traceback:
raise
sys.stderr.write(str(e.message) + '\n')
sys.exit(1)


def _get_output(args, stdout_isatty, response):

do_prettify = (args.prettify is True or
(args.prettify == cliparse.PRETTIFY_STDOUT_TTY_ONLY
and stdout_isatty))

do_output_request = (cliparse.OUT_REQ_HEADERS in args.output_options
or cliparse.OUT_REQ_BODY in args.output_options)

do_output_response = (cliparse.OUT_RESP_HEADERS in args.output_options
or cliparse.OUT_RESP_BODY in args.output_options)

prettifier = pretty.PrettyHttp(args.style) if do_prettify else None
output = []

if do_output_request:
output.append(httpmessage.format(
message=httpmessage.from_request(response.request),
prettifier=prettifier,
with_headers=cliparse.OUT_REQ_HEADERS in args.output_options,
with_body=cliparse.OUT_REQ_BODY in args.output_options
))
output.append('\n')
if do_output_response:
output.append('\n')

if do_output_response:
output.append(httpmessage.format(
message=httpmessage.from_response(response),
prettifier=prettifier,
with_headers=cliparse.OUT_RESP_HEADERS in args.output_options,
with_body=cliparse.OUT_RESP_BODY in args.output_options
))
output.append('\n')

return ''.join(output)


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,
stdout_isatty=stdout_isatty,
)

response = _get_response(args)
output = _get_output(args, stdout_isatty, response)
output_bytes = output.encode('utf8')
f = (stdout.buffer if hasattr(stdout, 'buffer') else stdout)
f.write(output_bytes)
"""
from .core import main


if __name__ == '__main__':
Expand Down
14 changes: 7 additions & 7 deletions httpie/cli.py
Expand Up @@ -2,10 +2,10 @@
CLI definition.
"""
from . import pretty
from . import __doc__
from . import __version__
from . import cliparse
from .output import AVAILABLE_STYLES


def _(text):
Expand Down Expand Up @@ -83,9 +83,9 @@ def _(text):
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_headers=cliparse.OUT_REQ_HEAD,
request_body=cliparse.OUT_REQ_BODY,
response_headers=cliparse.OUT_RESP_HEADERS,
response_headers=cliparse.OUT_RESP_HEAD,
response_body=cliparse.OUT_RESP_BODY,
))
)
Expand All @@ -99,11 +99,11 @@ def _(text):
)
output_options.add_argument(
'--headers', '-t', dest='output_options',
action='store_const', const=cliparse.OUT_RESP_HEADERS,
action='store_const', const=cliparse.OUT_RESP_HEAD,
help=_('''
Print only the response headers.
Shortcut for --print={0}.
'''.format(cliparse.OUT_RESP_HEADERS))
'''.format(cliparse.OUT_RESP_HEAD))
)
output_options.add_argument(
'--body', '-b', dest='output_options',
Expand All @@ -116,13 +116,13 @@ def _(text):

parser.add_argument(
'--style', '-s', dest='style', default='solarized', metavar='STYLE',
choices=pretty.AVAILABLE_STYLES,
choices=AVAILABLE_STYLES,
help=_('''
Output coloring style, one of %s. Defaults to solarized.
For this option to work properly, please make sure that the
$TERM environment variable is set to "xterm-256color" or similar
(e.g., via `export TERM=xterm-256color' in your ~/.bashrc).
''') % ', '.join(sorted(pretty.AVAILABLE_STYLES))
''') % ', '.join(sorted(AVAILABLE_STYLES))
)

# ``requests.request`` keyword arguments.
Expand Down
33 changes: 15 additions & 18 deletions httpie/cliparse.py
Expand Up @@ -33,13 +33,13 @@
]


OUT_REQ_HEADERS = 'H'
OUT_REQ_HEAD = 'H'
OUT_REQ_BODY = 'B'
OUT_RESP_HEADERS = 'h'
OUT_RESP_HEAD = 'h'
OUT_RESP_BODY = 'b'
OUTPUT_OPTIONS = [OUT_REQ_HEADERS,
OUTPUT_OPTIONS = [OUT_REQ_HEAD,
OUT_REQ_BODY,
OUT_RESP_HEADERS,
OUT_RESP_HEAD,
OUT_RESP_BODY]


Expand All @@ -50,20 +50,17 @@

class Parser(argparse.ArgumentParser):

def parse_args(self, args=None, namespace=None,
stdin=sys.stdin,
stdin_isatty=sys.stdin.isatty(),
stdout_isatty=sys.stdout.isatty()):
def parse_args(self, env, args=None, namespace=None):

args = super(Parser, self).parse_args(args, namespace)

self._process_output_options(args, stdout_isatty)
self._process_output_options(args, env)
self._validate_auth_options(args)
self._guess_method(args, stdin_isatty)
self._guess_method(args, env)
self._parse_items(args)

if not stdin_isatty:
self._body_from_file(args, stdin)
if not env.stdin_isatty:
self._body_from_file(args, env.stdin)

if args.auth and not args.auth.has_password():
# stdin has already been read (if not a tty) so
Expand All @@ -78,7 +75,7 @@ def _body_from_file(self, args, f):
'data (key=value) cannot be mixed.')
args.data = f.read()

def _guess_method(self, args, stdin_isatty=sys.stdin.isatty()):
def _guess_method(self, args, env):
"""
Set `args.method`, if not specified, to either POST or GET
based on whether the request has data or not.
Expand All @@ -87,7 +84,7 @@ def _guess_method(self, args, stdin_isatty=sys.stdin.isatty()):
if args.method is None:
# Invoked as `http URL'.
assert not args.items
if not stdin_isatty:
if not env.stdin_isatty:
args.method = 'POST'
else:
args.method = 'GET'
Expand All @@ -112,7 +109,7 @@ def _guess_method(self, args, stdin_isatty=sys.stdin.isatty()):
args.url = args.method
args.items.insert(0, item)

has_data = not stdin_isatty or any(
has_data = not env.stdin_isatty or any(
item.sep in DATA_ITEM_SEPARATORS for item in args.items)
if has_data:
args.method = 'POST'
Expand Down Expand Up @@ -162,10 +159,10 @@ def _parse_items(self, args):
content_type = '%s; charset=%s' % (mime, encoding)
args.headers['Content-Type'] = content_type

def _process_output_options(self, args, stdout_isatty):
def _process_output_options(self, args, env):
if not args.output_options:
if stdout_isatty:
args.output_options = OUT_RESP_HEADERS + OUT_RESP_BODY
if env.stdout_isatty:
args.output_options = OUT_RESP_HEAD + OUT_RESP_BODY
else:
args.output_options = OUT_RESP_BODY

Expand Down

0 comments on commit 87042f6

Please sign in to comment.