diff --git a/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/README.MD b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/README.MD new file mode 100644 index 0000000..9a0ad9f --- /dev/null +++ b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/README.MD @@ -0,0 +1,42 @@ +# Solución Reto Nerve #08 Puente HTTP + +## Estructura +```text +CesarAAR-Python +├── main.py #Programa principal. Aquí está toda la logica. +├── requirements.txt #Requerimientos de instalación. +└── test.py #Programa secundario. Pograma para ejecutar para comprobar el funcionamiento de la api. +``` + +## Pasos de uso +1. Crear entorno virtual e instalar dependencias: + +```bash +python -m venv venv +source venv/bin/activate # Linux / Mac +venv\Scripts\activate # Windows + +pip install -r requirements.txt +``` +2. Ejecutar NERVE: +```bash +nerve start +``` + +3. Ejecutar la API: + +```bash +uvicorn main:app --reload +``` +e ingresar a la documentación: `http://127.0.0.1:8000/docs`. + +4. Ejecutar el oyente: +```bash +python test.py +``` +## Opciones de la API +- */*: Verifica el estado de la API +- */login*: Crea el cliente(usuario) en NERVE +- */enviar*: Envias un mensaje a un cliente destino (el de test.py = test2). +- */enviar-all*: Envias el mensaje a todos los clientes. +- */logout*: Desconectas al cliente. \ No newline at end of file diff --git a/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/main.py b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/main.py new file mode 100644 index 0000000..df7bac8 --- /dev/null +++ b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/main.py @@ -0,0 +1,103 @@ +from fastapi import FastAPI, Response, status +from nerve import NexusClient +from fastapi.middleware.cors import CORSMiddleware + +client = NexusClient() + +app = FastAPI( + title="Reto 08 — Puente HTTP para Nerve (FastAPI) #8", + description="API Solución reto #8", + version="1.0.0", +) + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +@app.get("/", summary="Probar conexion a la API.") +def test(response: Response): + response.status_code = status.HTTP_200_OK + return {"status": 200, "details": "API funcionando correctamente"} + + +@app.post("/login", summary="Conectarse a NERVE.") +def login(name_user: str, response: Response): + try: + if not name_user or not name_user.strip(): + raise ValueError("El name_user no puede estar vacío.") + + if not isinstance(name_user, str) or not isinstance(name_user, str): + raise TypeError("El name_user debe ser texto (str).") + + client.connect(name_user) + response.status_code = status.HTTP_200_OK + return {"status": 200, "details": f"Conectado con el user: {name_user}"} + + except (ValueError, TypeError) as ev: + response.status_code = status.HTTP_422_UNPROCESSABLE_CONTENT + return {"status": 422, "details": f"Error de Validación: {ev}"} + except Exception as e: + response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + return {"status": 500, "details": str(e)} + + +@app.post("/enviar", summary="Enviar mensaje a otro usuario via NERVE.") +def enviar_nerve(destino: str, mensaje: str, response: Response): + try: + if not destino or not destino.strip(): + raise ValueError("El destino no puede estar vacío.") + if not mensaje or not mensaje.strip(): + raise ValueError("El mensaje no puede estar vacío.") + + if not isinstance(destino, str) or not isinstance(mensaje, str): + raise TypeError("Ambos campos deben ser texto (str).") + + msg_json = {"to": destino, "msg": mensaje} + + client.send(destino, msg_json) + response.status_code = status.HTTP_200_OK + return {"status": 200, "details": {"to": destino, "payload": msg_json}} + except (ValueError, TypeError) as ev: + response.status_code = status.HTTP_422_UNPROCESSABLE_CONTENT + return {"status": 422, "details": f"Error de Validación: {ev}"} + except Exception as e: + response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + return {"status": 500, "details": str(e)} + + +@app.post("/enviar-all", summary="Enviar mensaje a TODOS los clientes via NERVE.") +def enviar_nerve_all(mensaje: str, response: Response): + try: + if not mensaje or not mensaje.strip(): + raise ValueError("El mensaje no puede estar vacío.") + + if not isinstance(mensaje, str): + raise TypeError("MENSAJE debe ser texto (str).") + + msg_json = {"msg": mensaje} + + client.broadcast(msg_json) + response.status_code = status.HTTP_200_OK + return {"status": 200, "details": {"to": "all", "payload": msg_json}} + except (ValueError, TypeError) as ev: + response.status_code = status.HTTP_422_UNPROCESSABLE_CONTENT + return {"status": 422, "details": f"Error de Validación: {ev}"} + except Exception as e: + response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + return {"status": 500, "details": str(e)} + + +@app.delete("/logout", summary="Desconectarse de NERVE.") +def disconnect(response: Response): + try: + client.disconnect() + response.status_code = status.HTTP_200_OK + return {"status": 200, "details": "Desconexión exitosa."} + except Exception as e: + response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR + return {"status": 500, "details": str(e)} diff --git a/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/requirements.txt b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/requirements.txt new file mode 100644 index 0000000..7551b6e Binary files /dev/null and b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/requirements.txt differ diff --git a/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/test.py b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/test.py new file mode 100644 index 0000000..b2a672e --- /dev/null +++ b/retos/nerve/08-puente-http/soluciones/CesarAAR-Python/test.py @@ -0,0 +1,21 @@ +from nerve import NexusClient +import time + +client = NexusClient() + +client.connect("test2") + + +# Escuchar mensajes entrantes +def on_message(data): + print(f"Recibido: {data}") + + +print("Escuchando eventos en tiempo real... (Presiona Ctrl+C para salir)") +try: + while True: + client.listen(on_message) + time.sleep(1) +except KeyboardInterrupt: + print("\nDesconectando clientes...") + client.disconnect()