Working with APIs
Requests In, JSON Out
Calling an API from Python takes three steps:
- Send an HTTP GET request to a URL, often with query parameters
- Receive a response with a status code and a body, usually JSON
- Convert the JSON into a pandas DataFrame
The requests library handles step 1 and 2, and pandas handles step 3.
Open in Google Colab
The exchange rate, World Bank and pagination examples in this lesson call real, free APIs with no key needed, and run as they are in Colab. Open a new notebook and paste each block into its own cell.
Your First API Call: Live Naira Exchange Rates
The open.er-api.com service returns free daily exchange rates with no API key required.
import requests
response = requests.get("https://open.er-api.com/v6/latest/USD", timeout=10)
print(response.status_code) # 200 means success
data = response.json() # parse the JSON body into a Python dict
print(data.keys())
print("1 USD =", data["rates"]["NGN"], "NGN")
print("Last updated:", data["time_last_update_utc"])
The JSON body becomes nested Python dictionaries and lists, which is exactly what you practised in the Python basics lesson.
Status codes you must know
| Code | Meaning | What to do |
|---|---|---|
| 200 | OK | Parse the data |
| 400 | Bad request | Check your parameters |
| 401 / 403 | Unauthorised / forbidden | Check your API key |
| 404 | Not found | Check the URL |
| 429 | Too many requests | Slow down; you hit a rate limit |
| 500+ | Server error | Retry later |
Always check the status before you parse:
response.raise_for_status() # raises an error for any 4xx or 5xx code
Nigerian Economic Data from the World Bank API
The World Bank API publishes thousands of indicators for every country, including Nigeria (country code NGA). Much of Nigeria's official data in it comes from the National Bureau of Statistics (NBS) and the Central Bank of Nigeria (CBN), so it is one of the easiest programmatic routes to Nigerian macroeconomic data.
import pandas as pd
import requests
def world_bank(indicator, country="NGA"):
url = f"https://api.worldbank.org/v2/country/{country}/indicator/{indicator}"
params = {"format": "json", "per_page": 100}
r = requests.get(url, params=params, timeout=15)
r.raise_for_status()
meta, rows = r.json() # the API returns [metadata, data]
return pd.DataFrame([
{"year": int(row["date"]), "value": row["value"]} for row in rows
]).dropna().sort_values("year")
inflation = world_bank("FP.CPI.TOTL.ZG") # inflation, consumer prices (annual %)
gdp_growth = world_bank("NY.GDP.MKTP.KD.ZG") # GDP growth (annual %)
inflation.tail()
Some useful indicator codes:
| Indicator | Code |
|---|---|
| GDP (current US$) | NY.GDP.MKTP.CD |
| GDP growth (annual %) | NY.GDP.MKTP.KD.ZG |
| Inflation, consumer prices (annual %) | FP.CPI.TOTL.ZG |
| Official exchange rate (LCU per US$) | PA.NUS.FCRF |
| Population, total | SP.POP.TOTL |
| Unemployment (% of labour force, ILO estimate) | SL.UEM.TOTL.ZS |
Plot the result straight away:
merged = inflation.merge(gdp_growth, on="year", suffixes=("_inflation", "_gdp_growth"))
merged.plot(x="year", y=["value_inflation", "value_gdp_growth"], figsize=(10, 4),
title="Nigeria: Inflation vs GDP Growth (%)")
What about CBN and NBS directly?
- The CBN publishes exchange rates, interest rates and monetary statistics on cbn.gov.ng, mostly as web tables and downloadable Excel files rather than a documented public API.
pd.read_htmlorpd.read_excelon the downloaded file is the usual approach. - The NBS (nigerianstat.gov.ng) publishes CPI, GDP, labour force and trade reports, usually as PDF and Excel files.
You will work with both in the Nigerian Datasets lesson.
Query Parameters, Keys and Headers
Most APIs accept parameters that filter the results, and many require an API key:
# Needs a free OpenWeather API key in API_KEY
params = {"q": "Lagos", "units": "metric", "appid": API_KEY}
r = requests.get("https://api.openweathermap.org/data/2.5/weather", params=params)
Never paste API keys directly into a notebook you will share or push to GitHub. In Colab, use the Secrets panel (the key icon in the sidebar) and read the key with google.colab.userdata.get("MY_KEY").
Nested JSON and Pagination
Real API responses are often nested. pd.json_normalize flattens them:
records = [
{"id": 1, "customer": {"name": "Ada", "city": "Lagos"}, "amount": 15000},
{"id": 2, "customer": {"name": "Musa", "city": "Kano"}, "amount": 42000},
]
pd.json_normalize(records)
# columns: id, amount, customer.name, customer.city
Large results are split into pages. Loop until there are no more:
url = "https://api.worldbank.org/v2/country/NGA/indicator/SP.POP.TOTL"
all_rows, page = [], 1
while True:
r = requests.get(url, params={"format": "json", "per_page": 20, "page": page}, timeout=15).json()
meta, rows = r
all_rows.extend(rows)
if page >= meta["pages"]:
break
page += 1
Be a Good API Citizen
- Respect rate limits: add
time.sleep(1)between calls in loops - Cache results: save to CSV so you do not call the API every time you rerun the notebook
- Always set a
timeoutso a slow server does not hang your code - Read the documentation; every API has quirks
Try it yourself
Key Takeaways
- Calling an API means sending a GET request with requests.get, checking the status code, and parsing the JSON body with .json().
- The World Bank API is a free, keyless route to Nigerian macroeconomic indicators such as inflation, GDP and exchange rates.
- CBN and NBS mainly publish data as web tables and Excel or PDF files, so read_html and read_excel are the usual tools for their data.
- Use pd.json_normalize for nested JSON, and loop over pages for large results.
- Be a good API citizen: set timeouts, respect rate limits, cache results, and keep API keys out of your notebooks.
Quick Quiz
1.An API call returns status code 429. What does it mean?
2.What does pd.json_normalize do?
3.Where should you store an API key when working in a shared Colab notebook?
Ready to go further?
CareerEx gives you structured 12-week training, live classes every Saturday and Sunday, real tutor feedback, and a certificate. Join the next cohort.
Join CareerEx