kafka-python 2.2.16__py2.py3-none-any.whl → 2.2.17__py2.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.
kafka/conn.py CHANGED
@@ -326,6 +326,9 @@ class BrokerConnection(object):
326
326
  return True
327
327
 
328
328
  def _next_afi_sockaddr(self):
329
+ if self.config["socks5_proxy"] and Socks5Wrapper.use_remote_lookup(self.config["socks5_proxy"]):
330
+ return (socket.AF_UNSPEC, (self.host, self.port))
331
+
329
332
  if not self._gai:
330
333
  if not self._dns_lookup():
331
334
  return
@@ -379,6 +382,7 @@ class BrokerConnection(object):
379
382
  self._sock_afi, self._sock_addr = next_lookup
380
383
  try:
381
384
  if self.config["socks5_proxy"] is not None:
385
+ log.debug('%s: initializing Socks5 proxy at %s', self, self.config["socks5_proxy"])
382
386
  self._socks5_proxy = Socks5Wrapper(self.config["socks5_proxy"], self.afi)
383
387
  self._sock = self._socks5_proxy.socket(self._sock_afi, socket.SOCK_STREAM)
384
388
  else:
@@ -864,6 +868,8 @@ class BrokerConnection(object):
864
868
  if self.disconnected() or self.connecting():
865
869
  if len(self._gai) > 0:
866
870
  return 0
871
+ elif self.config["socks5_proxy"] and Socks5Wrapper.use_remote_lookup(self.config["socks5_proxy"]):
872
+ return 0
867
873
  else:
868
874
  time_waited = time.time() - self.last_attempt
869
875
  return max(self._reconnect_backoff - time_waited, 0) * 1000
@@ -964,6 +970,7 @@ class BrokerConnection(object):
964
970
  # the socket fd from selectors cleanly.
965
971
  sock = self._sock
966
972
  self._sock = None
973
+ self._socks5_proxy = None
967
974
 
968
975
  # drop lock before state change callback and processing futures
969
976
  self.config['state_change_callback'](self.node_id, sock, self)
kafka/consumer/group.py CHANGED
@@ -723,7 +723,9 @@ class KafkaConsumer(six.Iterator):
723
723
 
724
724
  # We do not want to be stuck blocking in poll if we are missing some positions
725
725
  # since the offset lookup may be backing off after a failure
726
- poll_timeout_ms = min(timer.timeout_ms, self._coordinator.time_to_next_poll() * 1000)
726
+ poll_timeout_ms = timer.timeout_ms
727
+ if self.config['group_id'] is not None:
728
+ poll_timeout_ms = min(poll_timeout_ms, self._coordinator.time_to_next_poll() * 1000)
727
729
  if not has_all_fetch_positions:
728
730
  log.debug('poll: do not have all fetch positions...')
729
731
  poll_timeout_ms = min(poll_timeout_ms, self.config['retry_backoff_ms'])
@@ -753,13 +755,12 @@ class KafkaConsumer(six.Iterator):
753
755
 
754
756
  timer = Timer(timeout_ms)
755
757
  position = self._subscription.assignment[partition].position
756
- while position is None:
758
+ while position is None and not timer.expired:
757
759
  # batch update fetch positions for any partitions without a valid position
758
- if self._update_fetch_positions(timeout_ms=timer.timeout_ms):
759
- position = self._subscription.assignment[partition].position
760
- if timer.expired:
761
- return None
762
- else:
760
+ self._update_fetch_positions(timeout_ms=timer.timeout_ms)
761
+ self._client.poll(timeout_ms=timer.timeout_ms)
762
+ position = self._subscription.assignment[partition].position
763
+ if position is not None:
763
764
  return position.offset
764
765
 
765
766
  def highwater(self, partition):
kafka/coordinator/base.py CHANGED
@@ -1120,6 +1120,7 @@ class HeartbeatThread(threading.Thread):
1120
1120
  self.coordinator._lock.wait(self.coordinator.config['retry_backoff_ms'] / 1000)
1121
1121
 
1122
1122
  elif not self.coordinator.connected():
1123
+ self.coordinator._client.maybe_connect(self.coordinator.coordinator_id)
1123
1124
  self.coordinator._client._lock.release()
1124
1125
  self.coordinator._lock.wait(self.coordinator.config['retry_backoff_ms'] / 1000)
1125
1126
 
kafka/producer/kafka.py CHANGED
@@ -134,10 +134,14 @@ class KafkaProducer(object):
134
134
  value_serializer (callable): used to convert user-supplied message
135
135
  values to bytes. If not None, called as f(value), should return
136
136
  bytes. Default: None.
137
+ transactional_id (str): Enable transactional producer with a unique
138
+ identifier. This will be used to identify the same producer
139
+ instance across process restarts. Default: None.
137
140
  enable_idempotence (bool): When set to True, the producer will ensure
138
141
  that exactly one copy of each message is written in the stream.
139
142
  If False, producer retries due to broker failures, etc., may write
140
- duplicates of the retried message in the stream. Default: False.
143
+ duplicates of the retried message in the stream.
144
+ Default: True if `transactional_id` is provided, otherwise False.
141
145
 
142
146
  Note that enabling idempotence requires
143
147
  `max_in_flight_requests_per_connection` to be set to 1 and `retries`
kafka/socks5_wrapper.py CHANGED
@@ -64,6 +64,15 @@ class Socks5Wrapper:
64
64
  log.warning("DNS lookup failed for proxy %s:%d, %r", host, port, ex)
65
65
  return []
66
66
 
67
+ @classmethod
68
+ def use_remote_lookup(cls, proxy_url):
69
+ if proxy_url is None:
70
+ return False
71
+ return urlparse(proxy_url).scheme == 'socks5h'
72
+
73
+ def _use_remote_lookup(self):
74
+ return self._proxy_url.scheme == 'socks5h'
75
+
67
76
  def socket(self, family, sock_type):
68
77
  """Open and record a socket.
69
78
 
@@ -187,7 +196,10 @@ class Socks5Wrapper:
187
196
  return errno.ECONNREFUSED
188
197
 
189
198
  if self._state == ProxyConnectionStates.REQUEST_SUBMIT:
190
- if self._target_afi == socket.AF_INET:
199
+ if self._use_remote_lookup():
200
+ addr_type = 3
201
+ addr_len = len(addr[0])
202
+ elif self._target_afi == socket.AF_INET:
191
203
  addr_type = 1
192
204
  addr_len = 4
193
205
  elif self._target_afi == socket.AF_INET6:
@@ -200,14 +212,28 @@ class Socks5Wrapper:
200
212
  return errno.ECONNREFUSED
201
213
 
202
214
  self._buffer_out = struct.pack(
203
- "!bbbb{}sh".format(addr_len),
215
+ "!bbbb",
204
216
  5, # version
205
217
  1, # command: connect
206
218
  0, # reserved
207
- addr_type, # 1 for ipv4, 4 for ipv6 address
208
- socket.inet_pton(self._target_afi, addr[0]), # either 4 or 16 bytes of actual address
209
- addr[1], # port
219
+ addr_type, # 1 for ipv4, 4 for ipv6 address, 3 for domain name
210
220
  )
221
+ # Addr format depends on type
222
+ if addr_type == 3:
223
+ # len + domain name (no null terminator)
224
+ self._buffer_out += struct.pack(
225
+ "!b{}s".format(addr_len),
226
+ addr_len,
227
+ addr[0].encode('ascii'),
228
+ )
229
+ else:
230
+ # either 4 (type 1) or 16 (type 4) bytes of actual address
231
+ self._buffer_out += struct.pack(
232
+ "!{}s".format(addr_len),
233
+ socket.inet_pton(self._target_afi, addr[0]),
234
+ )
235
+ self._buffer_out += struct.pack("!H", addr[1]) # port
236
+
211
237
  self._state = ProxyConnectionStates.REQUESTING
212
238
 
213
239
  if self._state == ProxyConnectionStates.REQUESTING:
kafka/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '2.2.16'
1
+ __version__ = '2.2.17'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.16
3
+ Version: 2.2.17
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dpkp/kafka-python
@@ -2,13 +2,13 @@ kafka/__init__.py,sha256=4dvHKZAxmD_4tfJ5wGcRV2X78vPcm8vsUoqceULevjA,1077
2
2
  kafka/client_async.py,sha256=R8q_rRpG3RrYrRmcZo7XgO2oSdpLJATNcq8w-1vIJ_8,56878
3
3
  kafka/cluster.py,sha256=B4tOZYhZaYrcGsyAtdA8yejFm9ue7ElJxn_pd6Xhdfk,16775
4
4
  kafka/codec.py,sha256=8NZpnehzNrhSBIjzbPVSvyFbSeLAqEntE7BfVHu-_9I,10036
5
- kafka/conn.py,sha256=La-xtpbM7k5ocswFJf3gm4fHNWzQV3fCG0YfeKFRYGI,69956
5
+ kafka/conn.py,sha256=hDwKQ93zpZAWfACdiInEfcBSD6MpYCxVNoAjFneQW9Q,70406
6
6
  kafka/errors.py,sha256=qX2Fp0qawU_HBNcZCwB7EDCmx3C2PehrETi6qSEJHmk,33290
7
7
  kafka/future.py,sha256=ZQStbfUYIPJRrgMfAWxxjrIRVxsw4WCtSR0J0bkyGno,2847
8
- kafka/socks5_wrapper.py,sha256=6woOaCTJXJ5e89_zdyW5BjOpyE4rCbYFH-kd-FeuPuk,9827
8
+ kafka/socks5_wrapper.py,sha256=h0Gag3xAOp8io2MfzeYLOiNvLRmq3rkmpZ6Aj-9uKTw,10716
9
9
  kafka/structs.py,sha256=SJGzmLdV21jZyQ7247k0WFy16UiusgTHK3I-e4qzI-E,3058
10
10
  kafka/util.py,sha256=WGqI5yT1yWGgHqSuRF9Fi8ejpiB53SurMy7ABkYxJ2g,4584
11
- kafka/version.py,sha256=UTmClSKnv3Rn1Qies89Pt3D8Dmn-myrPMLtPf-wbASY,23
11
+ kafka/version.py,sha256=cwT2pG8_0ZVnZ1VhpzKqNri9AmJ_-isNazUrTQ3CI14,23
12
12
  kafka/admin/__init__.py,sha256=S_XxqyyV480_yXhttK79XZqNAmZyXRjspd3SoqYykE8,720
13
13
  kafka/admin/acl_resource.py,sha256=ak_dUsSni4SyP0ORbSKenZpwTy0Ykxq3FSt_9XgLR8k,8265
14
14
  kafka/admin/client.py,sha256=94UpHTsgzvhOoB6_1QLeKxvZKlStKfI96xuWyaY9_Sc,78814
@@ -24,10 +24,10 @@ kafka/benchmarks/record_batch_read.py,sha256=vlFaWU2YWI379n_2M8qieb_S2uHUWKV0Nqu
24
24
  kafka/benchmarks/varint_speed.py,sha256=s4CuvKgDZL-_zna5E3vM8RgHjhXuW6pcaO1z1WYZ_0Y,12585
25
25
  kafka/consumer/__init__.py,sha256=NDdvtyuJgFyQZahqL9i5sYXGP6rOMIXWwHQEaZ1fCcs,122
26
26
  kafka/consumer/fetcher.py,sha256=RlQLut54c5nOMl21neTJA2tmdsxIIPIX2Idu5Q-dYKY,69184
27
- kafka/consumer/group.py,sha256=kGvgqqdV9zrgCXr7jSbTs9sSJACjuAKehuxt0QYRHHU,58943
27
+ kafka/consumer/group.py,sha256=rkjqEjWY72is-tRfm2mjAF1m6dACUP83PO_XGbkJu8I,59071
28
28
  kafka/consumer/subscription_state.py,sha256=bK-YTVbOzhy8OB206QAfXVuo7zPA9YqYXnrRRST369c,24289
29
29
  kafka/coordinator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- kafka/coordinator/base.py,sha256=hXfwtDkrHXHiNqjshCOa19js_2Y6ibLsdzDvJKGmcKc,54419
30
+ kafka/coordinator/base.py,sha256=4GdPwC28S5a6e7B20fvzMVcL0YKemS43B4JiogeEd0E,54507
31
31
  kafka/coordinator/consumer.py,sha256=le4bGbHfrDK4pperYXekPKzuZW576uXL324IOwS4Kmw,46348
32
32
  kafka/coordinator/heartbeat.py,sha256=LeJJlwz1oUEOfEMIFT-R7ZOHBQ-b-luVKwmKyWxLfDo,3242
33
33
  kafka/coordinator/protocol.py,sha256=wTaIOnUVbj0CKXZ82FktZo-zMRvOCk3hdQAoHJ62e3I,1041
@@ -67,7 +67,7 @@ kafka/partitioner/__init__.py,sha256=Fks3C5_kokVWYw1Ad5wv0sVVzaaBtOejL-2bIL1yRII
67
67
  kafka/partitioner/default.py,sha256=tW-RC1PWIPRDEbeEAaPTLn-00oiZnXoVouEk9AnYE4w,2879
68
68
  kafka/producer/__init__.py,sha256=i3Wxih0NHjmqCkRNE54ial8fBp9siqabUE6ZGyL6oX8,122
69
69
  kafka/producer/future.py,sha256=UC3-g9QlgVFmbitrtMXVpeP0Pbvr7xl2kcw6bAehKG8,2983
70
- kafka/producer/kafka.py,sha256=oGO-UxoVZEFdBLOQ7zEqeDJWXMxKyUdNV-pCRU3jZmg,53302
70
+ kafka/producer/kafka.py,sha256=T0c-QmoagY6HMyomNlvYaYSVfUHe42W72EDiegX6XyY,53573
71
71
  kafka/producer/record_accumulator.py,sha256=xNkHOCmganxDfa3W_Y3iBLT4RaAOZi0Lix-mUzsp2aQ,28170
72
72
  kafka/producer/sender.py,sha256=8-TLTw6vQO7AheWSDPI33cQdWMyTDxi1k-pkXuUb9k0,37789
73
73
  kafka/producer/transaction_manager.py,sha256=q3e9Lc9o-ofWvjT9FbHdTQH08XQBeRtoQEcQHGcnp7g,41535
@@ -120,7 +120,7 @@ kafka/vendor/enum34.py,sha256=-u-lxAiJMt6ru4Do7NUDY9OpeWkYJMksb2xengJawFE,31204
120
120
  kafka/vendor/selectors34.py,sha256=gxejLO4eXf8mRSGXaQiknPig3GdX1rtsZiYOQJVuAy8,20594
121
121
  kafka/vendor/six.py,sha256=lLBa9_HrANP5BMZ7twEzg1M3wofwPmXyptuWmHX0brY,34826
122
122
  kafka/vendor/socketpair.py,sha256=Fi3PoY1Okkppab720wFk1BhHXyjcw7hi5DwhqrYZH2Y,2737
123
- kafka_python-2.2.16.dist-info/METADATA,sha256=H-5YJSGk5csYCUOY1A6V8Yxboixmay0cG60di1TsGeU,9952
124
- kafka_python-2.2.16.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
125
- kafka_python-2.2.16.dist-info/top_level.txt,sha256=IivJz7l5WHdLNDT6RIiVAlhjQzYRwGqBBmKHZ7WjPeM,6
126
- kafka_python-2.2.16.dist-info/RECORD,,
123
+ kafka_python-2.2.17.dist-info/METADATA,sha256=u8fByYt-bY1oySuBwxpK9MiR1aGM5AFpNX5wNcTspWA,9952
124
+ kafka_python-2.2.17.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
125
+ kafka_python-2.2.17.dist-info/top_level.txt,sha256=IivJz7l5WHdLNDT6RIiVAlhjQzYRwGqBBmKHZ7WjPeM,6
126
+ kafka_python-2.2.17.dist-info/RECORD,,