Split webapp for Raspberry Pi deployment, remote generation API and sync

La webapp (carte + vignettes) et la génération de tuiles se déploient sur
deux machines : image légère Dockerfile.webapp (FastAPI + Pillow AVIF
natif + pyproj) sur Raspberry Pi, pipeline complet sur la machine de
traitement. LIDAR_GENERATION_URL délègue /api/generate, /api/preview et
/api/status ; /api/sync ramène les tuiles par rsync puis régénère
vignettes et index localement. Token partagé optionnel
(LIDAR_API_TOKEN/LIDAR_REMOTE_TOKEN). Retire du dépôt les journaux
internes (.swival, audit-findings) et les données (data/, notebooks/).
Doc : docs/DEPLOY_WEBAPP.md.
This commit is contained in:
Antoine Jacquin
2026-09-02 19:44:39 +02:00
parent ed3e90ea89
commit 422f58d772
24 changed files with 2390 additions and 329 deletions

View File

@ -20,9 +20,9 @@ class TestVizSteps:
assert len(names) == len(set(names)), "VIZ_STEPS has duplicate names"
def test_expected_visualization_count(self):
"""Should have 16 visualizations (14 terrain + ortho + topo)."""
"""Should have 15 visualizations (13 terrain + ortho + topo)."""
from lidar_pipeline.pipeline import VIZ_STEPS
assert len(VIZ_STEPS) == 16
assert len(VIZ_STEPS) == 15
def test_ortho_and_topo_present(self):
from lidar_pipeline.pipeline import VIZ_STEPS
@ -49,6 +49,29 @@ class TestLidarArchaeoPipeline:
with pytest.raises(ValueError, match="introuvable"):
LidarArchaeoPipeline("/nonexistent/path", str(tmp_path / "output"))
def test_incremental_index_rebuild(self, tmp_path, monkeypatch):
"""Mode incrémental : l'index est régénéré après une tuile, avec anti-rebond."""
from lidar_pipeline.pipeline import LidarArchaeoPipeline
import lidar_pipeline.index as index_mod
input_dir = tmp_path / "input"
input_dir.mkdir()
calls = []
monkeypatch.setattr(index_mod, "build_index",
lambda *a, **k: calls.append(a) or None)
pipeline = LidarArchaeoPipeline(str(input_dir), str(tmp_path / "output"),
incremental_index=True)
pipeline._rebuild_index_incremental()
pipeline._rebuild_index_incremental() # < 3 s : anti-rebond, ignoré
assert len(calls) == 1
# --no-index : jamais de rebuild incrémental
pipeline._last_index_rebuild = 0.0
pipeline.no_index = True
pipeline._rebuild_index_incremental()
assert len(calls) == 1
def test_find_laz_files_empty(self, tmp_path):
from lidar_pipeline.pipeline import LidarArchaeoPipeline
input_dir = tmp_path / "input"