Using OpenData in Jupyter Notebooks
Run notebooks on your own machine with JupyterLab or VS Code. This guide walks you through everything from installing Python to plotting your first chart.
If you want to skip local setup entirely, try Google Colab instead. Python is pre-installed and you can start querying data in seconds.
What's a Jupyter Notebook?
A Jupyter notebook is a document where you write code in "cells" and run each one individually. When you run a cell, the output (a table, a chart, a number) appears right below it. It's the most popular way to explore data with Python because you can see results as you go, instead of writing a whole script and running it all at once.
Step 1: Install Python
You need Python 3.9 or newer. Check if it's already installed by opening a terminal (Terminal on Mac, Command Prompt or PowerShell on Windows) and running:
# Mac / Linuxpython3 --version# Windows (try both -- depends on how Python was installed)python --versionpython3 --version
If you see something like Python 3.11.5, you're good. If you get "command not found", install Python:
- Mac: Install Homebrew if you don't have it, then run
brew install python - Windows: Download the installer from python.org/downloads. Check "Add Python to PATH" during install.
- Linux:
sudo apt install python3 python3-pip(Ubuntu/Debian) orsudo dnf install python3 python3-pip(Fedora)
Step 2: Install JupyterLab
JupyterLab is the notebook application itself. Install it from your terminal:
python3 -m pip install jupyterlab
Step 3: Start JupyterLab
jupyter lab
This opens JupyterLab in your browser. Click the "Python 3" tile under "Notebook" to create a new notebook.
VS Code alternative: If you use VS Code, install the Jupyter extension instead. You can create .ipynb files directly in VS Code without running a separate JupyterLab server.
Step 4: Install the SDK
In your notebook, type the following into the first cell and run it. The ! at the start tells the notebook to run this as a terminal command instead of Python code.
!pip install tryopendata[pandas]
You'll see some install output scroll by. Wait until it finishes before running the next cell.
Load Your First Dataset
Add a new cell below the install cell with this code:
from opendata_sdk import OpenData# No API key required for public datasets.# Create a free account for higher limits (no credit card):# https://tryopendata.ai/settings/api-keysclient = OpenData() # or: OpenData(api_key="od_live_...")df = client.load("fred/unemployment-rate").to_pandas()df.head()
Run it. You should see a table with monthly US unemployment rate data going back to 1948. That's the core loop: create a client, load a dataset, call .to_pandas() to get a DataFrame, and use .head() to preview the first 5 rows.
No API key required. Public datasets are free to query without one. If you hit rate limits during heavy use, create a free account (no credit card, no payment) at tryopendata.ai/settings/api-keys for higher limits.
Complete Working Example
Here's a full example you can copy and paste into a single cell. It loads US unemployment data, filters it to recent years, prints a summary, and plots a chart. You'll be able to see the COVID-19 spike in 2020.
# ── Install (skip if you already ran the install cell above) ──!pip install -q tryopendata[pandas] matplotlib# ── Setup ──from opendata_sdk import OpenData, Query# No key needed for public data. Create a free account for higher limits:# https://tryopendata.ai/settings/api-keys (no credit card required)client = OpenData() # or: OpenData(api_key="od_live_...")# ── Inspect the dataset before loading ──meta = client.meta("fred/unemployment-rate")print(f"Dataset: {meta.name}")print(f"Rows: {meta.rows:,}")print(f"Columns: {[c.name for c in meta.columns]}")print()# ── Load with server-side filters ──# Only matching rows are downloaded, so this is fast even for big datasetsq = (Query().gte("date", "2010-01-01") # 2010 onward.fields("date", "unemployment_rate") # just these two columns.sort("date") # oldest first)df = client.load("fred/unemployment-rate", q).to_pandas()print(f"Loaded {len(df)} rows\n")# ── Preview the data ──print(df.head(10))print()# ── Plot a chart ──ax = df.assign(date=df["date"].astype(str)).plot(x="date",y="unemployment_rate",title="US Unemployment Rate (2010 - Present)",xlabel="Date",ylabel="Unemployment Rate (%)",figsize=(12, 5),legend=False,)ax.figure.tight_layout()# ── Summary stats ──print(f"Range: {df['unemployment_rate'].min():.1f}% to {df['unemployment_rate'].max():.1f}%")print(f"Latest: {df['unemployment_rate'].iloc[-1]:.1f}%")
When you run that cell, you'll see the dataset info, a table of rows, a line chart showing the 2020 COVID spike and recovery, and summary stats. Everything in one shot.
Finding Datasets
You can search the catalog right from your notebook. No need to leave and open a browser.
results = client.search("consumer price index")for ds in results.results:print(f"{ds.provider}/{ds.slug}: {ds.name}")print(f" {(ds.description or '')[:80]}...")print()
Each dataset has a path like fred/unemployment-rate or fred/cpi. That's what you pass to client.load(). You can also browse the full catalog at tryopendata.ai/explore.
Using Views
Some datasets have pre-built "views" that reshape the raw data. A monthly dataset might have a timeseries view that normalizes dates, or an annual view that aggregates by year. You can load a specific view like this:
from opendata_sdk import Query# Load the annual average instead of monthly data pointsdf = client.load("fred/unemployment-rate", Query().view("annual")).to_pandas()df.head()
Every dataset page on tryopendata.ai has a Notebook tab in the API Examples section that gives you a ready-to-paste snippet with the right view pre-selected.
Using Polars Instead of pandas
Polars is a newer, faster DataFrame library. If you want to use it instead of pandas, swap the install extra and call .to_polars():
!pip install tryopendata[polars]from opendata_sdk import OpenDataclient = OpenData()df = client.load("fred/unemployment-rate").to_polars()df.head()
SQL Queries
You can run DuckDB-compatible SQL directly against any dataset using client.sql.execute(). This is useful when you need JOINs across datasets or anything the Query Builder can't express. SQL queries require an API key -- see the Authentication section below.
from opendata_sdk import OpenDataclient = OpenData(api_key="od_live_...")# Single dataset queryresult = client.sql.execute("SELECT year, value FROM fred/gdp WHERE year > 2020 ORDER BY year")df = result.to_pandas()df.head()
# Cross-dataset JOIN -- reference datasets by provider/slug in SQLresult = client.sql.execute("""SELECT a.year, a.value AS gdp, b.populationFROM fred/gdp aJOIN census/population b ON a.year = b.yearWHERE a.year > 2015""")df = result.to_pandas()df.head()
For the full SQL reference -- bind parameters, options, result metadata, and async usage -- see the Python SDK docs.
Large Datasets
Most datasets fit in memory without any trouble. For the occasional large one, process the data in chunks so you don't run out of memory:
for page in client.datasets.query_iter("census/acs5", page_size=5000):chunk = page.to_pandas()print(f"Processing {len(chunk)} rows...")# do something with each chunk
Authentication
Public datasets work without any key. For higher rate limits, pass your API key when creating the client:
client = OpenData(api_key="od_live_your_key_here")
You can also set it as an environment variable so every notebook picks it up automatically:
export OPENDATA_API_KEY=od_live_your_key_here
What's Next
- Google Colab -- zero-setup alternative if you don't want to install anything locally
- Python SDK Reference -- full SDK docs including async usage, error handling, and all available methods
- Querying Guide -- all filter operators, sorting, aggregation, and advanced queries
- Views -- how dataset views work
- Authentication -- API key management and rate limits