Skip to main content

India-first PIN code intelligence library — 165,627 records, zero dependencies

Project description

BharatPin

India-first PIN code intelligence library — production-grade, zero dependencies, pure Python.

Python 3.9+ MIT License Zero Dependencies PyPI


Why BharatPin?

Feature bharatpin indiapins pypinindia pgeocode
Pincode → State / District / Area
All areas / localities for a pincode
Real GPS coordinates (92.7% coverage)
Nearby pincodes (radius search)
Distance between pincodes
Fuzzy / typo-tolerant search
Old city names (Bombay, Madras, Calcutta…)
Address validation + suggestions
City tier classification (1 / 2 / 3)
HO / SO / BO office-type priority
Delivery vs Non-Delivery filter
CLI tool
Zero external dependencies
2026 updated dataset

Dataset

Metric Value
Post office records 1,65,627
Unique pincodes 19,586
States & Union Territories 37
GPS coordinate coverage 92.7%
Source India Post 2026

Installation

pip install bharatpin

Quick Start

import bharatpin

# Basic lookups
bharatpin.get_state("360001")           # "Gujarat"
bharatpin.get_district("360001")        # "Rajkot"
bharatpin.get_area("360001")            # "Rajkot"

# All localities covered by a pincode
bharatpin.get_all_areas("360001")
# ['Rajkot', 'Rajkot City', 'Rajkot D H College', 'Rajkot Jn Plot', ...]

# Full details
bharatpin.get_pincode_info("360001")

# Fuzzy search — typos and old city names both work
bharatpin.search_area("bangalor")       # finds Bengaluru
bharatpin.search_area("bombay")         # finds Mumbai
bharatpin.search_area("calcutta")       # finds Kolkata

# Geo
bharatpin.calculate_distance("360001", "110001")    # 1077.42 km
bharatpin.find_nearby("360001", radius_km=25)

# Validate an address
bharatpin.validate_address("380001", district="Ahmedabad", state="Gujarat")

# City tier
bharatpin.get_city_tier("110001")       # Tier 1 (Metro)
bharatpin.get_city_tier("360001")       # Tier 2 (Major City)

API Reference

Core

bharatpin.get_pincode_info("360001")    # full info dict + all_offices list
bharatpin.get_state("360001")           # "Gujarat"
bharatpin.get_district("360001")        # "Rajkot"
bharatpin.get_area("360001")            # primary area name (suffix-stripped)
bharatpin.get_all_areas("360001")       # every locality under the pincode
bharatpin.get_offices("360001")         # all offices sorted HO → SO → BO
bharatpin.get_delivery_offices("360001")# delivery-only offices
bharatpin.get_stats()                   # dataset statistics

Reverse Lookups

bharatpin.get_pincodes_by_state("Gujarat")      # all pincodes in a state
bharatpin.get_pincodes_by_district("Rajkot")    # all pincodes in a district
bharatpin.get_pincodes_by_area("Rajkot")        # pincodes for an area name
bharatpin.get_districts_by_state("Gujarat")     # districts in a state
bharatpin.get_all_states()                      # all 37 states / UTs

Search

# Fuzzy area search — supports typos, partial names, and old city names
bharatpin.search_area("rajkot")
bharatpin.search_area("bangalor")                        # typo → Bengaluru
bharatpin.search_area("bombay")                          # old name → Mumbai
bharatpin.search_area("mumbai", state="Maharashtra", top_n=5)

# Pincode prefix search
bharatpin.search_pincode("3600")         # all pincodes starting with 3600

Supported old / alternate city names (60+): Bombay → Mumbai · Madras → Chennai · Calcutta → Kolkata · Bangalore → Bengaluru · Baroda → Vadodara · Poona → Pune · Trivandrum → Thiruvananthapuram · Simla → Shimla · Allahabad → Prayagraj · Gauhati → Guwahati · Gurgaon → Gurugram …

Geo

bharatpin.get_coordinates("360001")
# {'lat': 22.298, 'lng': 70.7972}

bharatpin.calculate_distance("360001", "110001")    # km, Haversine

bharatpin.find_nearby("360001", radius_km=25)
# [{'pincode': '360020', 'area': 'Mavdi', 'distance_km': 3.21, ...}, ...]

bharatpin.find_nearby("360001", radius_km=100, state="Gujarat")

Address Validation

bharatpin.validate_address("380001", district="Ahmedabad", state="Gujarat")
# {'valid': True, 'state_match': True, 'district_match': True,
#  'actual': {'state': 'Gujarat', 'district': 'Ahmedabad', ...}}

bharatpin.validate_address("380001", state="Maharashtra")
# {'valid': False, 'state_match': False,
#  'message': "state mismatch: got 'Maharashtra', expected 'Gujarat'"}

bharatpin.suggest_correction("380001", state="Maharashtra")
# [{'pincode': '380001', 'state': 'Gujarat', 'confidence': 0.5}]

City Tier

bharatpin.get_city_tier("110001")
# {'tier': 1, 'label': 'Tier 1 (Metro)', 'area': 'New Delhi GPO', ...}

# Custom overrides for your business logic
bharatpin.set_custom_tiers({"Surat": 1, "Rajkot": 2})
bharatpin.set_custom_tiers({})   # reset

CLI

bharatpin lookup 360001
bharatpin search rajkot
bharatpin search bombay
bharatpin nearby 360001 --radius 25
bharatpin nearby 360001 --radius 100 --state Gujarat
bharatpin distance 360001 110001
bharatpin validate 380001 --state Gujarat --district Ahmedabad
bharatpin tier 110001
bharatpin stats

Common Use Cases

E-commerce — autofill city/state from pincode

info = bharatpin.get_pincode_info(user_pincode)
# Pre-fill checkout form with info["area"], info["district"], info["state"]

Logistics — serviceability check

dist = bharatpin.calculate_distance(warehouse_pin, customer_pin)
is_serviceable = dist is not None and dist <= 300

Fintech / KYC — address verification

result = bharatpin.validate_address(pin, district=district, state=state)
if not result["valid"]:
    corrections = bharatpin.suggest_correction(pin, state=state)

Marketing — tier-based segmentation

tier = bharatpin.get_city_tier(customer_pin)["tier"]   # 1, 2, or 3

Package Structure

bharatpin/
├── src/bharatpin/
│   ├── __init__.py      # public API
│   ├── _loader.py       # lazy singleton loader + Record dataclass
│   ├── core.py          # O(1) dict lookups
│   ├── search.py        # fuzzy search + alias resolution
│   ├── geo.py           # Haversine distance + nearby
│   ├── address.py       # validation + correction
│   ├── tier.py          # city tier classification
│   ├── cli.py           # CLI tool
│   └── data/
│       └── pincodes.csv # 1,65,627 rows — India Post 2026
├── tests/
├── assets/
│   └── bharatpin_logo.svg
├── pyproject.toml
└── README.md

Architecture

  • Lazy loading — CSV is parsed once on first call, not at import time
  • 5 in-memory indexes — all lookups are O(1) dictionary access
  • Bounding-box pre-filterfind_nearby rejects out-of-range points before running Haversine
  • Zero dependencies — Haversine (math), fuzzy search (trigrams), CSV (csv), CLI (argparse) — all stdlib

Contributing

Pull requests are welcome. For major changes, open an issue first.

git clone https://github.com/jeet308/bharatpin
cd bharatpin
pip install -e ".[dev]"
pytest tests/ -v

License

MIT © 2025 BharatPin Contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bharatpin-1.0.1.tar.gz (3.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bharatpin-1.0.1-py3-none-any.whl (3.4 MB view details)

Uploaded Python 3

File details

Details for the file bharatpin-1.0.1.tar.gz.

File metadata

  • Download URL: bharatpin-1.0.1.tar.gz
  • Upload date:
  • Size: 3.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.7

File hashes

Hashes for bharatpin-1.0.1.tar.gz
Algorithm Hash digest
SHA256 3d74adcedc6260ca4a267387ac4711650240aae2b60484a7e599fd7c7819dd90
MD5 0c257d2941866dcf80f67baffa7c556b
BLAKE2b-256 c95d3521ea4def11976aa6d81da9e1477fd3296a65421af28e8e396269031201

See more details on using hashes here.

File details

Details for the file bharatpin-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: bharatpin-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 3.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.7

File hashes

Hashes for bharatpin-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 441ec616933b6a25f6c25d50569fc3931bc753d5f81155964f5120d14c2cedec
MD5 42dbd2ccf737853c17227f658ef917d5
BLAKE2b-256 8b5b25266adf138fdbe3c987088fa37615e65d2059eaca677fbdb45fbefcf3d4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page