kafka-python 2.2.16__tar.gz → 2.2.17__tar.gz

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.
Files changed (168) hide show
  1. {kafka_python-2.2.16 → kafka_python-2.2.17}/CHANGES.md +12 -1
  2. {kafka_python-2.2.16 → kafka_python-2.2.17}/PKG-INFO +1 -1
  3. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/conn.py +7 -0
  4. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/consumer/group.py +8 -7
  5. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/base.py +1 -0
  6. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/producer/kafka.py +5 -1
  7. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/socks5_wrapper.py +31 -5
  8. kafka_python-2.2.17/kafka/version.py +1 -0
  9. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka_python.egg-info/PKG-INFO +1 -1
  10. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/test_consumer_integration.py +22 -0
  11. kafka_python-2.2.16/kafka/version.py +0 -1
  12. {kafka_python-2.2.16 → kafka_python-2.2.17}/AUTHORS.md +0 -0
  13. {kafka_python-2.2.16 → kafka_python-2.2.17}/LICENSE +0 -0
  14. {kafka_python-2.2.16 → kafka_python-2.2.17}/MANIFEST.in +0 -0
  15. {kafka_python-2.2.16 → kafka_python-2.2.17}/README.rst +0 -0
  16. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/__init__.py +0 -0
  17. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/admin/__init__.py +0 -0
  18. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/admin/acl_resource.py +0 -0
  19. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/admin/client.py +0 -0
  20. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/admin/config_resource.py +0 -0
  21. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/admin/new_partitions.py +0 -0
  22. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/admin/new_topic.py +0 -0
  23. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/__init__.py +0 -0
  24. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/consumer_performance.py +0 -0
  25. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/load_example.py +0 -0
  26. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/producer_performance.py +0 -0
  27. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/record_batch_compose.py +0 -0
  28. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/record_batch_read.py +0 -0
  29. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/benchmarks/varint_speed.py +0 -0
  30. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/client_async.py +0 -0
  31. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/cluster.py +0 -0
  32. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/codec.py +0 -0
  33. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/consumer/__init__.py +0 -0
  34. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/consumer/fetcher.py +0 -0
  35. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/consumer/subscription_state.py +0 -0
  36. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/__init__.py +0 -0
  37. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/__init__.py +0 -0
  38. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/abstract.py +0 -0
  39. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/range.py +0 -0
  40. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/roundrobin.py +0 -0
  41. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
  42. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
  43. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
  44. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
  45. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/consumer.py +0 -0
  46. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/heartbeat.py +0 -0
  47. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/coordinator/protocol.py +0 -0
  48. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/errors.py +0 -0
  49. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/future.py +0 -0
  50. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/__init__.py +0 -0
  51. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/compound_stat.py +0 -0
  52. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/dict_reporter.py +0 -0
  53. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/kafka_metric.py +0 -0
  54. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/measurable.py +0 -0
  55. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/measurable_stat.py +0 -0
  56. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/metric_config.py +0 -0
  57. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/metric_name.py +0 -0
  58. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/metrics.py +0 -0
  59. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/metrics_reporter.py +0 -0
  60. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/quota.py +0 -0
  61. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stat.py +0 -0
  62. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/__init__.py +0 -0
  63. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/avg.py +0 -0
  64. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/count.py +0 -0
  65. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/histogram.py +0 -0
  66. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/max_stat.py +0 -0
  67. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/min_stat.py +0 -0
  68. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/percentile.py +0 -0
  69. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/percentiles.py +0 -0
  70. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/rate.py +0 -0
  71. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/sampled_stat.py +0 -0
  72. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/sensor.py +0 -0
  73. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/metrics/stats/total.py +0 -0
  74. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/partitioner/__init__.py +0 -0
  75. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/partitioner/default.py +0 -0
  76. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/producer/__init__.py +0 -0
  77. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/producer/future.py +0 -0
  78. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/producer/record_accumulator.py +0 -0
  79. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/producer/sender.py +0 -0
  80. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/producer/transaction_manager.py +0 -0
  81. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/__init__.py +0 -0
  82. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/abstract.py +0 -0
  83. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/add_offsets_to_txn.py +0 -0
  84. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/add_partitions_to_txn.py +0 -0
  85. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/admin.py +0 -0
  86. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/api.py +0 -0
  87. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/api_versions.py +0 -0
  88. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/broker_api_versions.py +0 -0
  89. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/commit.py +0 -0
  90. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/end_txn.py +0 -0
  91. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/fetch.py +0 -0
  92. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/find_coordinator.py +0 -0
  93. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/frame.py +0 -0
  94. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/group.py +0 -0
  95. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/init_producer_id.py +0 -0
  96. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/list_offsets.py +0 -0
  97. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/message.py +0 -0
  98. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/metadata.py +0 -0
  99. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/offset_for_leader_epoch.py +0 -0
  100. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/parser.py +0 -0
  101. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/pickle.py +0 -0
  102. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/produce.py +0 -0
  103. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/sasl_authenticate.py +0 -0
  104. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/sasl_handshake.py +0 -0
  105. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/struct.py +0 -0
  106. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/txn_offset_commit.py +0 -0
  107. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/protocol/types.py +0 -0
  108. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/__init__.py +0 -0
  109. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/_crc32c.py +0 -0
  110. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/abc.py +0 -0
  111. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/default_records.py +0 -0
  112. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/legacy_records.py +0 -0
  113. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/memory_records.py +0 -0
  114. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/record/util.py +0 -0
  115. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/__init__.py +0 -0
  116. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/abc.py +0 -0
  117. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/gssapi.py +0 -0
  118. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/msk.py +0 -0
  119. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/oauth.py +0 -0
  120. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/plain.py +0 -0
  121. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/scram.py +0 -0
  122. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/sasl/sspi.py +0 -0
  123. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/serializer/__init__.py +0 -0
  124. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/serializer/abstract.py +0 -0
  125. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/structs.py +0 -0
  126. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/util.py +0 -0
  127. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/vendor/__init__.py +0 -0
  128. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/vendor/enum34.py +0 -0
  129. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/vendor/selectors34.py +0 -0
  130. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/vendor/six.py +0 -0
  131. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka/vendor/socketpair.py +0 -0
  132. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka_python.egg-info/SOURCES.txt +0 -0
  133. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka_python.egg-info/dependency_links.txt +0 -0
  134. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka_python.egg-info/requires.txt +0 -0
  135. {kafka_python-2.2.16 → kafka_python-2.2.17}/kafka_python.egg-info/top_level.txt +0 -0
  136. {kafka_python-2.2.16 → kafka_python-2.2.17}/pyproject.toml +0 -0
  137. {kafka_python-2.2.16 → kafka_python-2.2.17}/setup.cfg +0 -0
  138. {kafka_python-2.2.16 → kafka_python-2.2.17}/setup.py +0 -0
  139. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/__init__.py +0 -0
  140. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/conftest.py +0 -0
  141. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/fixtures.py +0 -0
  142. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/test_admin_integration.py +0 -0
  143. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/test_consumer_group.py +0 -0
  144. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/test_producer_integration.py +0 -0
  145. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/integration/test_sasl_integration.py +0 -0
  146. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_acl_comparisons.py +0 -0
  147. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_admin.py +0 -0
  148. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_api_object_implementation.py +0 -0
  149. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_assignors.py +0 -0
  150. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_client_async.py +0 -0
  151. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_cluster.py +0 -0
  152. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_codec.py +0 -0
  153. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_conn.py +0 -0
  154. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_consumer.py +0 -0
  155. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_coordinator.py +0 -0
  156. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_fetcher.py +0 -0
  157. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_metrics.py +0 -0
  158. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_object_conversion.py +0 -0
  159. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_package.py +0 -0
  160. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_partition_movements.py +0 -0
  161. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_partitioner.py +0 -0
  162. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_producer.py +0 -0
  163. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_protocol.py +0 -0
  164. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_record_accumulator.py +0 -0
  165. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_sender.py +0 -0
  166. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_subscription_state.py +0 -0
  167. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/test_util.py +0 -0
  168. {kafka_python-2.2.16 → kafka_python-2.2.17}/test/testutil.py +0 -0
@@ -1,3 +1,15 @@
1
+ # 2.2.17 (Nov 20, 2025)
2
+
3
+ Fixes
4
+ * Add internal poll to consumer.position() (#2696)
5
+ * Initiate Coordinator Reconnect w/ Backoff from Heartbeat Thread (#2695)
6
+
7
+ Networking
8
+ * SOCKS5: support looking up names remotely (jschwartzenberg / #2666)
9
+
10
+ Documentation
11
+ * Add `transactional_id` to KafkaProducer Keyword Arguments docstring
12
+
1
13
  # 2.2.16 (Nov 18, 2025)
2
14
 
3
15
  Fixes
@@ -32,7 +44,6 @@ Fixes
32
44
  * Avoid RuntimeError on mutated `_completed_fetches` deque in consumer fetcher (#2646)
33
45
  * Throw exception on invalid bucket type (#2642)
34
46
 
35
-
36
47
  # 2.2.11 (June 5, 2025)
37
48
 
38
49
  Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.16
3
+ Version: 2.2.17
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
@@ -326,6 +326,9 @@ class BrokerConnection(object):
326
326
  return True
327
327
 
328
328
  def _next_afi_sockaddr(self):
329
+ if self.config["socks5_proxy"] and Socks5Wrapper.use_remote_lookup(self.config["socks5_proxy"]):
330
+ return (socket.AF_UNSPEC, (self.host, self.port))
331
+
329
332
  if not self._gai:
330
333
  if not self._dns_lookup():
331
334
  return
@@ -379,6 +382,7 @@ class BrokerConnection(object):
379
382
  self._sock_afi, self._sock_addr = next_lookup
380
383
  try:
381
384
  if self.config["socks5_proxy"] is not None:
385
+ log.debug('%s: initializing Socks5 proxy at %s', self, self.config["socks5_proxy"])
382
386
  self._socks5_proxy = Socks5Wrapper(self.config["socks5_proxy"], self.afi)
383
387
  self._sock = self._socks5_proxy.socket(self._sock_afi, socket.SOCK_STREAM)
384
388
  else:
@@ -864,6 +868,8 @@ class BrokerConnection(object):
864
868
  if self.disconnected() or self.connecting():
865
869
  if len(self._gai) > 0:
866
870
  return 0
871
+ elif self.config["socks5_proxy"] and Socks5Wrapper.use_remote_lookup(self.config["socks5_proxy"]):
872
+ return 0
867
873
  else:
868
874
  time_waited = time.time() - self.last_attempt
869
875
  return max(self._reconnect_backoff - time_waited, 0) * 1000
@@ -964,6 +970,7 @@ class BrokerConnection(object):
964
970
  # the socket fd from selectors cleanly.
965
971
  sock = self._sock
966
972
  self._sock = None
973
+ self._socks5_proxy = None
967
974
 
968
975
  # drop lock before state change callback and processing futures
969
976
  self.config['state_change_callback'](self.node_id, sock, self)
@@ -723,7 +723,9 @@ class KafkaConsumer(six.Iterator):
723
723
 
724
724
  # We do not want to be stuck blocking in poll if we are missing some positions
725
725
  # since the offset lookup may be backing off after a failure
726
- poll_timeout_ms = min(timer.timeout_ms, self._coordinator.time_to_next_poll() * 1000)
726
+ poll_timeout_ms = timer.timeout_ms
727
+ if self.config['group_id'] is not None:
728
+ poll_timeout_ms = min(poll_timeout_ms, self._coordinator.time_to_next_poll() * 1000)
727
729
  if not has_all_fetch_positions:
728
730
  log.debug('poll: do not have all fetch positions...')
729
731
  poll_timeout_ms = min(poll_timeout_ms, self.config['retry_backoff_ms'])
@@ -753,13 +755,12 @@ class KafkaConsumer(six.Iterator):
753
755
 
754
756
  timer = Timer(timeout_ms)
755
757
  position = self._subscription.assignment[partition].position
756
- while position is None:
758
+ while position is None and not timer.expired:
757
759
  # batch update fetch positions for any partitions without a valid position
758
- if self._update_fetch_positions(timeout_ms=timer.timeout_ms):
759
- position = self._subscription.assignment[partition].position
760
- if timer.expired:
761
- return None
762
- else:
760
+ self._update_fetch_positions(timeout_ms=timer.timeout_ms)
761
+ self._client.poll(timeout_ms=timer.timeout_ms)
762
+ position = self._subscription.assignment[partition].position
763
+ if position is not None:
763
764
  return position.offset
764
765
 
765
766
  def highwater(self, partition):
@@ -1120,6 +1120,7 @@ class HeartbeatThread(threading.Thread):
1120
1120
  self.coordinator._lock.wait(self.coordinator.config['retry_backoff_ms'] / 1000)
1121
1121
 
1122
1122
  elif not self.coordinator.connected():
1123
+ self.coordinator._client.maybe_connect(self.coordinator.coordinator_id)
1123
1124
  self.coordinator._client._lock.release()
1124
1125
  self.coordinator._lock.wait(self.coordinator.config['retry_backoff_ms'] / 1000)
1125
1126
 
@@ -134,10 +134,14 @@ class KafkaProducer(object):
134
134
  value_serializer (callable): used to convert user-supplied message
135
135
  values to bytes. If not None, called as f(value), should return
136
136
  bytes. Default: None.
137
+ transactional_id (str): Enable transactional producer with a unique
138
+ identifier. This will be used to identify the same producer
139
+ instance across process restarts. Default: None.
137
140
  enable_idempotence (bool): When set to True, the producer will ensure
138
141
  that exactly one copy of each message is written in the stream.
139
142
  If False, producer retries due to broker failures, etc., may write
140
- duplicates of the retried message in the stream. Default: False.
143
+ duplicates of the retried message in the stream.
144
+ Default: True if `transactional_id` is provided, otherwise False.
141
145
 
142
146
  Note that enabling idempotence requires
143
147
  `max_in_flight_requests_per_connection` to be set to 1 and `retries`
@@ -64,6 +64,15 @@ class Socks5Wrapper:
64
64
  log.warning("DNS lookup failed for proxy %s:%d, %r", host, port, ex)
65
65
  return []
66
66
 
67
+ @classmethod
68
+ def use_remote_lookup(cls, proxy_url):
69
+ if proxy_url is None:
70
+ return False
71
+ return urlparse(proxy_url).scheme == 'socks5h'
72
+
73
+ def _use_remote_lookup(self):
74
+ return self._proxy_url.scheme == 'socks5h'
75
+
67
76
  def socket(self, family, sock_type):
68
77
  """Open and record a socket.
69
78
 
@@ -187,7 +196,10 @@ class Socks5Wrapper:
187
196
  return errno.ECONNREFUSED
188
197
 
189
198
  if self._state == ProxyConnectionStates.REQUEST_SUBMIT:
190
- if self._target_afi == socket.AF_INET:
199
+ if self._use_remote_lookup():
200
+ addr_type = 3
201
+ addr_len = len(addr[0])
202
+ elif self._target_afi == socket.AF_INET:
191
203
  addr_type = 1
192
204
  addr_len = 4
193
205
  elif self._target_afi == socket.AF_INET6:
@@ -200,14 +212,28 @@ class Socks5Wrapper:
200
212
  return errno.ECONNREFUSED
201
213
 
202
214
  self._buffer_out = struct.pack(
203
- "!bbbb{}sh".format(addr_len),
215
+ "!bbbb",
204
216
  5, # version
205
217
  1, # command: connect
206
218
  0, # reserved
207
- addr_type, # 1 for ipv4, 4 for ipv6 address
208
- socket.inet_pton(self._target_afi, addr[0]), # either 4 or 16 bytes of actual address
209
- addr[1], # port
219
+ addr_type, # 1 for ipv4, 4 for ipv6 address, 3 for domain name
210
220
  )
221
+ # Addr format depends on type
222
+ if addr_type == 3:
223
+ # len + domain name (no null terminator)
224
+ self._buffer_out += struct.pack(
225
+ "!b{}s".format(addr_len),
226
+ addr_len,
227
+ addr[0].encode('ascii'),
228
+ )
229
+ else:
230
+ # either 4 (type 1) or 16 (type 4) bytes of actual address
231
+ self._buffer_out += struct.pack(
232
+ "!{}s".format(addr_len),
233
+ socket.inet_pton(self._target_afi, addr[0]),
234
+ )
235
+ self._buffer_out += struct.pack("!H", addr[1]) # port
236
+
211
237
  self._state = ProxyConnectionStates.REQUESTING
212
238
 
213
239
  if self._state == ProxyConnectionStates.REQUESTING:
@@ -0,0 +1 @@
1
+ __version__ = '2.2.17'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.16
3
+ Version: 2.2.17
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
@@ -302,3 +302,25 @@ def test_kafka_consumer_offsets_for_times_errors(kafka_consumer_factory, topic):
302
302
 
303
303
  with pytest.raises(KafkaTimeoutError):
304
304
  consumer.offsets_for_times({bad_tp: 0})
305
+
306
+
307
+ @pytest.mark.skipif(not env_kafka_version(), reason="No KAFKA_VERSION set")
308
+ def test_kafka_consumer_position_after_seek_to_end(kafka_consumer_factory, topic, send_messages):
309
+ send_messages(range(0, 10), partition=0)
310
+
311
+ # Start a consumer with manual partition assignment.
312
+ consumer = kafka_consumer_factory(
313
+ topics=(),
314
+ group_id=None,
315
+ enable_auto_commit=False,
316
+ )
317
+ tp = TopicPartition(topic, 0)
318
+ consumer.assign([tp])
319
+
320
+ # Seek to the end of the partition, and call position() to synchronize the
321
+ # partition's offset without calling poll().
322
+ consumer.seek_to_end(tp)
323
+ position = consumer.position(tp, timeout_ms=1000)
324
+
325
+ # Verify we got the expected position
326
+ assert position == 10, f"Expected position 10, got {position}"
@@ -1 +0,0 @@
1
- __version__ = '2.2.16'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes