diff --git a/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py b/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py index 06eb04e..838e6a0 100644 --- a/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/fastapi_bootstrapper.py @@ -108,11 +108,6 @@ def bootstrap(self) -> None: self.bootstrap_config.application.include_router(self.build_fastapi_health_check_router()) -@dataclasses.dataclass(kw_only=True, frozen=True) -class FastAPILoggingInstrument(LoggingInstrument): - bootstrap_config: FastAPIConfig - - @dataclasses.dataclass(kw_only=True, frozen=True) class FastAPIOpenTelemetryInstrument(OpenTelemetryInstrument): bootstrap_config: FastAPIConfig @@ -138,11 +133,6 @@ def teardown(self) -> None: super().teardown() -@dataclasses.dataclass(kw_only=True, frozen=True) -class FastAPISentryInstrument(SentryInstrument): - bootstrap_config: FastAPIConfig - - @dataclasses.dataclass(kw_only=True, frozen=True) class FastAPIPrometheusInstrument(PrometheusInstrument): bootstrap_config: FastAPIConfig @@ -188,9 +178,9 @@ class FastAPIBootstrapper(BaseBootstrapper["fastapi.FastAPI"]): FastAPICorsInstrument, FastAPIOpenTelemetryInstrument, PyroscopeInstrument, - FastAPISentryInstrument, + SentryInstrument, FastAPIHealthChecksInstrument, - FastAPILoggingInstrument, + LoggingInstrument, FastAPIPrometheusInstrument, FastAPISwaggerInstrument, ] diff --git a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py index 6287b02..3baaabd 100644 --- a/lite_bootstrap/bootstrappers/faststream_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/faststream_bootstrapper.py @@ -132,11 +132,6 @@ def bootstrap(self) -> None: ) -@dataclasses.dataclass(kw_only=True, frozen=True) -class FastStreamSentryInstrument(SentryInstrument): - bootstrap_config: FastStreamConfig - - def _make_collector_registry() -> "prometheus_client.CollectorRegistry": return prometheus_client.CollectorRegistry() @@ -177,7 +172,7 @@ class FastStreamBootstrapper(BaseBootstrapper["AsgiFastStream"]): instruments_types: typing.ClassVar = [ FastStreamOpenTelemetryInstrument, PyroscopeInstrument, - FastStreamSentryInstrument, + SentryInstrument, FastStreamHealthChecksInstrument, FastStreamLoggingInstrument, FastStreamPrometheusInstrument, diff --git a/lite_bootstrap/bootstrappers/litestar_bootstrapper.py b/lite_bootstrap/bootstrappers/litestar_bootstrapper.py index ad1cc5a..7a026d9 100644 --- a/lite_bootstrap/bootstrappers/litestar_bootstrapper.py +++ b/lite_bootstrap/bootstrappers/litestar_bootstrapper.py @@ -196,11 +196,6 @@ def bootstrap(self) -> None: ) -@dataclasses.dataclass(kw_only=True, frozen=True) -class LitestarSentryInstrument(SentryInstrument): - bootstrap_config: LitestarConfig - - @dataclasses.dataclass(kw_only=True, frozen=True) class LitestarPrometheusInstrument(PrometheusInstrument): bootstrap_config: LitestarConfig @@ -271,7 +266,7 @@ class LitestarBootstrapper(BaseBootstrapper["litestar.Litestar"]): LitestarCorsInstrument, LitestarOpenTelemetryInstrument, PyroscopeInstrument, - LitestarSentryInstrument, + SentryInstrument, LitestarHealthChecksInstrument, LitestarLoggingInstrument, LitestarPrometheusInstrument, diff --git a/lite_bootstrap/instruments/base.py b/lite_bootstrap/instruments/base.py index 32256ea..bfd44cb 100644 --- a/lite_bootstrap/instruments/base.py +++ b/lite_bootstrap/instruments/base.py @@ -27,15 +27,18 @@ def from_object(cls, obj: object) -> typing_extensions.Self: return cls(**prepared_data) +ConfigT = typing.TypeVar("ConfigT", bound=BaseConfig) + + @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class BaseInstrument(abc.ABC): - bootstrap_config: BaseConfig +class BaseInstrument(abc.ABC, typing.Generic[ConfigT]): + bootstrap_config: ConfigT not_ready_message = "" missing_dependency_message = "" - def bootstrap(self) -> None: ... # noqa: B027 + def bootstrap(self) -> None: ... - def teardown(self) -> None: ... # noqa: B027 + def teardown(self) -> None: ... def is_ready(self) -> bool: return True diff --git a/lite_bootstrap/instruments/cors_instrument.py b/lite_bootstrap/instruments/cors_instrument.py index d00805c..22b7384 100644 --- a/lite_bootstrap/instruments/cors_instrument.py +++ b/lite_bootstrap/instruments/cors_instrument.py @@ -15,8 +15,7 @@ class CorsConfig(BaseConfig): @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class CorsInstrument(BaseInstrument): - bootstrap_config: CorsConfig +class CorsInstrument(BaseInstrument[CorsConfig]): not_ready_message = "cors_allowed_origins or cors_allowed_origin_regex must be provided" def is_ready(self) -> bool: diff --git a/lite_bootstrap/instruments/healthchecks_instrument.py b/lite_bootstrap/instruments/healthchecks_instrument.py index ac8074d..1116826 100644 --- a/lite_bootstrap/instruments/healthchecks_instrument.py +++ b/lite_bootstrap/instruments/healthchecks_instrument.py @@ -27,8 +27,7 @@ def health_check_data(self) -> HealthCheckTypedDict: @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class HealthChecksInstrument(BaseInstrument): - bootstrap_config: HealthChecksConfig +class HealthChecksInstrument(BaseInstrument[HealthChecksConfig]): not_ready_message = "health_checks_enabled is False" def is_ready(self) -> bool: diff --git a/lite_bootstrap/instruments/logging_instrument.py b/lite_bootstrap/instruments/logging_instrument.py index a830520..05304ed 100644 --- a/lite_bootstrap/instruments/logging_instrument.py +++ b/lite_bootstrap/instruments/logging_instrument.py @@ -115,8 +115,7 @@ class LoggingConfig(BaseConfig): @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class LoggingInstrument(BaseInstrument): - bootstrap_config: LoggingConfig +class LoggingInstrument(BaseInstrument[LoggingConfig]): not_ready_message = "logging_enabled is False" missing_dependency_message = "structlog is not installed" _logger_factory: "MemoryLoggerFactory | None" = dataclasses.field( diff --git a/lite_bootstrap/instruments/opentelemetry_instrument.py b/lite_bootstrap/instruments/opentelemetry_instrument.py index 88d0333..1e7eeda 100644 --- a/lite_bootstrap/instruments/opentelemetry_instrument.py +++ b/lite_bootstrap/instruments/opentelemetry_instrument.py @@ -78,8 +78,7 @@ def force_flush(self, timeout_millis: int = 30000) -> bool: # pragma: no cover @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class OpenTelemetryInstrument(BaseInstrument): - bootstrap_config: 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( diff --git a/lite_bootstrap/instruments/prometheus_instrument.py b/lite_bootstrap/instruments/prometheus_instrument.py index f0a7897..ccf047f 100644 --- a/lite_bootstrap/instruments/prometheus_instrument.py +++ b/lite_bootstrap/instruments/prometheus_instrument.py @@ -11,8 +11,7 @@ class PrometheusConfig(BaseConfig): @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class PrometheusInstrument(BaseInstrument): - bootstrap_config: PrometheusConfig +class PrometheusInstrument(BaseInstrument[PrometheusConfig]): not_ready_message = "prometheus_metrics_path is empty or not valid" def is_ready(self) -> bool: diff --git a/lite_bootstrap/instruments/pyroscope_instrument.py b/lite_bootstrap/instruments/pyroscope_instrument.py index 4670390..d64d0c1 100644 --- a/lite_bootstrap/instruments/pyroscope_instrument.py +++ b/lite_bootstrap/instruments/pyroscope_instrument.py @@ -19,8 +19,7 @@ class PyroscopeConfig(OpenTelemetryServiceFieldsConfig): @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class PyroscopeInstrument(BaseInstrument): - bootstrap_config: PyroscopeConfig +class PyroscopeInstrument(BaseInstrument[PyroscopeConfig]): not_ready_message = "pyroscope_endpoint is empty" missing_dependency_message = "pyroscope is not installed" diff --git a/lite_bootstrap/instruments/sentry_instrument.py b/lite_bootstrap/instruments/sentry_instrument.py index 370e86f..c109cb6 100644 --- a/lite_bootstrap/instruments/sentry_instrument.py +++ b/lite_bootstrap/instruments/sentry_instrument.py @@ -92,8 +92,7 @@ def run_before_send( @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class SentryInstrument(BaseInstrument): - bootstrap_config: SentryConfig +class SentryInstrument(BaseInstrument[SentryConfig]): not_ready_message = "sentry_dsn is empty" missing_dependency_message = "sentry_sdk is not installed" diff --git a/lite_bootstrap/instruments/swagger_instrument.py b/lite_bootstrap/instruments/swagger_instrument.py index 68e54de..22ef858 100644 --- a/lite_bootstrap/instruments/swagger_instrument.py +++ b/lite_bootstrap/instruments/swagger_instrument.py @@ -11,5 +11,5 @@ class SwaggerConfig(BaseConfig): @dataclasses.dataclass(kw_only=True, slots=True, frozen=True) -class SwaggerInstrument(BaseInstrument): - bootstrap_config: SwaggerConfig +class SwaggerInstrument(BaseInstrument[SwaggerConfig]): + pass