Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions sparkmeter/metering/lifespan.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,12 @@
logger = logging.getLogger(__name__)


def _is_ground() -> bool:
"""Whether this deployment should drive a meter network."""
try:
from sparkmeter.config.configdict import config

return config.is_ground()
except Exception: # noqa: BLE001
return os.environ.get("SPARKMETER_MODE", "ground") == "ground"


@asynccontextmanager
async def metering_lifespan(app: FastAPI) -> AsyncIterator[None]:
"""Owns the metering-provider connection on ground; no-op on cloud."""
if not _is_ground():
from sparkmeter.config.configdict import config

if config.is_cloud():
app.state.metering = None
yield
return
Expand Down
22 changes: 22 additions & 0 deletions sparkmeter/metering/tests/test_lifespan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Tests for the metering FastAPI lifespan."""

from types import SimpleNamespace

import pytest

from sparkmeter.metering import lifespan


@pytest.mark.asyncio
async def test_metering_lifespan_is_noop_on_cloud(monkeypatch):
"""On cloud, the lifespan sets app.state.metering to None and starts nothing."""
monkeypatch.setattr("sparkmeter.config.configdict.config.is_cloud", lambda: True)

app = SimpleNamespace(state=SimpleNamespace())

async with lifespan.metering_lifespan(app):
assert app.state.metering is None

# No metering runtime was started: only the no-op no-metering state exists.
assert app.state.metering is None
assert not hasattr(app.state, "metering_command_queue")
Loading