32c7336bf6
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.0 KiB
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. |
|
|
false | error_py_core |
|
true |
|
python/functions/infra/resolve_pg_dsn_test.py | python/functions/infra/resolve_pg_dsn.py |
|
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
.envdel proyecto en disco y ejecutapass showcomo subproceso. El resultado depende del entorno de la maquina. - El
dsndevuelto contiene el password en claro. NO lo logees ni lo imprimas en produccion (el## Ejemplolo redacta a proposito). - La ruta del
.envse resuelve relativa aFN_REGISTRY_ROOTsi esa env var esta seteada; si no, relativa al cwd. Lanza desde la raiz del registry o exportaFN_REGISTRY_ROOTpara que el paso (2).envfuncione. - 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
seoapunta hoy al mismo entry de pass quecaptacion(mismo contenedor Postgres, distinta dbseo). Si seo_analytics pasa a tener credenciales propias, actualiza_PROJECTS['seo'].