From 438304cfce46b05765f1fdbc9859cd95de5aff05 Mon Sep 17 00:00:00 2001 From: King Matthew Ochoa Date: Sat, 5 Jul 2025 21:24:33 +0800 Subject: [PATCH] init push --- main.py | 113 +++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 25 +++++++++++ 2 files changed, 138 insertions(+) create mode 100644 main.py create mode 100644 requirements.txt diff --git a/main.py b/main.py new file mode 100644 index 0000000..472e0f4 --- /dev/null +++ b/main.py @@ -0,0 +1,113 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel, Field +import boto3 +import os +import asyncio +from fastapi.responses import StreamingResponse +from botocore.exceptions import ClientError + +import time + +app = FastAPI() + +bots_config = { + "dronebot": { + "agent_id": "1", + "agent_alias": "1" + }, + "trainerbot": { + "agent_id": "1", + "agent_alias": "1" + }, + "checkinbot": { + "agent_id": "1", + "agent_alias": "1" + } +} +ssm = boto3.client("ssm", 'us-east-1') + + +async def fetch_agent_parameters(): + while True: + for i in ['trainerbot', 'dronebot', 'checkinbot']: + bot_key = i + try: + alias_param = f"/{bot_key}/agentalias" + response = ssm.get_parameter(Name=alias_param, WithDecryption=True) + bots_config[bot_key]["agent_alias"] = response['Parameter']['Value'] + except ClientError as e: + print(f"Error fetching {alias_param}: {e}") + bots_config[bot_key]["agent_alias"] = "1" # fallback + + try: + id_param = f"/{bot_key}/agentid" + response = ssm.get_parameter(Name=id_param, WithDecryption=True) + bots_config[bot_key]["agent_id"] = response['Parameter']['Value'] + except ClientError as e: + print(f"Error fetching {id_param}: {e}") + bots_config[bot_key]["agent_id"] = "1" # fallback + + print("Updated from SSM —") + for bot_key, config in bots_config.items(): + print(f"{bot_key.upper()} → ID: {config['agent_id']}, Alias: {config['agent_alias']}") + + await asyncio.sleep(60) + + +@app.on_event("startup") +async def startup_event(): + asyncio.create_task(fetch_agent_parameters()) + +# Define request body +class BedrockRequest(BaseModel): + question: str + requestSessionId: str = 'user' + bot: str = 'dronebot' + +# AWS Bedrock client setup +def get_bedrock_client(): + return boto3.client( + 'bedrock-agent-runtime', + region_name='us-east-1' + ) + +@app.get("/health") +def health_check(): + return {"message": "OK"} + +@app.post("/bedrock-agent") +def call_bedrock_agent(payload: BedrockRequest): + bot_alias = bots_config[payload.bot]['agent_alias'] + bot_id = bots_config[payload.bot]['agent_id'] + client = get_bedrock_client() + print(payload) + try: + response_stream = client.invoke_agent( + sessionId=payload.requestSessionId + bot_id + bot_alias, + agentId=bot_id, + agentAliasId = bot_alias, + inputText=payload.question, + ) + + def event_stream(): + for event in response_stream["completion"]: + if "chunk" in event: + # Decode bytes to string if needed + chunk_bytes = event["chunk"].get("bytes") + if chunk_bytes: + yield chunk_bytes.decode("utf-8") + else: + yield event["chunk"].get("text", "") + + return StreamingResponse(event_stream(), media_type="text/plain") + except Exception as e: + print(e) + raise HTTPException(status_code=500, detail=str(e)) + +@app.get("/test-stream") +def test_stream(): + def generator(): + for i in range(5): + yield f"Chunk {i}\n" + time.sleep(1) + return StreamingResponse(generator(), media_type="text/plain") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c5e3003 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,25 @@ +annotated-types==0.7.0 +anyio==4.9.0 +boto3==1.38.32 +botocore==1.38.32 +certifi==2025.4.26 +charset-normalizer==3.4.2 +click==8.2.1 +fastapi==0.115.12 +gunicorn==23.0.0 +h11==0.16.0 +idna==3.10 +jmespath==1.0.1 +packaging==25.0 +pydantic==2.11.5 +pydantic_core==2.33.2 +python-dateutil==2.9.0.post0 +requests==2.32.3 +s3transfer==0.13.0 +six==1.17.0 +sniffio==1.3.1 +starlette==0.46.2 +typing-inspection==0.4.1 +typing_extensions==4.14.0 +urllib3==2.4.0 +uvicorn==0.34.3 \ No newline at end of file