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,255 @@
1
+ # This class takes advantage of the fact that all formats v0, v1 and v2 of
2
+ # messages storage has the same byte offsets for Length and Magic fields.
3
+ # Lets look closely at what leading bytes all versions have:
4
+ #
5
+ # V0 and V1 (Offset is MessageSet part, other bytes are Message ones):
6
+ # Offset => Int64
7
+ # BytesLength => Int32
8
+ # CRC => Int32
9
+ # Magic => Int8
10
+ # ...
11
+ #
12
+ # V2:
13
+ # BaseOffset => Int64
14
+ # Length => Int32
15
+ # PartitionLeaderEpoch => Int32
16
+ # Magic => Int8
17
+ # ...
18
+ #
19
+ # So we can iterate over batches just by knowing offsets of Length. Magic is
20
+ # used to construct the correct class for Batch itself.
21
+
22
+ import struct
23
+
24
+ from kafka.errors import CorruptRecordError, IllegalStateError, UnsupportedVersionError
25
+ from kafka.record.abc import ABCRecords
26
+ from kafka.record.legacy_records import LegacyRecordBatch, LegacyRecordBatchBuilder
27
+ from kafka.record.default_records import DefaultRecordBatch, DefaultRecordBatchBuilder
28
+
29
+
30
+ class MemoryRecords(ABCRecords):
31
+
32
+ LENGTH_OFFSET = struct.calcsize(">q")
33
+ LOG_OVERHEAD = struct.calcsize(">qi")
34
+ MAGIC_OFFSET = struct.calcsize(">qii")
35
+
36
+ # Minimum space requirements for Record V0
37
+ MIN_SLICE = LOG_OVERHEAD + LegacyRecordBatch.RECORD_OVERHEAD_V0
38
+
39
+ __slots__ = ("_buffer", "_pos", "_next_slice", "_remaining_bytes")
40
+
41
+ def __init__(self, bytes_data):
42
+ self._buffer = bytes_data
43
+ self._pos = 0
44
+ # We keep one slice ahead so `has_next` will return very fast
45
+ self._next_slice = None
46
+ self._remaining_bytes = None
47
+ self._cache_next()
48
+
49
+ def size_in_bytes(self):
50
+ return len(self._buffer)
51
+
52
+ def valid_bytes(self):
53
+ # We need to read the whole buffer to get the valid_bytes.
54
+ # NOTE: in Fetcher we do the call after iteration, so should be fast
55
+ if self._remaining_bytes is None:
56
+ next_slice = self._next_slice
57
+ pos = self._pos
58
+ while self._remaining_bytes is None:
59
+ self._cache_next()
60
+ # Reset previous iterator position
61
+ self._next_slice = next_slice
62
+ self._pos = pos
63
+ return len(self._buffer) - self._remaining_bytes
64
+
65
+ # NOTE: we cache offsets here as kwargs for a bit more speed, as cPython
66
+ # will use LOAD_FAST opcode in this case
67
+ def _cache_next(self, len_offset=LENGTH_OFFSET, log_overhead=LOG_OVERHEAD):
68
+ buffer = self._buffer
69
+ buffer_len = len(buffer)
70
+ pos = self._pos
71
+ remaining = buffer_len - pos
72
+ if remaining < log_overhead:
73
+ # Will be re-checked in Fetcher for remaining bytes.
74
+ self._remaining_bytes = remaining
75
+ self._next_slice = None
76
+ return
77
+
78
+ length, = struct.unpack_from(
79
+ ">i", buffer, pos + len_offset)
80
+
81
+ slice_end = pos + log_overhead + length
82
+ if slice_end > buffer_len:
83
+ # Will be re-checked in Fetcher for remaining bytes
84
+ self._remaining_bytes = remaining
85
+ self._next_slice = None
86
+ return
87
+
88
+ self._next_slice = memoryview(buffer)[pos: slice_end]
89
+ self._pos = slice_end
90
+
91
+ def has_next(self):
92
+ return self._next_slice is not None
93
+
94
+ # NOTE: same cache for LOAD_FAST as above
95
+ def next_batch(self, _min_slice=MIN_SLICE,
96
+ _magic_offset=MAGIC_OFFSET):
97
+ next_slice = self._next_slice
98
+ if next_slice is None:
99
+ return None
100
+ if len(next_slice) < _min_slice:
101
+ raise CorruptRecordError(
102
+ "Record size is less than the minimum record overhead "
103
+ "({})".format(_min_slice - self.LOG_OVERHEAD))
104
+ self._cache_next()
105
+ magic, = struct.unpack_from(">b", next_slice, _magic_offset)
106
+ if magic <= 1:
107
+ return LegacyRecordBatch(next_slice, magic)
108
+ else:
109
+ return DefaultRecordBatch(next_slice)
110
+
111
+ def __iter__(self):
112
+ return self
113
+
114
+ def __next__(self):
115
+ if not self.has_next():
116
+ raise StopIteration
117
+ return self.next_batch()
118
+
119
+ next = __next__
120
+
121
+
122
+ class MemoryRecordsBuilder:
123
+
124
+ __slots__ = ("_builder", "_batch_size", "_buffer", "_next_offset", "_closed",
125
+ "_magic", "_bytes_written", "_producer_id", "_producer_epoch",
126
+ "_base_sequence")
127
+
128
+ def __init__(self, magic, compression_type, batch_size, offset=0,
129
+ transactional=False, producer_id=-1, producer_epoch=-1, base_sequence=-1):
130
+ assert magic in [0, 1, 2], "Not supported magic"
131
+ assert compression_type in [0, 1, 2, 3, 4], "Not valid compression type"
132
+ if magic >= 2:
133
+ assert not transactional or producer_id != -1, "Cannot write transactional messages without a valid producer ID"
134
+ assert producer_id == -1 or producer_epoch != -1, "Invalid negative producer epoch"
135
+ assert producer_id == -1 or base_sequence != -1, "Invalid negative sequence number used"
136
+
137
+ self._builder = DefaultRecordBatchBuilder(
138
+ magic=magic, compression_type=compression_type,
139
+ is_transactional=transactional, producer_id=producer_id,
140
+ producer_epoch=producer_epoch, base_sequence=base_sequence,
141
+ batch_size=batch_size)
142
+ self._producer_id = producer_id
143
+ self._producer_epoch = producer_epoch
144
+ self._base_sequence = base_sequence
145
+ else:
146
+ assert not transactional and producer_id == -1, "Idempotent messages are not supported for magic %s" % (magic,)
147
+ self._builder = LegacyRecordBatchBuilder(
148
+ magic=magic, compression_type=compression_type,
149
+ batch_size=batch_size)
150
+ self._producer_id = None
151
+ self._producer_epoch = None
152
+ self._base_sequence = None
153
+ self._batch_size = batch_size
154
+ self._buffer = None
155
+
156
+ self._next_offset = offset
157
+ self._closed = False
158
+ self._magic = magic
159
+ self._bytes_written = 0
160
+
161
+ def skip(self, offsets_to_skip):
162
+ # Exposed for testing compacted records
163
+ self._next_offset += offsets_to_skip
164
+
165
+ def append(self, timestamp, key, value, headers=None):
166
+ """ Append a message to the buffer.
167
+
168
+ Returns: RecordMetadata or None if unable to append
169
+ """
170
+ if headers is None:
171
+ headers = []
172
+ if self._closed:
173
+ return None
174
+
175
+ offset = self._next_offset
176
+ metadata = self._builder.append(offset, timestamp, key, value, headers)
177
+ # Return of None means there's no space to add a new message
178
+ if metadata is None:
179
+ return None
180
+
181
+ self._next_offset += 1
182
+ return metadata
183
+
184
+ def set_producer_state(self, producer_id, producer_epoch, base_sequence, is_transactional):
185
+ if self._magic < 2:
186
+ raise UnsupportedVersionError('Producer State requires Message format v2+')
187
+ elif self._closed:
188
+ # Sequence numbers are assigned when the batch is closed while the accumulator is being drained.
189
+ # If the resulting ProduceRequest to the partition leader failed for a retriable error, the batch will
190
+ # be re queued. In this case, we should not attempt to set the state again, since changing the pid and sequence
191
+ # once a batch has been sent to the broker risks introducing duplicates.
192
+ raise IllegalStateError("Trying to set producer state of an already closed batch. This indicates a bug on the client.")
193
+ self._builder.set_producer_state(producer_id, producer_epoch, base_sequence, is_transactional)
194
+ self._producer_id = producer_id
195
+ self._producer_epoch = producer_epoch
196
+ self._base_sequence = base_sequence
197
+
198
+ @property
199
+ def producer_id(self):
200
+ return self._producer_id
201
+
202
+ @property
203
+ def producer_epoch(self):
204
+ return self._producer_epoch
205
+
206
+ @property
207
+ def base_sequence(self):
208
+ return self._base_sequence
209
+
210
+ def records(self):
211
+ assert self._closed
212
+ return MemoryRecords(self._buffer)
213
+
214
+ def close(self):
215
+ # This method may be called multiple times on the same batch
216
+ # i.e., on retries
217
+ # we need to make sure we only close it out once
218
+ # otherwise compressed messages may be double-compressed
219
+ # see Issue 718
220
+ if not self._closed:
221
+ self._bytes_written = self._builder.size()
222
+ # Keep the buffer as bytearray to avoid a full-batch copy on
223
+ # close. Downstream consumers (MemoryRecords via memoryview and
224
+ # the protocol encoder via slice-assignment) handle bytearray
225
+ # without further copies.
226
+ self._buffer = self._builder.build()
227
+ if self._magic == 2:
228
+ self._producer_id = self._builder.producer_id
229
+ self._producer_epoch = self._builder.producer_epoch
230
+ self._base_sequence = self._builder.base_sequence
231
+ self._builder = None
232
+ self._closed = True
233
+
234
+ def size_in_bytes(self):
235
+ if not self._closed:
236
+ return self._builder.size()
237
+ else:
238
+ return len(self._buffer)
239
+
240
+ def compression_rate(self):
241
+ assert self._closed
242
+ return self.size_in_bytes() / self._bytes_written
243
+
244
+ def is_full(self):
245
+ if self._closed:
246
+ return True
247
+ else:
248
+ return self._builder.size() >= self._batch_size
249
+
250
+ def next_offset(self):
251
+ return self._next_offset
252
+
253
+ def buffer(self):
254
+ assert self._closed
255
+ return self._buffer
kafka/record/util.py ADDED
@@ -0,0 +1,135 @@
1
+ import binascii
2
+
3
+ from kafka.record._crc32c import crc as crc32c_py
4
+ try:
5
+ from crc32c import crc32c as crc32c_c
6
+ except ImportError:
7
+ crc32c_c = None
8
+
9
+
10
+ def encode_varint(value, write):
11
+ """ Encode an integer to a varint presentation. See
12
+ https://developers.google.com/protocol-buffers/docs/encoding?csw=1#varints
13
+ on how those can be produced.
14
+
15
+ Arguments:
16
+ value (int): Value to encode
17
+ write (function): Called per byte that needs to be writen
18
+
19
+ Returns:
20
+ int: Number of bytes written
21
+ """
22
+ value = (value << 1) ^ (value >> 63)
23
+
24
+ if value <= 0x7f: # 1 byte
25
+ write(value)
26
+ return 1
27
+ if value <= 0x3fff: # 2 bytes
28
+ write(0x80 | (value & 0x7f))
29
+ write(value >> 7)
30
+ return 2
31
+ if value <= 0x1fffff: # 3 bytes
32
+ write(0x80 | (value & 0x7f))
33
+ write(0x80 | ((value >> 7) & 0x7f))
34
+ write(value >> 14)
35
+ return 3
36
+ if value <= 0xfffffff: # 4 bytes
37
+ write(0x80 | (value & 0x7f))
38
+ write(0x80 | ((value >> 7) & 0x7f))
39
+ write(0x80 | ((value >> 14) & 0x7f))
40
+ write(value >> 21)
41
+ return 4
42
+ if value <= 0x7ffffffff: # 5 bytes
43
+ write(0x80 | (value & 0x7f))
44
+ write(0x80 | ((value >> 7) & 0x7f))
45
+ write(0x80 | ((value >> 14) & 0x7f))
46
+ write(0x80 | ((value >> 21) & 0x7f))
47
+ write(value >> 28)
48
+ return 5
49
+ else:
50
+ # Return to general algorithm
51
+ bits = value & 0x7f
52
+ value >>= 7
53
+ i = 0
54
+ while value:
55
+ write(0x80 | bits)
56
+ bits = value & 0x7f
57
+ value >>= 7
58
+ i += 1
59
+ write(bits)
60
+ return i
61
+
62
+
63
+ def size_of_varint(value):
64
+ """ Number of bytes needed to encode an integer in variable-length format.
65
+ """
66
+ value = (value << 1) ^ (value >> 63)
67
+ if value <= 0x7f:
68
+ return 1
69
+ if value <= 0x3fff:
70
+ return 2
71
+ if value <= 0x1fffff:
72
+ return 3
73
+ if value <= 0xfffffff:
74
+ return 4
75
+ if value <= 0x7ffffffff:
76
+ return 5
77
+ if value <= 0x3ffffffffff:
78
+ return 6
79
+ if value <= 0x1ffffffffffff:
80
+ return 7
81
+ if value <= 0xffffffffffffff:
82
+ return 8
83
+ if value <= 0x7fffffffffffffff:
84
+ return 9
85
+ return 10
86
+
87
+
88
+ def decode_varint(buffer, pos=0):
89
+ """ Decode an integer from a varint presentation. See
90
+ https://developers.google.com/protocol-buffers/docs/encoding?csw=1#varints
91
+ on how those can be produced.
92
+
93
+ Arguments:
94
+ buffer (bytearray): buffer to read from.
95
+ pos (int): optional position to read from
96
+
97
+ Returns:
98
+ (int, int): Decoded int value and next read position
99
+ """
100
+ result = buffer[pos]
101
+ if not (result & 0x81):
102
+ return (result >> 1), pos + 1
103
+ if not (result & 0x80):
104
+ return (result >> 1) ^ (~0), pos + 1
105
+
106
+ result &= 0x7f
107
+ pos += 1
108
+ shift = 7
109
+ while 1:
110
+ b = buffer[pos]
111
+ result |= ((b & 0x7f) << shift)
112
+ pos += 1
113
+ if not (b & 0x80):
114
+ return ((result >> 1) ^ -(result & 1), pos)
115
+ shift += 7
116
+ if shift >= 64:
117
+ raise ValueError("Out of int64 range")
118
+
119
+
120
+ _crc32c = crc32c_py
121
+ if crc32c_c is not None:
122
+ _crc32c = crc32c_c
123
+
124
+
125
+ def calc_crc32c(memview, _crc32c=_crc32c):
126
+ """ Calculate CRC-32C (Castagnoli) checksum over a memoryview of data
127
+ """
128
+ return _crc32c(memview)
129
+
130
+
131
+ def calc_crc32(memview):
132
+ """ Calculate simple CRC-32 checksum over a memoryview of data
133
+ """
134
+ crc = binascii.crc32(memview) & 0xffffffff
135
+ return crc
@@ -0,0 +1,4 @@
1
+ from .abstract import Serializer, Deserializer
2
+ from .default import DefaultSerializer
3
+ from .json import JsonSerializer
4
+ from .wrapper import DeserializeWrapper, SerializeWrapper
@@ -0,0 +1,20 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import List, Tuple, Any
3
+
4
+
5
+ class Serializer(ABC):
6
+ @abstractmethod
7
+ def serialize(self, topic: str, headers: List[Tuple[str, bytes]], data: Any):
8
+ pass
9
+
10
+ def close(self):
11
+ pass
12
+
13
+
14
+ class Deserializer(ABC):
15
+ @abstractmethod
16
+ def deserialize(self, topic: str, headers: List[Tuple[str, bytes]], data: bytes):
17
+ pass
18
+
19
+ def close(self):
20
+ pass
@@ -0,0 +1,16 @@
1
+ from .abstract import Serializer, Deserializer
2
+
3
+
4
+ class DefaultSerializer(Serializer, Deserializer):
5
+ def __init__(self, encoding='utf-8'):
6
+ self.encoding = encoding
7
+
8
+ def serialize(self, topic, headers, data):
9
+ if type(data) in (bytes, bytearray, memoryview, type(None)):
10
+ return data
11
+ return data.encode(self.encoding)
12
+
13
+ def deserialize(self, topic, headers, data):
14
+ if data is None:
15
+ return None
16
+ return data.decode(self.encoding)
@@ -0,0 +1,17 @@
1
+ import json
2
+
3
+ from .abstract import Serializer, Deserializer
4
+
5
+
6
+ class JsonSerializer(Serializer, Deserializer):
7
+ def serialize(self, topic, headers, data):
8
+ if data is None:
9
+ return None
10
+ s = json.dumps(data)
11
+ return super().serialize(topic, headers, s)
12
+
13
+ def deserialize(self, topic, headers, data):
14
+ if data is None:
15
+ return None
16
+ s = super().deserialize(topic, headers, data)
17
+ return json.loads(s)
@@ -0,0 +1,21 @@
1
+ from .abstract import Deserializer, Serializer
2
+
3
+
4
+ class DeserializeWrapper(Deserializer):
5
+ def __init__(self, fn):
6
+ self.fn = fn
7
+
8
+ def deserialize(self, topic, headers, data):
9
+ if self.fn is None:
10
+ return data
11
+ return self.fn(data)
12
+
13
+
14
+ class SerializeWrapper(Serializer):
15
+ def __init__(self, fn):
16
+ self.fn = fn
17
+
18
+ def serialize(self, topic, headers, data):
19
+ if self.fn is None:
20
+ return data
21
+ return self.fn(data)
kafka/structs.py ADDED
@@ -0,0 +1,69 @@
1
+ """ Other useful structs """
2
+
3
+ from collections import namedtuple
4
+
5
+
6
+ TopicPartition = namedtuple("TopicPartition",
7
+ ["topic", "partition"])
8
+ TopicPartition.__doc__ = """A topic and partition tuple
9
+
10
+ Keyword Arguments:
11
+ topic (str): A topic name
12
+ partition (int): A partition id
13
+ """
14
+
15
+
16
+ TopicPartitionReplica = namedtuple("TopicPartitionReplica",
17
+ ["topic", "partition", "broker_id"])
18
+ TopicPartitionReplica.__doc__ = """A topic / partition / broker replica tuple
19
+
20
+ Keyword Arguments:
21
+ topic (str): A topic name
22
+ partition (int): A partition id
23
+ broker_id (int): The node_id of the broker hosting the replica
24
+ """
25
+
26
+
27
+ OffsetAndMetadata = namedtuple("OffsetAndMetadata",
28
+ ["offset", "metadata", "leader_epoch"], defaults=[None, '', -1])
29
+ OffsetAndMetadata.__doc__ = """Container for committed group offset data.
30
+
31
+ The Kafka offset commit API allows users to provide additional metadata
32
+ (in the form of a string) when an offset is committed. This can be useful
33
+ (for example) to store information about which node made the commit,
34
+ what time the commit was made, etc.
35
+
36
+ Keyword Arguments:
37
+ offset (int): The offset to be committed
38
+ metadata (str): Non-null metadata
39
+ leader_epoch (int): The last known epoch from the leader / broker
40
+ """
41
+
42
+
43
+ OffsetAndTimestamp = namedtuple("OffsetAndTimestamp",
44
+ ["offset", "timestamp", "leader_epoch"])
45
+ OffsetAndTimestamp.__doc__ = """An offset and timestamp tuple
46
+
47
+ Keyword Arguments:
48
+ offset (int): An offset
49
+ timestamp (int): The timestamp associated to the offset
50
+ leader_epoch (int): The last known epoch from the leader / broker
51
+ """
52
+
53
+
54
+ ConsumerGroupMetadata = namedtuple("ConsumerGroupMetadata",
55
+ ["group_id", "generation_id", "member_id", "group_instance_id"],
56
+ defaults=[-1, '', None])
57
+ ConsumerGroupMetadata.__doc__ = """A snapshot of a consumer's group membership (KIP-447).
58
+
59
+ Passed to KafkaProducer.send_offsets_to_transaction() so the broker can fence
60
+ stale consumer instances when committing offsets inside a transaction. The
61
+ broker uses member_id + generation_id + group_instance_id to verify the
62
+ producer is acting on behalf of the current group generation.
63
+
64
+ Keyword Arguments:
65
+ group_id (str): The consumer group id.
66
+ generation_id (int): The current generation id (-1 if unjoined).
67
+ member_id (str): The current member id ('' if unjoined).
68
+ group_instance_id (str): The static membership instance id, or None.
69
+ """