"¿Es posible hacer un asistente que revise mercado público y vea ofertas para licitar? Onda le dices que busque, no sé, cosas de imprenta. Y que después te devuelva una definición breve, alcance, id de la oferta y plazos."
Entregable esperado: herramienta que, dada una palabra (ej. "imprenta"), devuelva por cada licitación:
Mercado Público de Chile tiene API pública documentada. Antes de escribir código, confirmé conectividad real desde este servidor (GCP e2-micro).
Prueba 1 – endpoint de ticket (ruta clásica de docs viejas):
GET /seguridad/obtenerticket?usuario=...&clave=...
→ HTTP 404 de IIS ("File or directory not found")
Conclusión: esa ruta YA NO EXISTE. La API migró.
Prueba 2 – listado sin ticket:
GET /servicios/v1/licitaciones.json
→ {"Codigo":404,"Mensaje":"Recurso no encontrado."}
Conclusión: la ruta existe pero exige ticket válido (JSON estructurado, no error de servidor).
No tengo web_search en esta instancia, así que sondeé directamente:
/seguridad/obtenerticket (varias combos de params) → 404 IIS/servicios/v1/obtenerticket → 404 JSONapi.mercadopublico.cl/ → redirige a https://www.chilecompra.cl/api/
(pista: migró a ChileCompra)Clave del hallazgo: grepeé la página de docs de ChileCompra y encontré las rutas reales embebidas en el HTML, incluyendo un ticket de ejemplo (GUID):
/servicios/v1/publico/licitaciones.json?ticket=F8537A18-...-426B4FEE2844
Prueba con esa ruta + ticket:
→ HTTP 429 "Lo sentimos. Hemos detectado peticiones simultáneas."
(rate-limit, NO 404 → la ruta y el ticket SON válidos)
Esperé 5s y reintenté:
→ HTTP 200, 68.902 bytes, Cantidad: 435 licitaciones del día. ✅
Prueba de detalle por código:
GET /servicios/v1/publico/licitaciones.json?codigo=2263-64-LE26&ticket=...
→ devolvió Descripcion, Comprador (organismo/región), Fechas
(cierre/adjudicación), Items, MontoEstimado. ✅
Esto cubre EXACTO lo que pidió Gonzalo: definición, alcance, ID, plazos (más un extra útil: monto estimado).
Archivo: /home/magickaito2141/licitaciones/buscar_licitaciones.py
Dependencia: ninguna (solo stdlib: urllib, json, argparse, datetime).
Lógica:
Uso:
python3 buscar_licitaciones.py "imprenta" --dias 7 --max 5
# --ticket TU_TICKET o env MP_TICKET para usar tu propio ticket
BUG 1 – KeyError al recortar Items
- Síntoma: items[:3] tiraba KeyError.
- Causa: a veces Items venía como dict, no lista.
- Fix temporal: if isinstance(items, dict): items = list(items.values())
(este fix estaba MAL – ver Bug 4).
BUG 2 – FechaCierre null en el detalle
- Síntoma: el detalle traía FechaCierre=null pero el listado sí la tenía.
- Fix: tomar el cierre del listado cuando falte en el detalle.
BUG 3 – AttributeError 'int' object has no attribute 'get'
- Síntoma: al imprimir items, crasheaba en elementos que no eran dict.
- Fix: parseo defensivo de cada item con isinstance(it, dict).
BUG 4 (el importante) – Items imprimía el JSON COMPLETO de 58 ítems
- Inspeccioné la estructura real de Items:
json
"Items": {"Cantidad": 58, "Listado": [ {...}, {...}, ... ]}
- Mi fix de Bug 1 hacía list(items.values()) → [58, [lista cruda]],
por eso pintaba "58" y toda la lista sin formato.
- Fix definitivo: desempaquetar el wrapper:
python
if isinstance(items, dict):
items = items.get("Listado", []) if isinstance(items.get("Listado"), list) else []
$ python3 buscar_licitaciones.py "imprenta" --dias 3 --max 2
=== 2 coincidencia(s) encontradas ===
1. ID: 4238-57-LE26
Definicion : MATERIAL DE IMPRENTA - DEPTO DE SALUD MUNICIPAL
Alcance : I MUNICIPALIDAD DE CURANILAHUE | Región del Biobío | 58 item(s)
Estado : Publicada
Cierre : 2026-07-31 12:00 (quedan 9 dias)
Ver : https://www.mercadopublico.cl/Portal/Principal/DetalleLicitacion?id=4238-57-LE26
2. ID: 4690-20-LE26
Definicion : CONVENIO SUMINISTRO TRABAJOS DE IMPRENTA
Alcance : I MUNICIPALIDAD DE MAULE | Región del Maule | 1 item(s)
Estado : Publicada
Cierre : 2026-07-30 18:30 (quedan 8 dias)
/servicios/v1/publico/licitaciones.json (no /seguridad/...
ni /servicios/v1/licitaciones.json sin /publico/). Descubierta grepeando
la página de docs de ChileCompra./home/magickaito2141/licitaciones/buscar_licitaciones.py/home/magickaito2141/licitaciones/REPORTE.md