mloda-plugin-govdata
Connectors for German open government data, built on mloda. Request the columns you want as mloda features; the plugin handles CKAN discovery, download with caching and retries, and parsing (German CSV or publisher JSON) into a typed Arrow table.
Three example datasets cover the M1 themes: population (GovData CSV), elections (Bundeswahlleiterin kerg.csv), and environment (UBA Air Data JSON).
Status
Young but working. All three example readers run end to end, with paginated dataset search, cached downloads with retries, and unit plus property-based tests behind them. Every reader is a thin subclass of BaseGovDataReader that overrides only the parse step; new datasets follow the same path (see docs/adding-a-reader.md). Development happens in a 6-month Prototype Fund stage (June to November 2026), so the API may still shift between releases.
Usage
Read the Stuttgart population dataset (via GovData) as a typed PyArrow table:
from mloda.user import Feature, mloda
from mloda_plugin_govdata.feature_groups.govdata import StuttgartPopulationReader
slug = "einwohner-nach-altersgruppen-und-stadtbezirken"
result = mloda.run_all(
[
Feature("Einwohner", options={StuttgartPopulationReader: slug}),
Feature("Stadtbezirk", options={StuttgartPopulationReader: slug}),
],
compute_frameworks=["PyArrowTable"],
)
table = result[0] # pyarrow.Table with the requested columns
result.plan # resolved execution steps: which FeatureGroup ran on which framework
The options key is the reader class or its class-name string; both select the same reader. The option value is a GovData dataset slug or a direct distribution URL. The license is read from the CKAN distribution metadata. Set BaseGovDataReader.cache_dir to control where downloads are cached. For any other GovData CSV dataset, GovDataReader works out of the box and reads every column as a string; subclass it and set schema for typed columns.
Don't know the slug yet? Search GovData with the paginated CKAN package_search API:
from mloda_plugin_govdata.feature_groups.govdata import build_client, search_datasets
with build_client() as client:
for dataset in search_datasets(client, "einwohner stuttgart", max_results=10):
print(dataset.name, "|", dataset.title)
search_datasets walks the result pages lazily (page_size per request) and stops at max_results or the end of the result set.
Got a slug but not the column names? peek lists what you can request as features:
StuttgartPopulationReader.peek(slug) # {"Stichtag": "date32[day]", "Stadtbezirk": "string", ...}
It works on every reader (BundeswahlleiterinReader.peek(kerg), UbaAirReader.peek(uba_measures_url(...))) and downloads through the cache, so the actual feature request reuses the file. peek takes a raw URL, bypassing the READER_OPTIONS validation below. A typo in a feature name fails with the available columns and a close-match suggestion instead of a raw KeyError.
The elections reader handles a direct CSV URL whose file has a multi-row merged header (Bundeswahlleiterin kerg.csv):
from mloda_plugin_govdata.feature_groups.govdata import BundeswahlleiterinReader
kerg = "https://www.bundeswahlleiterin.de/bundestagswahlen/2025/ergebnisse/opendata/btw25/csv/kerg.csv"
result = mloda.run_all(
[Feature("Gebiet", options={BundeswahlleiterinReader: kerg})],
compute_frameworks=["PyArrowTable"],
)
The environment reader fetches the Umweltbundesamt (UBA) Air Data v4 measures endpoint (REST JSON) and flattens it to one typed row per station and timestamp. Query parameters are per-feature options, not a pre-built URL (here: hourly ozone at station 143); a bad value is rejected during feature resolution, before any network call:
from mloda_plugin_govdata.feature_groups.govdata import (
OPTION_UBA_COMPONENT,
OPTION_UBA_DATE_FROM,
OPTION_UBA_DATE_TO,
OPTION_UBA_SCOPE,
OPTION_UBA_STATION,
UbaAirReader,
)
uba_options = {
UbaAirReader: True,
OPTION_UBA_STATION: 143,
OPTION_UBA_COMPONENT: 3,
OPTION_UBA_SCOPE: 2,
OPTION_UBA_DATE_FROM: "2025-01-01",
OPTION_UBA_DATE_TO: "2025-01-01",
}
result = mloda.run_all(
[
Feature("date_start", options=uba_options),
Feature("value", options=uba_options),
],
compute_frameworks=["PyArrowTable"],
)
Columns are station_id, date_start, component_id, scope_id, value, date_end, and index (the air-quality index). Component and scope ids come from the UBA components and scopes endpoints.
Demo
An interactive marimo notebook walks through dataset discovery and all three example datasets. The notebook lives in the repository (not in the published package), so run it from a source checkout:
git clone https://github.com/mloda-ai/mloda-plugin-govdata.git
cd mloda-plugin-govdata
uv sync --all-extras
uv run marimo edit demos/govdata_demo.py
The notebook hits the live GovData, Bundeswahlleiterin, and UBA endpoints; downloads are cached locally after the first run.
Related Repositories
-
mloda: the core library this plugin builds on. You declare which features you need; mloda resolves how to compute them.
-
mloda-registry: plugin registry and development guides for the mloda ecosystem.
Funding
Developed as part of the Prototype Fund (Round 2 / Jahrgang 02), funded by the German Federal Ministry of Research, Technology and Space (BMFTR) and supported by the Open Knowledge Foundation Deutschland. Funding code (Förderkennzeichen): 16IS26S11. Stage 1 funding period: 6 months from June 2026.
Release files for mloda-plugin-govdata 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mloda_plugin_govdata-0.2.4.tar.gz | 38.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mloda_plugin_govdata-0.2.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 82.7 kB
Release files / mloda_plugin_govdata-0.2.4.tar.gz
| Download URL | mloda_plugin_govdata-0.2.4.tar.gz |
|---|---|
| Size | 38.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
111286b284748861cfa1c14f017e535a35a4373b62a612f96bbc79fd2b548b9f
|
|
BLAKE2b-256 checksum How to use checksums |
6335f44539c9112ed5532f10c4f973974daac6d5858cba30610a14c2a58a0b81
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.20
|
Release files / mloda_plugin_govdata-0.2.4-py3-none-any.whl
| Download URL | mloda_plugin_govdata-0.2.4-py3-none-any.whl |
|---|---|
| Size | 44.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2289e6ee0204ae5cc79ab06e20e4613a6b02469523530457b97ea9bdbde51fbc
|
|
BLAKE2b-256 checksum How to use checksums |
76cecb80fa440b532702fa80ab59d6bfc155112de09300f4c0da53b7b665b263
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.20
|