Plugins
Plugins extend barangay by enriching PSGC records with supplementary data. Each plugin is a data package keyed by psgc_id that is joined onto the flat data model — adding fields like population, income classification, old names, and more.
How Plugins Work
Plugins are data packages — not code. Each plugin provides a data file (JSON, CSV, or Parquet) keyed by psgc_id, and the plugin loader joins that data onto PSGC records at query time.
There are two plugin shapes:
| Type | Description | Limit |
|---|---|---|
| Scalar | Each psgc_id maps to a single object. Fields are flattened as plugin_name.field. |
No limit on simultaneous scalar plugins |
| Array | Each psgc_id maps to a list of objects. Each element is cross-joined with the base record. |
Only one array plugin active at a time |
How each shape joins onto a base PSGC record:
Because array plugins cross-join (one base record → many output rows), activating more than one array plugin at a time would multiply row counts combinatorially. The loader enforces a single active array plugin. Scalar plugins have no such limit.
Entry Points
The plugin system can be accessed through three entry points:
| Entry Point | Best For | See |
|---|---|---|
CLI (barangay search / barangay export) |
Quick one-off enrichment, scripting | CLI Reference |
Python API (PluginLoader) |
Programmatic use in applications | Python API |
Configuration (BARANGAY_PLUGINS_DIR, barangay.yaml) |
Persistent setup across sessions | Configuration |
Quick Start
The psgc-aux-data plugin is enabled by default. It ships supplementary PSGC metadata from official PSA releases.
CLI
barangay search "City of Lapu-Lapu" --plugin psgc-aux-data --format json --limit 1[
{
"name": "Lapu-lapu",
"type": "barangay",
"psgc_id": "0401010008",
"parent_psgc_id": "0401010000",
"nicknames": null,
"region": "Region IV-A (CALABARZON)",
"province": "Batangas",
"highly_urbanized_city": null,
"independent_component_city": null,
"component_city": null,
"municipality": "Ibaan",
"submunicipality": null,
"special_geographic_area": null,
"barangay": "Lapu-lapu",
"rphicmsgb": "rp000m00b",
"score": 100.0,
"match_type": "barangay",
"psgc_aux_data.correspondence_code": "0041010008",
"psgc_aux_data.old_names": null,
"psgc_aux_data.city_class": null,
"psgc_aux_data.income_classification": null,
"psgc_aux_data.urban_rural": "R",
"psgc_aux_data.population": 2187,
"psgc_aux_data.status": null
}
]Python API
- 1
-
env=Truepicks up plugins fromBARANGAY_PLUGINS_DIR/barangay.yaml. - 2
- Activate a plugin by name. Multiple scalar plugins can be enabled together.
- 3
-
enrich_flat()joins plugin data onto a list of flat dicts.barangays.to_dicts()is the recommended source for that list.
Arco {'correspondence_code': '0150702001', 'old_names': None, 'city_class': None, 'income_classification': None, 'urban_rural': 'R', 'population': 1224, 'status': None}
Plugin Directory Structure
Each plugin lives in its own subdirectory within a plugin source directory:
plugins/
├── plugins.yaml # plugin activation config
├── psgc-aux-data/
│ └── manifest.yaml # plugin metadata (remote — no local data/)
├── sample_elevation/
│ ├── manifest.yaml
│ └── data/
│ └── sample_elevation.csv
├── sample_population/
│ ├── manifest.yaml
│ └── data/
│ ├── 2020-01-01/
│ │ └── sample_population.json
│ └── 2023-01-01/
│ └── sample_population.json
└── sample_schools/
├── manifest.yaml
└── data/
├── 2024-04-13/
│ └── sample_schools.json
└── 2024-07-13/
└── sample_schools.json
Manifest File
Every plugin must have a manifest.yaml:
name: psgc-aux-data # required
description: Supplementary PSGC data... # optional
version: 0.1.0 # optional
format: json # required: csv | json | parquet
key: psgc_id # required: join key column
repository: https://github.com/user/repo # optional: remote data source
ref: main # optional: git ref (default: main)
current: "2026-04-13" # optional: current version date
dates: # optional: available snapshot dates
- "2021-08-19"
- "2026-04-13"Data Formats
Plugins support three data formats. The key column (psgc_id by default) is used for joining and is excluded from the output fields.
JSON — an array of objects:
[
{ "psgc_id": "0731100000", "correspondence_code": "0072226000", "old_names": "Opon", "population": 497813 }
]CSV — a headered CSV file:
psgc_id,correspondence_code,old_names,population
0731100000,0072226000,Opon,497813
Parquet — a Parquet file with the same column layout.
Remote Plugins
Plugins with a repository field in their manifest fetch data from GitHub. The file is downloaded and cached locally. Time-aware remote plugins list date directories via the GitHub API.
When using --as-of, the loader resolves to the closest available plugin date that is <= the requested date.
Time-Aware Plugins
A plugin is time-aware if its data directory contains YYYY-MM-DD/ subdirectories (local) or declares dates in its manifest (remote). When --as-of is not specified, the current date from the manifest is used.
Built-in Plugins
| Plugin | Enabled | Type | Description |
|---|---|---|---|
psgc-aux-data |
Yes | Scalar, JSON, remote, time-aware | Supplementary PSGC data from official PSA releases |
sample_elevation |
No | Scalar, CSV, local, non-time-aware | Average elevation by province (demo) |
sample_population |
No | Scalar, JSON, local, time-aware | Population counts by city/municipality (demo) |
sample_schools |
No | Array, JSON, local, time-aware | BEISS school records per barangay (demo) |
sample_elevation_time |
No | Scalar, JSON, local, time-aware | Elevation data with date folders (demo) |
See Built-in Plugins for detailed field references.
Next Steps
- CLI Reference — Using plugins with
barangay searchandbarangay export - Python API — Programmatic enrichment with
PluginLoader - Configuration — Environment variables, config files, plugin discovery
- Creating a Plugin — Step-by-step guide to building your own plugin
- Built-in Plugins — Field reference for bundled plugins