Stream pipeline events via Server-Sent Events (SSE) so the frontend can show real-time progress.
(req: AnalyzeRequest)
| 117 | |
| 118 | @app.post("/analyze/stream") |
| 119 | async def analyze_stream(req: AnalyzeRequest): |
| 120 | """Stream pipeline events via Server-Sent Events (SSE) so the frontend |
| 121 | can show real-time progress.""" |
| 122 | |
| 123 | async def event_generator() -> AsyncGenerator[dict, None]: |
| 124 | initial_state: PipelineState = { |
| 125 | "competitor": req.competitor, |
| 126 | "monitor_urls": req.urls or [], |
| 127 | "previous_hashes": {}, |
| 128 | "changes_detected": [], |
| 129 | "research_results": [], |
| 130 | "comparison_matrix": {}, |
| 131 | "battlecard": {}, |
| 132 | "alerts_sent": [], |
| 133 | "quality_score": 0.0, |
| 134 | "reflexion_count": 0, |
| 135 | "error": None, |
| 136 | } |
| 137 | |
| 138 | try: |
| 139 | async for event in pipeline.astream(initial_state): |
| 140 | for node_name, node_output in event.items(): |
| 141 | yield { |
| 142 | "event": node_name, |
| 143 | "data": json.dumps(node_output, default=str, ensure_ascii=False), |
| 144 | } |
| 145 | except Exception as exc: |
| 146 | yield { |
| 147 | "event": "error", |
| 148 | "data": json.dumps({"error": str(exc)}), |
| 149 | } |
| 150 | |
| 151 | return EventSourceResponse(event_generator()) |
| 152 | |
| 153 | |
| 154 | @app.get("/competitors") |
nothing calls this directly
no test coverage detected