hls2: enumerate granules by _stac.json instead of the .jpg browse image - #378
Merged
Conversation
added 2 commits
August 4, 2026 18:46
LP DAAC stopped publishing the .jpg browse image for HLSS30 granules between 2026-06-16 and 2026-06-18. Confirmed against NASA CMR (8 granules sampled per day): 8/8 have a .jpg on 06-16, 0/8 from 06-18 onward. HLSL30 is unaffected and still publishes one. Both hls2 collections discovered source granules with `chunk_options.ends_with: .jpg`, so every post-cutover S30 granule became invisible to enumeration: never chunked, never turned into an item, never ingested. hls2-s30 has had no new STAC items since 2026-06-16 (~7 weeks) while hls2-l30 stayed current. Switch enumeration to _stac.json, which is present on every granule for both products, and rework create_item accordingly: - derive the granule base path from the _stac.json suffix rather than string-replacing '.jpg' - treat the browse image as optional: set the thumbnail href only when the .jpg actually exists, otherwise drop the asset - collapse the duplicated S30/L30 asset-verification branches - iterate over list(item.assets) when popping, which previously mutated the dict during iteration Tests updated to pass _stac.json URIs, plus a new case covering a post-cutover S30 granule that has no browse image. All 3 pass against production blob storage.
Wrap the regex, add noqa/spacing on the new test, and add the missing trailing newline. Pre-existing violations elsewhere in these files are left alone to keep the diff focused: datasets/hls2 goes from 11 flake8 violations on main to 7 with this PR.
Gustavo Hidalgo (ghidalgo3)
approved these changes
Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
hls2-s30stopped receiving new STAC items on 2026-06-16 and was ~7 weeks stale when this was found.hls2-l30was unaffected.Root cause is upstream. LP DAAC stopped publishing the
.jpgbrowse image for HLSS30 granules between 2026-06-16 and 2026-06-18. Confirmed against NASA CMR (8 granules sampled per day):.jpgHLSL30 still publishes one, which is why
hls2-l30stayed healthy.Both hls2 collections discovered source granules with
chunk_options.ends_with: .jpg, so every post-cutover S30 granule became invisible to enumeration — never chunked, never turned into an item, never ingested. A representative granule:20 files present, no
.jpg. The corresponding chunk list contained 161 rows, every one a.jpgunder2026/06.Change
Switch enumeration to
_stac.json, which is present on every granule for both products, and reworkcreate_itemaccordingly:_stac.jsonsuffix rather than string-replacing.jpgthumbnailhref only when the.jpgactually exists, otherwise drop the assetlist(item.assets)when popping, which previously mutated the dict during iterationDependencies / related
.jpgfromHLS2Scene.blob_namesfor S30, soassets_exist()can returnTrueagain (it requires every listed asset, so S30 granules were being treated as permanently incomplete).hls2-ingestion-pipelineAirflow DAG fetchesdataset.yamlandhls2.pyfrommainat parse time, so merging this is sufficient there — no image rebuild.hls2-s30-update/hls2-l30-updateworkflows must be re-registered (pctasks dataset process-items ... --upsert) after merge:ends_withand thehls2.pycode-blob hash are both baked in at registration time.Fixes # (no issue filed)
Type of change
Behaviour note: items for S30 granules produced after the upstream cutover no longer carry a
thumbnailasset, because the source image no longer exists. Existing items are unaffected.How Has This Been Tested?
datasets/hls2/test_hls2.py, run against production blob storage — 3 passed:test_hls2_landsat— existing L30 granule, updated to a_stac.jsonasset URI; still yields 16 assets includingthumbnailtest_hls2_sentinel— existing pre-cutover S30 granule (2025-01-05); still yields 19 assets includingthumbnailtest_hls2_sentinel_without_browse_image— new, a post-cutover S30 granule (HLS.S30.T06WXC.2026213T212519.v2.0, 2026-08-01) that has no.jpg; yields 18 assets, nothumbnail, and passesitem.validate()The third test is the direct regression test for this bug: on
mainthat granule cannot be enumerated at all.Checklist:
dataset.yamland the inline comments inhls2.pyexplain why enumeration keys on_stac.jsonpytest datasets/hls2/test_hls2.py(3 passed)../scripts/testwas not run because it requires Docker, which is unavailable in this environmentflake8 datasets/hls2/goes from 11 violations onmainto 7 with this PR; the 7 remaining are pre-existing and untouched (longS30_assets/L30_assetsliterals,E302on existing definitions).blackwould reformat these files, but it also reformats them onmain, so it is left alone to keep the diff reviewable"Changelog has been updated" deleted — this repo has no changelog and dataset changes do not use one.