kafka-python 3.0.2__tar.gz → 3.0.4__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-3.0.2 → kafka_python-3.0.4}/CHANGES.md +36 -1
- {kafka_python-3.0.2 → kafka_python-3.0.4}/PKG-INFO +1 -1
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/cluster/versions.py +1 -1
- kafka_python-3.0.4/kafka/cli/common.py +169 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cluster.py +3 -5
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/consumer/fetcher.py +68 -14
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/base.py +3 -4
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/connection.py +23 -11
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/manager.py +29 -12
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/selector.py +131 -59
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/transport.py +18 -4
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/wakeup_notifier.py +2 -5
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/broker_version_data.py +5 -1
- kafka_python-3.0.4/kafka/version.py +1 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka_python.egg-info/PKG-INFO +1 -1
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/fixtures.py +2 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_manager.py +37 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_selector.py +237 -3
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_transport.py +119 -0
- kafka_python-3.0.2/kafka/cli/common.py +0 -95
- kafka_python-3.0.2/kafka/version.py +0 -1
- {kafka_python-3.0.2 → kafka_python-3.0.4}/AUTHORS.md +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/LICENSE +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/MANIFEST.in +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/README.rst +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/__main__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/__main__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_acls.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_cluster.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_configs.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_groups.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_partitions.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_topics.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_transactions.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/_users.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/admin/client.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/consumer_performance.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/load_example.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/producer_encode_path.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/producer_performance.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/profile_protocol.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/protocol_old_vs_new.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/record_batch_compose.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/record_batch_read.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/benchmarks/varint_speed.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/acls/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/acls/common.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/acls/create.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/acls/delete.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/acls/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/cluster/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/cluster/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/cluster/describe_quorum.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/cluster/features.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/cluster/log_dirs.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/configs/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/configs/alter.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/configs/common.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/configs/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/configs/list.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/configs/reset.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/alter_offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/delete.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/delete_offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/list.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/list_offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/remove_members.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/groups/reset_offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/alter_reassignments.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/create.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/delete_records.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/elect_leaders.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/list_offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/partitions/list_reassignments.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/topics/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/topics/create.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/topics/delete.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/topics/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/topics/list.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/transactions/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/transactions/abort.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/transactions/describe.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/transactions/describe_producers.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/transactions/find_hanging.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/transactions/list.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/users/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/users/alter_user_scram_credentials.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/admin/users/describe_user_scram_credentials.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/consumer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/cli/producer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/codec.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/consumer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/consumer/__main__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/consumer/group.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/consumer/subscription_state.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/abstract.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/cooperative_sticky.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/range.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/roundrobin.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/assignors/sticky/user_data.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/consumer.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/heartbeat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/coordinator/subscription.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/errors.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/future.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/compound_stat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/dict_reporter.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/kafka_metric.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/measurable.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/measurable_stat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/metric_config.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/metric_name.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/metrics.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/metrics_reporter.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/quota.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/avg.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/count.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/histogram.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/max_stat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/min_stat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/percentile.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/percentiles.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/rate.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/sampled_stat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/sensor.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/metrics/stats/total.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/compat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/http_connect.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/inet.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/metrics.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/abc.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/gssapi.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/msk.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/oauth.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/plain.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/scram.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/sasl/sspi.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/net/socks5.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/partitioner/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/partitioner/abc.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/partitioner/default.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/partitioner/sticky.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/__main__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/future.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/kafka.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/producer_batch.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/record_accumulator.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/sender.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/producer/transaction_manager.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/acl.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/acl.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/client_quotas.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/client_quotas.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/cluster.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/cluster.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/configs.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/configs.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/groups.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/groups.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/topics.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/topics.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/transactions.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/transactions.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/users.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/admin/users.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/api_data.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/api_header.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/api_key.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/api_message.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/fetch.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/fetch.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/group.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/group.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/metadata.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/metadata.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/consumer/offsets.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/data_container.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/frame.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/generate_stubs.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/api_versions.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/api_versions.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/find_coordinator.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/find_coordinator.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/metadata.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/metadata/metadata.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/abstract.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/add_offsets_to_txn.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/add_partitions_to_txn.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/admin.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/api.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/api_versions.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/commit.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/consumer_protocol.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/end_txn.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/fetch.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/find_coordinator.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/group.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/init_producer_id.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/list_offsets.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/metadata.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/offset_for_leader_epoch.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/produce.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/sasl_authenticate.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/sasl_handshake.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/struct.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/txn_offset_commit.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/old/types.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/parser.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/producer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/producer/produce.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/producer/produce.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/producer/transaction.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/producer/transaction.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/sasl.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/sasl.pyi +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/array.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/base.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/codecs/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/codecs/encode_buffer.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/codecs/tagged_fields.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/codecs/types.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/codegen.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/simple.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/struct.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/fields/struct_array.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/load_json.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterConfigsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterConfigsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ApiVersionsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ApiVersionsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/CreateAclsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/CreateAclsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/CreatePartitionsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/CreatePartitionsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/CreateTopicsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/CreateTopicsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteAclsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteAclsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteGroupsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteGroupsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteRecordsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteRecordsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteTopicsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DeleteTopicsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeAclsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeAclsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeClusterRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeClusterResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeConfigsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeConfigsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeGroupsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeGroupsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeProducersRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeProducersResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeQuorumRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeQuorumResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ElectLeadersRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ElectLeadersResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/EndTxnRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/EndTxnResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/FetchRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/FetchResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/FindCoordinatorRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/FindCoordinatorResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/HeartbeatRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/HeartbeatResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/InitProducerIdRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/InitProducerIdResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/JoinGroupRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/JoinGroupResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/LeaveGroupRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/LeaveGroupResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListGroupsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListGroupsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListOffsetsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListOffsetsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListTransactionsRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ListTransactionsResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/MetadataRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/MetadataResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetCommitRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetCommitResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetDeleteRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetDeleteResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetFetchRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetFetchResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ProduceRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ProduceResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/RequestHeader.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/ResponseHeader.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/SaslHandshakeRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/SaslHandshakeResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/SyncGroupRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/SyncGroupResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/protocol/schemas/resources/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/_crc32c.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/abc.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/default_records.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/legacy_records.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/memory_records.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/record/util.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/serializer/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/serializer/abstract.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/serializer/default.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/serializer/json.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/serializer/wrapper.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/structs.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/util.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka/vendor/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka_python.egg-info/SOURCES.txt +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka_python.egg-info/dependency_links.txt +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka_python.egg-info/entry_points.txt +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka_python.egg-info/requires.txt +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/kafka_python.egg-info/top_level.txt +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/pyproject.toml +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/setup.cfg +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/conftest.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/test_admin_integration.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/test_consumer_integration.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/test_producer_integration.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/test_sasl_integration.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/integration/test_ssl_integration.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/__init__.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_compat.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_connection.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_http_connect.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_inet.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_sasl_reauthentication.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/net/test_wakeup_notifier.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_cluster.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_codec.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_future.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_metrics.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_mock_broker.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_package.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/test_util.py +0 -0
- {kafka_python-3.0.2 → kafka_python-3.0.4}/test/testutil.py +0 -0
|
@@ -1,7 +1,42 @@
|
|
|
1
|
-
# 3.0.
|
|
1
|
+
# 3.0.4 (Jun 23, 2026)
|
|
2
|
+
|
|
3
|
+
### Fixes
|
|
4
|
+
* Fix `_build_transport` / `conn.close` race (#3097)
|
|
5
|
+
* net.transport: Fix closed/write_eof handling in `_write_to_sock` (#3095)
|
|
6
|
+
* Fix kafka.net.connection await: raise connection failures (#3091)
|
|
7
|
+
|
|
8
|
+
### Logging
|
|
9
|
+
* bootstrap connection log changes (#3092)
|
|
10
|
+
* Improve connection logging; dont log version check if matches expected (#3089)
|
|
11
|
+
* tests: print integration fixture output to console if no log handlers
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
* docs: Add title headings for KafkaConsumer/KafkaProducer; add sphinx-argparse to requirements-dev.txt (#3096)
|
|
15
|
+
|
|
16
|
+
# 3.0.3 (Jun 22, 2026)
|
|
2
17
|
|
|
3
18
|
### Fixes
|
|
19
|
+
* Consumer: fix multi-broker fetch busy wait loop (#3084)
|
|
20
|
+
* net: inject KernelEvent handler exceptions into coro; warn dont crash if task state is still RUNNING (#3083)
|
|
21
|
+
* Fix: do not mark coordinator dead on all HeartbeatResponse errors (#3082)
|
|
22
|
+
* Improve task cleanup with net.cancel(task), TaskState, and consolidated wait_io cleanup (#3081)
|
|
23
|
+
* Fix/net selector task already done (#3078)
|
|
4
24
|
|
|
25
|
+
### Logging
|
|
26
|
+
* Fixup socks5_proxy deprecation warning (#3088)
|
|
27
|
+
* log metadata refresh failure stacktraces as DEBUG not ERROR (#3087)
|
|
28
|
+
* log heartbeat rebalance response as INFO, not WARNING (#3085)
|
|
29
|
+
|
|
30
|
+
### CLI
|
|
31
|
+
* add --log-format, --log-date-format, --log-file, --log-config (#3086)
|
|
32
|
+
* fix comma-separated --bootstrap-servers parsing (#3080)
|
|
33
|
+
|
|
34
|
+
### CI
|
|
35
|
+
* Bump actions/checkout from 6 to 7 (#3079)
|
|
36
|
+
|
|
37
|
+
# 3.0.2 (Jun 18, 2026)
|
|
38
|
+
|
|
39
|
+
### Fixes
|
|
5
40
|
* fix memory leak of cancelled timeout tasks (@azdobylak / #3077)
|
|
6
41
|
|
|
7
42
|
# 3.0.1 (Jun 17, 2026)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import logging.config
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def add_connect_cli_args(parser, bootstrap_required=True):
|
|
6
|
+
connect_group = parser.add_argument_group('connection')
|
|
7
|
+
connect_group.add_argument(
|
|
8
|
+
'-b', '--bootstrap-servers', type=str, action='append', required=bootstrap_required,
|
|
9
|
+
help='host:port for cluster bootstrap server. Can be provided multiple times.')
|
|
10
|
+
connect_group.add_argument(
|
|
11
|
+
'-S', '--security-protocol', type=str, default='PLAINTEXT', help='PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL')
|
|
12
|
+
connect_group.add_argument(
|
|
13
|
+
'-M', '--sasl-mechanism', type=str, default='PLAIN', help='PLAIN, GSSAPI, OAUTHBEARER, SCRAM-SHA-256, SCRAM-SHA-512')
|
|
14
|
+
connect_group.add_argument(
|
|
15
|
+
'-U', '--sasl-user', type=str)
|
|
16
|
+
connect_group.add_argument(
|
|
17
|
+
'-P', '--sasl-password', type=str)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def build_kwargs(props):
|
|
21
|
+
kwargs = {}
|
|
22
|
+
for prop in props or []:
|
|
23
|
+
k, v = prop.split('=')
|
|
24
|
+
try:
|
|
25
|
+
v = int(v)
|
|
26
|
+
except ValueError:
|
|
27
|
+
pass
|
|
28
|
+
if v == 'None':
|
|
29
|
+
v = None
|
|
30
|
+
elif v == 'False':
|
|
31
|
+
v = False
|
|
32
|
+
elif v == 'True':
|
|
33
|
+
v = True
|
|
34
|
+
kwargs[k] = v
|
|
35
|
+
return kwargs
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def build_connect_kwargs(config):
|
|
39
|
+
if not config.bootstrap_servers:
|
|
40
|
+
raise ValueError('python -m kafka: error: the following arguments are required: -b/--bootstrap-servers')
|
|
41
|
+
# Accept both repeated -b flags and comma-separated lists within a single flag
|
|
42
|
+
bootstrap_servers = []
|
|
43
|
+
for entry in config.bootstrap_servers:
|
|
44
|
+
bootstrap_servers.extend(s.strip() for s in entry.split(',') if s.strip())
|
|
45
|
+
kwargs = build_kwargs(config.extra_config)
|
|
46
|
+
kwargs.update({
|
|
47
|
+
'bootstrap_servers': bootstrap_servers,
|
|
48
|
+
'security_protocol': config.security_protocol,
|
|
49
|
+
'sasl_mechanism': config.sasl_mechanism,
|
|
50
|
+
'sasl_plain_username': config.sasl_user,
|
|
51
|
+
'sasl_plain_password': config.sasl_password,
|
|
52
|
+
})
|
|
53
|
+
return kwargs
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def add_logging_cli_args(parser):
|
|
57
|
+
logging_group = parser.add_argument_group('logging')
|
|
58
|
+
logging_group.add_argument(
|
|
59
|
+
'-l', '--log-level', type=str, default='CRITICAL',
|
|
60
|
+
help='logging level, passed to logging.basicConfig')
|
|
61
|
+
logging_group.add_argument(
|
|
62
|
+
'-L', '--enable-logger', type=str, action='append',
|
|
63
|
+
help='enable a specific logger. Can be provided multiple times. If not provided, all loggers are enabled')
|
|
64
|
+
logging_group.add_argument(
|
|
65
|
+
'-D', '--disable-logger', type=str, action='append',
|
|
66
|
+
help='disable a specific logger. Can be provided multiple times.')
|
|
67
|
+
logging_group.add_argument(
|
|
68
|
+
'--log-format', type=str, default=None,
|
|
69
|
+
help='log message format string, passed to logging.Formatter')
|
|
70
|
+
logging_group.add_argument(
|
|
71
|
+
'--log-date-format', type=str, default=None,
|
|
72
|
+
help='log date format string, passed to logging.Formatter')
|
|
73
|
+
logging_group.add_argument(
|
|
74
|
+
'--log-file', type=str, default=None,
|
|
75
|
+
help='write logs to this file instead of stderr')
|
|
76
|
+
logging_group.add_argument(
|
|
77
|
+
'--log-config', type=str, default=None,
|
|
78
|
+
help='path to a logging configuration file for full control over handlers, '
|
|
79
|
+
'formatters, etc. A .json (or .yaml/.yml, if PyYAML is installed) file is '
|
|
80
|
+
'loaded as a logging.config.dictConfig; any other extension is loaded as a '
|
|
81
|
+
'logging.config.fileConfig. The file owns handlers/formatters, so --log-format, '
|
|
82
|
+
'--log-date-format and --log-file are ignored, but --enable-logger and '
|
|
83
|
+
'--disable-logger still apply as logger level adjustments.')
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def add_extended_cli_args(parser):
|
|
87
|
+
extended_group = parser.add_argument_group('extended')
|
|
88
|
+
extended_group.add_argument(
|
|
89
|
+
'-C', '--extra-config', type=str, action='append',
|
|
90
|
+
help='additional configuration properties for client in "key=val" format. Can be provided multiple times.')
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _load_log_config(path):
|
|
94
|
+
"""Configure logging from a dictConfig (.json/.yaml) or fileConfig (.ini) file."""
|
|
95
|
+
if path.endswith(('.yaml', '.yml')):
|
|
96
|
+
try:
|
|
97
|
+
import yaml
|
|
98
|
+
except ImportError:
|
|
99
|
+
raise ValueError('PyYAML is required to load a YAML logging config: %s' % (path,))
|
|
100
|
+
with open(path) as f:
|
|
101
|
+
_dict_config(yaml.safe_load(f))
|
|
102
|
+
elif path.endswith('.json'):
|
|
103
|
+
import json
|
|
104
|
+
with open(path) as f:
|
|
105
|
+
_dict_config(json.load(f))
|
|
106
|
+
else:
|
|
107
|
+
# disable_existing_loggers defaults to True, which would silence loggers
|
|
108
|
+
# configured before this call (e.g. the loggers we are about to enable);
|
|
109
|
+
# keep them around so --enable-logger still works.
|
|
110
|
+
logging.config.fileConfig(path, disable_existing_loggers=False)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _dict_config(cfg):
|
|
114
|
+
# Default disable_existing_loggers to False (dictConfig defaults to True), so a
|
|
115
|
+
# config that does not mention an already-created logger does not silence it.
|
|
116
|
+
# A config may still set it explicitly to opt into the stdlib default.
|
|
117
|
+
cfg.setdefault('disable_existing_loggers', False)
|
|
118
|
+
logging.config.dictConfig(cfg)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def configure_logging(config):
|
|
122
|
+
_LOGGING_LEVELS = {
|
|
123
|
+
'NOTSET': 0,
|
|
124
|
+
'DEBUG': 10,
|
|
125
|
+
'INFO': 20,
|
|
126
|
+
'WARNING': 30,
|
|
127
|
+
'ERROR': 40,
|
|
128
|
+
'CRITICAL': 50,
|
|
129
|
+
}
|
|
130
|
+
log_level = _LOGGING_LEVELS[config.log_level.upper()]
|
|
131
|
+
if getattr(config, 'log_config', None):
|
|
132
|
+
_load_log_config(config.log_config)
|
|
133
|
+
if config.enable_logger is not None:
|
|
134
|
+
# Preserve the no-config behavior of --enable-logger: ONLY the named
|
|
135
|
+
# loggers emit. The config file owns the handlers/formatters, so rather
|
|
136
|
+
# than attach our own we reuse them: silence everything else by raising
|
|
137
|
+
# the root level, then let each enabled logger opt back in and propagate
|
|
138
|
+
# its records up to the config's handlers.
|
|
139
|
+
logging.getLogger().setLevel(logging.CRITICAL + 1)
|
|
140
|
+
for name in config.enable_logger:
|
|
141
|
+
logger = logging.getLogger(name)
|
|
142
|
+
logger.disabled = False
|
|
143
|
+
logger.setLevel(log_level)
|
|
144
|
+
else:
|
|
145
|
+
log_format = config.log_format or logging.BASIC_FORMAT
|
|
146
|
+
if config.enable_logger is not None:
|
|
147
|
+
if config.log_file:
|
|
148
|
+
handler = logging.FileHandler(config.log_file)
|
|
149
|
+
else:
|
|
150
|
+
handler = logging.StreamHandler()
|
|
151
|
+
handler.setLevel(log_level)
|
|
152
|
+
handler.setFormatter(logging.Formatter(log_format, datefmt=config.log_date_format))
|
|
153
|
+
for name in config.enable_logger:
|
|
154
|
+
logger = logging.getLogger(name)
|
|
155
|
+
logger.setLevel(log_level)
|
|
156
|
+
logger.addHandler(handler)
|
|
157
|
+
else:
|
|
158
|
+
logging.basicConfig(
|
|
159
|
+
level=log_level, format=log_format,
|
|
160
|
+
datefmt=config.log_date_format, filename=config.log_file)
|
|
161
|
+
# --disable-logger silences a named logger in either mode by raising its level.
|
|
162
|
+
for name in config.disable_logger or []:
|
|
163
|
+
logging.getLogger(name).setLevel(logging.CRITICAL + 1)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def add_common_cli_args(parser, bootstrap_required=True):
|
|
167
|
+
add_connect_cli_args(parser, bootstrap_required)
|
|
168
|
+
add_logging_cli_args(parser)
|
|
169
|
+
add_extended_cli_args(parser)
|
|
@@ -125,9 +125,8 @@ class ClusterMetadata:
|
|
|
125
125
|
if ttl_ms == 0:
|
|
126
126
|
try:
|
|
127
127
|
await self.refresh_metadata()
|
|
128
|
-
except Errors.KafkaError
|
|
129
|
-
log.debug('Metadata refresh failed
|
|
130
|
-
log.exception(exc)
|
|
128
|
+
except Errors.KafkaError:
|
|
129
|
+
log.debug('Metadata refresh failed', exc_info=True)
|
|
131
130
|
continue
|
|
132
131
|
try:
|
|
133
132
|
log.debug('Sleeping %s for next Metadata refresh', ttl_ms / 1000)
|
|
@@ -168,7 +167,6 @@ class ClusterMetadata:
|
|
|
168
167
|
raise Errors.NodeNotReadyError('metadata')
|
|
169
168
|
else:
|
|
170
169
|
self._manager.reset_backoff('metadata')
|
|
171
|
-
log.info(f'Metadata refresh (node_id={node_id})')
|
|
172
170
|
try:
|
|
173
171
|
request = self.metadata_request()
|
|
174
172
|
log.debug("Sending metadata request %s to node %s", request, node_id)
|
|
@@ -177,7 +175,7 @@ class ClusterMetadata:
|
|
|
177
175
|
log.error('Metadata refresh: failed %s', exc)
|
|
178
176
|
self.failed_update(exc)
|
|
179
177
|
raise
|
|
180
|
-
log.debug('Metadata refresh: success')
|
|
178
|
+
log.debug(f'Metadata refresh: success (node_id={node_id})')
|
|
181
179
|
self.update_metadata(response)
|
|
182
180
|
|
|
183
181
|
def _generate_bootstrap_brokers(self):
|
|
@@ -232,9 +232,18 @@ class Fetcher:
|
|
|
232
232
|
# No records yet. Block until either an in-flight fetch
|
|
233
233
|
# completes (records may have arrived) or a pending offset-reset
|
|
234
234
|
# task completes (positions become available, enabling a fetch
|
|
235
|
-
# on the next caller iteration).
|
|
236
|
-
#
|
|
237
|
-
#
|
|
235
|
+
# on the next caller iteration).
|
|
236
|
+
#
|
|
237
|
+
# add_both fires synchronously on an already-done future: if a fetch
|
|
238
|
+
# response lands between the drain above and this wait setup, _wake
|
|
239
|
+
# fires immediately so we re-drain instead of stalling for the full
|
|
240
|
+
# timeout.
|
|
241
|
+
#
|
|
242
|
+
# This relies on _fetch_futures holding only *recent* completions.
|
|
243
|
+
# otherwise a fetch that completed and was already drained iterations
|
|
244
|
+
# ago lingers behind a slow broker's in-flight fetch and re-fires
|
|
245
|
+
# _wake on every call, busy-looping the poll loop until that slow
|
|
246
|
+
# fetch finally returns.
|
|
238
247
|
waited_on = list(self._fetch_futures)
|
|
239
248
|
if self._reset_task is not None and not self._reset_task.is_done:
|
|
240
249
|
waited_on.append(self._reset_task)
|
|
@@ -277,21 +286,66 @@ class Fetcher:
|
|
|
277
286
|
future.add_both(self._clear_pending_fetch_request, node_id)
|
|
278
287
|
futures.append(future)
|
|
279
288
|
self._fetch_futures.extend(futures)
|
|
280
|
-
self._clean_done_fetch_futures()
|
|
289
|
+
await self._clean_done_fetch_futures()
|
|
281
290
|
return futures
|
|
282
291
|
|
|
283
|
-
def _clean_done_fetch_futures(self):
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
292
|
+
async def _clean_done_fetch_futures(self):
|
|
293
|
+
# Drop every completed fetch future. With multiple brokers, fetches
|
|
294
|
+
# may complete out of order. fetch_records() relies on _fetch_futures
|
|
295
|
+
# holding only recent completions (it fires _wake synchronously on any
|
|
296
|
+
# done future to avoid stalling -- see the wait setup there); a
|
|
297
|
+
# lingering stale completion re-fires that wake on every call and busy-
|
|
298
|
+
# loops the poll loop until the slow broker's in-flight fetch returns.
|
|
299
|
+
#
|
|
300
|
+
# Threading: this REBINDS self._fetch_futures, which must happen on the
|
|
301
|
+
# IO thread so it never races the foreground's list(self._fetch_futures)
|
|
302
|
+
# read in fetch_records(). Defined async to enforce that -- the body
|
|
303
|
+
# can only run by being driven on the IO loop (awaited from another
|
|
304
|
+
# coroutine, or scheduled via manager.run/call_soon), so the rebind
|
|
305
|
+
# always executes on the IO thread regardless of who initiates it.
|
|
306
|
+
# The rebind is a single atomic attribute store, so a foreground reader
|
|
307
|
+
# always sees either the old or the new deque, never a half-cleaned one.
|
|
308
|
+
#
|
|
309
|
+
# Two alternate designs we considered (either would remove the need for
|
|
310
|
+
# this "evict every done future + rebind" dance):
|
|
311
|
+
#
|
|
312
|
+
# 1. Wakeup flag (Apache Kafka Java client, FetchBuffer). Instead of
|
|
313
|
+
# waiting on the fetch-future objects, wait on a single consumable
|
|
314
|
+
# signal: the IO thread sets a flag (wokenup) when it buffers a
|
|
315
|
+
# completed fetch; the foreground's wait loops `while not woken:
|
|
316
|
+
# await` and consumes the flag (compareAndSet true->false) on each
|
|
317
|
+
# pass. Because the signal is cleared on consumption and is not
|
|
318
|
+
# re-derived from lingering future objects, a stale/drained
|
|
319
|
+
# completion cannot re-trigger it -- so no busy-loop and no
|
|
320
|
+
# per-call cleanup of a future list at all. This is the most
|
|
321
|
+
# faithful port of the threaded Java consumer's design.
|
|
322
|
+
#
|
|
323
|
+
# 2. Per-node fetch tracking. Key fetches by broker: dict[node_id,
|
|
324
|
+
# deque] (or just dict[node_id, Future], since _create_fetch_-
|
|
325
|
+
# requests keeps at most one in-flight fetch per node). Within a
|
|
326
|
+
# single connection responses return in request order, so each
|
|
327
|
+
# per-node deque completes in order and the simple head-only
|
|
328
|
+
# popleft cleanup is correct again -- no out-of-order stranding,
|
|
329
|
+
# and cleanup is an in-place popleft (atomic, no rebind, so the
|
|
330
|
+
# threading note above goes away). This structure could also
|
|
331
|
+
# subsume _nodes_with_pending_fetch_requests entirely ("pending"
|
|
332
|
+
# == the node's last future is not done), collapsing two
|
|
333
|
+
# structures into one source of truth.
|
|
334
|
+
if not self._fetch_futures:
|
|
335
|
+
return
|
|
336
|
+
self._fetch_futures = collections.deque(
|
|
337
|
+
fut for fut in self._fetch_futures if not fut.is_done)
|
|
290
338
|
|
|
291
339
|
def in_flight_fetches(self):
|
|
292
|
-
"""Return True if there are any unprocessed FetchRequests
|
|
293
|
-
|
|
294
|
-
|
|
340
|
+
"""Return True if there are any unprocessed (incomplete) FetchRequests
|
|
341
|
+
in flight."""
|
|
342
|
+
|
|
343
|
+
# Read-only on purpose: this may be called from the foreground thread,
|
|
344
|
+
# which must not mutate _fetch_futures (see _clean_done_fetch_futures --
|
|
345
|
+
# cleanup is IO-thread-only). Snapshot first so we never iterate the
|
|
346
|
+
# deque while the IO thread extends it, and check is_done directly
|
|
347
|
+
# rather than relying on a prior cleanup pass.
|
|
348
|
+
return any(not fut.is_done for fut in list(self._fetch_futures))
|
|
295
349
|
|
|
296
350
|
def reset_offsets_if_needed(self, timeout_ms=None):
|
|
297
351
|
"""Schedule pending offset resets and return the in-flight Task.
|
|
@@ -1117,10 +1117,11 @@ class BaseCoordinator(ABC):
|
|
|
1117
1117
|
try:
|
|
1118
1118
|
send_time = time.monotonic()
|
|
1119
1119
|
response = await self._manager.send(request, node_id=self.coordinator_id)
|
|
1120
|
-
return self._handle_heartbeat_response(response, send_time)
|
|
1121
1120
|
except Errors.KafkaError as exc:
|
|
1122
1121
|
self._failed_request(self.coordinator_id, request, exc)
|
|
1123
1122
|
raise
|
|
1123
|
+
else:
|
|
1124
|
+
return self._handle_heartbeat_response(response, send_time)
|
|
1124
1125
|
|
|
1125
1126
|
def _handle_heartbeat_response(self, response, send_time):
|
|
1126
1127
|
if self._sensors:
|
|
@@ -1138,8 +1139,7 @@ class BaseCoordinator(ABC):
|
|
|
1138
1139
|
self.coordinator_id)
|
|
1139
1140
|
self.coordinator_dead(error)
|
|
1140
1141
|
elif error_type is Errors.RebalanceInProgressError:
|
|
1141
|
-
heartbeat_log.
|
|
1142
|
-
" rebalancing", self.group_id)
|
|
1142
|
+
heartbeat_log.info("Group %s is rebalancing; rejoining.", self.group_id)
|
|
1143
1143
|
self.request_rejoin()
|
|
1144
1144
|
elif error_type is Errors.IllegalGenerationError:
|
|
1145
1145
|
heartbeat_log.warning("Heartbeat failed for group %s: generation id is not "
|
|
@@ -1158,7 +1158,6 @@ class BaseCoordinator(ABC):
|
|
|
1158
1158
|
heartbeat_log.error("Heartbeat failed: authorization error: %s", error)
|
|
1159
1159
|
else:
|
|
1160
1160
|
heartbeat_log.error("Heartbeat failed: Unhandled error: %s", error)
|
|
1161
|
-
|
|
1162
1161
|
raise error
|
|
1163
1162
|
|
|
1164
1163
|
|
|
@@ -96,7 +96,7 @@ class KafkaConnection:
|
|
|
96
96
|
return self._init_future
|
|
97
97
|
|
|
98
98
|
def __await__(self):
|
|
99
|
-
yield self.init_future
|
|
99
|
+
yield from self.init_future.__await__() # == await self.init_future; raises on failure
|
|
100
100
|
return self
|
|
101
101
|
|
|
102
102
|
@property
|
|
@@ -203,7 +203,7 @@ class KafkaConnection:
|
|
|
203
203
|
if req_correlation_id != resp_correlation_id:
|
|
204
204
|
return self.close(Errors.KafkaConnectionError('Received unrecognized correlation id'))
|
|
205
205
|
|
|
206
|
-
self.net.
|
|
206
|
+
self.net.cancel(timeout_task)
|
|
207
207
|
latency_ms = (time.monotonic() - sent_time) * 1000
|
|
208
208
|
if self._sensors:
|
|
209
209
|
self._sensors.request_time.record(latency_ms)
|
|
@@ -239,8 +239,10 @@ class KafkaConnection:
|
|
|
239
239
|
self._init_future.failure(error)
|
|
240
240
|
if not self._close_future.is_done:
|
|
241
241
|
if exc is None:
|
|
242
|
+
log.info('%s: Connection closed', self)
|
|
242
243
|
self._close_future.success(None)
|
|
243
244
|
else:
|
|
245
|
+
log.error('%s: Connection lost: %s', self, exc)
|
|
244
246
|
self._close_future.failure(exc)
|
|
245
247
|
|
|
246
248
|
def fail_in_flight_requests(self, error):
|
|
@@ -252,7 +254,7 @@ class KafkaConnection:
|
|
|
252
254
|
future.failure(error)
|
|
253
255
|
while self.in_flight_requests:
|
|
254
256
|
_, future, _, _, timeout_task = self.in_flight_requests.popleft()
|
|
255
|
-
self.net.
|
|
257
|
+
self.net.cancel(timeout_task)
|
|
256
258
|
future.failure(error)
|
|
257
259
|
|
|
258
260
|
def connection_made(self, transport):
|
|
@@ -262,6 +264,13 @@ class KafkaConnection:
|
|
|
262
264
|
To receive data, wait for data_received() calls.
|
|
263
265
|
When the connection is closed, connection_lost() is called.
|
|
264
266
|
"""
|
|
267
|
+
if self.closed:
|
|
268
|
+
# A concurrent close() may have torn the connection down while the
|
|
269
|
+
# transport was still being built. Setting initializing=True below
|
|
270
|
+
# would resurrect an already-closed connection mid-teardown and
|
|
271
|
+
# break the fail_in_flight_requests invariant; refuse instead. The
|
|
272
|
+
# caller (manager._connect) closes the orphaned transport.
|
|
273
|
+
raise Errors.KafkaConnectionError('Connection closed during connect')
|
|
265
274
|
self.transport = transport
|
|
266
275
|
if self.transport.get_protocol() != self:
|
|
267
276
|
self.transport.set_protocol(self)
|
|
@@ -276,6 +285,7 @@ class KafkaConnection:
|
|
|
276
285
|
client_id=self.config['client_id'],
|
|
277
286
|
receive_message_max_bytes=self.config['receive_message_max_bytes'],
|
|
278
287
|
ident=log_prefix)
|
|
288
|
+
log.debug('%s: Connection made', self)
|
|
279
289
|
|
|
280
290
|
def pause(self, v):
|
|
281
291
|
self.paused.add(v)
|
|
@@ -362,6 +372,7 @@ class KafkaConnection:
|
|
|
362
372
|
self.close(error)
|
|
363
373
|
else:
|
|
364
374
|
self._init_complete()
|
|
375
|
+
log.info('%s: Connected', self)
|
|
365
376
|
|
|
366
377
|
async def _get_api_versions(self, timeout_at=None):
|
|
367
378
|
if timeout_at is None:
|
|
@@ -400,11 +411,15 @@ class KafkaConnection:
|
|
|
400
411
|
api_versions = {api_version.api_key: (api_version.min_version, api_version.max_version)
|
|
401
412
|
for api_version in response.api_keys}
|
|
402
413
|
bvd = BrokerVersionData(api_versions=api_versions)
|
|
403
|
-
|
|
404
|
-
|
|
414
|
+
if self.broker_version_data is None:
|
|
415
|
+
log.info('%s: Broker version identified as %s', self, bvd.broker_version_str)
|
|
405
416
|
self.broker_version_data = bvd
|
|
406
|
-
|
|
407
|
-
log.info('%s:
|
|
417
|
+
elif self.broker_version_data > bvd:
|
|
418
|
+
log.info('%s: Broker version identified as %s (lower than user-supplied %s)', self, bvd.broker_version_str, self.broker_version_data.broker_version_str)
|
|
419
|
+
self.broker_version_data = bvd
|
|
420
|
+
elif self.broker_version_data is not None and self.broker_version_data < bvd:
|
|
421
|
+
log.info('%s: Broker version identified as %s; clamping to user-supplied %s', self, bvd.broker_version_str, self.broker_version_data.broker_version_str)
|
|
422
|
+
# No log if user-supplied api_version is the same as broker-identified version
|
|
408
423
|
|
|
409
424
|
@property
|
|
410
425
|
def sasl_enabled(self):
|
|
@@ -534,10 +549,7 @@ class SaslReauthenticator:
|
|
|
534
549
|
"""Cancel any pending re-auth and fail the drain awaiter if present.
|
|
535
550
|
Called from KafkaConnection.connection_lost."""
|
|
536
551
|
if self._task is not None:
|
|
537
|
-
|
|
538
|
-
self._conn.net.unschedule(self._task)
|
|
539
|
-
except (ValueError, KeyError):
|
|
540
|
-
pass
|
|
552
|
+
self._conn.net.cancel(self._task)
|
|
541
553
|
self._task = None
|
|
542
554
|
if self._drain_future is not None and not self._drain_future.is_done:
|
|
543
555
|
self._drain_future.failure(Errors.KafkaConnectionError())
|
|
@@ -73,7 +73,7 @@ class KafkaConnectionManager:
|
|
|
73
73
|
"client_dns_lookup must be one of %s; got %r"
|
|
74
74
|
% (self._VALID_DNS_LOOKUP_MODES, self.config['client_dns_lookup']))
|
|
75
75
|
|
|
76
|
-
if 'socks5_proxy'
|
|
76
|
+
if configs.get('socks5_proxy') is not None:
|
|
77
77
|
if self.config['proxy_url'] is None:
|
|
78
78
|
log.warning('socks5_proxy is deprecated, use proxy_url instead')
|
|
79
79
|
self.config['proxy_url'] = configs['socks5_proxy']
|
|
@@ -117,7 +117,9 @@ class KafkaConnectionManager:
|
|
|
117
117
|
async def _do_bootstrap(self, deadline):
|
|
118
118
|
while not self.closed and (deadline is None or time.monotonic() < deadline):
|
|
119
119
|
bootstrap_broker = random.choice(self.cluster.bootstrap_brokers())
|
|
120
|
-
log.
|
|
120
|
+
log.info('Attempting bootstrap to %s at %s:%s (rack %s)',
|
|
121
|
+
bootstrap_broker.node_id, bootstrap_broker.host,
|
|
122
|
+
bootstrap_broker.port, bootstrap_broker.rack)
|
|
121
123
|
try:
|
|
122
124
|
timeout_ms = (deadline - time.monotonic()) * 1000 if deadline is not None else None
|
|
123
125
|
conn = self.get_connection(bootstrap_broker.node_id,
|
|
@@ -129,7 +131,7 @@ class KafkaConnectionManager:
|
|
|
129
131
|
delay = self.connection_delay(bootstrap_broker.node_id)
|
|
130
132
|
if deadline is not None:
|
|
131
133
|
delay = min(delay, max(0, deadline - time.monotonic()))
|
|
132
|
-
log.
|
|
134
|
+
log.warning('Bootstrap %s not ready; waiting %.2f secs', bootstrap_broker.node_id, delay)
|
|
133
135
|
await self._bootstrap_wakeup(delay)
|
|
134
136
|
continue
|
|
135
137
|
|
|
@@ -145,12 +147,12 @@ class KafkaConnectionManager:
|
|
|
145
147
|
try:
|
|
146
148
|
await self.cluster.refresh_metadata(bootstrap_broker.node_id)
|
|
147
149
|
if not self.cluster.brokers():
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
backoff_ms = self.update_backoff(bootstrap_broker.node_id)
|
|
151
|
+
log.warning('Bootstrap metadata response has no brokers. Retrying in %.2f secs.', backoff_ms / 1000)
|
|
150
152
|
continue
|
|
151
153
|
except Exception as exc:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
backoff_ms = self.update_backoff(bootstrap_broker.node_id)
|
|
155
|
+
log.error(f'Bootstrap attempt to {bootstrap_broker.node_id} failed: {exc} (backoff {(backoff_ms / 1000):.2f} secs)')
|
|
154
156
|
continue
|
|
155
157
|
else:
|
|
156
158
|
self.reset_backoff(bootstrap_broker.node_id)
|
|
@@ -158,6 +160,7 @@ class KafkaConnectionManager:
|
|
|
158
160
|
log.info('Bootstrap complete: %s', self.cluster)
|
|
159
161
|
return True
|
|
160
162
|
finally:
|
|
163
|
+
log.info('Closing bootstrap connection %s', bootstrap_broker.node_id)
|
|
161
164
|
self._conns.pop(bootstrap_broker.node_id, conn).close()
|
|
162
165
|
else:
|
|
163
166
|
raise Errors.KafkaTimeoutError(
|
|
@@ -239,9 +242,22 @@ class KafkaConnectionManager:
|
|
|
239
242
|
return transport
|
|
240
243
|
|
|
241
244
|
async def _connect(self, node, conn, reset_backoff_on_connect=True, timeout_at=None):
|
|
245
|
+
# Tracks ownership of the freshly built transport: while non-None it is
|
|
246
|
+
# ours to clean up (the connection hasn't taken it over yet), so the
|
|
247
|
+
# finally clause closes it. Cleared once connection_made() succeeds.
|
|
248
|
+
transport = None
|
|
242
249
|
try:
|
|
243
250
|
transport = await self._build_transport(node, timeout_at=timeout_at)
|
|
251
|
+
# The connection (or the whole manager) may have been closed while
|
|
252
|
+
# we were building the transport. Handing it to connection_made()
|
|
253
|
+
# would flip the conn back to `initializing` and resurrect a
|
|
254
|
+
# connection that is already being torn down. Discard
|
|
255
|
+
# the new transport instead of reviving a dead connection.
|
|
256
|
+
if conn.closed or self.closed:
|
|
257
|
+
log.debug('%s: closed during connect; discarding new transport', conn)
|
|
258
|
+
return
|
|
244
259
|
conn.connection_made(transport)
|
|
260
|
+
transport = None # conn owns cleanup now; skip finally: transport.close()
|
|
245
261
|
await conn.initialize(timeout_at=timeout_at)
|
|
246
262
|
except Exception as exc:
|
|
247
263
|
log.error('Connection failed: %s', exc)
|
|
@@ -251,6 +267,9 @@ class KafkaConnectionManager:
|
|
|
251
267
|
Errors.AuthorizationError)):
|
|
252
268
|
self._auth_failures[node.node_id] = exc
|
|
253
269
|
return
|
|
270
|
+
finally:
|
|
271
|
+
if transport is not None:
|
|
272
|
+
transport.close()
|
|
254
273
|
|
|
255
274
|
if self._sensors:
|
|
256
275
|
self._sensors.connection_created.record()
|
|
@@ -275,6 +294,7 @@ class KafkaConnectionManager:
|
|
|
275
294
|
node = self.cluster.broker_metadata(node_id)
|
|
276
295
|
if node is None:
|
|
277
296
|
raise Errors.UnknownBrokerIdError(node_id)
|
|
297
|
+
log.info('Initializing connection for node_id %s at %s:%s (rack=%s)', node_id, node.host, node.port, node.rack)
|
|
278
298
|
conn = KafkaConnection(self._net, node_id=node_id, broker_version_data=self.broker_version_data, **self.config)
|
|
279
299
|
if pop_on_close:
|
|
280
300
|
conn.close_future.add_both(lambda _: self._conns.pop(node.node_id, None))
|
|
@@ -359,6 +379,7 @@ class KafkaConnectionManager:
|
|
|
359
379
|
node_id, backoff_ms, connect_ms, failures)
|
|
360
380
|
backoff_until_time = time.monotonic() + (backoff_ms / 1000)
|
|
361
381
|
self._backoff[node_id] = (failures, backoff_until_time, connect_ms)
|
|
382
|
+
return backoff_ms
|
|
362
383
|
|
|
363
384
|
def connection_delay(self, node_id):
|
|
364
385
|
"""Connection delay in seconds.
|
|
@@ -423,11 +444,7 @@ class KafkaConnectionManager:
|
|
|
423
444
|
try:
|
|
424
445
|
return await wrapper
|
|
425
446
|
finally:
|
|
426
|
-
|
|
427
|
-
try:
|
|
428
|
-
self._net.unschedule(timer)
|
|
429
|
-
except ValueError:
|
|
430
|
-
pass
|
|
447
|
+
self._net.cancel(timer)
|
|
431
448
|
|
|
432
449
|
def call_soon(self, coro, *args):
|
|
433
450
|
"""Accepts a coroutine / awaitable / function and schedules it on the event loop.
|