# cpe-engine
Sistema de Emisión del Contribuyente - Facturación Electrónica Peruana
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/downloads/)
[](#testing)
[](#production-status)
> **🎉 Status: Production Ready** - Comprehensive testing, complete documentation, and verified greenter compatibility.
## Descripción
**cpe-engine** es una librería completa de Python para facturación electrónica peruana que integra con SUNAT. Es un port completo de la librería PHP Greenter, proporcionando funcionalidades end-to-end para generación de documentos, firma digital, y envío a SUNAT.
### Características
- ✅ **Facturas (01)** y **Boletas (03)** - Facturas y recibos
- ✅ **Notas de Crédito (07)** y **Notas de Débito (08)**
- ✅ **35 Catálogos SUNAT oficiales** - Todos los códigos validados contra fuentes oficiales
- ✅ **Validador opcional** - DocumentValidator separado del core (como Greenter/validator)
- ✅ **Mapeo dinámico de tributos** - XML correcto según tipo de operación (gravado, exonerado, exportación)
- ✅ **Arquitectura declarativa** - Compatible 100% con Greenter (no cálculos automáticos)
- ✅ Generación XML UBL 2.1 con templates Jinja2
- ✅ Firmas digitales usando SHA-256 (certificados X.509)
- ✅ Integración SOAP con servicios web SUNAT y procesamiento CDR
- ✅ Compresión ZIP para transmisión de documentos
- ✅ Soporte para ambientes TEST y PRODUCCIÓN
- ✅ API de alto nivel con funciones simples
- ✅ **100% compatible con Greenter** con validaciones adicionales opcionales
## 📚 Documentación de Referencia
**Para desarrolladores y contribuidores:**
- **[API_REFERENCE.md](./API_REFERENCE.md)** - Documentación completa de APIs con firmas exactas y tipos de datos
- **[TEST_PATTERNS.md](./TEST_PATTERNS.md)** - Patrones de testing verificados (usar exactamente estos patrones)
- **[ARCHITECTURE.md](./ARCHITECTURE.md)** - Arquitectura del sistema y principios de diseño
- **[CLAUDE.md](./CLAUDE.md)** - Guía específica para desarrollo con Claude Code
- **[CHANGELOG.md](./CHANGELOG.md)** - Registro de cambios, mejoras y correcciones por versión
> ⚠️ **Importante**: Lee estos archivos antes de contribuir para evitar errores comunes y patrones incorrectos.
## Instalación
```bash
pip install cpe-engine
```
## Uso Rápido
### 1. Configurar Credenciales
```python
from cpe_engine import SunatCredentials
# Para ambiente de pruebas
credentials = SunatCredentials(
ruc="20000000001",
usuario="20000000001MODDATOS",
password="moddatos",
certificado=certificado_pem_content, # Contenido PEM como string
es_test=True
)
# Para producción
credentials = SunatCredentials(
ruc="20123456789",
usuario="20123456789USUARIO1",
password="mi_password",
certificado="/path/to/certificado.pem", # O path al archivo
es_test=False
)
```
### 2. Enviar Factura
```python
from cpe_engine import create_invoice_data, send_invoice
# Datos de la empresa
company_data = {
'ruc': '20000000001',
'razon_social': 'MI EMPRESA S.A.C.',
'email': 'facturacion@miempresa.com',
'address': {
'ubigeo': '150101',
'departamento': 'Lima',
'provincia': 'Lima',
'distrito': 'Lima',
'direccion': 'Av. Principal 123'
}
}
# Datos del cliente
client_data = {
'tipo_doc': 6, # RUC
'num_doc': '20000000002',
'razon_social': 'CLIENTE EMPRESA S.A.C.'
}
# Items de la factura
items = [
{
'cod_item': 'PROD001',
'des_item': 'Producto de ejemplo',
'cantidad': 2,
'mto_valor_unitario': 100.00,
'unidad': 'NIU'
}
]
# Crear datos de factura
invoice_data = create_invoice_data(
serie='F001',
correlativo=123,
company_data=company_data,
client_data=client_data,
items=items
)
# Enviar a SUNAT
result = send_invoice(credentials, invoice_data)
if result.get('success'):
print(f"Factura enviada exitosamente: {result}")
else:
print(f"Error: {result['error']}")
```
### 3. Enviar Nota de Crédito
```python
from cpe_engine import create_note_data, send_credit_note
# Crear datos de nota de crédito
note_data = create_note_data(
serie='FC01',
correlativo=1,
tipo_nota='07', # Crédito
documento_afectado='F001-123',
motivo='Anulación de la operación',
company_data=company_data,
client_data=client_data,
items=items
)
# Enviar a SUNAT
result = send_credit_note(credentials, note_data)
```
## Catálogos SUNAT
La librería incluye **35 catálogos oficiales de SUNAT** descargados directamente de fuentes gubernamentales:
### Importación Directa
```python
# Importar catálogos directamente desde el paquete principal
from cpe_engine import (
CODIGOS_AFECTACION_IGV,
TIPOS_MONEDA,
UNIDADES_MEDIDA,
TIPOS_OPERACION,
MOTIVOS_NOTA_CREDITO,
MOTIVOS_NOTA_DEBITO,
validar_afectacion_igv,
validar_tipo_moneda
)
```
### Consultar Catálogos
```python
from cpe_engine import CODIGOS_AFECTACION_IGV, TIPOS_OPERACION
# Ver códigos de afectación IGV disponibles
print("Códigos de afectación IGV:")
for codigo, descripcion in CODIGOS_AFECTACION_IGV.items():
print(f" {codigo}: {descripcion}")
# 10: Gravado - Operación Onerosa
# 20: Exonerado - Operación Onerosa
# 30: Inafecto - Operación Onerosa
# 40: Exportación
# ... y más
# Ver tipos de operación
print("Tipos de operación:")
for codigo, descripcion in TIPOS_OPERACION.items():
print(f" {codigo}: {descripcion}")
# 0101: Venta interna
# 0200: Exportación de bienes
# ... y más
```
### Validación de Códigos
```python
from cpe_engine import validar_afectacion_igv, validar_tipo_moneda
# Validar antes de usar
if validar_afectacion_igv("40"):
print("Código 40 (exportación) es válido")
if validar_tipo_moneda("USD"):
print("USD es una moneda válida")
# La librería valida automáticamente al crear documentos
try:
item = SaleDetail(
cod_item="PROD001",
des_item="Producto",
cantidad=1,
mto_valor_unitario=100.00,
unidad="INVALID_UNIT", # ❌ Código inválido
tip_afe_igv="10"
)
except ValueError as e:
print(f"Error de validación: {e}")
# Error: Código de unidad de medida inválido: 'INVALID_UNIT'
```
### Catálogos Disponibles (35 Catálogos Oficiales)
| Catálogo | Descripción | Fuente Oficial |
|----------|-------------|----------------|
| `TIPOS_DOCUMENTO_IDENTIDAD` | Tipos de documento (DNI, RUC, etc.) | Catálogo 06 |
| `TIPOS_MONEDA` | Monedas (PEN, USD, EUR) | Catálogo 02 |
| `UNIDADES_MEDIDA` | Unidades de medida (NIU, ZZ, KGM, etc.) | Catálogo 03 |
| `CODIGOS_AFECTACION_IGV` | Códigos de afectación del IGV | Catálogo 07 |
| `MOTIVOS_NOTA_CREDITO` | Motivos de notas de crédito | Catálogo 09 |
| `MOTIVOS_NOTA_DEBITO` | Motivos de notas de débito | Catálogo 10 |
| `TIPOS_OPERACION` | Tipos de operación (venta interna, exportación, etc.) | Catálogo 17 |
| `TIPOS_CARGOS_DESCUENTOS` | Tipos de cargos y descuentos | Catálogo 53 |
| `TIPOS_DOCUMENTOS` | Tipos de comprobantes (01, 03, 07, etc.) | Catálogo 01 |
| **+26 catálogos adicionales** | Regímenes, percepciones, tributos, etc. | Catálogos 04-59 |
### Ejemplo: Factura de Exportación
```python
from cpe_engine import create_invoice_data, CODIGOS_AFECTACION_IGV, TIPOS_OPERACION
# Consultar códigos antes de usar
print("Código para exportación:", CODIGOS_AFECTACION_IGV["40"])
print("Operación de exportación:", TIPOS_OPERACION["0200"])
# Crear factura de exportación
items_exportacion = [
{
'cod_item': 'EXP001',
'des_item': 'Producto de exportación',
'cantidad': 10,
'mto_valor_unitario': 50.00,
'unidad': 'NIU',
'tip_afe_igv': '40' # Exportación (sin IGV)
}
]
invoice_data = create_invoice_data(
serie='F001',
correlativo=100,
company_data={...},
client_data={...},
items=items_exportacion
)
# El XML generado tendrá automáticamente:
# <cbc:TaxExemptionReasonCode>40</cbc:TaxExemptionReasonCode>
# <cbc:ID>9995</cbc:ID>
# <cbc:Name>EXP</cbc:Name>
# <cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>
```
### 4. Ejemplo Completo
```python
from cpe_engine import send_invoice, SunatCredentials
def main():
# Configurar credenciales (ejemplo con ambiente de prueba)
credenciales = SunatCredentials(
ruc="20000000001",
usuario="20000000001MODDATOS",
password="moddatos",
certificado="""-----BEGIN CERTIFICATE-----
...tu certificado PEM aquí...
-----END CERTIFICATE-----""",
es_test=True # Cambiar a False para producción
)
# Datos de la empresa
empresa_data = {
'ruc': '20000000001',
'razon_social': 'MI EMPRESA S.A.C.',
'nombre_comercial': 'Mi Empresa',
'email': 'facturacion@miempresa.com',
'address': {
'ubigeo': '150101',
'departamento': 'Lima',
'provincia': 'Lima',
'distrito': 'Lima',
'direccion': 'Av. Principal 123'
}
}
# Datos del cliente
cliente_data = {
'tipo_doc': 6, # 6=RUC, 1=DNI, 4=Carné extranjería, etc.
'num_doc': '20000000002',
'razon_social': 'CLIENTE EMPRESA S.A.C.'
}
# Productos/servicios
items = [
{
'cod_item': 'PROD001',
'des_item': 'Producto ejemplo',
'cantidad': 2,
'mto_valor_unitario': 100.00,
'unidad': 'NIU' # NIU=Unidad, ZZ=Servicio, etc.
},
{
'cod_item': 'SERV001',
'des_item': 'Servicio ejemplo',
'cantidad': 1,
'mto_valor_unitario': 50.00,
'unidad': 'ZZ'
}
]
# Enviar factura
resultado = send_invoice(
serie="F001",
correlativo=123,
empresa_data=empresa_data,
cliente_data=cliente_data,
items=items,
credenciales=credenciales
)
# Procesar resultado
if resultado.get('success'):
print("✅ Factura enviada exitosamente")
# Información del CDR (Constancia de Recepción)
if resultado.get('cdr'):
cdr = resultado['cdr']
print(f"Código SUNAT: {cdr.get('response_code')}")
print(f"Descripción: {cdr.get('description')}")
if cdr.get('notes'):
print(f"Observaciones: {cdr.get('notes')}")
print(f"XML generado guardado en: {resultado.get('xml_path')}")
else:
print("❌ Error al enviar factura:")
print(f"Error: {resultado.get('error')}")
if __name__ == "__main__":
main()
```
## API de Bajo Nivel
Para mayor control, puedes usar las clases directamente:
```python
from cpe_engine import Invoice, Company, Client, Address, SaleDetail
from cpe_engine import SignedXmlBuilder
from datetime import datetime
# Crear modelos
company = Company(
ruc="20000000001",
razon_social="MI EMPRESA S.A.C.",
# ...
)
invoice = Invoice(
serie="F001",
correlativo=123,
fecha_emision=datetime.now(),
# ...
)
# Generar XML, firmar y enviar
builder = SignedXmlBuilder()
result = builder.build_sign_and_send(invoice, credentials)
```
## Configuración
### Certificados Digitales
La librería soporta certificados en dos formatos:
```python
# Como contenido PEM (recomendado para BD)
certificado_string = """-----BEGIN CERTIFICATE-----
MIICljCCAX4CAQEwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAe...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5example...
-----END PRIVATE KEY-----"""
# Como path a archivo
certificado_path = "/path/to/certificado.pem"
```
### Ambientes SUNAT
```python
# TEST (Beta)
credentials = SunatCredentials(..., es_test=True)
# Endpoints: https://e-beta.sunat.gob.pe/...
# PRODUCCIÓN
credentials = SunatCredentials(..., es_test=False)
# Endpoints: https://e-factura.sunat.gob.pe/...
```
## Validación Opcional
La librería incluye un **DocumentValidator opcional** completamente separado del core (igual que Greenter/validator):
```python
from cpe_engine import DocumentValidator, Invoice, Company, Client
from datetime import datetime
# Crear validador (opcional)
validator = DocumentValidator()
# Crear documento (core siempre funciona sin validador)
invoice = Invoice(
serie="F001",
correlativo=123,
fecha_emision=datetime.now(),
# ... otros campos
)
# Validar opcionalmente usando catálogos oficiales SUNAT
errores = validator.validate(invoice)
if errores:
print(f"❌ {len(errores)} errores encontrados:")
for error in errores:
print(f" - {error.field}: {error.message}")
else:
print("✅ Documento válido según catálogos SUNAT")
# El documento se puede usar independientemente del validador
xml_content = invoice.build_xml() # Siempre funciona
```
### Ventajas del Validador Opcional
- ✅ **Separado del core** - Los documentos se crean sin validar (como Greenter)
- ✅ **35 catálogos oficiales** - Validación contra fuentes gubernamentales SUNAT
- ✅ **Mensajes descriptivos** - Errores con códigos válidos sugeridos
- ✅ **Totalmente opcional** - El core funciona independientemente
- ✅ **Compatible con Greenter** - Misma arquitectura que PHP Greenter/validator
## Testing
La librería incluye tests completos que **no requieren configuración adicional**:
```bash
# Ejecutar todos los tests (incluye credenciales oficiales de SUNAT)
python -m pytest -v
# Tests específicos
python -m pytest tests/test_models.py -v # Tests de modelos (declarativo como Greenter)
python -m pytest tests/test_validator.py -v # Tests del validador opcional
python -m pytest tests/test_api.py -v # Tests de API de alto nivel
python -m pytest tests/test_certificate.py -v # Tests de certificados
python -m pytest tests/test_xml_generation.py -v # Tests de XML y mapeo dinámico
```
### Funcionalidades Validadas en Tests
- ✅ **Arquitectura declarativa** - Sin cálculos automáticos (compatible con Greenter)
- ✅ **35 catálogos SUNAT** - Validación opcional usando códigos oficiales
- ✅ **Mapeo dinámico de tributos** - XML correcto según tipo de operación
- ✅ **Facturas de exportación** - Soporte completo para operaciones sin IGV
- ✅ **DocumentValidator** - Validación opcional separada del core
- ✅ **Compatibilidad total** - Mismos resultados que Greenter PHP
### Credenciales de Test
Los tests usan automáticamente las **credenciales oficiales de prueba de SUNAT**:
- RUC: `20000000001`
- Usuario: `20000000001MODDATOS`
- Password: `moddatos`
- Certificado: Hardcodeado (no requiere archivos externos)
### Personalizar Credenciales (Opcional)
Si necesitas usar tus propias credenciales para testing:
```bash
export SUNAT_TEST_RUC="tu_ruc"
export SUNAT_TEST_USER="tu_usuario"
export SUNAT_TEST_PASSWORD="tu_password"
export SUNAT_TEST_CERT="/path/to/tu/cert.pem"
export SUNAT_TEST_PRODUCTION="false" # true para producción
python -m pytest
```
## Desarrollo
```bash
# Instalar en modo desarrollo
pip install -e ".[dev]"
# Formatear código
black src/
isort src/
# Verificar tipos
mypy src/
```
## Arquitectura
La librería sigue el **mismo diseño declarativo que Greenter** con 4 fases:
1. **Fase 1 - Modelos**: `Invoice`, `Company`, `Client` declarativos (sin cálculos automáticos)
2. **Fase 2 - XML**: Generación UBL 2.1 con templates Jinja2 y mapeo dinámico de tributos
3. **Fase 3 - Firma**: Firma digital X.509 con SHA-256
4. **Fase 4 - SUNAT**: Envío SOAP autenticado y procesamiento CDR
### Componentes Adicionales (Opcionales)
- **DocumentValidator**: Validador opcional usando 35 catálogos oficiales SUNAT
- **Catálogos SUNAT**: 35 catálogos oficiales descargados de fuentes gubernamentales
- **API de Alto Nivel**: Funciones simplificadas para casos de uso comunes
### Compatibilidad con Greenter
- ✅ **Arquitectura declarativa**: Sin cálculos automáticos (como Greenter)
- ✅ **Modelos equivalentes**: Mismos campos y comportamiento
- ✅ **Templates XML**: Generación idéntica de UBL 2.1
- ✅ **Validador separado**: DocumentValidator opcional (como Greenter/validator)
- ✅ **Mapeo de tributos**: TributoFunction equivalente al PHP original
## Testing
La librería incluye una suite completa de tests que valida todas las funcionalidades críticas:
### Test Coverage
| Categoría | Archivos | Descripción |
|-----------|----------|-------------|
| **API Tests** | `test_api.py`, `test_models.py` | APIs de alto nivel y modelos core |
| **SUNAT Integration** | `test_sunat_integration.py` | Cliente SOAP, envío de documentos, CDR |
| **Digital Signature** | `test_digital_signature.py` | Gestión certificados y firma XML |
| **End-to-End** | `test_end_to_end.py` | Flujos completos desde creación hasta envío |
| **Error Handling** | `test_error_handling.py` | Manejo de errores de red y datos malformados |
| **XML Generation** | `test_xml_generation.py` | Generación de XML UBL 2.1 |
| **Certificate Management** | `test_certificate.py` | Carga y validación de certificados |
| **Validation** | `test_validator.py` | Validador opcional con catálogos SUNAT |
### Ejecutar Tests
```bash
# Tests completos
python -m pytest
# Tests específicos
python -m pytest tests/test_api.py -v
# Con coverage
python -m pytest --cov=cpe_engine
# Tests de integración con SUNAT (requiere credenciales)
export SUNAT_TEST_RUC="20000000001"
export SUNAT_TEST_USER="20000000001MODDATOS"
export SUNAT_TEST_PASSWORD="moddatos"
python -m pytest tests/test_sunat_integration.py -v
```
### Official SUNAT Test Credentials
Los tests incluyen credenciales oficiales de SUNAT (hardcodeadas) que funcionan sin configuración adicional:
- **RUC**: 20000000001
- **Usuario**: 20000000001MODDATOS
- **Password**: moddatos
- **Ambiente**: BETA (pruebas)
## Production Status
### ✅ Ready for Production Use
La librería ha sido probada extensivamente y está lista para uso en producción:
**Verified Components:**
- ✅ **Core Models**: Todos los modelos validados contra Greenter
- ✅ **XML Generation**: Templates UBL 2.1 probadas con SUNAT
- ✅ **Digital Signatures**: Firma SHA-256 funcionando correctamente
- ✅ **SUNAT Communication**: Cliente SOAP probado con servicios reales
- ✅ **Error Handling**: Manejo robusto de errores de red y datos
- ✅ **Data Validation**: 35 catálogos oficiales SUNAT integrados
**Performance & Security:**
- ✅ **Thread-Safe**: Soporte para procesamiento concurrente
- ✅ **Security**: SHA-256 signatures, secure certificate handling
- ✅ **Memory Efficient**: Procesamiento optimizado para documentos grandes
- ✅ **Error Recovery**: Reintentos automáticos para errores transitorios
**Production Deployment:**
- ✅ **Environment Support**: TEST y PRODUCTION endpoints
- ✅ **Certificate Management**: Soporte para certificados reales y prueba
- ✅ **Monitoring**: Logging detallado para auditoría
- ✅ **Scalability**: Arquitectura stateless para alta disponibilidad
## Licencia
MIT License. Ver [LICENSE](LICENSE) para más detalles.
## Contribuir
1. Fork el proyecto
2. Crear branch para feature (`git checkout -b feature/amazing-feature`)
3. Commit cambios (`git commit -m 'Add amazing feature'`)
4. Push al branch (`git push origin feature/amazing-feature`)
5. Abrir Pull Request
## Soporte
- 📖 [Documentación](https://github.com/tu-repo/cpe-engine)
- 🐛 [Issues](https://github.com/tu-repo/cpe-engine/issues)
- 💬 [Discusiones](https://github.com/tu-repo/cpe-engine/discussions)
---
**Nota**: Esta librería es un port de [Greenter](https://greenter.dev/) de PHP a Python. Agradecimientos al equipo original por su excelente trabajo.
Raw data
{
"_id": null,
"home_page": null,
"name": "cpe-engine",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11.6",
"maintainer_email": null,
"keywords": "peru, sunat, facturacion, electronica, ubl, invoice, xml",
"author": null,
"author_email": "Quanta Solutions <suma@bequanta.com>",
"download_url": "https://files.pythonhosted.org/packages/50/41/a020c9665ea49125193ac3bff3b26c3c473d258482865802ec63480ab2ef/cpe_engine-0.2.0.tar.gz",
"platform": null,
"description": "# cpe-engine\n\nSistema de Emisi\u00f3n del Contribuyente - Facturaci\u00f3n Electr\u00f3nica Peruana\n\n[](https://opensource.org/licenses/MIT)\n[](https://www.python.org/downloads/)\n[](#testing)\n[](#production-status)\n\n> **\ud83c\udf89 Status: Production Ready** - Comprehensive testing, complete documentation, and verified greenter compatibility.\n\n## Descripci\u00f3n\n\n**cpe-engine** es una librer\u00eda completa de Python para facturaci\u00f3n electr\u00f3nica peruana que integra con SUNAT. Es un port completo de la librer\u00eda PHP Greenter, proporcionando funcionalidades end-to-end para generaci\u00f3n de documentos, firma digital, y env\u00edo a SUNAT.\n\n### Caracter\u00edsticas\n\n- \u2705 **Facturas (01)** y **Boletas (03)** - Facturas y recibos\n- \u2705 **Notas de Cr\u00e9dito (07)** y **Notas de D\u00e9bito (08)**\n- \u2705 **35 Cat\u00e1logos SUNAT oficiales** - Todos los c\u00f3digos validados contra fuentes oficiales\n- \u2705 **Validador opcional** - DocumentValidator separado del core (como Greenter/validator)\n- \u2705 **Mapeo din\u00e1mico de tributos** - XML correcto seg\u00fan tipo de operaci\u00f3n (gravado, exonerado, exportaci\u00f3n)\n- \u2705 **Arquitectura declarativa** - Compatible 100% con Greenter (no c\u00e1lculos autom\u00e1ticos)\n- \u2705 Generaci\u00f3n XML UBL 2.1 con templates Jinja2\n- \u2705 Firmas digitales usando SHA-256 (certificados X.509)\n- \u2705 Integraci\u00f3n SOAP con servicios web SUNAT y procesamiento CDR\n- \u2705 Compresi\u00f3n ZIP para transmisi\u00f3n de documentos\n- \u2705 Soporte para ambientes TEST y PRODUCCI\u00d3N\n- \u2705 API de alto nivel con funciones simples\n- \u2705 **100% compatible con Greenter** con validaciones adicionales opcionales\n\n## \ud83d\udcda Documentaci\u00f3n de Referencia\n\n**Para desarrolladores y contribuidores:**\n\n- **[API_REFERENCE.md](./API_REFERENCE.md)** - Documentaci\u00f3n completa de APIs con firmas exactas y tipos de datos\n- **[TEST_PATTERNS.md](./TEST_PATTERNS.md)** - Patrones de testing verificados (usar exactamente estos patrones) \n- **[ARCHITECTURE.md](./ARCHITECTURE.md)** - Arquitectura del sistema y principios de dise\u00f1o\n- **[CLAUDE.md](./CLAUDE.md)** - Gu\u00eda espec\u00edfica para desarrollo con Claude Code\n- **[CHANGELOG.md](./CHANGELOG.md)** - Registro de cambios, mejoras y correcciones por versi\u00f3n\n\n> \u26a0\ufe0f **Importante**: Lee estos archivos antes de contribuir para evitar errores comunes y patrones incorrectos.\n\n## Instalaci\u00f3n\n\n```bash\npip install cpe-engine\n```\n\n## Uso R\u00e1pido\n\n### 1. Configurar Credenciales\n\n```python\nfrom cpe_engine import SunatCredentials\n\n# Para ambiente de pruebas\ncredentials = SunatCredentials(\n ruc=\"20000000001\",\n usuario=\"20000000001MODDATOS\",\n password=\"moddatos\",\n certificado=certificado_pem_content, # Contenido PEM como string\n es_test=True\n)\n\n# Para producci\u00f3n\ncredentials = SunatCredentials(\n ruc=\"20123456789\",\n usuario=\"20123456789USUARIO1\", \n password=\"mi_password\",\n certificado=\"/path/to/certificado.pem\", # O path al archivo\n es_test=False\n)\n```\n\n### 2. Enviar Factura\n\n```python\nfrom cpe_engine import create_invoice_data, send_invoice\n\n# Datos de la empresa\ncompany_data = {\n 'ruc': '20000000001',\n 'razon_social': 'MI EMPRESA S.A.C.',\n 'email': 'facturacion@miempresa.com',\n 'address': {\n 'ubigeo': '150101',\n 'departamento': 'Lima',\n 'provincia': 'Lima', \n 'distrito': 'Lima',\n 'direccion': 'Av. Principal 123'\n }\n}\n\n# Datos del cliente\nclient_data = {\n 'tipo_doc': 6, # RUC\n 'num_doc': '20000000002',\n 'razon_social': 'CLIENTE EMPRESA S.A.C.'\n}\n\n# Items de la factura\nitems = [\n {\n 'cod_item': 'PROD001',\n 'des_item': 'Producto de ejemplo',\n 'cantidad': 2,\n 'mto_valor_unitario': 100.00,\n 'unidad': 'NIU'\n }\n]\n\n# Crear datos de factura\ninvoice_data = create_invoice_data(\n serie='F001',\n correlativo=123,\n company_data=company_data,\n client_data=client_data,\n items=items\n)\n\n# Enviar a SUNAT\nresult = send_invoice(credentials, invoice_data)\n\nif result.get('success'):\n print(f\"Factura enviada exitosamente: {result}\")\nelse:\n print(f\"Error: {result['error']}\")\n```\n\n### 3. Enviar Nota de Cr\u00e9dito\n\n```python\nfrom cpe_engine import create_note_data, send_credit_note\n\n# Crear datos de nota de cr\u00e9dito\nnote_data = create_note_data(\n serie='FC01',\n correlativo=1,\n tipo_nota='07', # Cr\u00e9dito\n documento_afectado='F001-123',\n motivo='Anulaci\u00f3n de la operaci\u00f3n',\n company_data=company_data,\n client_data=client_data,\n items=items\n)\n\n# Enviar a SUNAT\nresult = send_credit_note(credentials, note_data)\n```\n\n## Cat\u00e1logos SUNAT\n\nLa librer\u00eda incluye **35 cat\u00e1logos oficiales de SUNAT** descargados directamente de fuentes gubernamentales:\n\n### Importaci\u00f3n Directa\n\n```python\n# Importar cat\u00e1logos directamente desde el paquete principal\nfrom cpe_engine import (\n CODIGOS_AFECTACION_IGV,\n TIPOS_MONEDA,\n UNIDADES_MEDIDA,\n TIPOS_OPERACION,\n MOTIVOS_NOTA_CREDITO,\n MOTIVOS_NOTA_DEBITO,\n validar_afectacion_igv,\n validar_tipo_moneda\n)\n```\n\n### Consultar Cat\u00e1logos\n\n```python\nfrom cpe_engine import CODIGOS_AFECTACION_IGV, TIPOS_OPERACION\n\n# Ver c\u00f3digos de afectaci\u00f3n IGV disponibles\nprint(\"C\u00f3digos de afectaci\u00f3n IGV:\")\nfor codigo, descripcion in CODIGOS_AFECTACION_IGV.items():\n print(f\" {codigo}: {descripcion}\")\n# 10: Gravado - Operaci\u00f3n Onerosa\n# 20: Exonerado - Operaci\u00f3n Onerosa \n# 30: Inafecto - Operaci\u00f3n Onerosa\n# 40: Exportaci\u00f3n\n# ... y m\u00e1s\n\n# Ver tipos de operaci\u00f3n\nprint(\"Tipos de operaci\u00f3n:\")\nfor codigo, descripcion in TIPOS_OPERACION.items():\n print(f\" {codigo}: {descripcion}\")\n# 0101: Venta interna\n# 0200: Exportaci\u00f3n de bienes\n# ... y m\u00e1s\n```\n\n### Validaci\u00f3n de C\u00f3digos\n\n```python\nfrom cpe_engine import validar_afectacion_igv, validar_tipo_moneda\n\n# Validar antes de usar\nif validar_afectacion_igv(\"40\"):\n print(\"C\u00f3digo 40 (exportaci\u00f3n) es v\u00e1lido\")\n\nif validar_tipo_moneda(\"USD\"):\n print(\"USD es una moneda v\u00e1lida\")\n\n# La librer\u00eda valida autom\u00e1ticamente al crear documentos\ntry:\n item = SaleDetail(\n cod_item=\"PROD001\",\n des_item=\"Producto\",\n cantidad=1,\n mto_valor_unitario=100.00,\n unidad=\"INVALID_UNIT\", # \u274c C\u00f3digo inv\u00e1lido\n tip_afe_igv=\"10\"\n )\nexcept ValueError as e:\n print(f\"Error de validaci\u00f3n: {e}\")\n # Error: C\u00f3digo de unidad de medida inv\u00e1lido: 'INVALID_UNIT'\n```\n\n### Cat\u00e1logos Disponibles (35 Cat\u00e1logos Oficiales)\n\n| Cat\u00e1logo | Descripci\u00f3n | Fuente Oficial |\n|----------|-------------|----------------|\n| `TIPOS_DOCUMENTO_IDENTIDAD` | Tipos de documento (DNI, RUC, etc.) | Cat\u00e1logo 06 |\n| `TIPOS_MONEDA` | Monedas (PEN, USD, EUR) | Cat\u00e1logo 02 |\n| `UNIDADES_MEDIDA` | Unidades de medida (NIU, ZZ, KGM, etc.) | Cat\u00e1logo 03 |\n| `CODIGOS_AFECTACION_IGV` | C\u00f3digos de afectaci\u00f3n del IGV | Cat\u00e1logo 07 |\n| `MOTIVOS_NOTA_CREDITO` | Motivos de notas de cr\u00e9dito | Cat\u00e1logo 09 |\n| `MOTIVOS_NOTA_DEBITO` | Motivos de notas de d\u00e9bito | Cat\u00e1logo 10 |\n| `TIPOS_OPERACION` | Tipos de operaci\u00f3n (venta interna, exportaci\u00f3n, etc.) | Cat\u00e1logo 17 |\n| `TIPOS_CARGOS_DESCUENTOS` | Tipos de cargos y descuentos | Cat\u00e1logo 53 |\n| `TIPOS_DOCUMENTOS` | Tipos de comprobantes (01, 03, 07, etc.) | Cat\u00e1logo 01 |\n| **+26 cat\u00e1logos adicionales** | Reg\u00edmenes, percepciones, tributos, etc. | Cat\u00e1logos 04-59 |\n\n### Ejemplo: Factura de Exportaci\u00f3n\n\n```python\nfrom cpe_engine import create_invoice_data, CODIGOS_AFECTACION_IGV, TIPOS_OPERACION\n\n# Consultar c\u00f3digos antes de usar\nprint(\"C\u00f3digo para exportaci\u00f3n:\", CODIGOS_AFECTACION_IGV[\"40\"])\nprint(\"Operaci\u00f3n de exportaci\u00f3n:\", TIPOS_OPERACION[\"0200\"])\n\n# Crear factura de exportaci\u00f3n\nitems_exportacion = [\n {\n 'cod_item': 'EXP001',\n 'des_item': 'Producto de exportaci\u00f3n',\n 'cantidad': 10,\n 'mto_valor_unitario': 50.00,\n 'unidad': 'NIU',\n 'tip_afe_igv': '40' # Exportaci\u00f3n (sin IGV)\n }\n]\n\ninvoice_data = create_invoice_data(\n serie='F001',\n correlativo=100,\n company_data={...},\n client_data={...},\n items=items_exportacion\n)\n\n# El XML generado tendr\u00e1 autom\u00e1ticamente:\n# <cbc:TaxExemptionReasonCode>40</cbc:TaxExemptionReasonCode>\n# <cbc:ID>9995</cbc:ID>\n# <cbc:Name>EXP</cbc:Name> \n# <cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>\n```\n\n### 4. Ejemplo Completo\n\n```python\nfrom cpe_engine import send_invoice, SunatCredentials\n\ndef main():\n # Configurar credenciales (ejemplo con ambiente de prueba)\n credenciales = SunatCredentials(\n ruc=\"20000000001\",\n usuario=\"20000000001MODDATOS\",\n password=\"moddatos\", \n certificado=\"\"\"-----BEGIN CERTIFICATE-----\n ...tu certificado PEM aqu\u00ed...\n -----END CERTIFICATE-----\"\"\",\n es_test=True # Cambiar a False para producci\u00f3n\n )\n \n # Datos de la empresa\n empresa_data = {\n 'ruc': '20000000001',\n 'razon_social': 'MI EMPRESA S.A.C.',\n 'nombre_comercial': 'Mi Empresa',\n 'email': 'facturacion@miempresa.com',\n 'address': {\n 'ubigeo': '150101',\n 'departamento': 'Lima',\n 'provincia': 'Lima',\n 'distrito': 'Lima',\n 'direccion': 'Av. Principal 123'\n }\n }\n \n # Datos del cliente\n cliente_data = {\n 'tipo_doc': 6, # 6=RUC, 1=DNI, 4=Carn\u00e9 extranjer\u00eda, etc.\n 'num_doc': '20000000002',\n 'razon_social': 'CLIENTE EMPRESA S.A.C.'\n }\n \n # Productos/servicios\n items = [\n {\n 'cod_item': 'PROD001',\n 'des_item': 'Producto ejemplo',\n 'cantidad': 2,\n 'mto_valor_unitario': 100.00,\n 'unidad': 'NIU' # NIU=Unidad, ZZ=Servicio, etc.\n },\n {\n 'cod_item': 'SERV001', \n 'des_item': 'Servicio ejemplo',\n 'cantidad': 1,\n 'mto_valor_unitario': 50.00,\n 'unidad': 'ZZ'\n }\n ]\n \n # Enviar factura\n resultado = send_invoice(\n serie=\"F001\",\n correlativo=123,\n empresa_data=empresa_data,\n cliente_data=cliente_data, \n items=items,\n credenciales=credenciales\n )\n \n # Procesar resultado\n if resultado.get('success'):\n print(\"\u2705 Factura enviada exitosamente\")\n \n # Informaci\u00f3n del CDR (Constancia de Recepci\u00f3n)\n if resultado.get('cdr'):\n cdr = resultado['cdr']\n print(f\"C\u00f3digo SUNAT: {cdr.get('response_code')}\")\n print(f\"Descripci\u00f3n: {cdr.get('description')}\")\n \n if cdr.get('notes'):\n print(f\"Observaciones: {cdr.get('notes')}\")\n \n print(f\"XML generado guardado en: {resultado.get('xml_path')}\")\n else:\n print(\"\u274c Error al enviar factura:\")\n print(f\"Error: {resultado.get('error')}\")\n\nif __name__ == \"__main__\":\n main()\n```\n\n## API de Bajo Nivel\n\nPara mayor control, puedes usar las clases directamente:\n\n```python\nfrom cpe_engine import Invoice, Company, Client, Address, SaleDetail\nfrom cpe_engine import SignedXmlBuilder\nfrom datetime import datetime\n\n# Crear modelos\ncompany = Company(\n ruc=\"20000000001\",\n razon_social=\"MI EMPRESA S.A.C.\",\n # ...\n)\n\ninvoice = Invoice(\n serie=\"F001\",\n correlativo=123,\n fecha_emision=datetime.now(),\n # ...\n)\n\n# Generar XML, firmar y enviar\nbuilder = SignedXmlBuilder()\nresult = builder.build_sign_and_send(invoice, credentials)\n```\n\n## Configuraci\u00f3n\n\n### Certificados Digitales\n\nLa librer\u00eda soporta certificados en dos formatos:\n\n```python\n# Como contenido PEM (recomendado para BD)\ncertificado_string = \"\"\"-----BEGIN CERTIFICATE-----\nMIICljCCAX4CAQEwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAe...\n-----END CERTIFICATE-----\n-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5example...\n-----END PRIVATE KEY-----\"\"\"\n\n# Como path a archivo\ncertificado_path = \"/path/to/certificado.pem\"\n```\n\n### Ambientes SUNAT\n\n```python\n# TEST (Beta)\ncredentials = SunatCredentials(..., es_test=True)\n# Endpoints: https://e-beta.sunat.gob.pe/...\n\n# PRODUCCI\u00d3N \ncredentials = SunatCredentials(..., es_test=False)\n# Endpoints: https://e-factura.sunat.gob.pe/...\n```\n\n## Validaci\u00f3n Opcional\n\nLa librer\u00eda incluye un **DocumentValidator opcional** completamente separado del core (igual que Greenter/validator):\n\n```python\nfrom cpe_engine import DocumentValidator, Invoice, Company, Client\nfrom datetime import datetime\n\n# Crear validador (opcional)\nvalidator = DocumentValidator()\n\n# Crear documento (core siempre funciona sin validador)\ninvoice = Invoice(\n serie=\"F001\",\n correlativo=123,\n fecha_emision=datetime.now(),\n # ... otros campos\n)\n\n# Validar opcionalmente usando cat\u00e1logos oficiales SUNAT\nerrores = validator.validate(invoice)\n\nif errores:\n print(f\"\u274c {len(errores)} errores encontrados:\")\n for error in errores:\n print(f\" - {error.field}: {error.message}\")\nelse:\n print(\"\u2705 Documento v\u00e1lido seg\u00fan cat\u00e1logos SUNAT\")\n\n# El documento se puede usar independientemente del validador\nxml_content = invoice.build_xml() # Siempre funciona\n```\n\n### Ventajas del Validador Opcional\n\n- \u2705 **Separado del core** - Los documentos se crean sin validar (como Greenter)\n- \u2705 **35 cat\u00e1logos oficiales** - Validaci\u00f3n contra fuentes gubernamentales SUNAT\n- \u2705 **Mensajes descriptivos** - Errores con c\u00f3digos v\u00e1lidos sugeridos\n- \u2705 **Totalmente opcional** - El core funciona independientemente\n- \u2705 **Compatible con Greenter** - Misma arquitectura que PHP Greenter/validator\n\n## Testing\n\nLa librer\u00eda incluye tests completos que **no requieren configuraci\u00f3n adicional**:\n\n```bash\n# Ejecutar todos los tests (incluye credenciales oficiales de SUNAT)\npython -m pytest -v\n\n# Tests espec\u00edficos \npython -m pytest tests/test_models.py -v # Tests de modelos (declarativo como Greenter)\npython -m pytest tests/test_validator.py -v # Tests del validador opcional\npython -m pytest tests/test_api.py -v # Tests de API de alto nivel\npython -m pytest tests/test_certificate.py -v # Tests de certificados\npython -m pytest tests/test_xml_generation.py -v # Tests de XML y mapeo din\u00e1mico\n```\n\n### Funcionalidades Validadas en Tests\n\n- \u2705 **Arquitectura declarativa** - Sin c\u00e1lculos autom\u00e1ticos (compatible con Greenter)\n- \u2705 **35 cat\u00e1logos SUNAT** - Validaci\u00f3n opcional usando c\u00f3digos oficiales\n- \u2705 **Mapeo din\u00e1mico de tributos** - XML correcto seg\u00fan tipo de operaci\u00f3n \n- \u2705 **Facturas de exportaci\u00f3n** - Soporte completo para operaciones sin IGV\n- \u2705 **DocumentValidator** - Validaci\u00f3n opcional separada del core\n- \u2705 **Compatibilidad total** - Mismos resultados que Greenter PHP\n\n### Credenciales de Test\n\nLos tests usan autom\u00e1ticamente las **credenciales oficiales de prueba de SUNAT**:\n- RUC: `20000000001`\n- Usuario: `20000000001MODDATOS` \n- Password: `moddatos`\n- Certificado: Hardcodeado (no requiere archivos externos)\n\n### Personalizar Credenciales (Opcional)\n\nSi necesitas usar tus propias credenciales para testing:\n\n```bash\nexport SUNAT_TEST_RUC=\"tu_ruc\"\nexport SUNAT_TEST_USER=\"tu_usuario\"\nexport SUNAT_TEST_PASSWORD=\"tu_password\"\nexport SUNAT_TEST_CERT=\"/path/to/tu/cert.pem\"\nexport SUNAT_TEST_PRODUCTION=\"false\" # true para producci\u00f3n\n\npython -m pytest\n```\n\n## Desarrollo\n\n```bash\n# Instalar en modo desarrollo\npip install -e \".[dev]\"\n\n# Formatear c\u00f3digo\nblack src/\nisort src/\n\n# Verificar tipos\nmypy src/\n```\n\n## Arquitectura\n\nLa librer\u00eda sigue el **mismo dise\u00f1o declarativo que Greenter** con 4 fases:\n\n1. **Fase 1 - Modelos**: `Invoice`, `Company`, `Client` declarativos (sin c\u00e1lculos autom\u00e1ticos)\n2. **Fase 2 - XML**: Generaci\u00f3n UBL 2.1 con templates Jinja2 y mapeo din\u00e1mico de tributos\n3. **Fase 3 - Firma**: Firma digital X.509 con SHA-256\n4. **Fase 4 - SUNAT**: Env\u00edo SOAP autenticado y procesamiento CDR\n\n### Componentes Adicionales (Opcionales)\n\n- **DocumentValidator**: Validador opcional usando 35 cat\u00e1logos oficiales SUNAT\n- **Cat\u00e1logos SUNAT**: 35 cat\u00e1logos oficiales descargados de fuentes gubernamentales\n- **API de Alto Nivel**: Funciones simplificadas para casos de uso comunes\n\n### Compatibilidad con Greenter\n\n- \u2705 **Arquitectura declarativa**: Sin c\u00e1lculos autom\u00e1ticos (como Greenter)\n- \u2705 **Modelos equivalentes**: Mismos campos y comportamiento\n- \u2705 **Templates XML**: Generaci\u00f3n id\u00e9ntica de UBL 2.1\n- \u2705 **Validador separado**: DocumentValidator opcional (como Greenter/validator)\n- \u2705 **Mapeo de tributos**: TributoFunction equivalente al PHP original\n\n## Testing\n\nLa librer\u00eda incluye una suite completa de tests que valida todas las funcionalidades cr\u00edticas:\n\n### Test Coverage\n\n| Categor\u00eda | Archivos | Descripci\u00f3n |\n|-----------|----------|-------------|\n| **API Tests** | `test_api.py`, `test_models.py` | APIs de alto nivel y modelos core |\n| **SUNAT Integration** | `test_sunat_integration.py` | Cliente SOAP, env\u00edo de documentos, CDR |\n| **Digital Signature** | `test_digital_signature.py` | Gesti\u00f3n certificados y firma XML |\n| **End-to-End** | `test_end_to_end.py` | Flujos completos desde creaci\u00f3n hasta env\u00edo |\n| **Error Handling** | `test_error_handling.py` | Manejo de errores de red y datos malformados |\n| **XML Generation** | `test_xml_generation.py` | Generaci\u00f3n de XML UBL 2.1 |\n| **Certificate Management** | `test_certificate.py` | Carga y validaci\u00f3n de certificados |\n| **Validation** | `test_validator.py` | Validador opcional con cat\u00e1logos SUNAT |\n\n### Ejecutar Tests\n\n```bash\n# Tests completos\npython -m pytest\n\n# Tests espec\u00edficos\npython -m pytest tests/test_api.py -v\n\n# Con coverage\npython -m pytest --cov=cpe_engine\n\n# Tests de integraci\u00f3n con SUNAT (requiere credenciales)\nexport SUNAT_TEST_RUC=\"20000000001\"\nexport SUNAT_TEST_USER=\"20000000001MODDATOS\"\nexport SUNAT_TEST_PASSWORD=\"moddatos\"\npython -m pytest tests/test_sunat_integration.py -v\n```\n\n### Official SUNAT Test Credentials\n\nLos tests incluyen credenciales oficiales de SUNAT (hardcodeadas) que funcionan sin configuraci\u00f3n adicional:\n\n- **RUC**: 20000000001\n- **Usuario**: 20000000001MODDATOS \n- **Password**: moddatos\n- **Ambiente**: BETA (pruebas)\n\n## Production Status\n\n### \u2705 Ready for Production Use\n\nLa librer\u00eda ha sido probada extensivamente y est\u00e1 lista para uso en producci\u00f3n:\n\n**Verified Components:**\n- \u2705 **Core Models**: Todos los modelos validados contra Greenter\n- \u2705 **XML Generation**: Templates UBL 2.1 probadas con SUNAT\n- \u2705 **Digital Signatures**: Firma SHA-256 funcionando correctamente\n- \u2705 **SUNAT Communication**: Cliente SOAP probado con servicios reales\n- \u2705 **Error Handling**: Manejo robusto de errores de red y datos\n- \u2705 **Data Validation**: 35 cat\u00e1logos oficiales SUNAT integrados\n\n**Performance & Security:**\n- \u2705 **Thread-Safe**: Soporte para procesamiento concurrente\n- \u2705 **Security**: SHA-256 signatures, secure certificate handling\n- \u2705 **Memory Efficient**: Procesamiento optimizado para documentos grandes\n- \u2705 **Error Recovery**: Reintentos autom\u00e1ticos para errores transitorios\n\n**Production Deployment:**\n- \u2705 **Environment Support**: TEST y PRODUCTION endpoints\n- \u2705 **Certificate Management**: Soporte para certificados reales y prueba \n- \u2705 **Monitoring**: Logging detallado para auditor\u00eda\n- \u2705 **Scalability**: Arquitectura stateless para alta disponibilidad\n\n## Licencia\n\nMIT License. Ver [LICENSE](LICENSE) para m\u00e1s detalles.\n\n## Contribuir\n\n1. Fork el proyecto\n2. Crear branch para feature (`git checkout -b feature/amazing-feature`)\n3. Commit cambios (`git commit -m 'Add amazing feature'`)\n4. Push al branch (`git push origin feature/amazing-feature`)\n5. Abrir Pull Request\n\n## Soporte\n\n- \ud83d\udcd6 [Documentaci\u00f3n](https://github.com/tu-repo/cpe-engine)\n- \ud83d\udc1b [Issues](https://github.com/tu-repo/cpe-engine/issues)\n- \ud83d\udcac [Discusiones](https://github.com/tu-repo/cpe-engine/discussions)\n\n---\n\n**Nota**: Esta librer\u00eda es un port de [Greenter](https://greenter.dev/) de PHP a Python. Agradecimientos al equipo original por su excelente trabajo.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Sistema de Emisi\u00f3n del Contribuyente - Facturaci\u00f3n Electr\u00f3nica Peruana",
"version": "0.2.0",
"project_urls": null,
"split_keywords": [
"peru",
" sunat",
" facturacion",
" electronica",
" ubl",
" invoice",
" xml"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "181b8b157eb41f6ef094f0bc32c46d9e7a603e521e6bad5ba03c8edb962a0ccc",
"md5": "247ad1887366ba794f382328e53978b1",
"sha256": "ec801fdd68804e9cf91392213c574e24ace58d3a03a4f54c89718c4ec12a093c"
},
"downloads": -1,
"filename": "cpe_engine-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "247ad1887366ba794f382328e53978b1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11.6",
"size": 113472,
"upload_time": "2025-08-29T03:19:48",
"upload_time_iso_8601": "2025-08-29T03:19:48.358299Z",
"url": "https://files.pythonhosted.org/packages/18/1b/8b157eb41f6ef094f0bc32c46d9e7a603e521e6bad5ba03c8edb962a0ccc/cpe_engine-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5041a020c9665ea49125193ac3bff3b26c3c473d258482865802ec63480ab2ef",
"md5": "12fe01203c527c3122f9afb9fc846a1a",
"sha256": "4c8d9f18876def80ab7eb7d4fce35540dedbad3fefa37094ebb0c62fc8ed70d6"
},
"downloads": -1,
"filename": "cpe_engine-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "12fe01203c527c3122f9afb9fc846a1a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11.6",
"size": 121176,
"upload_time": "2025-08-29T03:19:50",
"upload_time_iso_8601": "2025-08-29T03:19:50.824942Z",
"url": "https://files.pythonhosted.org/packages/50/41/a020c9665ea49125193ac3bff3b26c3c473d258482865802ec63480ab2ef/cpe_engine-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-29 03:19:50",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "cpe-engine"
}