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,201 @@
1
+ #!/usr/bin/env python3
2
+ """Benchmarks for the producer encode hot path.
3
+
4
+ Measures the cost of finalizing a record batch and encoding it into a
5
+ ProduceRequest - the pipeline that runs on every send to the broker.
6
+
7
+ To compare two implementations (e.g. before/after a change) run this
8
+ script twice and diff the output:
9
+
10
+ # baseline
11
+ git stash
12
+ python -m kafka.benchmarks.producer_encode_path -o baseline.json
13
+ git stash pop
14
+
15
+ # new
16
+ python -m kafka.benchmarks.producer_encode_path -o new.json
17
+
18
+ pyperf compare_to baseline.json new.json
19
+
20
+ For an allocation count (tracemalloc) run with --allocations, which is
21
+ a separate mode (not a timing benchmark).
22
+ """
23
+ import argparse
24
+ import sys
25
+ import tracemalloc
26
+
27
+ import pyperf
28
+
29
+ from kafka.producer.producer_batch import ProducerBatch
30
+ from kafka.record.memory_records import MemoryRecordsBuilder
31
+ from kafka.structs import TopicPartition
32
+ from kafka.protocol.producer import ProduceRequest
33
+
34
+
35
+ DEFAULT_RECORDS_PER_BATCH = 100
36
+ DEFAULT_VALUE_SIZE = 128
37
+ DEFAULT_BATCH_SIZE = 1 << 20 # 1 MiB - big enough to hold the largest case
38
+
39
+
40
+ def _build_unclosed_batch(num_records, value_size):
41
+ tp = TopicPartition('bench', 0)
42
+ records = MemoryRecordsBuilder(
43
+ magic=2, compression_type=0, batch_size=DEFAULT_BATCH_SIZE)
44
+ batch = ProducerBatch(tp, records)
45
+ value = b'x' * value_size
46
+ for i in range(num_records):
47
+ future = batch.try_append(i, None, value, [])
48
+ assert future is not None, 'batch too small for %d records' % num_records
49
+ return batch
50
+
51
+
52
+ def _build_closed_batch(num_records, value_size):
53
+ batch = _build_unclosed_batch(num_records, value_size)
54
+ batch.records.close()
55
+ return batch
56
+
57
+
58
+ def bench_build_and_close(loops, num_records, value_size):
59
+ """Time build + close - isolates the batch-finalization path.
60
+
61
+ close() is fast enough that pyperf would need many thousands of loops
62
+ to measure it directly, so we include the build cost and rely on the
63
+ per-run diff to expose the close() delta.
64
+ """
65
+ value = b'x' * value_size
66
+ tp = TopicPartition('bench', 0)
67
+
68
+ t0 = pyperf.perf_counter()
69
+ for _ in range(loops):
70
+ records = MemoryRecordsBuilder(
71
+ magic=2, compression_type=0, batch_size=DEFAULT_BATCH_SIZE)
72
+ batch = ProducerBatch(tp, records)
73
+ for i in range(num_records):
74
+ batch.try_append(i, None, value, [])
75
+ batch.records.close()
76
+ return pyperf.perf_counter() - t0
77
+
78
+
79
+ def bench_encode(loops, num_records, value_size):
80
+ """Time ProduceRequest.encode() with a pre-closed batch.
81
+
82
+ Isolates the protocol encoding cost from batch finalization.
83
+ """
84
+ batch = _build_closed_batch(num_records, value_size)
85
+ buf = batch.records.buffer()
86
+ topic_data = [('bench', [(0, buf)])]
87
+
88
+ t0 = pyperf.perf_counter()
89
+ for _ in range(loops):
90
+ req = ProduceRequest[8](
91
+ transactional_id=None,
92
+ acks=1,
93
+ timeout_ms=30000,
94
+ topic_data=topic_data,
95
+ )
96
+ req.with_header(correlation_id=1, client_id='bench')
97
+ req.encode(framed=True, header=True)
98
+ return pyperf.perf_counter() - t0
99
+
100
+
101
+ def bench_full_pipeline(loops, num_records, value_size):
102
+ """Time the full producer hot path: append -> close -> encode.
103
+
104
+ Mirrors what the Sender thread does for each drained batch.
105
+ """
106
+ value = b'x' * value_size
107
+ tp = TopicPartition('bench', 0)
108
+
109
+ t0 = pyperf.perf_counter()
110
+ for _ in range(loops):
111
+ records = MemoryRecordsBuilder(
112
+ magic=2, compression_type=0, batch_size=DEFAULT_BATCH_SIZE)
113
+ batch = ProducerBatch(tp, records)
114
+ for i in range(num_records):
115
+ batch.try_append(i, None, value, [])
116
+ batch.records.close()
117
+ req = ProduceRequest[8](
118
+ transactional_id=None,
119
+ acks=1,
120
+ timeout_ms=30000,
121
+ topic_data=[('bench', [(0, batch.records.buffer())])],
122
+ )
123
+ req.with_header(correlation_id=1, client_id='bench')
124
+ req.encode(framed=True, header=True)
125
+ return pyperf.perf_counter() - t0
126
+
127
+
128
+ def report_allocations(num_records, value_size):
129
+ """Use tracemalloc to count bytes allocated during a single encode."""
130
+ # Pre-build so we only measure the encode path.
131
+ batch = _build_closed_batch(num_records, value_size)
132
+ buf = batch.records.buffer()
133
+ topic_data = [('bench', [(0, buf)])]
134
+ req = ProduceRequest[8](
135
+ transactional_id=None,
136
+ acks=1,
137
+ timeout_ms=30000,
138
+ topic_data=topic_data,
139
+ )
140
+ req.with_header(correlation_id=1, client_id='bench')
141
+
142
+ # Warmup - populate the compiled-encoder cache so we don't count its
143
+ # one-time allocations.
144
+ req.encode(framed=True, header=True)
145
+
146
+ tracemalloc.start()
147
+ snap_before = tracemalloc.take_snapshot()
148
+ data = req.encode(framed=True, header=True)
149
+ snap_after = tracemalloc.take_snapshot()
150
+ tracemalloc.stop()
151
+
152
+ stats = snap_after.compare_to(snap_before, 'lineno')
153
+ total_bytes = sum(max(0, s.size_diff) for s in stats)
154
+ total_allocs = sum(max(0, s.count_diff) for s in stats)
155
+
156
+ print('Config : %d records x %d bytes' % (num_records, value_size))
157
+ print('Wire bytes : %d' % len(data))
158
+ print('Allocated : %d bytes across %d allocations' % (total_bytes, total_allocs))
159
+ print()
160
+ print('Top allocation sites:')
161
+ for s in sorted(stats, key=lambda s: s.size_diff, reverse=True)[:10]:
162
+ if s.size_diff <= 0:
163
+ continue
164
+ frame = s.traceback[0]
165
+ loc = '%s:%d' % (frame.filename.split('/workspace/')[-1], frame.lineno)
166
+ print(' %8d bytes / %3d allocs %s' % (s.size_diff, s.count_diff, loc))
167
+
168
+
169
+ def main():
170
+ p = argparse.ArgumentParser(description=__doc__,
171
+ formatter_class=argparse.RawDescriptionHelpFormatter)
172
+ p.add_argument('--records', type=int, default=DEFAULT_RECORDS_PER_BATCH,
173
+ help='records per batch (default: %(default)d)')
174
+ p.add_argument('--value-size', type=int, default=DEFAULT_VALUE_SIZE,
175
+ help='record value size in bytes (default: %(default)d)')
176
+ p.add_argument('--allocations', action='store_true',
177
+ help='report tracemalloc allocations for one encode (not a timing run)')
178
+
179
+ # Let pyperf parse its own arguments (--output, --rigorous, etc).
180
+ args, pyperf_args = p.parse_known_args()
181
+
182
+ if args.allocations:
183
+ report_allocations(args.records, args.value_size)
184
+ return
185
+
186
+ # Rebuild sys.argv so pyperf sees only its own arguments.
187
+ sys.argv = [sys.argv[0]] + pyperf_args
188
+
189
+ runner = pyperf.Runner()
190
+ runner.metadata['records_per_batch'] = args.records
191
+ runner.metadata['value_size_bytes'] = args.value_size
192
+ runner.bench_time_func(
193
+ 'build_and_close', bench_build_and_close, args.records, args.value_size)
194
+ runner.bench_time_func(
195
+ 'encode', bench_encode, args.records, args.value_size)
196
+ runner.bench_time_func(
197
+ 'full_pipeline', bench_full_pipeline, args.records, args.value_size)
198
+
199
+
200
+ if __name__ == '__main__':
201
+ main()
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env python
2
+ # Adapted from https://github.com/mrafayaleem/kafka-jython
3
+
4
+ import argparse
5
+ import pprint
6
+ import sys
7
+ import threading
8
+ import time
9
+ import traceback
10
+
11
+ from kafka import KafkaProducer
12
+
13
+
14
+ class ProducerPerformance:
15
+ @staticmethod
16
+ def run(args):
17
+ try:
18
+ props = {}
19
+ for prop in args.producer_config:
20
+ k, v = prop.split('=')
21
+ try:
22
+ v = int(v)
23
+ except ValueError:
24
+ pass
25
+ if v == 'None':
26
+ v = None
27
+ elif v == 'False':
28
+ v = False
29
+ elif v == 'True':
30
+ v = True
31
+ props[k] = v
32
+
33
+ print('Initializing producer...')
34
+ props['bootstrap_servers'] = args.bootstrap_servers
35
+ record = bytes(bytearray(args.record_size))
36
+ props['metrics_sample_window_ms'] = args.stats_interval * 1000
37
+
38
+ producer = KafkaProducer(**props)
39
+ for k, v in props.items():
40
+ print('---> {0}={1}'.format(k, v))
41
+ print('---> topic={0}'.format(args.topic))
42
+ print('---> send {0} byte records'.format(args.record_size))
43
+ print('---> report stats every {0} secs'.format(args.stats_interval))
44
+ print('---> raw metrics? {0}'.format(args.raw_metrics))
45
+ timer_stop = threading.Event()
46
+ timer = StatsReporter(args.stats_interval, producer,
47
+ event=timer_stop,
48
+ raw_metrics=args.raw_metrics)
49
+ timer.start()
50
+ print('-> OK!')
51
+ print()
52
+
53
+ def _benchmark():
54
+ # Hoist attribute lookups and use positional args to minimize
55
+ # per-iteration harness overhead. With a well-optimized
56
+ # producer.send(), kwargs dict packing and repeated attribute
57
+ # dereference on `args`/`producer` dominate main-thread CPU
58
+ # inside this loop and mask the library's true throughput.
59
+ results = []
60
+ send = producer.send
61
+ append = results.append
62
+ topic = args.topic
63
+ num_records = args.num_records
64
+ for _ in range(num_records):
65
+ append(send(topic, record))
66
+ print("Send complete...")
67
+ producer.flush()
68
+ producer.close()
69
+ count_success, count_failure = 0, 0
70
+ for r in results:
71
+ if r.succeeded():
72
+ count_success += 1
73
+ elif r.failed():
74
+ count_failure += 1
75
+ else:
76
+ raise ValueError(r)
77
+ print("%d suceeded, %d failed" % (count_success, count_failure))
78
+
79
+ start_time = time.monotonic()
80
+ _benchmark()
81
+ end_time = time.monotonic()
82
+ timer_stop.set()
83
+ timer.join()
84
+ print('Execution time:', end_time - start_time, 'secs')
85
+
86
+ except Exception:
87
+ exc_info = sys.exc_info()
88
+ traceback.print_exception(*exc_info)
89
+ sys.exit(1)
90
+
91
+
92
+ class StatsReporter(threading.Thread):
93
+ def __init__(self, interval, producer, event=None, raw_metrics=False):
94
+ super().__init__()
95
+ self.interval = interval
96
+ self.producer = producer
97
+ self.event = event
98
+ self.raw_metrics = raw_metrics
99
+
100
+ def print_stats(self):
101
+ metrics = self.producer.metrics()
102
+ if not metrics:
103
+ return
104
+ if self.raw_metrics:
105
+ pprint.pprint(metrics)
106
+ else:
107
+ print('{record-send-rate:.0f} records/sec ({byte-rate:.0f} B/sec),'
108
+ ' {request-rate:.0f} avg requests/sec,'
109
+ ' {request-latency-avg:.0f}ms avg latency,'
110
+ ' {throttle-time-max:.0f}ms max throttle,'
111
+ ' {record-size-avg:.0f} avg record size,'
112
+ ' {batch-size-avg:.0f} avg batch size,'
113
+ ' {records-per-request-avg:.0f} avg records/req'
114
+ .format(**metrics['producer-metrics']))
115
+
116
+ def print_final(self):
117
+ self.print_stats()
118
+
119
+ def run(self):
120
+ while self.event and not self.event.wait(self.interval):
121
+ self.print_stats()
122
+ else:
123
+ self.print_final()
124
+
125
+
126
+ def get_args_parser():
127
+ parser = argparse.ArgumentParser(
128
+ description='This tool is used to verify the producer performance.')
129
+
130
+ parser.add_argument(
131
+ '-b', '--bootstrap-servers', type=str, nargs='+', default=(),
132
+ help='host:port for cluster bootstrap server')
133
+ parser.add_argument(
134
+ '-t', '--topic', type=str,
135
+ help='Topic name for test (default: kafka-python-benchmark-test)',
136
+ default='kafka-python-benchmark-test')
137
+ parser.add_argument(
138
+ '--num-records', type=int,
139
+ help='number of messages to produce (default: 1000000)',
140
+ default=1000000)
141
+ parser.add_argument(
142
+ '--record-size', type=int,
143
+ help='message size in bytes (default: 100)',
144
+ default=100)
145
+ parser.add_argument(
146
+ '-c', '--producer-config', type=str, nargs='+', default=(),
147
+ help='kafka producer related configuaration properties like '
148
+ 'bootstrap_servers,client_id etc..')
149
+ parser.add_argument(
150
+ '--stats-interval', type=int,
151
+ help='Interval in seconds for stats reporting to console (default: 5)',
152
+ default=5)
153
+ parser.add_argument(
154
+ '--raw-metrics', action='store_true',
155
+ help='Enable this flag to print full metrics dict on each interval')
156
+ return parser
157
+
158
+
159
+ if __name__ == '__main__':
160
+ args = get_args_parser().parse_args()
161
+ ProducerPerformance.run(args)
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env python3
2
+ """Per-function and per-line profiling of new protocol encode/decode hot methods.
3
+
4
+ Uses cProfile for call-level breakdown and a targeted manual timer
5
+ for line-level insight into the key hot methods.
6
+
7
+ Usage:
8
+ python kafka/benchmarks/profile_protocol.py [encode|decode|create] [N]
9
+
10
+ encode - profile encode path (default)
11
+ decode - profile decode path
12
+ create - profile object creation path
13
+ N - number of iterations (default: 1000)
14
+ """
15
+
16
+ import cProfile
17
+ import io
18
+ import pstats
19
+ import sys
20
+ import time
21
+
22
+ from kafka.protocol.metadata.metadata import MetadataResponse as NewMetadataResp
23
+ from kafka.protocol.consumer.fetch import FetchResponse as NewFetchResp
24
+
25
+ # === Test data (same as benchmark script) ===
26
+ _BROKERS = [(i, 'broker-%d.example.com' % i, 9092 + i) for i in range(3)]
27
+ _PARTITIONS = [(0, p, p % 3, [0, 1, 2], [0, 1]) for p in range(3)]
28
+ _TOPICS = [(0, 'test-topic-%d' % t, _PARTITIONS) for t in range(5)]
29
+
30
+ _RECORDS_BYTES = b'\x00' * 1024
31
+ _FETCH_TOPICS = [
32
+ ('test-topic-%d' % t, [
33
+ (p, 0, 1000 + p, 999 + p, None, _RECORDS_BYTES)
34
+ for p in range(3)
35
+ ])
36
+ for t in range(2)
37
+ ]
38
+
39
+
40
+ def profile_encode(n):
41
+ """Profile the encode path for MetadataResponse and FetchResponse."""
42
+ obj_meta = NewMetadataResp(version=0, brokers=_BROKERS, topics=_TOPICS)
43
+ obj_fetch = NewFetchResp(version=4, throttle_time_ms=0, responses=_FETCH_TOPICS)
44
+
45
+ # Warmup
46
+ obj_meta.encode(version=0)
47
+ obj_fetch.encode(version=4)
48
+
49
+ pr = cProfile.Profile()
50
+ pr.enable()
51
+ for _ in range(n):
52
+ obj_meta.encode(version=0)
53
+ obj_fetch.encode(version=4)
54
+ pr.disable()
55
+
56
+ print("=" * 80)
57
+ print("ENCODE PROFILE (%d iterations: MetadataResponse v0 + FetchResponse v4)" % n)
58
+ print("=" * 80)
59
+ stats = pstats.Stats(pr)
60
+ stats.sort_stats('cumulative')
61
+ stats.print_stats(40)
62
+ print()
63
+ stats.sort_stats('tottime')
64
+ stats.print_stats(40)
65
+
66
+
67
+ def profile_decode(n):
68
+ """Profile the decode path for MetadataResponse and FetchResponse."""
69
+ obj_meta = NewMetadataResp(version=0, brokers=_BROKERS, topics=_TOPICS)
70
+ obj_fetch = NewFetchResp(version=4, throttle_time_ms=0, responses=_FETCH_TOPICS)
71
+ encoded_meta = obj_meta.encode(version=0)
72
+ encoded_fetch = obj_fetch.encode(version=4)
73
+
74
+ # Warmup
75
+ NewMetadataResp.decode(io.BytesIO(encoded_meta), version=0)
76
+ NewFetchResp.decode(io.BytesIO(encoded_fetch), version=4)
77
+
78
+ pr = cProfile.Profile()
79
+ pr.enable()
80
+ for _ in range(n):
81
+ NewMetadataResp.decode(io.BytesIO(encoded_meta), version=0)
82
+ NewFetchResp.decode(io.BytesIO(encoded_fetch), version=4)
83
+ pr.disable()
84
+
85
+ print("=" * 80)
86
+ print("DECODE PROFILE (%d iterations: MetadataResponse v0 + FetchResponse v4)" % n)
87
+ print("=" * 80)
88
+ stats = pstats.Stats(pr)
89
+ stats.sort_stats('cumulative')
90
+ stats.print_stats(40)
91
+ print()
92
+ stats.sort_stats('tottime')
93
+ stats.print_stats(40)
94
+
95
+
96
+ def profile_create(n):
97
+ """Profile the object creation path."""
98
+ # Warmup
99
+ NewMetadataResp(version=0, brokers=_BROKERS, topics=_TOPICS)
100
+ NewFetchResp(version=4, throttle_time_ms=0, responses=_FETCH_TOPICS)
101
+
102
+ pr = cProfile.Profile()
103
+ pr.enable()
104
+ for _ in range(n):
105
+ NewMetadataResp(version=0, brokers=_BROKERS, topics=_TOPICS)
106
+ NewFetchResp(version=4, throttle_time_ms=0, responses=_FETCH_TOPICS)
107
+ pr.disable()
108
+
109
+ print("=" * 80)
110
+ print("CREATE PROFILE (%d iterations: MetadataResponse v0 + FetchResponse v4)" % n)
111
+ print("=" * 80)
112
+ stats = pstats.Stats(pr)
113
+ stats.sort_stats('cumulative')
114
+ stats.print_stats(40)
115
+ print()
116
+ stats.sort_stats('tottime')
117
+ stats.print_stats(40)
118
+
119
+
120
+ if __name__ == '__main__':
121
+ mode = sys.argv[1] if len(sys.argv) > 1 else 'encode'
122
+ iterations = int(sys.argv[2]) if len(sys.argv) > 2 else 1000
123
+
124
+ if mode == 'encode':
125
+ profile_encode(iterations)
126
+ elif mode == 'decode':
127
+ profile_decode(iterations)
128
+ elif mode == 'create':
129
+ profile_create(iterations)
130
+ elif mode == 'all':
131
+ profile_encode(iterations)
132
+ print("\n\n")
133
+ profile_decode(iterations)
134
+ print("\n\n")
135
+ profile_create(iterations)
136
+ else:
137
+ print("Usage: python profile_protocol.py [encode|decode|create|all] [N]")
138
+ sys.exit(1)