14

I am looking for a quick way to download a file via HTTP, using a Python one-liner from the command line (similar to the functionality of wget or curl). The idea is to enable a quick copy/paste to download distutils on Windows.

I know of one solution (see my answer below). I'm interested in other solutions that consider the following:

  • Concise
  • Most "Pythonic" solution
  • Compatible with both Python 2 and Python 3
  • Cross-platform
  • Can deal with large files efficiently
  • No dependencies (we're fetching distutils here. It's unlikely we'll have access to requests at this stage)
  • Correctly handles various HTTP headers, such as Content-Disposition
1
  • 2
    Distutils and setuptools have merged. To fulfill my original goal: c:\python27\python.exe -c "from urllib import urlretrieve; urlretrieve('https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py', 'ez_setup.py')" & c:\python27\python.exe ez_setup.py Commented Aug 13, 2013 at 14:07

3 Answers 3

13

The simplest solution I could come up with would be:

try:
    from urllib.request import urlretrieve
except ImportError:
    from urllib import urlretrieve

urlretrieve('http://example.org', 'outfile.dat')

urlretrieve takes care of downloading the resource to a local file and can deal with large files.

It, however, ignores Content-Disposition headers. If you want that to be considered, you'd need to use urlopen and parse the response headers yourself. Content-Disposition isn't a HTTP standard header, so I doubt you will find much support for it in the Python HTTP libraries...

Sign up to request clarification or add additional context in comments.

5 Comments

The main thing this doesn't have is the ability to run it via a CLI one-liner. I'll mark this as correct since it can be split into two statements, one for python2 and one for python3, that can handle large files and be run as a one-liner.
Python 2: python -c "from urllib import urlretrieve; urlretrieve('http://python-distribute.org/distribute_setup.py', 'distribute_setup.py')"
Python 3: python3 -c "from urllib.request import urlretrieve; urlretrieve('http://python-distribute.org/distribute_setup.py', 'distribute_setup.py')"
Dwurf has the answer correct: the original question wanted this as a one-liner suitable for invoking directly from the command line. (And coincidentally, the search for which brought me here).
Content-Disposition is a standard now. If recent python releases implemented it, well, I don't know. w3.org/Protocols/rfc2616/rfc2616-sec19.html --> 19.5.1 Content-Disposition
6

My solution is:

python -c "import urllib; print urllib.urlopen('http://python-distribute.org/distribute_setup.py').read()" > distribute_setup.py

1 Comment

this is really bad for large files, and it only works on python2. not really what the OP wanted.
0

Here's my one-liner avoiding the deprecated urlretrieve:

python -c 'from urllib.request import urlopen; from pathlib import Path; Path("outfile.dat").write_bytes(urlopen("http://example.org").read())'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.