Permalink
Browse files

Initial --download implementation (#104).

Closes #127
  • Loading branch information...
jakubroztocil committed Feb 26, 2013
1 parent f0c42cd commit 8e6c765be22803f1705f9a6c053a0728adeaf820
Showing with 635 additions and 218 deletions.
  1. +22 −0 README.rst
  2. +1 −1 httpie/__init__.py
  3. +109 −44 httpie/cli.py
  4. +29 −5 httpie/core.py
  5. +194 −0 httpie/downloads.py
  6. +53 −0 httpie/humanize.py
  7. +150 −106 httpie/input.py
  8. +10 −7 httpie/models.py
  9. +6 −2 httpie/output.py
  10. +1 −0 requirements.txt
  11. +60 −47 tests/tests.py
  12. +0 −6 tox.ini
View
@@ -16,6 +16,10 @@ for **testing, debugging**, and generally **interacting** with HTTP servers.
:height: 835
:align: center
+
+------
+
+
.. image:: https://raw.github.com/claudiatd/httpie-artwork/master/images/httpie_logo_simple.png
:alt: HTTPie logo
:align: center
@@ -158,6 +162,13 @@ Download a file and save it via `redirected output`_:
$ http example.org/file > file
+
+Download a file ``wget`` style:
+
+.. code-block:: bash
+
+ $ http --download example.org/file
+
Use named `sessions`_ to make certain aspects or the communication persistent
between requests to the same host:
@@ -811,6 +822,15 @@ by adding the following to your ``~/.bash_profile``:
}
+=============
+Download Mode
+=============
+
+HTTPie features a download mode, in which a download progress bar is shown,
+and the response body is saved to a file. You can enable this mode
+with the ``--download`` flag.
+
+
==================
Streamed Responses
==================
@@ -1081,6 +1101,8 @@ Changelog
*You can click a version name to see a diff with the previous one.*
+* `0.5.0-alpha`_
+ * Added ``--download`` mode.
* `0.4.1`_ (2013-02-26)
* Fixed ``setup.py``.
* `0.4.0`_ (2013-02-22)
View
@@ -3,7 +3,7 @@
"""
__author__ = 'Jakub Roztocil'
-__version__ = '0.4.1'
+__version__ = '0.5.0-alpha'
__licence__ = 'BSD'
View
@@ -1,15 +1,12 @@
"""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
from . import __doc__
from . import __version__
-from .compat import is_windows
from .sessions import DEFAULT_SESSIONS_DIR, Session
from .output import AVAILABLE_STYLES, DEFAULT_STYLE
from .input import (Parser, AuthCredentialsArgType, KeyValueArgType,
@@ -45,7 +42,8 @@ def _(text):
''')
)
positional.add_argument(
- 'method', metavar='METHOD',
+ 'method',
+ metavar='METHOD',
nargs=OPTIONAL,
default=None,
help=_('''
@@ -57,14 +55,16 @@ def _(text):
''')
)
positional.add_argument(
- 'url', metavar='URL',
+ 'url',
+ metavar='URL',
help=_('''
The protocol defaults to http:// if the
URL does not include one.
''')
)
positional.add_argument(
- 'items', metavar='REQUEST ITEM',
+ 'items',
+ metavar='REQUEST ITEM',
nargs=ZERO_OR_MORE,
type=KeyValueArgType(*SEP_GROUP_ITEMS),
help=_('''
@@ -90,7 +90,8 @@ def _(text):
)
content_type.add_argument(
- '--json', '-j', action='store_true',
+ '--json', '-j',
+ action='store_true',
help=_('''
(default) Data items from the command
line are serialized as a JSON object.
@@ -99,7 +100,8 @@ def _(text):
''')
)
content_type.add_argument(
- '--form', '-f', action='store_true',
+ '--form', '-f',
+ action='store_true',
help=_('''
Data items from the command line are serialized as form fields.
The Content-Type is set to application/x-www-form-urlencoded
@@ -117,20 +119,9 @@ def _(text):
output_processing = parser.add_argument_group(title='Output processing')
output_processing.add_argument(
- '--output', '-o', type=FileType('w+b'),
- metavar='FILE',
- help=SUPPRESS if not is_windows else _(
- '''
- Save output to FILE.
- This option is a replacement for piping output to FILE,
- which would on Windows result in corrupted data
- being saved.
-
- '''
- )
-)
-output_processing.add_argument(
- '--pretty', dest='prettify', default=PRETTY_STDOUT_TTY_ONLY,
+ '--pretty',
+ dest='prettify',
+ default=PRETTY_STDOUT_TTY_ONLY,
choices=sorted(PRETTY_MAP.keys()),
help=_('''
Controls output processing. The value can be "none" to not prettify
@@ -140,7 +131,10 @@ def _(text):
''')
)
output_processing.add_argument(
- '--style', '-s', dest='style', default=DEFAULT_STYLE, metavar='STYLE',
+ '--style', '-s',
+ dest='style',
+ metavar='STYLE',
+ default=DEFAULT_STYLE,
choices=AVAILABLE_STYLES,
help=_('''
Output coloring style. One of %s. Defaults to "%s".
@@ -157,7 +151,9 @@ def _(text):
output_options = parser.add_argument_group(title='Output options')
output_options.add_argument(
- '--print', '-p', dest='output_options', metavar='WHAT',
+ '--print', '-p',
+ dest='output_options',
+ metavar='WHAT',
help=_('''
String specifying what the output should contain:
"{request_headers}" stands for the request headers, and
@@ -174,32 +170,40 @@ def _(text):
response_body=OUT_RESP_BODY,))
)
output_options.add_argument(
- '--verbose', '-v', dest='output_options',
- action='store_const', const=''.join(OUTPUT_OPTIONS),
+ '--verbose', '-v',
+ dest='output_options',
+ action='store_const',
+ const=''.join(OUTPUT_OPTIONS),
help=_('''
Print the whole request as well as the response.
Shortcut for --print={0}.
'''.format(''.join(OUTPUT_OPTIONS)))
)
output_options.add_argument(
- '--headers', '-h', dest='output_options',
- action='store_const', const=OUT_RESP_HEAD,
+ '--headers', '-h',
+ dest='output_options',
+ action='store_const',
+ const=OUT_RESP_HEAD,
help=_('''
Print only the response headers.
Shortcut for --print={0}.
'''.format(OUT_RESP_HEAD))
)
output_options.add_argument(
- '--body', '-b', dest='output_options',
- action='store_const', const=OUT_RESP_BODY,
+ '--body', '-b',
+ dest='output_options',
+ action='store_const',
+ const=OUT_RESP_BODY,
help=_('''
Print only the response body.
Shortcut for --print={0}.
'''.format(OUT_RESP_BODY))
)
output_options.add_argument(
- '--stream', '-S', action='store_true', default=False,
+ '--stream', '-S',
+ action='store_true',
+ default=False,
help=_('''
Always stream the output by line, i.e., behave like `tail -f'.
@@ -214,7 +218,43 @@ def _(text):
''')
)
+output_processing.add_argument(
+ '--output', '-o',
+ type=FileType('a+b'),
+ dest='output_file',
+ metavar='FILE',
+ help=_(
+ '''
+ Save output to FILE. If --download is set, then only the response
+ body is saved to the file. Other parts of the HTTP exchange are
+ printed to stderr.
+ '''
+ )
+)
+
+output_options.add_argument(
+ '--download', '-d',
+ action='store_true',
+ default=False,
+ help=_('''
+ Do not print the response body to stdout. Rather, download it and store it
+ in a file. The filename is guessed unless specified with --output
+ [filename]. This action is similar to the default behaviour of wget.
+
+ ''')
+)
+
+output_options.add_argument(
+ '--continue', '-c',
+ dest='download_resume',
+ action='store_true',
+ default=False,
+ help=_('''
+ Resume an interrupted download.
+ The --output option needs to be specified as well.
+ ''')
+)
###############################################################################
# Sessions
@@ -223,7 +263,9 @@ def _(text):
.add_mutually_exclusive_group(required=False)
sessions.add_argument(
- '--session', metavar='SESSION_NAME', type=RegexValidator(
+ '--session',
+ metavar='SESSION_NAME',
+ type=RegexValidator(
Session.VALID_NAME_PATTERN,
'Session name contains invalid characters.'
),
@@ -235,7 +277,8 @@ def _(text):
''' % DEFAULT_SESSIONS_DIR)
)
sessions.add_argument(
- '--session-read-only', metavar='SESSION_NAME',
+ '--session-read-only',
+ metavar='SESSION_NAME',
help=_('''
Create or read a session without updating it form the
request/response exchange.
@@ -249,7 +292,8 @@ def _(text):
# ``requests.request`` keyword arguments.
auth = parser.add_argument_group(title='Authentication')
auth.add_argument(
- '--auth', '-a', metavar='USER[:PASS]',
+ '--auth', '-a',
+ metavar='USER[:PASS]',
type=AuthCredentialsArgType(SEP_CREDENTIALS),
help=_('''
If only the username is provided (-a username),
@@ -258,7 +302,9 @@ def _(text):
)
auth.add_argument(
- '--auth-type', choices=['basic', 'digest'], default='basic',
+ '--auth-type',
+ choices=['basic', 'digest'],
+ default='basic',
help=_('''
The authentication mechanism to be used.
Defaults to "basic".
@@ -272,7 +318,10 @@ def _(text):
network = parser.add_argument_group(title='Network')
network.add_argument(
- '--proxy', default=[], action='append', metavar='PROTOCOL:HOST',
+ '--proxy',
+ default=[],
+ action='append',
+ metavar='PROTOCOL:HOST',
type=KeyValueArgType(SEP_PROXY),
help=_('''
String mapping protocol to the URL of the proxy
@@ -281,14 +330,17 @@ def _(text):
''')
)
network.add_argument(
- '--follow', default=False, action='store_true',
+ '--follow',
+ default=False,
+ action='store_true',
help=_('''
Set this flag if full redirects are allowed
(e.g. re-POST-ing of data at new ``Location``)
''')
)
network.add_argument(
- '--verify', default='yes',
+ '--verify',
+ default='yes',
help=_('''
Set to "no" to skip checking the host\'s SSL certificate.
You can also pass the path to a CA_BUNDLE
@@ -299,14 +351,19 @@ def _(text):
)
network.add_argument(
- '--timeout', type=float, default=30, metavar='SECONDS',
+ '--timeout',
+ type=float,
+ default=30,
+ metavar='SECONDS',
help=_('''
The connection timeout of the request in seconds.
The default value is 30 seconds.
''')
)
network.add_argument(
- '--check-status', default=False, action='store_true',
+ '--check-status',
+ default=False,
+ action='store_true',
help=_('''
By default, HTTPie exits with 0 when no network or other fatal
errors occur.
@@ -333,17 +390,25 @@ def _(text):
troubleshooting.add_argument(
'--help',
- action='help', default=SUPPRESS,
+ action='help',
+ default=SUPPRESS,
help='Show this help message and exit'
)
troubleshooting.add_argument(
- '--version', action='version', version=__version__)
+ '--version',
+ action='version',
+ version=__version__
+)
troubleshooting.add_argument(
- '--traceback', action='store_true', default=False,
+ '--traceback',
+ action='store_true',
+ default=False,
help='Prints exception traceback should one occur.'
)
troubleshooting.add_argument(
- '--debug', action='store_true', default=False,
+ '--debug',
+ action='store_true',
+ default=False,
help=_('''
Prints exception traceback should one occur, and also other
information that is useful for debugging HTTPie itself and
Oops, something went wrong.

0 comments on commit 8e6c765

Please sign in to comment.