mccode-plumber 0.14.0__py3-none-any.whl → 0.14.1__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.
@@ -121,31 +121,31 @@ def start_writer(start_time: datetime,
121
121
  return job_id, success
122
122
 
123
123
 
124
- def get_topics_iter(data: list | tuple):
124
+ def get_stream_pairs_list(data: list | tuple):
125
125
  topics = set()
126
126
  for entry in data:
127
127
  if isinstance(entry, dict):
128
- topics.update(get_topics_dict(entry))
128
+ topics.update(get_stream_pairs_dict(entry))
129
129
  elif isinstance(entry, (list, tuple)):
130
- topics.update(get_topics_iter(entry))
130
+ topics.update(get_stream_pairs_list(entry))
131
131
  return topics
132
132
 
133
133
 
134
- def get_topics_dict(data: dict):
134
+ def get_stream_pairs_dict(data: dict):
135
135
  topics = set()
136
+ if all(k in data for k in ('topic', 'source')):
137
+ topics.add((data['topic'], data['source']))
136
138
  for k, v in data.items():
137
139
  if isinstance(v, dict):
138
- topics.update(get_topics_dict(v))
140
+ topics.update(get_stream_pairs_dict(v))
139
141
  elif isinstance(v, (list, tuple)):
140
- topics.update(get_topics_iter(list(v)))
141
- elif k == 'topic':
142
- topics.add(v)
142
+ topics.update(get_stream_pairs_list(list(v)))
143
143
  return topics
144
144
 
145
145
 
146
- def get_topics_json(data: dict) -> list[str]:
147
- """Traverse a loaded JSON object and return the found list of topic names"""
148
- return list(get_topics_dict(data))
146
+ def get_stream_pairs(data: dict) -> list[tuple[str, str]]:
147
+ """Traverse a loaded JSON object and return the found list of (topic, source) pairs."""
148
+ return list(get_stream_pairs_dict(data))
149
149
 
150
150
 
151
151
  def load_file_json(file: str | Path):
@@ -360,16 +360,22 @@ def main():
360
360
  instr = get_mcstas_instr(args.instrument)
361
361
 
362
362
  structure = load_file_json(args.structure if args.structure else Path(args.instrument).with_suffix('.json'))
363
+
364
+ streams = get_stream_pairs(structure)
365
+ # All monitors should use a single topic:
366
+ monitor_topic = f'{instr.name}_beam_monitor'
367
+ if {monitor_topic} != {s[0] for s in streams}:
368
+ raise ValueError(f'All monitor streams must use the same topic {monitor_topic}, found {streams}')
369
+ monitor_names = [s[1] for s in streams]
370
+
363
371
  broker = 'localhost:9092'
364
- monitor_source = 'mccode-to-kafka'
365
- callback_topics = get_topics_json(structure) # all structure-topics might be monitor topics?
366
- if len(callback_topics):
367
- print(f'register {callback_topics}')
368
- register_topics(broker, callback_topics) # ensure the topics are known to Kafka
369
- else:
370
- print('no callback topics registered')
372
+ # monitor_source = 'mccode-to-kafka' # old-style single source multi-topic
373
+ register_topics(broker, [monitor_topic]) # ensure the topics are known to Kafka
371
374
 
372
- callback, callback_args = monitors_to_kafka_callback_with_arguments(broker, monitor_source, callback_topics)
375
+ # Configure the callback to send monitor data to Kafka, using the common topic with source names as monitor names
376
+ callback, callback_args = monitors_to_kafka_callback_with_arguments(
377
+ broker=broker, topic=monitor_topic, source=None, names=monitor_names
378
+ )
373
379
  splitrun_kwargs = {
374
380
  'args': args, 'parameters': parameters, 'precision': precision,
375
381
  'callback': callback, 'callback_arguments': callback_args,
@@ -5,17 +5,27 @@ def make_parser():
5
5
  parser.prog = 'mp-splitrun'
6
6
  parser.add_argument('--broker', type=str, help='The Kafka broker to send monitors to', default=None)
7
7
  parser.add_argument('--source', type=str, help='The Kafka source name to use for monitors', default=None)
8
- parser.add_argument('--topic', type=str, help='The Kafka topic name(s) to use for monitors', default=None, action='append')
8
+ parser.add_argument('--topic', type=str, help='The Kafka topic name to use for monitors', default=None)
9
+ parser.add_argument('--names', type=str, help='The monitor name(s) to send to Kafka', default=None, action='append')
9
10
  parser.add_argument('-v', '--version', action='version', version=__version__)
10
11
  return parser
11
12
 
12
13
 
13
- def monitors_to_kafka_callback_with_arguments(broker: str, source: str, topics: list[str]):
14
+ def monitors_to_kafka_callback_with_arguments(
15
+ broker: str, topic: str | None, source: str | None, names: list[str] | None
16
+ ):
14
17
  from mccode_to_kafka.sender import send_histograms
15
18
 
16
- partial_kwargs = {'broker': broker, 'source': source}
17
- if topics is not None and len(topics) > 0:
18
- partial_kwargs['names'] = topics
19
+ partial_kwargs = {'broker': broker}
20
+ if topic is not None and source is not None and names is not None and len(names) > 1:
21
+ raise ValueError("Cannot specify both topic/source and multiple names simultaneously.")
22
+
23
+ if topic is not None:
24
+ partial_kwargs['topic'] = topic
25
+ if source is not None:
26
+ partial_kwargs['source'] = source
27
+ if names is not None and len(names) > 0:
28
+ partial_kwargs['names'] = names
19
29
 
20
30
  def callback(*args, **kwargs):
21
31
  return send_histograms(*args, **partial_kwargs, **kwargs)
@@ -28,5 +38,5 @@ def main():
28
38
  from restage.splitrun import splitrun_args, parse_splitrun
29
39
  args, parameters, precision = parse_splitrun(make_parser())
30
40
  instr = get_mcstas_instr(args.instrument)
31
- callback, callback_args = monitors_to_kafka_callback_with_arguments(args.broker, args.source, args.topic)
41
+ callback, callback_args = monitors_to_kafka_callback_with_arguments(args.broker, args.topic, args.source, args.names)
32
42
  return splitrun_args(instr, parameters, precision, args, callback=callback, callback_arguments=callback_args)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mccode-plumber
3
- Version: 0.14.0
3
+ Version: 0.14.1
4
4
  Author-email: Gregory Tucker <gregory.tucker@ess.eu>
5
5
  Classifier: License :: OSI Approved :: BSD License
6
6
  Description-Content-Type: text/markdown
@@ -8,8 +8,8 @@ Requires-Dist: p4p
8
8
  Requires-Dist: kafka-python>=2.2.11
9
9
  Requires-Dist: ess-streaming-data-types>=0.14.0
10
10
  Requires-Dist: restage>=0.9.0
11
- Requires-Dist: mccode-to-kafka>=0.2.2
12
- Requires-Dist: moreniius>=0.6.0
11
+ Requires-Dist: mccode-to-kafka>=0.3.0
12
+ Requires-Dist: moreniius>=0.6.1
13
13
  Requires-Dist: icecream
14
14
  Requires-Dist: ephemeral-port-reserve
15
15
 
@@ -5,7 +5,7 @@ mccode_plumber/epics_watcher.py,sha256=Jiz761A5NfoUzJ6ZzBGg8_BewFTmHDo5qYgh_DZHx
5
5
  mccode_plumber/forwarder.py,sha256=yzjb--r8M6vNSsWvvOi5IjXqpRn8MvT13cv89ezNEeU,3994
6
6
  mccode_plumber/kafka.py,sha256=Q3oAuk7c-PS7b7zWSDhOR3dOO8R6Q8Y3HPI7K-Kt-RU,2499
7
7
  mccode_plumber/mccode.py,sha256=vc4Gb5WhdOfuDRjEejU3Flps0C2A60sfFbMrxmKLhn0,2189
8
- mccode_plumber/splitrun.py,sha256=xL8k99NGRcU7tMCfdJCuj2a0-MvOZ7cPa6J11ACqpOA,1515
8
+ mccode_plumber/splitrun.py,sha256=K5VetcWpw8Aa-4d2BQLyshkwXkiVdzzJRB1mr2eNyP0,1971
9
9
  mccode_plumber/utils.py,sha256=E8NoGo_3Z-pPEpzicVGSWfQOX8p3eR-GxElT33-kX5U,2167
10
10
  mccode_plumber/writer.py,sha256=YN2I_gvoXn8XkHX_BVbdvCGhJC1aWbwU9VtiYFrcGS0,21185
11
11
  mccode_plumber/file_writer_control/CommandChannel.py,sha256=U32mvk8Ctlw8vg38_ULP__-UAG2funWIkhEFo2xahiY,9024
@@ -27,10 +27,10 @@ mccode_plumber/manage/ensure.py,sha256=0HaxcHYzvcDs6hBvBI39EZsIDt_rVA9CjHm5_yvOZ
27
27
  mccode_plumber/manage/epics.py,sha256=oQt_hL-7KgtI9Kmwyw8L7a7RxQe7YJWRbmHnKIqMLpQ,1310
28
28
  mccode_plumber/manage/forwarder.py,sha256=YYvHaOJ4djBXM7PFF2NBbnNDO6nnrwNOfSHaVOh16Ro,2876
29
29
  mccode_plumber/manage/manager.py,sha256=zzrduroUL-jwQ9BrPTdAm1IW4dGv5bi8-ieIQ6qiQ6M,4141
30
- mccode_plumber/manage/orchestrate.py,sha256=bumvHN6jPEOqd8V96f7gEmc5IpWOZ6mSo7_bosi3jY8,17662
30
+ mccode_plumber/manage/orchestrate.py,sha256=rd6tSAyqT6B0gqj4uXtk0o6plaoVfisCy1xrmlymlXk,18088
31
31
  mccode_plumber/manage/writer.py,sha256=SEv1U14L01Y9-BcaJKPei4Ah2LFfwexDy9FTjpvtSEs,2245
32
- mccode_plumber-0.14.0.dist-info/METADATA,sha256=tceaL7T1Li53p4HVOLaUOpKgvrEx12o8Npoqui_LgDY,594
33
- mccode_plumber-0.14.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
- mccode_plumber-0.14.0.dist-info/entry_points.txt,sha256=k3LDo_9HG2v4-IgMYlNukphdMmaAT6zkJZYaB1zJh3c,900
35
- mccode_plumber-0.14.0.dist-info/top_level.txt,sha256=kCCIpYtKHCKWxiPEqX9J1UaGEm-ze0Qb-cemBCEPhDA,15
36
- mccode_plumber-0.14.0.dist-info/RECORD,,
32
+ mccode_plumber-0.14.1.dist-info/METADATA,sha256=BbSQyG3UF1fPgzVR6XbfwB9hqicfaqYtSw8aoxC0Bic,594
33
+ mccode_plumber-0.14.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
+ mccode_plumber-0.14.1.dist-info/entry_points.txt,sha256=k3LDo_9HG2v4-IgMYlNukphdMmaAT6zkJZYaB1zJh3c,900
35
+ mccode_plumber-0.14.1.dist-info/top_level.txt,sha256=kCCIpYtKHCKWxiPEqX9J1UaGEm-ze0Qb-cemBCEPhDA,15
36
+ mccode_plumber-0.14.1.dist-info/RECORD,,