Call Web APIs Safely: Keys, Errors, Retries and Rate Limits
Hosted · ide
Beta

Call Web APIs Safely: Keys, Errors, Retries and Rate Limits

Call a real-behaving web API from Python with requests the way production code does: keep the key in the environment and out of git, send parameters and headers with a timeout, treat 404, 401 and silence differently, retry only what can succeed with exponential backoff and Retry-After, and page through results under a rate limit before handing them to a language model and checking its answer against the data.

60 min5 steps3 domainsBeginner

Hands-on labs require Pro · $29.99/mo · cancel anytime

What you'll learn

  1. 1
    Keep the key out of the code
    Brightline's book supplier has given you access to its catalogue API. The
  2. 2
    Your first request: GET, parameters, headers
    A web API is a set of addresses that answer with data instead of web
  3. 3
    When the answer is no: status codes and timeouts
    Status codes come in families, and each family calls for a different
  4. 4
    Retry what can succeed later, and only that
    Some failures fix themselves: a 503 while the server restarts, a 429
  5. 5
    Every page under a rate limit, then one grounded AI answer
    APIs rarely return everything at once. This one sends five books per

Step 1, as you will see it

This is the lab’s own text. Each step ends with a check that runs your work in the lab environment; the hint and the solution stay inside the lab.

Step 1: Keep the key out of the code

Brightline's book supplier has given you access to its catalogue API. The lab runs a copy of it (bookapi.py; Run starts it for you), and like almost every paid API it wants a key with each request. Whoever holds the key can spend your money, so it must never sit in your code: code gets shared, pasted into chats and pushed to GitHub, where bots scan new commits for keys within minutes.

The standard arrangement:

  • The key lives in an environment variable, a named value the operating system hands to your program. Python reads it with os.environ.get("NAME").
  • On your own machine, you keep those variables in a file called .env (open it: it is already here) and the python-dotenv library loads it. load_dotenv() copies each NAME=value line into the environment, without overwriting anything already set, so the real environment on a server wins.
  • .env is listed in .gitignore, so git never commits it.

Do this

1. Add .env to .gitignore. One line, under the TODO comment.

2. Write load_settings() in books.py: call load_dotenv(), read BOOKS_API_URL and BOOKS_API_KEY from os.environ, and if either is missing raise a RuntimeError that names both, so whoever sets up the program knows what to add. Return {"url": url.rstrip("/"), "key": key}. (rstrip("/") drops a trailing slash so url + "/books" never becomes //books.)

3. Run. It prints the settings with the key masked, then shows what the API says to a request without a key.

Starter file: .env

BOOKS_API_URL=http://127.0.0.1:8077
BOOKS_API_KEY=bl-live-4f9c2e71

Prerequisites

  • Basic Python: functions, dictionaries, loops, try/except

Exam domains covered

Python for AIWeb APIsUsing LLMs via API

Skills & technologies you'll practice

This beginner-level ai/ml lab gives you real-world reps across:

PythonrequestsAPIsretriesrate limitsbeginner

What calling an API safely means

Every AI application is a client of web APIs: the model provider, a vector database, a search service, your own backend. The happy path is one line of requests.get. Production code needs the rest: a key that never appears in the source, a timeout on every call, a clear reaction to each class of status code, retries that back off and stop, and pagination that survives a rate limit. In this lab a local book-catalogue API reproduces each of those conditions on demand, so every behaviour is tested, not described. You load secrets with python-dotenv and keep .env out of git, send query parameters and an API key header, return None for a 404 while letting a 401 raise, time out a server that goes silent, write a retry loop with exponential backoff that honours Retry-After and never retries a 400, follow next links through every page, and finish with a language model whose answer is checked against the data it was given.

Frequently asked questions

Why not just put the API key in the script?

Scripts get shared, pasted and committed, and public repositories are scanned for keys within minutes. Reading the key from an environment variable, loaded from a .env file that git ignores, keeps it out of every copy of the code.

Which errors should be retried?

Temporary ones: 429 Too Many Requests, 5xx server errors, timeouts and dropped connections. A 400, 401, 403 or 404 fails the same way on every try, so retrying only adds load. The lab's checker counts the calls your code makes to prove it.

What is exponential backoff?

Waiting longer after each failure, for example 0.5, 1 and 2 seconds, so a struggling server gets time to recover. When the server sends a Retry-After header, that value is used instead.

Does the lab need internet access?

No. The API runs inside the lab as a small Python server, which is what lets it fail on cue. The final step also calls a hosted language model through the lab's proxy.