kafka-python 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kafka/__init__.py +34 -0
- kafka/__main__.py +5 -0
- kafka/admin/__init__.py +29 -0
- kafka/admin/__main__.py +5 -0
- kafka/admin/_acls.py +355 -0
- kafka/admin/_cluster.py +359 -0
- kafka/admin/_configs.py +479 -0
- kafka/admin/_groups.py +754 -0
- kafka/admin/_partitions.py +595 -0
- kafka/admin/_topics.py +281 -0
- kafka/admin/_transactions.py +450 -0
- kafka/admin/_users.py +194 -0
- kafka/admin/client.py +373 -0
- kafka/benchmarks/__init__.py +0 -0
- kafka/benchmarks/consumer_performance.py +138 -0
- kafka/benchmarks/load_example.py +109 -0
- kafka/benchmarks/producer_encode_path.py +201 -0
- kafka/benchmarks/producer_performance.py +161 -0
- kafka/benchmarks/profile_protocol.py +138 -0
- kafka/benchmarks/protocol_old_vs_new.py +447 -0
- kafka/benchmarks/record_batch_compose.py +77 -0
- kafka/benchmarks/record_batch_read.py +82 -0
- kafka/benchmarks/varint_speed.py +426 -0
- kafka/cli/__init__.py +36 -0
- kafka/cli/admin/__init__.py +117 -0
- kafka/cli/admin/acls/__init__.py +9 -0
- kafka/cli/admin/acls/common.py +76 -0
- kafka/cli/admin/acls/create.py +19 -0
- kafka/cli/admin/acls/delete.py +23 -0
- kafka/cli/admin/acls/describe.py +16 -0
- kafka/cli/admin/cluster/__init__.py +14 -0
- kafka/cli/admin/cluster/describe.py +11 -0
- kafka/cli/admin/cluster/describe_quorum.py +11 -0
- kafka/cli/admin/cluster/features.py +52 -0
- kafka/cli/admin/cluster/log_dirs.py +43 -0
- kafka/cli/admin/cluster/versions.py +33 -0
- kafka/cli/admin/configs/__init__.py +10 -0
- kafka/cli/admin/configs/alter.py +43 -0
- kafka/cli/admin/configs/common.py +17 -0
- kafka/cli/admin/configs/describe.py +30 -0
- kafka/cli/admin/configs/list.py +16 -0
- kafka/cli/admin/configs/reset.py +20 -0
- kafka/cli/admin/groups/__init__.py +16 -0
- kafka/cli/admin/groups/alter_offsets.py +30 -0
- kafka/cli/admin/groups/delete.py +11 -0
- kafka/cli/admin/groups/delete_offsets.py +29 -0
- kafka/cli/admin/groups/describe.py +11 -0
- kafka/cli/admin/groups/list.py +28 -0
- kafka/cli/admin/groups/list_offsets.py +29 -0
- kafka/cli/admin/groups/remove_members.py +40 -0
- kafka/cli/admin/groups/reset_offsets.py +139 -0
- kafka/cli/admin/partitions/__init__.py +21 -0
- kafka/cli/admin/partitions/alter_reassignments.py +37 -0
- kafka/cli/admin/partitions/create.py +27 -0
- kafka/cli/admin/partitions/delete_records.py +31 -0
- kafka/cli/admin/partitions/describe.py +36 -0
- kafka/cli/admin/partitions/elect_leaders.py +53 -0
- kafka/cli/admin/partitions/list_offsets.py +88 -0
- kafka/cli/admin/partitions/list_reassignments.py +35 -0
- kafka/cli/admin/topics/__init__.py +10 -0
- kafka/cli/admin/topics/create.py +13 -0
- kafka/cli/admin/topics/delete.py +19 -0
- kafka/cli/admin/topics/describe.py +18 -0
- kafka/cli/admin/topics/list.py +11 -0
- kafka/cli/admin/transactions/__init__.py +17 -0
- kafka/cli/admin/transactions/abort.py +38 -0
- kafka/cli/admin/transactions/describe.py +24 -0
- kafka/cli/admin/transactions/describe_producers.py +29 -0
- kafka/cli/admin/transactions/find_hanging.py +26 -0
- kafka/cli/admin/transactions/list.py +37 -0
- kafka/cli/admin/users/__init__.py +8 -0
- kafka/cli/admin/users/alter_user_scram_credentials.py +34 -0
- kafka/cli/admin/users/describe_user_scram_credentials.py +15 -0
- kafka/cli/common.py +95 -0
- kafka/cli/consumer/__init__.py +63 -0
- kafka/cli/producer/__init__.py +57 -0
- kafka/cluster.py +824 -0
- kafka/codec.py +325 -0
- kafka/consumer/__init__.py +5 -0
- kafka/consumer/__main__.py +5 -0
- kafka/consumer/fetcher.py +2012 -0
- kafka/consumer/group.py +1347 -0
- kafka/consumer/subscription_state.py +897 -0
- kafka/coordinator/__init__.py +0 -0
- kafka/coordinator/assignors/__init__.py +0 -0
- kafka/coordinator/assignors/abstract.py +90 -0
- kafka/coordinator/assignors/cooperative_sticky.py +167 -0
- kafka/coordinator/assignors/range.py +81 -0
- kafka/coordinator/assignors/roundrobin.py +101 -0
- kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +37 -0
- kafka/coordinator/assignors/sticky/__init__.py +0 -0
- kafka/coordinator/assignors/sticky/partition_movements.py +149 -0
- kafka/coordinator/assignors/sticky/sorted_set.py +63 -0
- kafka/coordinator/assignors/sticky/sticky_assignor.py +665 -0
- kafka/coordinator/assignors/sticky/user_data.py +8 -0
- kafka/coordinator/base.py +1215 -0
- kafka/coordinator/consumer.py +1224 -0
- kafka/coordinator/heartbeat.py +82 -0
- kafka/coordinator/subscription.py +34 -0
- kafka/errors.py +1004 -0
- kafka/future.py +166 -0
- kafka/metrics/__init__.py +13 -0
- kafka/metrics/compound_stat.py +33 -0
- kafka/metrics/dict_reporter.py +81 -0
- kafka/metrics/kafka_metric.py +36 -0
- kafka/metrics/measurable.py +27 -0
- kafka/metrics/measurable_stat.py +13 -0
- kafka/metrics/metric_config.py +33 -0
- kafka/metrics/metric_name.py +105 -0
- kafka/metrics/metrics.py +261 -0
- kafka/metrics/metrics_reporter.py +53 -0
- kafka/metrics/quota.py +41 -0
- kafka/metrics/stat.py +19 -0
- kafka/metrics/stats/__init__.py +15 -0
- kafka/metrics/stats/avg.py +24 -0
- kafka/metrics/stats/count.py +17 -0
- kafka/metrics/stats/histogram.py +99 -0
- kafka/metrics/stats/max_stat.py +17 -0
- kafka/metrics/stats/min_stat.py +19 -0
- kafka/metrics/stats/percentile.py +14 -0
- kafka/metrics/stats/percentiles.py +75 -0
- kafka/metrics/stats/rate.py +118 -0
- kafka/metrics/stats/sampled_stat.py +99 -0
- kafka/metrics/stats/sensor.py +136 -0
- kafka/metrics/stats/total.py +15 -0
- kafka/net/__init__.py +19 -0
- kafka/net/compat.py +165 -0
- kafka/net/connection.py +593 -0
- kafka/net/http_connect.py +144 -0
- kafka/net/inet.py +122 -0
- kafka/net/manager.py +451 -0
- kafka/net/metrics.py +149 -0
- kafka/net/sasl/__init__.py +32 -0
- kafka/net/sasl/abc.py +28 -0
- kafka/net/sasl/gssapi.py +95 -0
- kafka/net/sasl/msk.py +245 -0
- kafka/net/sasl/oauth.py +98 -0
- kafka/net/sasl/plain.py +42 -0
- kafka/net/sasl/scram.py +135 -0
- kafka/net/sasl/sspi.py +111 -0
- kafka/net/selector.py +644 -0
- kafka/net/socks5.py +262 -0
- kafka/net/transport.py +415 -0
- kafka/net/wakeup_notifier.py +72 -0
- kafka/partitioner/__init__.py +8 -0
- kafka/partitioner/abc.py +8 -0
- kafka/partitioner/default.py +89 -0
- kafka/partitioner/sticky.py +109 -0
- kafka/producer/__init__.py +5 -0
- kafka/producer/__main__.py +5 -0
- kafka/producer/future.py +101 -0
- kafka/producer/kafka.py +1123 -0
- kafka/producer/producer_batch.py +192 -0
- kafka/producer/record_accumulator.py +647 -0
- kafka/producer/sender.py +884 -0
- kafka/producer/transaction_manager.py +1326 -0
- kafka/protocol/__init__.py +0 -0
- kafka/protocol/admin/__init__.py +29 -0
- kafka/protocol/admin/acl.py +83 -0
- kafka/protocol/admin/acl.pyi +375 -0
- kafka/protocol/admin/client_quotas.py +14 -0
- kafka/protocol/admin/client_quotas.pyi +265 -0
- kafka/protocol/admin/cluster.py +31 -0
- kafka/protocol/admin/cluster.pyi +620 -0
- kafka/protocol/admin/configs.py +22 -0
- kafka/protocol/admin/configs.pyi +437 -0
- kafka/protocol/admin/groups.py +24 -0
- kafka/protocol/admin/groups.pyi +261 -0
- kafka/protocol/admin/topics.py +53 -0
- kafka/protocol/admin/topics.pyi +982 -0
- kafka/protocol/admin/transactions.py +18 -0
- kafka/protocol/admin/transactions.pyi +311 -0
- kafka/protocol/admin/users.py +14 -0
- kafka/protocol/admin/users.pyi +223 -0
- kafka/protocol/api_data.py +125 -0
- kafka/protocol/api_header.py +55 -0
- kafka/protocol/api_key.py +97 -0
- kafka/protocol/api_message.py +277 -0
- kafka/protocol/broker_version_data.py +246 -0
- kafka/protocol/consumer/__init__.py +13 -0
- kafka/protocol/consumer/fetch.py +16 -0
- kafka/protocol/consumer/fetch.pyi +298 -0
- kafka/protocol/consumer/group.py +38 -0
- kafka/protocol/consumer/group.pyi +824 -0
- kafka/protocol/consumer/metadata.py +30 -0
- kafka/protocol/consumer/metadata.pyi +89 -0
- kafka/protocol/consumer/offsets.py +75 -0
- kafka/protocol/consumer/offsets.pyi +288 -0
- kafka/protocol/data_container.py +166 -0
- kafka/protocol/frame.py +30 -0
- kafka/protocol/generate_stubs.py +468 -0
- kafka/protocol/metadata/__init__.py +10 -0
- kafka/protocol/metadata/api_versions.py +41 -0
- kafka/protocol/metadata/api_versions.pyi +128 -0
- kafka/protocol/metadata/find_coordinator.py +19 -0
- kafka/protocol/metadata/find_coordinator.pyi +105 -0
- kafka/protocol/metadata/metadata.py +34 -0
- kafka/protocol/metadata/metadata.pyi +160 -0
- kafka/protocol/old/__init__.py +0 -0
- kafka/protocol/old/abstract.py +17 -0
- kafka/protocol/old/add_offsets_to_txn.py +54 -0
- kafka/protocol/old/add_partitions_to_txn.py +71 -0
- kafka/protocol/old/admin.py +1086 -0
- kafka/protocol/old/api.py +205 -0
- kafka/protocol/old/api_versions.py +133 -0
- kafka/protocol/old/commit.py +355 -0
- kafka/protocol/old/consumer_protocol.py +36 -0
- kafka/protocol/old/end_txn.py +53 -0
- kafka/protocol/old/fetch.py +408 -0
- kafka/protocol/old/find_coordinator.py +72 -0
- kafka/protocol/old/group.py +451 -0
- kafka/protocol/old/init_producer_id.py +42 -0
- kafka/protocol/old/list_offsets.py +186 -0
- kafka/protocol/old/metadata.py +290 -0
- kafka/protocol/old/offset_for_leader_epoch.py +133 -0
- kafka/protocol/old/produce.py +247 -0
- kafka/protocol/old/sasl_authenticate.py +38 -0
- kafka/protocol/old/sasl_handshake.py +39 -0
- kafka/protocol/old/struct.py +87 -0
- kafka/protocol/old/txn_offset_commit.py +73 -0
- kafka/protocol/old/types.py +440 -0
- kafka/protocol/parser.py +191 -0
- kafka/protocol/producer/__init__.py +7 -0
- kafka/protocol/producer/produce.py +17 -0
- kafka/protocol/producer/produce.pyi +197 -0
- kafka/protocol/producer/transaction.py +30 -0
- kafka/protocol/producer/transaction.pyi +663 -0
- kafka/protocol/sasl.py +52 -0
- kafka/protocol/sasl.pyi +126 -0
- kafka/protocol/schemas/__init__.py +7 -0
- kafka/protocol/schemas/fields/__init__.py +7 -0
- kafka/protocol/schemas/fields/array.py +127 -0
- kafka/protocol/schemas/fields/base.py +156 -0
- kafka/protocol/schemas/fields/codecs/__init__.py +12 -0
- kafka/protocol/schemas/fields/codecs/encode_buffer.py +82 -0
- kafka/protocol/schemas/fields/codecs/tagged_fields.py +109 -0
- kafka/protocol/schemas/fields/codecs/types.py +505 -0
- kafka/protocol/schemas/fields/codegen.py +40 -0
- kafka/protocol/schemas/fields/simple.py +127 -0
- kafka/protocol/schemas/fields/struct.py +357 -0
- kafka/protocol/schemas/fields/struct_array.py +142 -0
- kafka/protocol/schemas/load_json.py +42 -0
- kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +40 -0
- kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +35 -0
- kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +65 -0
- kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +60 -0
- kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +47 -0
- kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +41 -0
- kafka/protocol/schemas/resources/AlterConfigsRequest.json +43 -0
- kafka/protocol/schemas/resources/AlterConfigsResponse.json +39 -0
- kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +42 -0
- kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +47 -0
- kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +41 -0
- kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +41 -0
- kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +45 -0
- kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +35 -0
- kafka/protocol/schemas/resources/ApiVersionsRequest.json +34 -0
- kafka/protocol/schemas/resources/ApiVersionsResponse.json +79 -0
- kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +42 -0
- kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +49 -0
- kafka/protocol/schemas/resources/CreateAclsRequest.json +46 -0
- kafka/protocol/schemas/resources/CreateAclsResponse.json +37 -0
- kafka/protocol/schemas/resources/CreatePartitionsRequest.json +47 -0
- kafka/protocol/schemas/resources/CreatePartitionsResponse.json +41 -0
- kafka/protocol/schemas/resources/CreateTopicsRequest.json +65 -0
- kafka/protocol/schemas/resources/CreateTopicsResponse.json +72 -0
- kafka/protocol/schemas/resources/DeleteAclsRequest.json +46 -0
- kafka/protocol/schemas/resources/DeleteAclsResponse.json +59 -0
- kafka/protocol/schemas/resources/DeleteGroupsRequest.json +30 -0
- kafka/protocol/schemas/resources/DeleteGroupsResponse.json +36 -0
- kafka/protocol/schemas/resources/DeleteRecordsRequest.json +42 -0
- kafka/protocol/schemas/resources/DeleteRecordsResponse.json +43 -0
- kafka/protocol/schemas/resources/DeleteTopicsRequest.json +43 -0
- kafka/protocol/schemas/resources/DeleteTopicsResponse.json +52 -0
- kafka/protocol/schemas/resources/DescribeAclsRequest.json +43 -0
- kafka/protocol/schemas/resources/DescribeAclsResponse.json +55 -0
- kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +37 -0
- kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +47 -0
- kafka/protocol/schemas/resources/DescribeClusterRequest.json +35 -0
- kafka/protocol/schemas/resources/DescribeClusterResponse.json +56 -0
- kafka/protocol/schemas/resources/DescribeConfigsRequest.json +42 -0
- kafka/protocol/schemas/resources/DescribeConfigsResponse.json +69 -0
- kafka/protocol/schemas/resources/DescribeGroupsRequest.json +38 -0
- kafka/protocol/schemas/resources/DescribeGroupsResponse.json +74 -0
- kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +38 -0
- kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +65 -0
- kafka/protocol/schemas/resources/DescribeProducersRequest.json +32 -0
- kafka/protocol/schemas/resources/DescribeProducersResponse.json +55 -0
- kafka/protocol/schemas/resources/DescribeQuorumRequest.json +39 -0
- kafka/protocol/schemas/resources/DescribeQuorumResponse.json +82 -0
- kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +40 -0
- kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +66 -0
- kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +27 -0
- kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +52 -0
- kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +30 -0
- kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +45 -0
- kafka/protocol/schemas/resources/ElectLeadersRequest.json +41 -0
- kafka/protocol/schemas/resources/ElectLeadersResponse.json +45 -0
- kafka/protocol/schemas/resources/EndTxnRequest.json +43 -0
- kafka/protocol/schemas/resources/EndTxnResponse.json +41 -0
- kafka/protocol/schemas/resources/FetchRequest.json +125 -0
- kafka/protocol/schemas/resources/FetchResponse.json +124 -0
- kafka/protocol/schemas/resources/FindCoordinatorRequest.json +43 -0
- kafka/protocol/schemas/resources/FindCoordinatorResponse.json +58 -0
- kafka/protocol/schemas/resources/HeartbeatRequest.json +39 -0
- kafka/protocol/schemas/resources/HeartbeatResponse.json +35 -0
- kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +44 -0
- kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +38 -0
- kafka/protocol/schemas/resources/InitProducerIdRequest.json +50 -0
- kafka/protocol/schemas/resources/InitProducerIdResponse.json +47 -0
- kafka/protocol/schemas/resources/JoinGroupRequest.json +63 -0
- kafka/protocol/schemas/resources/JoinGroupResponse.json +69 -0
- kafka/protocol/schemas/resources/LeaveGroupRequest.json +47 -0
- kafka/protocol/schemas/resources/LeaveGroupResponse.json +47 -0
- kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +31 -0
- kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +37 -0
- kafka/protocol/schemas/resources/ListGroupsRequest.json +36 -0
- kafka/protocol/schemas/resources/ListGroupsResponse.json +49 -0
- kafka/protocol/schemas/resources/ListOffsetsRequest.json +72 -0
- kafka/protocol/schemas/resources/ListOffsetsResponse.json +71 -0
- kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +34 -0
- kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +46 -0
- kafka/protocol/schemas/resources/ListTransactionsRequest.json +40 -0
- kafka/protocol/schemas/resources/ListTransactionsResponse.json +42 -0
- kafka/protocol/schemas/resources/MetadataRequest.json +56 -0
- kafka/protocol/schemas/resources/MetadataResponse.json +101 -0
- kafka/protocol/schemas/resources/OffsetCommitRequest.json +76 -0
- kafka/protocol/schemas/resources/OffsetCommitResponse.json +71 -0
- kafka/protocol/schemas/resources/OffsetDeleteRequest.json +39 -0
- kafka/protocol/schemas/resources/OffsetDeleteResponse.json +42 -0
- kafka/protocol/schemas/resources/OffsetFetchRequest.json +76 -0
- kafka/protocol/schemas/resources/OffsetFetchResponse.json +107 -0
- kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +52 -0
- kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +51 -0
- kafka/protocol/schemas/resources/ProduceRequest.json +73 -0
- kafka/protocol/schemas/resources/ProduceResponse.json +96 -0
- kafka/protocol/schemas/resources/RequestHeader.json +44 -0
- kafka/protocol/schemas/resources/ResponseHeader.json +26 -0
- kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +29 -0
- kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +34 -0
- kafka/protocol/schemas/resources/SaslHandshakeRequest.json +31 -0
- kafka/protocol/schemas/resources/SaslHandshakeResponse.json +32 -0
- kafka/protocol/schemas/resources/SyncGroupRequest.json +56 -0
- kafka/protocol/schemas/resources/SyncGroupResponse.json +46 -0
- kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +68 -0
- kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +47 -0
- kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +43 -0
- kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +39 -0
- kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +49 -0
- kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +45 -0
- kafka/protocol/schemas/resources/__init__.py +0 -0
- kafka/record/__init__.py +3 -0
- kafka/record/_crc32c.py +161 -0
- kafka/record/abc.py +144 -0
- kafka/record/default_records.py +782 -0
- kafka/record/legacy_records.py +587 -0
- kafka/record/memory_records.py +255 -0
- kafka/record/util.py +135 -0
- kafka/serializer/__init__.py +4 -0
- kafka/serializer/abstract.py +20 -0
- kafka/serializer/default.py +16 -0
- kafka/serializer/json.py +17 -0
- kafka/serializer/wrapper.py +21 -0
- kafka/structs.py +69 -0
- kafka/util.py +159 -0
- kafka/vendor/__init__.py +0 -0
- kafka/version.py +1 -0
- kafka_python-3.0.0.dist-info/METADATA +319 -0
- kafka_python-3.0.0.dist-info/RECORD +373 -0
- kafka_python-3.0.0.dist-info/WHEEL +5 -0
- kafka_python-3.0.0.dist-info/entry_points.txt +2 -0
- kafka_python-3.0.0.dist-info/licenses/LICENSE +202 -0
- kafka_python-3.0.0.dist-info/top_level.txt +1 -0
kafka/protocol/parser.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
import logging
|
|
3
|
+
import struct
|
|
4
|
+
|
|
5
|
+
import kafka.errors as Errors
|
|
6
|
+
from kafka.protocol.metadata import FindCoordinatorResponse
|
|
7
|
+
from kafka.protocol.frame import KafkaBytes
|
|
8
|
+
from kafka.protocol.schemas.fields.codecs import Int32
|
|
9
|
+
from kafka.version import __version__
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class KafkaProtocol:
|
|
15
|
+
"""Manage the kafka network protocol
|
|
16
|
+
|
|
17
|
+
Use an instance of KafkaProtocol to manage bytes send/recv'd
|
|
18
|
+
from a network socket to a broker.
|
|
19
|
+
|
|
20
|
+
Arguments:
|
|
21
|
+
client_id (str): identifier string to be included in each request
|
|
22
|
+
ident (str): Optional log-prefix identifier.
|
|
23
|
+
receive_message_max_bytes (int): Maximum allowed message frame size.
|
|
24
|
+
Default: 100000000 (100MB).
|
|
25
|
+
"""
|
|
26
|
+
def __init__(self, **config):
|
|
27
|
+
self._ident = config.get('ident', '')
|
|
28
|
+
self._client_id = config.get('client_id', self._gen_client_id())
|
|
29
|
+
self._max_frame_size = config.get('receive_message_max_bytes', 100000000)
|
|
30
|
+
self._correlation_id = 0
|
|
31
|
+
self._header = KafkaBytes(4)
|
|
32
|
+
self._rbuffer = None
|
|
33
|
+
self._receiving = False
|
|
34
|
+
self.in_flight_requests = collections.deque()
|
|
35
|
+
self.bytes_to_send = []
|
|
36
|
+
|
|
37
|
+
def _next_correlation_id(self):
|
|
38
|
+
self._correlation_id = (self._correlation_id + 1) % 2**31
|
|
39
|
+
return self._correlation_id
|
|
40
|
+
|
|
41
|
+
def _gen_client_id(self):
|
|
42
|
+
return 'kafka-python' + __version__
|
|
43
|
+
|
|
44
|
+
def send_request(self, request, correlation_id=None):
|
|
45
|
+
"""Encode and queue a kafka api request for sending.
|
|
46
|
+
|
|
47
|
+
Arguments:
|
|
48
|
+
request : An un-encoded kafka request.
|
|
49
|
+
correlation_id (int, optional): Optionally specify an ID to
|
|
50
|
+
correlate requests with responses. If not provided, an ID will
|
|
51
|
+
be generated automatically.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
correlation_id
|
|
55
|
+
"""
|
|
56
|
+
if correlation_id is None:
|
|
57
|
+
correlation_id = self._next_correlation_id()
|
|
58
|
+
|
|
59
|
+
log.debug('%s Sending request %d %s', self._ident, correlation_id, request)
|
|
60
|
+
request.with_header(correlation_id=correlation_id, client_id=self._client_id)
|
|
61
|
+
data = request.encode(framed=True, header=True)
|
|
62
|
+
self.bytes_to_send.append(data)
|
|
63
|
+
if request.expect_response():
|
|
64
|
+
self.in_flight_requests.append(request.header)
|
|
65
|
+
return correlation_id
|
|
66
|
+
|
|
67
|
+
def send_bytes(self):
|
|
68
|
+
"""Retrieve all pending bytes to send on the network"""
|
|
69
|
+
# Short-circuit the common single-request case to avoid an extra
|
|
70
|
+
# full-request copy through b''.join.
|
|
71
|
+
n = len(self.bytes_to_send)
|
|
72
|
+
if n == 0:
|
|
73
|
+
return b''
|
|
74
|
+
if n == 1:
|
|
75
|
+
data = self.bytes_to_send[0]
|
|
76
|
+
self.bytes_to_send = []
|
|
77
|
+
else:
|
|
78
|
+
data = b''.join(self.bytes_to_send)
|
|
79
|
+
self.bytes_to_send = []
|
|
80
|
+
log.debug('%s Send: %r', self._ident, data)
|
|
81
|
+
return data
|
|
82
|
+
|
|
83
|
+
def receive_bytes(self, data):
|
|
84
|
+
"""Process bytes received from the network.
|
|
85
|
+
|
|
86
|
+
Arguments:
|
|
87
|
+
data (bytes): any length bytes received from a network connection
|
|
88
|
+
to a kafka broker.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
responses (list of (correlation_id, response)): any/all completed
|
|
92
|
+
responses, decoded from bytes to python objects.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
KafkaProtocolError: if the bytes received could not be decoded.
|
|
96
|
+
CorrelationIdError: if the response does not match the request
|
|
97
|
+
correlation id.
|
|
98
|
+
"""
|
|
99
|
+
i = 0
|
|
100
|
+
n = len(data)
|
|
101
|
+
responses = []
|
|
102
|
+
if data:
|
|
103
|
+
log.debug('%s Recv: %r', self._ident, data)
|
|
104
|
+
while i < n:
|
|
105
|
+
|
|
106
|
+
# Not receiving is the state of reading the payload header
|
|
107
|
+
if not self._receiving:
|
|
108
|
+
bytes_to_read = min(4 - self._header.tell(), n - i)
|
|
109
|
+
self._header.write(data[i:i+bytes_to_read])
|
|
110
|
+
i += bytes_to_read
|
|
111
|
+
|
|
112
|
+
if self._header.tell() == 4:
|
|
113
|
+
self._header.seek(0)
|
|
114
|
+
nbytes = Int32.decode(self._header)
|
|
115
|
+
self._validate_frame_size(nbytes)
|
|
116
|
+
# reset buffer and switch state to receiving payload bytes
|
|
117
|
+
self._rbuffer = KafkaBytes(nbytes)
|
|
118
|
+
self._receiving = True
|
|
119
|
+
elif self._header.tell() > 4:
|
|
120
|
+
raise Errors.KafkaError('this should not happen - are you threading?')
|
|
121
|
+
|
|
122
|
+
if self._receiving:
|
|
123
|
+
total_bytes = len(self._rbuffer)
|
|
124
|
+
staged_bytes = self._rbuffer.tell()
|
|
125
|
+
bytes_to_read = min(total_bytes - staged_bytes, n - i)
|
|
126
|
+
self._rbuffer.write(data[i:i+bytes_to_read])
|
|
127
|
+
i += bytes_to_read
|
|
128
|
+
|
|
129
|
+
staged_bytes = self._rbuffer.tell()
|
|
130
|
+
if staged_bytes > total_bytes:
|
|
131
|
+
raise Errors.KafkaError('Receive buffer has more bytes than expected?')
|
|
132
|
+
|
|
133
|
+
if staged_bytes != total_bytes:
|
|
134
|
+
break
|
|
135
|
+
|
|
136
|
+
self._receiving = False
|
|
137
|
+
self._rbuffer.seek(0)
|
|
138
|
+
resp = self._process_response(self._rbuffer)
|
|
139
|
+
responses.append(resp)
|
|
140
|
+
self._reset_buffer()
|
|
141
|
+
return responses
|
|
142
|
+
|
|
143
|
+
def _validate_frame_size(self, nbytes):
|
|
144
|
+
if nbytes < 0 or nbytes > self._max_frame_size:
|
|
145
|
+
raise Errors.InvalidReceiveError('Invalid frame length: %d' % nbytes)
|
|
146
|
+
|
|
147
|
+
def _process_response(self, read_buffer):
|
|
148
|
+
if not self.in_flight_requests:
|
|
149
|
+
raise Errors.CorrelationIdError('No in-flight-request found for server response')
|
|
150
|
+
header = self.in_flight_requests.popleft()
|
|
151
|
+
correlation_id = header.correlation_id
|
|
152
|
+
response_type = header.get_response_class()
|
|
153
|
+
if response_type is None:
|
|
154
|
+
log.error('Unable to find ResponseType for api=%d version=%d',
|
|
155
|
+
header.api_key, header.api_version)
|
|
156
|
+
raise Errors.KafkaProtocolError('Unable to find response type for api %d v%d' % (header.api_key, header.api_version))
|
|
157
|
+
response_header = response_type.parse_header(read_buffer)
|
|
158
|
+
recv_correlation_id = response_header.correlation_id
|
|
159
|
+
# ignore correlation id mismatch for 0.8.2 quirk
|
|
160
|
+
if (recv_correlation_id == 0 and correlation_id != 0 and
|
|
161
|
+
response_type is FindCoordinatorResponse and header.api_version == 0):
|
|
162
|
+
log.warning('Kafka 0.8.2 quirk -- FindCoordinatorResponse'
|
|
163
|
+
' Correlation ID does not match request. This'
|
|
164
|
+
' should go away once at least one topic has been'
|
|
165
|
+
' initialized on the broker.')
|
|
166
|
+
|
|
167
|
+
elif correlation_id != recv_correlation_id:
|
|
168
|
+
# return or raise?
|
|
169
|
+
raise Errors.CorrelationIdError(
|
|
170
|
+
'Correlation IDs do not match: sent %d, recv %d'
|
|
171
|
+
% (correlation_id, recv_correlation_id))
|
|
172
|
+
|
|
173
|
+
# decode response
|
|
174
|
+
try:
|
|
175
|
+
response = response_type.decode(read_buffer)
|
|
176
|
+
except (ValueError, struct.error):
|
|
177
|
+
read_buffer.seek(0)
|
|
178
|
+
buf = read_buffer.read()
|
|
179
|
+
log.error('Response %d [ResponseType: %s RequestHeader: %s]:'
|
|
180
|
+
' Unable to decode %d-byte buffer: %r',
|
|
181
|
+
correlation_id, response_type,
|
|
182
|
+
header, len(buf), buf)
|
|
183
|
+
raise Errors.KafkaProtocolError('Unable to decode response')
|
|
184
|
+
|
|
185
|
+
log.debug('%s Received response %d %s', self._ident, correlation_id, response)
|
|
186
|
+
return (correlation_id, response)
|
|
187
|
+
|
|
188
|
+
def _reset_buffer(self):
|
|
189
|
+
self._receiving = False
|
|
190
|
+
self._header.seek(0)
|
|
191
|
+
self._rbuffer = None
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ..api_message import ApiMessage
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ProduceRequest(ApiMessage):
|
|
7
|
+
def expect_response(self) -> bool:
|
|
8
|
+
if self.acks == 0: # pylint: disable=no-member # ty: ignore[unresolved-attribute]
|
|
9
|
+
return False
|
|
10
|
+
return True
|
|
11
|
+
|
|
12
|
+
class ProduceResponse(ApiMessage): pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
'ProduceRequest', 'ProduceResponse',
|
|
17
|
+
]
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Generated by generate_stubs.py (Python 3.14)
|
|
2
|
+
import uuid
|
|
3
|
+
from typing import Any, Self
|
|
4
|
+
|
|
5
|
+
from kafka.protocol.api_message import ApiMessage
|
|
6
|
+
from kafka.protocol.api_data import ApiData
|
|
7
|
+
from kafka.protocol.data_container import DataContainer
|
|
8
|
+
|
|
9
|
+
__all__ = ['ProduceRequest', 'ProduceResponse']
|
|
10
|
+
|
|
11
|
+
class ProduceRequest(ApiMessage):
|
|
12
|
+
class TopicProduceData(DataContainer):
|
|
13
|
+
class PartitionProduceData(DataContainer):
|
|
14
|
+
index: int
|
|
15
|
+
records: bytes | ApiData | None
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
*args: Any,
|
|
19
|
+
index: int = ...,
|
|
20
|
+
records: bytes | ApiData | None = ...,
|
|
21
|
+
version: int | None = None,
|
|
22
|
+
**kwargs: Any,
|
|
23
|
+
) -> None: ...
|
|
24
|
+
@property
|
|
25
|
+
def version(self) -> int | None: ...
|
|
26
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
27
|
+
|
|
28
|
+
name: str
|
|
29
|
+
topic_id: uuid.UUID
|
|
30
|
+
partition_data: list[PartitionProduceData]
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
*args: Any,
|
|
34
|
+
name: str = ...,
|
|
35
|
+
topic_id: uuid.UUID = ...,
|
|
36
|
+
partition_data: list[PartitionProduceData] = ...,
|
|
37
|
+
version: int | None = None,
|
|
38
|
+
**kwargs: Any,
|
|
39
|
+
) -> None: ...
|
|
40
|
+
@property
|
|
41
|
+
def version(self) -> int | None: ...
|
|
42
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
43
|
+
|
|
44
|
+
transactional_id: str | None
|
|
45
|
+
acks: int
|
|
46
|
+
timeout_ms: int
|
|
47
|
+
topic_data: list[TopicProduceData]
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
*args: Any,
|
|
51
|
+
transactional_id: str | None = ...,
|
|
52
|
+
acks: int = ...,
|
|
53
|
+
timeout_ms: int = ...,
|
|
54
|
+
topic_data: list[TopicProduceData] = ...,
|
|
55
|
+
version: int | None = None,
|
|
56
|
+
**kwargs: Any,
|
|
57
|
+
) -> None: ...
|
|
58
|
+
@property
|
|
59
|
+
def version(self) -> int | None: ...
|
|
60
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
61
|
+
name: str
|
|
62
|
+
type: str
|
|
63
|
+
API_KEY: int
|
|
64
|
+
API_VERSION: int
|
|
65
|
+
valid_versions: tuple[int, int]
|
|
66
|
+
min_version: int
|
|
67
|
+
max_version: int
|
|
68
|
+
@property
|
|
69
|
+
def header(self) -> Any: ...
|
|
70
|
+
@classmethod
|
|
71
|
+
def is_request(cls) -> bool: ...
|
|
72
|
+
def expect_response(self) -> bool: ...
|
|
73
|
+
def with_header(self, correlation_id: int = 0, client_id: str = "kafka-python") -> None: ...
|
|
74
|
+
def expect_response(self) -> bool: ...
|
|
75
|
+
|
|
76
|
+
class ProduceResponse(ApiMessage):
|
|
77
|
+
class TopicProduceResponse(DataContainer):
|
|
78
|
+
class PartitionProduceResponse(DataContainer):
|
|
79
|
+
class BatchIndexAndErrorMessage(DataContainer):
|
|
80
|
+
batch_index: int
|
|
81
|
+
batch_index_error_message: str | None
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
*args: Any,
|
|
85
|
+
batch_index: int = ...,
|
|
86
|
+
batch_index_error_message: str | None = ...,
|
|
87
|
+
version: int | None = None,
|
|
88
|
+
**kwargs: Any,
|
|
89
|
+
) -> None: ...
|
|
90
|
+
@property
|
|
91
|
+
def version(self) -> int | None: ...
|
|
92
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
93
|
+
|
|
94
|
+
class LeaderIdAndEpoch(DataContainer):
|
|
95
|
+
leader_id: int
|
|
96
|
+
leader_epoch: int
|
|
97
|
+
def __init__(
|
|
98
|
+
self,
|
|
99
|
+
*args: Any,
|
|
100
|
+
leader_id: int = ...,
|
|
101
|
+
leader_epoch: int = ...,
|
|
102
|
+
version: int | None = None,
|
|
103
|
+
**kwargs: Any,
|
|
104
|
+
) -> None: ...
|
|
105
|
+
@property
|
|
106
|
+
def version(self) -> int | None: ...
|
|
107
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
108
|
+
|
|
109
|
+
index: int
|
|
110
|
+
error_code: int
|
|
111
|
+
base_offset: int
|
|
112
|
+
log_append_time_ms: int
|
|
113
|
+
log_start_offset: int
|
|
114
|
+
record_errors: list[BatchIndexAndErrorMessage]
|
|
115
|
+
error_message: str | None
|
|
116
|
+
current_leader: LeaderIdAndEpoch
|
|
117
|
+
def __init__(
|
|
118
|
+
self,
|
|
119
|
+
*args: Any,
|
|
120
|
+
index: int = ...,
|
|
121
|
+
error_code: int = ...,
|
|
122
|
+
base_offset: int = ...,
|
|
123
|
+
log_append_time_ms: int = ...,
|
|
124
|
+
log_start_offset: int = ...,
|
|
125
|
+
record_errors: list[BatchIndexAndErrorMessage] = ...,
|
|
126
|
+
error_message: str | None = ...,
|
|
127
|
+
current_leader: LeaderIdAndEpoch = ...,
|
|
128
|
+
version: int | None = None,
|
|
129
|
+
**kwargs: Any,
|
|
130
|
+
) -> None: ...
|
|
131
|
+
@property
|
|
132
|
+
def version(self) -> int | None: ...
|
|
133
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
134
|
+
|
|
135
|
+
name: str
|
|
136
|
+
topic_id: uuid.UUID
|
|
137
|
+
partition_responses: list[PartitionProduceResponse]
|
|
138
|
+
def __init__(
|
|
139
|
+
self,
|
|
140
|
+
*args: Any,
|
|
141
|
+
name: str = ...,
|
|
142
|
+
topic_id: uuid.UUID = ...,
|
|
143
|
+
partition_responses: list[PartitionProduceResponse] = ...,
|
|
144
|
+
version: int | None = None,
|
|
145
|
+
**kwargs: Any,
|
|
146
|
+
) -> None: ...
|
|
147
|
+
@property
|
|
148
|
+
def version(self) -> int | None: ...
|
|
149
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
150
|
+
|
|
151
|
+
class NodeEndpoint(DataContainer):
|
|
152
|
+
node_id: int
|
|
153
|
+
host: str
|
|
154
|
+
port: int
|
|
155
|
+
rack: str | None
|
|
156
|
+
def __init__(
|
|
157
|
+
self,
|
|
158
|
+
*args: Any,
|
|
159
|
+
node_id: int = ...,
|
|
160
|
+
host: str = ...,
|
|
161
|
+
port: int = ...,
|
|
162
|
+
rack: str | None = ...,
|
|
163
|
+
version: int | None = None,
|
|
164
|
+
**kwargs: Any,
|
|
165
|
+
) -> None: ...
|
|
166
|
+
@property
|
|
167
|
+
def version(self) -> int | None: ...
|
|
168
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
169
|
+
|
|
170
|
+
responses: list[TopicProduceResponse]
|
|
171
|
+
throttle_time_ms: int
|
|
172
|
+
node_endpoints: list[NodeEndpoint]
|
|
173
|
+
def __init__(
|
|
174
|
+
self,
|
|
175
|
+
*args: Any,
|
|
176
|
+
responses: list[TopicProduceResponse] = ...,
|
|
177
|
+
throttle_time_ms: int = ...,
|
|
178
|
+
node_endpoints: list[NodeEndpoint] = ...,
|
|
179
|
+
version: int | None = None,
|
|
180
|
+
**kwargs: Any,
|
|
181
|
+
) -> None: ...
|
|
182
|
+
@property
|
|
183
|
+
def version(self) -> int | None: ...
|
|
184
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
185
|
+
name: str
|
|
186
|
+
type: str
|
|
187
|
+
API_KEY: int
|
|
188
|
+
API_VERSION: int
|
|
189
|
+
valid_versions: tuple[int, int]
|
|
190
|
+
min_version: int
|
|
191
|
+
max_version: int
|
|
192
|
+
@property
|
|
193
|
+
def header(self) -> Any: ...
|
|
194
|
+
@classmethod
|
|
195
|
+
def is_request(cls) -> bool: ...
|
|
196
|
+
def expect_response(self) -> bool: ...
|
|
197
|
+
def with_header(self, correlation_id: int = 0, client_id: str = "kafka-python") -> None: ...
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from ..api_message import ApiMessage
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class InitProducerIdRequest(ApiMessage): pass
|
|
5
|
+
class InitProducerIdResponse(ApiMessage): pass
|
|
6
|
+
|
|
7
|
+
class AddPartitionsToTxnRequest(ApiMessage): pass
|
|
8
|
+
class AddPartitionsToTxnResponse(ApiMessage): pass
|
|
9
|
+
|
|
10
|
+
class AddOffsetsToTxnRequest(ApiMessage): pass
|
|
11
|
+
class AddOffsetsToTxnResponse(ApiMessage): pass
|
|
12
|
+
|
|
13
|
+
class EndTxnRequest(ApiMessage): pass
|
|
14
|
+
class EndTxnResponse(ApiMessage): pass
|
|
15
|
+
|
|
16
|
+
class TxnOffsetCommitRequest(ApiMessage): pass
|
|
17
|
+
class TxnOffsetCommitResponse(ApiMessage): pass
|
|
18
|
+
|
|
19
|
+
class WriteTxnMarkersRequest(ApiMessage): pass
|
|
20
|
+
class WriteTxnMarkersResponse(ApiMessage): pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
'InitProducerIdRequest', 'InitProducerIdResponse',
|
|
25
|
+
'AddPartitionsToTxnRequest', 'AddPartitionsToTxnResponse',
|
|
26
|
+
'AddOffsetsToTxnRequest', 'AddOffsetsToTxnResponse',
|
|
27
|
+
'EndTxnRequest', 'EndTxnResponse',
|
|
28
|
+
'TxnOffsetCommitRequest', 'TxnOffsetCommitResponse',
|
|
29
|
+
'WriteTxnMarkersRequest', 'WriteTxnMarkersResponse',
|
|
30
|
+
]
|