Making requests
Use Python's requests library to send HTTP GET requests, inspect the response, and raise an error automatically when the server signals failure.
- Send a GET request with requests.get() and query parameters
- Inspect response.status_code, response.json(), and response.text
- Raise an exception automatically on non-200 responses with raise_for_status()
requests is the de facto standard Python library for HTTP. It takes the raw
mechanics of HTTP — connection management, encoding, redirects — and hides them
behind a straightforward interface. Installing it (pip install requests) is
almost always the right first step for any API work.
Sending a GET request
The minimal call is one line:
import requests
response = requests.get("https://jsonplaceholder.typicode.com/todos/1")requests.get() opens a connection, sends the request, waits for the full response,
and returns a Response object. Everything you need is on that object.
Reading the response
Three attributes cover the common cases:
response.status_code— the integer status code (200,404, etc.).response.json()— parses the body as JSON and returns a Python dict or list. Raisesjson.JSONDecodeErrorif the body is not valid JSON.response.text— the raw body as a string, regardless of content type.
Adding query parameters
Many endpoints accept optional parameters in the URL: ?page=2&per_page=50. Pass
them as a dict to the params argument instead of building the URL by hand —
requests handles encoding:
response = requests.get(
"https://jsonplaceholder.typicode.com/todos",
params={"userId": 1, "_limit": 5},
)This produces the URL https://jsonplaceholder.typicode.com/todos?userId=1&_limit=5.
Building URLs manually with string formatting is fragile and easy to get wrong.
Handling failure with raise_for_status()
requests.get() does not raise an exception just because the server returned a 4xx
or 5xx code. The response object arrives normally; you have to check it. The cleanest
way is raise_for_status():
response = requests.get("https://jsonplaceholder.typicode.com/todos/9999")
response.raise_for_status() # raises requests.HTTPError if status >= 400Call this immediately after every request unless you are intentionally handling specific non-200 codes yourself. It converts silent failures — where your script happily processes an error page — into loud exceptions.
raise_for_status() raises requests.exceptions.HTTPError. Always wrap your
request blocks in try/except when running in production so a transient server
error does not crash the whole script.
Try it
The block below hits a real public API. Run it to see a live response:
The browser runner uses urllib (which is available in Pyodide) instead of requests,
but the shape is the same: status code, parsed JSON body, explicit failure check. In a
real script you would use requests and the cleaner .raise_for_status() call.
Where to go next
Next: authentication — most real APIs require credentials. There are three common patterns, and one of them (hardcoding keys) will cause you serious problems the moment you push to version control.
HTTP fundamentals
HTTP is the language of the web — understanding its request/response cycle, methods, status codes, and headers is the foundation of every API integration.
Authentication
Most APIs require credentials. Learn the three common authentication patterns and why storing secrets in environment variables — not source code — is non-negotiable.