11from __future__ import annotations
22
33import asyncio
4+ import contextlib
45import json
56from logging import getLogger
67from typing import (
1415 Protocol ,
1516 Sequence ,
1617 Tuple ,
18+ cast ,
1719)
1820
1921import aiokafka
@@ -89,7 +91,7 @@ def _extract_client_id(client: aiokafka.AIOKafkaClient) -> str:
8991def _extract_consumer_group (
9092 consumer : aiokafka .AIOKafkaConsumer ,
9193) -> str | None :
92- return consumer ._group_id
94+ return consumer ._group_id # type: ignore[reportUnknownVariableType]
9395
9496
9597def _extract_argument (
@@ -139,6 +141,17 @@ def _move_headers_to_kwargs(
139141 return args [:5 ], kwargs
140142
141143
144+ def _deserialize_key (key : object | None ) -> str | None :
145+ if key is None :
146+ return None
147+
148+ if isinstance (key , bytes ):
149+ with contextlib .suppress (UnicodeDecodeError ):
150+ return key .decode ()
151+
152+ return str (key )
153+
154+
142155async def _extract_send_partition (
143156 instance : aiokafka .AIOKafkaProducer ,
144157 args : tuple [Any , ...],
@@ -150,17 +163,20 @@ async def _extract_send_partition(
150163 key = _extract_send_key (args , kwargs )
151164 value = _extract_send_value (args , kwargs )
152165 partition = _extract_argument ("partition" , 3 , None , args , kwargs )
153- key_bytes , value_bytes = instance ._serialize (topic , key , value )
166+ key_bytes , value_bytes = cast (
167+ tuple [bytes | None , bytes | None ],
168+ instance ._serialize (topic , key , value ), # type: ignore[reportUnknownMemberType]
169+ )
154170 valid_types = (bytes , bytearray , memoryview , type (None ))
155171 if (
156172 type (key_bytes ) not in valid_types
157173 or type (value_bytes ) not in valid_types
158174 ):
159175 return None
160176
161- await instance .client ._wait_on_metadata (topic )
177+ await instance .client ._wait_on_metadata (topic ) # type: ignore[reportUnknownMemberType]
162178
163- return instance ._partition (
179+ return instance ._partition ( # type: ignore[reportUnknownMemberType]
164180 topic , partition , key , value , key_bytes , value_bytes
165181 )
166182 except Exception as exception : # pylint: disable=W0703
@@ -170,26 +186,21 @@ async def _extract_send_partition(
170186
171187class AIOKafkaContextGetter (textmap .Getter ["HeadersT" ]):
172188 def get (self , carrier : HeadersT , key : str ) -> list [str ] | None :
173- if carrier is None :
174- return None
175-
176189 for item_key , value in carrier :
177190 if item_key == key :
178191 if value is not None :
179192 return [value .decode ()]
180193 return None
181194
182195 def keys (self , carrier : HeadersT ) -> list [str ]:
183- if carrier is None :
184- return []
185- return [key for (key , value ) in carrier ]
196+ return [key for (key , _ ) in carrier ]
186197
187198
188199class AIOKafkaContextSetter (textmap .Setter ["HeadersT" ]):
189200 def set (
190201 self , carrier : HeadersT , key : str | None , value : str | None
191202 ) -> None :
192- if carrier is None or key is None :
203+ if key is None :
193204 return
194205
195206 if not isinstance (carrier , MutableSequence ):
@@ -215,7 +226,7 @@ def _enrich_base_span(
215226 client_id : str ,
216227 topic : str ,
217228 partition : int | None ,
218- key : object | None ,
229+ key : str | None ,
219230) -> None :
220231 span .set_attribute (
221232 messaging_attributes .MESSAGING_SYSTEM ,
@@ -235,8 +246,7 @@ def _enrich_base_span(
235246
236247 if key is not None :
237248 span .set_attribute (
238- messaging_attributes .MESSAGING_KAFKA_MESSAGE_KEY ,
239- key , # FIXME: serialize key to str?
249+ messaging_attributes .MESSAGING_KAFKA_MESSAGE_KEY , key
240250 )
241251
242252
@@ -247,7 +257,7 @@ def _enrich_send_span(
247257 client_id : str ,
248258 topic : str ,
249259 partition : int | None ,
250- key : object | None ,
260+ key : str | None ,
251261) -> None :
252262 if not span .is_recording ():
253263 return
@@ -276,7 +286,7 @@ def _enrich_getone_span(
276286 consumer_group : str | None ,
277287 topic : str ,
278288 partition : int | None ,
279- key : object | None ,
289+ key : str | None ,
280290 offset : int ,
281291) -> None :
282292 if not span .is_recording ():
@@ -399,7 +409,7 @@ def _get_span_name(operation: str, topic: str):
399409 return f"{ topic } { operation } "
400410
401411
402- def _wrap_send (
412+ def _wrap_send ( # type: ignore[reportUnusedFunction]
403413 tracer : Tracer , async_produce_hook : ProduceHookT
404414) -> Callable [..., Awaitable [asyncio .Future [RecordMetadata ]]]:
405415 async def _traced_send (
@@ -417,7 +427,7 @@ async def _traced_send(
417427 topic = _extract_send_topic (args , kwargs )
418428 bootstrap_servers = _extract_bootstrap_servers (instance .client )
419429 client_id = _extract_client_id (instance .client )
420- key = _extract_send_key (args , kwargs )
430+ key = _deserialize_key ( _extract_send_key (args , kwargs ) )
421431 partition = await _extract_send_partition (instance , args , kwargs )
422432 span_name = _get_span_name ("send" , topic )
423433 with tracer .start_as_current_span (
@@ -473,7 +483,7 @@ async def _create_consumer_span(
473483 consumer_group = consumer_group ,
474484 topic = record .topic ,
475485 partition = record .partition ,
476- key = record .key ,
486+ key = _deserialize_key ( record .key ) ,
477487 offset = record .offset ,
478488 )
479489 try :
@@ -486,7 +496,7 @@ async def _create_consumer_span(
486496 return span
487497
488498
489- def _wrap_getone (
499+ def _wrap_getone ( # type: ignore[reportUnusedFunction]
490500 tracer : Tracer , async_consume_hook : ConsumeHookT
491501) -> Callable [..., Awaitable [aiokafka .ConsumerRecord [object , object ]]]:
492502 async def _traced_getone (
@@ -521,7 +531,7 @@ async def _traced_getone(
521531 return _traced_getone
522532
523533
524- def _wrap_getmany (
534+ def _wrap_getmany ( # type: ignore[reportUnusedFunction]
525535 tracer : Tracer , async_consume_hook : ConsumeHookT
526536) -> Callable [
527537 ...,
0 commit comments