P2-1 (containment): api/nestquest_core.py no longer mutates sys.path. Load core by file location with importlib.util.spec_from_file_location, registering it under the distinct top-level name 'nestquest_core' with submodule_search_locations pointing at the bundled core directory. No generic top-level names (db, const, schema, ...) are published that could shadow a future dependency, and the integration's HA-coupled __init__ is never executed. Use importlib.import_module for submodules; drop the redundant _BOOTSTRAPPED flag. Document that two core copies (nestquest_core.* and custom_components.nestquest.core.*) coexist in the pytest process so later tasks must not compare class/exception identity across them. P2-2 (fail fast): ApiConfig.from_env now RAISES ConfigError when NESTQUEST_DB_PATH is unset or empty — no silent fallback to a predictable world-writable temp path that loses data at reboot. Remove the module-level 'app = create_app()' (it read env at import time and would break fail-fast); document serving with 'uvicorn --factory api.app:create_app'. P3 cleanups: - /health drops db_path from the body (no filesystem path leak on an unauthenticated route) and runs a cheap SELECT 1 to reflect database reachability. - Remove dead code: resolve_db_path in api/config.py; unused LOGGER in api/app.py. - tests/test_api_health.py: add ApiConfig.from_env tests (set value, empty raises, missing raises); add startup-failure tests (unwritable dir, non-SQLite file); assert shutdown closes the connection (connected is False); make _AppRunner.__aexit__ use try/finally so a client error still shuts down the lifespan; reuse api.database._executor instead of a duplicated local copy; in the no-HA subprocess test assert core.__file__ points at the bundled directory and stop passing the unused ':memory:'. - pyproject.toml: comment that fastapi/uvicorn are dev-group only so the monorepo test venv can exercise the app; the API deployable's runtime dependencies must be declared when it is packaged (Feature 17).
20 lines
980 B
Python
20 lines
980 B
Python
"""NestQuest API service.
|
|
|
|
A standalone FastAPI deployable that owns the NestQuest database and
|
|
exposes it over HTTP to the Home Assistant integration (panel plane) and
|
|
the admin PWA (admin plane). See Feature 16 (task cd03735b) in the
|
|
project tracker for the full contract.
|
|
|
|
This package imports the NestQuest domain ``core`` WITHOUT executing
|
|
``custom_components/nestquest/__init__.py`` — that parent package's
|
|
``__init__.py`` imports ``homeassistant``, which is absent from the
|
|
API's runtime. The coupling is encapsulated in
|
|
:mod:`api.nestquest_core`, which loads ``core`` by file location with
|
|
:mod:`importlib.util` and registers it under the distinct top-level name
|
|
``nestquest_core`` (no ``sys.path`` mutation, no generic top-level
|
|
names published). It is a TRANSITIONAL coupling that Feature 18 will
|
|
revisit: once the integration becomes a thin API client and ``core``
|
|
moves out of the integration bundle, this helper goes away.
|
|
"""
|
|
from __future__ import annotations
|