fix: close Walloon terrain provisioning
This commit is contained in:
@@ -56,12 +56,27 @@ class SpwTerrainService:
|
||||
def _source_path(settings: Settings) -> Path:
|
||||
return Path(settings.spw_terrain_source_dir) / SpwTerrainService.SOURCE_FILENAME
|
||||
|
||||
@staticmethod
|
||||
def _source_sha256(settings: Settings) -> str | None:
|
||||
checksum_path = (
|
||||
Path(settings.spw_terrain_source_dir)
|
||||
/ SpwTerrainService.SOURCE_SHA256_FILENAME
|
||||
)
|
||||
if not checksum_path.is_file():
|
||||
return None
|
||||
parts = checksum_path.read_text(encoding="ascii").strip().split()
|
||||
digest = parts[0].lower() if parts else ""
|
||||
if len(digest) != 64 or any(character not in "0123456789abcdef" for character in digest):
|
||||
return None
|
||||
return digest
|
||||
|
||||
@staticmethod
|
||||
def list_products(*, settings: Settings | None = None) -> list[dict[str, Any]]:
|
||||
resolved = settings or get_settings()
|
||||
configured = (
|
||||
resolved.spw_terrain_enabled
|
||||
and SpwTerrainService._source_path(resolved).is_file()
|
||||
and SpwTerrainService._source_sha256(resolved) is not None
|
||||
)
|
||||
product = SpwTerrainProductRead(
|
||||
key=SpwTerrainService.PRODUCT_KEY,
|
||||
@@ -338,12 +353,16 @@ class SpwTerrainService:
|
||||
status_code=503,
|
||||
)
|
||||
source_path = SpwTerrainService._source_path(resolved)
|
||||
if not source_path.is_file():
|
||||
source_sha256 = SpwTerrainService._source_sha256(resolved)
|
||||
if not source_path.is_file() or source_sha256 is None:
|
||||
raise AppError(
|
||||
code="SPW_TERRAIN_SOURCE_NOT_PROVISIONED",
|
||||
message="The official SPW MNT source archive has not been provisioned on this runtime",
|
||||
message="The official SPW MNT source and checksum have not been provisioned on this runtime",
|
||||
details={
|
||||
"expected_path": str(source_path),
|
||||
"expected_checksum_path": str(
|
||||
source_path.with_name(SpwTerrainService.SOURCE_SHA256_FILENAME)
|
||||
),
|
||||
"operator_command": "python scripts/provision_spw_terrain_source.py",
|
||||
},
|
||||
status_code=503,
|
||||
@@ -390,14 +409,6 @@ class SpwTerrainService:
|
||||
content, validation = SpwTerrainService._read_source_window(
|
||||
source_path, scope, resolution, resolved
|
||||
)
|
||||
source_sha256_path = source_path.with_name(
|
||||
SpwTerrainService.SOURCE_SHA256_FILENAME
|
||||
)
|
||||
source_sha256 = (
|
||||
source_sha256_path.read_text(encoding="ascii").strip().split()[0]
|
||||
if source_sha256_path.is_file()
|
||||
else None
|
||||
)
|
||||
acquired_at = datetime.now(UTC)
|
||||
dataset = DatasetService.import_raster_bytes(
|
||||
db,
|
||||
@@ -410,7 +421,7 @@ class SpwTerrainService:
|
||||
observed_at=datetime(2022, 3, 5, 23, 59, 59, tzinfo=UTC),
|
||||
valid_from=datetime(2021, 2, 19, tzinfo=UTC),
|
||||
valid_to=datetime(2022, 3, 5, 23, 59, 59, tzinfo=UTC),
|
||||
temporal_granularity="acquisition_period",
|
||||
temporal_granularity="period",
|
||||
source_version="RELIEF_WALLONIE_MNT_1M_2021_2022",
|
||||
source_metadata={
|
||||
"provider": SpwTerrainService.PROVIDER,
|
||||
|
||||
@@ -102,11 +102,23 @@ def make_source(path: Path) -> list[float]:
|
||||
return [min_lon, min_lat, max_lon, max_lat]
|
||||
|
||||
|
||||
def write_source_checksum(source_dir: Path) -> str:
|
||||
digest = "a" * 64
|
||||
(source_dir / SpwTerrainService.SOURCE_SHA256_FILENAME).write_text(
|
||||
f"{digest} {SpwTerrainService.SOURCE_FILENAME}\n", encoding="ascii"
|
||||
)
|
||||
return digest
|
||||
|
||||
|
||||
def test_spw_terrain_registry_reports_real_source_state(tmp_path: Path) -> None:
|
||||
before = SpwTerrainService.list_products(settings=settings(tmp_path))[0]
|
||||
assert before["status"] == "source_not_provisioned"
|
||||
|
||||
make_source(tmp_path / SpwTerrainService.SOURCE_FILENAME)
|
||||
without_checksum = SpwTerrainService.list_products(settings=settings(tmp_path))[0]
|
||||
assert without_checksum["configured"] is False
|
||||
|
||||
write_source_checksum(tmp_path)
|
||||
after = SpwTerrainService.list_products(settings=settings(tmp_path))[0]
|
||||
|
||||
assert after["configured"] is True
|
||||
@@ -119,6 +131,7 @@ def test_spw_terrain_acquisition_persists_bounded_dng_raster_and_provenance(
|
||||
tmp_path: Path, monkeypatch
|
||||
) -> None:
|
||||
bbox = make_source(tmp_path / SpwTerrainService.SOURCE_FILENAME)
|
||||
source_digest = write_source_checksum(tmp_path)
|
||||
project = Project(id=uuid4(), name="Belgium")
|
||||
captured = {}
|
||||
|
||||
@@ -150,6 +163,8 @@ def test_spw_terrain_acquisition_persists_bounded_dng_raster_and_provenance(
|
||||
assert captured["source_metadata"]["vertical_unit_label"] == "m DNG"
|
||||
assert captured["source_metadata"]["coverage_zones"] == ["wallonia"]
|
||||
assert captured["provenance_metadata"]["resampling"] == "bilinear"
|
||||
assert captured["provenance_metadata"]["source_sha256"] == source_digest
|
||||
assert captured["temporal_granularity"] == "period"
|
||||
assert captured["valid_from"].date().isoformat() == "2021-02-19"
|
||||
with rasterio.MemoryFile(captured["content"]) as memory:
|
||||
with memory.open() as derived:
|
||||
|
||||
Reference in New Issue
Block a user