from typing import Literal from pydantic import BaseModel class EncrypterConfig(BaseModel): backend: Literal["fernet", "kms"] class DspConfig(BaseModel): rate_limit_stats_backend: Literal["redis", "memory"] spotify_songwhip_use_faker: bool spotify_smf_use_faker: bool class DataSinkConfig(BaseModel): backend: Literal["postgres", "kafka", "dummy"] class FanFanoutConfig(BaseModel): batch_size: int spotify_smf_batch_size: int | None spotify_songwhip_batch_size: int | None dispatch_backend: Literal["lambda", "dummy"] time_limit_s: int class FanCollectIntervalsConfig(BaseModel): profile_s: int top_artists_s: int top_tracks_s: int recently_played_s: int playlists_s: int saved_albums_s: int saved_tracks_s: int followed_artists_s: int class FanCollectSqsQueueUrlsConfig(BaseModel): spotify_smf: str spotify_songwhip: str class FanCollectConfig(BaseModel): dispatch_backend: Literal["sqs", "dummy"] time_limit_s: int timeout_buffer_s: int rate_limit_circuit_breaker_threshold: int cooldown_s: int concurrency: int spotify_smf_concurrency: int spotify_songwhip_concurrency: int intervals: FanCollectIntervalsConfig sqs_queue_urls: FanCollectSqsQueueUrlsConfig class PipelineRunConfig(BaseModel): stale_timeout_s: int estimate_avg_latency_ms: int class ConfigResponse(BaseModel): encrypter: EncrypterConfig dsp: DspConfig data_sink: DataSinkConfig fan_fanout: FanFanoutConfig fan_collect: FanCollectConfig pipeline_run: PipelineRunConfig