The six API tutorials on this site use Python to pull US economic data straight from government sources. This page is the on-ramp — install Python, learn the pieces you'll actually use, and see what common economic calculations look like in code. Already set up? Skip ahead to Working with Data or Common Calculations.
Setup
Install Python
The easiest way to install Python is with Miniconda, a lightweight installer that works on Windows, Mac, and Linux. Download the installer for your operating system and follow the prompts.
Install Packages
Open a terminal (or Anaconda Prompt on Windows) and install the packages used in the tutorials:
pip install requests pandas matplotlib jupyter
Launch Jupyter
Jupyter notebooks let you write and run Python code in small cells, seeing results immediately. This is ideal for exploring data. To start:
jupyter notebook
This opens a browser window where you can create a new notebook and start writing code. Each cell runs independently, but variables carry over from one cell to the next—so you can build up an analysis step by step.
Python Essentials
You don't need to learn all of Python to follow the tutorials. Here are the pieces that come up most often.
Variables and Types
In[1]:
# Numbers
gdp = 28_781.0 # underscores for readability (ignored by Python)
growth_rate = 2.5
# Strings
agency = 'Bureau of Economic Analysis'
# Lists (ordered collection)
years = [2022, 2023, 2024, 2025]
# Dictionaries (key-value pairs — used heavily in API responses)
indicators = {
'GDP': 28_781.0,
'Unemployment': 4.0,
'Inflation': 2.5
}
f-strings and Imports
f-strings let you embed variables directly in text. Imports load external packages.
In[2]:
import pandas as pd # data analysis
import numpy as np # math and linear algebra
import requests # HTTP requests (for APIs)
# f-strings: prefix a string with f to embed variables
print(f'{agency} reports GDP of ${gdp:,.0f} billion')
print(f'Year range: {years[0]} to {years[-1]}')
Bureau of Economic Analysis reports GDP of $28,781 billion Year range: 2022 to 2025
Dictionaries in Practice
API responses are typically JSON, which Python reads as nested dictionaries. Navigating them is a core skill.
In[3]:
# A simplified API response
response = {
'status': 'REQUEST_SUCCEEDED',
'Results': {
'series': [
{'seriesID': 'LNS14000003', 'data': [{'year': '2025', 'value': '3.5'}]}
]
}
}
# Navigate to the data
value = response['Results']['series'][0]['data'][0]['value']
print(f'Unemployment rate: {value}%')
Unemployment rate: 3.5%
Working with Data
Pandas is the main tool for working with tabular data in Python. The two key objects are Series (a single column) and DataFrame (a table).
Create a DataFrame
In[4]:
# Create from a dictionary
df = pd.DataFrame({
'quarter': ['2024-Q1', '2024-Q2', '2024-Q3', '2024-Q4'],
'gdp': [22050, 22320, 22580, 22710],
'unemployment': [3.8, 3.9, 4.1, 4.0]
})
df
Out[4]:
| quarter | gdp | unemployment | |
|---|---|---|---|
| 0 | 2024-Q1 | 22050 | 3.8 |
| 1 | 2024-Q2 | 22320 | 3.9 |
| 2 | 2024-Q3 | 22580 | 4.1 |
| 3 | 2024-Q4 | 22710 | 4.0 |
Time Series Index
Most economic data is a time series. Setting a datetime index unlocks powerful time-based operations.
In[5]:
# Create a monthly series with a date index
months = pd.date_range('2024-01', periods=6, freq='MS')
price_index = pd.Series([310.1, 311.1, 312.2, 313.0, 313.2, 314.1], index=months, name='CPI')
# Select by date range
price_index.loc['2024-03':'2024-05']
Out[5]:
2024-03-01 312.2 2024-04-01 313.0 2024-05-01 313.2 Name: CPI, dtype: float64
Combining Series
Much of economics is about relationships between variables. Pandas makes it easy to combine series and compute new ones.
In[6]:
# GDP (billions) and population (millions) by year
gdp = pd.Series([21_061, 22_996, 25_463, 27_361, 28_781],
index=[2020, 2021, 2022, 2023, 2024], name='GDP')
pop = pd.Series([331, 332, 333, 335, 336],
index=[2020, 2021, 2022, 2023, 2024], name='Population')
# GDP per capita (in thousands)
per_capita = (gdp / pop * 1000).round(0)
per_capita
Out[6]:
2020 63627.0 2021 69265.0 2022 76466.0 2023 81674.0 2024 85657.0 dtype: float64
Economics Example: The Fiscal Multiplier
Python can solve the kind of problems you'd work through by hand in an economics class. Here's the textbook Keynesian model, solved for GDP and run as a what-if when government spending rises.
A Simple Macro Model
In the basic Keynesian model, GDP (Y) equals consumption (C) plus investment (I) plus government spending (G). Consumption depends on after-tax income:
- Y = C + I + G
- C = 200 + 0.75(Y − T)
With I = 300, G = 400, and T = 300, substituting the consumption function into Y = C + I + G gives an equation in Y alone:
- Y = 200 + 0.75(Y − T) + I + G
- 0.25Y = 200 − 0.75T + I + G
In[7]:
# Solve for Y given the parameters
I, G, T = 300, 400, 300
Y = (200 - 0.75 * T + I + G) / (1 - 0.75)
C = 200 + 0.75 * (Y - T)
print(f'GDP = ${Y:,.0f}B, Consumption = ${C:,.0f}B')
GDP = $2,700B, Consumption = $2,000B
What If Congress Increases Spending?
Suppose government spending rises by $100 billion (G goes from 400 to 500). Re-solve with the new value:
In[8]:
G_new = 500 # up from 400
Y_new = (200 - 0.75 * T + I + G_new) / (1 - 0.75)
print(f'New GDP = ${Y_new:,.0f}B (was ${Y:,.0f}B)')
print(f'Change in GDP: ${Y_new - Y:,.0f}B from $100B in spending')
print(f'Multiplier: {(Y_new - Y) / 100:.0f}x')
New GDP = $3,100B (was $2,700B) Change in GDP: $400B from $100B in spending Multiplier: 4x
Each dollar of government spending raised GDP by four dollars. The multiplier is 1/(1 − 0.75) = 4, because the initial spending becomes someone's income, 75% of which is spent again, and so on. This is the textbook closed-economy result; real-world empirical estimates of the spending multiplier are smaller, typically in the 0.5 to 1.5 range, because some of the new income leaks to imports, savings, and taxes, and central banks may offset the stimulus through monetary policy.
Common Calculations
The API tutorials use a few economic calculations that are worth seeing in one place.
From Price Index to Inflation Rate
The Consumer Price Index (CPI) is a price level, not an inflation rate. To get the headline inflation rate that you see in the news, compare each month's index to the same month one year earlier.
In[9]:
# 18 months of CPI-U data (made up but realistic)
cpi = pd.Series(
[305.7, 307.0, 307.8, 307.7, 308.0, 308.7,
309.7, 310.3, 312.2, 313.5, 314.1, 314.2,
314.5, 315.6, 315.3, 315.8, 316.2, 316.5],
index=pd.date_range('2023-07', periods=18, freq='MS'),
name='CPI-U'
)
# Headline inflation: 12-month percent change
inflation = (cpi.pct_change(12) * 100).dropna().round(1)
inflation
Out[9]:
2024-07-01 2.9 2024-08-01 2.8 2024-09-01 2.4 2024-10-01 2.6 2024-11-01 2.7 2024-12-01 2.5 Name: CPI-U, dtype: float64
The headline inflation rate you see in the news is this 12-month percent change. The BLS API tutorial shows how to fetch the underlying CPI-U series directly.
Adjusting for Inflation
To compare dollar values across time, adjust for inflation by dividing by the price index. This converts nominal values to real (constant-dollar) values.
In[10]:
# Median weekly earnings (nominal) and CPI-U (2020 = 100)
earnings = pd.Series([984, 1001, 1059, 1100, 1145],
index=[2020, 2021, 2022, 2023, 2024], name='Nominal')
cpi_annual = pd.Series([100.0, 104.7, 113.1, 117.7, 120.6],
index=[2020, 2021, 2022, 2023, 2024], name='CPI')
# Real earnings in 2020 dollars
real = (earnings / cpi_annual * 100).round(0)
pd.DataFrame({'Nominal': earnings, 'Real (2020$)': real})
Out[10]:
| Nominal | Real (2020$) | |
|---|---|---|
| 2020 | 984 | 984.0 |
| 2021 | 1001 | 956.0 |
| 2022 | 1059 | 936.0 |
| 2023 | 1100 | 934.0 |
| 2024 | 1145 | 949.0 |
Nominal weekly earnings rose 16% from 2020 to 2024, but real earnings actually fell 4%—wage growth didn't keep pace with inflation. This is a key distinction in any analysis of living standards.
Growth Decomposition
When a total is the sum of components, you can decompose its growth into each component's contribution. Here, consumer spending (PCE) equals goods plus services.
In[11]:
# Quarterly PCE components (billions, made up)
pce = pd.DataFrame({
'Goods': [5800, 5850, 5900, 5880],
'Services': [10200, 10350, 10500, 10650]
}, index=pd.date_range('2024-01', periods=4, freq='QS'))
pce['Total'] = pce['Goods'] + pce['Services']
# Each component's contribution = its change / previous total × 100
for comp in ['Goods', 'Services']:
pce[f'{comp} contribution'] = pce[comp].diff() / pce['Total'].shift() * 100
pce[['Goods contribution', 'Services contribution']].dropna().round(2)
Out[11]:
| Goods contribution | Services contribution | |
|---|---|---|
| 2024-04-01 | 0.31 | 0.94 |
| 2024-07-01 | 0.31 | 0.93 |
| 2024-10-01 | -0.12 | 0.91 |
Services drove most of the growth, while goods spending turned negative in Q4. The contributions sum to the total growth rate each quarter—this is the same technique used in the BEA tutorial to analyze real consumer spending.
Setting Up for the API Tutorials
API Keys
Three of the six tutorials need a free API key — BLS, BEA, and Census all do; Treasury and IMF don't. To keep keys out of your notebook and out of version control, the tutorials read them from a file called config.py that you create in the same folder:
# config.py — keep this file private, don't commit it to git
bls_key = 'your-key-here'
bea_key = 'your-key-here'
census_key = 'your-key-here'
Then in your notebook, import the key you need:
from config import bea_key as api_key
The Treasury API is the exception—it requires no key at all, which makes it a good first tutorial to try.
Making a Request
The basic pattern for fetching data from an API is the same across all the tutorials:
In[12]:
import requests
url = 'https://api.fiscaldata.treasury.gov/services/api/fiscal_service'
url += '/v1/accounting/mts/mts_table_1'
params = {
'fields': 'record_date,current_month_gross_outly_amt',
'sort': '-record_date',
'page[size]': 3
}
r = requests.get(url, params=params)
r.json()['data']
Out[12] (your output will reflect the most recent data available):
[{'record_date': '2025-10-31', 'current_month_gross_outly_amt': '637640'},
{'record_date': '2025-09-30', 'current_month_gross_outly_amt': '547839'},
{'record_date': '2025-08-31', 'current_month_gross_outly_amt': '527946'}]
Next Steps
Each tutorial below walks through a complete example—from API request to finished chart. Treasury is the easiest starting point since it requires no API key.






