kafka-python 2.2.1__py2.py3-none-any.whl → 2.2.3__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kafka/admin/client.py CHANGED
@@ -274,7 +274,7 @@ class KafkaAdminClient(object):
274
274
  self._controller_id = controller_id
275
275
  return
276
276
  else:
277
- raise Errors.NodeNotAvailableError('controller')
277
+ raise Errors.NodeNotReadyError('controller')
278
278
  else:
279
279
  raise UnrecognizedBrokerVersion(
280
280
  "Kafka Admin interface cannot determine the controller using MetadataRequest_v{}."
kafka/cluster.py CHANGED
@@ -3,13 +3,15 @@ from __future__ import absolute_import
3
3
  import collections
4
4
  import copy
5
5
  import logging
6
+ import random
7
+ import re
6
8
  import threading
7
9
  import time
8
10
 
9
11
  from kafka.vendor import six
10
12
 
11
13
  from kafka import errors as Errors
12
- from kafka.conn import collect_hosts
14
+ from kafka.conn import get_ip_port_afi
13
15
  from kafka.future import Future
14
16
  from kafka.structs import BrokerMetadata, PartitionMetadata, TopicPartition
15
17
 
@@ -422,3 +424,24 @@ class ClusterMetadata(object):
422
424
  def __str__(self):
423
425
  return 'ClusterMetadata(brokers: %d, topics: %d, coordinators: %d)' % \
424
426
  (len(self._brokers), len(self._partitions), len(self._coordinators))
427
+
428
+
429
+ def collect_hosts(hosts, randomize=True):
430
+ """
431
+ Collects a comma-separated set of hosts (host:port) and optionally
432
+ randomize the returned list.
433
+ """
434
+
435
+ if isinstance(hosts, six.string_types):
436
+ hosts = hosts.strip().split(',')
437
+
438
+ result = []
439
+ for host_port in hosts:
440
+ # ignore leading SECURITY_PROTOCOL:// to mimic java client
441
+ host_port = re.sub('^.*://', '', host_port)
442
+ host, port, afi = get_ip_port_afi(host_port)
443
+ result.append((host, port, afi))
444
+
445
+ if randomize:
446
+ random.shuffle(result)
447
+ return result
kafka/conn.py CHANGED
@@ -4,7 +4,7 @@ import copy
4
4
  import errno
5
5
  import io
6
6
  import logging
7
- from random import shuffle, uniform
7
+ from random import uniform
8
8
 
9
9
  # selectors in stdlib as of py3.4
10
10
  try:
@@ -1496,32 +1496,6 @@ def get_ip_port_afi(host_and_port_str):
1496
1496
  return host, port, af
1497
1497
 
1498
1498
 
1499
- def collect_hosts(hosts, randomize=True):
1500
- """
1501
- Collects a comma-separated set of hosts (host:port) and optionally
1502
- randomize the returned list.
1503
- """
1504
-
1505
- if isinstance(hosts, six.string_types):
1506
- hosts = hosts.strip().split(',')
1507
-
1508
- result = []
1509
- afi = socket.AF_INET
1510
- for host_port in hosts:
1511
-
1512
- host, port, afi = get_ip_port_afi(host_port)
1513
-
1514
- if port < 0:
1515
- port = DEFAULT_KAFKA_PORT
1516
-
1517
- result.append((host, port, afi))
1518
-
1519
- if randomize:
1520
- shuffle(result)
1521
-
1522
- return result
1523
-
1524
-
1525
1499
  def is_inet_4_or_6(gai):
1526
1500
  """Given a getaddrinfo struct, return True iff ipv4 or ipv6"""
1527
1501
  return gai[0] in (socket.AF_INET, socket.AF_INET6)
kafka/consumer/fetcher.py CHANGED
@@ -153,6 +153,7 @@ class Fetcher(six.Iterator):
153
153
  future = self._client.send(node_id, request, wakeup=False)
154
154
  future.add_callback(self._handle_fetch_response, node_id, fetch_offsets, time.time())
155
155
  future.add_errback(self._handle_fetch_error, node_id)
156
+ future.add_both(self._clear_pending_fetch_request, node_id)
156
157
  futures.append(future)
157
158
  self._fetch_futures.extend(futures)
158
159
  self._clean_done_fetch_futures()
@@ -643,36 +644,42 @@ class Fetcher(six.Iterator):
643
644
  log.debug("Skipping fetch for partition %s because node %s is throttled",
644
645
  partition, node_id)
645
646
 
647
+ elif not self._client.ready(node_id):
648
+ # Until we support send request queues, any attempt to send to a not-ready node will be
649
+ # immediately failed with NodeNotReadyError.
650
+ log.debug("Skipping fetch for partition %s because connection to leader node is not ready yet")
651
+
646
652
  elif node_id in self._nodes_with_pending_fetch_requests:
647
653
  log.debug("Skipping fetch for partition %s because there is a pending fetch request to node %s",
648
654
  partition, node_id)
649
- continue
650
655
 
651
- if version < 5:
652
- partition_info = (
653
- partition.partition,
654
- position.offset,
655
- self.config['max_partition_fetch_bytes']
656
- )
657
- elif version <= 8:
658
- partition_info = (
659
- partition.partition,
660
- position.offset,
661
- -1, # log_start_offset is used internally by brokers / replicas only
662
- self.config['max_partition_fetch_bytes'],
663
- )
664
656
  else:
665
- partition_info = (
666
- partition.partition,
667
- position.leader_epoch,
668
- position.offset,
669
- -1, # log_start_offset is used internally by brokers / replicas only
670
- self.config['max_partition_fetch_bytes'],
671
- )
672
-
673
- fetchable[node_id][partition] = partition_info
674
- log.debug("Adding fetch request for partition %s at offset %d",
675
- partition, position.offset)
657
+ # Leader is connected and does not have a pending fetch request
658
+ if version < 5:
659
+ partition_info = (
660
+ partition.partition,
661
+ position.offset,
662
+ self.config['max_partition_fetch_bytes']
663
+ )
664
+ elif version <= 8:
665
+ partition_info = (
666
+ partition.partition,
667
+ position.offset,
668
+ -1, # log_start_offset is used internally by brokers / replicas only
669
+ self.config['max_partition_fetch_bytes'],
670
+ )
671
+ else:
672
+ partition_info = (
673
+ partition.partition,
674
+ position.leader_epoch,
675
+ position.offset,
676
+ -1, # log_start_offset is used internally by brokers / replicas only
677
+ self.config['max_partition_fetch_bytes'],
678
+ )
679
+
680
+ fetchable[node_id][partition] = partition_info
681
+ log.debug("Adding fetch request for partition %s at offset %d",
682
+ partition, position.offset)
676
683
 
677
684
  requests = {}
678
685
  for node_id, next_partitions in six.iteritems(fetchable):
@@ -761,14 +768,18 @@ class Fetcher(six.Iterator):
761
768
 
762
769
  if self._sensors:
763
770
  self._sensors.fetch_latency.record((time.time() - send_time) * 1000)
764
- self._nodes_with_pending_fetch_requests.remove(node_id)
765
771
 
766
772
  def _handle_fetch_error(self, node_id, exception):
767
773
  level = logging.INFO if isinstance(exception, Errors.Cancelled) else logging.ERROR
768
774
  log.log(level, 'Fetch to node %s failed: %s', node_id, exception)
769
775
  if node_id in self._session_handlers:
770
776
  self._session_handlers[node_id].handle_error(exception)
771
- self._nodes_with_pending_fetch_requests.remove(node_id)
777
+
778
+ def _clear_pending_fetch_request(self, node_id, _):
779
+ try:
780
+ self._nodes_with_pending_fetch_requests.remove(node_id)
781
+ except KeyError:
782
+ pass
772
783
 
773
784
  def _parse_fetched_data(self, completed_fetch):
774
785
  tp = completed_fetch.topic_partition
kafka/producer/sender.py CHANGED
@@ -315,7 +315,7 @@ class Sender(threading.Thread):
315
315
  return True
316
316
 
317
317
  except Exception as e:
318
- log.warn("%s: Got an exception when trying to find a node to send a transactional request to. Going to back off and retry", str(self), e)
318
+ log.warn("%s: Got an exception when trying to find a node to send a transactional request to. Going to back off and retry: %s", str(self), e)
319
319
  if next_request_handler.needs_coordinator():
320
320
  self._transaction_manager.lookup_coordinator_for_request(next_request_handler)
321
321
  break
@@ -260,7 +260,7 @@ class TransactionManager(object):
260
260
  with self._lock:
261
261
  if self._current_state == TransactionState.ABORTING_TRANSACTION:
262
262
  log.debug("Skipping transition to abortable error state since the transaction is already being "
263
- " aborted. Underlying exception: ", exc)
263
+ " aborted. Underlying exception: %s", exc)
264
264
  return
265
265
  self._transition_to(TransactionState.ABORTABLE_ERROR, error=exc)
266
266
 
@@ -687,7 +687,7 @@ class AddPartitionsToTxnHandler(TxnRequestHandler):
687
687
  if error is Errors.NoError:
688
688
  continue
689
689
  elif error in (Errors.CoordinatorNotAvailableError, Errors.NotCoordinatorError):
690
- self.transaction_manager._lookup_coordinator('transaction', self.transactiona_id)
690
+ self.transaction_manager._lookup_coordinator('transaction', self.transactional_id)
691
691
  self.reenqueue()
692
692
  return
693
693
  elif error is Errors.ConcurrentTransactionsError:
@@ -726,7 +726,7 @@ class AddPartitionsToTxnHandler(TxnRequestHandler):
726
726
  self.transaction_manager._pending_partitions_in_transaction -= partitions
727
727
 
728
728
  if unauthorized_topics:
729
- self.abortable_error(Errors.TopicAuthorizationError(unauthorized_topics))
729
+ self.abortable_error(Errors.TopicAuthorizationFailedError(unauthorized_topics))
730
730
  elif has_partition_errors:
731
731
  self.abortable_error(Errors.KafkaError("Could not add partitions to transaction due to errors: %s" % (results)))
732
732
  else:
@@ -795,7 +795,7 @@ class FindCoordinatorHandler(TxnRequestHandler):
795
795
  elif error is Errors.TransactionalIdAuthorizationFailedError:
796
796
  self.fatal_error(error())
797
797
  elif error is Errors.GroupAuthorizationFailedError:
798
- self.abortable_error(Errors.GroupAuthorizationError(self._coord_key))
798
+ self.abortable_error(error(self._coord_key))
799
799
  else:
800
800
  self.fatal_error(Errors.KafkaError(
801
801
  "Could not find a coordinator with type %s with key %s due to"
@@ -888,7 +888,7 @@ class AddOffsetsToTxnHandler(TxnRequestHandler):
888
888
  elif error is Errors.TransactionalIdAuthorizationFailedError:
889
889
  self.fatal_error(error())
890
890
  elif error is Errors.GroupAuthorizationFailedError:
891
- self.abortable_error(Errors.GroupAuthorizationError(self.consumer_group_id))
891
+ self.abortable_error(error(self.consumer_group_id))
892
892
  else:
893
893
  self.fatal_error(Errors.KafkaError("Unexpected error in AddOffsetsToTxnResponse: %s" % (error())))
894
894
 
@@ -955,7 +955,7 @@ class TxnOffsetCommitHandler(TxnRequestHandler):
955
955
  elif error is Errors.UnknownTopicOrPartitionError:
956
956
  retriable_failure = True
957
957
  elif error is Errors.GroupAuthorizationFailedError:
958
- self.abortable_error(Errors.GroupAuthorizationError(self.consumer_group_id))
958
+ self.abortable_error(error(self.consumer_group_id))
959
959
  return
960
960
  elif error in (Errors.TransactionalIdAuthorizationFailedError,
961
961
  Errors.InvalidProducerEpochError,
@@ -117,6 +117,8 @@ class DefaultRecordBase(object):
117
117
  checker, name = codecs.has_lz4, "lz4"
118
118
  elif compression_type == self.CODEC_ZSTD:
119
119
  checker, name = codecs.has_zstd, "zstd"
120
+ else:
121
+ raise UnsupportedCodecError("Unrecognized compression type: %s" % (compression_type,))
120
122
  if not checker():
121
123
  raise UnsupportedCodecError(
122
124
  "Libraries for {} compression codec not found".format(name))
kafka/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '2.2.1'
1
+ __version__ = '2.2.3'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.1
3
+ Version: 2.2.3
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dpkp/kafka-python
@@ -1,17 +1,17 @@
1
1
  kafka/__init__.py,sha256=4dvHKZAxmD_4tfJ5wGcRV2X78vPcm8vsUoqceULevjA,1077
2
2
  kafka/client_async.py,sha256=joZB3AnL1mLwvV5fv61Pqn8mkP90FVvzcZ2tZsTGmvM,57060
3
- kafka/cluster.py,sha256=f9VNkWanz8X2Rn67XDdmunfx5aJ4s35JUsF5VYJ5hvk,16143
3
+ kafka/cluster.py,sha256=N3_Al4We4ZhWzz6lVHy6SfqwDZfQy73iV7Qg4g4nxRs,16745
4
4
  kafka/codec.py,sha256=8NZpnehzNrhSBIjzbPVSvyFbSeLAqEntE7BfVHu-_9I,10036
5
- kafka/conn.py,sha256=IdWJTEYTalvsmnT74P0eu1Jzx6YdPyemvQovRoBQ8NM,70019
5
+ kafka/conn.py,sha256=pDmzcn-m8oiFdvYh-97qbRLEBXh0sSl9nT74VIIRuEE,69472
6
6
  kafka/errors.py,sha256=J3R7z2hkbWA1hsD-bGHdRjcz6BYjP6RNVSQswA2UMmE,33749
7
7
  kafka/future.py,sha256=ZQStbfUYIPJRrgMfAWxxjrIRVxsw4WCtSR0J0bkyGno,2847
8
8
  kafka/socks5_wrapper.py,sha256=6woOaCTJXJ5e89_zdyW5BjOpyE4rCbYFH-kd-FeuPuk,9827
9
9
  kafka/structs.py,sha256=SJGzmLdV21jZyQ7247k0WFy16UiusgTHK3I-e4qzI-E,3058
10
10
  kafka/util.py,sha256=LV6BlELC8-889FpWM1RECX25sccoVrY2U0r5dRZjLNo,3781
11
- kafka/version.py,sha256=-7agX4LcQ0956RU4mY0EYyxYQU9llH7JklZOsqoujdU,22
11
+ kafka/version.py,sha256=imyOcBgptJng0fWUAVwWSHYVE3csDgLCIYFSbnvEA-U,22
12
12
  kafka/admin/__init__.py,sha256=S_XxqyyV480_yXhttK79XZqNAmZyXRjspd3SoqYykE8,720
13
13
  kafka/admin/acl_resource.py,sha256=ak_dUsSni4SyP0ORbSKenZpwTy0Ykxq3FSt_9XgLR8k,8265
14
- kafka/admin/client.py,sha256=Mg0iuTFLOwc34JNQs99JvC0uDI_ZwZhF7x2jaEVstT4,78933
14
+ kafka/admin/client.py,sha256=RabA8l8Im3iBEXgPVkiofNW6QyeatQHaymBWFZ8Sxkw,78929
15
15
  kafka/admin/config_resource.py,sha256=_JZWN_Q7jbuTtq2kdfHxWyTt_jI1LI-xnVGsf6oYGyY,1039
16
16
  kafka/admin/new_partitions.py,sha256=rYSb7S6VL706ZauSmiN5J9GDsep0HYRmkkAZUgT2JIg,757
17
17
  kafka/admin/new_topic.py,sha256=fvezLP9JXumqX-nU27Fgo0tj4d85ybcJgKluQImm3-0,1306
@@ -23,7 +23,7 @@ kafka/benchmarks/record_batch_compose.py,sha256=CnUreNg1lUT0Qx9enmSr-THmBl9PjVMf
23
23
  kafka/benchmarks/record_batch_read.py,sha256=vlFaWU2YWI379n_2M8qieb_S2uHUWKV0NquEYy5b-Ho,2184
24
24
  kafka/benchmarks/varint_speed.py,sha256=s4CuvKgDZL-_zna5E3vM8RgHjhXuW6pcaO1z1WYZ_0Y,12585
25
25
  kafka/consumer/__init__.py,sha256=NDdvtyuJgFyQZahqL9i5sYXGP6rOMIXWwHQEaZ1fCcs,122
26
- kafka/consumer/fetcher.py,sha256=0SUg8_8W0b-sVDg8dMq06ydR3P_mIGvUwxfbYI8cUIE,67963
26
+ kafka/consumer/fetcher.py,sha256=EP7SHDS35BaIa3TqAu8GbI1HG8An15twGc9zia6LZ9M,68584
27
27
  kafka/consumer/group.py,sha256=Jvoal4SdOniweXeUhhYR_HxDUJmmUiKf4WrI_tuJfCQ,58857
28
28
  kafka/consumer/subscription_state.py,sha256=f_qJQMhTWQnUd_7lPj43gsagWSKGEmP4jpnEwA6s1Ec,23661
29
29
  kafka/coordinator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -69,8 +69,8 @@ kafka/producer/__init__.py,sha256=i3Wxih0NHjmqCkRNE54ial8fBp9siqabUE6ZGyL6oX8,12
69
69
  kafka/producer/future.py,sha256=UC3-g9QlgVFmbitrtMXVpeP0Pbvr7xl2kcw6bAehKG8,2983
70
70
  kafka/producer/kafka.py,sha256=tDCw1qr--ij4T88h2bIGxH7JQaRukkTl_kgnU83rRio,53379
71
71
  kafka/producer/record_accumulator.py,sha256=a_mdSATxl-3dVT2rVFh1gTwAv0wUzNbGwVXScwWJ5AE,28072
72
- kafka/producer/sender.py,sha256=-QOIp74ony5VwTykxksoIIJVbqZy2N2RJidx2tozpMs,37686
73
- kafka/producer/transaction_manager.py,sha256=cZlKFEZI6CY5zXEcTmCQE7TOyvK5V3H4FZLS1BKKEdY,41603
72
+ kafka/producer/sender.py,sha256=2EeA3c7po89F2BLTPjex8-MFKzrCdbXAPvHHDa0SOec,37690
73
+ kafka/producer/transaction_manager.py,sha256=HNfJNZwNfJtYdftn9SeaDfi7I5MKk0LD3sK64inuPt0,41537
74
74
  kafka/protocol/__init__.py,sha256=T1RBBlTH3zze0Cr1RqemPD4Z1b3IUDRmLOBfZTsPgLs,1184
75
75
  kafka/protocol/abstract.py,sha256=uOnuf6D8OTkL31Tp2QXG3VlzDPHVELGzM_bpSVa-_iw,424
76
76
  kafka/protocol/add_offsets_to_txn.py,sha256=Hya7vg6yqsV9XGLKWi8rES_VuN47-H4fdycg6mx8GLY,1486
@@ -101,7 +101,7 @@ kafka/protocol/types.py,sha256=f-lwfCqsJulYnBT1loek_KbMnZZqItN4YRIONjg3kbE,10244
101
101
  kafka/record/__init__.py,sha256=Q20hP_R5XX3AEnAlPkpoWzTLShESvxUT2OLXmI-JYEQ,129
102
102
  kafka/record/_crc32c.py,sha256=Ok-P62Yvg6D6rMGM9Z56OMjZWQlnps4xBbakg-sdxvI,5761
103
103
  kafka/record/abc.py,sha256=z1UYURHbD2RyyGRpVXKP598jck5eXU9p4M6iUo6ZSFo,4110
104
- kafka/record/default_records.py,sha256=l4DoU9eAkSn_f-ISfrMS8AOVYc846oLV_yMV91hsXH8,25879
104
+ kafka/record/default_records.py,sha256=IuICFp0soETihkp8bUyjjksqTlzU45o-UYmo8joLBmo,25992
105
105
  kafka/record/legacy_records.py,sha256=bm1Y24PLVgLKtWqamESKvMk9P01uw3aQ8Z8q2QHxJy8,18858
106
106
  kafka/record/memory_records.py,sha256=b7RFxvaQ93drXSk3o3_YB3FQlVoESoBlGj3Z5PD25n8,8874
107
107
  kafka/record/util.py,sha256=LDajBWdYVetmXts_t9Q76CxEx7njgC9LnjMgz9yPEMM,3556
@@ -120,7 +120,7 @@ kafka/vendor/enum34.py,sha256=-u-lxAiJMt6ru4Do7NUDY9OpeWkYJMksb2xengJawFE,31204
120
120
  kafka/vendor/selectors34.py,sha256=gxejLO4eXf8mRSGXaQiknPig3GdX1rtsZiYOQJVuAy8,20594
121
121
  kafka/vendor/six.py,sha256=lLBa9_HrANP5BMZ7twEzg1M3wofwPmXyptuWmHX0brY,34826
122
122
  kafka/vendor/socketpair.py,sha256=Fi3PoY1Okkppab720wFk1BhHXyjcw7hi5DwhqrYZH2Y,2737
123
- kafka_python-2.2.1.dist-info/METADATA,sha256=zgYWaouiO6KsqTYxb5PQi5LbEk9iSzttcvJjBq3ie7Q,9951
124
- kafka_python-2.2.1.dist-info/WHEEL,sha256=XAkygS4h1cf0JYWV13kJhTWht2y9NqKAsZuiTHc2920,109
125
- kafka_python-2.2.1.dist-info/top_level.txt,sha256=IivJz7l5WHdLNDT6RIiVAlhjQzYRwGqBBmKHZ7WjPeM,6
126
- kafka_python-2.2.1.dist-info/RECORD,,
123
+ kafka_python-2.2.3.dist-info/METADATA,sha256=5rHeRnLYzvBgmUIntERI45fmOmLAcZtPttVu2DDDZTs,9951
124
+ kafka_python-2.2.3.dist-info/WHEEL,sha256=_itY3bZllKbLk93i0gzNzdweAt5eocJdfN7atrjOnvQ,109
125
+ kafka_python-2.2.3.dist-info/top_level.txt,sha256=IivJz7l5WHdLNDT6RIiVAlhjQzYRwGqBBmKHZ7WjPeM,6
126
+ kafka_python-2.2.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.0.0)
2
+ Generator: setuptools (80.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any