Download src/api/feedback.py from nikeshn/LibBee: direct link, hf CLI and curl.
- Browser
- Download file 1.71 kB
-
https://huggingface.co/spaces/nikeshn/LibBee/resolve/main/src/api/feedback.py
- Command line
-
hf download hf://spaces/nikeshn/LibBee/src/api/feedback.py
-
curl -L -o feedback.py https://huggingface.co/spaces/nikeshn/LibBee/resolve/main/src/api/feedback.py
1.71 kB
| import json | |
| import time | |
| import re | |
| from fastapi import APIRouter | |
| from pydantic import BaseModel, ConfigDict, Field, field_validator | |
| from src.config import get_settings | |
| router = APIRouter() | |
| class FeedbackRequest(BaseModel): | |
| model_config = ConfigDict(extra="forbid") | |
| request_id: str = Field(pattern=r"^[A-Za-z0-9_-]{8,80}$") | |
| feedback: str | |
| comment: str = Field(default="", max_length=500) | |
| # The existing LibGuides client sends this field to its Worker. Accept it | |
| # if forwarded, but do not store it in the local feedback fallback. | |
| session_id: str | None = Field(default=None, pattern=r"^[A-Za-z0-9_-]{8,80}$") | |
| def valid_feedback(cls, v: str) -> str: | |
| if v not in {"up", "down"}: | |
| raise ValueError("feedback must be up or down") | |
| return v | |
| async def save_feedback(req: FeedbackRequest): | |
| settings = get_settings() | |
| comment = re.sub(r"[\w.+-]+@[\w-]+\.[\w.-]+", "[email]", req.comment) | |
| comment = re.sub(r"\b\d{6,}\b", "[number]", comment) | |
| payload = { | |
| "timestamp": time.time(), | |
| "request_id": req.request_id, | |
| "feedback": req.feedback, | |
| "comment": comment[:500], | |
| } | |
| settings.feedback_path.parent.mkdir(parents=True, exist_ok=True) | |
| with settings.feedback_path.open("a", encoding="utf-8") as handle: | |
| handle.write(json.dumps(payload, ensure_ascii=False) + "\n") | |
| try: | |
| from app import metrics_service | |
| metrics_service.incr("feedback_total") | |
| metrics_service.incr_bucket("feedback_breakdown", req.feedback) | |
| except Exception: | |
| pass | |
| return {"status": "ok"} | |