Getting started (3)
Last updated Oct 1, 2026 This guide will instruct you through:
- Creating your first R2 bucket and enabling its data catalog.
- Creating an API token needed for query engines to authenticate with your data catalog.
- Using PyIceberg ↗︎ to create your first Iceberg table in a marimo ↗︎ Python notebook.
- Using PyIceberg ↗︎ to load sample data into your table and query it.
Prerequisites
- Sign up for a Cloudflare account ↗︎.
- Install
Node.js↗︎.
<details>
<summary>
Node.js version manager
</summary>
Use <a href="https://viteplus.dev/guide/env">Vite+ (<code>vp env</code>) ↗︎</a> to install and manage Node.js versions.
For supported Node.js versions, refer to the <a href="https://developers.cloudflare.com/workers/wrangler/install-and-update/#install-wrangler">Wrangler system requirements</a>.
</details>
1. Create an R2 bucket and enable the data catalog
- If not already logged in, run:npmyarnpnpm
npx wrangler login
yarn wrangler login
pnpm wrangler login
- Create an R2 bucket:npmyarnpnpm
npx wrangler r2 bucket create r2-data-catalog-tutorial
yarn wrangler r2 bucket create r2-data-catalog-tutorial
pnpm wrangler r2 bucket create r2-data-catalog-tutorial
- Enable the catalog on your bucket:npmyarnpnpm
npx wrangler basin catalog enable r2-data-catalog-tutorial
yarn wrangler basin catalog enable r2-data-catalog-tutorial
pnpm wrangler basin catalog enable r2-data-catalog-tutorial
When you run this command, take note of the Warehouse and Catalog URI. You will need these later.
- In the Cloudflare dashboard, go to the Basin Catalog page. Go to Basin Catalog ↗
- Select Create catalog.
- Enter the bucket name
r2-data-catalog-tutorial. The wizard creates the bucket automatically if it does not already exist. Optionally choose a location hint. - Review the configuration and select Create catalog.
- Once created, the catalog detail page displays your Catalog URI and Warehouse name. Note these values for later.
2. Create an API token
Iceberg clients (including PyIceberg ↗︎) must authenticate to the catalog with an R2 API token that has both R2 and catalog permissions.
- In the Cloudflare dashboard, go to the R2 object storage page. Go to Overview ↗
- Select Manage API tokens.
- Select Create API token.
- Select the R2 Token text to edit your API token name.
- Under Permissions, choose the Admin Read & Write permission. This guide creates and writes to tables, so it requires read and write access. For query-only clients, you can instead use an Admin Read only token. For details on choosing the right permission level, refer to Authenticate your Iceberg engine.
- Select Create API Token.
- Note the Token value.
3. Install uv
You need to install a Python package manager. In this guide, use uv ↗︎. If you do not already have uv installed, follow the installing uv guide ↗︎.
4. Install marimo and set up your project with uv
We will use marimo ↗︎ as a Python notebook.
- Create a directory where our notebook will be stored:
bash
mkdir r2-data-catalog-notebook
- Change into our new directory:
bash
cd r2-data-catalog-notebook
- Initialize a new uv project (this creates a
.venvand apyproject.toml):
plaintext
uv init
- Add marimo and required dependencies:
py
uv add marimo pyiceberg pyarrow pandas
5. Create a Python notebook to interact with the data warehouse
- Create a file called
r2-data-catalog-tutorial.py. - Paste the following code snippet into your
r2-data-catalog-tutorial.pyfile:
```py import marimo
__generated_with = "0.11.31" app = marimo.App(width="medium")
@app.cell def _(): import marimo as mo return (mo,)
@app.cell def _(): import pandas import pyarrow as pa import pyarrow.compute as pc import pyarrow.parquet as pq
from pyiceberg.catalog.rest import RestCatalog
# Define catalog connection details (replace variables)
WAREHOUSE = "<WAREHOUSE>"
TOKEN = "<TOKEN>"
CATALOG_URI = "<CATALOG_URI>"
# Connect to Basin Catalog
catalog = RestCatalog(
name="my_catalog",
warehouse=WAREHOUSE,
uri=CATALOG_URI,
token=TOKEN,
)
return (
CATALOG_URI,
RestCatalog,
TOKEN,
WAREHOUSE,
catalog,
pa,
pandas,
pc,
pq,
)
@app.cell def _(catalog): # Create default namespace if needed catalog.create_namespace_if_not_exists("default") return
@app.cell def _(pa): # Create simple PyArrow table df = pa.table({ "id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"], "score": [80.0, 92.5, 88.0], }) return (df,)
@app.cell def _(catalog, df): # Create or load Iceberg table test_table = ("default", "people") if not catalog.table_exists(test_table): print(f"Creating table: {test_table}") table = catalog.create_table( test_table, schema=df.schema, ) else: table = catalog.load_table(test_table) return table, test_table
@app.cell def _(df, table): # Append data table.append(df) return
@app.cell def _(table): print("Table contents:") scanned = table.scan().to_arrow() print(scanned.to_pandas()) return (scanned,)
@app.cell def _(): # Optional cleanup. To run uncomment and run cell # print(f"Deleting table: {test_table}") # catalog.drop_table(test_table) # print("Table dropped.") return
if name == "main": app.run() ```
- Replace the
CATALOG_URI,WAREHOUSE, andTOKENvariables with your values from sections 1 and 2 respectively. - Launch the notebook editor in your browser:
plaintext
uv run marimo edit r2-data-catalog-tutorial.py
Once your notebook connects to the catalog, the catalog along with its namespaces and tables will appear in the Datasources panel in marimo.
In the Python notebook above, you:
- Connect to your catalog.
- Create the
defaultnamespace. - Create a simple PyArrow table.
- Create (or load) the
peopletable in thedefaultnamespace. - Append sample data to the table.
- Print the contents of the table.
- (Optional) Drop the
peopletable we created for this tutorial.
Learn more
Managing catalogs
Enable or disable Basin Catalog on your bucket, retrieve configuration details, and authenticate your Iceberg engine.
Connect to Iceberg engines
Find detailed setup instructions for Apache Spark and other common query engines.
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/basin-catalog/get-started/#page","headline":"Getting started","description":"Learn how to enable the Basin Catalog on your bucket, load sample data, and run your first query.","url":"https://developers.cloudflare.com/basin-catalog/get-started/","inLanguage":"en","image":"https://developers.cloudflare.com/basin-catalog/get-started/og.png?v=59ca79981771be63","dateModified":"2026-10-01","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
description: Understand how to manage Iceberg REST catalogs associated with R2 buckets title: Manage catalogs image: https://developers.cloudflare.com/basin-catalog/manage-catalogs/og.png?v=b56be5e9a67ac7cf
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/basin-catalog/llms.txt
Use this file to discover all available pages before exploring further.
Docs