Explain Codes LogoExplain Codes Logo

How to download a file over HTTP?

python
download-progress
binary-data
file-handling
Anton ShumikhinbyAnton Shumikhin·Sep 18, 2024
TLDR

Let's start with a way to download files in a jiffy using requests. Confirm it's installed with pip install requests. Then use the following snippet to fetch and save a file:

import requests url = 'http://example.com/file.zip' # If only downloading life was this simple response = requests.get(url, stream=True) # Take it slow, one stream at a time with open('downloaded_file.zip', 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) # It's a write-a-thon! Go, go, go!

Use your preferred file name instead of downloaded_file.zip. This code handles large files efficiently by streaming the data in manageable chunks.

No requests? No problem! (urllib)

If the requests library isn't available or unsuitable for your needs, turn to urllib.request.urlretrieve() in Python 3:

import urllib.request url = 'http://example.com/file.jpg' # The art of remote file fetching filename = 'downloaded_file.jpg' # Where the magic lives urllib.request.urlretrieve(url, filename) # Presto!

Python 2 users, don't fret: just swap urllib.request.urlretrieve() with urllib.urlretrieve(). For large file download, urllib.request.urlopen() to the rescue:

import urllib.request url = 'http://example.com/bigfile.zip' # Your big catch filename = 'bigfile.zip' # The secret stash with urllib.request.urlopen(url) as response: with open(filename, 'wb') as out_file: out_file.write(response.read()) # The great spill-over

This native Python feature mimics wget without any external commands.

Binary data (because it's not always about text)

Binary files such as MP3s or images require special handling. Remember: binary files are not text - don't discern .decode()! Write binary straight to the file:

import requests url = 'http://example.com/song.mp3' # The sweet, sweet sound of binary music filename = 'song.mp3' # Your next hit single response = requests.get(url) with open(filename, 'wb') as f: f.write(response.content) # Lay down the tracks

Ensure to use the 'wb' mode to preserve the integrity of binary data.

Download progress? ProgressBar to the rescue (tqdm)

To easily track download progress, integrate the tqdm progress bar. It's helpful in delivering an intuitive download experience:

import requests from tqdm import tqdm url = 'http://example.com/largefile.iso' # The saga continues... response = requests.get(url, stream=True) with open('largefile.iso', 'wb') as f, tqdm( unit='B', unit_scale=True, unit_divisor=1024, total=int(response.headers.get('content-length', 0)), ) as bar: for data in response.iter_content(chunk_size=1024): size = f.write(data) bar.update(size) # Slowly climbing the Everest

To install tqdm, run pip install tqdm. It's a small feature that goes a long way in enhancing user feedback.

Got your sweatbands on? Let's dive deep!

Working with small files

For small files or when in a hurry, urlretrieve() directly downloads the file in a single swift move. An elegant solution for a more civilized code.

C.O.D.: Chunks Over Delivery

When working with large files, breaking them into chunks can prevent your app from choking, thanks to streaming. It's like having your python eat the elephant... one bite at a time!

It's a Binary World!

Binary files aren't too difficult to handle in Python. Retain their binary nature while writing and they'll be just fine. Remember: no .decode()!

The joy of Progress

Feeling in the dark about your download progress? Light it up with tqdm. A progress bar not only looks cool but also tells the user that the code is working as expected.