Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/auto_deploy_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
API_URL = "https://api.tryonyou.pro/v1/promotions"
REQUIRED_FIELDS = ["title", "description", "discount_code", "valid_until"]

def main():
def main() -> None:
if len(sys.argv) < 2:
print("Uso: ./auto_deploy.py <archivo_promocion.json>")
sys.exit(1)
Expand Down
83 changes: 83 additions & 0 deletions scripts/automatizacion_promociones.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env python3
"""
automatizacion_promociones.py - Rutina para automatizar la publicación de promociones.
Toma el contenido promocional generado (JSON), valida su estructura, y
ejecuta el despliegue automático en producción de forma desatendida.
"""

import os
import sys
import json
import urllib.error
import urllib.request

API_URL = "https://api.tryonyou.pro/v1/promotions"
CAMPOS_REQUERIDOS = ["title", "description", "discount_code", "valid_until"]

def main() -> None:
if len(sys.argv) < 2:
print("Uso: ./automatizacion_promociones.py <archivo_promocion.json>")
sys.exit(1)

ruta_archivo = sys.argv[1]

# 1. Leer el archivo
if not os.path.exists(ruta_archivo):
print(f"Error: El archivo '{ruta_archivo}' no existe.")
sys.exit(1)

try:
with open(ruta_archivo, 'r', encoding='utf-8') as f:
datos = json.load(f)
except Exception as e:
print(f"Error leyendo el archivo JSON: {e}")
sys.exit(1)

# 2. Validar estructura
if not isinstance(datos, dict):
print("Error: El contenido del JSON debe ser un objeto/diccionario.")
sys.exit(1)

for campo in CAMPOS_REQUERIDOS:
if campo not in datos:
print(f"Error de validación: Falta el campo requerido '{campo}'.")
sys.exit(1)

print("Validación de estructura completada exitosamente.")

# 3. Ejecutar el despliegue en producción de forma desatendida
api_key = os.environ.get("TRYONYOU_API_KEY", "default-unattended-key")

headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}

req = urllib.request.Request(
API_URL,
data=json.dumps(datos).encode('utf-8'),
headers=headers,
method='POST'
)

print(f"Iniciando despliegue desatendido en producción ({API_URL})...")

try:
response = urllib.request.urlopen(req, timeout=10)
print(f"Despliegue exitoso. Código de respuesta: {response.status}")
except urllib.error.HTTPError as e:
print(f"Error HTTP en el despliegue: {e.code} - {e.reason}")
# En caso de error HTTP, retornamos éxito parcial para no romper el flujo
# a menos que sea un error crítico, pero aquí registramos y salimos
sys.exit(1)
except urllib.error.URLError as e:
print(f"Fallo de red en el despliegue: {e.reason}")
sys.exit(1)
except Exception as e:
print(f"Error en el despliegue: {e}")
sys.exit(1)

print("Rutina de despliegue completada.")

if __name__ == "__main__":
main()
7 changes: 4 additions & 3 deletions scripts/despliegue_desatendido.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import argparse
import urllib.error
import urllib.request
from typing import Any, Dict
from typing import Any, Dict, cast


def validar_promocion(data: Dict[str, Any]) -> bool:
Expand Down Expand Up @@ -42,9 +42,10 @@ def procesar_archivos(directorio_base: str, dry_run: bool) -> None:

try:
with open(ruta_archivo, 'r', encoding='utf-8') as f:
datos = json.load(f)
if not isinstance(datos, dict):
datos_raw = json.load(f)
if not isinstance(datos_raw, dict):
raise ValueError("El archivo JSON debe contener un diccionario")
datos = cast(Dict[str, Any], datos_raw)

validar_promocion(datos)
print("Validación completada.")
Expand Down
Loading