mirror of
https://github.com/httpie/cli.git
synced 2024-11-22 07:43:20 +01:00
Added --session-read
for read-only sessions.
This commit is contained in:
parent
da0eb7db79
commit
316e3f45a9
@ -509,13 +509,12 @@ Sessions
|
||||
*NOTE: This is an experimental feature. Feedback appretiated.*
|
||||
|
||||
HTTPie supports named, per-host sessions, where custom headers, authorization,
|
||||
and cookies sent by the server persist between requests:
|
||||
and cookies (manually specified or sent by the server) persist between requests:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ http --session user1 -a user1:password example.org X-Foo:Bar
|
||||
|
||||
|
||||
Now you can refer to the session by its name:
|
||||
|
||||
.. code-block:: bash
|
||||
@ -529,6 +528,9 @@ To switch to another session simple pass a different name:
|
||||
|
||||
$ http --session user2 -a user2:password example.org X-Bar:Foo
|
||||
|
||||
To use an existing session without updating it from the request/response
|
||||
exchange, specify the session via ``--session-read=SESSION_NAME`` instead.
|
||||
|
||||
You can view and manipulate existing sessions via the ``httpie`` management
|
||||
command, see ``httpie --help``.
|
||||
|
||||
|
@ -219,19 +219,25 @@ output_options.add_argument('--stream', '-S', action='store_true', default=False
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Misc
|
||||
# Sessions
|
||||
###############################################################################
|
||||
misc = parser.add_argument_group(title='Sessions')
|
||||
misc.add_argument(
|
||||
sessions = parser.add_argument_group(title='Sessions')\
|
||||
.add_mutually_exclusive_group(required=False)
|
||||
|
||||
sessions.add_argument(
|
||||
'--session', metavar='SESSION_NAME',
|
||||
help=_('''
|
||||
Create or reuse a session.
|
||||
Create, or reuse and update a session.
|
||||
Withing a session, custom headers, auth credential, as well as any
|
||||
cookies sent by the server persist between requests.
|
||||
You can use the `httpie' management command to manipulate
|
||||
and inspect existing sessions. See `httpie --help'.
|
||||
''')
|
||||
)
|
||||
sessions.add_argument(
|
||||
'--session-read', metavar='SESSION_NAME',
|
||||
help=_('''Create or reuse a session, but do not update it once saved.''')
|
||||
)
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
@ -16,6 +16,7 @@ DEFAULT_UA = 'HTTPie/%s' % __version__
|
||||
|
||||
|
||||
def get_response(args):
|
||||
"""Send the request and return a `request.Response`."""
|
||||
|
||||
requests_kwargs = get_requests_kwargs(args)
|
||||
|
||||
@ -23,14 +24,18 @@ def get_response(args):
|
||||
sys.stderr.write(
|
||||
'\n>>> requests.request(%s)\n\n' % pformat(requests_kwargs))
|
||||
|
||||
if args.session:
|
||||
return sessions.get_response(args.session, requests_kwargs)
|
||||
else:
|
||||
if not args.session and not args.session_read:
|
||||
return requests.request(**requests_kwargs)
|
||||
else:
|
||||
return sessions.get_response(
|
||||
name=args.session or args.session_read,
|
||||
request_kwargs=requests_kwargs,
|
||||
read_only=bool(args.session_read),
|
||||
)
|
||||
|
||||
|
||||
def get_requests_kwargs(args):
|
||||
"""Send the request and return a `request.Response`."""
|
||||
"""Translate our `args` into `requests.request` keyword arguments."""
|
||||
|
||||
base_headers = defaults['base_headers'].copy()
|
||||
base_headers['User-Agent'] = DEFAULT_UA
|
||||
|
@ -10,10 +10,11 @@ import codecs
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
import requests
|
||||
from requests.compat import urlparse
|
||||
from requests import Session as RSession
|
||||
from requests.cookies import RequestsCookieJar, create_cookie
|
||||
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
|
||||
from argparse import OPTIONAL
|
||||
|
||||
from.import __version__
|
||||
from.config import CONFIG_DIR
|
||||
@ -23,7 +24,11 @@ from.output import PygmentsProcessor
|
||||
SESSIONS_DIR = os.path.join(CONFIG_DIR, 'sessions')
|
||||
|
||||
|
||||
def get_response(name, request_kwargs):
|
||||
def get_response(name, request_kwargs, read_only=False):
|
||||
"""Like `client.get_response`, but applies permanent
|
||||
aspects of the session to the request.
|
||||
|
||||
"""
|
||||
host = Host(request_kwargs['headers'].get('Host', None)
|
||||
or urlparse(request_kwargs['url']).netloc.split('@')[-1])
|
||||
|
||||
@ -41,22 +46,26 @@ def get_response(name, request_kwargs):
|
||||
elif session.auth:
|
||||
request_kwargs['auth'] = session.auth
|
||||
|
||||
rsession = RSession(cookies=session.cookies)
|
||||
rsession = requests.Session(cookies=session.cookies)
|
||||
try:
|
||||
response = rsession.request(**request_kwargs)
|
||||
except Exception:
|
||||
raise
|
||||
else:
|
||||
session.cookies = rsession.cookies
|
||||
session.save()
|
||||
if not read_only or session.is_new:
|
||||
session.cookies = rsession.cookies
|
||||
session.save()
|
||||
return response
|
||||
|
||||
|
||||
class Host(object):
|
||||
"""A host is a per-host directory on the disk containing sessions files."""
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __iter__(self):
|
||||
"""Return a iterator yielding `(session_name, session_path)`."""
|
||||
for fn in sorted(glob.glob1(self.path, '*.json')):
|
||||
yield os.path.splitext(fn)[0], os.path.join(self.path, fn)
|
||||
|
||||
@ -78,12 +87,15 @@ class Host(object):
|
||||
|
||||
@classmethod
|
||||
def all(cls):
|
||||
"""Return a generator yielding a host at a time."""
|
||||
for name in sorted(glob.glob1(SESSIONS_DIR, '*')):
|
||||
if os.path.isdir(os.path.join(SESSIONS_DIR, name)):
|
||||
yield Host(name)
|
||||
|
||||
|
||||
class Session(dict):
|
||||
""""""
|
||||
|
||||
def __init__(self, host, name, *args, **kwargs):
|
||||
super(Session, self).__init__(*args, **kwargs)
|
||||
self.host = host
|
||||
@ -91,10 +103,6 @@ class Session(dict):
|
||||
self['headers'] = {}
|
||||
self['cookies'] = {}
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return os.path.join(self.host.path, self.name + '.json')
|
||||
|
||||
def load(self):
|
||||
try:
|
||||
with open(self.path, 'rt') as f:
|
||||
@ -121,6 +129,14 @@ class Session(dict):
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return os.path.join(self.host.path, self.name + '.json')
|
||||
|
||||
@property
|
||||
def is_new(self):
|
||||
return not os.path.exists(self.path)
|
||||
|
||||
@property
|
||||
def cookies(self):
|
||||
jar = RequestsCookieJar()
|
||||
@ -163,7 +179,7 @@ class Session(dict):
|
||||
HTTPDigestAuth: 'digest'}[type(cred)],
|
||||
'username': cred.username,
|
||||
'password': cred.password,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def list_command(args):
|
||||
@ -211,13 +227,14 @@ def edit_command(args):
|
||||
|
||||
|
||||
def add_commands(subparsers):
|
||||
|
||||
# List
|
||||
list_ = subparsers.add_parser('session-list', help='list sessions')
|
||||
list_.set_defaults(command=list_command)
|
||||
list_.add_argument('host', nargs='?')
|
||||
list_.add_argument('host', nargs=OPTIONAL)
|
||||
|
||||
# Show
|
||||
show = subparsers.add_parser('session-show', help='list or show sessions')
|
||||
show = subparsers.add_parser('session-show', help='show a session')
|
||||
show.set_defaults(command=show_command)
|
||||
show.add_argument('host')
|
||||
show.add_argument('name')
|
||||
@ -233,6 +250,6 @@ def add_commands(subparsers):
|
||||
delete = subparsers.add_parser('session-delete', help='delete a session')
|
||||
delete.set_defaults(command=delete_command)
|
||||
delete.add_argument('host')
|
||||
delete.add_argument('name', nargs='?',
|
||||
delete.add_argument('name', nargs=OPTIONAL,
|
||||
help='The name of the session to be deleted.'
|
||||
' If not specified, all host sessions are deleted.')
|
||||
|
Loading…
Reference in New Issue
Block a user