---
name: ingest_market_trends
kind: pipeline
lang: py
domain: pipelines
version: 1.0.0
purity: impure
signature: "ingest_market_trends(source)"
error_type: error_go_core
description: "Scrapea una fuente de tendencias de mercado (Amazon, Google Trends, TikTok, AliExpress o precios de competencia) y aterriza la foto del día en su tabla de la base de datos Postgres `trends`. Dispatcher one-shot pensado para invocarse desde dag_engine (un step por fuente). Proyecto captacion_clientes."
tags: [market-intel, scraping, trends, postgres, ingest, launcher]
uses_functions:
  - scrape_amazon_bestsellers_py_datascience
  - scrape_google_trends_py_datascience
  - scrape_tiktok_creative_py_datascience
  - scrape_aliexpress_trending_py_datascience
  - scrape_competitor_prices_py_datascience
  - pg_insert_rows_py_infra
uses_types: []
returns: []
returns_optional: false
file_path: python/functions/pipelines/ingest_market_trends.py
params:
  - name: source
    desc: "Fuente a scrapear: amazon | google_trends | tiktok | aliexpress | competitor. Una por invocación."
  - name: config
    desc: "Ruta del JSON de configuración (keywords, categorías, países). Default: projects/captacion_clientes/config/sources.json."
  - name: dsn
    desc: "DSN Postgres override. Si se omite, se resuelve por CAPTACION_DSN env -> .env del proyecto -> pass captacion/postgres."
output: "JSON por stdout con {source, scraped, inserted} (filas scrapeadas e insertadas en Postgres)."
---

Pipeline dispatcher que compone un scraper del registry con `pg_insert_rows` para
insertar la foto diaria de una fuente de tendencias en la base de datos `trends`.

Resuelve el DSN de Postgres por precedencia: `--dsn` → env `CAPTACION_DSN` →
`projects/captacion_clientes/.env` → `pass captacion/postgres`. La configuración de cada
fuente (keywords, categorías, países) vive en `config/sources.json` del proyecto, sin
secretos.

## Ejemplo

```bash
# Amazon Best Sellers + Movers & Shakers de las categorías del config
fn run ingest_market_trends_py_pipelines --source amazon
# -> {"source": "amazon", "scraped": 420, "inserted": 420}

# Google Trends de las keywords del config
fn run ingest_market_trends_py_pipelines --source google_trends

# Precios de la competencia (lee competitor_targets de la propia DB)
fn run ingest_market_trends_py_pipelines --source competitor
```

## Cuando usarla

Cuando quieras capturar la foto del día de una fuente de tendencias en Postgres para
analizarla en Metabase. Es el step canónico que invoca dag_engine (un `function:` por
fuente) para el scraping programado diario/horario del proyecto captacion_clientes.

## Gotchas

- **TikTok y AliExpress** bloquean el scraping HTTP-directo desde datacenter/headless
  (anti-bot, captcha). Esos `--source` lanzarán error (visible en el run de dag_engine)
  hasta que se reimplementen vía browser MCP/CDP con sesión real (doctrina `flow_replay.md`).
  Amazon y Google Trends sí funcionan por HTTP.
- **`--source competitor`** no hace nada si `competitor_targets` está vacía: hay que
  insertar primero los objetivos (competidor + URL + product_key) a vigilar.
- Append-only: cada corrida inserta una foto nueva (no actualiza), de modo que Metabase
  puede graficar la evolución temporal. No correr en bucle apretado o inflarás la tabla.
- Google Trends (pytrends) se rate-limitea (429); el scraper reintenta con backoff pero
  con muchas keywords puede tardar o fallar.
