EmmaScharfmann HF Staff
Add type filter to Pending/History tabs; review feedback.jsonl alongside requests.jsonl
c716b25 | """Submissions queue backed by the existing hugging-science/feedback HF Dataset. | |
| `requests.jsonl` holds every non-"feedback" type (dataset/model/organization/ | |
| blog/challenge/collaboration); `feedback.jsonl` holds "feedback". Both are | |
| written by the feedback-api Space's /submit endpoint. Ingestion happens | |
| there, not here — this module only reads those files and updates a row's | |
| status when the reviewer approves/rejects/acknowledges it. | |
| """ | |
| import json | |
| import threading | |
| from datetime import datetime, timezone | |
| from huggingface_hub import HfApi | |
| from huggingface_hub.utils import EntryNotFoundError | |
| from about import DATASET_REPO, FEEDBACK_FILE, REQUESTS_FILE, TOKEN | |
| _api = HfApi(token=TOKEN) | |
| _lock = threading.Lock() | |
| ALL_FILES = (REQUESTS_FILE, FEEDBACK_FILE) | |
| def _now() -> str: | |
| return datetime.now(timezone.utc).isoformat() | |
| def _read_file(filename: str) -> list[dict]: | |
| try: | |
| path = _api.hf_hub_download( | |
| repo_id=DATASET_REPO, repo_type="dataset", filename=filename | |
| ) | |
| except EntryNotFoundError: | |
| return [] | |
| with open(path, encoding="utf-8") as f: | |
| return [json.loads(line) for line in f if line.strip()] | |
| def _write_file(filename: str, rows: list[dict]) -> None: | |
| content = "\n".join(json.dumps(row) for row in rows) + "\n" | |
| _api.upload_file( | |
| path_or_fileobj=content.encode("utf-8"), | |
| path_in_repo=filename, | |
| repo_id=DATASET_REPO, | |
| repo_type="dataset", | |
| commit_message="Update requests queue", | |
| ) | |
| def _read_all() -> list[dict]: | |
| return [row for filename in ALL_FILES for row in _read_file(filename)] | |
| def list_submissions(status: str | None = None, type_: str | None = None) -> list[dict]: | |
| rows = _read_all() | |
| if status is not None: | |
| rows = [r for r in rows if r["status"] == status] | |
| if type_ is not None: | |
| rows = [r for r in rows if r["type"] == type_] | |
| return rows | |
| def get_submission(submission_id: str) -> dict | None: | |
| for row in _read_all(): | |
| if row["id"] == submission_id: | |
| return row | |
| return None | |
| def _update_row(submission_id: str, mutate_fn) -> None: | |
| """Find `submission_id` in whichever file its type lives in, mutate it in | |
| place, and rewrite only that file.""" | |
| with _lock: | |
| for filename in ALL_FILES: | |
| rows = _read_file(filename) | |
| for row in rows: | |
| if row["id"] == submission_id: | |
| mutate_fn(row) | |
| _write_file(filename, rows) | |
| return | |
| def mark_approved(submission_id: str, pr_url: str) -> None: | |
| def mutate(row): | |
| row["status"] = "approved" | |
| row["reviewed_at"] = _now() | |
| row["pr_url"] = pr_url | |
| _update_row(submission_id, mutate) | |
| def mark_acknowledged(submission_id: str) -> None: | |
| """For non-PR types (feedback, collaboration, challenge): close out a | |
| submission without opening a PR — e.g. once it's been read or the | |
| requester has been emailed.""" | |
| def mutate(row): | |
| row["status"] = "acknowledged" | |
| row["reviewed_at"] = _now() | |
| _update_row(submission_id, mutate) | |
| def mark_rejected(submission_id: str, reason: str | None) -> None: | |
| def mutate(row): | |
| row["status"] = "rejected" | |
| row["reviewed_at"] = _now() | |
| row["reject_reason"] = reason | |
| _update_row(submission_id, mutate) | |