Skip to content

Repository files navigation

Developer Data Portal

A data portal that serves Marimo notebooks through a Next.js interface. Built on OSO.

Quickstart

# 1. Get an OSO API key at https://www.oso.xyz/start
cp .env.example .env
# Add your key: OSO_API_KEY=your_key_here# 2. Install dependencies
uv sync
cd app && pnpm install &&cd ..
# 3. Export notebooks to static HTMLcd app && pnpm export:notebooks &&cd ..
# 4. Start the dev servercd app && pnpm dev

Open http://localhost:3000.

Prerequisites

Structure

ddp/
├── notebooks/ # Marimo notebooks (.py)
│ ├── quick-start.py
│ ├── publications.py
│ ├── agent-guide.py
│ ├── data/
│ │ ├── sources/ # Open Dev Data, GitHub Archive, OSS Directory
│ │ ├── models/ # Ecosystems, Repositories, Developers, Commits, Events, Timeseries Metrics
│ │ └── metric-definitions/ # Activity, Alignment, Lifecycle, Retention
│ └── insights/ # 2025 Developer Trends, Lifecycle, Speedrun Ethereum, DeFi Journeys, Retention
├── scripts/
│ └── export_notebooks.py # Exports notebooks to static HTML
├── app/ # Next.js app (UI shell)
│ ├── app/ # Pages (App Router)
│ ├── components/ # Sidebar, MarimoIframe
│ └── public/notebooks/ # Exported HTML (generated, gitignored)
└── pyproject.toml

How it works

  • Export stepscripts/export_notebooks.py runs marimo export html on each notebook, writing static HTML to app/public/notebooks/
  • Next.js app (localhost:3000) — navigation shell that serves the exported HTML via MarimoIframe
  • CI — the deploy workflow exports notebooks and builds the site on push to main. A weekly refresh re-exports to pick up fresh data.

Each page in the Next.js app is a thin wrapper around a MarimoIframe component:

<MarimoIframenotebookName="notebooks/insights/developer-lifecycle"/>

Adding a notebook

  1. Create notebooks/<category>/<name>.py using the standard template below
  2. Add a page at app/app/<category>/<name>/page.tsx
  3. Add a nav entry to app/components/Sidebar.tsx
  4. Run cd app && pnpm export:notebooks to generate the HTML

Notebook template

importmarimo__generated_with="unknown"app=marimo.App(width="full")
@app.cell(hide_code=True)defsetup_pyoso():
# This code sets up pyoso to be used as a database provider for this notebook# This code is autogenerated. Modification could lead to unexpected results :)importpyosoimportmarimoasmopyoso_db_conn=pyoso.Client().dbapi_connection()
returnmo, pyoso_db_conn# Add cells hereif__name__=="__main__":
app.run()

For detailed notebook conventions, see notebooks/claude.md.

Configuration

VariableDescription
OSO_API_KEYRequired. OSO data warehouse access key.

About

Raw data, unified models, and insights about crypto developer data.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Packages

Used by

Contributors

Languages