Spaces:
Sleeping
Sleeping
Commit ·
d6c336d
1
Parent(s): fe69644
fix(api): return queued or failed rows from /extract/url instead of 500
Browse filesSubmitting a URL whose row already existed but was not finished (pending,
processing or failed) returned 500: ExtractionResponse required a full
ReelExtraction and a title, and it dropped status/error. The response
model now matches what the table actually holds, so the dashboard shows
the queue or failure banner for that reel.
Claude-Session: https://claude.ai/code/session_0166W7S7XvHg5P2uyJtP4GiC
- main.py +7 -2
- verify_pipeline.py +21 -0
main.py
CHANGED
|
@@ -160,13 +160,18 @@ class ReelExtraction(BaseModel):
|
|
| 160 |
return str(item).strip()
|
| 161 |
|
| 162 |
class ExtractionResponse(BaseModel):
|
|
|
|
|
|
|
|
|
|
| 163 |
id: Optional[str] = None
|
| 164 |
url: Optional[str] = None
|
| 165 |
-
title: str
|
| 166 |
raw_transcript: Optional[str] = None
|
| 167 |
post_caption: Optional[str] = None
|
| 168 |
-
extracted_json:
|
| 169 |
created_at: Optional[str] = None
|
|
|
|
|
|
|
| 170 |
|
| 171 |
|
| 172 |
def _chat_json(task: str, system_prompt: str, user_prompt: str, parse):
|
|
|
|
| 160 |
return str(item).strip()
|
| 161 |
|
| 162 |
class ExtractionResponse(BaseModel):
|
| 163 |
+
"""A saved reel row. /extract/url can return one that is still queued or
|
| 164 |
+
failed (the URL was already submitted), so only finished rows carry a
|
| 165 |
+
title and a full ReelExtraction in extracted_json."""
|
| 166 |
id: Optional[str] = None
|
| 167 |
url: Optional[str] = None
|
| 168 |
+
title: Optional[str] = None
|
| 169 |
raw_transcript: Optional[str] = None
|
| 170 |
post_caption: Optional[str] = None
|
| 171 |
+
extracted_json: dict
|
| 172 |
created_at: Optional[str] = None
|
| 173 |
+
status: str = "done"
|
| 174 |
+
error: Optional[str] = None
|
| 175 |
|
| 176 |
|
| 177 |
def _chat_json(task: str, system_prompt: str, user_prompt: str, parse):
|
verify_pipeline.py
CHANGED
|
@@ -167,6 +167,26 @@ def test_extract_url_regression():
|
|
| 167 |
main.db.get_reel_by_url = orig_cache
|
| 168 |
|
| 169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
def test_worker_tick_success():
|
| 171 |
print("Testing worker_tick processes a pending reel (mocked)...")
|
| 172 |
import main
|
|
@@ -701,6 +721,7 @@ if __name__ == "__main__":
|
|
| 701 |
test_worker_tick_empty()
|
| 702 |
test_run_worker_drain()
|
| 703 |
test_extract_url_regression()
|
|
|
|
| 704 |
test_delete_reel()
|
| 705 |
test_get_reel_details()
|
| 706 |
test_reels_include_cluster()
|
|
|
|
| 167 |
main.db.get_reel_by_url = orig_cache
|
| 168 |
|
| 169 |
|
| 170 |
+
def test_extract_url_returns_unfinished_row():
|
| 171 |
+
print("Testing POST /extract/url returns an already-queued or failed row instead of 500...")
|
| 172 |
+
import main
|
| 173 |
+
orig = main.db.get_reel_by_url
|
| 174 |
+
try:
|
| 175 |
+
# title is None for rows the iPhone Shortcut inserts over REST
|
| 176 |
+
for status, title, error in (("pending", None, None), ("failed", "Reel (Q)", "Meta blocking request")):
|
| 177 |
+
main.db.get_reel_by_url = lambda url: {
|
| 178 |
+
"id": "row-q", "url": url, "title": title, "raw_transcript": "", "post_caption": None,
|
| 179 |
+
"extracted_json": {}, "created_at": "2026-10-10T00:00:00Z", "cluster": "Unclustered",
|
| 180 |
+
"status": status, "error": error}
|
| 181 |
+
r = client.post("/extract/url", json={"url": "https://www.instagram.com/reel/QUEUED1/"})
|
| 182 |
+
assert r.status_code == 200, r.text
|
| 183 |
+
assert r.json()["status"] == status, r.json()
|
| 184 |
+
assert r.json()["error"] == error, r.json()
|
| 185 |
+
print("[OK] extract_url unfinished-row passthrough passed!")
|
| 186 |
+
finally:
|
| 187 |
+
main.db.get_reel_by_url = orig
|
| 188 |
+
|
| 189 |
+
|
| 190 |
def test_worker_tick_success():
|
| 191 |
print("Testing worker_tick processes a pending reel (mocked)...")
|
| 192 |
import main
|
|
|
|
| 721 |
test_worker_tick_empty()
|
| 722 |
test_run_worker_drain()
|
| 723 |
test_extract_url_regression()
|
| 724 |
+
test_extract_url_returns_unfinished_row()
|
| 725 |
test_delete_reel()
|
| 726 |
test_get_reel_details()
|
| 727 |
test_reels_include_cluster()
|