ogacai
Pipeline de línea de comandos que convierte subtítulos automáticos de YouTube (.json3) en un artículo de blog en Markdown, usando DeepSeek (o, opcionalmente, Cloudflare Workers AI / Gemini) para la redacción.
Descripción
ogacai resuelve un problema puntual: pasar de un video de YouTube a un artículo publicable sin perder fidelidad al contenido hablado y sin depender de un proceso manual de transcripción y limpieza.
El flujo se divide en etapas separadas, cada una con una responsabilidad clara:
url de YouTube → .json3 → raw.txt + clean.txt → IA → artículo.md validado + portada.png
(fetch, opcional) (procesar) (procesar) (generar + validar) (portada, al final de `run` salvo --sin-portada)
- Obtención (
ogacai/fetch.py, opcional): descarga el.json3de subtítulos automáticos de un video de YouTube víayt-dlp, sin descargar el video. Es la única etapa que depende de una herramienta externa — por esoyt-dlpes una dependencia opcional (pip install "ogacai[fetch]"), no obligatoria para quien ya tiene su propio.json3. - Parseo y limpieza (
ogacai/procesar.py): lee el.json3, reconstruye el texto hablado y produce dos versiones — una extracción fiel (raw) y una limpia (clean, sin repeticiones de "rolling captions" ni anotaciones tipo[música]). No llama a ninguna API; es reproducible y auditable. - Generación (
ogacai/deepseek.py/ogacai/workers_ai.py/ogacai/gemini.py+ogacai/prompt.py): envía el texto limpio a un proveedor de IA (DeepSeek por defecto; Cloudflare Workers AI o Gemini como alternativas, seleccionables con--proveedor) con un system prompt fijo. El modelo solo recibe texto y solo devuelve texto — sin tool-calling, sin acceso a disco. - Validación (
ogacai/validar.py): revisa que el artículo generado tenga la estructura esperada (front matter completo, tags coherentes, bloques de código bien cerrados). No valida fidelidad al contenido original — eso sigue siendo responsabilidad de una revisión humana.
Esta separación permite calibrar cada etapa por separado (por ejemplo, ajustar el prompt) sin gastar llamadas a la API mientras se depura el parseo.
Características
- Parseo de
.json3de subtítulos automáticos de YouTube, con deduplicación de texto solapado por "rolling captions". - Limpieza opcional de muletillas comunes en español (
eh,mmm,este,o sea,bueno,digo, entre otras) vía--sin-muletillas. - Eliminación de anotaciones entre corchetes (
[música],[aplausos], etc.) que no son habla real. - Vista previa (
preview) de qué palabras exactas quita la limpieza, sin necesidad de leerraw.txt/clean.txtcompletos a mano. - Generación de artículos en Markdown vía DeepSeek, Cloudflare Workers AI o Gemini (
--proveedor deepseek|workers-ai|gemini, defaultdeepseek), con un system prompt fijo que distingue entre artículo narrativo (caso de estudio) y artículo explicativo/técnico, y reintentos con backoff ante fallas transitorias de red. - Validación estructural del front matter (
title,description,date,image,imageAlt,tags) y de los tags según el tipo de artículo. - Resolución de configuración (API key y carpeta de salida) por variable de entorno o archivo
config.toml. - Pipeline completo (
run) con modo--dry-runpara revisar el resultado antes de escribir el archivo final, y generación de la portada OpenGraph como paso final (salvo--sin-portada). - Sin dependencia de binarios compilados: corre igual en Termux, Linux o macOS usando el resolvedor DNS y el almacén de certificados del sistema (vía
requests).
Requisitos
- Python 3.9 o superior (usa
tomllibde la librería estándar en 3.11+; en versiones anteriores se instalatomlicomo dependencia). - Dependencia en tiempo de ejecución:
requests(>=2.25). - Una API key de DeepSeek (solo necesaria para los subcomandos que llaman al modelo, y solo si usás el proveedor por defecto). Si preferís otro proveedor, necesitás en cambio credenciales de Cloudflare Workers AI (account ID + API token) o de Gemini (una API key) — ver "Configurar credenciales" más abajo.
- Un archivo
.json3de subtítulos automáticos de un video de YouTube.ogacaipuede descargarlo por vos conogacai fetch(ver más abajo, requiere instalar el extrafetch), o podés obtenerlo por tu cuenta conyt-dlpy pasárselo directamente aogacai procesar/ogacai run. - Opcional:
yt-dlp(>=2024.1), solo si querés usarogacai fetch. Se instala conpip install "ogacai[fetch]".
Instalación
Instalá el paquete desde PyPI (requiere Python 3.9 o superior):
pip install ogacai
Termux:
pkg update
pkg install python
pip install ogacai
Verificá la instalación:
ogacai --help
Extras opcionales según la función que uses:
-
ogacai fetch(descargar el.json3víayt-dlp):pip install "ogacai[fetch]"
-
ogacai portada(generar la imagen OpenGraph 1200x630):pip install "ogacai[portada]"
Configurar credenciales de los proveedores de IA
ogacai generar/ogacai run usan DeepSeek por defecto (--proveedor deepseek), pero podés elegir Cloudflare Workers AI (--proveedor workers-ai) o Gemini (--proveedor gemini) en su lugar. Solo hace falta configurar las credenciales del proveedor que realmente vayas a usar.
DeepSeek (default, una sola credencial), en orden de prioridad (la primera gana si ambas están definidas):
export DEEPSEEK_API_KEY="tu-key-aqui"
o de forma persistente:
mkdir -p ~/.config/ogacai
cat > ~/.config/ogacai/config.toml << 'EOF'
api_key = "tu-key-aqui"
output_dir = "/ruta/a/tu-repo-blog/src/content/blog"
EOF
output_dir es opcional: define la carpeta por defecto donde ogacai run escribe el artículo final si no se pasa --output-dir.
Cloudflare Workers AI (--proveedor workers-ai, requiere DOS credenciales: account ID + API token):
export WORKERS_AI_ACCOUNT_ID="tu-account-id"
export WORKERS_AI_API_TOKEN="tu-api-token"
o de forma persistente:
ogacai config set workers_ai.account_id "tu-account-id"
ogacai config set workers_ai.api_token "tu-api-token"
Gemini (--proveedor gemini, una sola credencial, más un modelo opcional):
export GEMINI_API_KEY="tu-key-aqui"
o de forma persistente:
ogacai config set gemini.api_key "tu-key-aqui"
ogacai config set gemini.model "gemini-3.5-flash-lite" # opcional; ver nota abajo
gemini.model es opcional: si no se configura, se usa gemini-3.5-flash-lite (el default del cliente). El catálogo de modelos de Gemini rota rápido (versiones previas dejan de estar disponibles para cuentas nuevas), así que conviene poder cambiarlo sin tocar código si Google retira el modelo actual.
ogacai config show muestra la configuración resuelta, con las API keys/tokens enmascarados (solo se ven los últimos 4 caracteres).
Uso
Ejemplo mínimo, de principio a fin:
# 0. (Opcional) Descargar el .json3 directo desde una URL de YouTube
ogacai fetch "https://youtu.be/tu-video" --salida-dir /tmp/prueba
# -> imprime "Listo: /tmp/prueba/<video_id>.es.json3"
# 1. Parsear el .json3 (gratis, no llama a ninguna API)
ogacai procesar /tmp/prueba/<video_id>.es.json3 --salida-dir /tmp/prueba
# 2. (Opcional) Revisar qué quitó la limpieza antes de gastar la llamada a DeepSeek
ogacai preview /tmp/prueba/<video_id>.es.json3
# 3. Generar el artículo con DeepSeek (default) -- usá --proveedor workers-ai o --proveedor gemini para otro proveedor
export DEEPSEEK_API_KEY="tu-key-aqui"
ogacai generar /tmp/prueba/transcripcion_clean.txt --output /tmp/prueba/articulo.md
# 4. Validar la estructura del artículo generado
ogacai validar /tmp/prueba/articulo.md
Pipeline completo en un solo paso, primero en modo de prueba:
ogacai run mi-video.json3 --dry-run
Y, una vez conforme con el resultado, la corrida que escribe el archivo final:
ogacai run mi-video.json3 --output-dir /ruta/a/tu-repo-blog/src/content/blog
CLI
ogacai --help
usage: ogacai [-h] [-V] {fetch,procesar,preview,generar,validar,run} ...
| Subcomando | Qué hace |
|---|---|
fetch |
Etapa 0, opcional: descarga el .json3 de subtítulos automáticos de una URL de YouTube vía yt-dlp, sin descargar el video. |
procesar |
Etapas 1-2: .json3 → transcripcion_raw.txt + transcripcion_clean.txt. No llama a ninguna API. |
preview |
Corre las etapas 1-2 en memoria (sin escribir archivos) y muestra qué palabras exactas quitó la limpieza. |
generar |
Etapa 3: llama a un proveedor de IA (--proveedor deepseek|workers-ai|gemini, default deepseek) con un .txt ya limpio y devuelve el artículo por salida estándar (o a un archivo con --output). |
validar |
Valida estructuralmente un artículo .md/.mdx ya generado. |
run |
Pipeline completo: procesar → generar → validar, con escritura del artículo final y generación de la portada (paso 5, salvo --sin-portada). |
ogacai fetch
ogacai fetch [-h] [--lang LANG] [--salida-dir SALIDA_DIR] url
ogacai fetch "https://youtu.be/tu-video" --lang es-orig --salida-dir /tmp/prueba
url: URL del video de YouTube.--lang: pista de subtítulos automáticos a descargar (por defectoes).es-orig(español sin traducción automática) suele ser preferible cuando el video la tiene.--salida-dir: carpeta donde escribir el.json3(por defecto, el directorio actual).
Requiere el extra fetch instalado (pip install "ogacai[fetch]"). No descarga el video, solo los subtítulos. Si el video no tiene la pista pedida, informa qué pistas automáticas sí están disponibles en vez de fallar en silencio.
ogacai procesar
ogacai procesar [-h] [--sin-muletillas] [--salida-dir SALIDA_DIR] archivo_json3
ogacai procesar mi-video.json3 --sin-muletillas --salida-dir /tmp/prueba
archivo_json3: ruta al archivo.json3de subtítulos.--sin-muletillas: elimina muletillas comunes en español además de la limpieza básica.--salida-dir: carpeta de salida (por defecto, el directorio actual).
ogacai preview
ogacai preview [-h] [--sin-muletillas] archivo_json3
ogacai preview mi-video.json3 --sin-muletillas
Corre las etapas 1-2 en memoria (no escribe raw.txt/clean.txt) y muestra, con un diff por palabras (difflib, sin dependencias externas), exactamente qué se quitó entre raw y clean. Pensado para confiar en la limpieza antes de gastar una llamada a DeepSeek.
ogacai generar
ogacai generar [-h] [--proveedor {deepseek,workers-ai,gemini}] [--output OUTPUT] archivo_clean_txt
ogacai generar /tmp/prueba/transcripcion_clean.txt --output /tmp/prueba/articulo.md
ogacai generar /tmp/prueba/transcripcion_clean.txt --proveedor gemini --output /tmp/prueba/articulo.md
archivo_clean_txt: ruta al.txtlimpio.--proveedor: proveedor de IA a usar (defaultdeepseek). Requiere las credenciales correspondientes ya configuradas (ver "Configurar credenciales de los proveedores de IA" más arriba):DEEPSEEK_API_KEYparadeepseek,workers_ai.account_id/workers_ai.api_tokenparaworkers-ai,GEMINI_API_KEY/gemini.api_keyparagemini.--output OUTPUT: archivo donde escribir el artículo generado. Sin este flag, el resultado se imprime por salida estándar (hay que redirigirlo con>para guardarlo). Reintenta automáticamente (con backoff) ante timeouts o errores de red — no ante errores ya devueltos por el servidor (autenticación, límite de uso, etc.).
ogacai validar
ogacai validar [-h] archivo_articulo
ogacai validar /tmp/prueba/articulo.md
Revisa front matter completo, coherencia de tags y bloques de código balanceados. No confirma fidelidad al contenido original.
ogacai run
ogacai run [-h] [--sin-muletillas] [--proveedor {deepseek,workers-ai,gemini}] [--output-dir OUTPUT_DIR] [--dry-run] [--sin-portada] archivo_json3
ogacai run mi-video.json3 --output-dir /ruta/a/tu-repo-blog/src/content/blog
ogacai run mi-video.json3 --proveedor gemini --output-dir /ruta/a/tu-repo-blog/src/content/blog
--sin-muletillas: igual que enprocesar.--proveedor: igual que engenerar(defaultdeepseek).--output-dir: carpeta de salida final (si no se pasa, usaconfig.tomlo el directorio actual).--dry-run: corre todo el pipeline pero solo imprime el resultado, sin escribir el archivo.--sin-portada: no genera la portada OpenGraph al final. Por defecto,runla genera si la sección[portada]de la config está seteada (el extraogacai[portada]sigue siendo opcional: si falta, el error se anota al final del flujo yrundevuelve código 1).
El nombre del archivo final se deriva del campo title del front matter generado (slug en minúsculas, sin tildes, separado por guiones). Si no se puede extraer un título, se usa articulo-sin-titulo.md. Con la portada habilitada, run además escribe {assets_dir}/{slug}.png y corrige el campo image del front matter para que apunte a ese archivo (misma lógica que el subcomando portada, vía portada.generar_desde_articulo).
Salida / JSON
ogacai no genera JSON de salida: parte de un JSON de entrada, el .json3 de subtítulos que ogacai procesar/ogacai run esperan recibir (obtenido con ogacai fetch o por tu cuenta con yt-dlp). El parseo (ogacai/procesar.py) valida que el archivo sea JSON válido y que tenga la clave events; de lo contrario, corta con un error explícito.
Estructura real de un .json3 (ejemplo simplificado):
{
"wireMagic": "pb3",
"pens": [],
"wsWinStyles": [],
"wpWinPositions": [],
"events": [
{
"tStartMs": 0,
"dDurationMs": 801784,
"id": 1,
"wpWinPosId": 1,
"wsWinStyleId": 1
},
{
"tStartMs": 3840,
"dDurationMs": 4079,
"wWinId": 1,
"segs": [
{ "utf8": "desarrolladores.", "acAsrConf": 0 },
{ "utf8": " Y", "tOffsetMs": 800, "acAsrConf": 0 }
]
}
]
}
Campos relevantes para ogacai:
events: lista de eventos de subtítulo. Es la única clave que el parser exige.segs: dentro de cada evento, la lista de segmentos de texto. Solo los eventos que tienensegsaportan contenido — se concatena el campoutf8de cada segmento para reconstruir el texto hablado. Eventos sinsegs(como marcadores de posición o estilo) se ignoran.tStartMs/dDurationMs/tOffsetMs: timestamps que el parser lee pero que, por ahora, no se usan en ninguna salida.
A partir de ese .json3, ogacai procesar produce dos archivos de texto plano (no JSON): transcripcion_raw.txt y transcripcion_clean.txt.
Licencia
MIT. El paquete incluye el archivo 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 ogacai-0.1.1.tar.gz.
File metadata
- Download URL: ogacai-0.1.1.tar.gz
- Upload date:
- Size: 55.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
575e659ed4cb15a3dcd1b5a84222faccd50c76fa2752fbe6cd212ed8baef7f11
|
|
| MD5 |
0236f3281bc622e5d779468eb8d2d073
|
|
| BLAKE2b-256 |
eeed3ad45258c70afd61b8c1c28962393d97a472f6c456d5e775879ae340f55e
|
File details
Details for the file ogacai-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ogacai-0.1.1-py3-none-any.whl
- Upload date:
- Size: 44.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62f4051c1a3f88c23ed3c6db10bf9d2fb5d0d6316be6fe6faa6e4bef8a13d341
|
|
| MD5 |
799ff6fc4bb3f8756fa143345478eef5
|
|
| BLAKE2b-256 |
e2da9d8ace6264d3f384b8542a290f01b06b2d721584f5544225eb78eff87bd1
|