feat(infra): auto-commit con 56 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: resolve_pg_dsn
|
||||
kind: function
|
||||
lang: py
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def resolve_pg_dsn(project: str) -> dict"
|
||||
description: "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."
|
||||
tags: [postgres, postgresql, dsn, credential, infra]
|
||||
uses_functions: [pass_get_secret_py_infra]
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_py_core"
|
||||
imports: [os]
|
||||
tested: true
|
||||
tests: ["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"]
|
||||
test_file_path: "python/functions/infra/resolve_pg_dsn_test.py"
|
||||
file_path: "python/functions/infra/resolve_pg_dsn.py"
|
||||
params:
|
||||
- name: project
|
||||
desc: "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."
|
||||
output: "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
|
||||
|
||||
```python
|
||||
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']`.
|
||||
Reference in New Issue
Block a user