JSON Schema
Every file in data/ has a JSON Schema (draft-07) in schema/. The schemas are generated from the zod schemas the TypeScript types are inferred from, so the types, the schemas and the data can't drift apart: CI fails when any of the three disagree.
| Data file | Schema |
|---|---|
data/judicial-areas.json | judicial-areas.schema.json |
data/arrondissements.json | arrondissements.schema.json |
data/cantons.json | cantons.schema.json |
data/canton-boundaries.json | canton-boundaries.schema.json |
data/arrondissement-boundaries.json | arrondissement-boundaries.schema.json |
data/municipalities.json | municipalities.schema.json |
data/regions.json | regions.schema.json |
data/provinces.json | provinces.schema.json |
data/courts.json | courts.schema.json |
data/court-locations.json | court-locations.schema.json |
data/prisons.json | prisons.schema.json |
data/houses-of-justice.json | houses-of-justice.schema.json |
data/postal-codes.json | postal-codes.schema.json |
data/interest-rates.json | interest-rates.schema.json |
data/public-holidays.json | public-holidays.schema.json |
Each schema's $id is its URL on this site, e.g. https://pieterjanscheir.github.io/belgica/schema/courts.schema.json. They're also in the npm package as belgica/schema/courts.schema.json.
Validating the data
import json
from urllib.request import urlopen
from jsonschema import validate # pip install jsonschema
# Pinned to a release, so the data and the schema match
BASE = "https://raw.githubusercontent.com/pieterjanscheir/belgica/v0.6.1/"
courts = json.load(urlopen(f"{BASE}data/courts.json"))
schema = json.load(urlopen(f"{BASE}schema/courts.schema.json"))
validate(courts, schema)import { Ajv } from 'ajv'
import addFormats from 'ajv-formats'
import courts from 'belgica/data/courts.json' with { type: 'json' }
import schema from 'belgica/schema/courts.schema.json' with { type: 'json' }
const ajv = new Ajv()
addFormats(ajv)
ajv.validate(schema, courts) // trueIn TypeScript, the zod schemas do the same without a JSON Schema validator.
You'll mostly want this when you keep a copy of the data (a fork with extra records, a cached download) and want to know it still has the shape the package expects.
Zod schemas
belgica/schemas exports the zod schemas the package's types are inferred from: one per record (courtSchema, cantonSchema, …), per id (courtIdSchema, a z.enum of every id) and per data file (dataFileSchemas).
import { courtIdSchema, dataFileSchemas } from 'belgica/schemas'
const courts = dataFileSchemas.courts.parse(json) // throws a ZodError on a record that doesn't fit
courtIdSchema.safeParse(input).success // whether a string is a known court idOnly belgica/schemas loads zod; the datasets import their types alone.
Generating types for other languages
Because the schemas are standard, you can generate models instead of writing them by hand: datamodel-code-generator for Python (Pydantic), quicktype for C#, Go, Java, Kotlin, Swift and more.
datamodel-codegen --input courts.schema.json --input-file-type jsonschema --output courts.pydatapackage.json
The repository root has a datapackage.json, a Frictionless Data Package descriptor: the standard metadata file for open datasets. It lists each data file with its title, description, schema, official sources, licence, and two fields of our own:
lastReviewed: the day the dataset was last checked against its sources;reviewEveryMonths: how often it must be checked again. The freshness check opens an issue when a dataset is overdue.