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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ..api_data import ApiData
|
|
4
|
+
from kafka.structs import TopicPartition
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
ConsumerProtocolType = 'consumer'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ConsumerProtocolSubscription(ApiData): pass
|
|
11
|
+
class ConsumerProtocolAssignment(ApiData):
|
|
12
|
+
|
|
13
|
+
# Compatibility with old manual protocol definition
|
|
14
|
+
@property
|
|
15
|
+
def assignment(self) -> list:
|
|
16
|
+
return self.assigned_partitions
|
|
17
|
+
|
|
18
|
+
@assignment.setter
|
|
19
|
+
def assignment(self, value: list) -> None:
|
|
20
|
+
self.assigned_partitions = value
|
|
21
|
+
|
|
22
|
+
def partitions(self) -> list[TopicPartition]:
|
|
23
|
+
return [TopicPartition(topic, partition)
|
|
24
|
+
for topic, partitions in self.assigned_partitions
|
|
25
|
+
for partition in partitions]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
'ConsumerProtocolSubscription', 'ConsumerProtocolAssignment', 'ConsumerProtocolType',
|
|
30
|
+
]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Generated by generate_stubs.py (Python 3.14)
|
|
2
|
+
import uuid
|
|
3
|
+
from typing import Any, Self
|
|
4
|
+
|
|
5
|
+
from kafka.protocol.api_data import ApiData
|
|
6
|
+
from kafka.protocol.data_container import DataContainer
|
|
7
|
+
|
|
8
|
+
__all__ = ['ConsumerProtocolSubscription', 'ConsumerProtocolAssignment', 'ConsumerProtocolType']
|
|
9
|
+
|
|
10
|
+
class ConsumerProtocolSubscription(ApiData):
|
|
11
|
+
class TopicPartition(DataContainer):
|
|
12
|
+
topic: str
|
|
13
|
+
partitions: list[int]
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
*args: Any,
|
|
17
|
+
topic: str = ...,
|
|
18
|
+
partitions: list[int] = ...,
|
|
19
|
+
version: int | None = None,
|
|
20
|
+
**kwargs: Any,
|
|
21
|
+
) -> None: ...
|
|
22
|
+
@property
|
|
23
|
+
def version(self) -> int | None: ...
|
|
24
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
25
|
+
|
|
26
|
+
topics: list[str]
|
|
27
|
+
user_data: bytes | ApiData | None
|
|
28
|
+
owned_partitions: list[TopicPartition]
|
|
29
|
+
generation_id: int
|
|
30
|
+
rack_id: str | None
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
*args: Any,
|
|
34
|
+
topics: list[str] = ...,
|
|
35
|
+
user_data: bytes | ApiData | None = ...,
|
|
36
|
+
owned_partitions: list[TopicPartition] = ...,
|
|
37
|
+
generation_id: int = ...,
|
|
38
|
+
rack_id: str | None = ...,
|
|
39
|
+
version: int | None = None,
|
|
40
|
+
**kwargs: Any,
|
|
41
|
+
) -> None: ...
|
|
42
|
+
@property
|
|
43
|
+
def version(self) -> int | None: ...
|
|
44
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
45
|
+
name: str
|
|
46
|
+
type: str
|
|
47
|
+
valid_versions: tuple[int, int]
|
|
48
|
+
min_version: int
|
|
49
|
+
max_version: int
|
|
50
|
+
|
|
51
|
+
class ConsumerProtocolAssignment(ApiData):
|
|
52
|
+
class TopicPartition(DataContainer):
|
|
53
|
+
topic: str
|
|
54
|
+
partitions: list[int]
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
*args: Any,
|
|
58
|
+
topic: str = ...,
|
|
59
|
+
partitions: list[int] = ...,
|
|
60
|
+
version: int | None = None,
|
|
61
|
+
**kwargs: Any,
|
|
62
|
+
) -> None: ...
|
|
63
|
+
@property
|
|
64
|
+
def version(self) -> int | None: ...
|
|
65
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
66
|
+
|
|
67
|
+
assigned_partitions: list[TopicPartition]
|
|
68
|
+
user_data: bytes | ApiData | None
|
|
69
|
+
def __init__(
|
|
70
|
+
self,
|
|
71
|
+
*args: Any,
|
|
72
|
+
assigned_partitions: list[TopicPartition] = ...,
|
|
73
|
+
user_data: bytes | ApiData | None = ...,
|
|
74
|
+
version: int | None = None,
|
|
75
|
+
**kwargs: Any,
|
|
76
|
+
) -> None: ...
|
|
77
|
+
@property
|
|
78
|
+
def version(self) -> int | None: ...
|
|
79
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
80
|
+
name: str
|
|
81
|
+
type: str
|
|
82
|
+
valid_versions: tuple[int, int]
|
|
83
|
+
min_version: int
|
|
84
|
+
max_version: int
|
|
85
|
+
@property
|
|
86
|
+
def assignment(self) -> list: ...
|
|
87
|
+
def partitions(self) -> list[TopicPartition]: ...
|
|
88
|
+
|
|
89
|
+
ConsumerProtocolType: str
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
|
|
3
|
+
from ..api_message import ApiMessage
|
|
4
|
+
from kafka.util import EnumHelper
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
UNKNOWN_OFFSET = -1
|
|
8
|
+
|
|
9
|
+
class OffsetResetStrategy:
|
|
10
|
+
LATEST = -1
|
|
11
|
+
EARLIEST = -2
|
|
12
|
+
NONE = 0
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class IsolationLevel(EnumHelper, IntEnum):
|
|
16
|
+
READ_UNCOMMITTED = 0
|
|
17
|
+
READ_COMMITTED = 1
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class OffsetSpec(EnumHelper, IntEnum):
|
|
21
|
+
# Any >= 0: # earliest offset whose timestamp is greater than or equal to the given timestamp and the timestamp of that record.
|
|
22
|
+
LATEST = -1 # offset of the next message that will be appended to the log and a timestamp of -1
|
|
23
|
+
EARLIEST = -2 # first offset on the partition, including remote-storage, and a timestamp of -1
|
|
24
|
+
MAX_TIMESTAMP = -3 # offset and timestamp corresponding to the record with the highest timestamp on the partition. (KIP-734)
|
|
25
|
+
EARLIEST_LOCAL = -4 # first offset on the local partition of the leader broker, excluding remote-storage, and a timestamp of -1 (KIP-405)
|
|
26
|
+
LATEST_TIERED = -5 # the latest offset of the partition in remote storage (KIP-1005)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class OffsetTimestamp(int):
|
|
30
|
+
"""Millisecond-timestamp spec for partition offset lookup.
|
|
31
|
+
|
|
32
|
+
Wraps an int so it can be distinguished from a bare offset. Use with
|
|
33
|
+
:meth:`KafkaAdminClient.reset_group_offsets` (and anywhere else a spec
|
|
34
|
+
may be mixed with explicit offsets) to request "earliest offset whose
|
|
35
|
+
timestamp is >= N ms".
|
|
36
|
+
"""
|
|
37
|
+
__slots__ = ()
|
|
38
|
+
|
|
39
|
+
def __repr__(self):
|
|
40
|
+
return f'OffsetTimestamp({int(self)})'
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ListOffsetsRequest(ApiMessage):
|
|
44
|
+
@classmethod
|
|
45
|
+
def min_version_for_timestamp(cls, ts):
|
|
46
|
+
ts = OffsetSpec(ts)
|
|
47
|
+
if ts == OffsetSpec.MAX_TIMESTAMP:
|
|
48
|
+
return 7
|
|
49
|
+
elif ts == OffsetSpec.EARLIEST_LOCAL:
|
|
50
|
+
return 8
|
|
51
|
+
elif ts == OffsetSpec.LATEST_TIERED:
|
|
52
|
+
return 9
|
|
53
|
+
else:
|
|
54
|
+
return 0
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def min_version_for_isolation_level(cls, il):
|
|
58
|
+
if int(il) > 0:
|
|
59
|
+
return 2
|
|
60
|
+
else:
|
|
61
|
+
return 0
|
|
62
|
+
|
|
63
|
+
class ListOffsetsResponse(ApiMessage): pass
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class OffsetForLeaderEpochRequest(ApiMessage): pass
|
|
67
|
+
class OffsetForLeaderEpochResponse(ApiMessage): pass
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
'UNKNOWN_OFFSET', 'OffsetResetStrategy', 'IsolationLevel',
|
|
72
|
+
'OffsetSpec', 'OffsetTimestamp',
|
|
73
|
+
'ListOffsetsRequest', 'ListOffsetsResponse',
|
|
74
|
+
'OffsetForLeaderEpochRequest', 'OffsetForLeaderEpochResponse',
|
|
75
|
+
]
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Generated by generate_stubs.py (Python 3.14)
|
|
2
|
+
import uuid
|
|
3
|
+
from typing import Any, Self
|
|
4
|
+
|
|
5
|
+
from enum import IntEnum
|
|
6
|
+
from kafka.protocol.api_message import ApiMessage
|
|
7
|
+
from kafka.protocol.data_container import DataContainer
|
|
8
|
+
|
|
9
|
+
__all__ = ['UNKNOWN_OFFSET', 'OffsetResetStrategy', 'IsolationLevel', 'OffsetSpec', 'OffsetTimestamp', 'ListOffsetsRequest', 'ListOffsetsResponse', 'OffsetForLeaderEpochRequest', 'OffsetForLeaderEpochResponse']
|
|
10
|
+
|
|
11
|
+
UNKNOWN_OFFSET: int
|
|
12
|
+
|
|
13
|
+
class OffsetResetStrategy:
|
|
14
|
+
LATEST: int
|
|
15
|
+
EARLIEST: int
|
|
16
|
+
NONE: int
|
|
17
|
+
|
|
18
|
+
class IsolationLevel(EnumHelper, IntEnum):
|
|
19
|
+
READ_UNCOMMITTED: int
|
|
20
|
+
READ_COMMITTED: int
|
|
21
|
+
|
|
22
|
+
class OffsetSpec(EnumHelper, IntEnum):
|
|
23
|
+
LATEST: int
|
|
24
|
+
EARLIEST: int
|
|
25
|
+
MAX_TIMESTAMP: int
|
|
26
|
+
EARLIEST_LOCAL: int
|
|
27
|
+
LATEST_TIERED: int
|
|
28
|
+
|
|
29
|
+
class OffsetTimestamp(int):
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
class ListOffsetsRequest(ApiMessage):
|
|
33
|
+
class ListOffsetsTopic(DataContainer):
|
|
34
|
+
class ListOffsetsPartition(DataContainer):
|
|
35
|
+
partition_index: int
|
|
36
|
+
current_leader_epoch: int
|
|
37
|
+
timestamp: int
|
|
38
|
+
max_num_offsets: int
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
*args: Any,
|
|
42
|
+
partition_index: int = ...,
|
|
43
|
+
current_leader_epoch: int = ...,
|
|
44
|
+
timestamp: int = ...,
|
|
45
|
+
max_num_offsets: int = ...,
|
|
46
|
+
version: int | None = None,
|
|
47
|
+
**kwargs: Any,
|
|
48
|
+
) -> None: ...
|
|
49
|
+
@property
|
|
50
|
+
def version(self) -> int | None: ...
|
|
51
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
52
|
+
|
|
53
|
+
name: str
|
|
54
|
+
partitions: list[ListOffsetsPartition]
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
*args: Any,
|
|
58
|
+
name: str = ...,
|
|
59
|
+
partitions: list[ListOffsetsPartition] = ...,
|
|
60
|
+
version: int | None = None,
|
|
61
|
+
**kwargs: Any,
|
|
62
|
+
) -> None: ...
|
|
63
|
+
@property
|
|
64
|
+
def version(self) -> int | None: ...
|
|
65
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
66
|
+
|
|
67
|
+
replica_id: int
|
|
68
|
+
isolation_level: int
|
|
69
|
+
topics: list[ListOffsetsTopic]
|
|
70
|
+
timeout_ms: int
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
*args: Any,
|
|
74
|
+
replica_id: int = ...,
|
|
75
|
+
isolation_level: int = ...,
|
|
76
|
+
topics: list[ListOffsetsTopic] = ...,
|
|
77
|
+
timeout_ms: int = ...,
|
|
78
|
+
version: int | None = None,
|
|
79
|
+
**kwargs: Any,
|
|
80
|
+
) -> None: ...
|
|
81
|
+
@property
|
|
82
|
+
def version(self) -> int | None: ...
|
|
83
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
84
|
+
name: str
|
|
85
|
+
type: str
|
|
86
|
+
API_KEY: int
|
|
87
|
+
API_VERSION: int
|
|
88
|
+
valid_versions: tuple[int, int]
|
|
89
|
+
min_version: int
|
|
90
|
+
max_version: int
|
|
91
|
+
@property
|
|
92
|
+
def header(self) -> Any: ...
|
|
93
|
+
@classmethod
|
|
94
|
+
def is_request(cls) -> bool: ...
|
|
95
|
+
def expect_response(self) -> bool: ...
|
|
96
|
+
def with_header(self, correlation_id: int = 0, client_id: str = "kafka-python") -> None: ...
|
|
97
|
+
@classmethod
|
|
98
|
+
def min_version_for_timestamp(cls, ts: Any) -> Any: ...
|
|
99
|
+
@classmethod
|
|
100
|
+
def min_version_for_isolation_level(cls, il: Any) -> Any: ...
|
|
101
|
+
|
|
102
|
+
class ListOffsetsResponse(ApiMessage):
|
|
103
|
+
class ListOffsetsTopicResponse(DataContainer):
|
|
104
|
+
class ListOffsetsPartitionResponse(DataContainer):
|
|
105
|
+
partition_index: int
|
|
106
|
+
error_code: int
|
|
107
|
+
old_style_offsets: list[int]
|
|
108
|
+
timestamp: int
|
|
109
|
+
offset: int
|
|
110
|
+
leader_epoch: int
|
|
111
|
+
def __init__(
|
|
112
|
+
self,
|
|
113
|
+
*args: Any,
|
|
114
|
+
partition_index: int = ...,
|
|
115
|
+
error_code: int = ...,
|
|
116
|
+
old_style_offsets: list[int] = ...,
|
|
117
|
+
timestamp: int = ...,
|
|
118
|
+
offset: int = ...,
|
|
119
|
+
leader_epoch: int = ...,
|
|
120
|
+
version: int | None = None,
|
|
121
|
+
**kwargs: Any,
|
|
122
|
+
) -> None: ...
|
|
123
|
+
@property
|
|
124
|
+
def version(self) -> int | None: ...
|
|
125
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
126
|
+
|
|
127
|
+
name: str
|
|
128
|
+
partitions: list[ListOffsetsPartitionResponse]
|
|
129
|
+
def __init__(
|
|
130
|
+
self,
|
|
131
|
+
*args: Any,
|
|
132
|
+
name: str = ...,
|
|
133
|
+
partitions: list[ListOffsetsPartitionResponse] = ...,
|
|
134
|
+
version: int | None = None,
|
|
135
|
+
**kwargs: Any,
|
|
136
|
+
) -> None: ...
|
|
137
|
+
@property
|
|
138
|
+
def version(self) -> int | None: ...
|
|
139
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
140
|
+
|
|
141
|
+
throttle_time_ms: int
|
|
142
|
+
topics: list[ListOffsetsTopicResponse]
|
|
143
|
+
def __init__(
|
|
144
|
+
self,
|
|
145
|
+
*args: Any,
|
|
146
|
+
throttle_time_ms: int = ...,
|
|
147
|
+
topics: list[ListOffsetsTopicResponse] = ...,
|
|
148
|
+
version: int | None = None,
|
|
149
|
+
**kwargs: Any,
|
|
150
|
+
) -> None: ...
|
|
151
|
+
@property
|
|
152
|
+
def version(self) -> int | None: ...
|
|
153
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
154
|
+
name: str
|
|
155
|
+
type: str
|
|
156
|
+
API_KEY: int
|
|
157
|
+
API_VERSION: int
|
|
158
|
+
valid_versions: tuple[int, int]
|
|
159
|
+
min_version: int
|
|
160
|
+
max_version: int
|
|
161
|
+
@property
|
|
162
|
+
def header(self) -> Any: ...
|
|
163
|
+
@classmethod
|
|
164
|
+
def is_request(cls) -> bool: ...
|
|
165
|
+
def expect_response(self) -> bool: ...
|
|
166
|
+
def with_header(self, correlation_id: int = 0, client_id: str = "kafka-python") -> None: ...
|
|
167
|
+
|
|
168
|
+
class OffsetForLeaderEpochRequest(ApiMessage):
|
|
169
|
+
class OffsetForLeaderTopic(DataContainer):
|
|
170
|
+
class OffsetForLeaderPartition(DataContainer):
|
|
171
|
+
partition: int
|
|
172
|
+
current_leader_epoch: int
|
|
173
|
+
leader_epoch: int
|
|
174
|
+
def __init__(
|
|
175
|
+
self,
|
|
176
|
+
*args: Any,
|
|
177
|
+
partition: int = ...,
|
|
178
|
+
current_leader_epoch: int = ...,
|
|
179
|
+
leader_epoch: int = ...,
|
|
180
|
+
version: int | None = None,
|
|
181
|
+
**kwargs: Any,
|
|
182
|
+
) -> None: ...
|
|
183
|
+
@property
|
|
184
|
+
def version(self) -> int | None: ...
|
|
185
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
186
|
+
|
|
187
|
+
topic: str
|
|
188
|
+
partitions: list[OffsetForLeaderPartition]
|
|
189
|
+
def __init__(
|
|
190
|
+
self,
|
|
191
|
+
*args: Any,
|
|
192
|
+
topic: str = ...,
|
|
193
|
+
partitions: list[OffsetForLeaderPartition] = ...,
|
|
194
|
+
version: int | None = None,
|
|
195
|
+
**kwargs: Any,
|
|
196
|
+
) -> None: ...
|
|
197
|
+
@property
|
|
198
|
+
def version(self) -> int | None: ...
|
|
199
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
200
|
+
|
|
201
|
+
replica_id: int
|
|
202
|
+
topics: list[OffsetForLeaderTopic]
|
|
203
|
+
def __init__(
|
|
204
|
+
self,
|
|
205
|
+
*args: Any,
|
|
206
|
+
replica_id: int = ...,
|
|
207
|
+
topics: list[OffsetForLeaderTopic] = ...,
|
|
208
|
+
version: int | None = None,
|
|
209
|
+
**kwargs: Any,
|
|
210
|
+
) -> None: ...
|
|
211
|
+
@property
|
|
212
|
+
def version(self) -> int | None: ...
|
|
213
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
214
|
+
name: str
|
|
215
|
+
type: str
|
|
216
|
+
API_KEY: int
|
|
217
|
+
API_VERSION: int
|
|
218
|
+
valid_versions: tuple[int, int]
|
|
219
|
+
min_version: int
|
|
220
|
+
max_version: int
|
|
221
|
+
@property
|
|
222
|
+
def header(self) -> Any: ...
|
|
223
|
+
@classmethod
|
|
224
|
+
def is_request(cls) -> bool: ...
|
|
225
|
+
def expect_response(self) -> bool: ...
|
|
226
|
+
def with_header(self, correlation_id: int = 0, client_id: str = "kafka-python") -> None: ...
|
|
227
|
+
|
|
228
|
+
class OffsetForLeaderEpochResponse(ApiMessage):
|
|
229
|
+
class OffsetForLeaderTopicResult(DataContainer):
|
|
230
|
+
class EpochEndOffset(DataContainer):
|
|
231
|
+
error_code: int
|
|
232
|
+
partition: int
|
|
233
|
+
leader_epoch: int
|
|
234
|
+
end_offset: int
|
|
235
|
+
def __init__(
|
|
236
|
+
self,
|
|
237
|
+
*args: Any,
|
|
238
|
+
error_code: int = ...,
|
|
239
|
+
partition: int = ...,
|
|
240
|
+
leader_epoch: int = ...,
|
|
241
|
+
end_offset: int = ...,
|
|
242
|
+
version: int | None = None,
|
|
243
|
+
**kwargs: Any,
|
|
244
|
+
) -> None: ...
|
|
245
|
+
@property
|
|
246
|
+
def version(self) -> int | None: ...
|
|
247
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
248
|
+
|
|
249
|
+
topic: str
|
|
250
|
+
partitions: list[EpochEndOffset]
|
|
251
|
+
def __init__(
|
|
252
|
+
self,
|
|
253
|
+
*args: Any,
|
|
254
|
+
topic: str = ...,
|
|
255
|
+
partitions: list[EpochEndOffset] = ...,
|
|
256
|
+
version: int | None = None,
|
|
257
|
+
**kwargs: Any,
|
|
258
|
+
) -> None: ...
|
|
259
|
+
@property
|
|
260
|
+
def version(self) -> int | None: ...
|
|
261
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
262
|
+
|
|
263
|
+
throttle_time_ms: int
|
|
264
|
+
topics: list[OffsetForLeaderTopicResult]
|
|
265
|
+
def __init__(
|
|
266
|
+
self,
|
|
267
|
+
*args: Any,
|
|
268
|
+
throttle_time_ms: int = ...,
|
|
269
|
+
topics: list[OffsetForLeaderTopicResult] = ...,
|
|
270
|
+
version: int | None = None,
|
|
271
|
+
**kwargs: Any,
|
|
272
|
+
) -> None: ...
|
|
273
|
+
@property
|
|
274
|
+
def version(self) -> int | None: ...
|
|
275
|
+
def to_dict(self, meta: bool = False, json: bool = True) -> dict: ...
|
|
276
|
+
name: str
|
|
277
|
+
type: str
|
|
278
|
+
API_KEY: int
|
|
279
|
+
API_VERSION: int
|
|
280
|
+
valid_versions: tuple[int, int]
|
|
281
|
+
min_version: int
|
|
282
|
+
max_version: int
|
|
283
|
+
@property
|
|
284
|
+
def header(self) -> Any: ...
|
|
285
|
+
@classmethod
|
|
286
|
+
def is_request(cls) -> bool: ...
|
|
287
|
+
def expect_response(self) -> bool: ...
|
|
288
|
+
def with_header(self, correlation_id: int = 0, client_id: str = "kafka-python") -> None: ...
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
from kafka.util import classproperty
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SlotsBuilder(type):
|
|
5
|
+
def __new__(metacls, name, bases, attrs, **kw):
|
|
6
|
+
if attrs.get('_struct') is not None:
|
|
7
|
+
attrs['__slots__'] = attrs.get('__slots__', ()) + tuple(attrs['_struct'].fields.keys())
|
|
8
|
+
return super().__new__(metacls, name, bases, attrs)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DataContainer(metaclass=SlotsBuilder):
|
|
12
|
+
__slots__ = ('tags', 'unknown_tags', '_version')
|
|
13
|
+
_struct = None
|
|
14
|
+
|
|
15
|
+
def __init_subclass__(cls, **kwargs):
|
|
16
|
+
super().__init_subclass__(**kwargs)
|
|
17
|
+
# Generate field data_classes and set as class attrs (by field.type_str)
|
|
18
|
+
if cls._struct is not None:
|
|
19
|
+
for field in cls._struct.fields.values():
|
|
20
|
+
if field.is_struct() or field.is_struct_array():
|
|
21
|
+
if not field.has_data_class():
|
|
22
|
+
field.set_data_class(type(field.type_str, (DataContainer,), {'_struct': field}))
|
|
23
|
+
setattr(cls, field.type_str, field.data_class)
|
|
24
|
+
|
|
25
|
+
def __init__(self, *args, version=None, **field_vals):
|
|
26
|
+
assert self._struct is not None
|
|
27
|
+
if version is not None and not self._struct.min_version <= version <= self._struct.max_version:
|
|
28
|
+
raise ValueError(f'Invalid version: {version} (min={self._struct.min_version}, max={self._struct.max_version})')
|
|
29
|
+
self._version = version
|
|
30
|
+
# Support positional arg init for convenience
|
|
31
|
+
if len(args) > 0:
|
|
32
|
+
field_args = self._struct.untagged_fields(self._version) if self._version is not None else self._struct._fields
|
|
33
|
+
if len(args) > len(field_args):
|
|
34
|
+
raise RuntimeError('Unable to init DataContainer with %d positional args: unexpected %d' % (len(args), len(field_args)))
|
|
35
|
+
field_vals.update({field_args[i].name: arg for i, arg in enumerate(args)})
|
|
36
|
+
args = ()
|
|
37
|
+
self.tags = None
|
|
38
|
+
self.unknown_tags = None
|
|
39
|
+
for field in self._struct._fields:
|
|
40
|
+
name = field.name
|
|
41
|
+
if name in field_vals:
|
|
42
|
+
if field._tag is not None:
|
|
43
|
+
if self.tags is None:
|
|
44
|
+
self.tags = set()
|
|
45
|
+
self.tags.add(name)
|
|
46
|
+
setattr(self, name, field_vals.pop(name))
|
|
47
|
+
# set default values for in-version attributes only
|
|
48
|
+
# for outbound requests these fields will be encoded and this
|
|
49
|
+
# optimizes to avoid __getattr__ lookups in the general case
|
|
50
|
+
elif self._version is not None and field.for_version_q(self._version):
|
|
51
|
+
setattr(self, name, field.default)
|
|
52
|
+
# Remaining field_vals are unknown tags or errors
|
|
53
|
+
for name in list(field_vals):
|
|
54
|
+
if name.startswith('_'):
|
|
55
|
+
if self.unknown_tags is None:
|
|
56
|
+
self.unknown_tags = {}
|
|
57
|
+
self.unknown_tags[name] = field_vals.pop(name)
|
|
58
|
+
if field_vals:
|
|
59
|
+
raise ValueError('Unrecognized fields for type %s: %s' % (self._struct.name, field_vals))
|
|
60
|
+
|
|
61
|
+
def __getattr__(self, name):
|
|
62
|
+
# Only called when normal slot lookup fails (field not set).
|
|
63
|
+
# Returns the schema default for fields outside the decoded version.
|
|
64
|
+
field_map = self._struct.fields
|
|
65
|
+
if name in field_map:
|
|
66
|
+
return field_map[name].default
|
|
67
|
+
raise AttributeError("'%s' object has no attribute '%s'" % (type(self).__name__, name))
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def version(self):
|
|
71
|
+
return self._version
|
|
72
|
+
|
|
73
|
+
def encode(self, *args, **kwargs):
|
|
74
|
+
"""Add version= to kwargs, otherwise pass-through to _struct"""
|
|
75
|
+
return self._struct.encode(self, *args, **kwargs)
|
|
76
|
+
|
|
77
|
+
def encode_into(self, out, *args, **kwargs):
|
|
78
|
+
"""Buffer-based encode, pass-through to _struct.encode_into"""
|
|
79
|
+
self._struct.encode_into(self, out, *args, **kwargs)
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def decode(cls, data, **kwargs):
|
|
83
|
+
"""Add version= to kwargs, otherwise pass-through to _struct"""
|
|
84
|
+
return cls._struct.decode(data, **kwargs)
|
|
85
|
+
|
|
86
|
+
@classproperty
|
|
87
|
+
def fields(cls): # pylint: disable=E0213
|
|
88
|
+
return cls._struct.fields
|
|
89
|
+
|
|
90
|
+
def __repr__(self):
|
|
91
|
+
if self._version is not None:
|
|
92
|
+
v_filter = lambda field: field.for_version_q(self._version)
|
|
93
|
+
key_vals = ['version=%s' % self._version]
|
|
94
|
+
else:
|
|
95
|
+
v_filter = lambda field: True
|
|
96
|
+
key_vals = []
|
|
97
|
+
for field in filter(v_filter, self._struct._fields):
|
|
98
|
+
key_vals.append('%s=%s' % (field.name, repr(getattr(self, field.name))))
|
|
99
|
+
return self.__class__.__name__ + '(' + ', '.join(key_vals) + ')'
|
|
100
|
+
|
|
101
|
+
def __eq__(self, other):
|
|
102
|
+
# For backwards compatibility Data struct is equal to tuple with same field values
|
|
103
|
+
if isinstance(other, tuple):
|
|
104
|
+
# TODO: handle fields changes by version?
|
|
105
|
+
if len(other) < len(self._struct._fields):
|
|
106
|
+
return False
|
|
107
|
+
for i, field in enumerate(self._struct._fields):
|
|
108
|
+
if getattr(self, field.name) != other[i]:
|
|
109
|
+
return False
|
|
110
|
+
if len(other) == len(self._struct._fields):
|
|
111
|
+
return True
|
|
112
|
+
elif len(other) == len(self._struct._fields) + 1 and isinstance(other[-1], dict) and other[-1] == {}:
|
|
113
|
+
# TODO: Handle non-empty tag dicts...
|
|
114
|
+
return True
|
|
115
|
+
return False
|
|
116
|
+
if self.__class__ != other.__class__:
|
|
117
|
+
return False
|
|
118
|
+
if self._struct != other._struct:
|
|
119
|
+
return False
|
|
120
|
+
for field in self._struct._fields:
|
|
121
|
+
if getattr(self, field.name) != getattr(other, field.name):
|
|
122
|
+
return False
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
def __iter__(self):
|
|
126
|
+
if self._version is None:
|
|
127
|
+
raise RuntimeError('DataContainer Iteration not supported without _version')
|
|
128
|
+
return iter([getattr(self, field.name) for field in self._struct.untagged_fields(self._version)])
|
|
129
|
+
|
|
130
|
+
def _to_dict_vals(self, meta=False, json=True):
|
|
131
|
+
if meta:
|
|
132
|
+
yield ('_type', self.__class__.__name__)
|
|
133
|
+
yield ('_version', self._version)
|
|
134
|
+
if meta != 'all':
|
|
135
|
+
meta=False
|
|
136
|
+
for field in self._struct._fields:
|
|
137
|
+
if self._version is not None and not field.for_version_q(self._version):
|
|
138
|
+
continue
|
|
139
|
+
if field.is_struct():
|
|
140
|
+
val = getattr(self, field.name)
|
|
141
|
+
yield (field.name, None if val is None else dict(val._to_dict_vals(meta=meta, json=json)))
|
|
142
|
+
elif field.is_struct_array():
|
|
143
|
+
val = getattr(self, field.name)
|
|
144
|
+
yield (field.name, None if val is None else [dict(v._to_dict_vals(meta=meta, json=json)) for v in val])
|
|
145
|
+
else:
|
|
146
|
+
val = getattr(self, field.name)
|
|
147
|
+
yield (field.name, field.to_json(val) if json else val)
|
|
148
|
+
|
|
149
|
+
def to_dict(self, meta=False, json=True):
|
|
150
|
+
"""Use meta=True to include top-level version; meta='all' to include all internal versions
|
|
151
|
+
json=False to return raw encoding; json=True (default) to convert values to be json-serializable
|
|
152
|
+
"""
|
|
153
|
+
return dict(self._to_dict_vals(meta=meta, json=json))
|
|
154
|
+
|
|
155
|
+
def __getitem__(self, key):
|
|
156
|
+
if self._version is None:
|
|
157
|
+
raise RuntimeError('DataContainer subscript not supported without _version')
|
|
158
|
+
elif isinstance(key, int):
|
|
159
|
+
field = self._struct.untagged_fields(self._version)[key]
|
|
160
|
+
return getattr(self, field.name)
|
|
161
|
+
elif isinstance(key, slice):
|
|
162
|
+
fields = self._struct.untagged_fields(self._version)
|
|
163
|
+
start, stop, step = key.indices(len(fields))
|
|
164
|
+
return [getattr(self, fields[i].name) for i in range(start, stop, step)]
|
|
165
|
+
else:
|
|
166
|
+
raise TypeError('DataContainer subscript supports int or slices only: %s' % type(key).__name__)
|
kafka/protocol/frame.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class KafkaBytes(bytearray):
|
|
2
|
+
def __init__(self, size):
|
|
3
|
+
super().__init__(size)
|
|
4
|
+
self._idx = 0
|
|
5
|
+
|
|
6
|
+
def read(self, nbytes=None):
|
|
7
|
+
if nbytes is None:
|
|
8
|
+
nbytes = len(self) - self._idx
|
|
9
|
+
start = self._idx
|
|
10
|
+
self._idx += nbytes
|
|
11
|
+
if self._idx > len(self):
|
|
12
|
+
self._idx = len(self)
|
|
13
|
+
return bytes(self[start:self._idx])
|
|
14
|
+
|
|
15
|
+
def write(self, data):
|
|
16
|
+
start = self._idx
|
|
17
|
+
self._idx += len(data)
|
|
18
|
+
self[start:self._idx] = data
|
|
19
|
+
|
|
20
|
+
def seek(self, idx):
|
|
21
|
+
self._idx = idx
|
|
22
|
+
|
|
23
|
+
def tell(self):
|
|
24
|
+
return self._idx
|
|
25
|
+
|
|
26
|
+
def __str__(self):
|
|
27
|
+
return 'KafkaBytes(%d)' % len(self)
|
|
28
|
+
|
|
29
|
+
def __repr__(self):
|
|
30
|
+
return str(self)
|