Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- database.py +23 -0
- main.py +28 -4
database.py
CHANGED
|
@@ -462,3 +462,26 @@ def update_job_status(job_id: str, status: str, result: Optional[Dict] = None, e
|
|
| 462 |
return False
|
| 463 |
|
| 464 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
return False
|
| 463 |
|
| 464 |
|
| 465 |
+
|
| 466 |
+
def get_latest_job(username: str) -> Optional[Dict[str, Any]]:
|
| 467 |
+
"""Retrieve the most recent job for a user."""
|
| 468 |
+
conn = get_db_connection()
|
| 469 |
+
c = conn.cursor()
|
| 470 |
+
c.execute('''
|
| 471 |
+
SELECT * FROM jobs
|
| 472 |
+
WHERE username = ?
|
| 473 |
+
ORDER BY created_at DESC
|
| 474 |
+
LIMIT 1
|
| 475 |
+
''', (username,))
|
| 476 |
+
row = c.fetchone()
|
| 477 |
+
conn.close()
|
| 478 |
+
|
| 479 |
+
if row:
|
| 480 |
+
job = dict(row)
|
| 481 |
+
if job['result']:
|
| 482 |
+
try:
|
| 483 |
+
job['result'] = json.loads(job['result'])
|
| 484 |
+
except:
|
| 485 |
+
job['result'] = None
|
| 486 |
+
return job
|
| 487 |
+
return None
|
main.py
CHANGED
|
@@ -1543,15 +1543,39 @@ async def analyze_image(
|
|
| 1543 |
|
| 1544 |
# Enqueue Worker (Pass ID, not bytes)
|
| 1545 |
background_tasks.add_task(process_analysis_job, task_id, request.image_id, current_user.username)
|
| 1546 |
-
|
| 1547 |
-
logger.info(f"Job Created: {task_id} for Image: {request.image_id}")
|
| 1548 |
-
|
| 1549 |
-
return {
|
| 1550 |
"task_id": task_id,
|
| 1551 |
"status": "queued",
|
| 1552 |
"image_id": request.image_id
|
| 1553 |
}
|
| 1554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1555 |
@app.get("/result/{task_id}")
|
| 1556 |
async def get_result(task_id: str, current_user: User = Depends(get_current_user)):
|
| 1557 |
"""
|
|
|
|
| 1543 |
|
| 1544 |
# Enqueue Worker (Pass ID, not bytes)
|
| 1545 |
background_tasks.add_task(process_analysis_job, task_id, request.image_id, current_user.username)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1546 |
"task_id": task_id,
|
| 1547 |
"status": "queued",
|
| 1548 |
"image_id": request.image_id
|
| 1549 |
}
|
| 1550 |
|
| 1551 |
+
@app.get("/job/current")
|
| 1552 |
+
async def get_current_job(current_user: User = Depends(get_current_active_user)):
|
| 1553 |
+
"""
|
| 1554 |
+
Get the latest job state for the user to restore UI on refresh.
|
| 1555 |
+
Returns 404 if no recent job found (< 24h).
|
| 1556 |
+
"""
|
| 1557 |
+
job = database.get_latest_job(current_user.username)
|
| 1558 |
+
if not job:
|
| 1559 |
+
raise HTTPException(status_code=404, detail="No active job")
|
| 1560 |
+
|
| 1561 |
+
# Check if job is stale (e.g. > 24 hours old)
|
| 1562 |
+
# If completed and old, we might not want to auto-load it on fresh login
|
| 1563 |
+
# But for F5 refresh, we definitely want it.
|
| 1564 |
+
# Heuristic: If < 1 hour, always return.
|
| 1565 |
+
|
| 1566 |
+
created_at = job.get('created_at', 0)
|
| 1567 |
+
if time.time() - created_at > 86400: # 24 hours
|
| 1568 |
+
raise HTTPException(status_code=404, detail="Job expired")
|
| 1569 |
+
|
| 1570 |
+
return {
|
| 1571 |
+
"task_id": job['id'],
|
| 1572 |
+
"status": job['status'],
|
| 1573 |
+
"result": job['result'],
|
| 1574 |
+
"error": job.get('error'),
|
| 1575 |
+
"created_at": created_at,
|
| 1576 |
+
"image_id": job.get('storage_path')
|
| 1577 |
+
}
|
| 1578 |
+
|
| 1579 |
@app.get("/result/{task_id}")
|
| 1580 |
async def get_result(task_id: str, current_user: User = Depends(get_current_user)):
|
| 1581 |
"""
|