Source code for litestar_queues.execution.kafka.config

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any, ClassVar

from litestar_queues.exceptions import QueueConfigurationError

if TYPE_CHECKING:
    from litestar_queues.config import QueueConfig

__all__ = ("KafkaExecutionConfig",)


[docs] @dataclass(slots=True) class KafkaExecutionConfig: """Kafka execution-dispatch configuration.""" backend_name: "ClassVar[str]" = "kafka" bootstrap_servers: "str" """Comma-separated Kafka bootstrap servers.""" topic: "str" = "litestar-queues" """Topic receiving task-id dispatch records.""" consumer_group: "str" = "litestar-queues" """Consumer group used by ``litestar queues run-consumer``.""" dispatch_stale_after: "int" = 60 """Age after which a reserved attempt can be rotated and republished.""" api_timeout: "float" = 30 """Timeout applied to producer delivery acknowledgements.""" producer_options: "dict[str, Any]" = field(default_factory=dict, repr=False) """Additional ``AIOKafkaProducer`` options, such as TLS or SASL settings.""" consumer_options: "dict[str, Any]" = field(default_factory=dict, repr=False) """Additional ``AIOKafkaConsumer`` options, such as TLS or SASL settings.""" def __post_init__(self) -> "None": for field_name in ("bootstrap_servers", "topic", "consumer_group"): value = getattr(self, field_name) if not isinstance(value, str) or not value.strip(): msg = f"KafkaExecutionConfig.{field_name} must not be empty." raise QueueConfigurationError(msg) if self.dispatch_stale_after <= 0 or self.api_timeout <= 0: msg = "dispatch_stale_after and api_timeout must be positive." raise QueueConfigurationError(msg) producer_owned = {"acks", "bootstrap_servers"}.intersection(self.producer_options) consumer_owned = {"auto_offset_reset", "bootstrap_servers", "enable_auto_commit", "group_id"}.intersection( self.consumer_options ) invalid = [ *(f"producer_options.{name}" for name in sorted(producer_owned)), *(f"consumer_options.{name}" for name in sorted(consumer_owned)), ] if invalid: msg = f"Kafka client options are owned by the backend and cannot be overridden: {', '.join(invalid)}." raise QueueConfigurationError(msg) def __repr__(self) -> "str": return ( "KafkaExecutionConfig(bootstrap_servers='<redacted>', " f"topic={self.topic!r}, consumer_group={self.consumer_group!r}, " f"dispatch_stale_after={self.dispatch_stale_after!r}, api_timeout={self.api_timeout!r})" )
def _execution_config_from_queue_config(config: "QueueConfig | None") -> "KafkaExecutionConfig": if config is not None and isinstance(config.execution_backend, KafkaExecutionConfig): return config.execution_backend msg = "Kafka execution requires QueueConfig.execution_backend=KafkaExecutionConfig(...)." raise QueueConfigurationError(msg)