Python library for validating Italian Codice Fiscale and Partita IVA
Project description
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
- Agenzia delle Entrate - Official Italian Tax Agency
- Codice Fiscale Format - Wikipedia
- Partita IVA Format - Wikipedia
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file italian_tax_validators-1.1.0.tar.gz.
File metadata
- Download URL: italian_tax_validators-1.1.0.tar.gz
- Upload date:
- Size: 24.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c62c64f08a53389a32629d24a3192207952530132cac3f49c24cd6e7a9ddaf22
|
|
| MD5 |
71d255c35271903c001f77e855a42cf1
|
|
| BLAKE2b-256 |
6a383f377e8e8649d84cdb0024b1008289768998c2885c2d3de7b02b0193066b
|
Provenance
The following attestation bundles were made for italian_tax_validators-1.1.0.tar.gz:
Publisher:
publish-to-pypi.yml on thesmokinator/italian-tax-validators
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
italian_tax_validators-1.1.0.tar.gz -
Subject digest:
c62c64f08a53389a32629d24a3192207952530132cac3f49c24cd6e7a9ddaf22 - Sigstore transparency entry: 760410549
- Sigstore integration time:
-
Permalink:
thesmokinator/italian-tax-validators@6b0a51d60f17e43c14387ea5998741d2f8d0299e -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/thesmokinator
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@6b0a51d60f17e43c14387ea5998741d2f8d0299e -
Trigger Event:
push
-
Statement type:
File details
Details for the file italian_tax_validators-1.1.0-py3-none-any.whl.
File metadata
- Download URL: italian_tax_validators-1.1.0-py3-none-any.whl
- Upload date:
- Size: 19.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6f0275f0b9b2f7095a9c7f28ffda9f78be4026a9369a794627be28db53fc91c
|
|
| MD5 |
664dc5e2c585e5968e453712c32eca5e
|
|
| BLAKE2b-256 |
41e893ea8f8da6e322fd1031eb4e92d75add9dfeec32facedfd1772d7198a419
|
Provenance
The following attestation bundles were made for italian_tax_validators-1.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on thesmokinator/italian-tax-validators
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
italian_tax_validators-1.1.0-py3-none-any.whl -
Subject digest:
a6f0275f0b9b2f7095a9c7f28ffda9f78be4026a9369a794627be28db53fc91c - Sigstore transparency entry: 760410550
- Sigstore integration time:
-
Permalink:
thesmokinator/italian-tax-validators@6b0a51d60f17e43c14387ea5998741d2f8d0299e -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/thesmokinator
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@6b0a51d60f17e43c14387ea5998741d2f8d0299e -
Trigger Event:
push
-
Statement type: