Add suitbuilder backend improvements and SSE streaming fix
- Add dedicated streaming proxy endpoint for real-time suitbuilder SSE updates - Implement stable sorting with character_name and name tiebreakers for deterministic results - Refactor locked items to locked slots supporting set_id and spell constraints - Add Mag-SuitBuilder style branch pruning tracking variables - Enhance search with phase updates and detailed progress logging - Update design document with SSE streaming proxy fix details Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8e70f88de1
commit
e0265e261c
4 changed files with 655 additions and 222 deletions
41
main.py
41
main.py
|
|
@ -18,7 +18,7 @@ import socket
|
|||
import struct
|
||||
|
||||
from fastapi import FastAPI, Header, HTTPException, Query, WebSocket, WebSocketDisconnect, Request
|
||||
from fastapi.responses import JSONResponse, Response
|
||||
from fastapi.responses import JSONResponse, Response, StreamingResponse
|
||||
from fastapi.routing import APIRoute
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
|
@ -2268,13 +2268,50 @@ async def test_inventory_route():
|
|||
"""Test route to verify inventory proxy is working"""
|
||||
return {"message": "Inventory proxy route is working"}
|
||||
|
||||
@app.post("/inv/suitbuilder/search")
|
||||
async def proxy_suitbuilder_search(request: Request):
|
||||
"""Stream suitbuilder search results - SSE requires streaming proxy."""
|
||||
inventory_service_url = os.getenv('INVENTORY_SERVICE_URL', 'http://inventory-service:8000')
|
||||
logger.info(f"Streaming proxy to suitbuilder search")
|
||||
|
||||
# Read body BEFORE creating generator (request context needed)
|
||||
body = await request.body()
|
||||
|
||||
async def stream_response():
|
||||
try:
|
||||
# Use streaming request with long timeout for searches
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(300.0, connect=10.0)) as client:
|
||||
async with client.stream(
|
||||
method="POST",
|
||||
url=f"{inventory_service_url}/suitbuilder/search",
|
||||
content=body,
|
||||
headers={"Content-Type": "application/json"}
|
||||
) as response:
|
||||
async for chunk in response.aiter_bytes():
|
||||
yield chunk
|
||||
except httpx.ReadTimeout:
|
||||
yield b"event: error\ndata: {\"message\": \"Search timeout\"}\n\n"
|
||||
except Exception as e:
|
||||
logger.error(f"Streaming proxy error: {e}")
|
||||
yield f"event: error\ndata: {{\"message\": \"Proxy error: {str(e)}\"}}\n\n".encode()
|
||||
|
||||
return StreamingResponse(
|
||||
stream_response(),
|
||||
media_type="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache",
|
||||
"Connection": "keep-alive",
|
||||
"X-Accel-Buffering": "no" # Disable nginx buffering
|
||||
}
|
||||
)
|
||||
|
||||
@app.api_route("/inv/{path:path}", methods=["GET", "POST"])
|
||||
async def proxy_inventory_service(path: str, request: Request):
|
||||
"""Proxy all inventory service requests"""
|
||||
try:
|
||||
inventory_service_url = os.getenv('INVENTORY_SERVICE_URL', 'http://inventory-service:8000')
|
||||
logger.info(f"Proxying to inventory service: {inventory_service_url}/{path}")
|
||||
|
||||
|
||||
# Forward the request to inventory service (60s timeout for large queries)
|
||||
async with httpx.AsyncClient(timeout=60.0) as client:
|
||||
response = await client.request(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue