Metadata-Version: 2.4
Name: catalogmx
Version: 0.3.0
Summary: Comprehensive Mexican data validators and official catalogs library - 170K+ records
Author-email: Luis Fernando Barrera <luisfernando@informind.com>
Maintainer-email: Luis Fernando Barrera <luisfernando@informind.com>
License: BSD-2-Clause
Project-URL: Homepage, https://github.com/openbancor/catalogmx
Project-URL: Documentation, https://catalogmx.readthedocs.io
Project-URL: Repository, https://github.com/openbancor/catalogmx.git
Project-URL: Issues, https://github.com/openbancor/catalogmx/issues
Project-URL: Changelog, https://github.com/openbancor/catalogmx/blob/main/CHANGELOG.rst
Keywords: mexico,rfc,curp,clabe,nss,sat,cfdi,inegi,sepomex,banxico,validators,catalogs,postal-codes,geographic-data
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: AUTHORS.rst
Requires-Dist: unidecode>=1.4.0
Requires-Dist: click>=8.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.4.0; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.7.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx>=7.0.0; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints>=1.25.0; extra == "docs"
Provides-Extra: all
Requires-Dist: catalogmx[dev,docs]; extra == "all"
Dynamic: license-file

# catalogmx

**Comprehensive Mexican Data Validators and Official Catalogs Library**

A complete multi-language library (Python 3.10+ | TypeScript 5.0+) for validating Mexican identifiers and accessing official catalogs from SAT, Banxico, INEGI, SEPOMEX, and other government agencies.

[![Python Version](https://img.shields.io/pypi/pyversions/catalogmx)](https://pypi.org/project/catalogmx/)
[![PyPI Version](https://img.shields.io/pypi/v/catalogmx)](https://pypi.org/project/catalogmx/)
[![NPM Version](https://img.shields.io/npm/v/catalogmx)](https://www.npmjs.com/package/catalogmx)
[![Coverage](https://img.shields.io/badge/coverage-93.78%25-brightgreen)](https://github.com/openbancor/catalogmx)
[![Tests](https://img.shields.io/badge/tests-926%20passing-brightgreen)](https://github.com/openbancor/catalogmx)
[![License](https://img.shields.io/badge/license-BSD--2--Clause-blue.svg)](LICENSE)

**Languages**: [English](#) | [Español](README.es.md)

---

## Overview

**catalogmx** provides production-ready tools for Mexican data validation and official catalog access:

- **4 Validators**: RFC, CURP, CLABE, NSS with complete algorithms
- **58 Official Catalogs**: SAT (CFDI 4.0, Comercio Exterior, Carta Porte, Nómina), INEGI, SEPOMEX, Banxico, IFT, Mexico National
- **170,505+ Records**: Complete databases including 157K postal codes, 2.4K municipalities, 10K+ localities with GPS
- **Economic Indicators**: Salarios Mínimos, UMA, UDI with historical data (2010-2025)
- **Traffic Regulations**: Hoy No Circula CDMX with hologram exemptions and contingency rules
- **SQLite Hybrid Architecture**: 22-59% size reduction for large catalogs with FTS5 full-text search
- **Multi-language Support**: Python and TypeScript with identical APIs
- **Type-Safe**: Full type hints (PEP 604) and TypeScript declarations
- **Production Ready**: Comprehensive test coverage (1,147 tests: 926 Python + 221 TypeScript = 93.78% coverage), fully documented, and actively maintained

---

## Quick Start

### Python

```bash
# Using pip
pip install catalogmx

# Using uv (10-100x faster)
uv pip install catalogmx
```

```python
from catalogmx.validators import rfc, curp
from catalogmx.catalogs.sepomex import CodigosPostales
from catalogmx.catalogs.inegi import LocalidadesCatalog

# Validate and generate RFC
is_valid = rfc.validate_rfc("XAXX010101000")
rfc_code = rfc.generate_rfc_persona_fisica(
    nombre="Juan",
    apellido_paterno="Pérez", 
    apellido_materno="López",
    fecha_nacimiento="1990-01-15"
)  # Returns: "PELJ900115XXX"

# Generate and validate CURP
curp_code = curp.generate_curp(
    nombre="Juan",
    apellido_paterno="Pérez",
    apellido_materno="García", 
    fecha_nacimiento="1990-05-15",
    sexo="H",
    estado="Jalisco"
)  # Returns: "PEGJ900515HJCRRN09"

# Search postal codes
postal_codes = CodigosPostales.get_by_cp("06700")
print(postal_codes[0]['asentamiento'])  # "Roma Norte"

# Geographic search with GPS coordinates
localities = LocalidadesCatalog.get_by_coordinates(
    lat=19.4326, lon=-99.1332, radio_km=10
)
```

### TypeScript

```bash
npm install catalogmx
```

```typescript
import { validateRFC, validateCURP } from 'catalogmx';
import { RegimenFiscalCatalog } from 'catalogmx/catalogs';

const isValid = validateRFC('XAXX010101000');
const regimen = RegimenFiscalCatalog.getRegimen('605');
```

---

## Testing & Quality

- ✅ **926 Tests** with **93.78% coverage**
- ✅ **50+ modules at 100%** coverage
- ✅ Comprehensive validator tests (CLABE, NSS, RFC, CURP)
- ✅ All critical functionality fully tested
- ✅ CI/CD with GitHub Actions
- ✅ [View Coverage Reports](docs/testing-coverage.md)

---

## Features

### Validators

**RFC (Registro Federal de Contribuyentes)**
- Persona Física (13 characters) and Persona Moral (12 characters)
- Homoclave calculation using Módulo 11 algorithm
- Check digit validation
- 170+ cacophonic word replacement
- Foreign resident support

**CURP (Clave Única de Registro de Población)**
- 18-character validation with complete RENAPO algorithm
- **CURP generation** from name, birth date, gender, and state
- Check digit calculation and verification (position 18)
- State code validation (32 Mexican states)
- 70+ inconvenient words handling (Anexo 2)
- Birth date, gender, and state extraction

**CLABE (Clave Bancaria Estandarizada)**
- 18-digit bank account validation
- Modulo 10 check digit algorithm
- Bank, branch, and account number extraction
- Integration with Banxico bank catalog (110 institutions)

**NSS (Número de Seguridad Social)**
- 11-digit IMSS number validation
- Modified Luhn algorithm check digit
- Subdelegation, year, and serial extraction

### Official Catalogs

**SAT (Tax Administration Service)** - 31 catalogs
- **CFDI 4.0 Core**: 11 catalogs including tax regimes, CFDI uses, payment methods, product/service keys (52K+ with SQLite hybrid), unit codes
- **Comercio Exterior 2.0**: 8 catalogs including Incoterms, countries, currencies, customs procedures, tax ID registry
- **Carta Porte 3.0**: 7 catalogs including airports, seaports, highways, dangerous materials (UN codes), packaging types
- **Nómina 1.2**: 7 catalogs including payroll types, contracts, work shifts, IMSS risk levels
- **Tax Calculators**: IEPS, ISR (historical tables 2002-2025), IVA, withholdings, local taxes

**INEGI (Geographic Data)** - 4 catalogs
- **Complete municipalities**: 2,478 records with population data (Census 2020)
- **Localities with GPS**: 10,635 localities (1,000+ inhabitants) with SQLite hybrid architecture
- **States**: Complete 32 Mexican states with geographic codes
- Geographic search by coordinates with radius filtering
- Urban/rural classification

**SEPOMEX (Postal Service)** - 2 catalogs
- **Complete postal codes**: 157,252 records (largest catalog)
- **Simplified postal codes**: Fast lookup version
- All 32 Mexican states (100% coverage)
- Search by postal code, municipality, or state

**Banxico (Central Bank)** - 3 catalogs
- **Financial institutions**: 110 banks with SPEI participation
- **Currencies**: ISO 4217 codes with exchange rate availability
- Bank code validation and lookup

**IFT (Telecommunications)** - 2 catalogs
- **LADA codes**: Mexican area codes with geographic coverage
- **Mobile operators**: Telecom providers and network identifiers

**Mexico National Catalogs** - 6 catalogs
- **License Plates (Placas)**: 35 official vehicle plate formats by NOM-001-SCT-2-2016 (particular, federal, diplomatic, military, emergency services, etc.)
- **Minimum Wages (Salarios Mínimos)**: Historical minimum wages 2010-2025 (daily, monthly, annual)
- **UMA**: Unidad de Medida y Actualización 2017-2025 (reference unit for fines/taxes)
- **UDI (Banxico)**: Unidades de Inversión with historical values (inflation-indexed investment units)
- **Hoy No Circula CDMX**: Traffic restrictions program for Mexico City and Metro Area
- **Economic Indicators**: Historical data for wages, UMA, and UDI values

---

## Statistics

| Catalog Category | Records | Implementation | Size |
|-----------------|---------|----------------|------|
| SEPOMEX Postal Codes | 157,252 | JSON | 41 MB |
| SAT Clave Prod/Serv | 52,063 | **SQLite hybrid** | 13.4 MB (was 18 MB JSON, **26% reduction**) |
| INEGI Localities | 10,635 | **SQLite hybrid** | 2.0 MB (was 4.9 MB JSON, **59% reduction**) |
| INEGI Municipalities | 2,478 | JSON | 0.98 MB |
| SAT CFDI 4.0 | ~30 catalogs | JSON | <1 MB |
| SAT Comercio Exterior | 8 catalogs | JSON | <1 MB |
| SAT Carta Porte | 7 catalogs | JSON | <2 MB |
| SAT Nómina | 7 catalogs | JSON | <1 MB |
| SAT Tax Calculators | 5 calculators | JSON | <1 MB |
| Banxico | 3 catalogs | JSON | 41 KB |
| Banxico UDI | 24 values | JSON | ~2 KB |
| IFT Telecom | 2 catalogs | JSON | 38 KB |
| Mexico National | 6 catalogs | JSON | ~15 KB |
| **TOTAL** | **170,505+ records** | **56 JSON + 2 SQLite** | **~82 MB total** |

### Test Coverage (TypeScript)

| Metric | Coverage | Status |
|--------|----------|--------|
| **Functional Tests** | **220/220 passing** | ✅ **100%** |
| Code Statements | 59.83% | ⚠️ Below 80% threshold |
| Branches | 37.48% | ⚠️ Below 80% threshold |
| Lines | 61.56% | ⚠️ Below 80% threshold |
| Functions | 45.69% | ⚠️ Below 80% threshold |

*All functional tests pass. Lower code coverage is due to many catalog methods and validators not yet having exhaustive test cases. Core functionality is fully tested.*

---

## Installation

### Python

#### From PyPI (Recommended)

```bash
pip install catalogmx
```

#### From Source

```bash
git clone https://github.com/openbancor/catalogmx.git
cd catalogmx/packages/python
pip install -e .
```

**Requirements**:
- Python 3.10 or higher
- unidecode (for RFC generation)
- click (for CLI)

### TypeScript/JavaScript

#### NPM

```bash
npm install catalogmx
```

#### Yarn

```bash
yarn add catalogmx
```

**Requirements**:
- Node.js 16 or higher
- TypeScript 5.0+ (optional, type definitions included)

---

## Documentation

### Getting Started
- [Installation Guide](docs/installation.rst)
- [Quick Start Guide](docs/quickstart.rst)
- [API Reference](docs/api/)

### Guides
- [Architecture Guide](docs/guides/architecture.md)
- [Developer's Guide](docs/guides/developers-guide.md)
- [Catalog Updates](docs/guides/catalog-updates.md)
- [CP-Locality Linking](docs/guides/cp-locality-linking.md)

### Catalogs
- [Catalog Overview](docs/catalogs/overview.md)
- [SEPOMEX Documentation](docs/catalogs/sepomex.md)
- [INEGI Documentation](docs/catalogs/inegi.md)
- [SAT Documentation](docs/catalogs/sat.md)

### Project
- [Roadmap](docs/roadmap.md)
- [Changelog](CHANGELOG.rst)
- [Catalog Changelog](docs/changelog-catalogs.md)
- [Contributing](CONTRIBUTING.rst)

---

## Usage Examples

### Address Validation

```python
from catalogmx.catalogs.sepomex import CodigosPostales
from catalogmx.catalogs.inegi import MunicipiosCatalog

def validate_address(postal_code, municipality_name):
    """Validate Mexican address"""
    
    if not CodigosPostales.is_valid(postal_code):
        return False, "Invalid postal code"
    
    cp_info = CodigosPostales.get_by_cp(postal_code)[0]
    
    if municipality_name.lower() not in cp_info['municipio'].lower():
        return False, f"Postal code {postal_code} does not belong to {municipality_name}"
    
    return True, cp_info
```

### Geographic Analysis

```python
from catalogmx.catalogs.inegi import LocalidadesCatalog

# Find localities near a coordinate
nearby = LocalidadesCatalog.get_by_coordinates(
    lat=19.4326,      # Mexico City
    lon=-99.1332,
    radio_km=50
)

for locality in nearby[:5]:
    print(f"{locality['nom_localidad']}: {locality['distancia_km']} km")
    print(f"  Population: {locality['poblacion_total']:,}")
```

### CFDI Validation

```python
from catalogmx.validators import rfc
from catalogmx.catalogs.sat.cfdi_4 import (
    RegimenFiscalCatalog,
    UsoCFDICatalog,
    FormaPagoCatalog
)

def validate_cfdi_data(rfc_code, tax_regime, cfdi_use, payment_method):
    """Validate CFDI invoice data"""
    
    errors = []
    
    if not rfc.validate_rfc(rfc_code):
        errors.append("Invalid RFC")
    
    if not RegimenFiscalCatalog.is_valid(tax_regime):
        errors.append(f"Invalid tax regime: {tax_regime}")
    
    if not UsoCFDICatalog.is_valid(cfdi_use):
        errors.append(f"Invalid CFDI use: {cfdi_use}")
    
    if not FormaPagoCatalog.is_valid(payment_method):
        errors.append(f"Invalid payment method: {payment_method}")
    
    return len(errors) == 0, errors
```

---

## Roadmap

### Version 0.3.0 (Current - November 2025)

**Completed**:
- ✅ Complete SEPOMEX postal codes (157,252 records)
- ✅ Complete INEGI municipalities (2,478 records)
- ✅ INEGI localities with GPS coordinates (10,635 records)
- ✅ **SQLite hybrid architecture** for large catalogs (22-59% size reduction)
- ✅ FTS5 full-text search with Spanish tokenization
- ✅ IFT telecommunications catalogs (LADA codes, mobile operators)
- ✅ Banxico complete financial catalogs (banks, currencies)
- ✅ SAT tax calculators (IEPS, ISR historical 2002-2025, IVA, withholdings)
- ✅ Geographic search by coordinates with radius filtering
- ✅ Population and housing data (Census 2020)
- ✅ Urban/rural classification
- ✅ **Comprehensive test coverage** (337 tests: 221 TypeScript + 116 Python, all passing)
- ✅ Bilingual documentation

### Version 0.4.0 (Planned - Q1 2025)

**Planned**:
- Geocoding integration (add GPS to postal codes)
- Pre-computed CP-Locality correspondence table
- REST API server examples
- GraphQL API examples
- Improve code coverage to 80%+ threshold
- Python test suite and coverage reporting

### Version 0.5.0 (Future - Q2-Q3 2025)

**Planned**:
- Additional validators (ISAN, license plates, MRZ)
- IMSS (social security) extended catalogs
- TIGIE (customs tariff) catalog
- Historical catalog versions with temporal queries
- ML-based address normalization
- WebAssembly compilation for validators
- Browser-compatible SQLite with sql.js

**Full Roadmap**: See [docs/roadmap.md](docs/roadmap.md) for detailed roadmap by catalog and implementation strategy.

---

## SQLite Hybrid Architecture

For catalogs with >10,000 records, we provide **SQLite hybrid implementation** with automatic backend selection:

**Benefits** (Proven Results):
- **22-59% smaller file size** (measured on production catalogs)
- **10-100x faster queries** with indexed lookups
- **FTS5 full-text search** with Spanish text tokenization
- **Memory efficient**: Query without loading entire dataset into memory
- **Automatic selection**: Falls back to JSON if SQLite unavailable

**Current Implementation** (v0.3.0):

| Catalog | JSON Size | SQLite Size | Size Reduction | Features |
|---------|-----------|-------------|----------------|----------|
| **Clave Prod/Serv** | 18 MB | 13.4 MB | **26%** | FTS5 Spanish search |
| **INEGI Localities** | 4.9 MB | 2.0 MB | **59%** | GPS coordinates indexed |

**Technical Details**:
- `better-sqlite3` for Node.js (native performance)
- `sql.js` for WebAssembly browser support (planned)
- FTS5 tokenization with Spanish stop words
- Lazy loading with static caching
- Seamless fallback to JSON for compatibility

---

## Catalog Update Strategy

### Update Frequencies

| Catalog | Frequency | Source | Auto-update |
|---------|-----------|--------|-------------|
| SEPOMEX | Monthly | correosdemexico.gob.mx | Planned (v0.4.0) |
| INEGI | Annually | inegi.org.mx | Manual |
| SAT CFDI | Quarterly | sat.gob.mx | Planned (v0.4.0) |
| Banxico | Quarterly | banxico.org.mx | Planned (v0.4.0) |

### Current Process

```bash
# Check for updates
python scripts/check_catalog_updates.py

# Download and process
python scripts/fetch_sat_catalogs.py
python scripts/process_sepomex_file.py
python scripts/process_inegi_municipios.py
```

**Automated updates planned for v0.4.0**

---

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.rst](CONTRIBUTING.rst) for guidelines.

### Development Setup

```bash
git clone https://github.com/openbancor/catalogmx.git
cd catalogmx

# Python
cd packages/python
pip install -e ".[dev]"
pytest

# TypeScript
cd packages/typescript
npm install
npm test
```

### Adding New Catalogs

See [Developer's Guide](docs/guides/developers-guide.md) for detailed instructions on:
- Creating catalog JSON files
- Implementing catalog classes
- Writing tests
- Updating documentation

---

## Project Structure

```
catalogmx/
├── README.md                   # This file
├── LICENSE                     # BSD 2-Clause
├── CONTRIBUTING.rst            # Contribution guidelines
├── CHANGELOG.rst               # Project changelog
│
├── docs/                       # Documentation
│   ├── guides/                 # Technical guides
│   ├── catalogs/              # Catalog documentation
│   ├── api/                    # API reference
│   ├── roadmap.md             # Detailed roadmap
│   └── releases/              # Release notes
│
├── packages/
│   ├── python/                # Python implementation
│   │   ├── catalogmx/
│   │   ├── tests/
│   │   ├── pyproject.toml     # Modern Python config
│   │   └── requirements.txt
│   │
│   ├── typescript/            # TypeScript implementation
│   │   ├── src/
│   │   ├── tests/
│   │   └── package.json
│   │
│   └── shared-data/           # Catalog JSON data
│       ├── sepomex/          # 157K postal codes
│       ├── inegi/            # Municipalities & localities
│       ├── sat/              # Tax catalogs
│       └── banxico/          # Banking data
│
└── scripts/                   # Processing scripts
    ├── process_sepomex_file.py
    ├── process_inegi_municipios.py
    └── process_inegi_localidades.py
```

---

## License

BSD 2-Clause License. See [LICENSE](LICENSE) for details.

---

## Acknowledgments

### Official Data Sources

- **SAT** - Servicio de Administración Tributaria
- **INEGI** - Instituto Nacional de Estadística y Geografía
- **SEPOMEX** - Servicio Postal Mexicano
- **Banxico** - Banco de México
- **RENAPO** - Registro Nacional de Población

### Technology Stack

- Python 3.10+ with modern type hints (PEP 604)
- TypeScript 5.0+
- Zero external dependencies (validators)
- Lazy loading architecture
- JSON-based catalog storage

---

## Support

- **Documentation**: [docs/](docs/)
- **Issues**: [GitHub Issues](https://github.com/openbancor/catalogmx/issues)
- **Email**: luisfernando@informind.com

---

## Project Statistics

```
Package Size:     ~82 MB (all catalogs + SQLite)
Total Catalogs:   58 (56 JSON + 2 SQLite)
Total Records:    170,505+
Test Coverage:    337/337 tests passing (221 TypeScript + 116 Python)
Code Coverage:    ~60% statements, ~37% branches
Population:       126,014,024 (100% coverage)
GPS Localities:   10,635
Municipalities:   2,478
Postal Codes:     157,252
Banks:            110
IFT Operators:    Multiple telecom providers
Tax Calculators:  5 (IEPS, ISR, IVA, Withholdings, Local)
Economic Data:    UMA (2017-2025), UDI (1995-2025), Salarios Mínimos (2010-2025)
Traffic Rules:    Hoy No Circula CDMX (complete program)
License Plates:   35 official formats (NOM-001-SCT-2-2016)
```

### Package Size Breakdown

```
Directory         Size    Description
-----------------------------------------
sepomex/          41 MB   Postal codes (complete)
sat/              19 MB   Tax catalogs (all modules)
sqlite/           16 MB   Hybrid databases (2 files)
inegi/            5.8 MB  Geographic data
banxico/          41 KB   Financial institutions
ift/              38 KB   Telecommunications
misc/             5.5 KB  Supporting data
```

---

**catalogmx** v0.3.0 | November 2025 | Made for the Mexican developer community

