13

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
    – dwurf
    Commented Aug 13, 2013 at 14:07

2 Answers 2

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...

5
  • 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.
    – dwurf
    Commented Jun 19, 2013 at 4:32
  • 5
    Python 2: python -c "from urllib import urlretrieve; urlretrieve('http://python-distribute.org/distribute_setup.py', 'distribute_setup.py')"
    – dwurf
    Commented Jun 19, 2013 at 4:46
  • 5
    Python 3: python3 -c "from urllib.request import urlretrieve; urlretrieve('http://python-distribute.org/distribute_setup.py', 'distribute_setup.py')"
    – dwurf
    Commented Jun 19, 2013 at 4:46
  • 2
    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). Commented Dec 16, 2013 at 17:38
  • 1
    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
    – iuridiniz
    Commented Dec 5, 2018 at 23:05
6

My solution is:

python -c "import urllib; print urllib.urlopen('http://python-distribute.org/distribute_setup.py').read()" > distribute_setup.py
1
  • 1
    this is really bad for large files, and it only works on python2. not really what the OP wanted.
    – mata
    Commented Jun 18, 2013 at 7:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.