Skip to main content

IndiaID 🇮🇳

PyPI version Python versions Tests License: MIT Dependencies Typing

IndiaID is a high-performance, zero-dependency Python library for validating, parsing, and masking Indian government IDs, identity numbers, and document codes.

Designed specifically for FinTechs, KYC onboarding pipelines, HRMS, and modern web applications.


✨ Features

  • ⚡ Zero Runtime Dependencies: Built entirely on standard Python 3.9+.
  • 🧮 Algorithmic Validation: Verhoeff checksum for Aadhaar, Luhn mod-36 for GSTIN.
  • 🎭 Privacy & Masking: UIDAI-compliant Aadhaar masking (XXXXXXXX1234) and PAN/Phone masking.
  • 🧩 Rich Metadata Extraction: Parse state, entity type (PAN), issue year (DL), and postal circles.
  • 🔌 Framework Integrations: First-class optional support for Pydantic v2 and Django / DRF.
  • 🛡️ Strictly Typed: PEP 561 compliant (py.typed) with full static type checking (mypy --strict).
  • 🚀 Automated CI/CD: Seamless GitHub Actions workflow for testing and auto-deploying to PyPI on push to main.

📦 Installation

pip install indiaid

Optional Integrations

# With Pydantic v2 support
pip install "indiaid[pydantic]"

# With Django / DRF support
pip install "indiaid[django]"

# With all integrations
pip install "indiaid[all]"


🚀 Quickstart

Import validators directly for maximum speed and IDE autocompletion:

from indiaid import pan, aadhaar, gstin, vehicle

# Simple boolean check
pan.is_valid("ABCPE1234F")          # True
aadhaar.is_valid("3675 9834 6211")  # True (Verhoeff checksum validated)

# Callable shortcut syntax
if pan("ABCPE1234F"):
    print("Valid PAN format!")

# Mask for privacy / compliance
pan.mask("ABCPE1234F")              # "ABXXXXXX4F"
aadhaar.mask("3675 9834 6211")      # "XXXXXXXX6211"

2. Universal Registry

If you are accepting dynamic document types (e.g., from an API parameter):

import indiaid

# Dynamic validation by document key or alias
is_valid = indiaid.is_valid("pan", "ABCPE1234F")
masked = indiaid.mask("aadhaar", "3675 9834 6211")

3. Rich Validation & Metadata Extraction

Validation returns a ValidationResult dataclass with cleaned values, validation state, and parsed metadata:

from indiaid import pan, gstin, vehicle, pincode

# PAN entity & surname breakdown
res = pan.validate("ABCPE1234F")
if res.is_valid:
    print(res.cleaned_value)             # "ABCPE1234F"
    print(res.get("entity_type"))        # "Individual / Person"
    print(res.get("surname_initial"))    # "E"

# GSTIN state and embedded PAN
res = gstin.validate("27AAPFU0939F1ZV")
if res.is_valid:
    print(res.get("state_name"))         # "Maharashtra"
    print(res.get("state_code"))         # "27"
    print(res.get("pan"))                # "AAPFU0939F"

# Vehicle RC lookup (standard & Bharat 'BH' series)
res = vehicle.validate("MH01A2925")
print(res.get("state_name"))             # "Maharashtra"

# Direct state query helper
print(vehicle.state("MH01A2925"))        # "Maharashtra"
print(vehicle.state("22BH1234AA"))       # "Bharat Series (All India)"

# Pincode zone inspection
res = pincode.validate("400001")
print(res.get("zone_info"))              # "Western Zone (Maharashtra, Goa, Madhya Pradesh, Chhattisgarh)"

4. Exception-Based Workflow (raise_if_invalid)

If your application prefers raising exceptions over checking boolean return values:

from indiaid import vehicle, ValidationError

try:
    res = vehicle.validate("ZZ01A2925").raise_if_invalid()
except ValidationError as exc:
    print(f"Validation failed: {exc}")
    # Output: Validation failed: Invalid state code 'ZZ' in vehicle registration number.

📑 Supported Documents

For in-depth format definitions and regex rules, see docs/supported_documents.md.

Document Direct Import Dynamic Keys / Aliases Validation Rules Masking
Aadhaar aadhaar "aadhaar", "uidai" Verhoeff $D_5$ checksum, non-0/1 start ✅ XXXXXXXX1234
PAN Card pan "pan", "pan_card" 10-char format, entity code, checksum ✅ ABXXXXXX4F
GSTIN gstin "gstin", "gst" State code, embedded PAN, Luhn mod-36 ✅ 27XXXXXXXXXX1ZV
Passport passport "passport" 8-character Indian passport format ✅ X******1
Driving Licence driving_licence "driving_licence", "dl" State RTO code, year boundary (1900–curr) ❌
Voter ID (EPIC) voter_id "voter_id", "epic" Standard 3-alpha/7-digit & legacy formats ✅ XXXXXXX123
Vehicle RC vehicle "vehicle", "rc" State RTO series + Bharat Series (BH) ❌
Bank IFSC ifsc "ifsc" RBI 11-char alphanumeric format ❌
Mobile Phone phone "phone", "mobile" Indian 10-digit (+91/0 prefix handled) ✅ XXXXXX1234
Pincode pincode "pincode", "pin" 6-digit postal circle validation ❌

🛠️ Framework Integrations

Pydantic v2

from pydantic import BaseModel
from indiaid.integrations.pydantic import AadhaarStr, PanStr, GstinStr

class OnboardingRequest(BaseModel):
    name: str
    pan: PanStr
    aadhaar: AadhaarStr
    gstin: GstinStr

Django Models & DRF Serializers

from django.db import models
from indiaid.integrations.django import validate_pan, validate_aadhaar

class Customer(models.Model):
    name = models.CharField(max_length=100)
    pan = models.CharField(max_length=10, validators=[validate_pan])
    aadhaar = models.CharField(max_length=12, validators=[validate_aadhaar])

🧪 Interactive Demo & Testing

Try the interactive demonstration script with complete examples:

python demo.py

Run test suite:

pytest

🚀 Auto-Deploy to PyPI (CI/CD)

This repository includes automated GitHub Actions workflows:

  1. Continuous Testing (.github/workflows/tests.yml): Runs tests, linting (ruff), and type checking (mypy) against Python 3.9, 3.10, 3.11, 3.12, and 3.13 on every push and pull request.

  2. Auto-Deploy on Push to main (.github/workflows/publish.yml): Whenever a commit is pushed to the main branch (or a release is published):

    • GitHub Actions runs the entire test suite.
    • Builds source distribution (sdist) and binary wheel (wheel).
    • Verifies package distribution integrity using twine.
    • Automatically publishes to PyPI using Trusted Publishing (OIDC) or PyPI API Token.
    • skip-existing: true ensures that commits without a version bump won't break your pipeline.

Configuring PyPI Deployment

  1. Go to pypi.org/manage/account/publishing/.
  2. Add a new publisher:
    • PyPI Project Name: indiaid
    • Owner: Shailesh-2128
    • Repository name: indiaid_library
    • Workflow name: publish.yml
    • Environment name: pypi
  3. Push to main! GitHub Actions will authenticate directly with PyPI via OpenID Connect (OIDC).

Option B: PyPI API Token Secret

  1. Create an API token on pypi.org.
  2. In your GitHub repository, navigate to Settings > Secrets and variables > Actions.
  3. Add a secret named PYPI_API_TOKEN with your token value.

👨‍💻 Author & Credits

Created and maintained by Shailesh Jiwana.

Contributions and suggestions are always welcome! Feel free to open an issue or pull request on GitHub.


📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License
Copyright (c) 2026 Shailesh Jiwana

Metadata

Release files for indiaid 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for indiaid 0.1.1
File Size Uploaded Provenance
indiaid-0.1.1.tar.gz 27.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for indiaid 0.1.1
File Interpreter ABI Platform
indiaid-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 52.8 kB

Release files / indiaid-0.1.1.tar.gz

Download URL indiaid-0.1.1.tar.gz
Size 27.3 kB
Tags Source
SHA-256 checksum
How to use checksums
96b5075651568192d3ef4ea643893a72a4ae34362ef6ca00102431962ef0c6e2
BLAKE2b-256 checksum
How to use checksums
556346a5d4dfbc1a19a5d6148fbfb5aa158f6e06a2b7b5934c4adabc4ebb288c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / indiaid-0.1.1-py3-none-any.whl

Download URL indiaid-0.1.1-py3-none-any.whl
Size 25.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b79777a34ffa3e9d30dfb034499552ce24feb3d526f065afb4325fa84d83e560
BLAKE2b-256 checksum
How to use checksums
5353c6b01598234e791556345dbb26ceac49b098b4688129c8a4596d5f11b997
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Security for indiaid 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page