This episode covers HTTP communication from Python: modern usage of requests, httpx for sync and async modes, setting up retries, timeouts, and connection pooling, plus an overview of WSGI servers with Gunicorn and ASGI with Uvicorn.

Almost every modern application communicates over HTTP — calling APIs, sending data, and integrating with other services. Episode 12 equips you with networking skills: how Python becomes a reliable HTTP client.
We'll compare requests and httpx, learn to set up retries, timeouts, and connection pooling, then understand the WSGI and ASGI servers that are the foundation of the web frameworks in episode 13.
requests is the most popular HTTP library for Python:
pip install requestsimport requests
resp = requests.get("https://httpbin.org/json", timeout=10)
print(resp.status_code)
print(resp.json())requests.get("https://httpbin.org/json", timeout=10) sends a GET request and resp.json() parses the JSON body. Always set a timeout so requests don't hang forever — one of the causes of apps feeling slow.
httpx is the modern successor to requests with HTTP/2 and async support. Its API is nearly identical, so the switch is easy:
pip install httpximport httpx
resp = httpx.get("https://httpbin.org/json", timeout=10.0)
print(resp.status_code)
print(resp.json()["slideshow"]["title"])httpx.get(url, timeout=10.0) behaves like requests. The main difference is the async support that can run many requests concurrently.
Async mode uses an event loop and the await keyword:
import asyncio
import httpx
async def ambil():
async with httpx.AsyncClient(timeout=10.0) as klien:
resp = await klien.get("https://httpbin.org/json")
return resp.json()
hasil = asyncio.run(ambil())
print(hasil["slideshow"]["title"])async with httpx.AsyncClient(timeout=10.0) as klien: opens an async client. await klien.get(...) waits for the response without blocking other threads. This pattern is very efficient for many concurrent requests and pairs well with FastAPI in episode 13.
Timeouts prevent the application from hanging when a service is slow:
import httpx
klien = httpx.Client(
timeout=httpx.Timeout(connect=5.0, read=30.0, write=10.0, pool=5.0)
)
print(klien.timeout.read)httpx.Timeout(connect=5.0, read=30.0, ...) separates the limits for connect, read, write, and pool. A long read time accommodates slow APIs, while the connection still fails fast if the target is unreachable.
Retries handle transient failures. httpx supports them through a transport:
import httpx
transport = httpx.HTTPTransport(retries=3)
klien = httpx.Client(transport=transport, timeout=10.0)
resp = klien.get("https://httpbin.org/status/500")
print(resp.status_code)httpx.HTTPTransport(retries=3) creates a transport that retries failed connections up to three times. For smarter retries — for instance with exponential backoff — consider the tenacity or backoff libraries.
Pooling reuses TCP connections for subsequent requests, saving handshake overhead:
import httpx
klien = httpx.Client(
limits=httpx.Limits(max_connections=20, max_keepalive_connections=10)
)
for _ in range(5):
resp = klien.get("https://httpbin.org/json")
print(resp.status_code)
klien.close()httpx.Limits(max_connections=20, max_keepalive_connections=10) caps the number of open connections. Using one client for many requests avoids creating a new connection every time — an important pattern for high-traffic services.
Python web servers follow two different specifications:
The core difference is the execution model: WSGI is one request per thread, ASGI is one event loop handling many requests.
Gunicorn is a popular production WSGI server:
pip install gunicorngunicorn --workers 4 --bind 0.0.0.0:8000 app:appgunicorn --workers 4 --bind 0.0.0.0:8000 app:app runs a WSGI application with four workers. Gunicorn manages processes and threads to handle many requests — the backbone of Flask and Django deployments.
Uvicorn is an ASGI server for async applications:
pip install "uvicorn[standard]"uvicorn --workers 4 --host 0.0.0.0 --port 8000 app:appuvicorn --workers 4 --host 0.0.0.0 --port 8000 app:app runs an ASGI application. Uvicorn uses an event loop to handle thousands of concurrent connections — the performance foundation of the FastAPI we'll build in the next episode.
Key takeaways:
In the next episode, episode 13, we'll cover web frameworks and API design — comparing Flask, Django, and FastAPI, how to choose the right framework, designing RESTful and GraphQL APIs, plus versioning, pagination, and input validation. This is the time to build a real API!