Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 18 additions & 75 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,97 +1,40 @@
name: CI

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
group: ecosystem-${{ github.ref }}
cancel-in-progress: true

env:
PYTHONDONTWRITEBYTECODE: "1"

jobs:
contracts:
name: Contracts and generation
integration:
name: Independent SDK integration
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 20
env:
TMPDIR: /var/tmp
PYTHONDONTWRITEBYTECODE: "1"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e
with:
go-version: stable
cache: false
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0
with:
python-version: "3.14"
- run: python -m pip install -r tools/requirements.txt
- run: python tools/check_contracts.py
- run: python tools/generate.py --check

go:
name: Go ${{ matrix.go }}
runs-on: ubuntu-latest
timeout-minutes: 10
env:
TMPDIR: /var/tmp
strategy:
fail-fast: false
matrix:
go: ["1.26.x", stable]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
- name: Verify independent repositories and packages
run: |
stage=$(mktemp -d /var/tmp/peru-ecosystem.XXXXXXXX)
echo "ECOSYSTEM_REPORT=$stage" >> "$GITHUB_ENV"
python tools/check_ecosystem.py --output "$stage"
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
with:
go-version: ${{ matrix.go }}
cache: false
- run: go vet ./...
working-directory: sdk-go
- run: go test -race ./...
working-directory: sdk-go
- name: Compile without cgo
run: go test ./...
working-directory: sdk-go
env:
CGO_ENABLED: "0"

python:
name: Python ${{ matrix.python }} / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.14"]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: ${{ matrix.python }}
- run: python -m pip install ./sdk-python
- run: python -m unittest discover -s sdk-python/tests -v

packages:
name: Installed packages
runs-on: ubuntu-latest
timeout-minutes: 15
env:
TMPDIR: /var/tmp
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: stable
cache: false
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: "3.14"
- run: python tools/check_packages.py
name: ecosystem-${{ github.sha }}
path: ${{ env.ECOSYSTEM_REPORT }}
41 changes: 0 additions & 41 deletions .github/workflows/packages.yml

This file was deleted.

20 changes: 0 additions & 20 deletions .github/workflows/source-watch.yml

This file was deleted.

139 changes: 22 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,137 +1,42 @@
# Peru SDK

[![CI](https://github.com/DataScienceResearchPeru/peru-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/DataScienceResearchPeru/peru-sdk/actions/workflows/ci.yml)
Ecosistema MIT de SDKs nativos para servicios del Estado peruano. Cada lenguaje tiene implementación, instalación y releases independientes; se comparten contratos y casos de conformidad versionados.

SDKs nativos para integrar servicios del Estado peruano, con contratos comunes y pruebas de conformidad. Licencia MIT.
| Componente | Repositorio | Implementación en revisión |
| --- | --- | --- |
| Go | [peru-sdk-go](https://github.com/DataScienceResearchPeru/peru-sdk-go) | [PR #1](https://github.com/DataScienceResearchPeru/peru-sdk-go/pull/1) |
| Python | [peru-sdk-python](https://github.com/DataScienceResearchPeru/peru-sdk-python) | [PR #1](https://github.com/DataScienceResearchPeru/peru-sdk-python/pull/1) |
| Contratos y generación | [peru-sdk-models](https://github.com/DataScienceResearchPeru/peru-sdk-models) | [PR #1](https://github.com/DataScienceResearchPeru/peru-sdk-models/pull/1) |
| Corpus compartido | [peru-sdk-conformance](https://github.com/DataScienceResearchPeru/peru-sdk-conformance) | [PR #1](https://github.com/DataScienceResearchPeru/peru-sdk-conformance/pull/1) |

**Prueba mínima en desarrollo.** Go y Python ejecutan implementaciones propias: no requieren un motor compartido, PHP, un servidor intermedio ni un compilador adicional para instalar el paquete Python. No hay dependencias de terceros en el runtime de esta prueba.
Este repositorio contiene coordinación, documentación y un verificador de integración real entre commits públicos. El código de cada SDK se mantiene en su repositorio. Hasta fusionar las PRs, las implementaciones se pueden consumir por los commits completos registrados en ecosystem.lock.json.

## Alcance comprobado
## Qué funciona

| Capacidad | Go | Python | Evidencia |
|---|---|---|---|
| Modelos desde JSON Schema | Sí | Sí | Generación reproducible y validación del corpus |
| Consulta Integrada SUNAT | Cliente HTTP | Cliente HTTP | Solicitudes contra servidor local y respuestas sintéticas |
| OAuth2 `client_credentials` | Sí | Sí | Expiración, caché y renovación concurrente con servidor local |
| Consulta de identidad | Proveedor simulado | Proveedor simulado | Datos sintéticos; contrato provisional |
| Integración real con SUNAT o RENIEC | No verificada | No verificada | Sin credenciales ni consultas reales |
| Emisión UBL, firma y CDR | Pendiente | Pendiente | Fuera del alcance inicial |
Go y Python implementan Consulta Integrada SUNAT mediante HTTP y OAuth2 client_credentials, caché/renovación del token, importes decimales exactos y errores diferenciados. También ofrecen un proveedor de identidad sintético para comprobar la extensibilidad de la API.

Las pruebas no acreditan aceptación por una institución. El proveedor RENIEC no consulta personas ni representa un endpoint oficial. El nombre del paquete Python todavía no implica disponibilidad en PyPI.
Las pruebas HTTP se ejecutan contra servidores locales y respuestas sintéticas. No se ha verificado aún el servicio institucional con credenciales reales. El proveedor RENIEC no consulta ni verifica personas. La emisión UBL, firma y CDR permanecen fuera del alcance inicial.

## Probar sin credenciales
## Reproducir la integración

Requisitos: Go 1.26+ y Python 3.11+. Los scripts de generación necesitan ambos; cada SDK funciona independientemente.
Requisitos de desarrollo: Git, Go 1.26+ y Python 3.11+.

```bash
git clone https://github.com/DataScienceResearchPeru/peru-sdk.git
cd peru-sdk
python3 -m pip install ./sdk-python
python3 examples/offline.py
go -C sdk-go run ./examples/offline
```

Los ejemplos son locales y no realizan peticiones HTTP.

### Go

```go
service, err := reniec.NewMockIdentityService([]reniec.Identity{
{DNI: "00000001", GivenNames: "PERSONA", FirstSurname: "PRUEBA", SecondSurname: "SINTETICA"},
})
if err != nil {
return err
}
person, err := service.Lookup(ctx, reniec.IdentityQuery{DNI: "00000001"})
```

Imports: `github.com/DataScienceResearchPeru/peru-sdk/sdk-go/reniec` y `.../sunat`. Se puede consumir el módulo desde Git; todavía no hay versión estable. Fijar un commit para reproducibilidad.

### Python

```python
from peru_sdk.reniec import Identity, IdentityQuery, MockIdentityService

service = MockIdentityService([
Identity("00000001", "PERSONA", "PRUEBA", "SINTETICA"),
])
person = service.lookup(IdentityQuery("00000001"))
```

## Cliente SUNAT

El cliente implementa Consulta Integrada, no emisión de comprobantes. El RUC de la ruta es el de quien consulta; el RUC del cuerpo es el del emisor. La autenticación es `client_credentials`, no la Clave SOL ni el flujo de SIRE/GRE.

Ejemplo Python para una integración que ya tenga sus datos y credenciales autorizadas:

```python
from peru_sdk.sunat import OAuth2TokenProvider, ValidityClient, ValidityQuery

# client_id, client_secret y requester_ruc los proporciona tu aplicación.
tokens = OAuth2TokenProvider(client_id, client_secret)
client = ValidityClient(requester_ruc, tokens)
query = ValidityQuery(
issuer_ruc=issuer_ruc,
document_type="01",
series="F001",
number=123,
issued_on="2026-11-02",
amount="118.00",
)
# Esta llamada sí utiliza la red y los endpoints SUNAT de producción.
result = client.check(query)
```

En Go se usan `sunat.NewOAuth2TokenSource`, `sunat.NewValidityClient` y `client.Check(ctx, query)`. También hay proveedores de token estático. No se leen secretos automáticamente del entorno ni se escriben logs.

`document_status` conserva el código de SUNAT, incluso si es desconocido. El código `0` significa comprobante no informado según el manual: **no es un error de transporte ni una aceptación**. Un resultado tampoco determina deducibilidad tributaria.

Los importes públicos son strings decimales. Se transmiten como números JSON exactos, sin conversión a `float`. Las fechas públicas usan `YYYY-MM-DD` y se convierten a `dd/mm/yyyy` para esta operación.

Por defecto: timeout HTTP de 10 segundos, respuesta limitada a 1 MiB, TLS normal y sin redirecciones ni reintentos automáticos. HTTP sin TLS solo se permite en direcciones IP de loopback para pruebas. Go admite cancelación con `context.Context`; Python ofrece timeout por operación HTTP, sin cliente async en esta etapa. Se preservan códigos desconocidos y se ignoran campos adicionales de respuestas compatibles.

## Contratos y generación

```text
contracts/ Modelos públicos y procedencia de fuentes
conformance/ Casos sintéticos compartidos
tools/ Generador, comprobaciones y vigilancia de fuentes
sdk-go/ Implementación Go
sdk-python/ Implementación Python
examples/ Ejemplos locales
```

El generador soporta un subconjunto explícito de JSON Schema: objetos cerrados con campos obligatorios, strings, patrones compatibles con ambos lenguajes, fechas, enteros acotados y arrays de strings. Rechaza keywords no soportadas. No es un generador universal ni genera la lógica HTTP, fiscal o criptográfica.

```bash
python3 tools/generate.py
python3 tools/generate.py --check
```

La segunda orden falla si un modelo difiere del contrato. Los archivos generados se versionan y no se editan manualmente.

## Pruebas y CI/CD

```bash
go -C sdk-go test -race ./...
python3 -m unittest discover -s sdk-python/tests -v
python3 -m pip install -r tools/requirements.txt
python3 tools/check_contracts.py
python3 tools/check_packages.py
stage=$(mktemp -d /var/tmp/peru-ecosystem.XXXXXXXX)
python3 tools/check_ecosystem.py --output "$stage"
```

La suite Python requiere instalar primero `./sdk-python`. Las únicas dependencias adicionales de validación son de desarrollo. `check_packages.py` construye e instala una wheel en un destino aislado, ejecuta sus pruebas fuera del repositorio y compila un consumidor Go externo. Los temporales se crean en subdirectorios únicos de `/var/tmp`.

En cada push/PR, CI comprueba contratos, generación, ambos SDKs, condiciones de error y consumo del paquete instalado. Incluye Go mínimo/actual, race detector, Go sin cgo y Python 3.11/3.14 en Linux y Windows. Los tests HTTP solo acceden a loopback; las instalaciones de herramientas sí requieren acceso a sus registros.
El comando comprueba las referencias comunes, clona los SDKs por commit, crea artefactos aislados y ejecuta sus pruebas fuera de los checkouts. Además descarga el módulo Go desde GitHub, ejecuta un consumidor y su suite desde el módulo distribuido. Python se instala desde la wheel, usando los tests y el corpus contenidos en el sdist. No requiere repositorios hermanos ni credenciales SUNAT/RENIEC.

El workflow manual **Build preview distributions** produce wheel, sdist, código fuente y hashes como artefactos de GitHub. No publica automáticamente en PyPI ni crea versiones estables. Para Go, una futura versión del módulo ubicado en `sdk-go/` requiere una etiqueta como `sdk-go/v0.1.0`.
El resultado incluye report.json con versiones, commits, referencias y número de casos. Los artefactos se inspeccionan para evitar incluir implementaciones de otro SDK. La generación y sincronización son operaciones explícitas de desarrollo; no ocurren al instalar o usar los SDKs.

El workflow semanal **Official source watch** compara el hash del PDF oficial accesible: salida 0 sin cambios, 1 documento cambiado y 2 fuente inaccesible. Es una señal separada de las regresiones del SDK. No modifica reglas ni demuestra que el documento vigilado sea el más reciente.
## Actualizaciones y releases

## Fuentes, límites y próximos pasos
Cada SDK usa upstream.lock.json y conserva sus modelos y datos de prueba locales. Cambiar un contrato compartido no reescribe ni publica SDKs automáticamente. ecosystem.lock.json solo fija la combinación que verifica este hub.

La procedencia y las limitaciones están en [docs/compatibility.md](docs/compatibility.md); las decisiones en [docs/architecture.md](docs/architecture.md).
Go tiene un workflow Release manual que crea tags y releases después de comprobar los artefactos. Python tiene publicación PyPI mediante OIDC preparada, con validación de tag y versión. Para publicarlo falta configurar el Trusted Publisher en una cuenta PyPI del proyecto. No se ha publicado una versión estable ni un paquete PyPI en esta migración.

Próximos pasos: contrastar el cliente SUNAT con una consulta real autorizada; obtener el contrato y acceso correspondiente de RENIEC; ampliar pruebas de compatibilidad; incorporar una factura UBL acotada con verificación independiente de firma. La publicación estable y las credenciales de registros se configurarán después de comprobar esos hitos.
Orden de fusión: conformidad, modelos, SDKs y este hub. Los repositorios nuevos conservan merge commits para que los hashes fijados sigan siendo alcanzables. El módulo Go nuevo usa github.com/DataScienceResearchPeru/peru-sdk-go; las versiones previas del prototipo conservan su historia en Git.

Este proyecto no está afiliado a SUNAT ni a RENIEC.
Más detalles: [arquitectura](docs/architecture.md) y [publicación](docs/publishing.md). Los workflows usan runners de GitHub; no se ha modificado k3s ni añadido runners al host.
Loading
Loading