Qipudata
San Francisco · v0.7.1
qipu data›San Francisco›Documentation›Downloads and API

Downloads and API

Everything is static files on a public bucket: no key, no sign-up, no rate plan. Parquet is the reference format.

Base URLs

WhatURL
The current releasehttps://tiles.qipu.org/data/latest.json
Release v0.7.1 fileshttps://tiles.qipu.org/data/releases/v0.7.1/
One Parquet file per tablehttps://tiles.qipu.org/data/releases/v0.7.1/parquet/<table>.parquet
SQLite, all tableshttps://tiles.qipu.org/data/releases/v0.7.1/qipu_sf.db (6.44 GB)
CSV by decadehttps://tiles.qipu.org/data/releases/v0.7.1/csv/ (see CSV_MANIFEST.json)
JSON per place or personhttps://tiles.qipu.org/data/sf/<kind>/<slug>
Manifest (sha256 of every file)https://tiles.qipu.org/data/releases/v0.7.1/manifest.json

A release never changes after it is published. latest.json names the newest one:

curl https://tiles.qipu.org/data/latest.json
{"version": "v0.7.1", "url": "releases/v0.7.1/", …}

Query without downloading

The Parquet files support HTTP range requests, so DuckDB, Polars or the SQL console fetch only the columns and row groups a query needs.

-- every passed decision that names Kezar Stadium, oldest first
SELECT year, date, plain_best, source_url
FROM 'https://tiles.qipu.org/data/releases/v0.7.1/parquet/decisions.parquet'
WHERE plain_best ILIKE '%Kezar Stadium%' AND outcome_best = 'passed'
ORDER BY year, date;
# how one supervisor voted, from the vote claims (Python + DuckDB)
import duckdb
base = "https://tiles.qipu.org/data/releases/v0.7.1/parquet"
duckdb.sql(f"""
  SELECT value_text AS vote, count(*) AS n
  FROM '{base}/claims.parquet'
  WHERE property = 'voted' AND subject_id = 'qipu:sf/person/dianne-feinstein'
  GROUP BY 1 ORDER BY 2 DESC""").show()
# yes 31,596 · absent 4,500 · no 1,479 · excused 3

Download everything

curl -O https://tiles.qipu.org/data/releases/v0.7.1/qipu_sf.db
pip install datasette
datasette qipu_sf.db -m metadata.json

metadata.json (in the release) labels every table and column for Datasette.

Check what you downloaded

curl -s https://tiles.qipu.org/data/releases/v0.7.1/manifest.json | python3 -c "import json,sys; m=json.load(sys.stdin); print(len(m['files']), 'files')"
shasum -a 256 decisions.parquet   # compare with the manifest's sha256

Licence and citation

The facts are CC0 1.0: use them for anything, no permission needed. The scans belong to their holders; we link to them. To cite a decision, cite the page: SF Board of Supervisors, Journal of Proceedings, 1912, archive.org/details/journalofproceed1912sanfrich/page/n66. To cite the dataset, see the release.