kafka-python 3.0.0__tar.gz → 3.0.1__tar.gz

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 (409) hide show
  1. {kafka_python-3.0.0 → kafka_python-3.0.1}/CHANGES.md +19 -0
  2. {kafka_python-3.0.0 → kafka_python-3.0.1}/PKG-INFO +1 -1
  3. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/client.py +2 -2
  4. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/consumer/fetcher.py +30 -0
  5. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/consumer/group.py +26 -6
  6. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/base.py +8 -10
  7. kafka_python-3.0.1/kafka/partitioner/abc.py +52 -0
  8. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/future.py +38 -0
  9. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/kafka.py +2 -2
  10. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/structs.py +22 -8
  11. kafka_python-3.0.1/kafka/version.py +1 -0
  12. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka_python.egg-info/PKG-INFO +1 -1
  13. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/conftest.py +122 -0
  14. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/test_admin_integration.py +22 -87
  15. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/test_consumer_integration.py +35 -111
  16. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_mock_broker.py +258 -1
  17. kafka_python-3.0.0/kafka/partitioner/abc.py +0 -8
  18. kafka_python-3.0.0/kafka/version.py +0 -1
  19. {kafka_python-3.0.0 → kafka_python-3.0.1}/AUTHORS.md +0 -0
  20. {kafka_python-3.0.0 → kafka_python-3.0.1}/LICENSE +0 -0
  21. {kafka_python-3.0.0 → kafka_python-3.0.1}/MANIFEST.in +0 -0
  22. {kafka_python-3.0.0 → kafka_python-3.0.1}/README.rst +0 -0
  23. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/__init__.py +0 -0
  24. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/__main__.py +0 -0
  25. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/__init__.py +0 -0
  26. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/__main__.py +0 -0
  27. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_acls.py +0 -0
  28. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_cluster.py +0 -0
  29. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_configs.py +0 -0
  30. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_groups.py +0 -0
  31. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_partitions.py +0 -0
  32. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_topics.py +0 -0
  33. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_transactions.py +0 -0
  34. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/admin/_users.py +0 -0
  35. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/__init__.py +0 -0
  36. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/consumer_performance.py +0 -0
  37. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/load_example.py +0 -0
  38. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/producer_encode_path.py +0 -0
  39. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/producer_performance.py +0 -0
  40. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/profile_protocol.py +0 -0
  41. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/protocol_old_vs_new.py +0 -0
  42. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/record_batch_compose.py +0 -0
  43. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/record_batch_read.py +0 -0
  44. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/benchmarks/varint_speed.py +0 -0
  45. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/__init__.py +0 -0
  46. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/__init__.py +0 -0
  47. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/acls/__init__.py +0 -0
  48. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/acls/common.py +0 -0
  49. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/acls/create.py +0 -0
  50. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/acls/delete.py +0 -0
  51. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/acls/describe.py +0 -0
  52. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/cluster/__init__.py +0 -0
  53. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/cluster/describe.py +0 -0
  54. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/cluster/describe_quorum.py +0 -0
  55. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/cluster/features.py +0 -0
  56. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/cluster/log_dirs.py +0 -0
  57. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/cluster/versions.py +0 -0
  58. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/configs/__init__.py +0 -0
  59. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/configs/alter.py +0 -0
  60. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/configs/common.py +0 -0
  61. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/configs/describe.py +0 -0
  62. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/configs/list.py +0 -0
  63. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/configs/reset.py +0 -0
  64. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/__init__.py +0 -0
  65. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/alter_offsets.py +0 -0
  66. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/delete.py +0 -0
  67. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/delete_offsets.py +0 -0
  68. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/describe.py +0 -0
  69. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/list.py +0 -0
  70. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/list_offsets.py +0 -0
  71. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/remove_members.py +0 -0
  72. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/groups/reset_offsets.py +0 -0
  73. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/__init__.py +0 -0
  74. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/alter_reassignments.py +0 -0
  75. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/create.py +0 -0
  76. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/delete_records.py +0 -0
  77. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/describe.py +0 -0
  78. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/elect_leaders.py +0 -0
  79. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/list_offsets.py +0 -0
  80. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/partitions/list_reassignments.py +0 -0
  81. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/topics/__init__.py +0 -0
  82. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/topics/create.py +0 -0
  83. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/topics/delete.py +0 -0
  84. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/topics/describe.py +0 -0
  85. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/topics/list.py +0 -0
  86. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/transactions/__init__.py +0 -0
  87. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/transactions/abort.py +0 -0
  88. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/transactions/describe.py +0 -0
  89. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/transactions/describe_producers.py +0 -0
  90. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/transactions/find_hanging.py +0 -0
  91. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/transactions/list.py +0 -0
  92. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/users/__init__.py +0 -0
  93. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/users/alter_user_scram_credentials.py +0 -0
  94. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/admin/users/describe_user_scram_credentials.py +0 -0
  95. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/common.py +0 -0
  96. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/consumer/__init__.py +0 -0
  97. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cli/producer/__init__.py +0 -0
  98. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/cluster.py +0 -0
  99. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/codec.py +0 -0
  100. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/consumer/__init__.py +0 -0
  101. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/consumer/__main__.py +0 -0
  102. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/consumer/subscription_state.py +0 -0
  103. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/__init__.py +0 -0
  104. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/__init__.py +0 -0
  105. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/abstract.py +0 -0
  106. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/cooperative_sticky.py +0 -0
  107. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/range.py +0 -0
  108. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/roundrobin.py +0 -0
  109. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +0 -0
  110. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
  111. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
  112. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
  113. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
  114. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/assignors/sticky/user_data.py +0 -0
  115. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/consumer.py +0 -0
  116. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/heartbeat.py +0 -0
  117. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/coordinator/subscription.py +0 -0
  118. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/errors.py +0 -0
  119. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/future.py +0 -0
  120. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/__init__.py +0 -0
  121. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/compound_stat.py +0 -0
  122. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/dict_reporter.py +0 -0
  123. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/kafka_metric.py +0 -0
  124. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/measurable.py +0 -0
  125. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/measurable_stat.py +0 -0
  126. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/metric_config.py +0 -0
  127. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/metric_name.py +0 -0
  128. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/metrics.py +0 -0
  129. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/metrics_reporter.py +0 -0
  130. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/quota.py +0 -0
  131. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stat.py +0 -0
  132. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/__init__.py +0 -0
  133. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/avg.py +0 -0
  134. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/count.py +0 -0
  135. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/histogram.py +0 -0
  136. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/max_stat.py +0 -0
  137. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/min_stat.py +0 -0
  138. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/percentile.py +0 -0
  139. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/percentiles.py +0 -0
  140. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/rate.py +0 -0
  141. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/sampled_stat.py +0 -0
  142. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/sensor.py +0 -0
  143. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/metrics/stats/total.py +0 -0
  144. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/__init__.py +0 -0
  145. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/compat.py +0 -0
  146. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/connection.py +0 -0
  147. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/http_connect.py +0 -0
  148. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/inet.py +0 -0
  149. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/manager.py +0 -0
  150. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/metrics.py +0 -0
  151. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/__init__.py +0 -0
  152. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/abc.py +0 -0
  153. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/gssapi.py +0 -0
  154. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/msk.py +0 -0
  155. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/oauth.py +0 -0
  156. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/plain.py +0 -0
  157. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/scram.py +0 -0
  158. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/sasl/sspi.py +0 -0
  159. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/selector.py +0 -0
  160. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/socks5.py +0 -0
  161. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/transport.py +0 -0
  162. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/net/wakeup_notifier.py +0 -0
  163. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/partitioner/__init__.py +0 -0
  164. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/partitioner/default.py +0 -0
  165. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/partitioner/sticky.py +0 -0
  166. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/__init__.py +0 -0
  167. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/__main__.py +0 -0
  168. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/producer_batch.py +0 -0
  169. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/record_accumulator.py +0 -0
  170. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/sender.py +0 -0
  171. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/producer/transaction_manager.py +0 -0
  172. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/__init__.py +0 -0
  173. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/__init__.py +0 -0
  174. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/acl.py +0 -0
  175. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/acl.pyi +0 -0
  176. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/client_quotas.py +0 -0
  177. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/client_quotas.pyi +0 -0
  178. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/cluster.py +0 -0
  179. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/cluster.pyi +0 -0
  180. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/configs.py +0 -0
  181. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/configs.pyi +0 -0
  182. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/groups.py +0 -0
  183. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/groups.pyi +0 -0
  184. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/topics.py +0 -0
  185. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/topics.pyi +0 -0
  186. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/transactions.py +0 -0
  187. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/transactions.pyi +0 -0
  188. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/users.py +0 -0
  189. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/admin/users.pyi +0 -0
  190. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/api_data.py +0 -0
  191. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/api_header.py +0 -0
  192. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/api_key.py +0 -0
  193. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/api_message.py +0 -0
  194. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/broker_version_data.py +0 -0
  195. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/__init__.py +0 -0
  196. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/fetch.py +0 -0
  197. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/fetch.pyi +0 -0
  198. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/group.py +0 -0
  199. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/group.pyi +0 -0
  200. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/metadata.py +0 -0
  201. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/metadata.pyi +0 -0
  202. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/offsets.py +0 -0
  203. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/consumer/offsets.pyi +0 -0
  204. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/data_container.py +0 -0
  205. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/frame.py +0 -0
  206. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/generate_stubs.py +0 -0
  207. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/__init__.py +0 -0
  208. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/api_versions.py +0 -0
  209. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/api_versions.pyi +0 -0
  210. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/find_coordinator.py +0 -0
  211. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/find_coordinator.pyi +0 -0
  212. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/metadata.py +0 -0
  213. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/metadata/metadata.pyi +0 -0
  214. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/__init__.py +0 -0
  215. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/abstract.py +0 -0
  216. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/add_offsets_to_txn.py +0 -0
  217. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/add_partitions_to_txn.py +0 -0
  218. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/admin.py +0 -0
  219. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/api.py +0 -0
  220. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/api_versions.py +0 -0
  221. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/commit.py +0 -0
  222. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/consumer_protocol.py +0 -0
  223. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/end_txn.py +0 -0
  224. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/fetch.py +0 -0
  225. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/find_coordinator.py +0 -0
  226. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/group.py +0 -0
  227. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/init_producer_id.py +0 -0
  228. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/list_offsets.py +0 -0
  229. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/metadata.py +0 -0
  230. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/offset_for_leader_epoch.py +0 -0
  231. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/produce.py +0 -0
  232. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/sasl_authenticate.py +0 -0
  233. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/sasl_handshake.py +0 -0
  234. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/struct.py +0 -0
  235. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/txn_offset_commit.py +0 -0
  236. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/old/types.py +0 -0
  237. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/parser.py +0 -0
  238. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/producer/__init__.py +0 -0
  239. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/producer/produce.py +0 -0
  240. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/producer/produce.pyi +0 -0
  241. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/producer/transaction.py +0 -0
  242. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/producer/transaction.pyi +0 -0
  243. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/sasl.py +0 -0
  244. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/sasl.pyi +0 -0
  245. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/__init__.py +0 -0
  246. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/__init__.py +0 -0
  247. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/array.py +0 -0
  248. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/base.py +0 -0
  249. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/codecs/__init__.py +0 -0
  250. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/codecs/encode_buffer.py +0 -0
  251. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/codecs/tagged_fields.py +0 -0
  252. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/codecs/types.py +0 -0
  253. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/codegen.py +0 -0
  254. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/simple.py +0 -0
  255. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/struct.py +0 -0
  256. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/fields/struct_array.py +0 -0
  257. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/load_json.py +0 -0
  258. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +0 -0
  259. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +0 -0
  260. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +0 -0
  261. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +0 -0
  262. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +0 -0
  263. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +0 -0
  264. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterConfigsRequest.json +0 -0
  265. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterConfigsResponse.json +0 -0
  266. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +0 -0
  267. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +0 -0
  268. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +0 -0
  269. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +0 -0
  270. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +0 -0
  271. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +0 -0
  272. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ApiVersionsRequest.json +0 -0
  273. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ApiVersionsResponse.json +0 -0
  274. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +0 -0
  275. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +0 -0
  276. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/CreateAclsRequest.json +0 -0
  277. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/CreateAclsResponse.json +0 -0
  278. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/CreatePartitionsRequest.json +0 -0
  279. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/CreatePartitionsResponse.json +0 -0
  280. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/CreateTopicsRequest.json +0 -0
  281. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/CreateTopicsResponse.json +0 -0
  282. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteAclsRequest.json +0 -0
  283. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteAclsResponse.json +0 -0
  284. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteGroupsRequest.json +0 -0
  285. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteGroupsResponse.json +0 -0
  286. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteRecordsRequest.json +0 -0
  287. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteRecordsResponse.json +0 -0
  288. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteTopicsRequest.json +0 -0
  289. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DeleteTopicsResponse.json +0 -0
  290. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeAclsRequest.json +0 -0
  291. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeAclsResponse.json +0 -0
  292. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +0 -0
  293. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +0 -0
  294. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeClusterRequest.json +0 -0
  295. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeClusterResponse.json +0 -0
  296. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeConfigsRequest.json +0 -0
  297. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeConfigsResponse.json +0 -0
  298. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeGroupsRequest.json +0 -0
  299. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeGroupsResponse.json +0 -0
  300. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +0 -0
  301. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +0 -0
  302. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeProducersRequest.json +0 -0
  303. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeProducersResponse.json +0 -0
  304. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeQuorumRequest.json +0 -0
  305. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeQuorumResponse.json +0 -0
  306. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +0 -0
  307. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +0 -0
  308. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +0 -0
  309. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +0 -0
  310. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +0 -0
  311. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +0 -0
  312. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ElectLeadersRequest.json +0 -0
  313. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ElectLeadersResponse.json +0 -0
  314. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/EndTxnRequest.json +0 -0
  315. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/EndTxnResponse.json +0 -0
  316. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/FetchRequest.json +0 -0
  317. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/FetchResponse.json +0 -0
  318. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/FindCoordinatorRequest.json +0 -0
  319. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/FindCoordinatorResponse.json +0 -0
  320. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/HeartbeatRequest.json +0 -0
  321. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/HeartbeatResponse.json +0 -0
  322. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +0 -0
  323. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +0 -0
  324. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/InitProducerIdRequest.json +0 -0
  325. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/InitProducerIdResponse.json +0 -0
  326. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/JoinGroupRequest.json +0 -0
  327. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/JoinGroupResponse.json +0 -0
  328. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/LeaveGroupRequest.json +0 -0
  329. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/LeaveGroupResponse.json +0 -0
  330. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +0 -0
  331. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +0 -0
  332. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListGroupsRequest.json +0 -0
  333. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListGroupsResponse.json +0 -0
  334. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListOffsetsRequest.json +0 -0
  335. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListOffsetsResponse.json +0 -0
  336. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +0 -0
  337. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +0 -0
  338. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListTransactionsRequest.json +0 -0
  339. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ListTransactionsResponse.json +0 -0
  340. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/MetadataRequest.json +0 -0
  341. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/MetadataResponse.json +0 -0
  342. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetCommitRequest.json +0 -0
  343. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetCommitResponse.json +0 -0
  344. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetDeleteRequest.json +0 -0
  345. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetDeleteResponse.json +0 -0
  346. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetFetchRequest.json +0 -0
  347. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetFetchResponse.json +0 -0
  348. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +0 -0
  349. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +0 -0
  350. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ProduceRequest.json +0 -0
  351. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ProduceResponse.json +0 -0
  352. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/RequestHeader.json +0 -0
  353. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/ResponseHeader.json +0 -0
  354. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +0 -0
  355. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +0 -0
  356. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/SaslHandshakeRequest.json +0 -0
  357. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/SaslHandshakeResponse.json +0 -0
  358. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/SyncGroupRequest.json +0 -0
  359. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/SyncGroupResponse.json +0 -0
  360. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +0 -0
  361. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +0 -0
  362. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +0 -0
  363. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +0 -0
  364. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +0 -0
  365. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +0 -0
  366. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/protocol/schemas/resources/__init__.py +0 -0
  367. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/__init__.py +0 -0
  368. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/_crc32c.py +0 -0
  369. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/abc.py +0 -0
  370. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/default_records.py +0 -0
  371. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/legacy_records.py +0 -0
  372. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/memory_records.py +0 -0
  373. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/record/util.py +0 -0
  374. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/serializer/__init__.py +0 -0
  375. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/serializer/abstract.py +0 -0
  376. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/serializer/default.py +0 -0
  377. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/serializer/json.py +0 -0
  378. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/serializer/wrapper.py +0 -0
  379. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/util.py +0 -0
  380. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka/vendor/__init__.py +0 -0
  381. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka_python.egg-info/SOURCES.txt +0 -0
  382. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka_python.egg-info/dependency_links.txt +0 -0
  383. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka_python.egg-info/entry_points.txt +0 -0
  384. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka_python.egg-info/requires.txt +0 -0
  385. {kafka_python-3.0.0 → kafka_python-3.0.1}/kafka_python.egg-info/top_level.txt +0 -0
  386. {kafka_python-3.0.0 → kafka_python-3.0.1}/pyproject.toml +0 -0
  387. {kafka_python-3.0.0 → kafka_python-3.0.1}/setup.cfg +0 -0
  388. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/__init__.py +0 -0
  389. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/fixtures.py +0 -0
  390. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/test_producer_integration.py +0 -0
  391. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/test_sasl_integration.py +0 -0
  392. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/integration/test_ssl_integration.py +0 -0
  393. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/__init__.py +0 -0
  394. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_compat.py +0 -0
  395. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_connection.py +0 -0
  396. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_http_connect.py +0 -0
  397. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_inet.py +0 -0
  398. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_manager.py +0 -0
  399. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_sasl_reauthentication.py +0 -0
  400. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_selector.py +0 -0
  401. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_transport.py +0 -0
  402. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/net/test_wakeup_notifier.py +0 -0
  403. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_cluster.py +0 -0
  404. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_codec.py +0 -0
  405. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_future.py +0 -0
  406. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_metrics.py +0 -0
  407. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_package.py +0 -0
  408. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/test_util.py +0 -0
  409. {kafka_python-3.0.0 → kafka_python-3.0.1}/test/testutil.py +0 -0
@@ -1,3 +1,22 @@
1
+ # 3.0.1 (Jun 17, 2026)
2
+
3
+ ### Fixes
4
+ * receive_message_max_bytes default 100MiB (consumer/producer/admin); check against fetch_max_bytes and max_partition_fetch_bytes in Consumer (#3075)
5
+
6
+ ### Consumer
7
+ * Add MemberState to ConsumerGroupMetadata / consumer.group_metadata() (#3071)
8
+
9
+ ### Tests
10
+ * Add ConsumerGroupRunner fixture to manage multi-consumer group integration tests (#3072)
11
+ * Add MockGroup and test coordinator rebalance / metadata snapshot changes (#3069)
12
+ * Use 4.3 api_version for producer tests; fixup inadvertent sender thread leak in test (#3068)
13
+ * Add test coverage for producer acks (#3067)
14
+ * Fill-in empty sender tests (#3066)
15
+ * Add MockCluster; test failover on CoordinatorNotAvailableError (#3065)
16
+
17
+ ### Documentation
18
+ * Add ConsumerRecord, RecordMetadata, and FutureRecordMetadata to docs (#3070)
19
+
1
20
  # 3.0.0 (Jun 11, 2026)
2
21
 
3
22
  This is a major release with significant changes to kafka-python internals to simplify networking and feature development. It introduces a new networking layer (`kafka.net`) and a dynamic protocol system that uses JSON schema files imported from Apache Kafka. It substantially refactors and expands the Admin client, including breaking changes to some API signatures, and it lands a long list of KIP features/changes across the producer, consumer, admin, and networking/metadata clients. Protocol support across kafka-python is now at or beyond the apache kafka 3.0 baseline.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 3.0.0
3
+ Version: 3.0.1
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -75,7 +75,7 @@ class KafkaAdminClient(
75
75
  broker connection. Default: 5.
76
76
  receive_message_max_bytes (int): Maximum allowed network frame size.
77
77
  Used to avoid OOM when decoding malformed network message header.
78
- Default: 1000000.
78
+ Default: 100_000_000.
79
79
  receive_buffer_bytes (int): The size of the TCP receive buffer
80
80
  (SO_RCVBUF) to use when reading data. Default: None (relies on
81
81
  system defaults). Java client defaults to 32768.
@@ -177,7 +177,7 @@ class KafkaAdminClient(
177
177
  'reconnect_backoff_ms': 50,
178
178
  'reconnect_backoff_max_ms': 30000,
179
179
  'max_in_flight_requests_per_connection': 5,
180
- 'receive_message_max_bytes': 1000000,
180
+ 'receive_message_max_bytes': 100_000_000,
181
181
  'receive_buffer_bytes': None,
182
182
  'send_buffer_bytes': None,
183
183
  'socket_options': [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)],
@@ -26,6 +26,36 @@ _LOGGED_DESERIALIZE_WARNING = False
26
26
  ConsumerRecord = collections.namedtuple("ConsumerRecord",
27
27
  ["topic", "partition", "leader_epoch", "offset", "timestamp", "timestamp_type",
28
28
  "key", "value", "headers", "checksum", "serialized_key_size", "serialized_value_size", "serialized_header_size"])
29
+ ConsumerRecord.__doc__ = """A single record (message) consumed from a topic partition.
30
+
31
+ Yielded by :meth:`~kafka.KafkaConsumer.poll` (inside the returned
32
+ ``{TopicPartition: [ConsumerRecord, ...]}`` mapping) and by iterating
33
+ over a :class:`~kafka.KafkaConsumer`. ``key`` and ``value`` are decoded
34
+ by the consumer's configured deserializers.
35
+
36
+ Keyword Arguments:
37
+ topic (str): The topic this record was received from.
38
+ partition (int): The partition this record was received from.
39
+ leader_epoch (int): The partition leader epoch for this record, or -1
40
+ if unknown.
41
+ offset (int): The position of this record in the topic partition.
42
+ timestamp (int): The timestamp of this record, in milliseconds since
43
+ the epoch (UTC), or -1 if unknown.
44
+ timestamp_type (int): The type of the timestamp: 0 for CreateTime (set
45
+ by the producer) or 1 for LogAppendTime (set by the broker).
46
+ key: The (deserialized) key of the record, or None.
47
+ value: The (deserialized) value of the record, or None.
48
+ headers (list): A list of ``(key, value)`` header tuples, where key is
49
+ a str and value is bytes.
50
+ checksum (int): Deprecated. The CRC32 checksum of the record, or None.
51
+ Removed in message format v2 (Kafka 0.11+).
52
+ serialized_key_size (int): The size of the serialized, uncompressed key
53
+ in bytes, or -1 if the key is None.
54
+ serialized_value_size (int): The size of the serialized, uncompressed
55
+ value in bytes, or -1 if the value is None.
56
+ serialized_header_size (int): The size of the serialized, uncompressed
57
+ headers in bytes, or -1 if there are no headers.
58
+ """
29
59
 
30
60
 
31
61
  CompletedFetch = collections.namedtuple("CompletedFetch",
@@ -180,7 +180,9 @@ class KafkaConsumer:
180
180
  rebalances. Default: 3000
181
181
  receive_message_max_bytes (int): Maximum allowed network frame size.
182
182
  Used to avoid OOM when decoding malformed network message header.
183
- Default: 1000000.
183
+ Automatically raised to ``fetch_max_bytes + max_partition_fetch_bytes``
184
+ if configured lower, since a FetchResponse frame may be that large.
185
+ Default: 100_000_000.
184
186
  receive_buffer_bytes (int): The size of the TCP receive buffer
185
187
  (SO_RCVBUF) to use when reading data. Default: None (relies on
186
188
  system defaults). The java client defaults to 32768.
@@ -328,7 +330,7 @@ class KafkaConsumer:
328
330
  'heartbeat_interval_ms': 3000,
329
331
  'receive_buffer_bytes': None,
330
332
  'send_buffer_bytes': None,
331
- 'receive_message_max_bytes': 1000000,
333
+ 'receive_message_max_bytes': 100_000_000,
332
334
  'socket_options': [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)],
333
335
  'consumer_timeout_ms': float('inf'),
334
336
  'security_protocol': 'PLAINTEXT',
@@ -389,6 +391,20 @@ class KafkaConsumer:
389
391
  "fetch_max_wait_ms ({})."
390
392
  .format(connections_max_idle_ms, request_timeout_ms, fetch_max_wait_ms))
391
393
 
394
+ # fetch_max_bytes (KIP-74) is a soft cap the broker applies to the
395
+ # *record data* in a FetchResponse body, not to the whole frame. The
396
+ # frame also carries the response header + per-topic/per-partition
397
+ # metadata, and the broker returns at least the first record batch even
398
+ # when it alone exceeds fetch_max_bytes. So a FetchResponse frame can be
399
+ # somewhat larger than fetch_max_bytes; give the frame-size guard
400
+ # max_partition_fetch_bytes of headroom over it so legitimate responses
401
+ # aren't rejected as InvalidReceiveError. Auto-raise so the guard tracks
402
+ # the fetch sizing unless the user explicitly configured a larger value.
403
+ fetch_response_max_bytes = (
404
+ self.config['fetch_max_bytes'] + self.config['max_partition_fetch_bytes'])
405
+ if self.config['receive_message_max_bytes'] < fetch_response_max_bytes:
406
+ self.config['receive_message_max_bytes'] = fetch_response_max_bytes
407
+
392
408
  if self.config['metrics_enabled']:
393
409
  metrics_tags = {'client-id': self.config['client_id']}
394
410
  metric_config = MetricConfig(samples=self.config['metrics_num_samples'],
@@ -662,13 +678,17 @@ class KafkaConsumer:
662
678
  self._coordinator.commit_offsets_sync(offsets, timeout_ms=timeout_ms)
663
679
 
664
680
  def group_metadata(self):
665
- """Return a snapshot of this consumer's group membership (KIP-447).
681
+ """Return a snapshot of this consumer's group membership.
666
682
 
667
683
  Pass the result to KafkaProducer.send_offsets_to_transaction() so the
668
684
  broker can fence stale instances of this consumer when committing
669
- offsets inside a transaction. The snapshot is always safe to call:
670
- if no group_id is configured (manual assignment) the returned
671
- ConsumerGroupMetadata has group_id=None.
685
+ offsets inside a transaction (KIP-447). The snapshot also exposes the
686
+ current MemberState (``state``), so callers can observe whether the
687
+ consumer has converged on a stable assignment.
688
+
689
+ The snapshot is always safe to call: if no group_id is configured
690
+ (manual assignment) the returned ConsumerGroupMetadata has
691
+ group_id=None and is permanently unjoined.
672
692
 
673
693
  Returns:
674
694
  ConsumerGroupMetadata
@@ -16,19 +16,13 @@ from kafka.protocol.consumer import (
16
16
  HeartbeatRequest, JoinGroupRequest, LeaveGroupRequest, SyncGroupRequest,
17
17
  DEFAULT_GENERATION_ID, UNKNOWN_MEMBER_ID,
18
18
  )
19
- from kafka.structs import ConsumerGroupMetadata
19
+ from kafka.structs import ConsumerGroupMetadata, MemberState
20
20
  from kafka.util import Timer
21
21
 
22
22
  log = logging.getLogger('kafka.coordinator')
23
23
  heartbeat_log = logging.getLogger('kafka.coordinator.heartbeat')
24
24
 
25
25
 
26
- class MemberState:
27
- UNJOINED = '<unjoined>' # the client is not part of a group
28
- REBALANCING = '<rebalancing>' # the client has begun rebalancing
29
- STABLE = '<stable>' # the client has joined and is sending heartbeats
30
-
31
-
32
26
  class Generation:
33
27
  def __init__(self, generation_id, member_id, protocol):
34
28
  self.generation_id = generation_id
@@ -891,13 +885,16 @@ class BaseCoordinator(ABC):
891
885
  return self._generation
892
886
 
893
887
  def group_metadata(self):
894
- """Return a snapshot of this member's group identity (KIP-447).
888
+ """Return a snapshot of this member's group membership.
895
889
 
896
890
  Returns the current generation_id / member_id / group_instance_id even
897
891
  when the group is not stable; the caller (typically
898
892
  KafkaProducer.send_offsets_to_transaction) needs whatever is current
899
- so the broker can fence stale instances. If the consumer has never
900
- joined, the snapshot has the no-generation defaults.
893
+ so the broker can fence stale instances (KIP-447). If the consumer has
894
+ never joined, the snapshot has the no-generation defaults.
895
+
896
+ Also carries the live MemberState (``state``) so callers can observe
897
+ whether the group has converged (it is ignored by the fencing path).
901
898
  """
902
899
  with self._lock:
903
900
  return ConsumerGroupMetadata(
@@ -905,6 +902,7 @@ class BaseCoordinator(ABC):
905
902
  generation_id=self._generation.generation_id,
906
903
  member_id=self._generation.member_id,
907
904
  group_instance_id=self.group_instance_id,
905
+ state=self.state,
908
906
  )
909
907
 
910
908
  # deprecated
@@ -0,0 +1,52 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class Partitioner(ABC):
5
+ """Base class for pluggable partition selection strategies.
6
+
7
+ A :class:`~kafka.KafkaProducer` consults its configured partitioner to
8
+ choose a partition for each record whose ``partition`` was not supplied
9
+ explicitly to :meth:`~kafka.KafkaProducer.send`. Subclass this and
10
+ implement :meth:`partition`, then pass an instance via the
11
+ ``partitioner`` config argument.
12
+
13
+ Two built-in implementations are provided: ``DefaultPartitioner``
14
+ (murmur2-hash keyed records, random partition for null keys) and
15
+ ``StickyPartitioner`` (KIP-480; null-key records stick to one partition
16
+ per topic until a new batch is started, then rotate).
17
+
18
+ Sticky-style partitioners may additionally implement an optional
19
+ ``on_new_batch(self, topic, cluster, prev_partition)`` hook, which the
20
+ producer calls when a null-key record would have triggered a fresh
21
+ batch, giving the partitioner a chance to rotate off its current sticky
22
+ choice. The hook is looked up with ``getattr``, so it is entirely
23
+ optional.
24
+ """
25
+
26
+ @abstractmethod
27
+ def partition(self, topic, key, serialized_key, value, serialized_value, cluster):
28
+ """Choose a partition for a record.
29
+
30
+ Arguments:
31
+ topic (str): The topic the record is destined for.
32
+ key: The user-supplied key, before serialization. May be None.
33
+ serialized_key (bytes): The post-serializer key bytes, or None
34
+ when the caller passed ``key=None``.
35
+ value: The user-supplied value, before serialization.
36
+ serialized_value (bytes): The post-serializer value bytes, or
37
+ None when the caller passed ``value=None``.
38
+ cluster (ClusterMetadata): A live cluster snapshot. Use
39
+ ``cluster.partitions_for_topic(topic)`` for all partitions
40
+ and ``cluster.available_partitions_for_topic(topic)`` for
41
+ those whose leader is currently known.
42
+
43
+ Returns:
44
+ int: The partition id to assign the record to.
45
+
46
+ Raises:
47
+ ValueError: If the topic is not present in cluster metadata.
48
+ Partitioner exceptions surface to the caller via the
49
+ returned :class:`~kafka.producer.future.FutureRecordMetadata`.
50
+ """
51
+ pass
52
+
@@ -30,6 +30,19 @@ class FutureProduceResult(Future):
30
30
 
31
31
 
32
32
  class FutureRecordMetadata(Future):
33
+ """An asynchronous handle to the result of a single :meth:`~kafka.KafkaProducer.send`.
34
+
35
+ :meth:`~kafka.KafkaProducer.send` returns one of these immediately,
36
+ before the record has been transmitted to the broker. Call :meth:`get`
37
+ to block until the record is acknowledged and obtain its
38
+ :class:`RecordMetadata`, or register callbacks via
39
+ :meth:`~kafka.future.Future.add_callback` /
40
+ :meth:`~kafka.future.Future.add_errback` to be notified without
41
+ blocking. The future resolves successfully once the containing batch is
42
+ acknowledged according to the producer's ``acks`` configuration, or
43
+ fails with the relevant exception (for example
44
+ :class:`~kafka.errors.KafkaTimeoutError`).
45
+ """
33
46
  __slots__ = ('_produce_future', 'args')
34
47
  def __init__(self, produce_future, batch_index, timestamp_ms, checksum, serialized_key_size, serialized_value_size, serialized_header_size):
35
48
  super().__init__()
@@ -99,3 +112,28 @@ class FutureRecordMetadata(Future):
99
112
  RecordMetadata = collections.namedtuple(
100
113
  'RecordMetadata', ['topic', 'partition', 'topic_partition', 'offset', 'timestamp',
101
114
  'checksum', 'serialized_key_size', 'serialized_value_size', 'serialized_header_size'])
115
+ RecordMetadata.__doc__ = """Metadata about a record that has been acknowledged by the broker.
116
+
117
+ Returned by :meth:`FutureRecordMetadata.get`, which resolves once the
118
+ batch containing the record has been acknowledged according to the
119
+ producer's ``acks`` configuration.
120
+
121
+ Keyword Arguments:
122
+ topic (str): The topic the record was appended to.
123
+ partition (int): The partition the record was appended to.
124
+ topic_partition (TopicPartition): The ``(topic, partition)`` the record
125
+ was appended to.
126
+ offset (int): The offset of the record in the topic partition, or -1 if
127
+ the broker did not assign one (e.g. ``acks=0``).
128
+ timestamp (int): The timestamp of the record, in milliseconds since the
129
+ epoch (UTC). For CreateTime this is the producer-supplied timestamp;
130
+ for LogAppendTime it is the broker-assigned timestamp.
131
+ checksum (int): Deprecated. The CRC32 checksum of the record, or None.
132
+ Removed in message format v2 (Kafka 0.11+).
133
+ serialized_key_size (int): The size of the serialized, uncompressed key
134
+ in bytes, or -1 if the key is None.
135
+ serialized_value_size (int): The size of the serialized, uncompressed
136
+ value in bytes, or -1 if the value is None.
137
+ serialized_header_size (int): The size of the serialized, uncompressed
138
+ headers in bytes, or -1 if there are no headers.
139
+ """
@@ -282,7 +282,7 @@ class KafkaProducer:
282
282
  Default: 30000.
283
283
  receive_message_max_bytes (int): Maximum allowed network frame size.
284
284
  Used to avoid OOM when decoding malformed network message header.
285
- Default: 1000000.
285
+ Default: 100_000_000.
286
286
  receive_buffer_bytes (int): The size of the TCP receive buffer
287
287
  (SO_RCVBUF) to use when reading data. Default: None (relies on
288
288
  system defaults). Java client defaults to 32768.
@@ -425,7 +425,7 @@ class KafkaProducer:
425
425
  'client_dns_lookup': 'use_all_dns_ips',
426
426
  'retry_backoff_ms': 100,
427
427
  'request_timeout_ms': 30000,
428
- 'receive_message_max_bytes': 1000000,
428
+ 'receive_message_max_bytes': 100_000_000,
429
429
  'receive_buffer_bytes': None,
430
430
  'send_buffer_bytes': None,
431
431
  'socket_options': [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)],
@@ -51,19 +51,33 @@ Keyword Arguments:
51
51
  """
52
52
 
53
53
 
54
+ class MemberState:
55
+ UNJOINED = '<unjoined>' # the client is not part of a group
56
+ REBALANCING = '<rebalancing>' # the client has begun rebalancing
57
+ STABLE = '<stable>' # the client has joined and is sending heartbeats
58
+
59
+
54
60
  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).
61
+ ["group_id", "generation_id", "member_id", "group_instance_id", "state"],
62
+ defaults=[None, -1, '', None, MemberState.UNJOINED])
63
+ ConsumerGroupMetadata.__doc__ = """A snapshot of a consumer's group membership.
64
+
65
+ The first four fields are the KIP-447 fencing identity: pass the snapshot to
66
+ KafkaProducer.send_offsets_to_transaction() so the broker can fence stale
67
+ consumer instances when committing offsets inside a transaction. The broker
68
+ uses member_id + generation_id + group_instance_id to verify the producer is
69
+ acting on behalf of the current group generation.
58
70
 
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.
71
+ The ``state`` field exposes the live MemberState (it is ignored by the
72
+ producer/fencing path). It lets callers observe whether the consumer has
73
+ converged on a stable assignment - useful for monitoring and for tests that
74
+ wait for a group to finish rebalancing.
63
75
 
64
76
  Keyword Arguments:
65
- group_id (str): The consumer group id.
77
+ group_id (str): The consumer group id, or None for manual assignment.
66
78
  generation_id (int): The current generation id (-1 if unjoined).
67
79
  member_id (str): The current member id ('' if unjoined).
68
80
  group_instance_id (str): The static membership instance id, or None.
81
+ state (str): The current MemberState (one of MemberState.UNJOINED,
82
+ MemberState.REBALANCING, MemberState.STABLE).
69
83
  """
@@ -0,0 +1 @@
1
+ __version__ = '3.0.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 3.0.0
3
+ Version: 3.0.1
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -1,5 +1,8 @@
1
+ import collections
1
2
  import contextlib
2
3
  import os
4
+ import threading
5
+ import time
3
6
  from urllib.parse import urlparse
4
7
  import uuid
5
8
 
@@ -7,6 +10,7 @@ import pytest
7
10
 
8
11
  from kafka import KafkaAdminClient, KafkaConsumer, KafkaProducer
9
12
  from kafka.net.compat import KafkaNetClient
13
+ from kafka.structs import MemberState
10
14
  from kafka.util import TOPIC_LEGAL_CHARS, TOPIC_MAX_LENGTH, ensure_valid_topic_name
11
15
  from test.testutil import env_kafka_version, random_string
12
16
  from test.integration.fixtures import KafkaFixture, ZookeeperFixture, create_topics, client_params
@@ -248,3 +252,121 @@ def send_messages(topic, producer, request):
248
252
  return [msg for (msg, f) in messages_and_futures]
249
253
 
250
254
  return _send_messages
255
+
256
+
257
+ class ConsumerGroupRunner:
258
+ """Manage pools of group-consuming threads for integration tests.
259
+
260
+ Each spawned consumer runs ``poll()`` in its own background thread until
261
+ the runner is torn down. Use :meth:`wait_for_stable` to block until every
262
+ member has joined and the group has finished rebalancing. Threads are
263
+ stopped and joined automatically when the ``consumer_group`` fixture tears
264
+ down, so tests don't need their own ``try/finally`` bookkeeping.
265
+
266
+ consumers = consumer_group.spawn(group_id='g', count=4)
267
+ consumer_group.wait_for_stable()
268
+ # ... assert on consumers[i].assignment() ...
269
+
270
+ ``wait_for_stable`` reads ``consumer.group_metadata()`` / ``assignment()``
271
+ from the test thread while each consumer polls on its own thread. Both
272
+ reads are lock-protected snapshots, so this cross-thread observation is
273
+ safe even though KafkaConsumer is otherwise single-threaded.
274
+ """
275
+ def __init__(self, consumer_factory):
276
+ self._factory = consumer_factory
277
+ self._members = [] # [{thread, stop, ready, consumer, error}, ...]
278
+
279
+ @property
280
+ def consumers(self):
281
+ """Live consumers in spawn order (across all groups)."""
282
+ return [m['consumer'] for m in self._members]
283
+
284
+ def spawn(self, group_id, count=1, client_id_prefix='consumer', **consumer_params):
285
+ """Start ``count`` consumer threads in ``group_id``; return their consumers.
286
+
287
+ Blocks until each consumer has been constructed (or re-raises whatever
288
+ the consumer thread failed with during startup). Extra keyword args are
289
+ passed through to ``kafka_consumer_factory``.
290
+ """
291
+ started = []
292
+ for _ in range(count):
293
+ member = {
294
+ 'stop': threading.Event(),
295
+ 'ready': threading.Event(),
296
+ 'consumer': None,
297
+ 'error': None,
298
+ }
299
+ client_id = '%s-%d' % (client_id_prefix, len(self._members))
300
+
301
+ def run(member=member, client_id=client_id):
302
+ try:
303
+ with self._factory(group_id=group_id, client_id=client_id,
304
+ **consumer_params) as c:
305
+ member['consumer'] = c
306
+ member['ready'].set()
307
+ while not member['stop'].is_set():
308
+ c.poll(timeout_ms=200)
309
+ except Exception as e: # surfaced via spawn() / stop()
310
+ member['error'] = e
311
+ finally:
312
+ member['ready'].set()
313
+
314
+ member['thread'] = threading.Thread(target=run, name=client_id, daemon=True)
315
+ self._members.append(member)
316
+ member['thread'].start()
317
+ assert member['ready'].wait(timeout=15), \
318
+ 'consumer %s failed to start within 15s' % client_id
319
+ if member['error'] is not None:
320
+ raise member['error'] # pylint: disable=raising-bad-type
321
+ started.append(member['consumer'])
322
+ return started
323
+
324
+ def wait_for_stable(self, timeout=30, poll_interval=1):
325
+ """Block until every member is STABLE, assigned, and on one generation.
326
+
327
+ "One generation" is checked per group_id: a fully converged group has
328
+ all of its members reporting the same generation_id, which means the
329
+ most recent rebalance has propagated to everyone.
330
+ """
331
+ deadline = time.monotonic() + timeout
332
+ while True:
333
+ generations = collections.defaultdict(set)
334
+ converged = True
335
+ for c in self.consumers:
336
+ meta = c.group_metadata()
337
+ if meta.state != MemberState.STABLE or not c.assignment():
338
+ converged = False
339
+ break
340
+ generations[meta.group_id].add(meta.generation_id)
341
+ if converged and all(len(g) == 1 for g in generations.values()):
342
+ return
343
+ assert time.monotonic() < deadline, 'timeout waiting for stable group'
344
+ time.sleep(poll_interval)
345
+
346
+ def stop(self):
347
+ """Signal all threads to stop, then join them (called at teardown)."""
348
+ for member in self._members:
349
+ member['stop'].set()
350
+ for member in self._members:
351
+ member['thread'].join(timeout=5)
352
+ assert not member['thread'].is_alive(), \
353
+ 'consumer thread %s did not exit' % member['thread'].name
354
+
355
+
356
+ @pytest.fixture
357
+ def consumer_group(kafka_consumer_factory):
358
+ """Return a ConsumerGroupRunner for multi-threaded consumer group tests.
359
+
360
+ Spawns group-consuming threads on demand and tears them all down (stop +
361
+ join) when the test finishes::
362
+
363
+ def test_something(consumer_group, topic):
364
+ consumer_group.spawn(group_id='g', count=3)
365
+ consumer_group.wait_for_stable()
366
+ ...
367
+ """
368
+ runner = ConsumerGroupRunner(kafka_consumer_factory)
369
+ try:
370
+ yield runner
371
+ finally:
372
+ runner.stop()
@@ -1,5 +1,4 @@
1
1
  from logging import info
2
- from threading import Event, Thread
3
2
  from time import monotonic as time, sleep
4
3
 
5
4
  import pytest
@@ -170,95 +169,31 @@ def test_describe_configs_invalid_broker_id_raises(kafka_admin_client):
170
169
 
171
170
 
172
171
  @pytest.mark.skipif(env_kafka_version() < (0, 11), reason='Describe consumer group requires broker >=0.11')
173
- def test_describe_group_exists(kafka_admin_client, kafka_consumer_factory, topic):
174
- """Tests that the describe consumer group call returns valid consumer group information
175
- This test takes inspiration from the test 'test_group' in test_consumer_group.py.
176
- """
177
- consumers = {}
178
- stop = {}
179
- threads = {}
172
+ def test_describe_group_exists(kafka_admin_client, consumer_group, topic):
173
+ """Tests that the describe consumer group call returns valid consumer group information"""
180
174
  random_group_id = 'test-group-' + random_string(6)
181
175
  group_id_list = [random_group_id, random_group_id + '_2']
182
- generations = {group_id_list[0]: set(), group_id_list[1]: set()}
183
- def consumer_thread(i, group_id):
184
- assert i not in consumers
185
- assert i not in stop
186
- stop[i] = Event()
187
- with kafka_consumer_factory(group_id=group_id) as c:
188
- consumers[i] = c
189
- while not stop[i].is_set():
190
- consumers[i].poll(timeout_ms=200)
191
- consumers[i] = None
192
- stop[i] = None
193
-
194
- num_consumers = 3
195
- for i in range(num_consumers):
196
- group_id = group_id_list[i % 2]
197
- t = Thread(target=consumer_thread, args=(i, group_id,))
198
- t.start()
199
- threads[i] = t
200
-
201
- try:
202
- timeout = time() + 35
203
- while True:
204
- info('Checking consumers...')
205
- for c in range(num_consumers):
206
-
207
- # Verify all consumers have been created
208
- if c not in consumers:
209
- break
210
-
211
- # Verify all consumers have an assignment
212
- elif not consumers[c].assignment():
213
- break
214
-
215
- # If all consumers exist and have an assignment
216
- else:
217
-
218
- info('All consumers have assignment... checking for stable group')
219
- # Verify all consumers are in the same generation
220
- # then log state and break while loop
221
-
222
- for consumer in consumers.values():
223
- generations[consumer.config['group_id']].add(consumer._coordinator._generation.generation_id)
224
-
225
- is_same_generation = any([len(consumer_generation) == 1 for consumer_generation in generations.values()])
226
-
227
- # New generation assignment is not complete until
228
- # coordinator.rejoining = False
229
- rejoining = any([consumer._coordinator.rejoining
230
- for consumer in list(consumers.values())])
231
-
232
- if not rejoining and is_same_generation:
233
- break
234
- assert time() < timeout, "timeout waiting for assignments"
235
- info('sleeping...')
236
- sleep(1)
237
176
 
238
- info('Group stabilized; verifying assignment')
239
- output = kafka_admin_client.describe_groups(group_id_list)
240
- assert len(output) == 2
241
- groups = set()
242
- for group in output.values():
243
- assert(group['group_id'] in group_id_list)
244
- if group['group_id'] == group_id_list[0]:
245
- assert(len(group['members']) == 2)
246
- else:
247
- assert(len(group['members']) == 1)
248
- for member in group['members']:
249
- assert(member['member_metadata']['topics'] == [topic])
250
- assert(member['member_assignment']['assigned_partitions'][0]['topic'] == topic)
251
- groups.add(group['group_id'])
252
- assert(sorted(list(groups)) == group_id_list)
253
- finally:
254
- info('Shutting down %s consumers', num_consumers)
255
- for c in range(num_consumers):
256
- info('Stopping consumer %s', c)
257
- stop[c].set()
258
- for c in range(num_consumers):
259
- info('Waiting for consumer thread %s', c)
260
- threads[c].join()
261
- threads[c] = None
177
+ # Two members in the first group, one in the second.
178
+ consumer_group.spawn(group_id=group_id_list[0], count=2)
179
+ consumer_group.spawn(group_id=group_id_list[1], count=1)
180
+ consumer_group.wait_for_stable(timeout=35)
181
+
182
+ info('Group stabilized; verifying assignment')
183
+ output = kafka_admin_client.describe_groups(group_id_list)
184
+ assert len(output) == 2
185
+ groups = set()
186
+ for group in output.values():
187
+ assert(group['group_id'] in group_id_list)
188
+ if group['group_id'] == group_id_list[0]:
189
+ assert(len(group['members']) == 2)
190
+ else:
191
+ assert(len(group['members']) == 1)
192
+ for member in group['members']:
193
+ assert(member['member_metadata']['topics'] == [topic])
194
+ assert(member['member_assignment']['assigned_partitions'][0]['topic'] == topic)
195
+ groups.add(group['group_id'])
196
+ assert(sorted(list(groups)) == group_id_list)
262
197
 
263
198
 
264
199
  @pytest.mark.skipif(env_kafka_version() < (1, 1), reason="Delete consumer groups requires broker >=1.1")