Files
fn_registry/python/functions/infra/resolve_pg_dsn.md
T
egutierrez 32c7336bf6 feat(infra): auto-commit con 56 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-21 14:22:55 +02:00

4.0 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, params, output
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports tested tests test_file_path file_path params output
resolve_pg_dsn function py infra 1.0.0 impure def resolve_pg_dsn(project: str) -> dict Resuelve el DSN de PostgreSQL de un proyecto conocido del ecosistema (captacion_clientes, seo_analytics) sin lanzar. Centraliza el patron inline repetido por el agente: leer el DSN desde la variable de entorno del proyecto (CAPTACION_DSN, SEO_DSN), caer a la linea <ENV_VAR>= del .env del proyecto, y como ultimo recurso construirlo desde el secreto de pass (password en runtime, user/host/port/db fijos por proyecto). Cada proyecto declara su politica de resolucion en un mapa interno explicito (_PROJECTS) con alias para el nombre largo. Orden de resolucion: (1) env var, (2) .env, (3) pass. Devuelve {status:'ok', project, dsn, source} con source='env'|'dotenv'|'pass', o {status:'error', error} si el proyecto es desconocido o no se pudo construir el DSN. NUNCA hardcodea el password: lo lee de pass via pass_get_secret en runtime.
postgres
postgresql
dsn
credential
infra
pass_get_secret_py_infra
false error_py_core
os
true
env var seteada gana y source es env
proyecto desconocido devuelve error sin lanzar
alias largo resuelve a la clave canonica
fallback a .env cuando no hay env var
python/functions/infra/resolve_pg_dsn_test.py python/functions/infra/resolve_pg_dsn.py
name desc
project Nombre del proyecto. Acepta la clave canonica ('captacion', 'seo') o el alias largo ('captacion_clientes', 'seo_analytics'). Un nombre no registrado devuelve {status:'error'} con la lista de proyectos conocidos.
dict. En exito: {status:'ok', project:str (clave canonica), dsn:str (cadena postgresql://...), source:str ('env'|'dotenv'|'pass')}. En error (sin lanzar): {status:'error', error:str} para proyecto desconocido o DSN no resoluble.

Ejemplo

import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from infra.resolve_pg_dsn import resolve_pg_dsn

# Por nombre corto o largo, da igual.
res = resolve_pg_dsn("captacion")
print(res["status"])   # ok
print(res["source"])   # 'dotenv' (lee CAPTACION_DSN del .env del proyecto)
# res["dsn"] -> "postgresql://captacion:***@localhost:5433/trends"

# La env var, si esta seteada, gana sobre el .env y sobre pass.
os.environ["SEO_DSN"] = "postgresql://captacion:x@localhost:5433/seo"
print(resolve_pg_dsn("seo_analytics")["source"])  # env

Cuando usarla

Usala antes de cualquier psql/psycopg2/pg_query contra el Postgres de un proyecto del ecosistema, en vez de reescribir a mano la resolucion del DSN (grep al .env + fallback a pass). Es el unico sitio que sabe como se llama la env var de cada proyecto, donde vive su .env y de que entry de pass sale el password. Si vas a lanzar varias queries seguidas, resuelve el DSN una vez y reusalo; para el caso comun de "una query a un proyecto" usa el pipeline query_project_pg_py_pipelines que ya compone esta resolucion con pg_query.

Gotchas

  • Impura: lee variables de entorno, el .env del proyecto en disco y ejecuta pass show como subproceso. El resultado depende del entorno de la maquina.
  • El dsn devuelto contiene el password en claro. NO lo logees ni lo imprimas en produccion (el ## Ejemplo lo redacta a proposito).
  • La ruta del .env se resuelve relativa a FN_REGISTRY_ROOT si esa env var esta seteada; si no, relativa al cwd. Lanza desde la raiz del registry o exporta FN_REGISTRY_ROOT para que el paso (2) .env funcione.
  • Solo conoce los proyectos del mapa _PROJECTS. Anadir uno nuevo = una entrada de diccionario (env_var + dotenv_path + pass_path + pg fijos), no otro bloque de bash inline.
  • El fallback de seo apunta hoy al mismo entry de pass que captacion (mismo contenedor Postgres, distinta db seo). Si seo_analytics pasa a tener credenciales propias, actualiza _PROJECTS['seo'].