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 |
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
[
{
"barangay": "Ibo",
"province_or_huc": "City of Lapu-Lapu",
"municipality_or_city": null,
"psgc_id": "0731100013",
"f_0p0b_ratio_score": 80.0,
"f_00mb_ratio_score": 0.0,
"f_0pmb_ratio_score": 64.0,
"000b": "ibo",
"0p0b": "lapulapu ibo",
"00mb": "none ibo",
"0pmb": "lapulapu none ibo",
"psgc-aux-data.correspondence_code": "0072226013",
"psgc-aux-data.old_names": null,
"psgc-aux-data.city_class": null,
"psgc-aux-data.income_classification": null,
"psgc-aux-data.urban_rural": "U",
"psgc-aux-data.population": 7453,
"psgc-aux-data.status": null
}
]
Python API
from barangay import barangay_flat
from barangay.plugin_loader import PluginLoader
loader = PluginLoader(env=True)
loader.enable_plugin("psgc-aux-data")
enriched = loader.enrich_flat([r.model_dump() for r in barangay_flat])
for r in enriched:
if r.get("extensions"):
print(r["name"], r["extensions"][0]["data"])
break
Bangsamoro Autonomous Region In Muslim Mindanao (BARMM) {'correspondence_code': '0150000000', 'old_names': None, 'city_class': None, 'income_classification': None, 'urban_rural': None, 'population': 4545486, '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