Spaces:
Paused
Paused
Update main.py
Browse files
main.py
CHANGED
|
@@ -435,8 +435,8 @@ def get_leads():
|
|
| 435 |
@with_db_retry
|
| 436 |
def object_detail(object_id: int):
|
| 437 |
with cursor() as cur:
|
| 438 |
-
#
|
| 439 |
-
cur.execute("SELECT *, image_url FROM objects WHERE object_id=%s", (object_id,))
|
| 440 |
obj = cur.fetchone()
|
| 441 |
if not obj:
|
| 442 |
return jsonify({"ok": False, "error": "not_found"}), 404
|
|
@@ -455,8 +455,8 @@ def object_detail(object_id: int):
|
|
| 455 |
@with_db_retry
|
| 456 |
def graph(object_id: int):
|
| 457 |
with cursor() as cur:
|
| 458 |
-
#
|
| 459 |
-
cur.execute("SELECT object_id, source, title FROM objects WHERE object_id=%s", (object_id,))
|
| 460 |
obj = cur.fetchone()
|
| 461 |
if not obj:
|
| 462 |
return jsonify({"ok": False, "error": "not_found"}), 404
|
|
@@ -471,15 +471,18 @@ def graph(object_id: int):
|
|
| 471 |
@with_db_retry
|
| 472 |
def timeline(object_id: int):
|
| 473 |
with cursor() as cur:
|
| 474 |
-
#
|
| 475 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 476 |
cur.execute("SELECT seq, sentence FROM provenance_sentences WHERE object_id=%s ORDER BY seq", (object_id,))
|
| 477 |
sents = cur.fetchall()
|
| 478 |
cur.execute("""SELECT event_type, date_from, date_to, place, actor, source_ref
|
| 479 |
FROM provenance_events WHERE object_id=%s
|
| 480 |
ORDER BY COALESCE(date_from,'0001-01-01')""", (object_id,))
|
| 481 |
events = cur.fetchall()
|
| 482 |
-
|
| 483 |
items = build_timeline_from_events_and_sentences(events, sents)
|
| 484 |
return jsonify({"ok": True, "items": items})
|
| 485 |
|
|
@@ -558,7 +561,7 @@ def similar_search():
|
|
| 558 |
rows = cur.fetchall()
|
| 559 |
return jsonify({"ok": True, "device": _DEVICE_INFO, "query": text, "data": rows,
|
| 560 |
"meta": {"limit": limit, "candidates": candidates, "source": source_filter or None}})
|
| 561 |
-
except OperationalError as
|
| 562 |
# TiDB OOM (1105) → retry with smaller candidate set automatically
|
| 563 |
if e.args and e.args[0] == 1105 and candidates > max(100, limit * 4):
|
| 564 |
smaller = max(100, limit * 4)
|
|
@@ -603,7 +606,8 @@ def vocab():
|
|
| 603 |
def explain_object(object_id: int):
|
| 604 |
"""Generate a concise, policy-aware research note for an object."""
|
| 605 |
with cursor() as cur:
|
| 606 |
-
|
|
|
|
| 607 |
obj = cur.fetchone()
|
| 608 |
if not obj:
|
| 609 |
return jsonify({"ok": False, "error": "not_found"}), 404
|
|
|
|
| 435 |
@with_db_retry
|
| 436 |
def object_detail(object_id: int):
|
| 437 |
with cursor() as cur:
|
| 438 |
+
# Enforce that object must have an image_url to be seen
|
| 439 |
+
cur.execute("SELECT *, image_url FROM objects WHERE object_id=%s AND image_url IS NOT NULL AND image_url != ''", (object_id,))
|
| 440 |
obj = cur.fetchone()
|
| 441 |
if not obj:
|
| 442 |
return jsonify({"ok": False, "error": "not_found"}), 404
|
|
|
|
| 455 |
@with_db_retry
|
| 456 |
def graph(object_id: int):
|
| 457 |
with cursor() as cur:
|
| 458 |
+
# Enforce that object must have an image_url to be seen
|
| 459 |
+
cur.execute("SELECT object_id, source, title FROM objects WHERE object_id=%s AND image_url IS NOT NULL AND image_url != ''", (object_id,))
|
| 460 |
obj = cur.fetchone()
|
| 461 |
if not obj:
|
| 462 |
return jsonify({"ok": False, "error": "not_found"}), 404
|
|
|
|
| 471 |
@with_db_retry
|
| 472 |
def timeline(object_id: int):
|
| 473 |
with cursor() as cur:
|
| 474 |
+
# First, check if the object exists AND has an image. This enforces the rule.
|
| 475 |
+
cur.execute("SELECT object_id FROM objects WHERE object_id=%s AND image_url IS NOT NULL AND image_url != ''", (object_id,))
|
| 476 |
+
if not cur.fetchone():
|
| 477 |
+
return jsonify({"ok": False, "error": "not_found"}), 404
|
| 478 |
+
|
| 479 |
+
# If the check passes, proceed to get its data
|
| 480 |
cur.execute("SELECT seq, sentence FROM provenance_sentences WHERE object_id=%s ORDER BY seq", (object_id,))
|
| 481 |
sents = cur.fetchall()
|
| 482 |
cur.execute("""SELECT event_type, date_from, date_to, place, actor, source_ref
|
| 483 |
FROM provenance_events WHERE object_id=%s
|
| 484 |
ORDER BY COALESCE(date_from,'0001-01-01')""", (object_id,))
|
| 485 |
events = cur.fetchall()
|
|
|
|
| 486 |
items = build_timeline_from_events_and_sentences(events, sents)
|
| 487 |
return jsonify({"ok": True, "items": items})
|
| 488 |
|
|
|
|
| 561 |
rows = cur.fetchall()
|
| 562 |
return jsonify({"ok": True, "device": _DEVICE_INFO, "query": text, "data": rows,
|
| 563 |
"meta": {"limit": limit, "candidates": candidates, "source": source_filter or None}})
|
| 564 |
+
except OperationalError as.e:
|
| 565 |
# TiDB OOM (1105) → retry with smaller candidate set automatically
|
| 566 |
if e.args and e.args[0] == 1105 and candidates > max(100, limit * 4):
|
| 567 |
smaller = max(100, limit * 4)
|
|
|
|
| 606 |
def explain_object(object_id: int):
|
| 607 |
"""Generate a concise, policy-aware research note for an object."""
|
| 608 |
with cursor() as cur:
|
| 609 |
+
# Enforce that object must have an image_url to be seen
|
| 610 |
+
cur.execute("SELECT object_id, source, title, creator, date_display, risk_score FROM objects WHERE object_id=%s AND image_url IS NOT NULL AND image_url != ''", (object_id,))
|
| 611 |
obj = cur.fetchone()
|
| 612 |
if not obj:
|
| 613 |
return jsonify({"ok": False, "error": "not_found"}), 404
|