HTTP requests & web APIs
Call REST APIs with requests: GET/POST, params, JSON, auth, timeouts, error handling, sessions, retries and pagination.
Modern software is glued together by web APIs: payment gateways, weather services, GitHub, Slack, your own company's microservices. They speak HTTP and usually exchange JSON. The third-party requests library is the most popular way to call them from Python — it's simple, robust and used by millions of projects. In this lesson you'll make GET and POST requests, handle errors and timeouts properly, authenticate, and build a small reusable API client.
The examples use two free public test APIs: JSONPlaceholder (fake blog data) and httpbin.org (echoes back what you send).
HTTP in two minutes#
An HTTP request has a method, a URL, headers and optionally a body. The server returns a response with a status code, headers and a body.
Your first GET request#
The response object gives you status_code, headers (a case-insensitive dict), text (body as a string), content (raw bytes) and json() (parsed JSON).
Query parameters#
Don't glue query strings together by hand; pass a dict with params and requests encodes it safely:
Sending data: POST with JSON#
json= serialises your dict and sets the Content-Type: application/json header. Use data= for HTML-form-style submissions and files= for uploads. requests.put, requests.patch and requests.delete work the same way.
Headers and authentication#
APIs usually require an API key or token, normally sent in a header. Never hard-code secrets in source code — read them from environment variables:
In development, people often keep secrets in a .env file loaded with the python-dotenv package — and add .env to .gitignore.
Handling errors properly#
Network code fails in many ways: DNS errors, refused connections, slow servers, 404s, 500s, invalid JSON. Two crucial facts:
- requests has no default timeout. Without
timeout=, a stuck server can hang your program forever. - HTTP error codes don't raise exceptions by themselves. Call
raise_for_status().
All of these exceptions inherit from requests.RequestException, which you can catch as a fallback.
Sessions: connection reuse and shared settings#
When you call the same API repeatedly, use a requests.Session. It reuses TCP connections (much faster), and lets you set headers, auth and cookies once:
Automatic retries#
Transient failures (a 503, a 429 rate limit, a dropped connection) are often fixed by waiting and trying again. requests can do this with urllib3's Retry, mounted on a session:
Be careful retrying non-idempotent requests like POST — you might create the same order twice.
Pagination#
APIs return large collections in pages. Loop until there's nothing left — a generator keeps the calling code clean:
Real APIs signal the next page in different ways — a next URL in the JSON, a Link header (r.links["next"]["url"]), or a cursor token. Read the API's docs.
Worked example: a small API client class#
Wrapping an API in a class keeps URLs, auth and error handling in one place:
In tests, you'd replace the network calls with fakes (see the pytest lesson) so tests are fast and don't depend on the internet.
Beyond requests: httpx and async#
httpx offers an almost identical API plus async support and HTTP/2 — useful with FastAPI and asyncio (covered in the concurrency lesson):
Common mistakes#
- No
timeout— your program can hang forever. - Not checking the status code — use
raise_for_status(). - Hard-coding API keys in code or committing them to git.
- Building query strings by hand — use
params=. - Hammering an API in a tight loop — respect rate limits (
429), cache results, and back off. - Creating a new connection for every call in a loop — use a
Session.
What's next#
An API client without tests is a liability. Next you'll learn the industry-standard testing tool: pytest.
Check your understanding
Quick quiz
1.Why should you always pass
timeout=torequests.get()?2.What does
response.raise_for_status()do?3.How should you send a JSON body in a POST request with requests?
Finished reading?
Mark this lesson complete to track your progress.