File size: 3,368 Bytes
c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 c716b25 e2bb8e8 aae35e2 c716b25 aae35e2 e2bb8e8 c716b25 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | """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)
|