Download app/controllers/ask.py from hari7775/fsconvo: direct link, hf CLI and curl.
- Browser
- Download file 5.13 kB
-
https://huggingface.co/spaces/hari7775/fsconvo/resolve/main/app/controllers/ask.py
- Command line
-
hf download hf://spaces/hari7775/fsconvo/app/controllers/ask.py
-
curl -L -o ask.py https://huggingface.co/spaces/hari7775/fsconvo/resolve/main/app/controllers/ask.py
5.13 kB
| import asyncio | |
| import json | |
| import logging | |
| from typing import Optional | |
| from fastapi import APIRouter, HTTPException | |
| from fastapi.responses import StreamingResponse | |
| from pydantic import BaseModel | |
| from app.service.rag_pipeline import get_answer_from_rag, get_answer_stream_from_rag | |
| from app.service.session_manager import session_manager | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter( | |
| prefix="/api", | |
| tags=["Ask"] | |
| ) | |
| class AskQuestionRequest(BaseModel): | |
| question: str | |
| context: Optional[str] = None | |
| session_id: Optional[str] = None | |
| model: Optional[str] = None | |
| stream: Optional[bool] = False | |
| use_rag: Optional[bool] = None | |
| class StopAskRequest(BaseModel): | |
| session_id: Optional[str] = None | |
| async def ask_question_stream(request: AskQuestionRequest): | |
| """ | |
| Stream tokens in real-time using Server-Sent Events (SSE). | |
| """ | |
| session_id = (request.session_id or "default").strip() | |
| current_task = asyncio.current_task() | |
| if current_task: | |
| session_manager.register_task(session_id, current_task) | |
| logger.info( | |
| f"[ask-stream] session_id={session_id!r} " | |
| f"model={request.model!r} " | |
| f"use_rag={request.use_rag!r} " | |
| f"question={request.question[:80]!r}" | |
| ) | |
| def event_stream(): | |
| try: | |
| for token in get_answer_stream_from_rag( | |
| question=request.question, | |
| context=request.context, | |
| session_id=session_id, | |
| model=request.model, | |
| use_rag=request.use_rag, | |
| ): | |
| payload = json.dumps({"token": token}) | |
| yield f"data: {payload}\n\n" | |
| yield "data: [DONE]\n\n" | |
| except asyncio.CancelledError: | |
| logger.info(f"[ask-stream] Cancelled for session '{session_id}'.") | |
| err_payload = json.dumps({"error": f"Generation stopped for session '{session_id}'."}) | |
| yield f"data: {err_payload}\n\n" | |
| except Exception as e: | |
| logger.error(f"[ask-stream] error: {e}") | |
| err_payload = json.dumps({"error": str(e)}) | |
| yield f"data: {err_payload}\n\n" | |
| finally: | |
| if current_task: | |
| session_manager.unregister_task(session_id, current_task) | |
| return StreamingResponse( | |
| event_stream(), | |
| media_type="text/event-stream", | |
| headers={ | |
| "Cache-Control": "no-cache", | |
| "Connection": "keep-alive", | |
| "X-Accel-Buffering": "no", | |
| } | |
| ) | |
| async def ask_question(request: AskQuestionRequest): | |
| if request.stream: | |
| return await ask_question_stream(request) | |
| session_id = (request.session_id or "default").strip() | |
| current_task = asyncio.current_task() | |
| if current_task: | |
| session_manager.register_task(session_id, current_task) | |
| try: | |
| logger.info( | |
| f"[ask] session_id={session_id!r} " | |
| f"model={request.model!r} " | |
| f"use_rag={request.use_rag!r} " | |
| f"question={request.question[:80]!r}" | |
| ) | |
| answer = get_answer_from_rag( | |
| question=request.question, | |
| context=request.context, | |
| session_id=session_id, | |
| model=request.model, | |
| use_rag=request.use_rag, | |
| ) | |
| logger.info( | |
| f"[ask] answer preview: {str(answer)[:120]!r}" | |
| ) | |
| return { | |
| "status": "success", | |
| "answer": answer, | |
| } | |
| except asyncio.CancelledError: | |
| logger.info(f"[ask] Generation stopped for session '{session_id}'.") | |
| raise HTTPException( | |
| status_code=499, | |
| detail=f"Generation terminated for session '{session_id}'." | |
| ) | |
| except Exception as e: | |
| logger.error(f"[ask] error: {e}") | |
| raise HTTPException( | |
| status_code=500, | |
| detail=str(e) | |
| ) | |
| finally: | |
| if current_task: | |
| session_manager.unregister_task(session_id, current_task) | |
| async def stop_ask( | |
| request: Optional[StopAskRequest] = None, | |
| session_id: Optional[str] = None, | |
| ): | |
| """ | |
| Cancel active model generation task(s). | |
| If session_id is provided, only halts that specific session. | |
| """ | |
| target_id = (request.session_id if request else None) or session_id | |
| if target_id: | |
| target_id = target_id.strip() | |
| terminated = session_manager.terminate_session(target_id) | |
| logger.info(f"[ask] Stop signal for session '{target_id}' (terminated={terminated}).") | |
| return { | |
| "status": "success", | |
| "session_id": target_id, | |
| "terminated": terminated, | |
| "message": ( | |
| f"Generation for session '{target_id}' stopped." | |
| if terminated | |
| else f"No active generation running for session '{target_id}'." | |
| ), | |
| } | |
| count = session_manager.terminate_all() | |
| return { | |
| "status": "success", | |
| "message": f"Stopped {count} active generation(s).", | |
| "stopped_count": count, | |
| } |