kafka-python 2.1.1__tar.gz → 2.1.3__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.
- {kafka_python-2.1.1 → kafka_python-2.1.3}/CHANGES.md +41 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/PKG-INFO +3 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/admin/client.py +1 -1
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/client_async.py +8 -1
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/cluster.py +1 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/conn.py +21 -4
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/consumer/fetcher.py +209 -252
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/consumer/group.py +27 -19
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/consumer/subscription_state.py +69 -63
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/base.py +11 -9
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/consumer.py +12 -5
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/compound_stat.py +2 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/measurable_stat.py +2 -1
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/metrics_reporter.py +3 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stat.py +3 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/sampled_stat.py +2 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/producer/kafka.py +5 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/abstract.py +3 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/admin.py +2 -1
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/api.py +12 -9
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/api_versions.py +45 -1
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/broker_api_versions.py +2 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/parser.py +7 -6
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/abc.py +22 -4
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/default_records.py +17 -9
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/legacy_records.py +33 -10
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/memory_records.py +6 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/abc.py +3 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/util.py +24 -0
- kafka_python-2.1.3/kafka/version.py +1 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka_python.egg-info/PKG-INFO +3 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka_python.egg-info/SOURCES.txt +1 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/pyproject.toml +1 -0
- kafka_python-2.1.3/test/test_consumer.py +52 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_consumer_group.py +7 -6
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_consumer_integration.py +2 -2
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_coordinator.py +1 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_fetcher.py +47 -51
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_producer.py +1 -1
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_sasl_integration.py +1 -1
- kafka_python-2.1.3/test/test_subscription_state.py +57 -0
- kafka_python-2.1.1/test/test_subscription_state.py → kafka_python-2.1.3/test/test_util.py +2 -3
- kafka_python-2.1.1/kafka/version.py +0 -1
- kafka_python-2.1.1/test/test_consumer.py +0 -26
- {kafka_python-2.1.1 → kafka_python-2.1.3}/AUTHORS.md +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/LICENSE +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/MANIFEST.in +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/README.rst +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/admin/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/admin/acl_resource.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/admin/config_resource.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/admin/new_partitions.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/admin/new_topic.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/codec.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/consumer/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/abstract.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/range.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/roundrobin.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/heartbeat.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/coordinator/protocol.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/errors.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/future.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/dict_reporter.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/kafka_metric.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/measurable.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/metric_config.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/metric_name.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/metrics.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/quota.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/avg.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/count.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/histogram.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/max_stat.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/min_stat.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/percentile.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/percentiles.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/rate.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/sensor.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/metrics/stats/total.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/partitioner/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/partitioner/default.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/producer/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/producer/buffer.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/producer/future.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/producer/record_accumulator.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/producer/sender.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/commit.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/fetch.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/find_coordinator.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/frame.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/group.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/list_offsets.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/message.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/metadata.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/offset_for_leader_epoch.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/pickle.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/produce.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/sasl_authenticate.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/sasl_handshake.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/struct.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/protocol/types.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/_crc32c.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/record/util.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/gssapi.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/msk.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/oauth.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/plain.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/scram.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/sasl/sspi.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/serializer/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/serializer/abstract.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/socks5_wrapper.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/structs.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/vendor/__init__.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/vendor/enum34.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/vendor/selectors34.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/vendor/six.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka/vendor/socketpair.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka_python.egg-info/dependency_links.txt +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka_python.egg-info/requires.txt +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/kafka_python.egg-info/top_level.txt +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/setup.cfg +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/setup.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_acl_comparisons.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_admin.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_admin_integration.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_api_object_implementation.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_assignors.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_client_async.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_cluster.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_codec.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_conn.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_metrics.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_object_conversion.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_package.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_partition_movements.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_partitioner.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_protocol.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/test_sender.py +0 -0
- {kafka_python-2.1.1 → kafka_python-2.1.3}/test/testutil.py +0 -0
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
# 2.1.3 (Mar 25, 2025)
|
|
2
|
+
|
|
3
|
+
Fixes
|
|
4
|
+
* Fix crash when switching to closest compatible api_version in KafkaClient (#2567)
|
|
5
|
+
* Fix maximum version to send an OffsetFetchRequest in KafkaAdminClient (#2563)
|
|
6
|
+
* Return empty set from consumer.partitions_for_topic when topic not found (#2556)
|
|
7
|
+
|
|
8
|
+
Improvements
|
|
9
|
+
* KIP-511: Use ApiVersions v4 on initial connect w/ client_software_name + version (#2558)
|
|
10
|
+
* KIP-74: Manage assigned partition order in consumer (#2562)
|
|
11
|
+
* KIP-70: Auto-commit offsets on consumer.unsubscribe(), defer assignment changes to rejoin (#2560)
|
|
12
|
+
* Use SubscriptionType to track topics/pattern/user assignment (#2565)
|
|
13
|
+
* Add optional timeout_ms kwarg to consumer.close() (#2564)
|
|
14
|
+
* Move ensure_valid_topic_name to kafka.util; use in client and producer (#2561)
|
|
15
|
+
|
|
16
|
+
Testing
|
|
17
|
+
* Support KRaft / 4.0 brokers in tests (#2559)
|
|
18
|
+
* Test older pythons against 4.0 broker
|
|
19
|
+
|
|
20
|
+
Compatibility
|
|
21
|
+
* Add python 3.13 to compatibility list
|
|
22
|
+
|
|
23
|
+
# 2.1.2 (Mar 17, 2025)
|
|
24
|
+
|
|
25
|
+
Fixes
|
|
26
|
+
* Simplify consumer.poll send fetches logic
|
|
27
|
+
* Fix crc validation in consumer / fetcher
|
|
28
|
+
* Lazy `_unpack_records` in PartitionRecords to fix premature fetch offset advance in consumer.poll() (#2555)
|
|
29
|
+
* Debug log fetch records return; separate offsets update log
|
|
30
|
+
* Fix Fetcher retriable error handling (#2554)
|
|
31
|
+
* Use six.add_metaclass for py2/py3 compatible abc (#2551)
|
|
32
|
+
|
|
33
|
+
Improvements
|
|
34
|
+
* Add FetchMetrics class; move topic_fetch_metrics inside aggregator
|
|
35
|
+
* DefaultRecordsBatchBuilder: support empty batch
|
|
36
|
+
* MemoryRecordsBuilder: support arbitrary offset, skipping offsets
|
|
37
|
+
* Add record.validate_crc() for v0/v1 crc checks
|
|
38
|
+
* Remove fetcher message_generator / iterator interface
|
|
39
|
+
* Add size_in_bytes to ABCRecordBatch and implement for Legacy and Default
|
|
40
|
+
* Add magic property to ABCRecord and implement for LegacyRecord
|
|
41
|
+
|
|
1
42
|
# 2.1.1 (Mar 16, 2025)
|
|
2
43
|
|
|
3
44
|
Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: kafka-python
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.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
|
|
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
25
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
25
26
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
26
27
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -1496,7 +1496,7 @@ class KafkaAdminClient(object):
|
|
|
1496
1496
|
A message future
|
|
1497
1497
|
"""
|
|
1498
1498
|
version = self._client.api_version(OffsetFetchRequest, max_version=5)
|
|
1499
|
-
if version <=
|
|
1499
|
+
if version <= 5:
|
|
1500
1500
|
if partitions is None:
|
|
1501
1501
|
if version <= 1:
|
|
1502
1502
|
raise ValueError(
|
|
@@ -27,7 +27,7 @@ from kafka.metrics.stats import Avg, Count, Rate
|
|
|
27
27
|
from kafka.metrics.stats.rate import TimeUnit
|
|
28
28
|
from kafka.protocol.broker_api_versions import BROKER_API_VERSIONS
|
|
29
29
|
from kafka.protocol.metadata import MetadataRequest
|
|
30
|
-
from kafka.util import Dict, WeakMethod
|
|
30
|
+
from kafka.util import Dict, WeakMethod, ensure_valid_topic_name
|
|
31
31
|
# Although this looks unused, it actually monkey-patches socket.socketpair()
|
|
32
32
|
# and should be left in as long as we're using socket.socketpair() in this file
|
|
33
33
|
from kafka.vendor import socketpair # noqa: F401
|
|
@@ -276,6 +276,7 @@ class KafkaClient(object):
|
|
|
276
276
|
if compatible_version:
|
|
277
277
|
log.warning('Configured api_version %s not supported; using %s',
|
|
278
278
|
self.config['api_version'], compatible_version)
|
|
279
|
+
self.config['api_version'] = compatible_version
|
|
279
280
|
self._api_versions = BROKER_API_VERSIONS[compatible_version]
|
|
280
281
|
else:
|
|
281
282
|
raise Errors.UnrecognizedBrokerVersion(self.config['api_version'])
|
|
@@ -909,7 +910,13 @@ class KafkaClient(object):
|
|
|
909
910
|
|
|
910
911
|
Returns:
|
|
911
912
|
Future: resolves after metadata request/response
|
|
913
|
+
|
|
914
|
+
Raises:
|
|
915
|
+
TypeError: if topic is not a string
|
|
916
|
+
ValueError: if topic is invalid: must be chars (a-zA-Z0-9._-), and less than 250 length
|
|
912
917
|
"""
|
|
918
|
+
ensure_valid_topic_name(topic)
|
|
919
|
+
|
|
913
920
|
if topic in self._topics:
|
|
914
921
|
return Future().success(set(self._topics))
|
|
915
922
|
|
|
@@ -101,6 +101,10 @@ class BrokerConnection(object):
|
|
|
101
101
|
server-side log entries that correspond to this client. Also
|
|
102
102
|
submitted to GroupCoordinator for logging with respect to
|
|
103
103
|
consumer group administration. Default: 'kafka-python-{version}'
|
|
104
|
+
client_software_name (str): Sent to kafka broker for KIP-511.
|
|
105
|
+
Default: 'kafka-python'
|
|
106
|
+
client_software_version (str): Sent to kafka broker for KIP-511.
|
|
107
|
+
Default: The kafka-python version (via kafka.version).
|
|
104
108
|
reconnect_backoff_ms (int): The amount of time in milliseconds to
|
|
105
109
|
wait before attempting to reconnect to a given host.
|
|
106
110
|
Default: 50.
|
|
@@ -191,6 +195,8 @@ class BrokerConnection(object):
|
|
|
191
195
|
|
|
192
196
|
DEFAULT_CONFIG = {
|
|
193
197
|
'client_id': 'kafka-python-' + __version__,
|
|
198
|
+
'client_software_name': 'kafka-python',
|
|
199
|
+
'client_software_version': __version__,
|
|
194
200
|
'node_id': 0,
|
|
195
201
|
'request_timeout_ms': 30000,
|
|
196
202
|
'reconnect_backoff_ms': 50,
|
|
@@ -242,7 +248,7 @@ class BrokerConnection(object):
|
|
|
242
248
|
self._api_versions = None
|
|
243
249
|
self._api_version = None
|
|
244
250
|
self._check_version_idx = None
|
|
245
|
-
self._api_versions_idx =
|
|
251
|
+
self._api_versions_idx = 4 # version of ApiVersionsRequest to try on first connect
|
|
246
252
|
self._throttle_time = None
|
|
247
253
|
self._socks5_proxy = None
|
|
248
254
|
|
|
@@ -538,7 +544,14 @@ class BrokerConnection(object):
|
|
|
538
544
|
log.debug('%s: Using pre-configured api_version %s for ApiVersions', self, self._api_version)
|
|
539
545
|
return True
|
|
540
546
|
elif self._check_version_idx is None:
|
|
541
|
-
|
|
547
|
+
version = self._api_versions_idx
|
|
548
|
+
if version >= 3:
|
|
549
|
+
request = ApiVersionsRequest[version](
|
|
550
|
+
client_software_name=self.config['client_software_name'],
|
|
551
|
+
client_software_version=self.config['client_software_version'],
|
|
552
|
+
_tagged_fields={})
|
|
553
|
+
else:
|
|
554
|
+
request = ApiVersionsRequest[version]()
|
|
542
555
|
future = Future()
|
|
543
556
|
response = self._send(request, blocking=True, request_timeout_ms=(self.config['api_version_auto_timeout_ms'] * 0.8))
|
|
544
557
|
response.add_callback(self._handle_api_versions_response, future)
|
|
@@ -573,11 +586,15 @@ class BrokerConnection(object):
|
|
|
573
586
|
|
|
574
587
|
def _handle_api_versions_response(self, future, response):
|
|
575
588
|
error_type = Errors.for_code(response.error_code)
|
|
576
|
-
# if error_type i UNSUPPORTED_VERSION: retry w/ latest version from response
|
|
577
589
|
if error_type is not Errors.NoError:
|
|
578
590
|
future.failure(error_type())
|
|
579
591
|
if error_type is Errors.UnsupportedVersionError:
|
|
580
592
|
self._api_versions_idx -= 1
|
|
593
|
+
for api_key, min_version, max_version, *rest in response.api_versions:
|
|
594
|
+
# If broker provides a lower max_version, skip to that
|
|
595
|
+
if api_key == response.API_KEY:
|
|
596
|
+
self._api_versions_idx = min(self._api_versions_idx, max_version)
|
|
597
|
+
break
|
|
581
598
|
if self._api_versions_idx >= 0:
|
|
582
599
|
self._api_versions_future = None
|
|
583
600
|
self.state = ConnectionStates.API_VERSIONS_SEND
|
|
@@ -587,7 +604,7 @@ class BrokerConnection(object):
|
|
|
587
604
|
return
|
|
588
605
|
self._api_versions = dict([
|
|
589
606
|
(api_key, (min_version, max_version))
|
|
590
|
-
for api_key, min_version, max_version in response.api_versions
|
|
607
|
+
for api_key, min_version, max_version, *rest in response.api_versions
|
|
591
608
|
])
|
|
592
609
|
self._api_version = self._infer_broker_version_from_api_versions(self._api_versions)
|
|
593
610
|
log.info('Broker version identified as %s', '.'.join(map(str, self._api_version)))
|