Spaces:
Sleeping
Sleeping
| """FastAPI application for PromptGuard environment.""" | |
| import os | |
| from pathlib import Path | |
| from typing import Any, Dict, List, Optional | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from pydantic import BaseModel | |
| from promptguard.models import PromptGuardAction, PromptGuardObservation, PromptGuardState | |
| from promptguard.server.environment import PromptGuardEnvironment | |
| app = FastAPI( | |
| title="PromptGuard", | |
| description="Prompt Injection Defense Environment for OpenEnv", | |
| version="0.1.0", | |
| ) | |
| # Global environment instance | |
| env = PromptGuardEnvironment() | |
| # Dashboard data store | |
| _dashboard_data: Dict[str, Any] = {} | |
| STATIC_DIR = Path(__file__).parent / "static" | |
| class ResetRequest(BaseModel): | |
| task_id: str = "easy" | |
| seed: Optional[int] = None | |
| episode_id: Optional[str] = None | |
| class StepRequest(BaseModel): | |
| system_prompt: str | |
| defense_rules: List[str] = [] | |
| refusal_policy: str = "" | |
| allowed_topics: List[str] = [] | |
| blocked_patterns: List[str] = [] | |
| async def health(): | |
| return {"status": "ok"} | |
| async def reset(request: ResetRequest = None): | |
| try: | |
| if request is None: | |
| request = ResetRequest() | |
| obs = env.reset( | |
| seed=request.seed, | |
| episode_id=request.episode_id, | |
| task_id=request.task_id, | |
| ) | |
| return obs.model_dump() | |
| except Exception as e: | |
| raise HTTPException(status_code=400, detail=str(e)) | |
| async def step(request: StepRequest): | |
| try: | |
| action = PromptGuardAction( | |
| system_prompt=request.system_prompt, | |
| defense_rules=request.defense_rules, | |
| refusal_policy=request.refusal_policy, | |
| allowed_topics=request.allowed_topics, | |
| blocked_patterns=request.blocked_patterns, | |
| ) | |
| obs = await env.step_async(action) | |
| # Update dashboard data | |
| _dashboard_data.update({ | |
| "task_id": env.state.task_id, | |
| "current_step": env.state.current_step, | |
| "score": obs.reward, | |
| "defense_rate": obs.defense_rate, | |
| "utility_rate": obs.utility_rate, | |
| "scores_history": list(env.state.scores_history), | |
| "best_score": env.state.best_score, | |
| "feedback": obs.feedback, | |
| "done": obs.done, | |
| }) | |
| return obs.model_dump() | |
| except RuntimeError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=str(e)) | |
| async def state(): | |
| return env.state.model_dump() | |
| async def dashboard(): | |
| dashboard_path = STATIC_DIR / "dashboard.html" | |
| if not dashboard_path.exists(): | |
| return JSONResponse( | |
| content={"message": "Dashboard not yet available"}, | |
| status_code=404, | |
| ) | |
| return FileResponse(dashboard_path) | |
| async def dashboard_data(): | |
| return _dashboard_data | |
| def main(): | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=8000) | |
| if __name__ == "__main__": | |
| main() | |