Skip to content

thesmokinator/italian-tax-validators

Italian Tax Validators

A comprehensive Python library for validating and generating Italian fiscal identification documents:

  • Codice Fiscale (CF): Italian personal tax identification code
  • Partita IVA (P.IVA): Italian VAT registration number

Features

Codice Fiscale Validation

  • Format validation with omocodia handling
  • Check digit verification
  • Birthdate, age, and gender extraction
  • Birth place lookup (municipality name and province)
  • Minimum age verification (18+ by default)

Codice Fiscale Generation

  • Generate CF from personal data (name, surname, birthdate, gender, birth place)
  • Automatic check digit calculation
  • Municipality code lookup by name

Partita IVA Validation

  • Format and check digit verification (Italian Luhn algorithm)
  • Temporary VAT number detection (starts with 99)
  • Provincial office code extraction

Municipality Database

  • ~200 major Italian municipalities with cadastral codes
  • Foreign country codes
  • Search by name or code

Command-Line Interface

  • Validate CF and P.IVA from terminal
  • Generate CF from command line
  • Search municipality codes

Developer Friendly

  • Simple, intuitive API
  • Type hints for IDE support
  • Zero external dependencies
  • Python 3.9+

Installation

pip install italian-tax-validators

Quick Start

Validating Codice Fiscale

from italian_tax_validators import validate_codice_fiscale

# Basic validation
result = validate_codice_fiscale("RSSMRA85M01H501Q")
print(result.is_valid)      # True
print(result.birthdate)     # 1985-08-01
print(result.age)           # 40
print(result.gender)        # "M"
print(result.birth_place_name)     # "ROMA"
print(result.birth_place_province) # "RM"

# With age verification
result = validate_codice_fiscale("RSSMRA85M01H501Q", check_adult=True)
print(result.is_valid)  # True (person is 18+)

# With custom minimum age
result = validate_codice_fiscale("RSSMRA85M01H501Q", check_adult=True, minimum_age=21)

Generating Codice Fiscale

from datetime import date
from italian_tax_validators import generate_codice_fiscale

result = generate_codice_fiscale(
    surname="Rossi",
    name="Mario",
    birthdate=date(1985, 8, 1),
    gender="M",
    birth_place_code="H501"  # Rome
)
print(result.codice_fiscale)  # "RSSMRA85M01H501Q"

Validating Partita IVA

from italian_tax_validators import validate_partita_iva

result = validate_partita_iva("12345678903")
print(result.is_valid)       # True
print(result.province_code)  # "890"
print(result.is_temporary)   # False

# Flexible input handling
result = validate_partita_iva("IT 123 456 78903")  # Works with spaces and prefix

Municipality Lookup

from italian_tax_validators import (
    get_municipality_info,
    get_cadastral_code,
    search_municipality
)

# Get info from cadastral code
info = get_municipality_info("H501")
print(info)  # ("ROMA", "RM")

# Get cadastral code from name
code = get_cadastral_code("MILANO")
print(code)  # "F205"

# Search by partial name
results = search_municipality("ROMA")
# [("H501", "ROMA", "RM"), ("Z124", "ROMANIA", "EE")]

Command-Line Interface

The package includes a CLI tool for quick validations:

# Validate Codice Fiscale
italian-tax-validators validate-cf RSSMRA85M01H501Q

# Validate with age check
italian-tax-validators validate-cf RSSMRA85M01H501Q --check-adult --minimum-age 21

# Validate Partita IVA
italian-tax-validators validate-piva 12345678903

# Generate Codice Fiscale
italian-tax-validators generate-cf \
    --surname Rossi \
    --name Mario \
    --birthdate 1985-08-01 \
    --gender M \
    --birth-place-code H501

# Generate using municipality name
italian-tax-validators generate-cf \
    --surname Rossi \
    --name Mario \
    --birthdate 1985-08-01 \
    --gender M \
    --birth-place ROMA

# Search municipality codes
italian-tax-validators search-municipality MILAN

API Reference

See API.md for complete API documentation.

Quick Reference

Function Description
validate_codice_fiscale(value, check_adult, minimum_age) Validate a Codice Fiscale
validate_partita_iva(value) Validate a Partita IVA
generate_codice_fiscale(surname, name, birthdate, gender, birth_place_code) Generate a Codice Fiscale
get_municipality_info(code) Get municipality name and province from cadastral code
get_cadastral_code(name) Get cadastral code from municipality name
search_municipality(query) Search municipalities by partial name
is_foreign_country(code) Check if cadastral code is a foreign country

Codice Fiscale Structure

The Italian Codice Fiscale is a 16-character alphanumeric code:

RSSMRA85M01H501Q
├─ RSS    → Surname (first 3 consonants)
├─ MRA    → Name (first 3 consonants, or 1st+3rd+4th if 4+ consonants)
├─ 85     → Birth year (1985)
├─ M      → Birth month (M = August)
├─ 01     → Birth day (01), +40 for females (e.g., 41 = day 1, female)
├─ H501   → Birth place cadastral code (H501 = Rome)
└─ Q      → Check digit

Month Codes

Code Month Code Month
A January L July
B February M August
C March P September
D April R October
E May S November
H June T December

Omocodia

When multiple people share the same CF, digits can be replaced with letters:

  • L=0, M=1, N=2, P=3, Q=4, R=5, S=6, T=7, U=8, V=9

The library automatically handles omocodia substitutions during validation.

Partita IVA Structure

The Italian Partita IVA is an 11-digit number:

12345678903
├─ 1234567  → Company registration number (matricola)
├─ 890      → Provincial office code
└─ 3        → Check digit (Luhn algorithm variant)

Note: VAT numbers starting with 99 are temporary numbers.

Testing

# Run tests with pytest
pytest tests/

# Run with coverage
pytest tests/ --cov=italian_tax_validators

# Run with unittest
python -m unittest discover tests/

Examples

Django Integration

from django.core.exceptions import ValidationError
from italian_tax_validators import validate_codice_fiscale

def validate_cf(value):
    result = validate_codice_fiscale(value, check_adult=True)
    if not result.is_valid:
        raise ValidationError(f"Invalid CF: {result.error_code}")

class Person(models.Model):
    codice_fiscale = models.CharField(max_length=16, validators=[validate_cf])

Pydantic Integration

from pydantic import BaseModel, field_validator
from italian_tax_validators import validate_codice_fiscale

class PersonForm(BaseModel):
    codice_fiscale: str
    
    @field_validator('codice_fiscale')
    @classmethod
    def validate_cf(cls, v):
        result = validate_codice_fiscale(v, check_adult=True)
        if not result.is_valid:
            raise ValueError(f"Invalid Codice Fiscale: {result.error_code}")
        return result.formatted_value

FastAPI Integration

from fastapi import FastAPI, HTTPException
from italian_tax_validators import validate_codice_fiscale, validate_partita_iva

app = FastAPI()

@app.get("/validate/cf/{value}")
def validate_cf(value: str, check_adult: bool = False):
    result = validate_codice_fiscale(value, check_adult=check_adult)
    if not result.is_valid:
        raise HTTPException(400, detail=result.error_code)
    return {
        "codice_fiscale": result.formatted_value,
        "birthdate": str(result.birthdate),
        "age": result.age,
        "gender": result.gender,
        "birth_place": result.birth_place_name,
    }

License

MIT License - See LICENSE.md for details.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Changelog

v1.1.0

  • ✨ Added Codice Fiscale generation
  • ✨ Added gender extraction from CF
  • ✨ Added birth place lookup (municipality database)
  • ✨ Added temporary VAT number detection
  • ✨ Added provincial office code extraction from P.IVA
  • ✨ Added command-line interface (CLI)
  • 📚 Added comprehensive API documentation

v1.0.0

  • Initial release with CF and P.IVA validation

Resources

About

A comprehensive Python library for validating Italian fiscal identification documents

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages