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.
Files changed (373) hide show
  1. kafka/__init__.py +34 -0
  2. kafka/__main__.py +5 -0
  3. kafka/admin/__init__.py +29 -0
  4. kafka/admin/__main__.py +5 -0
  5. kafka/admin/_acls.py +355 -0
  6. kafka/admin/_cluster.py +359 -0
  7. kafka/admin/_configs.py +479 -0
  8. kafka/admin/_groups.py +754 -0
  9. kafka/admin/_partitions.py +595 -0
  10. kafka/admin/_topics.py +281 -0
  11. kafka/admin/_transactions.py +450 -0
  12. kafka/admin/_users.py +194 -0
  13. kafka/admin/client.py +373 -0
  14. kafka/benchmarks/__init__.py +0 -0
  15. kafka/benchmarks/consumer_performance.py +138 -0
  16. kafka/benchmarks/load_example.py +109 -0
  17. kafka/benchmarks/producer_encode_path.py +201 -0
  18. kafka/benchmarks/producer_performance.py +161 -0
  19. kafka/benchmarks/profile_protocol.py +138 -0
  20. kafka/benchmarks/protocol_old_vs_new.py +447 -0
  21. kafka/benchmarks/record_batch_compose.py +77 -0
  22. kafka/benchmarks/record_batch_read.py +82 -0
  23. kafka/benchmarks/varint_speed.py +426 -0
  24. kafka/cli/__init__.py +36 -0
  25. kafka/cli/admin/__init__.py +117 -0
  26. kafka/cli/admin/acls/__init__.py +9 -0
  27. kafka/cli/admin/acls/common.py +76 -0
  28. kafka/cli/admin/acls/create.py +19 -0
  29. kafka/cli/admin/acls/delete.py +23 -0
  30. kafka/cli/admin/acls/describe.py +16 -0
  31. kafka/cli/admin/cluster/__init__.py +14 -0
  32. kafka/cli/admin/cluster/describe.py +11 -0
  33. kafka/cli/admin/cluster/describe_quorum.py +11 -0
  34. kafka/cli/admin/cluster/features.py +52 -0
  35. kafka/cli/admin/cluster/log_dirs.py +43 -0
  36. kafka/cli/admin/cluster/versions.py +33 -0
  37. kafka/cli/admin/configs/__init__.py +10 -0
  38. kafka/cli/admin/configs/alter.py +43 -0
  39. kafka/cli/admin/configs/common.py +17 -0
  40. kafka/cli/admin/configs/describe.py +30 -0
  41. kafka/cli/admin/configs/list.py +16 -0
  42. kafka/cli/admin/configs/reset.py +20 -0
  43. kafka/cli/admin/groups/__init__.py +16 -0
  44. kafka/cli/admin/groups/alter_offsets.py +30 -0
  45. kafka/cli/admin/groups/delete.py +11 -0
  46. kafka/cli/admin/groups/delete_offsets.py +29 -0
  47. kafka/cli/admin/groups/describe.py +11 -0
  48. kafka/cli/admin/groups/list.py +28 -0
  49. kafka/cli/admin/groups/list_offsets.py +29 -0
  50. kafka/cli/admin/groups/remove_members.py +40 -0
  51. kafka/cli/admin/groups/reset_offsets.py +139 -0
  52. kafka/cli/admin/partitions/__init__.py +21 -0
  53. kafka/cli/admin/partitions/alter_reassignments.py +37 -0
  54. kafka/cli/admin/partitions/create.py +27 -0
  55. kafka/cli/admin/partitions/delete_records.py +31 -0
  56. kafka/cli/admin/partitions/describe.py +36 -0
  57. kafka/cli/admin/partitions/elect_leaders.py +53 -0
  58. kafka/cli/admin/partitions/list_offsets.py +88 -0
  59. kafka/cli/admin/partitions/list_reassignments.py +35 -0
  60. kafka/cli/admin/topics/__init__.py +10 -0
  61. kafka/cli/admin/topics/create.py +13 -0
  62. kafka/cli/admin/topics/delete.py +19 -0
  63. kafka/cli/admin/topics/describe.py +18 -0
  64. kafka/cli/admin/topics/list.py +11 -0
  65. kafka/cli/admin/transactions/__init__.py +17 -0
  66. kafka/cli/admin/transactions/abort.py +38 -0
  67. kafka/cli/admin/transactions/describe.py +24 -0
  68. kafka/cli/admin/transactions/describe_producers.py +29 -0
  69. kafka/cli/admin/transactions/find_hanging.py +26 -0
  70. kafka/cli/admin/transactions/list.py +37 -0
  71. kafka/cli/admin/users/__init__.py +8 -0
  72. kafka/cli/admin/users/alter_user_scram_credentials.py +34 -0
  73. kafka/cli/admin/users/describe_user_scram_credentials.py +15 -0
  74. kafka/cli/common.py +95 -0
  75. kafka/cli/consumer/__init__.py +63 -0
  76. kafka/cli/producer/__init__.py +57 -0
  77. kafka/cluster.py +824 -0
  78. kafka/codec.py +325 -0
  79. kafka/consumer/__init__.py +5 -0
  80. kafka/consumer/__main__.py +5 -0
  81. kafka/consumer/fetcher.py +2012 -0
  82. kafka/consumer/group.py +1347 -0
  83. kafka/consumer/subscription_state.py +897 -0
  84. kafka/coordinator/__init__.py +0 -0
  85. kafka/coordinator/assignors/__init__.py +0 -0
  86. kafka/coordinator/assignors/abstract.py +90 -0
  87. kafka/coordinator/assignors/cooperative_sticky.py +167 -0
  88. kafka/coordinator/assignors/range.py +81 -0
  89. kafka/coordinator/assignors/roundrobin.py +101 -0
  90. kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +37 -0
  91. kafka/coordinator/assignors/sticky/__init__.py +0 -0
  92. kafka/coordinator/assignors/sticky/partition_movements.py +149 -0
  93. kafka/coordinator/assignors/sticky/sorted_set.py +63 -0
  94. kafka/coordinator/assignors/sticky/sticky_assignor.py +665 -0
  95. kafka/coordinator/assignors/sticky/user_data.py +8 -0
  96. kafka/coordinator/base.py +1215 -0
  97. kafka/coordinator/consumer.py +1224 -0
  98. kafka/coordinator/heartbeat.py +82 -0
  99. kafka/coordinator/subscription.py +34 -0
  100. kafka/errors.py +1004 -0
  101. kafka/future.py +166 -0
  102. kafka/metrics/__init__.py +13 -0
  103. kafka/metrics/compound_stat.py +33 -0
  104. kafka/metrics/dict_reporter.py +81 -0
  105. kafka/metrics/kafka_metric.py +36 -0
  106. kafka/metrics/measurable.py +27 -0
  107. kafka/metrics/measurable_stat.py +13 -0
  108. kafka/metrics/metric_config.py +33 -0
  109. kafka/metrics/metric_name.py +105 -0
  110. kafka/metrics/metrics.py +261 -0
  111. kafka/metrics/metrics_reporter.py +53 -0
  112. kafka/metrics/quota.py +41 -0
  113. kafka/metrics/stat.py +19 -0
  114. kafka/metrics/stats/__init__.py +15 -0
  115. kafka/metrics/stats/avg.py +24 -0
  116. kafka/metrics/stats/count.py +17 -0
  117. kafka/metrics/stats/histogram.py +99 -0
  118. kafka/metrics/stats/max_stat.py +17 -0
  119. kafka/metrics/stats/min_stat.py +19 -0
  120. kafka/metrics/stats/percentile.py +14 -0
  121. kafka/metrics/stats/percentiles.py +75 -0
  122. kafka/metrics/stats/rate.py +118 -0
  123. kafka/metrics/stats/sampled_stat.py +99 -0
  124. kafka/metrics/stats/sensor.py +136 -0
  125. kafka/metrics/stats/total.py +15 -0
  126. kafka/net/__init__.py +19 -0
  127. kafka/net/compat.py +165 -0
  128. kafka/net/connection.py +593 -0
  129. kafka/net/http_connect.py +144 -0
  130. kafka/net/inet.py +122 -0
  131. kafka/net/manager.py +451 -0
  132. kafka/net/metrics.py +149 -0
  133. kafka/net/sasl/__init__.py +32 -0
  134. kafka/net/sasl/abc.py +28 -0
  135. kafka/net/sasl/gssapi.py +95 -0
  136. kafka/net/sasl/msk.py +245 -0
  137. kafka/net/sasl/oauth.py +98 -0
  138. kafka/net/sasl/plain.py +42 -0
  139. kafka/net/sasl/scram.py +135 -0
  140. kafka/net/sasl/sspi.py +111 -0
  141. kafka/net/selector.py +644 -0
  142. kafka/net/socks5.py +262 -0
  143. kafka/net/transport.py +415 -0
  144. kafka/net/wakeup_notifier.py +72 -0
  145. kafka/partitioner/__init__.py +8 -0
  146. kafka/partitioner/abc.py +8 -0
  147. kafka/partitioner/default.py +89 -0
  148. kafka/partitioner/sticky.py +109 -0
  149. kafka/producer/__init__.py +5 -0
  150. kafka/producer/__main__.py +5 -0
  151. kafka/producer/future.py +101 -0
  152. kafka/producer/kafka.py +1123 -0
  153. kafka/producer/producer_batch.py +192 -0
  154. kafka/producer/record_accumulator.py +647 -0
  155. kafka/producer/sender.py +884 -0
  156. kafka/producer/transaction_manager.py +1326 -0
  157. kafka/protocol/__init__.py +0 -0
  158. kafka/protocol/admin/__init__.py +29 -0
  159. kafka/protocol/admin/acl.py +83 -0
  160. kafka/protocol/admin/acl.pyi +375 -0
  161. kafka/protocol/admin/client_quotas.py +14 -0
  162. kafka/protocol/admin/client_quotas.pyi +265 -0
  163. kafka/protocol/admin/cluster.py +31 -0
  164. kafka/protocol/admin/cluster.pyi +620 -0
  165. kafka/protocol/admin/configs.py +22 -0
  166. kafka/protocol/admin/configs.pyi +437 -0
  167. kafka/protocol/admin/groups.py +24 -0
  168. kafka/protocol/admin/groups.pyi +261 -0
  169. kafka/protocol/admin/topics.py +53 -0
  170. kafka/protocol/admin/topics.pyi +982 -0
  171. kafka/protocol/admin/transactions.py +18 -0
  172. kafka/protocol/admin/transactions.pyi +311 -0
  173. kafka/protocol/admin/users.py +14 -0
  174. kafka/protocol/admin/users.pyi +223 -0
  175. kafka/protocol/api_data.py +125 -0
  176. kafka/protocol/api_header.py +55 -0
  177. kafka/protocol/api_key.py +97 -0
  178. kafka/protocol/api_message.py +277 -0
  179. kafka/protocol/broker_version_data.py +246 -0
  180. kafka/protocol/consumer/__init__.py +13 -0
  181. kafka/protocol/consumer/fetch.py +16 -0
  182. kafka/protocol/consumer/fetch.pyi +298 -0
  183. kafka/protocol/consumer/group.py +38 -0
  184. kafka/protocol/consumer/group.pyi +824 -0
  185. kafka/protocol/consumer/metadata.py +30 -0
  186. kafka/protocol/consumer/metadata.pyi +89 -0
  187. kafka/protocol/consumer/offsets.py +75 -0
  188. kafka/protocol/consumer/offsets.pyi +288 -0
  189. kafka/protocol/data_container.py +166 -0
  190. kafka/protocol/frame.py +30 -0
  191. kafka/protocol/generate_stubs.py +468 -0
  192. kafka/protocol/metadata/__init__.py +10 -0
  193. kafka/protocol/metadata/api_versions.py +41 -0
  194. kafka/protocol/metadata/api_versions.pyi +128 -0
  195. kafka/protocol/metadata/find_coordinator.py +19 -0
  196. kafka/protocol/metadata/find_coordinator.pyi +105 -0
  197. kafka/protocol/metadata/metadata.py +34 -0
  198. kafka/protocol/metadata/metadata.pyi +160 -0
  199. kafka/protocol/old/__init__.py +0 -0
  200. kafka/protocol/old/abstract.py +17 -0
  201. kafka/protocol/old/add_offsets_to_txn.py +54 -0
  202. kafka/protocol/old/add_partitions_to_txn.py +71 -0
  203. kafka/protocol/old/admin.py +1086 -0
  204. kafka/protocol/old/api.py +205 -0
  205. kafka/protocol/old/api_versions.py +133 -0
  206. kafka/protocol/old/commit.py +355 -0
  207. kafka/protocol/old/consumer_protocol.py +36 -0
  208. kafka/protocol/old/end_txn.py +53 -0
  209. kafka/protocol/old/fetch.py +408 -0
  210. kafka/protocol/old/find_coordinator.py +72 -0
  211. kafka/protocol/old/group.py +451 -0
  212. kafka/protocol/old/init_producer_id.py +42 -0
  213. kafka/protocol/old/list_offsets.py +186 -0
  214. kafka/protocol/old/metadata.py +290 -0
  215. kafka/protocol/old/offset_for_leader_epoch.py +133 -0
  216. kafka/protocol/old/produce.py +247 -0
  217. kafka/protocol/old/sasl_authenticate.py +38 -0
  218. kafka/protocol/old/sasl_handshake.py +39 -0
  219. kafka/protocol/old/struct.py +87 -0
  220. kafka/protocol/old/txn_offset_commit.py +73 -0
  221. kafka/protocol/old/types.py +440 -0
  222. kafka/protocol/parser.py +191 -0
  223. kafka/protocol/producer/__init__.py +7 -0
  224. kafka/protocol/producer/produce.py +17 -0
  225. kafka/protocol/producer/produce.pyi +197 -0
  226. kafka/protocol/producer/transaction.py +30 -0
  227. kafka/protocol/producer/transaction.pyi +663 -0
  228. kafka/protocol/sasl.py +52 -0
  229. kafka/protocol/sasl.pyi +126 -0
  230. kafka/protocol/schemas/__init__.py +7 -0
  231. kafka/protocol/schemas/fields/__init__.py +7 -0
  232. kafka/protocol/schemas/fields/array.py +127 -0
  233. kafka/protocol/schemas/fields/base.py +156 -0
  234. kafka/protocol/schemas/fields/codecs/__init__.py +12 -0
  235. kafka/protocol/schemas/fields/codecs/encode_buffer.py +82 -0
  236. kafka/protocol/schemas/fields/codecs/tagged_fields.py +109 -0
  237. kafka/protocol/schemas/fields/codecs/types.py +505 -0
  238. kafka/protocol/schemas/fields/codegen.py +40 -0
  239. kafka/protocol/schemas/fields/simple.py +127 -0
  240. kafka/protocol/schemas/fields/struct.py +357 -0
  241. kafka/protocol/schemas/fields/struct_array.py +142 -0
  242. kafka/protocol/schemas/load_json.py +42 -0
  243. kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +40 -0
  244. kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +35 -0
  245. kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +65 -0
  246. kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +60 -0
  247. kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +47 -0
  248. kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +41 -0
  249. kafka/protocol/schemas/resources/AlterConfigsRequest.json +43 -0
  250. kafka/protocol/schemas/resources/AlterConfigsResponse.json +39 -0
  251. kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +42 -0
  252. kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +47 -0
  253. kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +41 -0
  254. kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +41 -0
  255. kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +45 -0
  256. kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +35 -0
  257. kafka/protocol/schemas/resources/ApiVersionsRequest.json +34 -0
  258. kafka/protocol/schemas/resources/ApiVersionsResponse.json +79 -0
  259. kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +42 -0
  260. kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +49 -0
  261. kafka/protocol/schemas/resources/CreateAclsRequest.json +46 -0
  262. kafka/protocol/schemas/resources/CreateAclsResponse.json +37 -0
  263. kafka/protocol/schemas/resources/CreatePartitionsRequest.json +47 -0
  264. kafka/protocol/schemas/resources/CreatePartitionsResponse.json +41 -0
  265. kafka/protocol/schemas/resources/CreateTopicsRequest.json +65 -0
  266. kafka/protocol/schemas/resources/CreateTopicsResponse.json +72 -0
  267. kafka/protocol/schemas/resources/DeleteAclsRequest.json +46 -0
  268. kafka/protocol/schemas/resources/DeleteAclsResponse.json +59 -0
  269. kafka/protocol/schemas/resources/DeleteGroupsRequest.json +30 -0
  270. kafka/protocol/schemas/resources/DeleteGroupsResponse.json +36 -0
  271. kafka/protocol/schemas/resources/DeleteRecordsRequest.json +42 -0
  272. kafka/protocol/schemas/resources/DeleteRecordsResponse.json +43 -0
  273. kafka/protocol/schemas/resources/DeleteTopicsRequest.json +43 -0
  274. kafka/protocol/schemas/resources/DeleteTopicsResponse.json +52 -0
  275. kafka/protocol/schemas/resources/DescribeAclsRequest.json +43 -0
  276. kafka/protocol/schemas/resources/DescribeAclsResponse.json +55 -0
  277. kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +37 -0
  278. kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +47 -0
  279. kafka/protocol/schemas/resources/DescribeClusterRequest.json +35 -0
  280. kafka/protocol/schemas/resources/DescribeClusterResponse.json +56 -0
  281. kafka/protocol/schemas/resources/DescribeConfigsRequest.json +42 -0
  282. kafka/protocol/schemas/resources/DescribeConfigsResponse.json +69 -0
  283. kafka/protocol/schemas/resources/DescribeGroupsRequest.json +38 -0
  284. kafka/protocol/schemas/resources/DescribeGroupsResponse.json +74 -0
  285. kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +38 -0
  286. kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +65 -0
  287. kafka/protocol/schemas/resources/DescribeProducersRequest.json +32 -0
  288. kafka/protocol/schemas/resources/DescribeProducersResponse.json +55 -0
  289. kafka/protocol/schemas/resources/DescribeQuorumRequest.json +39 -0
  290. kafka/protocol/schemas/resources/DescribeQuorumResponse.json +82 -0
  291. kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +40 -0
  292. kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +66 -0
  293. kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +27 -0
  294. kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +52 -0
  295. kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +30 -0
  296. kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +45 -0
  297. kafka/protocol/schemas/resources/ElectLeadersRequest.json +41 -0
  298. kafka/protocol/schemas/resources/ElectLeadersResponse.json +45 -0
  299. kafka/protocol/schemas/resources/EndTxnRequest.json +43 -0
  300. kafka/protocol/schemas/resources/EndTxnResponse.json +41 -0
  301. kafka/protocol/schemas/resources/FetchRequest.json +125 -0
  302. kafka/protocol/schemas/resources/FetchResponse.json +124 -0
  303. kafka/protocol/schemas/resources/FindCoordinatorRequest.json +43 -0
  304. kafka/protocol/schemas/resources/FindCoordinatorResponse.json +58 -0
  305. kafka/protocol/schemas/resources/HeartbeatRequest.json +39 -0
  306. kafka/protocol/schemas/resources/HeartbeatResponse.json +35 -0
  307. kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +44 -0
  308. kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +38 -0
  309. kafka/protocol/schemas/resources/InitProducerIdRequest.json +50 -0
  310. kafka/protocol/schemas/resources/InitProducerIdResponse.json +47 -0
  311. kafka/protocol/schemas/resources/JoinGroupRequest.json +63 -0
  312. kafka/protocol/schemas/resources/JoinGroupResponse.json +69 -0
  313. kafka/protocol/schemas/resources/LeaveGroupRequest.json +47 -0
  314. kafka/protocol/schemas/resources/LeaveGroupResponse.json +47 -0
  315. kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +31 -0
  316. kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +37 -0
  317. kafka/protocol/schemas/resources/ListGroupsRequest.json +36 -0
  318. kafka/protocol/schemas/resources/ListGroupsResponse.json +49 -0
  319. kafka/protocol/schemas/resources/ListOffsetsRequest.json +72 -0
  320. kafka/protocol/schemas/resources/ListOffsetsResponse.json +71 -0
  321. kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +34 -0
  322. kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +46 -0
  323. kafka/protocol/schemas/resources/ListTransactionsRequest.json +40 -0
  324. kafka/protocol/schemas/resources/ListTransactionsResponse.json +42 -0
  325. kafka/protocol/schemas/resources/MetadataRequest.json +56 -0
  326. kafka/protocol/schemas/resources/MetadataResponse.json +101 -0
  327. kafka/protocol/schemas/resources/OffsetCommitRequest.json +76 -0
  328. kafka/protocol/schemas/resources/OffsetCommitResponse.json +71 -0
  329. kafka/protocol/schemas/resources/OffsetDeleteRequest.json +39 -0
  330. kafka/protocol/schemas/resources/OffsetDeleteResponse.json +42 -0
  331. kafka/protocol/schemas/resources/OffsetFetchRequest.json +76 -0
  332. kafka/protocol/schemas/resources/OffsetFetchResponse.json +107 -0
  333. kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +52 -0
  334. kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +51 -0
  335. kafka/protocol/schemas/resources/ProduceRequest.json +73 -0
  336. kafka/protocol/schemas/resources/ProduceResponse.json +96 -0
  337. kafka/protocol/schemas/resources/RequestHeader.json +44 -0
  338. kafka/protocol/schemas/resources/ResponseHeader.json +26 -0
  339. kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +29 -0
  340. kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +34 -0
  341. kafka/protocol/schemas/resources/SaslHandshakeRequest.json +31 -0
  342. kafka/protocol/schemas/resources/SaslHandshakeResponse.json +32 -0
  343. kafka/protocol/schemas/resources/SyncGroupRequest.json +56 -0
  344. kafka/protocol/schemas/resources/SyncGroupResponse.json +46 -0
  345. kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +68 -0
  346. kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +47 -0
  347. kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +43 -0
  348. kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +39 -0
  349. kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +49 -0
  350. kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +45 -0
  351. kafka/protocol/schemas/resources/__init__.py +0 -0
  352. kafka/record/__init__.py +3 -0
  353. kafka/record/_crc32c.py +161 -0
  354. kafka/record/abc.py +144 -0
  355. kafka/record/default_records.py +782 -0
  356. kafka/record/legacy_records.py +587 -0
  357. kafka/record/memory_records.py +255 -0
  358. kafka/record/util.py +135 -0
  359. kafka/serializer/__init__.py +4 -0
  360. kafka/serializer/abstract.py +20 -0
  361. kafka/serializer/default.py +16 -0
  362. kafka/serializer/json.py +17 -0
  363. kafka/serializer/wrapper.py +21 -0
  364. kafka/structs.py +69 -0
  365. kafka/util.py +159 -0
  366. kafka/vendor/__init__.py +0 -0
  367. kafka/version.py +1 -0
  368. kafka_python-3.0.0.dist-info/METADATA +319 -0
  369. kafka_python-3.0.0.dist-info/RECORD +373 -0
  370. kafka_python-3.0.0.dist-info/WHEEL +5 -0
  371. kafka_python-3.0.0.dist-info/entry_points.txt +2 -0
  372. kafka_python-3.0.0.dist-info/licenses/LICENSE +202 -0
  373. kafka_python-3.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,359 @@
1
+ """Cluster metadata mixin for KafkaAdminClient."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections import defaultdict
6
+ from enum import IntEnum
7
+ import logging
8
+ from typing import TYPE_CHECKING
9
+ import uuid
10
+
11
+ import kafka.errors as Errors
12
+ from kafka.protocol.api_key import ApiKey
13
+ from kafka.protocol.metadata import ApiVersionsRequest, MetadataRequest
14
+ from kafka.protocol.admin import (
15
+ AlterReplicaLogDirsRequest,
16
+ DescribeClusterRequest,
17
+ DescribeLogDirsRequest,
18
+ DescribeQuorumRequest,
19
+ UpdateFeaturesRequest,
20
+ )
21
+ from kafka.structs import TopicPartitionReplica
22
+ from kafka.util import EnumHelper
23
+
24
+ if TYPE_CHECKING:
25
+ from kafka.net.manager import KafkaConnectionManager
26
+
27
+ log = logging.getLogger(__name__)
28
+
29
+
30
+ class ClusterAdminMixin:
31
+ """Mixin providing cluster management methods for KafkaAdminClient."""
32
+ _manager: KafkaConnectionManager
33
+
34
+ async def _get_cluster_metadata(self, topics):
35
+ """topics = [] for no topics, None for all. Items may be topic-name
36
+ strings or :class:`uuid.UUID` topic ids (KIP-516, requires broker
37
+ >= 2.8 / MetadataRequest v12+)."""
38
+ _Topic = MetadataRequest.MetadataRequestTopic
39
+ if topics is None:
40
+ request_topics = None
41
+ else:
42
+ request_topics = [
43
+ _Topic(name=None, topic_id=t) if isinstance(t, uuid.UUID)
44
+ else _Topic(name=t)
45
+ for t in topics
46
+ ]
47
+ request = MetadataRequest(
48
+ topics=request_topics,
49
+ allow_auto_topic_creation=False,
50
+ include_cluster_authorized_operations=True,
51
+ include_topic_authorized_operations=True,
52
+ )
53
+ response = await self._manager.send(request)
54
+ metadata = response.to_dict()
55
+ self._process_acl_operations(metadata)
56
+ for topic in metadata['topics']:
57
+ self._process_acl_operations(topic)
58
+ return metadata
59
+
60
+ async def _describe_cluster(self):
61
+ try:
62
+ request = DescribeClusterRequest(
63
+ include_cluster_authorized_operations=True,
64
+ include_fenced_brokers=True,
65
+ )
66
+ response = await self._manager.send(request)
67
+ error_type = Errors.for_code(response.error_code)
68
+ if error_type is not Errors.NoError:
69
+ raise error_type(response.error_message)
70
+ metadata = response.to_dict()
71
+ metadata.pop('error_code')
72
+ metadata.pop('error_message')
73
+ metadata.pop('endpoint_type')
74
+ metadata.pop('throttle_time_ms', None)
75
+ self._process_acl_operations(metadata)
76
+ return metadata
77
+
78
+ except Errors.IncompatibleBrokerVersion:
79
+ # On older brokers fallback to MetadataRequest w/o topics
80
+ metadata = await self._get_cluster_metadata([])
81
+ metadata.pop('topics')
82
+ metadata.pop('throttle_time_ms', None)
83
+ for broker in metadata['brokers']:
84
+ broker['broker_id'] = broker.pop('node_id')
85
+ return metadata
86
+
87
+ def describe_cluster(self):
88
+ """Fetch cluster-wide metadata such as the list of brokers, the controller ID,
89
+ and the cluster ID.
90
+
91
+ Returns:
92
+ A dict with cluster-wide metadata, excluding topic details.
93
+ """
94
+ return self._manager.run(self._describe_cluster)
95
+
96
+ async def _async_describe_log_dirs(self, topic_partitions=(), brokers=None):
97
+ request = DescribeLogDirsRequest(topics=topic_partitions)
98
+ responses = []
99
+ if brokers is None:
100
+ brokers = [broker.node_id for broker in self._manager.cluster.brokers()]
101
+ for node_id in brokers:
102
+ response = await self._manager.send(request, node_id=node_id)
103
+ responses.append({"broker": node_id, "log_dirs": [result.to_dict() for result in response.results]})
104
+ return responses
105
+
106
+ def describe_log_dirs(self, topic_partitions=None, brokers=None):
107
+ """Fetch broker log directory and topic/partition stats
108
+
109
+ Keyword Arguments:
110
+ topic_partitions (dict, list, optional):
111
+ Either: dict of {topic_name: [partition ids]}.
112
+ Or: list of [topic_name], to query all partitions for topic.
113
+ Or: None, to query all topics / all partitions.
114
+ Default: None
115
+ brokers (list, optional): List of [node_id] for brokers to query.
116
+ If None, query is sent to all brokers. Default: None
117
+
118
+ Returns:
119
+ list of dicts, containing per-broker log-dir data
120
+ """
121
+ topic_partitions = self._get_topic_partitions(topic_partitions)
122
+ return self._manager.run(self._async_describe_log_dirs, topic_partitions, brokers)
123
+
124
+ @staticmethod
125
+ def _alter_replica_log_dirs_requests(replica_assignments):
126
+ _Dir = AlterReplicaLogDirsRequest.AlterReplicaLogDir
127
+ _Topic = _Dir.AlterReplicaLogDirTopic
128
+ broker_to_dirs = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
129
+ for tpr, log_dir in replica_assignments.items():
130
+ if not isinstance(tpr, TopicPartitionReplica):
131
+ tpr = TopicPartitionReplica(*tpr)
132
+ broker_to_dirs[tpr.broker_id][log_dir][tpr.topic].append(tpr.partition)
133
+ return {
134
+ broker_id: AlterReplicaLogDirsRequest(dirs=[
135
+ _Dir(path=path, topics=[
136
+ _Topic(name=topic, partitions=parts)
137
+ for topic, parts in topics.items()
138
+ ])
139
+ for path, topics in dirs.items()
140
+ ])
141
+ for broker_id, dirs in broker_to_dirs.items()
142
+ }
143
+
144
+ async def _async_alter_replica_log_dirs(self, replica_assignments):
145
+ if not replica_assignments:
146
+ return {}
147
+ broker_requests = self._alter_replica_log_dirs_requests(replica_assignments)
148
+ result = {}
149
+ for broker_id, request in broker_requests.items():
150
+ response = await self._manager.send(request, node_id=broker_id)
151
+ for topic in response.results:
152
+ for partition in topic.partitions:
153
+ tpr = TopicPartitionReplica(
154
+ topic=topic.topic_name,
155
+ partition=partition.partition_index,
156
+ broker_id=broker_id)
157
+ result[tpr] = Errors.for_code(partition.error_code)
158
+ return result
159
+
160
+ def alter_replica_log_dirs(self, replica_assignments):
161
+ """Move replicas between log directories on their hosting brokers.
162
+
163
+ Each entry instructs the targeted broker to move (or place) the
164
+ replica for a given partition into the specified absolute log
165
+ directory path. Requests are sent to each broker in parallel; a
166
+ broker will only act on replicas it currently hosts.
167
+
168
+ Arguments:
169
+ replica_assignments: A dict mapping
170
+ :class:`~kafka.TopicPartitionReplica` (``topic``,
171
+ ``partition``, ``broker_id``) to the destination log
172
+ directory path (absolute string). Tuples of
173
+ ``(topic, partition, broker_id)`` are also accepted.
174
+
175
+ Returns:
176
+ dict mapping :class:`~kafka.TopicPartitionReplica` to the
177
+ corresponding error class (``kafka.errors.NoError`` on success).
178
+ """
179
+ return self._manager.run(self._async_alter_replica_log_dirs, replica_assignments)
180
+
181
+ async def _async_describe_quorum(self, topic, partition):
182
+ _Topic = DescribeQuorumRequest.TopicData
183
+ _Partition = _Topic.PartitionData
184
+ request = DescribeQuorumRequest(topics=[
185
+ _Topic(topic_name=topic, partitions=[_Partition(partition_index=partition)])
186
+ ])
187
+ response = await self._manager.send(request)
188
+ top_error = Errors.for_code(response.error_code)
189
+ if top_error is not Errors.NoError:
190
+ raise top_error(response.error_message or '')
191
+ result = response.to_dict()
192
+ result.pop('throttle_time_ms', None)
193
+ result.pop('error_code', None)
194
+ result.pop('error_message', None)
195
+ for topic in result['topics']:
196
+ for partition in topic['partitions']:
197
+ error = Errors.for_code(partition.pop('error_code'))(partition.pop('error_message'))
198
+ if not isinstance(error, Errors.NoError):
199
+ partition['error'] = str(error)
200
+ else:
201
+ partition['error'] = None
202
+ return result
203
+
204
+ def describe_metadata_quorum(self):
205
+ """Describe the KRaft quorum state for the cluster metadata log.
206
+
207
+ Returns quorum info for the ``__cluster_metadata`` topic
208
+ (partition 0), including the current leader, leader epoch, high
209
+ watermark, voters, and observers. On broker version >= 3.8 (KIP-853),
210
+ the response also reports controller node endpoints in ``nodes``.
211
+ Requires a KRaft cluster.
212
+
213
+ Returns:
214
+ dict matching the DescribeQuorumResponse shape.
215
+ """
216
+ return self._manager.run(self._async_describe_quorum, '__cluster_metadata', 0)
217
+
218
+ async def _async_get_broker_version_data(self, broker_id):
219
+ conn = await self._manager.get_connection(broker_id)
220
+ return conn.broker_version_data
221
+
222
+ def get_broker_version_data(self, broker_id):
223
+ """Return BrokerVersionData for a specific broker"""
224
+ return self._manager.run(self._async_get_broker_version_data, broker_id)
225
+
226
+ def api_versions(self):
227
+ api_versions = self._manager.broker_version_data.api_versions
228
+ return {ApiKey(k): v for k, v in api_versions.items()}
229
+
230
+ async def _async_describe_features(self, send_request_to_controller=False):
231
+ request = ApiVersionsRequest(
232
+ client_software_name=self._manager.config['client_software_name'],
233
+ client_software_version=self._manager.config['client_software_version'],
234
+ min_version=3,
235
+ )
236
+ if send_request_to_controller:
237
+ response = await self._send_request_to_controller(request)
238
+ else:
239
+ response = await self._manager.send(request)
240
+ error_type = Errors.for_code(response.error_code)
241
+ if error_type is not Errors.NoError:
242
+ raise error_type(f"ApiVersionsRequest failed: {response}")
243
+ result = defaultdict(dict)
244
+ epoch = response.finalized_features_epoch
245
+ if epoch is None or epoch < 0:
246
+ epoch = None
247
+ for feature in (response.supported_features or []):
248
+ result[feature.name]['supported'] = (feature.min_version, feature.max_version)
249
+ for feature in (response.finalized_features or []):
250
+ result[feature.name]['finalized'] = (feature.min_version_level, feature.max_version_level)
251
+ result[feature.name]['finalized_epoch'] = epoch
252
+ return dict(result)
253
+
254
+ def describe_features(self, send_request_to_controller=False):
255
+ """Fetch the cluster's supported and finalized feature flags.
256
+
257
+ Features are broker-level capabilities (e.g. ``metadata.version``)
258
+ that can be finalized cluster-wide via ``update_features`` (KIP-584).
259
+ Requires broker >= 2.4.
260
+
261
+ Keyword Arguments:
262
+ send_request_to_controller (bool, optional): If True, route the
263
+ request to the active controller. By default the request is
264
+ sent to any available broker. Default: False.
265
+
266
+ Returns:
267
+ dict with keys:
268
+ - ``supported_features``: dict of
269
+ ``{feature_name: (min_version, max_version)}``
270
+ - ``finalized_features``: dict of
271
+ ``{feature_name: (min_version_level, max_version_level)}``
272
+ - ``finalized_features_epoch``: int, or None if unknown
273
+ (broker did not report an epoch, or reported -1)
274
+ """
275
+ return self._manager.run(self._async_describe_features, send_request_to_controller)
276
+
277
+ @staticmethod
278
+ def _build_feature_updates(feature_updates):
279
+ if not isinstance(feature_updates, dict):
280
+ raise TypeError('feature_updates must be a dict of '
281
+ '{feature_name: (max_version_level, upgrade_type)} '
282
+ 'or {feature_name: max_version_level}')
283
+ _FeatureUpdateKey = UpdateFeaturesRequest.FeatureUpdateKey
284
+ updates = []
285
+ for feature, spec in feature_updates.items():
286
+ if isinstance(spec, tuple):
287
+ upgrade_type, max_version_level = spec
288
+ else:
289
+ upgrade_type = UpdateFeatureType.UPGRADE
290
+ max_version_level = spec
291
+ upgrade_code = UpdateFeatureType.value_for(upgrade_type)
292
+ downgrade = upgrade_code in (
293
+ UpdateFeatureType.SAFE_DOWNGRADE.value,
294
+ UpdateFeatureType.UNSAFE_DOWNGRADE.value)
295
+ updates.append(_FeatureUpdateKey(
296
+ feature=feature,
297
+ max_version_level=int(max_version_level),
298
+ allow_downgrade=downgrade,
299
+ upgrade_type=upgrade_code))
300
+ return updates
301
+
302
+ async def _async_update_features(self, feature_updates, validate_only=False, timeout_ms=60000):
303
+ min_version = 1 if validate_only else 0
304
+ request = UpdateFeaturesRequest(
305
+ timeout_ms=timeout_ms,
306
+ feature_updates=self._build_feature_updates(feature_updates),
307
+ validate_only=validate_only,
308
+ min_version=min_version,
309
+ )
310
+ response = await self._send_request_to_controller(
311
+ request,
312
+ get_errors_fn=lambda r: [Errors.for_code(r.error_code)],
313
+ )
314
+ ret = {}
315
+ for result in response.results or []:
316
+ if result.error_code == 0:
317
+ ret[result.feature] = 'OK'
318
+ else:
319
+ ret[result.feature] = str(Errors.for_code(result.error_code)(result.error_message))
320
+ # v2+ responses omit per-feature results; top-level error is already
321
+ # raised by _send_request_to_controller, so any feature we asked about
322
+ # succeeded.
323
+ for feature in feature_updates:
324
+ ret.setdefault(feature, 'OK')
325
+ return ret
326
+
327
+ def update_features(self, feature_updates, validate_only=False, timeout_ms=60000):
328
+ """Update cluster-wide finalized feature flags.
329
+
330
+ Finalize cluster-wide feature capabilities (e.g. ``metadata.version``).
331
+ The request is always routed to the active controller. See KIP-584.
332
+ Requires broker >= 2.7.
333
+
334
+ Arguments:
335
+ feature_updates: A dict of
336
+ ``{feature_name: (upgrade_type, max_version_level)}`` or
337
+ ``{feature_name: max_version_level}`` (implicit UPGRADE).
338
+ ``upgrade_type`` may be a :class:`UpdateFeatureType`,
339
+ its name, or int value. A ``max_version_level < 1`` requests
340
+ deletion of the finalized feature.
341
+
342
+ Keyword Arguments:
343
+ validate_only (bool, optional): If True, validate the request but
344
+ do not apply it. Default: False.
345
+ timeout_ms (int, optional): Broker-side timeout in milliseconds.
346
+ Default: 60000.
347
+
348
+ Returns:
349
+ dict of {feature_name: 'OK' | error message}
350
+ """
351
+ return self._manager.run(self._async_update_features,
352
+ feature_updates, validate_only, timeout_ms)
353
+
354
+
355
+ class UpdateFeatureType(EnumHelper, IntEnum):
356
+ UNKNOWN = 0
357
+ UPGRADE = 1
358
+ SAFE_DOWNGRADE = 2
359
+ UNSAFE_DOWNGRADE = 3