Skip to content

Commit

Permalink
0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jkbrzt committed Sep 21, 2012
1 parent a41dd7a commit f7e6233
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 49 deletions.
38 changes: 20 additions & 18 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
HTTPie: cURL for Humans
***********************

v0.2.8-alpha (`stable version`_)
v0.3.0

HTTPie is a **command line HTTP client** whose goal is to make CLI interaction
with web services as **human-friendly** as possible. It provides a
Expand Down Expand Up @@ -42,6 +42,7 @@ Main Features
* HTTPS, proxies, and authentication
* Arbitrary request data
* Custom headers
* Persistent sessions
* Python 2.6, 2.7 and 3.x support
* Linux, Mac OS X and Windows support
* Documentation
Expand Down Expand Up @@ -825,34 +826,35 @@ Streamed output by small chunks alá ``tail -f``:
Sessions
========
HTTPie supports named, per-host sessions, where custom headers, authorization,
and cookies (manually specified or sent by the server) persist between requests:
By default, every request is completely independent of the previous ones.
HTTPie supports persistent sessions, where custom headers, authorization,
and cookies (manually specified or sent by the server) persist between
requests. Sessions are named and host-bound.
Create a new session named ``user1``:
.. 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:
.. code-block:: bash
$ http --session user1 example.org
$ http --session=user1 example.org
To switch to another session simple pass a different name:
To create or reuse a different session, simple specify a different name:
.. code-block:: bash
$ http --session user2 -a user2:password example.org X-Bar:Foo
$ http --session=user2 -a user2:password example.org X-Bar:Foo
To use a session without updating it from the request/response exchange
once it is created, specify the session name via
``--session-read-only=SESSION_NAME`` instead.
You can view and manipulate existing sessions via the ``httpie`` management
command, see ``httpie --help``.
Sessions are stored as JSON in ``~/.httpie/sessions/<host>/<name>.json``
Sessions are stored as JSON files in ``~/.httpie/sessions/<host>/<name>.json``
(``%APPDATA%\httpie\sessions\<host>\<name>.json`` on Windows).
See also `config`_.
Expand All @@ -862,8 +864,8 @@ See also `config`_.
Config
======
HTTPie provides a simple configuration file containing a JSON
object with the following keys:
HTTPie uses a simple configuration file that contains a JSON object with the
following keys:
========================= =================================================
``__version__`` HTTPie automatically sets this to its version.
Expand Down Expand Up @@ -1025,9 +1027,9 @@ Changelog
*You can click a version name to see a diff with the previous one.*
* `0.2.8-alpha`_
* `0.3.0`_ (2012-09-21)
* Allow output redirection on Windows.
* Added config file.
* Added configuration file.
* Added persistent session support.
* Renamed ``--allow-redirects`` to ``--follow``.
* Improved the usability of ``http --help``.
Expand Down Expand Up @@ -1117,7 +1119,7 @@ Changelog
.. _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.7: https://github.com/jkbr/httpie/compare/0.2.5...0.2.7
.. _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
.. _0.3.0: https://github.com/jkbr/httpie/compare/0.2.7...0.3.0
.. _stable version: https://github.com/jkbr/httpie/tree/0.3.0#readme
.. _AUTHORS.rst: https://github.com/jkbr/httpie/blob/master/AUTHORS.rst
.. _LICENSE: https://github.com/jkbr/httpie/blob/master/LICENSE
4 changes: 2 additions & 2 deletions httpie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"""
__author__ = 'Jakub Roztocil'
__version__ = '0.2.8-alpha'
__version__ = '0.3.0'
__licence__ = 'BSD'


class EXIT:
class exit:
OK = 0
ERROR = 1
ERROR_TIMEOUT = 2
Expand Down
12 changes: 7 additions & 5 deletions httpie/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""CLI arguments definition.
NOTE: the CLI interface may change before reaching v1.0.
TODO: make the options config friendly, i.e., no mutually exclusive groups to
allow options overwriting.
"""
from argparse import FileType, OPTIONAL, ZERO_OR_MORE, SUPPRESS
Expand All @@ -9,7 +11,7 @@

from . import __doc__
from . import __version__
from .config import DEFAULT_CONFIG_DIR
from .sessions import DEFAULT_SESSIONS_DIR
from .output import AVAILABLE_STYLES, DEFAULT_STYLE
from .input import (Parser, AuthCredentialsArgType, KeyValueArgType,
SEP_PROXY, SEP_CREDENTIALS, SEP_GROUP_ITEMS,
Expand Down Expand Up @@ -231,14 +233,14 @@ def _(text):
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'.
''')
Session files are stored in %s/<HOST>/<SESSION_NAME>.json.
''' % DEFAULT_SESSIONS_DIR)
)
sessions.add_argument(
'--session-read-only', metavar='SESSION_NAME',
help=_('''
Create or reuse a session, but do not update it once saved.
Create or read a session without updating it form the
request/response exchange.
''')
)

Expand Down
20 changes: 10 additions & 10 deletions httpie/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,22 @@
from .client import get_response
from .models import Environment
from .output import output_stream, write, write_with_colors_win_p3k
from . import EXIT
from . import exit


def get_exist_status(code, follow=False):
"""Translate HTTP status code to exit status."""
if 300 <= code <= 399 and not follow:
# Redirect
return EXIT.ERROR_HTTP_3XX
return exit.ERROR_HTTP_3XX
elif 400 <= code <= 499:
# Client Error
return EXIT.ERROR_HTTP_4XX
return exit.ERROR_HTTP_4XX
elif 500 <= code <= 599:
# Server Error
return EXIT.ERROR_HTTP_5XX
return exit.ERROR_HTTP_5XX
else:
return EXIT.OK
return exit.OK


def print_debug_info(env):
Expand Down Expand Up @@ -66,12 +66,12 @@ def error(msg, *args):

debug = '--debug' in args
traceback = debug or '--traceback' in args
status = EXIT.OK
status = exit.OK

if debug:
print_debug_info(env)
if args == ['--debug']:
sys.exit(EXIT.OK)
sys.exit(exit.OK)

try:
args = parser.parse_args(args=args, env=env)
Expand Down Expand Up @@ -108,16 +108,16 @@ def error(msg, *args):
if traceback:
raise
env.stderr.write('\n')
status = EXIT.ERROR
status = exit.ERROR
except requests.Timeout:
status = EXIT.ERROR_TIMEOUT
status = exit.ERROR_TIMEOUT
error('Request timed out (%ss).', args.timeout)
except Exception as e:
# TODO: distinguish between expected and unexpected errors.
# network errors vs. bugs, etc.
if traceback:
raise
error('%s: %s', type(e).__name__, str(e))
status = EXIT.ERROR
status = exit.ERROR

return status
8 changes: 6 additions & 2 deletions httpie/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@


SESSIONS_DIR_NAME = 'sessions'
DEFAULT_SESSIONS_DIR = os.path.join(DEFAULT_CONFIG_DIR, SESSIONS_DIR_NAME)


def get_response(name, request_kwargs, config_dir, read_only=False):
Expand Down Expand Up @@ -92,8 +93,8 @@ def path(self):
@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)):
for name in sorted(glob.glob1(DEFAULT_SESSIONS_DIR, '*')):
if os.path.isdir(os.path.join(DEFAULT_SESSIONS_DIR, name)):
yield Host(name)


Expand Down Expand Up @@ -156,6 +157,9 @@ def auth(self, cred):
}


# The commands are disabled for now.
# TODO: write tests for the commands.

def list_command(args):
if args.host:
for name, path in Host(args.host):
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def long_description():
entry_points={
'console_scripts': [
'http = httpie.__main__:main',
'httpie = httpie.manage:main',
# Not ready yet.
# 'httpie = httpie.manage:main',
],
},
install_requires=requirements,
Expand Down
24 changes: 13 additions & 11 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
HTTPBIN_URL=http://localhost:5000 tox
"""
from functools import partial
import subprocess
import os
import sys
Expand All @@ -28,6 +29,7 @@
import unittest
import shutil

from requests.compat import urlparse
try:
from urllib.request import urlopen
except ImportError:
Expand Down Expand Up @@ -55,7 +57,7 @@ def decorator(test_method):
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..')))

from httpie import EXIT
from httpie import exit
from httpie import input
from httpie.models import Environment
from httpie.core import main
Expand Down Expand Up @@ -183,7 +185,7 @@ def http(*args, **kwargs):
sys.stderr.write(env.stderr.read())
raise
except SystemExit:
exit_status = EXIT.ERROR
exit_status = exit.ERROR

env.stdout.seek(0)
env.stderr.seek(0)
Expand Down Expand Up @@ -865,15 +867,15 @@ def test_ok_response_exits_0(self):
httpbin('/status/200')
)
self.assertIn(OK, r)
self.assertEqual(r.exit_status, EXIT.OK)
self.assertEqual(r.exit_status, exit.OK)

def test_error_response_exits_0_without_check_status(self):
r = http(
'GET',
httpbin('/status/500')
)
self.assertIn('HTTP/1.1 500', r)
self.assertEqual(r.exit_status, EXIT.OK)
self.assertEqual(r.exit_status, exit.OK)
self.assertTrue(not r.stderr)

def test_timeout_exit_status(self):
Expand All @@ -882,7 +884,7 @@ def test_timeout_exit_status(self):
'GET',
httpbin('/delay/1')
)
self.assertEqual(r.exit_status, EXIT.ERROR_TIMEOUT)
self.assertEqual(r.exit_status, exit.ERROR_TIMEOUT)

def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(self):
r = http(
Expand All @@ -893,7 +895,7 @@ def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(self):
env=TestEnvironment(stdout_isatty=False,)
)
self.assertIn('HTTP/1.1 301', r)
self.assertEqual(r.exit_status, EXIT.ERROR_HTTP_3XX)
self.assertEqual(r.exit_status, exit.ERROR_HTTP_3XX)
self.assertIn('301 moved permanently', r.stderr.lower())

@skipIf(requests_version == '0.13.6',
Expand All @@ -907,7 +909,7 @@ def test_3xx_check_status_redirects_allowed_exits_0(self):
)
# The redirect will be followed so 200 is expected.
self.assertIn('HTTP/1.1 200 OK', r)
self.assertEqual(r.exit_status, EXIT.OK)
self.assertEqual(r.exit_status, exit.OK)

def test_4xx_check_status_exits_4(self):
r = http(
Expand All @@ -916,7 +918,7 @@ def test_4xx_check_status_exits_4(self):
httpbin('/status/401')
)
self.assertIn('HTTP/1.1 401', r)
self.assertEqual(r.exit_status, EXIT.ERROR_HTTP_4XX)
self.assertEqual(r.exit_status, exit.ERROR_HTTP_4XX)
# Also stderr should be empty since stdout isn't redirected.
self.assertTrue(not r.stderr)

Expand All @@ -927,7 +929,7 @@ def test_5xx_check_status_exits_5(self):
httpbin('/status/500')
)
self.assertIn('HTTP/1.1 500', r)
self.assertEqual(r.exit_status, EXIT.ERROR_HTTP_5XX)
self.assertEqual(r.exit_status, exit.ERROR_HTTP_5XX)


class WindowsOnlyTests(BaseTestCase):
Expand Down Expand Up @@ -1267,7 +1269,7 @@ def tearDown(self):
shutil.rmtree(self.config_dir)

def test_session_create(self):
# Verify that the has been created
# Verify that the session has been created.
r = http(
'--session=test',
'GET',
Expand Down Expand Up @@ -1316,7 +1318,7 @@ def test_session_update(self):
self.assertNotEqual(r1.json['headers']['Authorization'],
r3.json['headers']['Authorization'])

def test_session_only(self):
def test_session_read_only(self):
# Get a response from the original session.
r1 = http(
'--session=test',
Expand Down

0 comments on commit f7e6233

Please sign in to comment.