# barangay

> Philippine Standard Geographic Code (PSGC) Python package with fuzzy search for barangays, municipalities, cities, provinces, and regions. Offline access to all 42,011 barangays — no API calls or database needed. Based on the official April 2026 PSGC masterlist from the Philippine Statistics Authority.

## Installation

```bash
pip install barangay
```

Requires Python 3.13+.

## Quick Start

```python
from barangay import barangays, search_fuzzy

print(barangays)  # <PSGC barangay database: 42010 records>

brgy = barangays.get(name="Tongmageng")
print(brgy.region)    # Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
print(brgy.province)  # Tawi-Tawi
print(brgy.psgc_id)   # 1907005010

for r in search_fuzzy("Tongmagen, Tawi-Tawi"):
    print(f"{r.name} ({r.psgc_id}) — score: {r.score}")
```

## Key Features

- **Fuzzy search** — handles misspellings and unstandardized addresses using rapidfuzz
- **Bundled data** — all 42,011 barangays, 1,488 municipalities, 146 cities, 82 provinces, 17 regions included offline
- **Hierarchy traversal** — navigate parent, children, and ancestors of any admin division
- **Pandas export** — `to_frame()` and `to_dicts()` for immediate DataFrame access
- **Address validation** — `validate()` and `validate_many()` with configurable thresholds
- **Historical PSGC** — access previous masterlist releases by date (2023–2026)
- **Three data models** — nested (dict-like), flat (list), extended (recursive with metadata)
- **CLI included** — search, export, validate, batch operations
- **Smart caching** — automatic local caching for subsequent loads
- **Plug-in system** — enrich PSGC data with custom extensions (CSV, JSON, Parquet), built-in and remote plugins supported

## Database API

### Views

```python
from barangay import regions, provinces, municipalities, cities, submunicipalities, barangays, special_geographic_areas

# Iterate, count, check membership
print(len(barangays))  # 42010
print("1907005010" in barangays)  # True
for region in regions:
    print(region.name)
```

### Lookup

```python
# By name (raises MultipleResultsError if ambiguous)
brgy = barangays.get(name="Tongmageng")

# By PSGC ID (always unique)
brgy = barangays.lookup("1907005010")
```

### Hierarchy

```python
brgy = barangays.get(name="Tongmageng")
print(brgy.region)       # Bangsamoro Autonomous Region In Muslim Mindanao (BARMM)
print(brgy.province)     # Tawi-Tawi
print(brgy.municipality)  # Sitangkai
print(brgy.parent)       # <municipality: Sitangkai (1907005000)>
print(brgy.ancestors)    # [municipality, province, region]
print(brgy.children)      # direct children

# Serialize with hierarchy fields
d = brgy.to_dict()
# {'name': 'Tongmageng', 'psgc_id': '1907005010', 'region': '...', 'province': 'Tawi-Tawi', ...}
```

### Export

```python
df = barangays.to_frame()     # pd.DataFrame with region, province, highly_urbanized_city, independent_component_city, component_city, municipality, submunicipality, special_geographic_area, barangay columns
data = barangays.to_dicts()   # List[dict]
```

### Fuzzy Search

```python
from barangay import search_fuzzy

results = search_fuzzy("query", level=None, threshold=60.0, limit=5, as_of=None, match_hooks=None)
for r in results:
    print(r.name, r.psgc_id, r.score, r.match_type)
```

### Validation

```python
from barangay import validate, validate_many

v = validate("Tongmageng, Tawi-Tawi")  # default threshold 95.0
print(v.valid, v.matched_name, v.score)  # True Tongmageng 100.0

results = validate_many(["addr1", "addr2"])
```

### Version Switching

```python
import barangay

barangay.use_version("2025-07-08")
brgy = barangay.barangays.lookup("1907005010")
barangay.use_version(None)  # back to latest
```

### Plugins

```python
import barangay

barangay.use_plugins(["population"], levels=[barangay.AdminLevel.HIGHLY_URBANIZED_CITY])
```

## Legacy API (Deprecated — removal in 2027.X.X.X)

### Search (dict-based)

```python
from barangay import search

results = search("query", n=5, threshold=60.0, match_hooks=["barangay"], as_of=None)
# Returns List[dict] with keys: barangay, province_or_huc, municipality_or_city, psgc_id, ...
```

### Data Access

```python
from barangay import barangay, barangay_flat, barangay_extended

# Nested: region → municipality/city → barangay
ncr = barangay["National Capital Region (NCR)"]

# Flat: list of all admin divisions with psgc_id, parent_psgc_id, type
brgy = [item for item in barangay_flat if item.name == "Marayos"]

# Extended: recursive tree with metadata
for region in barangay_extended.components:
    print(region.name, region.psgc_id)
```

### Utilities

```python
from barangay import sanitize_input, resolve_date, get_available_dates, create_fuzz_base

cleaned = sanitize_input("City of San Jose", exclude=["city of "])
fuzz_base = create_fuzz_base()  # reuse for batch searches
dates = get_available_dates()
```

## CLI

```bash
barangay search "Tongmageng, Tawi-Tawi"
barangay search "Tongmageng" --plugin psgc-aux-data --format json
barangay export --model flat --format json --output data.json
barangay export --model flat --plugin psgc-aux-data --format json --output enriched.json
barangay info version
barangay batch validate names.txt
```

## PyPI

https://pypi.org/project/barangay/

## Repository

https://github.com/bendlikeabamboo/barangay

## Documentation

https://bendlikeabamboo.github.io/barangay/
