Metadata-Version: 2.4
Name: dgt-petete
Version: 0.2.1
Summary: Cliente y CLI de la API interna del buscador PETETE de la DGT (consultas vinculantes de Tributos)
Project-URL: Homepage, https://github.com/hulahoop-media/dgt-petete
Project-URL: Repository, https://github.com/hulahoop-media/dgt-petete
Project-URL: Issues, https://github.com/hulahoop-media/dgt-petete/issues
Author-email: Hulahoop Media <guillem@hulahoop.media>
License-Expression: MIT
License-File: LICENSE
Keywords: consultas-vinculantes,dgt,fiscal,hacienda,petete,spain,tributos
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Natural Language :: Spanish
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Requires-Python: >=3.12
Requires-Dist: requests>=2.32.0
Description-Content-Type: text/markdown

# dgt-petete 📖

[![CI](https://github.com/hulahoop-media/dgt-petete/actions/workflows/ci.yml/badge.svg)](https://github.com/hulahoop-media/dgt-petete/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/dgt-petete)](https://pypi.org/project/dgt-petete/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

> Client and CLI for PETETE, the binding-rulings search engine of the Spanish
> tax authority (DGT). Docs are in Spanish, as is the subject matter.

La Dirección General de Tributos responde cada año miles de dudas fiscales en
forma de **consultas vinculantes**, y las guarda todas en **PETETE**, su
buscador oficial (sí, como el libro gordo: lo sabe todo). El problema es que
el libro gordo de Tributos no tiene API pública y su web es... de Hacienda.

Así que se la hemos hecho nosotros: este paquete replica los tres endpoints
internos del buscador por HTTP puro y le pone encima una CLI y una librería
Python. Buscar y descargar doctrina fiscal (p. ej. las consultas del Art. 36 /
39.7 LIS sobre incentivos fiscales culturales) pasa de ser una tarde a ser un
comando. Sin navegador, sin servidor, sin drama.

## 🚀 Instalación

El paquete está en [PyPI](https://pypi.org/project/dgt-petete/). Con
[`uv`](https://docs.astral.sh/uv/) ni siquiera hay que instalarlo:

```bash
uvx dgt-petete search --normativa "Ley 27/2014" --freetext "producciones cinematográficas"
```

O a la manera clásica:

```bash
pip install dgt-petete
# después:
dgt-petete download V2144-18 V0189-20 --out ./corpus
```

Para probar la última versión de desarrollo, instala desde el repo con
`pip install git+https://github.com/hulahoop-media/dgt-petete`.

## 🔍 Uso: CLI

```bash
# Buscar (combina campos; devuelve una línea "Nº<TAB>docid" por consulta)
dgt-petete search --normativa "Ley 27/2014" --freetext "artes escénicas y musicales"

# Descargar el texto verbatim de una o más consultas a .txt
dgt-petete download V2144-18 V0189-20 --out ./corpus
```

Flags de `search`: `--freetext`, `--normativa`, `--cuestion`, `--hechos`,
`--num`, `--tab` (`1`=generales, `2`=vinculantes, por defecto `2`).

## 🐍 Uso: librería

```python
from dgt_petete import search, download

hits = search(normativa="Ley 27/2014", freetext="producciones cinematográficas")
# -> [("V0006-17", "54874"), ("V0018-17", "54885"), ...]

texto = download("V2144-18")   # texto oficial completo de la consulta
```

## 🤖 Plugin de Claude Code

El repo es también un **marketplace de plugins de Claude Code**. Instala el
plugin y tu Claude podrá consultarle al libro gordo lo que haga falta, a
demanda y sin MCP:

```
/plugin marketplace add hulahoop-media/dgt-petete
/plugin install dgt-petete@dgt-petete
```

El plugin (`plugins/dgt-petete/`) empaqueta un **skill** que envuelve esta CLI
y la ejecuta vía `uvx` desde PyPI, sin que haga falta clonar nada.

## 🔬 Cómo funciona (la ingeniería inversa)

El buscador de PETETE (Knosys) llama a tres endpoints:

| Endpoint | Qué hace |
|---|---|
| `GET /consultas/do/form` | Establece la sesión (cookie) |
| `POST /consultas/do/search` | Busca. Devuelve HTML con `viewDocument(<docid>, <tab>)` y `updateNumResults("2","<total>")` |
| `POST /consultas/do/document` | Texto completo de una consulta (requiere el `docid`) |

**Detalles no obvios** (sin ellos no funciona, y nos costaron lo suyo):

- `/do/document` responde **401** sin cabeceras de AJAX (`X-Requested-With: XMLHttpRequest` + `Referer`).
- El operador entre campos es **`OPCMP_n=.Y`** (con punto inicial), no `Y`.
- Los valores van **doble-codificados**: el JS hace `encodeURI` sobre un string
  ya serializado, así que hay que `quote_plus(v)` y luego escapar los `%`. Sin
  esto, combinar dos campos devuelve **HTTP 400**.
- `tab`: `1` = consultas generales, `2` = consultas vinculantes.
- El servidor no envía el certificado intermedio de su cadena TLS (FNMT-RCM),
  así que `curl` y `requests` no lo validan de serie. El paquete incluye la
  cadena pública de la FNMT (`dgt_petete/fnmt-chain.pem`) y verifica contra
  ella por defecto; se puede sobrescribir con `new_session(verify=...)`.

## 🛠️ Desarrollo

```bash
git clone https://github.com/hulahoop-media/dgt-petete
cd dgt-petete
uv sync            # instala el paquete + dependencias de desarrollo
uv run pytest      # tests
uv run ruff check .
```

Ver [CONTRIBUTING.md](CONTRIBUTING.md) para la convención de commits y cómo
proponer cambios.

## ⚖️ Aviso

Herramienta no oficial que consulta datos **públicos** de la sede electrónica
de la Agencia Tributaria. Úsala con moderación (las descargas ya espacian las
peticiones). No afiliada a la AEAT ni a la DGT. El libro gordo no sabe que
existimos.

## 📄 Licencia

MIT. Ver [LICENSE](LICENSE).

---

Hecho por [Hulahoop Media](https://hulahoop.media) 🎪 Convertimos el caos
fiscal del entertainment en magia digital, y a veces liberamos las
herramientas que construimos por el camino.
