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/yourname/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.0.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.0-py3-none-any.whl (3.4 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: bharatpin-1.0.0.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.0.tar.gz
Algorithm Hash digest
SHA256 6f2f339229221453c55c58b08bcb12231d9464ace31c16f1c7464621f24448d9
MD5 0b34e12e6bfb3826745d14463e917223
BLAKE2b-256 18868cbded120db423940d32ec23069d32710f417fa2bf9ddcdf2c325f023d85

See more details on using hashes here.

File details

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

File metadata

  • Download URL: bharatpin-1.0.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 024ba7c67b358a7ebd2319f8271dc40e0dd056c10532509600f41693ea8c0582
MD5 866832b3598c9a6e30ebf4f9e1904c76
BLAKE2b-256 147896b5c75dd6c8bb7b636abf36bc57c39018ae18fb5fb84fb712112aab95fd

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