33import asyncio
44from collections .abc import AsyncGenerator , Callable , Iterable
55from logging import getLogger
6- from typing import Any , TypeAlias , TypeVar
6+ from typing import Any , TypeVar , overload
77
88from aiokafka import AIOKafkaConsumer , AIOKafkaProducer
99from kafka .admin import KafkaAdminClient , NewTopic
1010from kafka .coordinator .assignors .roundrobin import RoundRobinPartitionAssignor
1111from kafka .partitioner .default import DefaultPartitioner
1212from taskiq import AsyncResultBackend , BrokerMessage
1313from taskiq .abc .broker import AsyncBroker
14- from taskiq .decor import AsyncTaskiqDecoratedTask
15- from taskiq .kicker import AsyncKicker
1614from typing_extensions import ParamSpec
1715
18- from taskiq_aio_kafka .exceptions import WrongAioKafkaBrokerParametersError
19- from taskiq_aio_kafka .models import KafkaConsumerParameters , KafkaProducerParameters
20- from taskiq_aio_kafka .topic import Topic
16+ from .constants import TASK_TOPIC_LABEL
17+ from .decorated_task import AioKafkaDecoratedTask
18+ from .exceptions import WrongAioKafkaBrokerParametersError
19+ from .models import KafkaConsumerParameters , KafkaProducerParameters
20+ from .topic import Topic
21+ from .types import TopicType
22+ from .utils import get_topic_name
2123
2224_T = TypeVar ("_T" )
2325_FuncParams = ParamSpec ("_FuncParams" )
2426_ReturnType = TypeVar ("_ReturnType" )
25- TopicType : TypeAlias = str | NewTopic | Topic
26- TASK_TOPIC_LABEL = "taskiq_aio_kafka_topic"
2727
2828
2929logger = getLogger ("taskiq.kafka_broker" )
3030
3131
32- def _get_topic_name (topic : TopicType ) -> str :
33- if isinstance (topic , str ):
34- return topic
35- return topic .name
36-
37-
38- class AioKafkaKicker (AsyncKicker [_FuncParams , _ReturnType ]):
39- """Kicker that can override kafka topic for a task call."""
40-
41- def with_topic (
42- self ,
43- topic : TopicType ,
44- ) -> "AioKafkaKicker[_FuncParams, _ReturnType]" :
45- """Set kafka topic for current kick."""
46- self .labels = {
47- ** self .labels ,
48- TASK_TOPIC_LABEL : _get_topic_name (topic ),
49- }
50- return self
51-
52-
53- class AioKafkaDecoratedTask (AsyncTaskiqDecoratedTask [_FuncParams , _ReturnType ]):
54- """Taskiq decorated task with kafka-specific kicker."""
55-
56- def kicker (self ) -> AioKafkaKicker [_FuncParams , _ReturnType ]:
57- """Return kafka-aware kicker."""
58- return AioKafkaKicker (
59- task_name = self .task_name ,
60- broker = self .broker ,
61- labels = self .labels ,
62- return_type = self .return_type ,
63- )
64-
65-
6632class AioKafkaBroker (AsyncBroker ):
6733 """Broker that works with Kafka."""
6834
@@ -110,7 +76,7 @@ def __init__( # noqa: PLR0913
11076 if kafka_topics is not None :
11177 for topic in kafka_topics :
11278 self ._kafka_topics .setdefault (
113- self . _get_topic_name (topic ),
79+ get_topic_name (topic ),
11480 topic ,
11581 )
11682
@@ -137,10 +103,6 @@ def __init__( # noqa: PLR0913
137103 self ._is_producer_started = False
138104 self ._is_consumer_started = False
139105
140- @staticmethod
141- def _get_topic_name (topic : TopicType ) -> str :
142- return _get_topic_name (topic )
143-
144106 @classmethod
145107 def _normalize_default_topic (
146108 cls ,
@@ -203,21 +165,72 @@ def configure_consumer(self, **consumer_parameters: Any) -> None:
203165 ** consumer_parameters ,
204166 )
205167
206- def task ( # type: ignore[override]
168+ @overload
169+ def task (
170+ self ,
171+ task_name : Callable [_FuncParams , _ReturnType ],
172+ ** labels : Any ,
173+ ) -> AioKafkaDecoratedTask [_FuncParams , _ReturnType ]: ...
174+
175+ @overload
176+ def task (
177+ self ,
178+ task_name : str | None = None ,
179+ ** labels : Any ,
180+ ) -> Callable [
181+ [Callable [_FuncParams , _ReturnType ]],
182+ AioKafkaDecoratedTask [_FuncParams , _ReturnType ],
183+ ]: ...
184+
185+ def task (
186+ self ,
187+ task_name : str | Callable [..., Any ] | None = None ,
188+ ** labels : Any ,
189+ ) -> Any :
190+ """Decorate function."""
191+ if callable (task_name ):
192+ return super ().task (task_name , ** labels )
193+
194+ return super ().task (
195+ task_name = task_name ,
196+ ** labels ,
197+ )
198+
199+ @overload
200+ def task_with_topic (
201+ self ,
202+ topic : TopicType ,
203+ task_name : Callable [_FuncParams , _ReturnType ],
204+ ** labels : Any ,
205+ ) -> AioKafkaDecoratedTask [_FuncParams , _ReturnType ]: ...
206+
207+ @overload
208+ def task_with_topic (
209+ self ,
210+ topic : TopicType ,
211+ task_name : str | None = None ,
212+ ** labels : Any ,
213+ ) -> Callable [
214+ [Callable [_FuncParams , _ReturnType ]],
215+ AioKafkaDecoratedTask [_FuncParams , _ReturnType ],
216+ ]: ...
217+
218+ def task_with_topic (
207219 self ,
220+ topic : TopicType ,
208221 task_name : str | Callable [..., Any ] | None = None ,
209- * ,
210- topic : TopicType | None = None ,
211222 ** labels : Any ,
212223 ) -> Any :
213224 """Decorate function and bind it to a kafka topic by default."""
214- if topic is not None :
215- topic_name = self ._get_topic_name (topic )
216- self ._kafka_topics .setdefault (topic_name , topic )
217- labels [self .task_topic_label ] = topic_name
225+ topic_name = get_topic_name (topic )
226+ self ._kafka_topics .setdefault (topic_name , topic )
227+ labels [self .task_topic_label ] = topic_name
228+
229+ if callable (task_name ):
230+ return super ().task (task_name , ** labels )
218231
219232 return super ().task (
220- task_name = task_name , # type: ignore[arg-type]
233+ task_name = task_name ,
221234 ** labels ,
222235 )
223236
@@ -229,12 +242,13 @@ async def startup(self) -> None:
229242 """
230243 await super ().startup ()
231244 existed_topic_names = set (self ._kafka_admin_client .list_topics ())
232- new_topics = [
233- new_topic
234- for topic in self ._kafka_topics .values ()
235- if (new_topic := self ._get_declaration_topic (topic )) is not None
236- and new_topic .name not in existed_topic_names
237- ]
245+
246+ new_topics = []
247+ for topic in self ._kafka_topics .values ():
248+ new_topic = self ._get_declaration_topic (topic )
249+ if new_topic is not None and new_topic .name not in existed_topic_names :
250+ new_topics .append (new_topic )
251+
238252 if new_topics :
239253 self ._kafka_admin_client .create_topics (
240254 new_topics = new_topics ,
0 commit comments