Reading streaming http response with Python requests library
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Streaming a response with requests is the right approach when the payload is large or when the server keeps sending data over time. Instead of buffering the entire body into memory, you consume bytes or lines incrementally. The crucial rule is to request the response with stream=True and then iterate using the right API for the data shape you expect.
Start the Request in Streaming Mode
Without stream=True, requests downloads the full body before you begin processing it. For large files or long-lived responses, that defeats the purpose.
Basic chunked download:
This is the standard file-download pattern. iter_content yields bytes incrementally as they arrive.
Use iter_lines for Line-Oriented Streams
If the server emits newline-delimited text, iter_lines is usually a better choice than iter_content.
This works well for log streams, newline-delimited JSON, and similar protocols.
Processing NDJSON Safely
Many streaming APIs send one JSON object per line. You can parse each line as it arrives:
This keeps memory usage low and lets you act on each record immediately.
Why response.text and response.json() Are the Wrong Tools Here
These convenience methods assume you want the full response body. They buffer the response and only then decode or parse it. That is fine for small responses, but it is the opposite of streaming behavior.
If you call response.text on a large or endless stream, you lose the main benefit of incremental processing.
Timeouts and Connection Hygiene
Streaming code should always define a timeout. Otherwise, a stalled connection can hang the process indefinitely.
Also use a context manager or explicitly close the response so the connection returns to the pool:
The with form is usually cleaner, but both patterns are correct.
Choosing the Right Chunk Size
There is no universally correct chunk size. Smaller chunks improve responsiveness and reduce latency to first processing, while larger chunks reduce loop overhead.
Practical defaults:
- '
8192bytes for general file downloads' - smaller sizes for highly interactive streaming
- line-based iteration when the stream is naturally line-delimited
Do not tune this prematurely unless profiling shows it matters.
Long-Lived Streams Need Failure Handling
Network streams break. Production code should decide what to do when the server disconnects:
- stop and report the failure
- reconnect with backoff
- resume from a checkpoint if the protocol supports it
The requests iteration helpers make the read loop easy, but they do not solve retry strategy for you.
Common Pitfalls
- Forgetting
stream=Trueand buffering the whole response anyway. - Using
response.textorresponse.json()on data that should be consumed incrementally. - Ignoring
chunkemptiness checks when writing streamed file data. - Omitting timeouts and letting the process hang on slow or broken connections.
- Using
iter_contentwhen the protocol is actually line-oriented anditer_lineswould be simpler.
Summary
- Use
stream=Trueto keep response bodies incremental. - Use
iter_contentfor binary or chunk-based processing. - Use
iter_linesfor text streams and newline-delimited protocols. - Avoid full-body helpers like
response.textfor genuinely streamed workloads. - Add timeouts and connection cleanup so the streaming loop behaves predictably.
Related reading
- Read/Write String from/to a File in Android
- (Re)attaching to an App Insights Operation from another machine/process (not using HTTP)
- Receive AccessDenied when trying to access a page via the full url on my website
- Redirect http port to nodePort
- Recalling function Tensor 'object' is not callable
- Received a label value of 1 which is outside the valid range of 0, 1 - Python, Keras
- Redirect http// requests to https// on AWS API Gateway using Custom Domains
- Refreshing OAuth token using Retrofit without modifying all calls

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.