Install requests once (pip install requests), then a call is three lines that matter: make the request, check it worked, read the JSON.
import requests response = requests.get( "https://api.github.com/repos/python/cpython", timeout=10, ) response.raise_for_status() # stop here on 404, 500 and friends repo = response.json() # the body, parsed into a dict print(repo["full_name"], "has", repo["stargazers_count"], "stars")
That block needs your own machine (new to running Python there? start with the terminal): browsers only let a page call servers that explicitly allow it, so it can't run here. Everything after response.json() is ordinary Python, and you can run that part. Here is the same handling on a dict shaped like GitHub's reply (the numbers are made up):
data = {
"full_name": "python/cpython",
"stargazers_count": 68000,
"topics": ["python", "interpreter"],
"license": {"name": "Other"},
}
print(data["full_name"], "has", data["stargazers_count"], "stars")
print("topics:", ", ".join(data.get("topics", [])))
print("licence:", data.get("license", {}).get("name", "none"))python/cpython has 68000 stars topics: python, interpreter licence: Other
The chained .get(..., {}) is worth copying: real APIs leave fields out, and one missing key shouldn't crash the whole run.
The three lines people skip
timeout=10.requestshas no timeout by default. If the server accepts the connection and then says nothing, your script waits forever. Ten seconds is a sensible starting point.raise_for_status(). A404or500is not an exception inrequests; it's a normal response with an error code. Without this line,.json()runs on an error page and you get a confusingJSONDecodeErrorinstead of a clear "404 Not Found".params=instead of building the URL by hand. It encodes spaces and&correctly:
import requests response = requests.get( "https://api.github.com/search/repositories", params={"q": "web scraping language:python", "per_page": 5}, timeout=10, ) response.raise_for_status() for repo in response.json()["items"]: print(repo["full_name"])
Sending data
json= turns a dict into a JSON body and sets the header for you. Keep keys out of your code and read them from the environment:
import os import requests response = requests.post( "https://api.example.com/v1/orders", json={"product": "Notebook", "quantity": 2}, headers={"Authorization": f"Bearer {os.environ['SHOP_API_KEY']}"}, timeout=10, ) response.raise_for_status() print(response.json()["id"])
The APIs lesson carries on from here: pagination, retries with back-off, and rate limits.