kafka-python 2.2.0__tar.gz → 2.2.2__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.0 → kafka_python-2.2.2}/CHANGES.md +14 -0
  2. {kafka_python-2.2.0 → kafka_python-2.2.2}/PKG-INFO +24 -1
  3. {kafka_python-2.2.0 → kafka_python-2.2.2}/README.rst +23 -0
  4. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/admin/client.py +1 -1
  5. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/conn.py +12 -3
  6. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/consumer/group.py +2 -2
  7. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/producer/sender.py +1 -1
  8. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/producer/transaction_manager.py +6 -6
  9. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/default_records.py +2 -0
  10. kafka_python-2.2.2/kafka/version.py +1 -0
  11. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka_python.egg-info/PKG-INFO +24 -1
  12. kafka_python-2.2.0/kafka/version.py +0 -1
  13. {kafka_python-2.2.0 → kafka_python-2.2.2}/AUTHORS.md +0 -0
  14. {kafka_python-2.2.0 → kafka_python-2.2.2}/LICENSE +0 -0
  15. {kafka_python-2.2.0 → kafka_python-2.2.2}/MANIFEST.in +0 -0
  16. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/__init__.py +0 -0
  17. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/admin/__init__.py +0 -0
  18. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/admin/acl_resource.py +0 -0
  19. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/admin/config_resource.py +0 -0
  20. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/admin/new_partitions.py +0 -0
  21. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/admin/new_topic.py +0 -0
  22. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/__init__.py +0 -0
  23. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/consumer_performance.py +0 -0
  24. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/load_example.py +0 -0
  25. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/producer_performance.py +0 -0
  26. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/record_batch_compose.py +0 -0
  27. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/record_batch_read.py +0 -0
  28. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/benchmarks/varint_speed.py +0 -0
  29. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/client_async.py +0 -0
  30. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/cluster.py +0 -0
  31. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/codec.py +0 -0
  32. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/consumer/__init__.py +0 -0
  33. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/consumer/fetcher.py +0 -0
  34. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/consumer/subscription_state.py +0 -0
  35. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/__init__.py +0 -0
  36. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/__init__.py +0 -0
  37. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/abstract.py +0 -0
  38. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/range.py +0 -0
  39. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/roundrobin.py +0 -0
  40. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
  41. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
  42. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
  43. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
  44. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/base.py +0 -0
  45. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/consumer.py +0 -0
  46. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/heartbeat.py +0 -0
  47. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/coordinator/protocol.py +0 -0
  48. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/errors.py +0 -0
  49. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/future.py +0 -0
  50. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/__init__.py +0 -0
  51. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/compound_stat.py +0 -0
  52. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/dict_reporter.py +0 -0
  53. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/kafka_metric.py +0 -0
  54. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/measurable.py +0 -0
  55. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/measurable_stat.py +0 -0
  56. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/metric_config.py +0 -0
  57. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/metric_name.py +0 -0
  58. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/metrics.py +0 -0
  59. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/metrics_reporter.py +0 -0
  60. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/quota.py +0 -0
  61. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stat.py +0 -0
  62. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/__init__.py +0 -0
  63. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/avg.py +0 -0
  64. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/count.py +0 -0
  65. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/histogram.py +0 -0
  66. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/max_stat.py +0 -0
  67. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/min_stat.py +0 -0
  68. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/percentile.py +0 -0
  69. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/percentiles.py +0 -0
  70. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/rate.py +0 -0
  71. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/sampled_stat.py +0 -0
  72. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/sensor.py +0 -0
  73. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/metrics/stats/total.py +0 -0
  74. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/partitioner/__init__.py +0 -0
  75. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/partitioner/default.py +0 -0
  76. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/producer/__init__.py +0 -0
  77. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/producer/future.py +0 -0
  78. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/producer/kafka.py +0 -0
  79. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/producer/record_accumulator.py +0 -0
  80. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/__init__.py +0 -0
  81. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/abstract.py +0 -0
  82. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/add_offsets_to_txn.py +0 -0
  83. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/add_partitions_to_txn.py +0 -0
  84. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/admin.py +0 -0
  85. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/api.py +0 -0
  86. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/api_versions.py +0 -0
  87. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/broker_api_versions.py +0 -0
  88. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/commit.py +0 -0
  89. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/end_txn.py +0 -0
  90. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/fetch.py +0 -0
  91. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/find_coordinator.py +0 -0
  92. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/frame.py +0 -0
  93. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/group.py +0 -0
  94. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/init_producer_id.py +0 -0
  95. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/list_offsets.py +0 -0
  96. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/message.py +0 -0
  97. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/metadata.py +0 -0
  98. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/offset_for_leader_epoch.py +0 -0
  99. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/parser.py +0 -0
  100. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/pickle.py +0 -0
  101. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/produce.py +0 -0
  102. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/sasl_authenticate.py +0 -0
  103. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/sasl_handshake.py +0 -0
  104. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/struct.py +0 -0
  105. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/txn_offset_commit.py +0 -0
  106. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/protocol/types.py +0 -0
  107. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/__init__.py +0 -0
  108. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/_crc32c.py +0 -0
  109. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/abc.py +0 -0
  110. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/legacy_records.py +0 -0
  111. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/memory_records.py +0 -0
  112. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/record/util.py +0 -0
  113. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/__init__.py +0 -0
  114. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/abc.py +0 -0
  115. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/gssapi.py +0 -0
  116. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/msk.py +0 -0
  117. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/oauth.py +0 -0
  118. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/plain.py +0 -0
  119. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/scram.py +0 -0
  120. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/sasl/sspi.py +0 -0
  121. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/serializer/__init__.py +0 -0
  122. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/serializer/abstract.py +0 -0
  123. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/socks5_wrapper.py +0 -0
  124. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/structs.py +0 -0
  125. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/util.py +0 -0
  126. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/vendor/__init__.py +0 -0
  127. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/vendor/enum34.py +0 -0
  128. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/vendor/selectors34.py +0 -0
  129. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/vendor/six.py +0 -0
  130. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka/vendor/socketpair.py +0 -0
  131. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka_python.egg-info/SOURCES.txt +0 -0
  132. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka_python.egg-info/dependency_links.txt +0 -0
  133. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka_python.egg-info/requires.txt +0 -0
  134. {kafka_python-2.2.0 → kafka_python-2.2.2}/kafka_python.egg-info/top_level.txt +0 -0
  135. {kafka_python-2.2.0 → kafka_python-2.2.2}/pyproject.toml +0 -0
  136. {kafka_python-2.2.0 → kafka_python-2.2.2}/setup.cfg +0 -0
  137. {kafka_python-2.2.0 → kafka_python-2.2.2}/setup.py +0 -0
  138. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/__init__.py +0 -0
  139. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/conftest.py +0 -0
  140. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/fixtures.py +0 -0
  141. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/test_admin_integration.py +0 -0
  142. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/test_consumer_group.py +0 -0
  143. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/test_consumer_integration.py +0 -0
  144. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/test_producer_integration.py +0 -0
  145. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/integration/test_sasl_integration.py +0 -0
  146. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_acl_comparisons.py +0 -0
  147. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_admin.py +0 -0
  148. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_api_object_implementation.py +0 -0
  149. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_assignors.py +0 -0
  150. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_client_async.py +0 -0
  151. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_cluster.py +0 -0
  152. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_codec.py +0 -0
  153. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_conn.py +0 -0
  154. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_consumer.py +0 -0
  155. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_coordinator.py +0 -0
  156. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_fetcher.py +0 -0
  157. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_metrics.py +0 -0
  158. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_object_conversion.py +0 -0
  159. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_package.py +0 -0
  160. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_partition_movements.py +0 -0
  161. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_partitioner.py +0 -0
  162. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_producer.py +0 -0
  163. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_protocol.py +0 -0
  164. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_record_accumulator.py +0 -0
  165. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_sender.py +0 -0
  166. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_subscription_state.py +0 -0
  167. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/test_util.py +0 -0
  168. {kafka_python-2.2.0 → kafka_python-2.2.2}/test/testutil.py +0 -0
@@ -1,3 +1,17 @@
1
+ # 2.2.2 (Apr 30, 2025)
2
+
3
+ Fixes
4
+ * Fix lint errors
5
+
6
+ # 2.2.1 (Apr 29, 2025)
7
+
8
+ Fixes
9
+ * Always try ApiVersionsRequest v0, even on broker disconnect (#2603)
10
+ * Fix SubscriptionState AttributeError in KafkaConsumer (#2599)
11
+
12
+ Documentation
13
+ * Add transactional examples to docs
14
+
1
15
  # 2.2.0 (Apr 28, 2025)
2
16
 
3
17
  KafkaProducer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.0
3
+ Version: 2.2.2
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
@@ -138,6 +138,14 @@ that expose basic message attributes: topic, partition, offset, key, and value:
138
138
  for msg in consumer:
139
139
  print (msg.headers)
140
140
 
141
+ .. code-block:: python
142
+
143
+ # Read only committed messages from transactional topic
144
+ consumer = KafkaConsumer(isolation_level='read_committed')
145
+ consumer.subscribe(['txn_topic'])
146
+ for msg in consumer:
147
+ print(msg)
148
+
141
149
  .. code-block:: python
142
150
 
143
151
  # Get consumer metrics
@@ -197,6 +205,21 @@ for more details.
197
205
  for i in range(1000):
198
206
  producer.send('foobar', b'msg %d' % i)
199
207
 
208
+ .. code-block:: python
209
+
210
+ # Use transactions
211
+ producer = KafkaProducer(transactional_id='fizzbuzz')
212
+ producer.init_transactions()
213
+ producer.begin_transaction()
214
+ future = producer.send('txn_topic', value=b'yes')
215
+ future.get() # wait for successful produce
216
+ producer.commit_transaction() # commit the transaction
217
+
218
+ producer.begin_transaction()
219
+ future = producer.send('txn_topic', value=b'no')
220
+ future.get() # wait for successful produce
221
+ producer.abort_transaction() # abort the transaction
222
+
200
223
  .. code-block:: python
201
224
 
202
225
  # Include record headers. The format is list of tuples with string key
@@ -94,6 +94,14 @@ that expose basic message attributes: topic, partition, offset, key, and value:
94
94
  for msg in consumer:
95
95
  print (msg.headers)
96
96
 
97
+ .. code-block:: python
98
+
99
+ # Read only committed messages from transactional topic
100
+ consumer = KafkaConsumer(isolation_level='read_committed')
101
+ consumer.subscribe(['txn_topic'])
102
+ for msg in consumer:
103
+ print(msg)
104
+
97
105
  .. code-block:: python
98
106
 
99
107
  # Get consumer metrics
@@ -153,6 +161,21 @@ for more details.
153
161
  for i in range(1000):
154
162
  producer.send('foobar', b'msg %d' % i)
155
163
 
164
+ .. code-block:: python
165
+
166
+ # Use transactions
167
+ producer = KafkaProducer(transactional_id='fizzbuzz')
168
+ producer.init_transactions()
169
+ producer.begin_transaction()
170
+ future = producer.send('txn_topic', value=b'yes')
171
+ future.get() # wait for successful produce
172
+ producer.commit_transaction() # commit the transaction
173
+
174
+ producer.begin_transaction()
175
+ future = producer.send('txn_topic', value=b'no')
176
+ future.get() # wait for successful produce
177
+ producer.abort_transaction() # abort the transaction
178
+
156
179
  .. code-block:: python
157
180
 
158
181
  # Include record headers. The format is list of tuples with string key
@@ -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{}."
@@ -301,6 +301,7 @@ class BrokerConnection(object):
301
301
  if self.config['ssl_context'] is not None:
302
302
  self._ssl_context = self.config['ssl_context']
303
303
  self._api_versions_future = None
304
+ self._api_versions_check_timeout = self.config['api_version_auto_timeout_ms']
304
305
  self._sasl_auth_future = None
305
306
  self.last_attempt = 0
306
307
  self._gai = []
@@ -557,7 +558,8 @@ class BrokerConnection(object):
557
558
  else:
558
559
  request = ApiVersionsRequest[version]()
559
560
  future = Future()
560
- response = self._send(request, blocking=True, request_timeout_ms=(self.config['api_version_auto_timeout_ms'] * 0.8))
561
+ self._api_versions_check_timeout /= 2
562
+ response = self._send(request, blocking=True, request_timeout_ms=self._api_versions_check_timeout)
561
563
  response.add_callback(self._handle_api_versions_response, future)
562
564
  response.add_errback(self._handle_api_versions_failure, future)
563
565
  self._api_versions_future = future
@@ -566,7 +568,8 @@ class BrokerConnection(object):
566
568
  elif self._check_version_idx < len(self.VERSION_CHECKS):
567
569
  version, request = self.VERSION_CHECKS[self._check_version_idx]
568
570
  future = Future()
569
- response = self._send(request, blocking=True, request_timeout_ms=(self.config['api_version_auto_timeout_ms'] * 0.8))
571
+ self._api_versions_check_timeout /= 2
572
+ response = self._send(request, blocking=True, request_timeout_ms=self._api_versions_check_timeout)
570
573
  response.add_callback(self._handle_check_version_response, future, version)
571
574
  response.add_errback(self._handle_check_version_failure, future)
572
575
  self._api_versions_future = future
@@ -618,7 +621,13 @@ class BrokerConnection(object):
618
621
 
619
622
  def _handle_api_versions_failure(self, future, ex):
620
623
  future.failure(ex)
621
- self._check_version_idx = 0
624
+ # Modern brokers should not disconnect on unrecognized api-versions request,
625
+ # but in case they do we always want to try v0 as a fallback
626
+ # otherwise switch to check_version probe.
627
+ if self._api_versions_idx > 0:
628
+ self._api_versions_idx = 0
629
+ else:
630
+ self._check_version_idx = 0
622
631
  # after failure connection is closed, so state should already be DISCONNECTED
623
632
 
624
633
  def _handle_check_version_response(self, future, version, _response):
@@ -877,7 +877,7 @@ class KafkaConsumer(six.Iterator):
877
877
 
878
878
  for tp in partitions:
879
879
  log.debug("Seeking to beginning of partition %s", tp)
880
- self._subscription.need_offset_reset(tp, OffsetResetStrategy.EARLIEST)
880
+ self._subscription.request_offset_reset(tp, OffsetResetStrategy.EARLIEST)
881
881
  self._iterator = None
882
882
 
883
883
  def seek_to_end(self, *partitions):
@@ -902,7 +902,7 @@ class KafkaConsumer(six.Iterator):
902
902
 
903
903
  for tp in partitions:
904
904
  log.debug("Seeking to end of partition %s", tp)
905
- self._subscription.need_offset_reset(tp, OffsetResetStrategy.LATEST)
905
+ self._subscription.request_offset_reset(tp, OffsetResetStrategy.LATEST)
906
906
  self._iterator = None
907
907
 
908
908
  def subscribe(self, topics=(), pattern=None, listener=None):
@@ -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))
@@ -0,0 +1 @@
1
+ __version__ = '2.2.2'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.0
3
+ Version: 2.2.2
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
@@ -138,6 +138,14 @@ that expose basic message attributes: topic, partition, offset, key, and value:
138
138
  for msg in consumer:
139
139
  print (msg.headers)
140
140
 
141
+ .. code-block:: python
142
+
143
+ # Read only committed messages from transactional topic
144
+ consumer = KafkaConsumer(isolation_level='read_committed')
145
+ consumer.subscribe(['txn_topic'])
146
+ for msg in consumer:
147
+ print(msg)
148
+
141
149
  .. code-block:: python
142
150
 
143
151
  # Get consumer metrics
@@ -197,6 +205,21 @@ for more details.
197
205
  for i in range(1000):
198
206
  producer.send('foobar', b'msg %d' % i)
199
207
 
208
+ .. code-block:: python
209
+
210
+ # Use transactions
211
+ producer = KafkaProducer(transactional_id='fizzbuzz')
212
+ producer.init_transactions()
213
+ producer.begin_transaction()
214
+ future = producer.send('txn_topic', value=b'yes')
215
+ future.get() # wait for successful produce
216
+ producer.commit_transaction() # commit the transaction
217
+
218
+ producer.begin_transaction()
219
+ future = producer.send('txn_topic', value=b'no')
220
+ future.get() # wait for successful produce
221
+ producer.abort_transaction() # abort the transaction
222
+
200
223
  .. code-block:: python
201
224
 
202
225
  # Include record headers. The format is list of tuples with string key
@@ -1 +0,0 @@
1
- __version__ = '2.2.0'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes