forked from extern/httpie-cli
Added initial support for persistent sessions.
This commit is contained in:
commit
4c0d7d526f
59
README.rst
59
README.rst
@ -502,6 +502,30 @@ path. The path can also be configured via the environment variable
|
|||||||
``REQUESTS_CA_BUNDLE``.
|
``REQUESTS_CA_BUNDLE``.
|
||||||
|
|
||||||
|
|
||||||
|
========
|
||||||
|
Sessions
|
||||||
|
========
|
||||||
|
|
||||||
|
HTTPie supports named sessions, where several options and cookies sent
|
||||||
|
by the server persists between requests:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
http --session=user1 --auth=user1:password example.org
|
||||||
|
|
||||||
|
Now you can always refer to the session by passing ``--session=user1``,
|
||||||
|
and the credentials and cookies will be reused:
|
||||||
|
|
||||||
|
http --session=user1 GET example.org
|
||||||
|
|
||||||
|
Since sessions are named, you can switch between multiple sessions:
|
||||||
|
|
||||||
|
http --session=user2 --auth=user2:password example.org
|
||||||
|
|
||||||
|
Note that session cookies respect domain and path.
|
||||||
|
|
||||||
|
Session data are store in ``~/httpie/sessions/<name>.pickle``.
|
||||||
|
|
||||||
==============
|
==============
|
||||||
Output Options
|
Output Options
|
||||||
==============
|
==============
|
||||||
@ -700,12 +724,14 @@ Also, the following formatting is applied:
|
|||||||
|
|
||||||
One of these options can be used to control output processing:
|
One of these options can be used to control output processing:
|
||||||
|
|
||||||
=============== ==============================================================
|
==================== ========================================================
|
||||||
``--pretty`` Apply both colors and formatting. Default for terminal output.
|
``--pretty=all`` Apply both colors and formatting.
|
||||||
``--colors`` Apply colors.
|
Default for terminal output.
|
||||||
``--format`` Apply formatting.
|
``--pretty=colors`` Apply colors.
|
||||||
``--ugly, -u`` Disables output processing. Default for redirected output.
|
``--pretty=format`` Apply formatting.
|
||||||
=============== ==============================================================
|
``--pretty=none`` Disables output processing.
|
||||||
|
Default for redirected output.
|
||||||
|
==================== ========================================================
|
||||||
|
|
||||||
-----------
|
-----------
|
||||||
Binary data
|
Binary data
|
||||||
@ -743,8 +769,7 @@ Redirected Output
|
|||||||
HTTPie uses **different defaults** for redirected output than for
|
HTTPie uses **different defaults** for redirected output than for
|
||||||
`terminal output`_:
|
`terminal output`_:
|
||||||
|
|
||||||
* Formatting and colors aren't applied (unless ``--pretty``, ``--format``,
|
* Formatting and colors aren't applied (unless ``--pretty`` is specified).
|
||||||
or ``--colors`` is set).
|
|
||||||
* Only the response body is printed (unless one of the `output options`_ is set).
|
* Only the response body is printed (unless one of the `output options`_ is set).
|
||||||
* Also, binary data isn't suppressed.
|
* Also, binary data isn't suppressed.
|
||||||
|
|
||||||
@ -771,7 +796,7 @@ Force colorizing and formatting, and show both the request and the response in
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
$ http --pretty --verbose example.org | less -R
|
$ http --pretty=all --verbose example.org | less -R
|
||||||
|
|
||||||
|
|
||||||
The ``-R`` flag tells ``less`` to interpret color escape sequences included
|
The ``-R`` flag tells ``less`` to interpret color escape sequences included
|
||||||
@ -880,7 +905,7 @@ and that only a small portion of the command is used to control HTTPie and
|
|||||||
doesn't directly correspond to any part of the request (here it's only ``-f``
|
doesn't directly correspond to any part of the request (here it's only ``-f``
|
||||||
asking HTTPie to send a form request).
|
asking HTTPie to send a form request).
|
||||||
|
|
||||||
The two modes, ``--pretty`` (default for terminal) and ``--ugly, -u``
|
The two modes, ``--pretty=all`` (default for terminal) and ``--pretty=none``
|
||||||
(default for redirected output), allow for both user-friendly interactive use
|
(default for redirected output), allow for both user-friendly interactive use
|
||||||
and usage from scripts, where HTTPie serves as a generic HTTP client.
|
and usage from scripts, where HTTPie serves as a generic HTTP client.
|
||||||
|
|
||||||
@ -956,20 +981,22 @@ Changelog
|
|||||||
|
|
||||||
*You can click a version name to see a diff with the previous one.*
|
*You can click a version name to see a diff with the previous one.*
|
||||||
|
|
||||||
* `0.2.8dev`_
|
* `0.2.8-alpha`_
|
||||||
* Fixed colorized output on Windows with Python 3.
|
* Added persistent session support.
|
||||||
* Fixed installation on Windows with Python 3.
|
* Fixed installation on Windows with Python 3.
|
||||||
|
* Fixed colorized output on Windows with Python 3.
|
||||||
* CRLF HTTP header field separation in the output.
|
* CRLF HTTP header field separation in the output.
|
||||||
* Added exit status code ``2`` for timed-out requests.
|
* Added exit status code ``2`` for timed-out requests.
|
||||||
* Added ``--colors`` and ``--format`` in addition to ``--pretty``, to
|
* Added the option to separate colorizing and formatting
|
||||||
be able to separate colorizing and formatting.
|
(``--pretty=all``, ``--pretty=colors`` and ``--pretty=format``).
|
||||||
|
``--ugly`` has bee removed in favor of ``--pretty=none``.
|
||||||
* `0.2.7`_ (2012-08-07)
|
* `0.2.7`_ (2012-08-07)
|
||||||
* Compatibility with Requests 0.13.6.
|
* Compatibility with Requests 0.13.6.
|
||||||
* Streamed terminal output. ``--stream`` / ``-S`` can be used to enable
|
* Streamed terminal output. ``--stream`` / ``-S`` can be used to enable
|
||||||
streaming also with ``--pretty`` and to ensure a more frequent output
|
streaming also with ``--pretty`` and to ensure a more frequent output
|
||||||
flushing.
|
flushing.
|
||||||
* Support for efficient large file downloads.
|
* Support for efficient large file downloads.
|
||||||
* Sort headers by name (unless ``--ugly``).
|
* Sort headers by name (unless ``--pretty=none``).
|
||||||
* Response body is fetched only when needed (e.g., not with ``--headers``).
|
* Response body is fetched only when needed (e.g., not with ``--headers``).
|
||||||
* Improved content type matching.
|
* Improved content type matching.
|
||||||
* Updated Solarized color scheme.
|
* Updated Solarized color scheme.
|
||||||
@ -1042,7 +1069,7 @@ Changelog
|
|||||||
.. _0.2.5: https://github.com/jkbr/httpie/compare/0.2.2...0.2.5
|
.. _0.2.5: https://github.com/jkbr/httpie/compare/0.2.2...0.2.5
|
||||||
.. _0.2.6: https://github.com/jkbr/httpie/compare/0.2.5...0.2.6
|
.. _0.2.6: https://github.com/jkbr/httpie/compare/0.2.5...0.2.6
|
||||||
.. _0.2.7: https://github.com/jkbr/httpie/compare/0.2.5...0.2.7
|
.. _0.2.7: https://github.com/jkbr/httpie/compare/0.2.5...0.2.7
|
||||||
.. _0.2.8dev: https://github.com/jkbr/httpie/compare/0.2.7...master
|
.. _0.2.8-alpha: https://github.com/jkbr/httpie/compare/0.2.7...master
|
||||||
.. _stable version: https://github.com/jkbr/httpie/tree/0.2.7#readme
|
.. _stable version: https://github.com/jkbr/httpie/tree/0.2.7#readme
|
||||||
.. _AUTHORS.rst: https://github.com/jkbr/httpie/blob/master/AUTHORS.rst
|
.. _AUTHORS.rst: https://github.com/jkbr/httpie/blob/master/AUTHORS.rst
|
||||||
.. _LICENSE: https://github.com/jkbr/httpie/blob/master/LICENSE
|
.. _LICENSE: https://github.com/jkbr/httpie/blob/master/LICENSE
|
||||||
|
@ -3,7 +3,7 @@ HTTPie - cURL for humans.
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
__author__ = 'Jakub Roztocil'
|
__author__ = 'Jakub Roztocil'
|
||||||
__version__ = '0.2.8dev'
|
__version__ = '0.2.8-alpha'
|
||||||
__licence__ = 'BSD'
|
__licence__ = 'BSD'
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,8 +14,7 @@ from .input import (Parser, AuthCredentialsArgType, KeyValueArgType,
|
|||||||
SEP_PROXY, SEP_CREDENTIALS, SEP_GROUP_ITEMS,
|
SEP_PROXY, SEP_CREDENTIALS, SEP_GROUP_ITEMS,
|
||||||
OUT_REQ_HEAD, OUT_REQ_BODY, OUT_RESP_HEAD,
|
OUT_REQ_HEAD, OUT_REQ_BODY, OUT_RESP_HEAD,
|
||||||
OUT_RESP_BODY, OUTPUT_OPTIONS,
|
OUT_RESP_BODY, OUTPUT_OPTIONS,
|
||||||
PRETTY_STDOUT_TTY_ONLY, PRETTY_ALL,
|
PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY)
|
||||||
PRETTY_FORMAT, PRETTY_COLORS)
|
|
||||||
|
|
||||||
|
|
||||||
def _(text):
|
def _(text):
|
||||||
@ -69,29 +68,17 @@ parser.add_argument(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
prettify = parser.add_mutually_exclusive_group(required=False)
|
|
||||||
prettify.add_argument(
|
parser.add_argument(
|
||||||
'--pretty', dest='prettify', action='store_const', const=PRETTY_ALL,
|
'--pretty', dest='prettify', default=PRETTY_STDOUT_TTY_ONLY,
|
||||||
default=PRETTY_STDOUT_TTY_ONLY,
|
choices=sorted(PRETTY_MAP.keys()),
|
||||||
help=_('''
|
help=_('''
|
||||||
Apply both colors and formatting. Default for terminal output.
|
Controls output processing. The value can be "none" to not prettify
|
||||||
|
the output (default for redirected output), "all" to apply both colors
|
||||||
|
and formatting
|
||||||
|
(default for terminal output), "colors", or "format".
|
||||||
''')
|
''')
|
||||||
)
|
)
|
||||||
prettify.add_argument(
|
|
||||||
'--colors', dest='prettify', action='store_const', const=PRETTY_COLORS,
|
|
||||||
help=_('''Apply colors to the output.''')
|
|
||||||
)
|
|
||||||
prettify.add_argument(
|
|
||||||
'--format', dest='prettify', action='store_const', const=PRETTY_FORMAT,
|
|
||||||
help=_('''Apply formatting to the output.''')
|
|
||||||
)
|
|
||||||
prettify.add_argument(
|
|
||||||
'--ugly', '-u', dest='prettify', action='store_false',
|
|
||||||
help=_('''
|
|
||||||
Disables output processing.
|
|
||||||
Default for redirected output.
|
|
||||||
''')
|
|
||||||
)
|
|
||||||
|
|
||||||
output_options = parser.add_mutually_exclusive_group(required=False)
|
output_options = parser.add_mutually_exclusive_group(required=False)
|
||||||
output_options.add_argument('--print', '-p', dest='output_options',
|
output_options.add_argument('--print', '-p', dest='output_options',
|
||||||
@ -182,9 +169,19 @@ parser.add_argument(
|
|||||||
''')
|
''')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--session', metavar='NAME',
|
||||||
|
help=_('''
|
||||||
|
Create or reuse a session.
|
||||||
|
Withing a session, values of --auth, --timeout,
|
||||||
|
--verify, --proxies are persistent, as well as any
|
||||||
|
cookies sent by the server.
|
||||||
|
''')
|
||||||
|
)
|
||||||
|
|
||||||
# ``requests.request`` keyword arguments.
|
# ``requests.request`` keyword arguments.
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--auth', '-a', metavar='USER:PASS',
|
'--auth', '-a', metavar='USER[:PASS]',
|
||||||
type=AuthCredentialsArgType(SEP_CREDENTIALS),
|
type=AuthCredentialsArgType(SEP_CREDENTIALS),
|
||||||
help=_('''
|
help=_('''
|
||||||
username:password.
|
username:password.
|
||||||
|
77
httpie/client.py
Normal file
77
httpie/client.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pprint import pformat
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import requests.auth
|
||||||
|
|
||||||
|
from .import sessions
|
||||||
|
|
||||||
|
|
||||||
|
FORM = 'application/x-www-form-urlencoded; charset=utf-8'
|
||||||
|
JSON = 'application/json; charset=utf-8'
|
||||||
|
|
||||||
|
|
||||||
|
def get_response(args):
|
||||||
|
|
||||||
|
requests_kwargs = get_requests_kwargs(args)
|
||||||
|
|
||||||
|
if args.debug:
|
||||||
|
sys.stderr.write(
|
||||||
|
'\n>>> requests.request(%s)\n\n' % pformat(requests_kwargs))
|
||||||
|
|
||||||
|
if args.session:
|
||||||
|
return sessions.get_response(args.session, requests_kwargs)
|
||||||
|
else:
|
||||||
|
return requests.request(**requests_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def get_requests_kwargs(args):
|
||||||
|
"""Send the request and return a `request.Response`."""
|
||||||
|
|
||||||
|
auto_json = args.data and not args.form
|
||||||
|
if args.json or auto_json:
|
||||||
|
if 'Content-Type' not in args.headers and args.data:
|
||||||
|
args.headers['Content-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:
|
||||||
|
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'] = FORM
|
||||||
|
|
||||||
|
credentials = None
|
||||||
|
if args.auth:
|
||||||
|
credentials = {
|
||||||
|
'basic': requests.auth.HTTPBasicAuth,
|
||||||
|
'digest': requests.auth.HTTPDigestAuth,
|
||||||
|
}[args.auth_type](args.auth.key, args.auth.value)
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
'prefetch': False,
|
||||||
|
'method': args.method.lower(),
|
||||||
|
'url': 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.params
|
||||||
|
}
|
||||||
|
|
||||||
|
return kwargs
|
6
httpie/config.py
Normal file
6
httpie/config.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
__author__ = 'jakub'
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_DIR = os.path.expanduser('~/.httpie')
|
@ -11,77 +11,21 @@ Invocation flow:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import json
|
|
||||||
import errno
|
import errno
|
||||||
from pprint import pformat
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import requests.auth
|
|
||||||
from requests.compat import str, is_py3
|
from requests.compat import str, is_py3
|
||||||
from httpie import __version__ as httpie_version
|
from httpie import __version__ as httpie_version
|
||||||
from requests import __version__ as requests_version
|
from requests import __version__ as requests_version
|
||||||
from pygments import __version__ as pygments_version
|
from pygments import __version__ as pygments_version
|
||||||
|
|
||||||
from .cli import parser
|
from .cli import parser
|
||||||
|
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 output_stream, write, write_with_colors_win_p3k
|
||||||
from . import EXIT
|
from . import EXIT
|
||||||
|
|
||||||
|
|
||||||
FORM = 'application/x-www-form-urlencoded; charset=utf-8'
|
|
||||||
JSON = 'application/json; charset=utf-8'
|
|
||||||
|
|
||||||
|
|
||||||
def get_requests_kwargs(args):
|
|
||||||
"""Send the request and return a `request.Response`."""
|
|
||||||
|
|
||||||
auto_json = args.data and not args.form
|
|
||||||
if args.json or auto_json:
|
|
||||||
if 'Content-Type' not in args.headers and args.data:
|
|
||||||
args.headers['Content-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:
|
|
||||||
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'] = FORM
|
|
||||||
|
|
||||||
credentials = None
|
|
||||||
if args.auth:
|
|
||||||
credentials = {
|
|
||||||
'basic': requests.auth.HTTPBasicAuth,
|
|
||||||
'digest': requests.auth.HTTPDigestAuth,
|
|
||||||
}[args.auth_type](args.auth.key, args.auth.value)
|
|
||||||
|
|
||||||
kwargs = {
|
|
||||||
'prefetch': False,
|
|
||||||
'method': args.method.lower(),
|
|
||||||
'url': 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.params
|
|
||||||
}
|
|
||||||
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
|
|
||||||
def get_exist_status(code, allow_redirects=False):
|
def get_exist_status(code, allow_redirects=False):
|
||||||
"""Translate HTTP status code to exit status."""
|
"""Translate HTTP status code to exit status."""
|
||||||
@ -121,13 +65,7 @@ def main(args=sys.argv[1:], env=Environment()):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
args = parser.parse_args(args=args, env=env)
|
args = parser.parse_args(args=args, env=env)
|
||||||
requests_kwargs = get_requests_kwargs(args)
|
response = get_response(args)
|
||||||
|
|
||||||
if args.debug:
|
|
||||||
sys.stderr.write(
|
|
||||||
'\n>>> requests.request(%s)\n\n' % pformat(requests_kwargs))
|
|
||||||
|
|
||||||
response = requests.request(**requests_kwargs)
|
|
||||||
|
|
||||||
if args.check_status:
|
if args.check_status:
|
||||||
status = get_exist_status(response.status_code,
|
status = get_exist_status(response.status_code,
|
||||||
|
@ -67,9 +67,12 @@ OUTPUT_OPTIONS = frozenset([
|
|||||||
])
|
])
|
||||||
|
|
||||||
# Pretty
|
# Pretty
|
||||||
PRETTY_ALL = ['format', 'colors']
|
PRETTY_MAP = {
|
||||||
PRETTY_FORMAT = ['format']
|
'all': ['format', 'colors'],
|
||||||
PRETTY_COLORS = ['colors']
|
'colors': ['colors'],
|
||||||
|
'format': ['format'],
|
||||||
|
'none': []
|
||||||
|
}
|
||||||
PRETTY_STDOUT_TTY_ONLY = object()
|
PRETTY_STDOUT_TTY_ONLY = object()
|
||||||
|
|
||||||
|
|
||||||
@ -114,6 +117,7 @@ class Parser(argparse.ArgumentParser):
|
|||||||
env.stdout_isatty = False
|
env.stdout_isatty = False
|
||||||
|
|
||||||
self._process_output_options(args, env)
|
self._process_output_options(args, env)
|
||||||
|
self._process_pretty_options(args, env)
|
||||||
self._guess_method(args, env)
|
self._guess_method(args, env)
|
||||||
self._parse_items(args)
|
self._parse_items(args)
|
||||||
|
|
||||||
@ -128,10 +132,6 @@ class Parser(argparse.ArgumentParser):
|
|||||||
# Stdin already read (if not a tty) so it's save to prompt.
|
# Stdin already read (if not a tty) so it's save to prompt.
|
||||||
args.auth.prompt_password(urlparse(args.url).netloc)
|
args.auth.prompt_password(urlparse(args.url).netloc)
|
||||||
|
|
||||||
if args.prettify == PRETTY_STDOUT_TTY_ONLY:
|
|
||||||
args.prettify = PRETTY_ALL if env.stdout_isatty else []
|
|
||||||
elif args.prettify and env.is_windows:
|
|
||||||
self.error('Only terminal output can be prettified on Windows.')
|
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
@ -246,6 +246,14 @@ class Parser(argparse.ArgumentParser):
|
|||||||
if unknown:
|
if unknown:
|
||||||
self.error('Unknown output options: %s' % ','.join(unknown))
|
self.error('Unknown output options: %s' % ','.join(unknown))
|
||||||
|
|
||||||
|
def _process_pretty_options(self, args, env):
|
||||||
|
if args.prettify == PRETTY_STDOUT_TTY_ONLY:
|
||||||
|
args.prettify = PRETTY_MAP['all' if env.stdout_isatty else 'none']
|
||||||
|
elif args.prettify and env.is_windows:
|
||||||
|
self.error('Only terminal output can be prettified on Windows.')
|
||||||
|
else:
|
||||||
|
args.prettify = PRETTY_MAP[args.prettify]
|
||||||
|
|
||||||
|
|
||||||
class ParseError(Exception):
|
class ParseError(Exception):
|
||||||
pass
|
pass
|
||||||
|
68
httpie/sessions.py
Normal file
68
httpie/sessions.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
import errno
|
||||||
|
from requests import Session
|
||||||
|
|
||||||
|
from .config import CONFIG_DIR
|
||||||
|
|
||||||
|
|
||||||
|
SESSIONS_DIR = os.path.join(CONFIG_DIR, 'sessions')
|
||||||
|
|
||||||
|
|
||||||
|
def get_response(name, request_kwargs):
|
||||||
|
session = load(name)
|
||||||
|
session_kwargs, request_kwargs = split_kwargs(request_kwargs)
|
||||||
|
headers = session_kwargs.pop('headers', None)
|
||||||
|
if headers:
|
||||||
|
session.headers.update(headers)
|
||||||
|
session.__dict__.update(session_kwargs)
|
||||||
|
try:
|
||||||
|
response = session.request(**request_kwargs)
|
||||||
|
except Exception:
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
save(session, name)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def split_kwargs(requests_kwargs):
|
||||||
|
session = {}
|
||||||
|
request = {}
|
||||||
|
session_attrs = [
|
||||||
|
'auth', 'timeout',
|
||||||
|
'verify', 'proxies',
|
||||||
|
'params'
|
||||||
|
]
|
||||||
|
|
||||||
|
for k, v in requests_kwargs.items():
|
||||||
|
if v is not None:
|
||||||
|
if k in session_attrs:
|
||||||
|
session[k] = v
|
||||||
|
else:
|
||||||
|
request[k] = v
|
||||||
|
return session, request
|
||||||
|
|
||||||
|
|
||||||
|
def get_path(name):
|
||||||
|
try:
|
||||||
|
os.makedirs(SESSIONS_DIR, mode=0o700)
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno != errno.EEXIST:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return os.path.join(SESSIONS_DIR, name + '.pickle')
|
||||||
|
|
||||||
|
|
||||||
|
def load(name):
|
||||||
|
try:
|
||||||
|
with open(get_path(name), 'rb') as f:
|
||||||
|
return pickle.load(f)
|
||||||
|
except IOError as e:
|
||||||
|
if e.errno != errno.ENOENT:
|
||||||
|
raise
|
||||||
|
return Session()
|
||||||
|
|
||||||
|
|
||||||
|
def save(session, name):
|
||||||
|
with open(get_path(name), 'wb') as f:
|
||||||
|
pickle.dump(session, f)
|
@ -524,7 +524,7 @@ class ImplicitHTTPMethodTest(BaseTestCase):
|
|||||||
|
|
||||||
|
|
||||||
class PrettyOptionsTest(BaseTestCase):
|
class PrettyOptionsTest(BaseTestCase):
|
||||||
"""Test the --pretty / --ugly flag handling."""
|
"""Test the --pretty flag handling."""
|
||||||
|
|
||||||
def test_pretty_enabled_by_default(self):
|
def test_pretty_enabled_by_default(self):
|
||||||
r = http(
|
r = http(
|
||||||
@ -543,7 +543,7 @@ class PrettyOptionsTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_force_pretty(self):
|
def test_force_pretty(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--pretty',
|
'--pretty=all',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get'),
|
httpbin('/get'),
|
||||||
env=TestEnvironment(stdout_isatty=False, colors=256),
|
env=TestEnvironment(stdout_isatty=False, colors=256),
|
||||||
@ -552,7 +552,7 @@ class PrettyOptionsTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_force_ugly(self):
|
def test_force_ugly(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--ugly',
|
'--pretty=none',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get'),
|
httpbin('/get'),
|
||||||
)
|
)
|
||||||
@ -565,7 +565,7 @@ class PrettyOptionsTest(BaseTestCase):
|
|||||||
"""
|
"""
|
||||||
r = http(
|
r = http(
|
||||||
'--print=B',
|
'--print=B',
|
||||||
'--pretty',
|
'--pretty=all',
|
||||||
httpbin('/post'),
|
httpbin('/post'),
|
||||||
'Content-Type:text/foo+json',
|
'Content-Type:text/foo+json',
|
||||||
'a=b',
|
'a=b',
|
||||||
@ -576,7 +576,7 @@ class PrettyOptionsTest(BaseTestCase):
|
|||||||
def test_colors_option(self):
|
def test_colors_option(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--print=B',
|
'--print=B',
|
||||||
'--colors',
|
'--pretty=colors',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get'),
|
httpbin('/get'),
|
||||||
'a=b',
|
'a=b',
|
||||||
@ -590,7 +590,7 @@ class PrettyOptionsTest(BaseTestCase):
|
|||||||
def test_format_option(self):
|
def test_format_option(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--print=B',
|
'--print=B',
|
||||||
'--format',
|
'--pretty=format',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get'),
|
httpbin('/get'),
|
||||||
'a=b',
|
'a=b',
|
||||||
@ -737,7 +737,7 @@ class BinaryResponseDataTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_binary_suppresses_when_not_terminal_but_pretty(self):
|
def test_binary_suppresses_when_not_terminal_but_pretty(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--pretty',
|
'--pretty=all',
|
||||||
'GET',
|
'GET',
|
||||||
self.url,
|
self.url,
|
||||||
env=TestEnvironment(stdin_isatty=True,
|
env=TestEnvironment(stdin_isatty=True,
|
||||||
@ -944,7 +944,7 @@ class FakeWindowsTest(BaseTestCase):
|
|||||||
r = http(
|
r = http(
|
||||||
'--output',
|
'--output',
|
||||||
os.path.join(tempfile.gettempdir(), '__httpie_test_output__'),
|
os.path.join(tempfile.gettempdir(), '__httpie_test_output__'),
|
||||||
'--pretty',
|
'--pretty=all',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get'),
|
httpbin('/get'),
|
||||||
env=TestEnvironment(is_windows=True)
|
env=TestEnvironment(is_windows=True)
|
||||||
@ -962,7 +962,7 @@ class StreamTest(BaseTestCase):
|
|||||||
with open(BIN_FILE_PATH, 'rb') as f:
|
with open(BIN_FILE_PATH, 'rb') as f:
|
||||||
r = http(
|
r = http(
|
||||||
'--verbose',
|
'--verbose',
|
||||||
'--pretty',
|
'--pretty=all',
|
||||||
'--stream',
|
'--stream',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get'),
|
httpbin('/get'),
|
||||||
@ -981,7 +981,7 @@ class StreamTest(BaseTestCase):
|
|||||||
"""Test that --stream works with non-prettified redirected terminal output."""
|
"""Test that --stream works with non-prettified redirected terminal output."""
|
||||||
with open(BIN_FILE_PATH, 'rb') as f:
|
with open(BIN_FILE_PATH, 'rb') as f:
|
||||||
r = http(
|
r = http(
|
||||||
'--ugly',
|
'--pretty=none',
|
||||||
'--stream',
|
'--stream',
|
||||||
'--verbose',
|
'--verbose',
|
||||||
'GET',
|
'GET',
|
||||||
@ -999,7 +999,7 @@ class StreamTest(BaseTestCase):
|
|||||||
"""Test that --stream works with non-prettified redirected terminal output."""
|
"""Test that --stream works with non-prettified redirected terminal output."""
|
||||||
with open(BIN_FILE_PATH, 'rb') as f:
|
with open(BIN_FILE_PATH, 'rb') as f:
|
||||||
r = http(
|
r = http(
|
||||||
'--ugly',
|
'--pretty=none',
|
||||||
'--stream',
|
'--stream',
|
||||||
'--verbose',
|
'--verbose',
|
||||||
'GET',
|
'GET',
|
||||||
@ -1043,7 +1043,7 @@ class LineEndingsTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_CRLF_ugly_response(self):
|
def test_CRLF_ugly_response(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--ugly',
|
'--pretty=none',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get')
|
httpbin('/get')
|
||||||
)
|
)
|
||||||
@ -1051,7 +1051,7 @@ class LineEndingsTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_CRLF_formatted_response(self):
|
def test_CRLF_formatted_response(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--format',
|
'--pretty=format',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get')
|
httpbin('/get')
|
||||||
)
|
)
|
||||||
@ -1060,7 +1060,7 @@ class LineEndingsTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_CRLF_ugly_request(self):
|
def test_CRLF_ugly_request(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--ugly',
|
'--pretty=none',
|
||||||
'--print=HB',
|
'--print=HB',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get')
|
httpbin('/get')
|
||||||
@ -1069,7 +1069,7 @@ class LineEndingsTest(BaseTestCase):
|
|||||||
|
|
||||||
def test_CRLF_formatted_request(self):
|
def test_CRLF_formatted_request(self):
|
||||||
r = http(
|
r = http(
|
||||||
'--format',
|
'--pretty=format',
|
||||||
'--print=HB',
|
'--print=HB',
|
||||||
'GET',
|
'GET',
|
||||||
httpbin('/get')
|
httpbin('/get')
|
||||||
|
Loading…
Reference in New Issue
Block a user