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,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__)
@@ -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)