909290ddbf
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
"""Firma un JWT de static-embedding de Metabase y construye la URL del iframe."""
|
|
|
|
import time
|
|
|
|
import jwt
|
|
|
|
|
|
def sign_metabase_embed_jwt(
|
|
secret: str,
|
|
resource_type: str,
|
|
resource_id: int,
|
|
base_url: str,
|
|
params: dict | None = None,
|
|
exp_seconds: int = 3600,
|
|
theme: str | None = None,
|
|
bordered: bool = True,
|
|
titled: bool = True,
|
|
) -> dict:
|
|
"""Firma un JWT de static-embedding de Metabase (HS256) y arma la URL del iframe.
|
|
|
|
Args:
|
|
secret: secret de embedding de Metabase (Settings > Embedding). NUNCA va al cliente.
|
|
resource_type: "question" o "dashboard".
|
|
resource_id: id numerico de la card/dashboard en Metabase.
|
|
base_url: URL base de la instancia, ej. "https://reports.autingo.es".
|
|
params: parametros de embedding locked/enabled. Default {}.
|
|
exp_seconds: TTL del token en segundos desde ahora. Default 3600 (1h).
|
|
theme: tema opcional ("night" | "transparent" | None).
|
|
bordered: si el iframe muestra borde. Default True.
|
|
titled: si el iframe muestra titulo. Default True.
|
|
|
|
Returns:
|
|
dict con {"token": <jwt str>, "embed_url": <url completa>, "exp": <unix int>}.
|
|
|
|
Raises:
|
|
ValueError: si resource_type no es "question" ni "dashboard".
|
|
"""
|
|
if resource_type not in ("question", "dashboard"):
|
|
raise ValueError(
|
|
f'resource_type debe ser "question" o "dashboard", recibido: {resource_type!r}'
|
|
)
|
|
|
|
exp = int(time.time()) + exp_seconds
|
|
payload = {
|
|
"resource": {resource_type: resource_id},
|
|
"params": params or {},
|
|
"exp": exp,
|
|
}
|
|
token = jwt.encode(payload, secret, algorithm="HS256")
|
|
|
|
options = [f"bordered={str(bordered).lower()}", f"titled={str(titled).lower()}"]
|
|
if theme is not None:
|
|
options.append(f"theme={theme}")
|
|
fragment = "&".join(options)
|
|
|
|
embed_url = f"{base_url.rstrip('/')}/embed/{resource_type}/{token}#{fragment}"
|
|
|
|
return {"token": token, "embed_url": embed_url, "exp": exp}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
result = sign_metabase_embed_jwt(
|
|
secret="0" * 64,
|
|
resource_type="question",
|
|
resource_id=8048,
|
|
base_url="https://reports.autingo.es",
|
|
)
|
|
print(result["embed_url"])
|
|
print(f"exp={result['exp']}")
|