Python

Everything below runs at build time against the latest release — this page’s own output is real, not copied.

Install

pip install duckdb

Attach and query

import duckdb

con = duckdb.connect()
con.execute("ATTACH 'https://basemap.cancerdatasci.org/data/latest/cancerbasemap.duckdb' AS cbm (READ_ONLY)")
<_duckdb.DuckDBPyConnection at 0x7fe8e21a3040>

Mammography screening in Colorado counties, lowest first, with the interval, the release that said so, and the county’s rurality code:

con.sql("""
    SELECT u.name, o.source_release, o.value AS pct, o.lower, o.upper, o.value_status,
           r.value AS rucc_code
    FROM cbm.measure.observation o
    JOIN cbm.geography.unit u
      ON u.geo_id = o.geo_id AND u.vintage = 2026
    LEFT JOIN cbm.measure.observation r
      ON r.geo_id = o.geo_id AND r.source = 'RUCC'
    WHERE o.source = 'PLACES' AND o.measure_id = 'PLACES:MAMMOUSE:age_adjusted'
      AND o.source_release = '2025' AND u.parent_geo_id = 'state:08'
     
    ORDER BY pct LIMIT 10
""").df()
name source_release pct lower upper value_status rucc_code
0 Kiowa County 2025 62.3 57.4 66.8 reported 9.0
1 Otero County 2025 63.9 54.4 72.9 reported 6.0
2 Bent County 2025 63.9 54.4 72.6 reported 9.0
3 Baca County 2025 64.2 54.2 73.1 reported 9.0
4 Crowley County 2025 64.6 54.8 73.7 reported 8.0
5 Adams County 2025 64.9 57.6 71.7 reported 1.0
6 Prowers County 2025 65.3 56.2 74.3 reported 7.0
7 Delta County 2025 65.5 56.7 73.3 reported 6.0
8 Costilla County 2025 65.6 55.8 74.4 reported 9.0
9 Montezuma County 2025 66.2 57.1 75.3 reported 6.0

Fetch with duckdb, requests or polars: Python’s default urllib user agent is blocked by the zone (HTTP 403, Cloudflare error 1010). Pin a dated folder (.../data/v2026-11-02/cancerbasemap.duckdb) for anything you will rerun.

u.vintage = 2026 is named explicitly rather than trusting o.geo_vintage — see Concepts › Time axes for why a measure’s own geo_vintage column isn’t always the vintage its geo_id actually belongs to (tracked as #21).

con.sql(...) returns a DuckDB relation; .df() materializes it as a pandas DataFrame, .arrow() as an Arrow table, or iterate it directly — whatever the rest of your analysis expects.