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