#
# API Gateway: Cliente de API en Python.
# Copyright (C) API Gateway <https://www.apigateway.cl>
#
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
# bajo los términos de la GNU Lesser General Public License (LGPL) publicada
# por la Fundación para el Software Libre, ya sea la versión 3 de la Licencia,
# o (a su elección) cualquier versión posterior de la misma.
#
# Este programa se distribuye con la esperanza de que sea útil, pero SIN
# GARANTÍA ALGUNA; ni siquiera la garantía implícita MERCANTIL o de APTITUD
# PARA UN PROPÓSITO DETERMINADO. Consulte los detalles de la GNU Lesser General
# Public License (LGPL) para obtener una información más detallada.
#
# Debería haber recibido una copia de la GNU Lesser General Public License
# (LGPL) junto a este programa. En caso contrario, consulte
# <http://www.gnu.org/licenses/lgpl.html>.
#
"""
Módulo para el Formulario 29 (F29) del SII.
Para más información sobre la API, consulte la `documentación completa
del Formulario 29 <https://www.apigateway.cl/docs>`_.
"""
from __future__ import annotations
from typing import Any
from .. import ApiBase, ApiResponse
[documentos]
class F29(ApiBase):
"""
Cliente para consultas del Formulario 29 (F29) del SII.
:param str identificador: Identificador del contribuyente.
:param str clave: Clave del identificador.
:param kwargs: Argumentos adicionales.
"""
def __init__(
self,
identificador: str,
clave: str,
**kwargs: str,
) -> None:
"""Autentica con `identificador`/`clave` del contribuyente."""
super().__init__(
identificador=identificador,
clave=clave,
**kwargs, # type: ignore[arg-type]
)
[documentos]
def obtener_estados(self) -> ApiResponse[list[dict[str, Any]]]:
"""
Consulta integral de fiscalización del Formulario 29.
Para cada período, indica si fue declarado y su estado (sin
observaciones, con observaciones, con observaciones
justificadas, o sin declaración presentada).
Respuesta (ejemplo)::
{
"data": [
{
"periodo": 202304,
"declarado": false,
"estado": "Periodo sin declaración."
}
],
"metadata": {"timestamp": "..."}
}
:return: Respuesta de la API, con `data` y `metadata`.
En `data`, listado de períodos con su estado de declaración.
:rtype: ApiResponse[list[dict[str, Any]]]
"""
url = '/sii/f29/obtener_estados'
body = {'auth': self._get_auth()}
response = self.client.post(url, data=body)
return self._json(response)
[documentos]
def detalles_declaracion(self, folio: str) -> ApiResponse[dict[str, Any]]:
"""
Detalles de una declaración del Formulario 29 por folio.
Respuesta (ejemplo)::
{
"data": {
"folio": "3341234111",
"periodo": 202104,
"fecha_hora": "11/12/2025 21:16:33",
"estado": "Vigente",
"historial": [
{
"fecha": "26-05-2021 23:25:43",
"descripcion": "Selección de opción de pago PEL."
}
]
},
"metadata": {"timestamp": "..."}
}
:param str folio: Folio del formulario 29.
:return: Respuesta de la API, con `data` y `metadata`.
En `data`, folio, período, fecha/hora, estado e historial de la
declaración.
:rtype: ApiResponse[dict[str, Any]]
"""
url = '/sii/f29/detalles_declaracion/%(folio)s' % {'folio': folio}
body = {'auth': self._get_auth()}
response = self.client.post(url, data=body)
return self._json(response)
[documentos]
def declaraciones_listado(
self, periodo: str
) -> ApiResponse[list[dict[str, Any]]]:
"""
Listado de declaraciones del Formulario 29 por período.
Respuesta (ejemplo)::
{
"data": [
{
"periodo": 202501,
"folio": "8107267196",
"rut": "76192083-9",
"fecha": "20/02/2025",
"estado": "Vigente"
}
],
"metadata": {"timestamp": "..."}
}
:param str periodo: Período a consultar (AAAA o AAAA-MM).
:return: Respuesta de la API, con `data` y `metadata`.
En `data`, listado de declaraciones (período, folio, RUT, fecha y
estado) del período.
:rtype: ApiResponse[list[dict[str, Any]]]
"""
url = '/sii/f29/declaraciones/listado/%(periodo)s' % {
'periodo': periodo,
}
body = {'auth': self._get_auth()}
response = self.client.post(url, data=body)
return self._json(response)
[documentos]
def certificado_solemne_pdf(self, folio: str) -> bytes:
"""
Descarga el PDF del Certificado Solemne del Formulario 29.
:param str folio: Folio del certificado solemne.
:return: Contenido del PDF del certificado solemne.
:rtype: bytes
"""
url = '/sii/f29/certificado_solemne/pdf/%(folio)s' % {'folio': folio}
body = {'auth': self._get_auth()}
response = self.client.post(url, data=body)
return response.content