|
37 | 37 | "get_raw_path", |
38 | 38 | ] |
39 | 39 |
|
40 | | -import json |
41 | 40 | import logging |
42 | 41 | import os |
43 | 42 | import re |
44 | 43 | import time |
45 | 44 | import urllib.parse |
46 | 45 |
|
| 46 | +import botocore.exceptions |
| 47 | +import pydantic_core |
47 | 48 | import requests |
48 | 49 |
|
49 | 50 | from lsst.obs.lsst import LsstCam, LsstCamImSim, LsstComCam, LsstComCamSim |
50 | 51 | from lsst.obs.lsst.translators.lsst import LsstBaseTranslator |
51 | 52 | from lsst.resources import ResourcePath |
52 | 53 |
|
| 54 | +from .connect_utils import retry |
53 | 55 | from .visit import FannedOutVisit |
54 | 56 |
|
55 | 57 | _log = logging.getLogger("lsst." + __name__) |
@@ -387,19 +389,38 @@ def get_group_id_from_oid(oid: str) -> str: |
387 | 389 | oid.removesuffix(m["extension"]) |
388 | 390 | + ".json" |
389 | 391 | ) |
390 | | - # Wait a bit but not too long for the file. |
391 | | - # It should normally show up before the image. |
392 | | - count = 0 |
393 | | - while not sidecar.exists(): |
394 | | - count += 1 |
395 | | - if count > 20: |
396 | | - raise RuntimeError(f"Unable to retrieve JSON sidecar: {sidecar}") |
397 | | - time.sleep(0.1) |
| 392 | + group_id = _get_group_id_from_sidecar(sidecar) |
| 393 | + return group_id |
| 394 | + |
| 395 | + |
| 396 | +@retry(4, botocore.exceptions.ClientError, wait=5) |
| 397 | +def _get_group_id_from_sidecar(sidecar): |
| 398 | + """Read the group id from a sidecar JSON file. |
398 | 399 |
|
399 | | - with sidecar.open("r") as f: |
400 | | - md = json.load(f) |
| 400 | + The sidecar file normally show up before the image. If not present, wait a |
| 401 | + bit but not too long for the file. Sometimes, the object store gives other |
| 402 | + transient ClientErrors, which are retried in a longer timescale. |
| 403 | +
|
| 404 | + Parameters |
| 405 | + ---------- |
| 406 | + sidecar : `lsst.resources.ResourcePath` |
| 407 | + URI to a sidecar JSON file. |
401 | 408 |
|
402 | | - return md.get("GROUPID", "") |
| 409 | + Returns |
| 410 | + ------- |
| 411 | + group_id : `str` |
| 412 | + The group identifier as a string. |
| 413 | + """ |
| 414 | + count = 0 |
| 415 | + while count <= 20: |
| 416 | + try: |
| 417 | + md = pydantic_core.from_json(sidecar.read()) |
| 418 | + return md.get("GROUPID", "") |
| 419 | + # If no such sidecar exists, a FileNotFoundError is raised. |
| 420 | + except FileNotFoundError: |
| 421 | + count += 1 |
| 422 | + time.sleep(0.1) |
| 423 | + raise RuntimeError(f"Unable to retrieve JSON sidecar: {sidecar}") |
403 | 424 |
|
404 | 425 |
|
405 | 426 | def get_raw_path(instrument, detector, group, snap, exposure_id, physical_filter): |
|
0 commit comments