Skip to main content

Python utilities for Indian developers — lakh/crore formatting, GST & PAN validation, address parsing, festival calendar

Project description

🇮🇳 bharatutils

Python utilities for Indian developers — because 1,500,000 should display as ₹15 L

PyPI Python License Downloads

Lakh/crore formatting · GST & PAN validation · Address parsing · Festival calendar

Zero dependencies. Never crashes on messy data. Made for Bharat.

pip install bharatutils

😩 The problem every Indian developer knows

# Without bharatutils — written for the 100th time, breaks on NaN
df["salary_display"] = df["salary"].apply(
    lambda x: f"₹{round(x/100000, 2)} L" if x >= 100000 else f"₹{x:,}"
)

# With bharatutils — one import, handles everything
from bharatutils import format_inr
df["salary_display"] = df["salary"].apply(format_inr)

Western libraries format millions and billions, validate US Social Security numbers, and know when Thanksgiving falls. bharatutils speaks lakh and crore, validates GSTIN with real checksums, reads addresses with landmarks instead of street numbers, and knows when Diwali is.


✨ Features

💰 Indian number formatting

from bharatutils import format_inr, to_lakh, to_crore

format_inr(1500000)        # '₹15.0 L'
format_inr(50000000)       # '₹5.0 Cr'
format_inr("15,00,000")    # '₹15.0 L'   — messy strings? handled
format_inr(-750000)        # '-₹7.5 L'   — negatives? handled
format_inr(float("nan"))   # 'N/A'       — pandas NaN? handled
indian_commas(15000000)    # '1,50,00,000' — full Indian grouping

Drop it straight into a pandas pipeline on 100,000 dirty rows. It won't flinch.

🧾 GST validation — with the real checksum

from bharatutils import validate_gstin_strict, parse_gstin

validate_gstin_strict("27AAAPZ2318J1ZI")   # True — verifies check digit
validate_gstin_strict("27AAAPZ2319J1ZI")   # False — catches the typo!

parse_gstin("27AAAPZ2318J1ZI")
# {'state': 'Maharashtra', 'pan': 'AAAPZ2318J', 'entity_number': '1', ...}

Most validators only check the format pattern. bharatutils implements the official mod-36 check-digit algorithm — a single wrong character fails validation, exactly as it should.

🪪 PAN validation + holder type decoding

from bharatutils import parse_pan

parse_pan("AAAPZ2318J")
# {'holder_type': 'Individual', 'name_initial': 'Z', 'is_individual': True}

The 4th character of every PAN hides its meaning: P person, C company, T trust, G government — decoded for you.

📍 Indian address parsing

from bharatutils import parse_address

parse_address("Flat 302, Shree Krishna Apts, Nr. SBI ATM, MG Road, Pune - 411001")
# {'pincode': '411001', 'state': 'Maharashtra', 'city': 'Pune'}

Landmarks, flat numbers, "Nr. SBI ATM" — none of it confuses the parser. Space-broken pincodes (700 016) get normalized. Phone numbers don't fool it. It always returns a dict, never crashes.

🪔 One calendar for all of Bharat

from bharatutils import get_festivals, next_festival, days_until

next_festival()          # {'name': 'Muharram', 'date': datetime.date(2026, 6, 26)}
days_until("Diwali")     # 150
get_festivals(2026)      # every festival of the year, sorted by date

Holi and Eid. Christmas and Guru Nanak Jayanti. Buddha Purnima and Diwali. One calendar, every celebration — the way India actually lives. Dates for 2023–2027, verified against official Government of India holiday lists.


📖 Quick reference

Function What it does
format_inr(n) Smart ₹ formatting (auto lakh/crore)
to_lakh(n) / to_crore(n) Plain numeric conversion
validate_gstin(g) Format + state check
validate_gstin_strict(g) Format + state + checksum
parse_gstin(g) Extract state, PAN, entity number
validate_pan(p) / parse_pan(p) PAN check + holder type decode
parse_address(a) Pincode, state, city from messy text
extract_pincode(a) / pincode_to_state(p) The building blocks
get_festivals(year) Full year calendar, sorted
next_festival() / days_until(name) / is_festival(date) Calendar queries

🗺️ Roadmap

  • v0.1 — five core modules, published
  • v0.1.2 — festival data 2023–2027, Buddha Purnima added
  • v0.2 — exact pincode→district lookup, pandas accessor (df["col"].india.to_lakh())
  • v0.3 — IFSC validation, vehicle registration parsing, regional festival calendars

Honest note: pincode→state mapping is currently prefix-based (~95% accurate). Exact lookup is the headline feature of v0.2.

🤝 Contributing

Found a bug? Wrong festival date? Missing your state's festivals? Open an issue — responses are fast. PRs welcome.

📄 License

MIT — use it anywhere, build anything, just keep the name on it.

Made with ❤️ for every developer who ever wrote a lakh formatter at 2am

pip install bharatutils

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

bharatutils-0.1.2.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

bharatutils-0.1.2-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file bharatutils-0.1.2.tar.gz.

File metadata

  • Download URL: bharatutils-0.1.2.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for bharatutils-0.1.2.tar.gz
Algorithm Hash digest
SHA256 439a93d82a8bb0d50c737c9724d0c9ef61b55e0fe711eb557200dcdeca4a09a9
MD5 e459539797d8b906b36ffbe8da64e066
BLAKE2b-256 06694959a2bd4a68fb1094a8257178a61c9737db59165633ca611a82955128ee

See more details on using hashes here.

File details

Details for the file bharatutils-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: bharatutils-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 10.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for bharatutils-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6f6016010cb33a0bd932d5a9b3c45d916502645724c8c1c39f9be848f5166151
MD5 1a59e41d2e4c32745456aa661bbd87c3
BLAKE2b-256 182992b4ab6b828767c6e60dcb7a1fc7af04228d366ef12884d3bf6142be1dd7

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