amortizacion-engine
Motor puro y stateless de tablas de amortización en Python: 13 modalidades
de crédito con precisión decimal.Decimal exacta, API mínima (simulate()),
cero dependencias duras y resultados serializables (to_dict() / to_json()).
Tabla de contenidos
- Instalacion
- Quickstart
- Las 13 modalidades
- Comparativa rapida de sistemas
- Ejemplos por modalidad
- Principios de diseno
- API publica
- Desarrollo
- Contributing
- FAQ
- Licencia
Caracteristicas clave
- Precision decimal exacta: todo monto y tasa se calcula con
decimal.Decimal, nuncafloat. El cuadre de capital está garantizado:sum(principal_component) == principaly saldo final en0.00. - 13 modalidades de credito: interes simple, compuesto, sistema frances, aleman, americano, con enganche, pagos extraordinarios, sin intereses, tasa variable, pagos personalizados, periodo de gracia, cargos/seguros e indexado a inflacion.
- API minima: una sola funcion de entrada,
simulate(), con conversion de tipos amigable y semantica request XOR kwargs. - Cero dependencias duras: solo libreria estandar (extra opcional
pydantic). - Stateless y determinista: funciones puras y
dataclasses(frozen=True); las fechas siempre llegan como parametro, nuncadatetime.now()implicito. - Serializable:
to_dict()yto_json()en todos los resultados, sin dependencias externas (Decimal comostrpara roundtrip JSON exacto). - Extensible por Strategy: cada modalidad es una estrategia de
AmortizationStrategy; anadir la modalidad 14 no rompe nada existente. - Errores propios: jerarquia
FinancialEngineErrorcon subclases accionables; validacion agresiva, nuncaassert.
Instalacion
Requiere Python >= 3.10 y no tiene dependencias duras (solo libreria
estandar; el extra pydantic es opcional).
pip install amortizacion-engine
Con soporte opcional de Pydantic (validacion adicional de los modelos):
pip install "amortizacion-engine[pydantic]"
Quickstart
Genera una tabla de amortizacion en menos de 10 lineas: un credito frances de 15 000 a 24 % anual en 12 meses.
from financial_engine import simulate, AmortizationMode
result = simulate(
mode=AmortizationMode.FRENCH_FIXED_PAYMENT,
principal="15000.00",
annual_rate="0.24",
periods=12,
start_date="2026-08-09",
)
print(result.summary.total_interest)
for row in result.schedule:
print(row.period, row.payment, row.principal_component, row.interest_component, row.balance)
Salida (interes total del credito y las 12 filas del calendario):
2020.68
1 1418.39 1118.39 300.00 13881.61
2 1418.39 1140.76 277.63 12740.85
3 1418.39 1163.57 254.82 11577.28
4 1418.39 1186.84 231.55 10390.44
5 1418.39 1210.58 207.81 9179.86
6 1418.39 1234.79 183.60 7945.07
7 1418.39 1259.49 158.90 6685.58
8 1418.39 1284.68 133.71 5400.90
9 1418.39 1310.37 108.02 4090.53
10 1418.39 1336.58 81.81 2753.95
11 1418.39 1363.31 55.08 1390.64
12 1418.39 1390.64 27.75 0.00
Cada fila del calendario es una PaymentRow inmutable con
payment, principal_component, interest_component, fees_component,
balance y extra_payment; el resumen (summary) agrega los totales.
Las 13 modalidades
Cada modalidad corresponde a un miembro del enum AmortizationMode y se
implementa como una estrategia del patron Strategy.
Modalidad (AmortizationMode) |
Sistema | Descripcion |
|---|---|---|
SIMPLE_INTEREST |
Interes simple | Interes simple sobre saldo insoluto, sin capitalizacion. |
COMPOUND_INTEREST |
Interes compuesto | Interes compuesto con capitalizacion periodica configurable (mensual, quincenal o anual). |
FRENCH_FIXED_PAYMENT |
Sistema frances | Cuota fija, amortizacion creciente, interes decreciente. |
GERMAN_CONSTANT_AMORTIZATION |
Sistema aleman | Amortizacion de capital constante, cuota decreciente. |
AMERICAN_BULLET |
Sistema americano | Solo interes en cada periodo, capital al vencimiento. |
DOWN_PAYMENT_ADJUSTED |
Con enganche/anticipo | Igual que frances/aleman pero descontando un enganche inicial del principal. |
EXTRA_PAYMENTS |
Pagos extraordinarios | Abonos a capital con dos submodalidades: reducir plazo o reducir cuota. |
ZERO_INTEREST |
Sin intereses | Tasa 0 %, divide el principal entre el numero de periodos. |
VARIABLE_RATE |
Tasa variable | Acepta un calendario de tasas distintas por periodo o rango de periodos. |
CUSTOM_SCHEDULE |
Pagos personalizados | El usuario define manualmente el monto de cada pago. |
GRACE_PERIOD_DEFERRED |
Periodo de gracia | N periodos iniciales sin pago de capital (solo interes, o totalmente diferido con capitalizacion). |
FEES_AND_INSURANCE |
Con cargos/seguro | Igual que frances/aleman sumando cargos periodicos fijos o porcentuales a cada cuota. |
INDEXED_INFLATION |
Indexado a inflacion | Ajusta el saldo o la cuota periodo a periodo segun un indice externo (UDI, INPC, etc.). |
Comparativa rapida de sistemas
Los cuatro sistemas clasicos frente a frente. La base comun es un credito de
15 000 a 24 % anual en 12 meses; excepciones: AMERICAN_BULLET usa
10 000 a 12 % (como en los ejemplos de modalidad) y SIMPLE_INTEREST usa
1 200 a 12 % (tambien como en sus ejemplos), para mantener la coherencia con
el resto del documento.
| Sistema | Cuota inicial | Interes total | Total pagado |
|---|---|---|---|
Frances (FRENCH_FIXED_PAYMENT) |
1418.39 | 2020.68 | 17020.68 |
Aleman (GERMAN_CONSTANT_AMORTIZATION) |
1550.00 (1250 + 300) | 1950.00 | 16950.00 |
Americano (AMERICAN_BULLET, 10 000 a 12 %) |
100.00 | 1200.00 | 11200.00 |
Interes simple (SIMPLE_INTEREST, 1 200 a 12 %) |
112.00 | 78.00 | 1278.00 |
Ejemplos por modalidad
Todos los ejemplos usan la API publica simulate() con los mismos datos de
partida (start_date="2026-08-09") y los valores comentados son la salida
real verificada contra la libreria.
1. SIMPLE_INTEREST — interes simple
r = simulate(
mode=AmortizationMode.SIMPLE_INTEREST,
principal="1200.00", annual_rate="0.12", periods=12,
start_date="2026-08-09",
)
print(r.summary.total_interest) # 78.00
print(r.summary.total_paid) # 1278.00
print(r.schedule[0].interest_component) # 12.00 (decrece hasta 1.00)
2. COMPOUND_INTEREST — interes compuesto (zero-coupon)
r = simulate(
mode=AmortizationMode.COMPOUND_INTEREST,
principal="1000.00", annual_rate="0.12", periods=12,
start_date="2026-08-09",
)
print(r.summary.total_interest) # 126.84
print(r.schedule[-1].payment) # 1126.84 (capital + interes al vencimiento)
3. FRENCH_FIXED_PAYMENT — sistema frances
r = simulate(
mode=AmortizationMode.FRENCH_FIXED_PAYMENT,
principal="15000.00", annual_rate="0.24", periods=12,
start_date="2026-08-09",
)
print(r.schedule[0].payment) # 1418.39 (cuota fija)
print(r.summary.total_interest) # 2020.68
print(r.summary.total_paid) # 17020.68
4. GERMAN_CONSTANT_AMORTIZATION — sistema aleman
r = simulate(
mode=AmortizationMode.GERMAN_CONSTANT_AMORTIZATION,
principal="15000.00", annual_rate="0.24", periods=12,
start_date="2026-08-09",
)
print(r.schedule[0].interest_component) # 300.00 (decrece linealmente)
print(r.schedule[-1].interest_component) # 25.00
print(r.summary.total_interest) # 1950.00
print(r.summary.total_paid) # 16950.00
5. AMERICAN_BULLET — sistema americano
r = simulate(
mode=AmortizationMode.AMERICAN_BULLET,
principal="10000.00", annual_rate="0.12", periods=12,
start_date="2026-08-09",
)
print(r.schedule[0].payment) # 100.00 (solo interes)
print(r.schedule[-1].payment) # 10100.00 (capital + interes final)
print(r.summary.total_interest) # 1200.00
print(r.summary.total_paid) # 11200.00
6. DOWN_PAYMENT_ADJUSTED — con enganche
El enganche se paga fuera de la tabla; el motor amortiza con sistema frances
el capital efectivo principal - down_payment.
r = simulate(
mode=AmortizationMode.DOWN_PAYMENT_ADJUSTED,
principal="15000.00", annual_rate="0.24", periods=12,
down_payment="3000.00", start_date="2026-08-09",
)
print(r.schedule[0].principal_component) # 894.72
print(r.schedule[0].balance) # 11105.28
print(r.summary.total_interest) # 1616.64
print(sum(x.principal_component for x in r.schedule)) # 12000.00 (cuadre exacto)
7. EXTRA_PAYMENTS — pagos extraordinarios
Dos submodalidades via extra_payment_behavior. Abono de 2 000 en el
periodo 6 sobre el credito frances de 15 000:
r = simulate(
mode=AmortizationMode.EXTRA_PAYMENTS,
principal="15000.00", annual_rate="0.24", periods=12,
extra_payments=[{"period": 6, "amount": "2000.00"}],
extra_payment_behavior="reduce_term", # misma cuota, plazo mas corto
start_date="2026-08-09",
)
print(r.schedule[5].extra_payment) # 2000.00
print(r.schedule[5].balance) # 5945.07
print(r.summary.periods_count) # 11 (el plazo se acorto)
print(r.summary.total_interest) # 1784.76
Y con reduce_payment (mismo plazo, cuota menor):
r = simulate(
mode=AmortizationMode.EXTRA_PAYMENTS,
principal="15000.00", annual_rate="0.24", periods=12,
extra_payments=[{"period": 6, "amount": "2000.00"}],
extra_payment_behavior="reduce_payment",
start_date="2026-08-09",
)
print(r.schedule[0].principal_component) # 950.46
print(r.summary.total_interest) # 2005.54
print(r.summary.total_paid) # 17005.54
8. ZERO_INTEREST — sin intereses
La tasa anual debe ser exactamente 0.00; cada cuota es principal / n.
r = simulate(
mode=AmortizationMode.ZERO_INTEREST,
principal="6000.00", annual_rate="0.00", periods=12,
start_date="2026-08-09",
)
print(r.schedule[0].payment) # 500.00
print(r.summary.total_interest) # 0.00
print(r.summary.total_paid) # 6000.00
9. VARIABLE_RATE — tasa variable
Base de amortizacion constante; rate_schedule cambia la tasa del periodo 7
en adelante al 30 % anual (la tasa vigente se expone en
row.extra_data["annual_rate"]):
r = simulate(
mode=AmortizationMode.VARIABLE_RATE,
principal="15000.00", annual_rate="0.24", periods=12,
rate_schedule=[{"period_from": 7, "period_to": None, "annual_rate": "0.30"}],
start_date="2026-08-09",
)
print(r.schedule[0].interest_component) # 300.00 (24 % anual)
print(r.schedule[6].interest_component) # 187.50 (30 % anual)
print(r.summary.total_interest) # 2081.25
print(r.summary.total_paid) # 17081.25
10. CUSTOM_SCHEDULE — pagos personalizados
El usuario define el monto de cada pago (custom_payments); el motor
distribuye cada pago entre interes y capital. Solo se emiten filas para los
periodos pagados.
r = simulate(
mode=AmortizationMode.CUSTOM_SCHEDULE,
principal="10000.00", annual_rate="0.12", periods=12,
custom_payments=[
{"period": 1, "amount": "1100.00"},
{"period": 6, "amount": "2100.00"},
{"period": 12, "amount": "7000.00"},
],
start_date="2026-08-09",
)
print(r.schedule[0].principal_component) # 1000.00
print(r.schedule[-1].payment) # 7059.90 (ultima fila cuadrada)
print(r.summary.total_interest) # 259.90
print(r.summary.total_paid) # 10259.90
11. GRACE_PERIOD_DEFERRED — periodo de gracia
Submodalidad interest_only (se paga solo interes durante la gracia):
r = simulate(
mode=AmortizationMode.GRACE_PERIOD_DEFERRED,
principal="15000.00", annual_rate="0.24", periods=12,
grace_periods=3, grace_period_behavior="interest_only",
start_date="2026-08-09",
)
print(r.schedule[0].interest_component) # 300.00
print(r.summary.total_interest) # 2439.57
print(r.summary.total_paid) # 17439.57
Submodalidad deferred (sin pagos, el interes se capitaliza en el saldo):
r = simulate(
mode=AmortizationMode.GRACE_PERIOD_DEFERRED,
principal="15000.00", annual_rate="0.24", periods=12,
grace_periods=3, grace_period_behavior="deferred",
start_date="2026-08-09",
)
print(r.metadata["principal_effective"]) # 15918.12 (saldo capitalizado)
print(r.metadata["capitalized_interest"]) # 918.12
print(r.summary.total_interest) # 2551.98
print(r.summary.total_paid) # 17551.98
12. FEES_AND_INSURANCE — con cargos/seguro
Base francesa mas un cargo porcentual sobre saldo (seguro, 2 % anual,
cobrado mensualmente) en fees_component:
r = simulate(
mode=AmortizationMode.FEES_AND_INSURANCE,
principal="15000.00", annual_rate="0.24", periods=12,
fees=[{"name": "seguro", "rate": "0.02"}],
start_date="2026-08-09",
)
print(r.schedule[0].fees_component) # 25.00 (decrece con el saldo)
print(r.schedule[-1].fees_component) # 2.32
print(r.summary.total_fees) # 168.40
print(r.summary.total_paid) # 17189.08
13. INDEXED_INFLATION — indexado a inflacion
El saldo se ajusta por el factor compuesto del indice (un factor por periodo) y el capital efectivo se amortiza en sistema frances:
r = simulate(
mode=AmortizationMode.INDEXED_INFLATION,
principal="1000.00", annual_rate="0.12", periods=12,
inflation_index=["1.004"] * 12,
start_date="2026-08-09",
)
print(r.metadata["principal_effective"]) # 1049.07
print(r.summary.total_interest) # 69.45
print(r.summary.total_paid) # 1118.52
Principios de diseno
- Precision decimal exacta: todo monto y tasa se calcula con
decimal.Decimal, nuncafloat. El redondeo es explicito y configurable (rounding="ROUND_HALF_UP"por defecto) y el cuadre de capital esta garantizado:sum(principal_component) == principaly saldo final en0.00. - Sin estado (stateless): funciones puras y
dataclasses(frozen=True)para entradas y salidas. Cada calculo recibe todo como parametro y devuelve un resultado inmutable; no hay persistencia ni efectos secundarios. - Determinista: las fechas siempre llegan como parametro
(
dateostrISO), nuncadatetime.now()implicito. Misma entrada, mismo resultado exacto. - Inmutabilidad matematica: una vez publicada, una modalidad no se
modifica. Si hay que cambiar una formula se crea una nueva modalidad
(p.ej.
..._V2), nunca se altera la existente. - Schema de salida fijo:
AmortizationResultyPaymentRowexponen siempre los mismos campos en las 13 modalidades; los montos no aplicables se emiten como0.00y los datos especificos de modalidad viajan enextra_data/metadata. - Extensible: cada modalidad es una estrategia de la interfaz
AmortizationStrategy; anadir la modalidad 14 no rompe nada existente. - Serializable:
to_dict()yto_json()en todos los resultados, sin dependencias externas (losDecimalse serializan comostrpara un roundtrip JSON exacto; las fechas como ISO 8601). - Errores propios: jerarquia
FinancialEngineErrorcon subclases accionables; validacion agresiva, nuncaassert.
API publica
simulate(mode, request=None, **kwargs) -> AmortizationResult
Unica funcion de entrada de la libreria. Resuelve la modalidad, construye la
AmortizationRequest, ejecuta la estrategia y devuelve el resultado
inmutable.
- Semantica request XOR kwargs: se pasa un
AmortizationRequestpreconstruido o campos sueltos en**kwargs, nunca ambos (pasar ambos lanzaInvalidParametersError).modees obligatorio en ambos casos. - Conversion de tipos amigable en
**kwargs: montos y tasas comostr/int/Decimal(elfloatse rechaza explicitamente); fechas ISO comostr; listas deExtraPayment/RateChange/Fee/CustomPaymentcomo dataclasses o dicts planos;annual_ratees obligatorio. - Los campos opcionales con valor por defecto son
periodicity="monthly"yrounding="ROUND_HALF_UP".
AmortizationMode
Enum con los 13 miembros listados en la tabla anterior. Tambien acepta el
nombre como str (el valor del enum es identico al nombre, p.ej.
"FRENCH_FIXED_PAYMENT").
AmortizationRequest
Dataclass frozen=True con los campos de entrada (los opcionales son
None cuando no aplican):
principal: Decimal— monto del credito (obligatorio, no negativo).annual_rate: Decimal— tasa anual como fraccion, p.ej.0.24= 24 % (obligatorio en todas las modalidades;ZERO_INTERESTexige0.00).periods: int— numero de periodos (>= 1).periodicity: Literal["monthly","biweekly","weekly","annual"].start_date: date— base del calendario (el periodo 1 cae enstart_date + un periodo).rounding: str = "ROUND_HALF_UP"— modo de redondeo dedecimal.down_payment: Decimal | None— enganche descontado del principal.extra_payments: list[ExtraPayment] | None— abonos a capital.rate_schedule: list[RateChange] | None— cambios de tasa por rango.fees: list[Fee] | None— cargos fijos o porcentuales.grace_periods: int | None— periodos iniciales con diferimiento.inflation_index: list[Decimal] | None— factores de ajuste por periodo.extra_payment_behavior: Literal["reduce_term","reduce_payment"] = "reduce_term".grace_period_behavior: Literal["deferred","interest_only"] = "deferred".custom_payments: list[CustomPayment] | None— pagos manuales por periodo.
Dataclasses auxiliares (todas frozen=True): ExtraPayment(period, amount), RateChange(period_from, period_to, annual_rate), Fee(name, amount=None, rate=None, periodicity="monthly") y CustomPayment(period, amount).
Resultado: AmortizationResult
mode: AmortizationMode— modalidad aplicada.schedule: list[PaymentRow]— calendario de pagos.summary: AmortizationSummary— totales agregados.metadata: dict— parametros originales del calculo (trazabilidad) y datos de contexto de la modalidad.to_dict() -> dictyto_json() -> str.
PaymentRow (schema fijo): period, date, payment,
principal_component, interest_component, fees_component, balance,
extra_payment y extra_data (dict opcional con datos especificos de la
modalidad, p.ej. index_factor, capitalized_interest).
AmortizationSummary: total_paid, total_interest, total_fees,
effective_rate (tasa periodica) y periods_count; con to_dict() /
to_json().
Excepciones
Jerarquia propia que hereda de FinancialEngineError:
InvalidParametersError— parametros que violan el contrato de entrada (periodos < 1, calendarios inconsistentes,request+kwargsa la vez,floaten un monto,annual_rate=None, etc.).NegativePrincipalError— principal negativo.RateOutOfRangeError— tasa anual fuera de[0, 1](inclusive).ScheduleMismatchError— el calendario no cuadra con la solicitud.
Captura la raiz except FinancialEngineError o la subclase concreta segun
lo que necesites.
Desarrollo
Clonar el repo, crear el venv e instalar en modo editable:
git clone https://github.com/jesusmrv81/amortizacion-engine.git
cd amortizacion-engine
python3.12 -m venv .venv
.venv/bin/pip install -e .
.venv/bin/pip install -r requirements-dev.txt
Ejecutar la suite completa con cobertura (objetivo >= 90 %):
.venv/bin/pytest --cov=financial_engine --cov-report=term-missing
Lint y formato:
.venv/bin/ruff check .
.venv/bin/black --check .
Los docstrings del API publico incluyen ejemplos verificables; se pueden ejecutar como doctests con pytest:
.venv/bin/pytest --doctest-modules src/financial_engine/ -q
Contributing
Las contribuciones son bienvenidas:
- Haz un fork del repositorio y crea una rama para tu cambio.
- Anade o actualiza los tests (
pytest) y verifica que la cobertura se mantiene en el 100 %. - Ejecuta
ruff check .yblack .antes de abrir el PR. - Respeto a la inmutabilidad matematica: no modifiques la formula de
una modalidad ya publicada. Si necesitas cambiar una formula, crea una
modalidad nueva (p.ej.
FRENCH_FIXED_PAYMENT_V2) y registrala enAmortizationMode.
FAQ
¿Por que Decimal y no float?
El dinero no admite errores de punto flotante. decimal.Decimal representa
montos y tasas de forma exacta y permite un control explicito del redondeo
(ROUND_HALF_UP por defecto), lo que garantiza que dos calculos identicos
produzcan siempre el mismo resultado exacto y que el cuadre del capital
cierre al centavo.
¿Como garantiza el cuadre del capital?
El motor concilia la ultima fila de cada calendario
(reconcile_last_payment): ajusta el ultimo pago para que
sum(principal_component) sea exactamente igual al principal original y
el saldo final quede en 0.00, sin arrastrar redondeos intermedios.
¿Puedo usar fechas reales?
Si. La fecha base del calendario se pasa como parametro
(start_date, como datetime.date o str ISO "YYYY-MM-DD") y el motor
calcula las fechas de cada periodo a partir de ella. El motor es
determinista: nunca usa datetime.now() implicito.
¿Es libre?
Si, esta bajo licencia MIT. Puedes usarlo, modificarlo y distribuirlo en proyectos comerciales o personales sin restricciones (ver LICENSE).
¿Como anado una modalidad nueva?
Implementa una clase que herede de AmortizationStrategy con su metodo
compute(), registrala en el mapa de estrategias y anade el miembro
correspondiente a AmortizationMode. El resto de la API (validacion,
schema de salida, serializacion) funciona sin cambios. Nunca modifiques una
modalidad ya publicada: crea una _V2.
Licencia
MIT — ver LICENSE.
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 amortizacion_engine-0.1.0.tar.gz.
File metadata
- Download URL: amortizacion_engine-0.1.0.tar.gz
- Upload date:
- Size: 74.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b76a56f10f030896a182d01ca924276fa5fdc3ded580d048c67f5f1860c529dc
|
|
| MD5 |
22e744d455086468275ade86fe31e1df
|
|
| BLAKE2b-256 |
7bebe6082046095f70e50950bb012a9c3695b5d8e539519c97501f86ec10488a
|
Provenance
The following attestation bundles were made for amortizacion_engine-0.1.0.tar.gz:
Publisher:
publish.yml on jesusmrv81/amortizacion-engine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amortizacion_engine-0.1.0.tar.gz -
Subject digest:
b76a56f10f030896a182d01ca924276fa5fdc3ded580d048c67f5f1860c529dc - Sigstore transparency entry: 2409753660
- Sigstore integration time:
-
Permalink:
jesusmrv81/amortizacion-engine@45cd6829b2f33fd83ee55057b25efc92a3a2cbc8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jesusmrv81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@45cd6829b2f33fd83ee55057b25efc92a3a2cbc8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file amortizacion_engine-0.1.0-py3-none-any.whl.
File metadata
- Download URL: amortizacion_engine-0.1.0-py3-none-any.whl
- Upload date:
- Size: 63.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16e71eba170b4f8ad1681f177d32d159c83bb49647fd1539100c1455bf6373aa
|
|
| MD5 |
e92d161ddb9d2387e81b9c4b9f3cb679
|
|
| BLAKE2b-256 |
73b3db7b1f10f38e22b2cc6f8c41bc7e7b302b657c6980edc652124665c9832a
|
Provenance
The following attestation bundles were made for amortizacion_engine-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on jesusmrv81/amortizacion-engine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
amortizacion_engine-0.1.0-py3-none-any.whl -
Subject digest:
16e71eba170b4f8ad1681f177d32d159c83bb49647fd1539100c1455bf6373aa - Sigstore transparency entry: 2409753701
- Sigstore integration time:
-
Permalink:
jesusmrv81/amortizacion-engine@45cd6829b2f33fd83ee55057b25efc92a3a2cbc8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jesusmrv81
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@45cd6829b2f33fd83ee55057b25efc92a3a2cbc8 -
Trigger Event:
push
-
Statement type: