Laborator commited on
Commit
5921366
·
1 Parent(s): c685c2c

fix(space): simplified IBM UI - instant Job ID, use recovery panel for results

Browse files
Files changed (1) hide show
  1. app.py +12 -126
app.py CHANGED
@@ -384,153 +384,39 @@ def _final_payload(
384
  }
385
 
386
 
387
- def verify_on_ibm(label: str, mode: str) -> Iterator[dict[str, Any]]:
388
- """Submit the example to IBM and yield progressive status updates.
389
-
390
- First yield: ``status="submitted"`` with the IBM job_id and dashboard
391
- URL. Subsequent yields: ``status="in_progress"`` with the IBM-reported
392
- status and elapsed seconds. Final yield: ``status="completed"`` with
393
- the full verification result, or ``status="timeout"`` if the live
394
- poll loop exceeded :data:`LIVE_POLL_TIMEOUT_SECONDS`, or
395
- ``status="error"`` if something went wrong.
396
- """
397
  if label not in EXAMPLES:
398
- yield {"status": "error", "error": f"unknown example: {label}"}
399
- return
400
  try:
401
  narrow_mode = _coerce_mode(mode)
402
  except ValueError as exc:
403
- yield {"status": "error", "error": str(exc)}
404
- return
405
 
406
  if not IBM_AVAILABLE:
407
- yield {
408
  "status": "error",
409
- "error": (
410
- "IBM_QUANTUM_TOKEN and/or IBM_QUANTUM_INSTANCE are not set "
411
- "in this Space's Secrets. The IBM hardware path is "
412
- "unavailable; use the simulator button."
413
- ),
414
  }
415
- return
416
 
417
  start = time.monotonic()
418
  try:
419
  job, job_id, backend_name, prepared = _prepare_and_submit(label)
420
  except Exception as exc:
421
- yield {
422
- "status": "error",
423
- "error": f"{type(exc).__name__}: {exc}",
424
- }
425
- return
426
 
427
- yield {
 
428
  "status": "submitted",
429
  "ibm_job_id": job_id,
430
  "ibm_job_url": IBM_CONSOLE_BASE + job_id,
431
- "ibm_status": "QUEUED",
432
- "seconds_elapsed": int(time.monotonic() - start),
433
  "backend": backend_name,
434
  "example": label,
435
  "mode": narrow_mode,
436
- "message": (
437
- "Job submitted. Polling every "
438
- f"{POLL_INTERVAL_SECONDS} s for up to "
439
- f"{LIVE_POLL_TIMEOUT_SECONDS // 60} minutes. If your browser "
440
- "loses the live stream before the job finishes, copy the "
441
- "Job ID from this output and use the 'Recover a previous "
442
- "job' panel below."
443
- ),
444
  }
445
-
446
- while True:
447
- elapsed = int(time.monotonic() - start)
448
- if elapsed > LIVE_POLL_TIMEOUT_SECONDS:
449
- yield {
450
- "status": "timeout",
451
- "ibm_job_id": job_id,
452
- "ibm_job_url": IBM_CONSOLE_BASE + job_id,
453
- "seconds_elapsed": elapsed,
454
- "message": (
455
- "Live wait exceeded "
456
- f"{LIVE_POLL_TIMEOUT_SECONDS} s without the job "
457
- "completing. The job is still running on IBM. Use "
458
- "the 'Recover a previous job' panel below with this "
459
- "Job ID once it finishes (typical wall-clock 2-20 "
460
- "minutes for free-tier queue + run)."
461
- ),
462
- }
463
- return
464
-
465
- time.sleep(POLL_INTERVAL_SECONDS)
466
-
467
- try:
468
- ibm_status = str(job.status())
469
- except Exception as exc:
470
- yield {
471
- "status": "error",
472
- "ibm_job_id": job_id,
473
- "ibm_job_url": IBM_CONSOLE_BASE + job_id,
474
- "seconds_elapsed": int(time.monotonic() - start),
475
- "error": f"polling failed: {type(exc).__name__}: {exc}",
476
- }
477
- return
478
-
479
- if ibm_status not in IBM_TERMINAL_STATUSES:
480
- yield {
481
- "status": "in_progress",
482
- "ibm_job_id": job_id,
483
- "ibm_job_url": IBM_CONSOLE_BASE + job_id,
484
- "ibm_status": ibm_status,
485
- "seconds_elapsed": int(time.monotonic() - start),
486
- }
487
- continue
488
-
489
- if ibm_status != "DONE":
490
- yield {
491
- "status": "error",
492
- "ibm_job_id": job_id,
493
- "ibm_job_url": IBM_CONSOLE_BASE + job_id,
494
- "ibm_status": ibm_status,
495
- "seconds_elapsed": int(time.monotonic() - start),
496
- "error": f"IBM job ended with status {ibm_status}",
497
- }
498
- return
499
-
500
- try:
501
- result_obj = job.result()
502
- pub_result = result_obj[0]
503
- raw_counts = pub_result.data.meas.get_counts()
504
- except Exception as exc:
505
- yield {
506
- "status": "error",
507
- "ibm_job_id": job_id,
508
- "ibm_job_url": IBM_CONSOLE_BASE + job_id,
509
- "seconds_elapsed": int(time.monotonic() - start),
510
- "error": f"result fetch failed: {type(exc).__name__}: {exc}",
511
- }
512
- return
513
-
514
- counts = _decode_counts(raw_counts)
515
- verification = _build_verification_result(counts, prepared, backend_name, narrow_mode)
516
- wall = round(time.monotonic() - start, 1)
517
- yield _final_payload(
518
- label, narrow_mode, job_id, backend_name, verification, wall, ibm_status, int(wall)
519
- )
520
- return
521
-
522
-
523
- # --------------------------------------------------------------------------
524
- # Manual recovery path - look up a previous job by ID
525
- # --------------------------------------------------------------------------
526
-
527
-
528
- def check_job_status(job_id: str) -> dict[str, Any]:
529
- """One-shot status query for a job already submitted (live stream lost)."""
530
- job_id = (job_id or "").strip()
531
- if not job_id:
532
- return {"error": "Enter a Job ID first."}
533
-
534
  if not IBM_AVAILABLE:
535
  return {
536
  "error": (
 
384
  }
385
 
386
 
387
+ def verify_on_ibm(label: str, mode: str) -> dict[str, Any]:
388
+ """Submit job to IBM, return Job ID immediately (no polling)."""
 
 
 
 
 
 
 
 
389
  if label not in EXAMPLES:
390
+ return {"status": "error", "error": f"unknown example: {label}"}
391
+
392
  try:
393
  narrow_mode = _coerce_mode(mode)
394
  except ValueError as exc:
395
+ return {"status": "error", "error": str(exc)}
 
396
 
397
  if not IBM_AVAILABLE:
398
+ return {
399
  "status": "error",
400
+ "error": "IBM credentials not configured in Space Secrets.",
 
 
 
 
401
  }
 
402
 
403
  start = time.monotonic()
404
  try:
405
  job, job_id, backend_name, prepared = _prepare_and_submit(label)
406
  except Exception as exc:
407
+ return {"status": "error", "error": f"{type(exc).__name__}: {exc}"}
 
 
 
 
408
 
409
+ elapsed = int(time.monotonic() - start)
410
+ return {
411
  "status": "submitted",
412
  "ibm_job_id": job_id,
413
  "ibm_job_url": IBM_CONSOLE_BASE + job_id,
 
 
414
  "backend": backend_name,
415
  "example": label,
416
  "mode": narrow_mode,
417
+ "seconds_elapsed": elapsed,
418
+ "message": f"Job {job_id} submitted to {backend_name}. Use 'Recover a previous job' panel below with this Job ID to check status.",
 
 
 
 
 
 
419
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  if not IBM_AVAILABLE:
421
  return {
422
  "error": (