From c82b1c3ca084644812440c2add78426ba482507c Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Mon, 1 Jun 2026 20:26:58 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20rename=20OpentelemetryConfig=20?= =?UTF-8?q?=E2=86=92=20OpenTelemetryConfig;=20FreeBootstrapperConfig=20?= =?UTF-8?q?=E2=86=92=20FreeConfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two API-surface renames with silent backward-compatibility aliases. OpentelemetryConfig → OpenTelemetryConfig: matches the conventional OpenTelemetry capitalization and the OpenTelemetryServiceFieldsConfig mixin introduced in PR6. Module-level alias `OpentelemetryConfig = OpenTelemetryConfig` preserves existing imports. Not exported from __init__.py (wasn't before either). FreeBootstrapperConfig → FreeConfig: matches the sibling configs (FastAPIConfig, LitestarConfig, FastStreamConfig — none carry the "Bootstrapper" infix). Module-level alias plus `FreeBootstrapperConfig` re-export in __init__.py preserves existing public imports. Internal references and tests updated to the new canonical names. Aliases are simple class assignments — same class object, so isinstance(x, OldName) and isinstance(x, NewName) are interchangeable. Old pickles continue to unpickle via the alias. No behavior change. 129/129 tests pass. Closes LOW-7 from the audit. Also closes the bonus Otel capitalization item surfaced during PR6's code review. --- lite_bootstrap/__init__.py | 3 ++- .../bootstrappers/fastapi_bootstrapper.py | 4 ++-- .../bootstrappers/faststream_bootstrapper.py | 4 ++-- .../bootstrappers/free_bootstrapper.py | 12 ++++++++---- .../bootstrappers/litestar_bootstrapper.py | 4 ++-- .../instruments/opentelemetry_instrument.py | 8 ++++++-- tests/instruments/test_logging_instrument.py | 4 ++-- .../test_opentelemetry_instrument.py | 10 +++++----- tests/instruments/test_pyroscope_instrument.py | 8 ++++---- tests/test_free_bootstrap.py | 18 +++++++++--------- 10 files changed, 42 insertions(+), 33 deletions(-) diff --git a/lite_bootstrap/__init__.py b/lite_bootstrap/__init__.py index 1c6799c..171185a 100644 --- a/lite_bootstrap/__init__.py +++ b/lite_bootstrap/__init__.py @@ -1,6 +1,6 @@ from lite_bootstrap.bootstrappers.fastapi_bootstrapper import FastAPIBootstrapper, FastAPIConfig from lite_bootstrap.bootstrappers.faststream_bootstrapper import FastStreamBootstrapper, FastStreamConfig -from lite_bootstrap.bootstrappers.free_bootstrapper import FreeBootstrapper, FreeBootstrapperConfig +from lite_bootstrap.bootstrappers.free_bootstrapper import FreeBootstrapper, FreeBootstrapperConfig, FreeConfig from lite_bootstrap.bootstrappers.litestar_bootstrapper import LitestarBootstrapper, LitestarConfig from lite_bootstrap.exceptions import ( BootstrapperNotReadyError, @@ -23,6 +23,7 @@ "FastStreamConfig", "FreeBootstrapper", "FreeBootstrapperConfig", + "FreeConfig", "InstrumentDependencyMissingWarning", "InstrumentNotReadyWarning", "InstrumentSkippedWarning", diff --git a/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py b/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py index 345516f..5cba5e5 100644 --- a/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py @@ -14,7 +14,7 @@ HealthCheckTypedDict, ) from lite_bootstrap.instruments.logging_instrument import LoggingConfig, LoggingInstrument -from lite_bootstrap.instruments.opentelemetry_instrument import OpentelemetryConfig, OpenTelemetryInstrument +from lite_bootstrap.instruments.opentelemetry_instrument import OpenTelemetryConfig, OpenTelemetryInstrument from lite_bootstrap.instruments.prometheus_instrument import PrometheusConfig, PrometheusInstrument from lite_bootstrap.instruments.pyroscope_instrument import PyroscopeConfig, PyroscopeInstrument from lite_bootstrap.instruments.sentry_instrument import SentryConfig, SentryInstrument @@ -42,7 +42,7 @@ class FastAPIConfig( CorsConfig, HealthChecksConfig, LoggingConfig, - OpentelemetryConfig, + OpenTelemetryConfig, PrometheusConfig, PyroscopeConfig, SentryConfig, diff --git a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py index fc9dffb..72ecb25 100644 --- a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py @@ -7,7 +7,7 @@ from lite_bootstrap.bootstrappers.base import BaseBootstrapper from lite_bootstrap.instruments.healthchecks_instrument import HealthChecksConfig, HealthChecksInstrument from lite_bootstrap.instruments.logging_instrument import LoggingConfig, LoggingInstrument -from lite_bootstrap.instruments.opentelemetry_instrument import OpentelemetryConfig, OpenTelemetryInstrument +from lite_bootstrap.instruments.opentelemetry_instrument import OpenTelemetryConfig, OpenTelemetryInstrument from lite_bootstrap.instruments.prometheus_instrument import PrometheusConfig, PrometheusInstrument from lite_bootstrap.instruments.pyroscope_instrument import PyroscopeConfig, PyroscopeInstrument from lite_bootstrap.instruments.sentry_instrument import SentryConfig, SentryInstrument @@ -62,7 +62,7 @@ def _make_asgi_faststream() -> "AsgiFastStream": @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) class FastStreamConfig( - HealthChecksConfig, LoggingConfig, OpentelemetryConfig, PrometheusConfig, PyroscopeConfig, SentryConfig + HealthChecksConfig, LoggingConfig, OpenTelemetryConfig, PrometheusConfig, PyroscopeConfig, SentryConfig ): application: "AsgiFastStream" = dataclasses.field(default_factory=_make_asgi_faststream) opentelemetry_middleware_cls: type[FastStreamTelemetryMiddlewareProtocol] | None = None diff --git a/lite_bootstrap/bootstrappers/free_bootstrapper.py b/lite_bootstrap/bootstrappers/free_bootstrapper.py index b5c3b5c..065b906 100644 --- a/lite_bootstrap/bootstrappers/free_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/free_bootstrapper.py @@ -3,13 +3,13 @@ from lite_bootstrap.bootstrappers.base import BaseBootstrapper from lite_bootstrap.instruments.logging_instrument import LoggingConfig, LoggingInstrument -from lite_bootstrap.instruments.opentelemetry_instrument import OpentelemetryConfig, OpenTelemetryInstrument +from lite_bootstrap.instruments.opentelemetry_instrument import OpenTelemetryConfig, OpenTelemetryInstrument from lite_bootstrap.instruments.pyroscope_instrument import PyroscopeConfig, PyroscopeInstrument from lite_bootstrap.instruments.sentry_instrument import SentryConfig, SentryInstrument @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class FreeBootstrapperConfig(LoggingConfig, OpentelemetryConfig, PyroscopeConfig, SentryConfig): ... +class FreeConfig(LoggingConfig, OpenTelemetryConfig, PyroscopeConfig, SentryConfig): ... class FreeBootstrapper(BaseBootstrapper[None]): @@ -21,14 +21,18 @@ class FreeBootstrapper(BaseBootstrapper[None]): OpenTelemetryInstrument, PyroscopeInstrument, ] - bootstrap_config: FreeBootstrapperConfig + bootstrap_config: FreeConfig not_ready_message = "" def is_ready(self) -> bool: return True - def __init__(self, bootstrap_config: FreeBootstrapperConfig) -> None: + def __init__(self, bootstrap_config: FreeConfig) -> None: super().__init__(bootstrap_config) def _prepare_application(self) -> None: return None + + +# Backward-compatible alias preserved for users importing the old name. +FreeBootstrapperConfig = FreeConfig diff --git a/lite_bootstrap/bootstrappers/litestar_bootstrapper.py b/lite_bootstrap/bootstrappers/litestar_bootstrapper.py index b99f075..0addc25 100644 --- a/lite_bootstrap/bootstrappers/litestar_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/litestar_bootstrapper.py @@ -12,7 +12,7 @@ HealthCheckTypedDict, ) from lite_bootstrap.instruments.logging_instrument import LoggingConfig, LoggingInstrument -from lite_bootstrap.instruments.opentelemetry_instrument import OpentelemetryConfig, OpenTelemetryInstrument +from lite_bootstrap.instruments.opentelemetry_instrument import OpenTelemetryConfig, OpenTelemetryInstrument from lite_bootstrap.instruments.prometheus_instrument import ( PrometheusConfig as PrometheusBootstrapperConfig, ) @@ -104,7 +104,7 @@ class LitestarConfig( CorsConfig, HealthChecksConfig, LoggingConfig, - OpentelemetryConfig, + OpenTelemetryConfig, PrometheusBootstrapperConfig, PyroscopeConfig, SentryConfig, diff --git a/lite_bootstrap/instruments/opentelemetry_instrument.py b/lite_bootstrap/instruments/opentelemetry_instrument.py index 05e972a..e753ce7 100644 --- a/lite_bootstrap/instruments/opentelemetry_instrument.py +++ b/lite_bootstrap/instruments/opentelemetry_instrument.py @@ -39,7 +39,7 @@ class OpenTelemetryServiceFieldsConfig(BaseConfig): @dataclasses.dataclass(kw_only=True, frozen=True) -class OpentelemetryConfig(OpenTelemetryServiceFieldsConfig): +class OpenTelemetryConfig(OpenTelemetryServiceFieldsConfig): opentelemetry_container_name: str | None = dataclasses.field( default_factory=lambda: os.environ.get("HOSTNAME") or None ) @@ -78,7 +78,7 @@ def force_flush(self, timeout_millis: int = 30000) -> bool: # pragma: no cover @dataclasses.dataclass(kw_only=True, slots=True) -class OpenTelemetryInstrument(BaseInstrument[OpentelemetryConfig]): +class OpenTelemetryInstrument(BaseInstrument[OpenTelemetryConfig]): not_ready_message = "opentelemetry_endpoint is empty and opentelemetry_log_traces is False" missing_dependency_message = "opentelemetry is not installed" _tracer_provider: "TracerProvider | None" = dataclasses.field( @@ -153,3 +153,7 @@ def teardown(self) -> None: self._tracer_provider.shutdown() finally: self._tracer_provider = None + + +# Backward-compatible alias preserved for users importing the old (lowercase t) spelling. +OpentelemetryConfig = OpenTelemetryConfig diff --git a/tests/instruments/test_logging_instrument.py b/tests/instruments/test_logging_instrument.py index d859415..3e155e2 100644 --- a/tests/instruments/test_logging_instrument.py +++ b/tests/instruments/test_logging_instrument.py @@ -8,7 +8,7 @@ from lite_bootstrap.instruments.logging_factory import _MemoryLoggerFactoryConfig from lite_bootstrap.instruments.logging_instrument import LoggingConfig, LoggingInstrument, MemoryLoggerFactory -from lite_bootstrap.instruments.opentelemetry_instrument import OpentelemetryConfig, OpenTelemetryInstrument +from lite_bootstrap.instruments.opentelemetry_instrument import OpenTelemetryConfig, OpenTelemetryInstrument from tests.conftest import LoggingMock @@ -51,7 +51,7 @@ def test_logging_instrument_tracer_injection(logging_mock: LoggingMock) -> None: ) ) opentelemetry_instrument = OpenTelemetryInstrument( - bootstrap_config=OpentelemetryConfig( + bootstrap_config=OpenTelemetryConfig( opentelemetry_log_traces=True, ) ) diff --git a/tests/instruments/test_opentelemetry_instrument.py b/tests/instruments/test_opentelemetry_instrument.py index 6c041d8..332b5bf 100644 --- a/tests/instruments/test_opentelemetry_instrument.py +++ b/tests/instruments/test_opentelemetry_instrument.py @@ -4,7 +4,7 @@ from lite_bootstrap.instruments.opentelemetry_instrument import ( InstrumentorWithParams, - OpentelemetryConfig, + OpenTelemetryConfig, OpenTelemetryInstrument, ) from tests.conftest import CustomInstrumentor @@ -12,7 +12,7 @@ def test_opentelemetry_instrument() -> None: opentelemetry_instrument = OpenTelemetryInstrument( - bootstrap_config=OpentelemetryConfig( + bootstrap_config=OpenTelemetryConfig( opentelemetry_instrumentors=[ InstrumentorWithParams(instrumentor=CustomInstrumentor(), additional_params={"key": "value"}), CustomInstrumentor(), @@ -28,7 +28,7 @@ def test_opentelemetry_instrument() -> None: def test_opentelemetry_instrument_empty_instruments() -> None: opentelemetry_instrument = OpenTelemetryInstrument( - bootstrap_config=OpentelemetryConfig( + bootstrap_config=OpenTelemetryConfig( opentelemetry_log_traces=True, ) ) @@ -40,7 +40,7 @@ def test_opentelemetry_instrument_empty_instruments() -> None: def test_opentelemetry_instrument_teardown_shuts_down_tracer_provider() -> None: instrument = OpenTelemetryInstrument( - bootstrap_config=OpentelemetryConfig(opentelemetry_log_traces=True), + bootstrap_config=OpenTelemetryConfig(opentelemetry_log_traces=True), ) instrument.bootstrap() tracer_provider = instrument._tracer_provider # noqa: SLF001 @@ -55,7 +55,7 @@ def test_opentelemetry_instrument_teardown_shuts_down_tracer_provider() -> None: def test_opentelemetry_instrument_teardown_resets_tracer_provider_when_shutdown_raises() -> None: instrument = OpenTelemetryInstrument( - bootstrap_config=OpentelemetryConfig(opentelemetry_log_traces=True), + bootstrap_config=OpenTelemetryConfig(opentelemetry_log_traces=True), ) instrument.bootstrap() tracer_provider = instrument._tracer_provider # noqa: SLF001 diff --git a/tests/instruments/test_pyroscope_instrument.py b/tests/instruments/test_pyroscope_instrument.py index b347052..b7a77dc 100644 --- a/tests/instruments/test_pyroscope_instrument.py +++ b/tests/instruments/test_pyroscope_instrument.py @@ -10,7 +10,7 @@ from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter import lite_bootstrap.instruments.opentelemetry_instrument as otel_module -from lite_bootstrap import FreeBootstrapperConfig +from lite_bootstrap import FreeConfig from lite_bootstrap.instruments.opentelemetry_instrument import OpenTelemetryInstrument from lite_bootstrap.instruments.pyroscope_instrument import PyroscopeConfig, PyroscopeInstrument @@ -52,7 +52,7 @@ def test_pyroscope_instrument_bootstrap_and_teardown() -> None: def test_pyroscope_bootstrap_uses_opentelemetry_service_name() -> None: - config = FreeBootstrapperConfig( + config = FreeConfig( service_name="fallback", pyroscope_endpoint="http://pyroscope:4040", opentelemetry_service_name="otel-name", @@ -78,7 +78,7 @@ def test_pyroscope_standalone_config_accepts_otel_fields() -> None: def test_pyroscope_bootstrap_merges_namespace_tag() -> None: - config = FreeBootstrapperConfig( + config = FreeConfig( service_name="svc", pyroscope_endpoint="http://pyroscope:4040", pyroscope_tags={"env": "prod"}, @@ -165,7 +165,7 @@ def test_pyroscope_span_processor_on_start_remote_parent() -> None: def test_pyroscope_otel_adds_span_processor_when_configured() -> None: """OTel instrument adds PyroscopeSpanProcessor when pyroscope_endpoint is set.""" - config = FreeBootstrapperConfig( + config = FreeConfig( service_name="test-svc", opentelemetry_log_traces=True, pyroscope_endpoint="http://pyroscope:4040", diff --git a/tests/test_free_bootstrap.py b/tests/test_free_bootstrap.py index 184511e..c097a62 100644 --- a/tests/test_free_bootstrap.py +++ b/tests/test_free_bootstrap.py @@ -6,7 +6,7 @@ from lite_bootstrap import ( FreeBootstrapper, - FreeBootstrapperConfig, + FreeConfig, InstrumentNotReadyWarning, TeardownError, ) @@ -17,8 +17,8 @@ @pytest.fixture -def free_bootstrapper_config() -> FreeBootstrapperConfig: - return FreeBootstrapperConfig( +def free_bootstrapper_config() -> FreeConfig: + return FreeConfig( service_debug=False, opentelemetry_instrumentors=[CustomInstrumentor()], opentelemetry_log_traces=True, @@ -27,7 +27,7 @@ def free_bootstrapper_config() -> FreeBootstrapperConfig: ) -def test_free_bootstrap(free_bootstrapper_config: FreeBootstrapperConfig) -> None: +def test_free_bootstrap(free_bootstrapper_config: FreeConfig) -> None: bootstrapper = FreeBootstrapper(bootstrap_config=free_bootstrapper_config) bootstrapper.bootstrap() try: @@ -39,7 +39,7 @@ def test_free_bootstrap(free_bootstrapper_config: FreeBootstrapperConfig) -> Non def test_free_bootstrap_logging_disabled() -> None: with pytest.warns(InstrumentNotReadyWarning) as records: FreeBootstrapper( - bootstrap_config=FreeBootstrapperConfig( + bootstrap_config=FreeConfig( logging_enabled=False, opentelemetry_instrumentors=[CustomInstrumentor()], opentelemetry_log_traces=True, @@ -53,7 +53,7 @@ def test_free_bootstrap_logging_disabled() -> None: assert "PyroscopeInstrument is not ready: pyroscope_endpoint is empty" in messages -def test_teardown_error_isolation(free_bootstrapper_config: FreeBootstrapperConfig) -> None: +def test_teardown_error_isolation(free_bootstrapper_config: FreeConfig) -> None: bootstrapper = FreeBootstrapper(bootstrap_config=free_bootstrapper_config) bootstrapper.bootstrap() @@ -73,7 +73,7 @@ def test_teardown_error_isolation(free_bootstrapper_config: FreeBootstrapperConf assert excinfo.value.errors == [("MagicMock", excinfo.value.__cause__)] -def test_teardown_error_aggregates_all_failures(free_bootstrapper_config: FreeBootstrapperConfig) -> None: +def test_teardown_error_aggregates_all_failures(free_bootstrapper_config: FreeConfig) -> None: bootstrapper = FreeBootstrapper(bootstrap_config=free_bootstrapper_config) bootstrapper.bootstrap() @@ -104,13 +104,13 @@ def test_teardown_error_aggregates_all_failures(free_bootstrapper_config: FreeBo ], ) def test_free_bootstrapper_with_missing_instrument_dependency( - free_bootstrapper_config: FreeBootstrapperConfig, package_name: str + free_bootstrapper_config: FreeConfig, package_name: str ) -> None: with emulate_package_missing(package_name), pytest.warns(UserWarning, match=package_name): FreeBootstrapper(bootstrap_config=free_bootstrapper_config) -def test_teardown_is_idempotent(free_bootstrapper_config: FreeBootstrapperConfig) -> None: +def test_teardown_is_idempotent(free_bootstrapper_config: FreeConfig) -> None: bootstrapper = FreeBootstrapper(bootstrap_config=free_bootstrapper_config) bootstrapper.bootstrap()