adc-streaming 2.4.0__tar.gz → 2.5.0__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 (36) hide show
  1. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/.github/workflows/build.yml +1 -1
  2. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/PKG-INFO +1 -1
  3. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/auth.py +5 -0
  4. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/consumer.py +4 -3
  5. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/producer.py +6 -4
  6. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc_streaming.egg-info/PKG-INFO +1 -1
  7. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/tests/test_auth.py +1 -1
  8. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/tests/test_kafka_integration.py +39 -10
  9. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/.gitignore +0 -0
  10. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/LICENSE +0 -0
  11. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/Makefile +0 -0
  12. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/README.md +0 -0
  13. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/__init__.py +0 -0
  14. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/errors.py +0 -0
  15. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/io.py +0 -0
  16. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/kafka.py +0 -0
  17. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc/oidc.py +0 -0
  18. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc_streaming.egg-info/SOURCES.txt +0 -0
  19. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc_streaming.egg-info/dependency_links.txt +0 -0
  20. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc_streaming.egg-info/not-zip-safe +0 -0
  21. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc_streaming.egg-info/requires.txt +0 -0
  22. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/adc_streaming.egg-info/top_level.txt +0 -0
  23. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/Makefile +0 -0
  24. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/_static/css/my_theme.css +0 -0
  25. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/_templates/layout.html +0 -0
  26. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/api/api.rst +0 -0
  27. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/api/streaming.rst +0 -0
  28. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/conf.py +0 -0
  29. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/index.rst +0 -0
  30. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/user/installation.rst +0 -0
  31. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/doc/user/quickstart.rst +0 -0
  32. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/pyproject.toml +0 -0
  33. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/recipe/meta.yaml +0 -0
  34. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/setup.cfg +0 -0
  35. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/setup.py +0 -0
  36. {adc-streaming-2.4.0 → adc-streaming-2.5.0}/tests/test_kafka.py +0 -0
@@ -7,7 +7,7 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- python-version: [3.7, 3.8, 3.9]
10
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
11
11
 
12
12
  steps:
13
13
  - name: Check out the code
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: adc-streaming
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Astronomy Data Commons streaming client libraries
5
5
  Home-page: https://github.com/astronomy-commons/adc-streaming
6
6
  Author: Astronomy Data Commons Team
@@ -38,6 +38,8 @@ class SASLAuth(object):
38
38
  ssl_ca_location : `str`, optional
39
39
  If using SSL via a self-signed cert, a path/location
40
40
  to the certificate.
41
+ ssl_endpoint_identification_algorithm : `str`, optional
42
+ If using SSL, the algorithm used to verify that certificate is valid for the endpoint.
41
43
  token_endpoint : `str`, optional
42
44
  The OpenID Connect token endpoint URL.
43
45
  Required for OAUTHBEARER / OpenID Connect, otherwise ignored.
@@ -63,6 +65,9 @@ class SASLAuth(object):
63
65
  "security.protocol": "SASL_SSL",
64
66
  "ssl.ca.location": ssl_cert,
65
67
  }
68
+ if "ssl_endpoint_identification_algorithm" in kwargs:
69
+ self._config["ssl.endpoint.identification.algorithm"] = \
70
+ kwargs["ssl_endpoint_identification_algorithm"]
66
71
  else:
67
72
  self._config = {"security.protocol": "SASL_PLAINTEXT"}
68
73
 
@@ -38,7 +38,8 @@ class Consumer:
38
38
  self.logger = logging.getLogger("adc-streaming.consumer")
39
39
  self.conf = conf
40
40
  self._consumer = confluent_kafka.Consumer(conf._to_confluent_kafka())
41
- # Workaround for https://github.com/confluentinc/librdkafka/issues/3753#issuecomment-1058272987.
41
+ # Workaround for
42
+ # https://github.com/confluentinc/librdkafka/issues/3753#issuecomment-1058272987.
42
43
  # FIXME: Remove once fixed upstream, or on removal of oauth_cb.
43
44
  self._consumer.poll(0)
44
45
  self._stop_event = threading.Event()
@@ -196,7 +197,7 @@ class Consumer:
196
197
  self.mark_done(m, asynchronous=True)
197
198
  yield m
198
199
  else:
199
- raise(confluent_kafka.KafkaException(err))
200
+ raise (confluent_kafka.KafkaException(err))
200
201
  finally:
201
202
  if autocommit:
202
203
  self._consumer.commit(asynchronous=True)
@@ -242,7 +243,7 @@ class Consumer:
242
243
  # Done with all partitions for the topic, remove it
243
244
  del active_partitions[m.topic()]
244
245
  else:
245
- raise(confluent_kafka.KafkaException(err))
246
+ raise (confluent_kafka.KafkaException(err))
246
247
  finally:
247
248
  if autocommit:
248
249
  self._consumer.commit(asynchronous=True)
@@ -27,7 +27,8 @@ class Producer:
27
27
  self.conf = conf
28
28
  self.logger.debug(f"connecting to producer with config {conf._to_confluent_kafka()}")
29
29
  self._producer = confluent_kafka.Producer(conf._to_confluent_kafka())
30
- # Workaround for https://github.com/confluentinc/librdkafka/issues/3753#issuecomment-1058272987.
30
+ # Workaround for
31
+ # https://github.com/confluentinc/librdkafka/issues/3753#issuecomment-1058272987.
31
32
  # FIXME: Remove once fixed upstream, or on removal of oauth_cb.
32
33
  self._producer.poll(0)
33
34
 
@@ -35,7 +36,8 @@ class Producer:
35
36
  msg: Union[bytes, 'Serializable'],
36
37
  headers: Optional[Union[dict, list]] = None,
37
38
  delivery_callback: Optional[DeliveryCallback] = log_delivery_errors,
38
- topic: Optional[str] = None) -> None:
39
+ topic: Optional[str] = None,
40
+ key: Optional[Union[str, bytes]] = None) -> None:
39
41
  if isinstance(msg, Serializable):
40
42
  msg = msg.serialize()
41
43
  if topic is None:
@@ -47,10 +49,10 @@ class Producer:
47
49
  "or specify the topic argument to write()")
48
50
  self.logger.debug("writing message to %s", topic)
49
51
  if delivery_callback is not None:
50
- self._producer.produce(topic, msg, headers=headers,
52
+ self._producer.produce(topic, msg, headers=headers, key=key,
51
53
  on_delivery=delivery_callback)
52
54
  else:
53
- self._producer.produce(topic, msg, headers=headers)
55
+ self._producer.produce(topic, msg, headers=headers, key=key,)
54
56
 
55
57
  def flush(self, timeout: timedelta = timedelta(seconds=10)) -> int:
56
58
  """Attempt to flush enqueued messages. Return the number of messages still
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: adc-streaming
3
- Version: 2.4.0
3
+ Version: 2.5.0
4
4
  Summary: Astronomy Data Commons streaming client libraries
5
5
  Home-page: https://github.com/astronomy-commons/adc-streaming
6
6
  Author: Astronomy Data Commons Team
@@ -1,6 +1,6 @@
1
1
  import pytest
2
2
 
3
- from adc.auth import SASLAuth, SASLMethod
3
+ from adc.auth import SASLAuth
4
4
 
5
5
 
6
6
  @pytest.mark.parametrize('auth,expected_config', [
@@ -2,8 +2,8 @@ import logging
2
2
  import tempfile
3
3
  import time
4
4
  import unittest
5
- from datetime import datetime, timedelta, timezone
6
- from typing import List
5
+ from datetime import datetime, timedelta
6
+ from typing import List, Optional
7
7
 
8
8
  import docker
9
9
  import pytest
@@ -59,6 +59,31 @@ class KafkaIntegrationTestCase(unittest.TestCase):
59
59
  self.assertEqual(msg.topic(), topic)
60
60
  self.assertEqual(msg.value(), b"can you hear me?")
61
61
 
62
+ def test_message_with_key(self):
63
+ """Try writing a message into the Kafka broker, and try pulling the same
64
+ message back out.
65
+
66
+ """
67
+ topic = "test_message_with_key"
68
+ # Push one message in...
69
+ simple_write_msg(self.kafka, topic, "can you hear me?", key="test_msg")
70
+ # ... and pull it back out.
71
+ consumer = adc.consumer.Consumer(adc.consumer.ConsumerConfig(
72
+ broker_urls=[self.kafka.address],
73
+ group_id="test_consumer",
74
+ auth=self.kafka.auth,
75
+ ))
76
+ consumer.subscribe(topic)
77
+ stream = consumer.stream()
78
+
79
+ msg = next(stream)
80
+ if msg.error() is not None:
81
+ raise Exception(msg.error())
82
+
83
+ self.assertEqual(msg.topic(), topic)
84
+ self.assertEqual(msg.value(), b"can you hear me?")
85
+ self.assertEqual(msg.key(), b"test_msg")
86
+
62
87
  def test_reset_to_end(self):
63
88
  # Write a few messages.
64
89
  topic = "test_reset_to_end"
@@ -283,7 +308,7 @@ class KafkaIntegrationTestCase(unittest.TestCase):
283
308
  "message 1",
284
309
  "message 2",
285
310
  "message 3",
286
- ])
311
+ ])
287
312
  # Wait a while, write, and wait some more
288
313
  time.sleep(2)
289
314
  client_middle_time = datetime.now()
@@ -390,8 +415,8 @@ class KafkaIntegrationTestCase(unittest.TestCase):
390
415
  topic=None,
391
416
  auth=self.kafka.auth,
392
417
  ))
393
- for i in range(0,8):
394
- producer.write(str(i), topic=topics[i%2])
418
+ for i in range(0, 8):
419
+ producer.write(str(i), topic=topics[i % 2])
395
420
  producer.flush()
396
421
  logger.info("messages sent")
397
422
 
@@ -403,12 +428,12 @@ class KafkaIntegrationTestCase(unittest.TestCase):
403
428
  ))
404
429
  consumer.subscribe(topics)
405
430
  stream = consumer.stream()
406
- total_messages = 0;
431
+ total_messages = 0
407
432
  for msg in stream:
408
433
  if msg.error() is not None:
409
434
  raise Exception(msg.error())
410
435
  idx = int(msg.value())
411
- self.assertEqual(msg.topic(), topics[idx%2])
436
+ self.assertEqual(msg.topic(), topics[idx % 2])
412
437
  total_messages += 1
413
438
  if total_messages == 8:
414
439
  break
@@ -451,6 +476,10 @@ class KafkaDockerConnection:
451
476
  self.auth = adc.auth.SASLAuth(
452
477
  user="test", password="test-pass",
453
478
  ssl_ca_location=self.certfile.name,
479
+ # disable endpoint verification because the docker service generates a certificate with
480
+ # a useless subject (the container ID) which can never match the hostname used to
481
+ # connect (typically 0.0.0.0)
482
+ ssl_endpoint_identification_algorithm="none",
454
483
  )
455
484
 
456
485
  def poll_for_kafka_broker_address(self, maxiter=20, sleep=timedelta(milliseconds=500)):
@@ -550,7 +579,7 @@ class KafkaDockerConnection:
550
579
  # these tests cannot run if there is already an instance of Kafka running on
551
580
  # the same host.
552
581
  ports={"9092/tcp": 9092},
553
- command=["/root/runServer","--advertisedListener","SASL_SSL://localhost:9092"],
582
+ command=["/root/runServer", "--advertisedListener", "SASL_SSL://localhost:9092"],
554
583
  )
555
584
 
556
585
  def get_or_create_docker_network(self):
@@ -565,13 +594,13 @@ class KafkaDockerConnection:
565
594
  return self.docker_client.networks.create(name="adc-integration-test")
566
595
 
567
596
 
568
- def simple_write_msg(conn: KafkaDockerConnection, topic: str, msg: str):
597
+ def simple_write_msg(conn: KafkaDockerConnection, topic: str, msg: str, key: Optional[str] = None):
569
598
  producer = adc.producer.Producer(adc.producer.ProducerConfig(
570
599
  broker_urls=[conn.address],
571
600
  topic=topic,
572
601
  auth=conn.auth,
573
602
  ))
574
- producer.write(msg)
603
+ producer.write(msg, key=key)
575
604
  producer.flush()
576
605
 
577
606
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes