Release/v0.0.5#5
Conversation
…ports Deferred resolver router construction until module access, added resolver mutmut configuration, introduced lazy baseline/granger engine import hooks, hardened shared Redis patching in tests, and updated resolver changelog.
There was a problem hiding this comment.
Pull request overview
Release v0.0.5 focused on reducing import-time coupling (lazy imports/routers), tightening API boundaries via keyword-only arguments + structured input dataclasses, and expanding test + mutation-testing configuration to keep lint/type/test suites green.
Changes:
- Introduces mutation-testing configuration (
mutmut) and updates versions to0.0.5across project metadata/OpenAPI artifacts. - Refactors analyzer/connector/engine APIs toward keyword-only params and structured input objects (e.g.,
FetchRequestOptions,GrangerAnalysisOptions, analyzer stage dataclasses,RcaSignalInputs). - Hardens tests and bootstrapping (dynamic store patching, optional temp SQLite bootstrap, improved exception-wrapper shape/identity assertions), plus widespread header/docstring cleanups.
Reviewed changes
Copilot reviewed 191 out of 192 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| CHANGELOG.md | Adds v0.0.5 entry (release notes/date). |
| api/init.py | Replaces placeholder comment with package docstring + license header. |
| api/requests/init.py | License header normalization. |
| api/requests/_time_range.py | Clarifies docstring and adds license header. |
| api/requests/analyze.py | License header normalization. |
| api/requests/correlation.py | License header normalization. |
| api/requests/events.py | License header normalization. |
| api/requests/logs.py | License header normalization. |
| api/requests/metrics.py | License header normalization. |
| api/requests/slo.py | License header normalization. |
| api/requests/topology.py | License header normalization. |
| api/requests/traces.py | License header normalization. |
| api/responses/init.py | License header normalization. |
| api/responses/analysis.py | License header normalization. |
| api/responses/anomalies.py | License header normalization. |
| api/responses/base.py | Minor refactor to structured branching while coercing numpy types. |
| api/responses/jobs.py | License header normalization. |
| api/responses/logs.py | License header normalization. |
| api/responses/rca.py | License header normalization. |
| api/responses/slo.py | License header normalization. |
| api/responses/traces.py | License header normalization. |
| api/routes/init.py | Removes aggregated router wiring; exports empty router. |
| api/routes/analyze.py | License header normalization. |
| api/routes/causal.py | License header normalization; makes limit keyword-only query param; updates fetch_metrics call style. |
| api/routes/common.py | Updates fetch_metrics call to use keyword step. |
| api/routes/correlation.py | Updates fetch_metrics call to use keyword step. |
| api/routes/events.py | License header normalization. |
| api/routes/exception.py | License header normalization in docstring header block. |
| api/routes/forecast.py | License header normalization. |
| api/routes/health.py | License header normalization. |
| api/routes/logs.py | License header normalization. |
| api/routes/metrics.py | License header normalization; removes legacy changepoint signature fallback. |
| api/routes/ml.py | License header normalization. |
| api/routes/slo.py | License header normalization; uses keyword-only target_availability when calling SLO evaluation. |
| api/routes/topology.py | License header normalization. |
| api/routes/traces.py | License header normalization. |
| config.py | Minor comment cleanup; license header normalization. |
| connectors/init.py | License header normalization. |
| connectors/common.py | Introduces BackendErrorMessages and routes all connector calls through FetchRequestOptions/FetchErrorMessages. |
| connectors/loki.py | Adds module docstring; switches to BackendErrorMessages; makes ctor args keyword-only for timeout/headers; query signature uses keyword-only limit. |
| connectors/mimir.py | Adds module docstring; introduces FetchRequestOptions/FetchErrorMessages; makes step keyword-only + required. |
| connectors/tempo.py | Adds module docstring; switches to BackendErrorMessages; makes ctor args keyword-only; query signature uses keyword-only limit. |
| custom_types/init.py | License header normalization. |
| custom_types/json.py | License header normalization. |
| database.py | License header normalization. |
| datasources/init.py | License header normalization. |
| datasources/base.py | Makes ctor and connector protocol methods keyword-only for timeout/headers/limit/step. |
| datasources/data_config.py | License header normalization. |
| datasources/exceptions.py | License header normalization. |
| datasources/factory.py | License header normalization. |
| datasources/helpers.py | Introduces FetchRequestOptions/FetchErrorMessages API; removes legacy kwargs support; simplifies coercion. |
| datasources/provider.py | Adds input coercion for optional ints; makes step keyword-only + required; makes limit keyword-only. |
| datasources/retry.py | License header normalization. |
| datasources/types.py | License header normalization. |
| db_models.py | License header normalization. |
| engine/init.py | License header normalization. |
| engine/analyze/init.py | Adds license header. |
| engine/analyze/filters.py | Refactors to avoid early returns; functional behavior preserved. |
| engine/analyze/helpers.py | Extracts quality-gate helpers into engine.analyze.quality_support; enforces structured inputs for gates/output limiting and metric-series processing; updates forecast call to keyword-only. |
| engine/analyze/quality_support.py | New shared quality-gate utilities (signal counting, density gates, root cause gating, diagnostics). |
| engine/analyze/series.py | Adds module docstring/license header (existing logic remains). |
| engine/analyze/stage_context.py | New dataclasses for analyzer stage inputs and analysis scope. |
| engine/analyzer.py | Refactors analyzer pipeline to use stage dataclasses + RcaSignalInputs; makes severity helper accept grouped sequences; updates SLO call signature usage. |
| engine/anomaly/init.py | License header normalization. |
| engine/anomaly/detection.py | Refactors Tukey class logic to single-return style (behavior preserved). |
| engine/anomaly/series.py | License header normalization. |
| engine/anomaly/stats.py | License header normalization. |
| engine/baseline/init.py | License header normalization. |
| engine/baseline/compute.py | License header normalization. |
| engine/causal/init.py | License header normalization. |
| engine/causal/bayesian.py | Makes has_error_propagation keyword-only. |
| engine/causal/granger.py | Introduces GrangerAnalysisOptions; makes options keyword-only; updates multi-pair helper to pass options object. |
| engine/causal/graph.py | Makes lag_seconds keyword-only in add_edge. |
| engine/changepoint/init.py | License/header normalization for Apache link. |
| engine/changepoint/cusum.py | License header normalization. |
| engine/correlation/init.py | License header normalization. |
| engine/correlation/signals.py | License header normalization. |
| engine/correlation/temporal.py | Refactors correlation selection/scoring into helper functions for readability and testability. |
| engine/dedup/init.py | License header normalization. |
| engine/dedup/grouping.py | License header normalization. |
| engine/enums.py | License header normalization. |
| engine/events/init.py | License header normalization. |
| engine/events/models.py | Adds license header/docstring. |
| engine/events/registry.py | License header normalization. |
| engine/fetcher.py | Makes step keyword-only and required; normalizes/validates step. |
| engine/forecast/init.py | License header normalization. |
| engine/forecast/degradation.py | License header normalization. |
| engine/forecast/trajectory.py | Makes horizon_seconds keyword-only. |
| engine/log_query.py | Adds license header/docstring. |
| engine/logs/init.py | License header normalization. |
| engine/logs/frequency.py | License header normalization. |
| engine/logs/patterns.py | License header normalization. |
| engine/ml/init.py | License header normalization. |
| engine/ml/clustering.py | License header normalization. |
| engine/ml/ranking.py | Removes unused event_refs accumulator (minor cleanup). |
| engine/ml/weights.py | License header normalization. |
| engine/rca/init.py | Exports RcaSignalInputs from RCA package. |
| engine/rca/hypothesis.py | Refactors deployment lookup + event hypothesis building; switches generate to accept only RcaSignalInputs (no legacy positional signal groups). |
| engine/rca/scoring.py | License header normalization. |
| engine/registry.py | Refactors update-count coercion into single-flow parse + clamp. |
| engine/slo/init.py | License header normalization. |
| engine/slo/budget.py | License header normalization. |
| engine/slo/burn.py | Makes target_availability keyword-only; adds robust coercion/fallback to default setting. |
| engine/slo/models.py | Adds license header/docstring. |
| engine/topology/init.py | Adds license header/docstring. |
| engine/topology/graph.py | License header normalization. |
| engine/traces/init.py | License header normalization. |
| engine/traces/common.py | Adds license header/docstring. |
| engine/traces/errors.py | License header normalization. |
| engine/traces/latency.py | License header normalization. |
| main.py | Removes aggregated router import; includes routers explicitly; adds async DB bootstrap/retry; adds runtime SSL wrapper usage. |
| middleware/init.py | License header normalization. |
| middleware/openapi.py | License header normalization. |
| middleware/runtime_ssl.py | New runtime SSL helper + uvicorn runner wrapper. |
| openapi.yaml | Bumps documented API version to 0.0.5. |
| pyproject.toml | Bumps project version to 0.0.5; adds mutmut config; tightens pylint design thresholds; excludes mutants/ from mypy; increases pylint jobs. |
| services/init.py | License header formatting normalization. |
| services/analyze_service.py | License header formatting normalization. |
| services/analysis_config_service.py | Adds license header block. |
| services/rca_job_service.py | Makes several parameters positional (removes keyword-only); license header formatting normalization. |
| services/security_service.py | License header formatting normalization. |
| store/init.py | License header normalization. |
| store/baseline.py | Lazily imports Baseline/compute via __getattr__; adds helper wrappers _compute/_baseline_cls. |
| store/client.py | License header normalization. |
| store/events.py | Refactors event coercion to reduce branching/early returns; adds cast. |
| store/granger.py | Avoids import-time engine dependency by moving GrangerResult import behind TYPE_CHECKING. |
| store/keys.py | License header normalization. |
| store/weights.py | License header normalization. |
| tests/conftest.py | Adds optional temp SQLite bootstrap + dynamic store module patching for redis fakes. |
| tests/test_analysis_config_service.py | Adds license header block to file docstring. |
| tests/test_analyze_helpers_filters_edges.py | Updates to new structured inputs (MetricSeriesJob, PrecisionQualityGateInputs) and changepoint signature. |
| tests/test_analyzer_integration.py | License header normalization. |
| tests/test_analyzer_quality.py | Updates to new structured inputs (AnalyzerOutputInputs, PrecisionQualityGateInputs). |
| tests/test_anomaly_detection.py | License header normalization. |
| tests/test_anomaly_series.py | License header normalization. |
| tests/test_anomaly_stats.py | License header normalization. |
| tests/test_api_models.py | License header normalization. |
| tests/test_api_route_surface_edges.py | Updates changepoint capture signature; adds SSL/no-SSL uvicorn behavior tests; validates RuntimeSSLOptions errors. |
| tests/test_api_routes_analyze.py | License header normalization. |
| tests/test_api_routes_causal.py | License header normalization. |
| tests/test_api_routes_correlation.py | License header normalization. |
| tests/test_api_routes_events.py | License header normalization. |
| tests/test_api_routes_metrics.py | License header normalization. |
| tests/test_api_routes_ml.py | License header normalization. |
| tests/test_api_routes_slo.py | Updates dummy evaluators to accept target_availability; license header normalization. |
| tests/test_api_routes_topology.py | License header normalization. |
| tests/test_api_routes_traces.py | License header normalization. |
| tests/test_changepoint.py | License header normalization. |
| tests/test_config_database_and_engine_edges.py | Updates fetch_metrics call to keyword step; updates context manager exit signature. |
| tests/test_config_security.py | License header normalization. |
| tests/test_connectors_provider_and_security_edges.py | Updates fetch helpers API usage; adds provider limit coercion edge-case assertions; adds Mimir step-required test. |
| tests/test_correlation.py | License header normalization. |
| tests/test_datasource_and_store_helpers_more.py | Updates backend message passing; adds request_headers fallback coverage. |
| tests/test_datasource_factory.py | License header normalization. |
| tests/test_degradation.py | License header normalization. |
| tests/test_engine_causal.py | Updates Granger options + bayesian keyword-only arg; adds TypeError assertion for missing kw-only param. |
| tests/test_engine_registry.py | License header normalization. |
| tests/test_engine_weights.py | License header normalization. |
| tests/test_enums.py | License header normalization. |
| tests/test_events_registry.py | License header normalization. |
| tests/test_fetcher.py | Updates fetch_metrics usage to keyword step; minor dummy method signature cleanup. |
| tests/test_forecast.py | License header normalization. |
| tests/test_fuzzy.py | Updates Granger options usage. |
| tests/test_health_service_and_main_edges.py | Updates __aexit__ signatures. |
| tests/test_helpers.py | Updates fetch helpers API usage and async context manager exit signature. |
| tests/test_internal_security.py | License header normalization. |
| tests/test_jobs_routes.py | License header normalization. |
| tests/test_logs.py | License header normalization. |
| tests/test_loki_connector.py | License header normalization. |
| tests/test_main_ready.py | License header normalization. |
| tests/test_ml_clustering.py | License header normalization. |
| tests/test_ml_ranking.py | License header normalization. |
| tests/test_mutation_routes.py | Adds license header block to file docstring. |
| tests/test_openapi_middleware.py | Makes monkeypatched read_text accept flexible args/kwargs. |
| tests/test_rca_hypothesis.py | Updates RCA generate calls to use RcaSignalInputs. |
| tests/test_rca_scoring.py | License header normalization. |
| tests/test_regression_route_gap_workflows.py | Adds license header block to file docstring. |
| tests/test_retry.py | License header normalization. |
| tests/test_route_common_helpers.py | License header normalization. |
| tests/test_route_exception_wrapper.py | Strengthens exception-wrapper tests; asserts sync/async wrapper shape; ensures HTTPException identity preserved. |
| tests/test_route_permissions.py | License header normalization. |
| tests/test_slo.py | Updates SLO evaluate call to use keyword target_availability. |
| tests/test_store_baseline.py | License header normalization. |
| tests/test_store_client.py | License header normalization. |
| tests/test_store_client_events_and_weights_edges.py | License header normalization. |
| tests/test_store_granger.py | License header normalization. |
| tests/test_store_keys.py | License header normalization. |
| tests/test_store_registry.py | License header normalization. |
| tests/test_store_weights.py | License header normalization. |
| tests/test_topology.py | License header normalization. |
| tests/test_traces_parsing.py | License header normalization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def _coerce_fetch_options(options: FetchRequestOptions | None) -> FetchRequestOptions: | ||
| base = options or FetchRequestOptions() | ||
|
|
||
| params = legacy_kwargs.pop("params", base.params) | ||
| headers = legacy_kwargs.pop("headers", base.headers) | ||
| timeout_raw = legacy_kwargs.pop("timeout", base.timeout) | ||
| client_raw = legacy_kwargs.pop("client", base.client) | ||
|
|
||
| timeout = int(cast(int | str | bytes | bytearray, timeout_raw)) | ||
|
|
||
| timeout = int(cast(int | str | bytes | bytearray, base.timeout)) | ||
| client_raw = base.client | ||
| client = client_raw if hasattr(client_raw, "get") else base.client | ||
|
|
||
| return FetchRequestOptions( | ||
| params=cast(QueryParams | None, params), | ||
| headers=cast(dict[str, str] | None, headers), | ||
| params=base.params, | ||
| headers=base.headers, | ||
| timeout=timeout, | ||
| client=client, | ||
| ) |
There was a problem hiding this comment.
_coerce_fetch_options attempts to validate the provided client, but currently leaves a non-HTTP client object in place (the else base.client branch). If options.client doesn't implement .get, fetch_json/fetch_text will still try to call .get(...) and raise AttributeError instead of falling back to an owned httpx.AsyncClient. Consider setting client=None when the provided object isn't a valid async client (or explicitly checking for an async get attribute) so invalid clients reliably fall back to the owned client path.
| def from_settings(cls, settings: object) -> RuntimeSSLOptions | None: | ||
| if not getattr(settings, "ssl_enabled"): | ||
| return None |
There was a problem hiding this comment.
RuntimeSSLOptions.from_settings uses getattr(settings, "ssl_enabled") without a default. Since settings is typed as object, passing an object without ssl_enabled will raise AttributeError instead of treating SSL as disabled. Consider using getattr(settings, "ssl_enabled", False) to make this helper safe for generic settings objects.
| from fastapi import APIRouter | ||
|
|
||
| from api.routes.analyze import router as analyze_router | ||
| from api.routes.causal import router as causal_router | ||
| from api.routes.correlation import router as correlation_router | ||
| from api.routes.events import router as events_router | ||
| from api.routes.forecast import router as forecast_router | ||
| from api.routes.health import router as health_router | ||
| from api.routes.jobs import router as jobs_router | ||
| from api.routes.logs import router as logs_router | ||
| from api.routes.metrics import router as metrics_router | ||
| from api.routes.ml import router as ml_router | ||
| from api.routes.slo import router as slo_router | ||
| from api.routes.topology import router as topology_router | ||
| from api.routes.traces import router as traces_router | ||
|
|
||
| router = APIRouter() | ||
|
|
||
| router.include_router(health_router) | ||
| router.include_router(analyze_router) | ||
| router.include_router(metrics_router) | ||
| router.include_router(logs_router) | ||
| router.include_router(traces_router) | ||
| router.include_router(correlation_router) | ||
| router.include_router(slo_router) | ||
| router.include_router(topology_router) | ||
| router.include_router(events_router) | ||
| router.include_router(forecast_router) | ||
| router.include_router(causal_router) | ||
| router.include_router(ml_router) | ||
| router.include_router(jobs_router) | ||
|
|
||
| __all__ = ["router"] |
There was a problem hiding this comment.
The PR description says the aggregated API router is now constructed lazily when api.routes.router is accessed, but api/routes/__init__.py currently exports an empty APIRouter with no lazy inclusion logic. If external code still imports and uses api.routes.router, it will silently miss all routes. Either reintroduce lazy route inclusion (e.g., via __getattr__ that populates router) or update/remove the exported router to avoid a misleading compatibility surface.
| ## [v0.0.5] - 2026-04-21 | ||
|
|
There was a problem hiding this comment.
The PR metadata describes v0.0.5 as dated 2026-04-21, but the changelog entry is dated 2026-04-17. Please align the changelog release date with the intended release date (or adjust the PR description) so version history is consistent.
[v0.0.5] - 2026-04-21
Changed
routerattribute is accessed, reducing import-time dependency coupling.mutmut, including resolver API routes, services, store modules, and selective test invocation.__getattr__hooks to avoid import-time engine dependencies in store modules.mypy,pylint, andpytestall pass cleanly at 100% coverage.