trustgraph-base 0.22.6__tar.gz → 0.22.7__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 (87) hide show
  1. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/PKG-INFO +2 -2
  2. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/api/api.py +230 -0
  3. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/async_processor.py +15 -12
  4. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/consumer.py +1 -1
  5. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/consumer_spec.py +2 -2
  6. trustgraph-base-0.22.7/trustgraph/base/metrics.py +136 -0
  7. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/producer_spec.py +2 -2
  8. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/request_response_spec.py +11 -6
  9. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/subscriber.py +17 -1
  10. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/subscriber_spec.py +5 -5
  11. trustgraph-base-0.22.7/trustgraph/base_version.py +1 -0
  12. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/__init__.py +1 -1
  13. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/flows.py +4 -4
  14. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/graph.py +0 -19
  15. trustgraph-base-0.22.7/trustgraph/schema/lookup.py +21 -0
  16. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/models.py +0 -13
  17. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/object.py +1 -3
  18. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/prompt.py +0 -7
  19. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/retrieval.py +0 -13
  20. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph_base.egg-info/PKG-INFO +2 -2
  21. trustgraph-base-0.22.6/trustgraph/base/metrics.py +0 -82
  22. trustgraph-base-0.22.6/trustgraph/base_version.py +0 -1
  23. trustgraph-base-0.22.6/trustgraph/schema/lookup.py +0 -42
  24. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/README.md +0 -0
  25. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/setup.cfg +0 -0
  26. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/setup.py +0 -0
  27. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/api/__init__.py +0 -0
  28. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/__init__.py +0 -0
  29. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/agent_client.py +0 -0
  30. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/agent_service.py +0 -0
  31. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/document_embeddings_client.py +0 -0
  32. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/document_embeddings_query_service.py +0 -0
  33. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/document_embeddings_store_service.py +0 -0
  34. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/embeddings_client.py +0 -0
  35. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/embeddings_service.py +0 -0
  36. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/flow.py +0 -0
  37. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/flow_processor.py +0 -0
  38. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/graph_embeddings_client.py +0 -0
  39. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/graph_embeddings_query_service.py +0 -0
  40. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/graph_embeddings_store_service.py +0 -0
  41. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/graph_rag_client.py +0 -0
  42. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/llm_service.py +0 -0
  43. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/producer.py +0 -0
  44. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/prompt_client.py +0 -0
  45. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/publisher.py +0 -0
  46. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/pubsub.py +0 -0
  47. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/setting_spec.py +0 -0
  48. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/spec.py +0 -0
  49. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/text_completion_client.py +0 -0
  50. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/triples_client.py +0 -0
  51. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/triples_query_service.py +0 -0
  52. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/base/triples_store_service.py +0 -0
  53. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/__init__.py +0 -0
  54. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/agent_client.py +0 -0
  55. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/base.py +0 -0
  56. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/config_client.py +0 -0
  57. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/document_embeddings_client.py +0 -0
  58. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/document_rag_client.py +0 -0
  59. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/embeddings_client.py +0 -0
  60. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/graph_embeddings_client.py +0 -0
  61. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/graph_rag_client.py +0 -0
  62. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/llm_client.py +0 -0
  63. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/prompt_client.py +0 -0
  64. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/clients/triples_query_client.py +0 -0
  65. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/exceptions.py +0 -0
  66. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/knowledge/__init__.py +0 -0
  67. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/knowledge/defs.py +0 -0
  68. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/knowledge/document.py +0 -0
  69. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/knowledge/identifier.py +0 -0
  70. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/knowledge/organization.py +0 -0
  71. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/knowledge/publication.py +0 -0
  72. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/log_level.py +0 -0
  73. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/objects/__init__.py +0 -0
  74. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/objects/field.py +0 -0
  75. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/objects/object.py +0 -0
  76. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/rdf.py +0 -0
  77. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/agent.py +0 -0
  78. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/config.py +0 -0
  79. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/documents.py +0 -0
  80. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/library.py +0 -0
  81. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/metadata.py +0 -0
  82. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/topic.py +0 -0
  83. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph/schema/types.py +0 -0
  84. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph_base.egg-info/SOURCES.txt +0 -0
  85. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph_base.egg-info/dependency_links.txt +0 -0
  86. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph_base.egg-info/requires.txt +0 -0
  87. {trustgraph-base-0.22.6 → trustgraph-base-0.22.7}/trustgraph_base.egg-info/top_level.txt +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trustgraph-base
3
- Version: 0.22.6
3
+ Version: 0.22.7
4
4
  Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
5
5
  Home-page: https://github.com/trustgraph-ai/trustgraph
6
- Download-URL: https://github.com/trustgraph-ai/trustgraph/archive/refs/tags/v0.22.6.tar.gz
6
+ Download-URL: https://github.com/trustgraph-ai/trustgraph/archive/refs/tags/v0.22.7.tar.gz
7
7
  Author: trustgraph.ai
8
8
  Author-email: security@trustgraph.ai
9
9
  Classifier: Programming Language :: Python :: 3
@@ -562,3 +562,233 @@ class Api:
562
562
  except:
563
563
  raise ProtocolException(f"Response not formatted correctly")
564
564
 
565
+ def flow_list_classes(self):
566
+
567
+ # The input consists of system and prompt strings
568
+ input = {
569
+ "operation": "list-classes",
570
+ }
571
+
572
+ url = f"{self.url}flow"
573
+
574
+ # Invoke the API, input is passed as JSON
575
+ resp = requests.post(url, json=input)
576
+
577
+ # Should be a 200 status code
578
+ if resp.status_code != 200:
579
+ raise ProtocolException(f"Status code {resp.status_code}")
580
+
581
+ try:
582
+ # Parse the response as JSON
583
+ object = resp.json()
584
+ except:
585
+ raise ProtocolException(f"Expected JSON response")
586
+
587
+ self.check_error(object)
588
+
589
+ try:
590
+ return object["class-names"]
591
+ except:
592
+ raise ProtocolException(f"Response not formatted correctly")
593
+
594
+ def flow_get_class(self, class_name):
595
+
596
+ # The input consists of system and prompt strings
597
+ input = {
598
+ "operation": "get-class",
599
+ "class-name": class_name,
600
+ }
601
+
602
+ url = f"{self.url}flow"
603
+
604
+ # Invoke the API, input is passed as JSON
605
+ resp = requests.post(url, json=input)
606
+
607
+ # Should be a 200 status code
608
+ if resp.status_code != 200:
609
+ raise ProtocolException(f"Status code {resp.status_code}")
610
+
611
+ try:
612
+ # Parse the response as JSON
613
+ object = resp.json()
614
+ except:
615
+ raise ProtocolException(f"Expected JSON response")
616
+
617
+ self.check_error(object)
618
+
619
+ try:
620
+ return json.loads(object["class-definition"])
621
+ except Exception as e:
622
+ print(e)
623
+ raise ProtocolException(f"Response not formatted correctly")
624
+
625
+ def flow_put_class(self, class_name, definition):
626
+
627
+ # The input consists of system and prompt strings
628
+ input = {
629
+ "operation": "put-class",
630
+ "class-name": class_name,
631
+ "class-definition": json.dumps(definition),
632
+ }
633
+
634
+ url = f"{self.url}flow"
635
+
636
+ # Invoke the API, input is passed as JSON
637
+ resp = requests.post(url, json=input)
638
+
639
+ # Should be a 200 status code
640
+ if resp.status_code != 200:
641
+ raise ProtocolException(f"Status code {resp.status_code}")
642
+
643
+ try:
644
+ # Parse the response as JSON
645
+ object = resp.json()
646
+ except:
647
+ raise ProtocolException(f"Expected JSON response")
648
+
649
+ self.check_error(object)
650
+
651
+ return
652
+
653
+ def flow_delete_class(self, class_name):
654
+
655
+ # The input consists of system and prompt strings
656
+ input = {
657
+ "operation": "delete-class",
658
+ "class-name": class_name,
659
+ }
660
+
661
+ url = f"{self.url}flow"
662
+
663
+ # Invoke the API, input is passed as JSON
664
+ resp = requests.post(url, json=input)
665
+
666
+ # Should be a 200 status code
667
+ if resp.status_code != 200:
668
+ raise ProtocolException(f"Status code {resp.status_code}")
669
+
670
+ try:
671
+ # Parse the response as JSON
672
+ object = resp.json()
673
+ except:
674
+ raise ProtocolException(f"Expected JSON response")
675
+
676
+ self.check_error(object)
677
+
678
+ return
679
+
680
+ def flow_list(self):
681
+
682
+ # The input consists of system and prompt strings
683
+ input = {
684
+ "operation": "list-flows",
685
+ }
686
+
687
+ url = f"{self.url}flow"
688
+
689
+ # Invoke the API, input is passed as JSON
690
+ resp = requests.post(url, json=input)
691
+
692
+ # Should be a 200 status code
693
+ if resp.status_code != 200:
694
+ raise ProtocolException(f"Status code {resp.status_code}")
695
+
696
+ try:
697
+ # Parse the response as JSON
698
+ object = resp.json()
699
+ except:
700
+ raise ProtocolException(f"Expected JSON response")
701
+
702
+ self.check_error(object)
703
+
704
+ try:
705
+ return object["flow-ids"]
706
+ except:
707
+ raise ProtocolException(f"Response not formatted correctly")
708
+
709
+ def flow_get(self, id):
710
+
711
+ # The input consists of system and prompt strings
712
+ input = {
713
+ "operation": "get-flow",
714
+ "flow-id": id,
715
+ }
716
+
717
+ url = f"{self.url}flow"
718
+
719
+ # Invoke the API, input is passed as JSON
720
+ resp = requests.post(url, json=input)
721
+
722
+ # Should be a 200 status code
723
+ if resp.status_code != 200:
724
+ raise ProtocolException(f"Status code {resp.status_code}")
725
+
726
+ try:
727
+ # Parse the response as JSON
728
+ object = resp.json()
729
+ except:
730
+ raise ProtocolException(f"Expected JSON response")
731
+
732
+ self.check_error(object)
733
+
734
+ try:
735
+ return json.loads(object["flow"])
736
+ except:
737
+ raise ProtocolException(f"Response not formatted correctly")
738
+
739
+ def flow_start(self, class_name, id, description):
740
+
741
+ # The input consists of system and prompt strings
742
+ input = {
743
+ "operation": "start-flow",
744
+ "flow-id": id,
745
+ "class-name": class_name,
746
+ "description": description,
747
+ }
748
+
749
+ url = f"{self.url}flow"
750
+
751
+ # Invoke the API, input is passed as JSON
752
+ resp = requests.post(url, json=input)
753
+
754
+ # Should be a 200 status code
755
+ if resp.status_code != 200:
756
+ raise ProtocolException(f"Status code {resp.status_code}")
757
+
758
+ try:
759
+ # Parse the response as JSON
760
+ object = resp.json()
761
+ except:
762
+ raise ProtocolException(f"Expected JSON response")
763
+
764
+ self.check_error(object)
765
+
766
+ return
767
+
768
+ def flow_stop(self, id):
769
+
770
+ # The input consists of system and prompt strings
771
+ input = {
772
+ "operation": "stop-flow",
773
+ "flow-id": id,
774
+ }
775
+
776
+ url = f"{self.url}flow"
777
+
778
+ # Invoke the API, input is passed as JSON
779
+ resp = requests.post(url, json=input)
780
+
781
+ # Should be a 200 status code
782
+ if resp.status_code != 200:
783
+ raise ProtocolException(f"Status code {resp.status_code}")
784
+
785
+ try:
786
+ # Parse the response as JSON
787
+ object = resp.json()
788
+ except:
789
+ raise ProtocolException(f"Expected JSON response")
790
+
791
+ self.check_error(object)
792
+
793
+ return
794
+
@@ -17,7 +17,7 @@ from .. exceptions import TooManyRequests
17
17
  from . pubsub import PulsarClient
18
18
  from . producer import Producer
19
19
  from . consumer import Consumer
20
- from . metrics import ProcessorMetrics
20
+ from . metrics import ProcessorMetrics, ConsumerMetrics
21
21
 
22
22
  default_config_queue = config_push_queue
23
23
 
@@ -30,10 +30,10 @@ class AsyncProcessor:
30
30
  self.id = params.get("id")
31
31
 
32
32
  # Register a pulsar client
33
- self.pulsar_client = PulsarClient(**params)
33
+ self.pulsar_client_object = PulsarClient(**params)
34
34
 
35
35
  # Initialise metrics, records the parameters
36
- ProcessorMetrics(id=self.id).info({
36
+ ProcessorMetrics(processor = self.id).info({
37
37
  k: str(params[k])
38
38
  for k in params
39
39
  if k != "id"
@@ -57,11 +57,15 @@ class AsyncProcessor:
57
57
  # service
58
58
  config_subscriber_id = str(uuid.uuid4())
59
59
 
60
+ config_consumer_metrics = ConsumerMetrics(
61
+ processor = self.id, flow = None, name = "config",
62
+ )
63
+
60
64
  # Subscribe to config queue
61
65
  self.config_sub_task = Consumer(
62
66
 
63
67
  taskgroup = self.taskgroup,
64
- client = self.client,
68
+ client = self.pulsar_client,
65
69
  subscriber = config_subscriber_id,
66
70
  flow = None,
67
71
 
@@ -70,6 +74,8 @@ class AsyncProcessor:
70
74
 
71
75
  handler = self.on_config_change,
72
76
 
77
+ metrics = config_consumer_metrics,
78
+
73
79
  # This causes new subscriptions to view the entire history of
74
80
  # configuration
75
81
  start_of_messages = True
@@ -85,31 +91,28 @@ class AsyncProcessor:
85
91
  # This is called to stop all threads. An over-ride point for extra
86
92
  # functionality
87
93
  def stop(self):
88
- self.client.close()
94
+ self.pulsar_client.close()
89
95
  self.running = False
90
96
 
91
97
  # Returns the pulsar host
92
98
  @property
93
- def pulsar_host(self): return self.client.pulsar_host
99
+ def pulsar_host(self): return self.pulsar_client_object.pulsar_host
94
100
 
95
101
  # Returns the pulsar client
96
102
  @property
97
- def client(self): return self.pulsar_client.client
103
+ def pulsar_client(self): return self.pulsar_client_object.client
98
104
 
99
105
  # Register a new event handler for configuration change
100
106
  def register_config_handler(self, handler):
101
107
  self.config_handlers.append(handler)
102
108
 
103
109
  # Called when a new configuration message push occurs
104
- async def on_config_change(self, message, consumer):
110
+ async def on_config_change(self, message, consumer, flow):
105
111
 
106
112
  # Get configuration data and version number
107
113
  config = message.value().config
108
114
  version = message.value().version
109
115
 
110
- # Acknowledge the message
111
- consumer.acknowledge(message)
112
-
113
116
  # Invoke message handlers
114
117
  print("Config change event", config, version, flush=True)
115
118
  for ch in self.config_handlers:
@@ -234,7 +237,7 @@ class AsyncProcessor:
234
237
  PulsarClient.add_args(parser)
235
238
 
236
239
  parser.add_argument(
237
- '--config-push-queue',
240
+ '--config-queue',
238
241
  default=default_config_queue,
239
242
  help=f'Config push queue {default_config_queue}',
240
243
  )
@@ -156,7 +156,7 @@ class Consumer:
156
156
  await self.handler(msg, self, self.flow)
157
157
 
158
158
  else:
159
- await self.handler(msg, self.consumer)
159
+ await self.handler(msg, self, self.flow)
160
160
 
161
161
  print("Handled.", flush=True)
162
162
 
@@ -12,13 +12,13 @@ class ConsumerSpec(Spec):
12
12
  def add(self, flow, processor, definition):
13
13
 
14
14
  consumer_metrics = ConsumerMetrics(
15
- flow.id, f"{flow.name}-{self.name}"
15
+ processor = flow.id, flow = flow.name, name = self.name,
16
16
  )
17
17
 
18
18
  consumer = Consumer(
19
19
  taskgroup = processor.taskgroup,
20
20
  flow = flow,
21
- client = processor.client,
21
+ client = processor.pulsar_client,
22
22
  topic = definition[self.name],
23
23
  subscriber = processor.id + "--" + self.name,
24
24
  schema = self.schema,
@@ -0,0 +1,136 @@
1
+
2
+ from prometheus_client import start_http_server, Info, Enum, Histogram
3
+ from prometheus_client import Counter
4
+
5
+ class ConsumerMetrics:
6
+
7
+ def __init__(self, processor, flow, name):
8
+
9
+ self.processor = processor
10
+ self.flow = flow
11
+ self.name = name
12
+
13
+ if not hasattr(__class__, "state_metric"):
14
+ __class__.state_metric = Enum(
15
+ 'consumer_state', 'Consumer state',
16
+ ["processor", "flow", "name"],
17
+ states=['stopped', 'running']
18
+ )
19
+
20
+ if not hasattr(__class__, "request_metric"):
21
+ __class__.request_metric = Histogram(
22
+ 'request_latency', 'Request latency (seconds)',
23
+ ["processor", "flow", "name"],
24
+ )
25
+
26
+ if not hasattr(__class__, "processing_metric"):
27
+ __class__.processing_metric = Counter(
28
+ 'processing_count', 'Processing count',
29
+ ["processor", "flow", "name", "status"],
30
+ )
31
+
32
+ if not hasattr(__class__, "rate_limit_metric"):
33
+ __class__.rate_limit_metric = Counter(
34
+ 'rate_limit_count', 'Rate limit event count',
35
+ ["processor", "flow", "name"],
36
+ )
37
+
38
+ def process(self, status):
39
+ __class__.processing_metric.labels(
40
+ processor = self.processor, flow = self.flow, name = self.name,
41
+ status=status
42
+ ).inc()
43
+
44
+ def rate_limit(self):
45
+ __class__.rate_limit_metric.labels(
46
+ processor = self.processor, flow = self.flow, name = self.name,
47
+ ).inc()
48
+
49
+ def state(self, state):
50
+ __class__.state_metric.labels(
51
+ processor = self.processor, flow = self.flow, name = self.name,
52
+ ).state(state)
53
+
54
+ def record_time(self):
55
+ return __class__.request_metric.labels(
56
+ processor = self.processor, flow = self.flow, name = self.name,
57
+ ).time()
58
+
59
+ class ProducerMetrics:
60
+
61
+ def __init__(self, processor, flow, name):
62
+
63
+ self.processor = processor
64
+ self.flow = flow
65
+ self.name = name
66
+
67
+ if not hasattr(__class__, "producer_metric"):
68
+ __class__.producer_metric = Counter(
69
+ 'producer_count', 'Output items produced',
70
+ ["processor", "flow", "name"],
71
+ )
72
+
73
+ def inc(self):
74
+ __class__.producer_metric.labels(
75
+ processor = self.processor, flow = self.flow, name = self.name
76
+ ).inc()
77
+
78
+ class ProcessorMetrics:
79
+ def __init__(self, processor):
80
+
81
+ self.processor = processor
82
+
83
+ if not hasattr(__class__, "processor_metric"):
84
+ __class__.processor_metric = Info(
85
+ 'processor', 'Processor configuration',
86
+ ["processor"]
87
+ )
88
+
89
+ def info(self, info):
90
+ __class__.processor_metric.labels(
91
+ processor = self.processor
92
+ ).info(info)
93
+
94
+ class SubscriberMetrics:
95
+
96
+ def __init__(self, processor, flow, name):
97
+
98
+ self.processor = processor
99
+ self.flow = flow
100
+ self.name = name
101
+
102
+ if not hasattr(__class__, "state_metric"):
103
+ __class__.state_metric = Enum(
104
+ 'subscriber_state', 'Subscriber state',
105
+ ["processor", "flow", "name"],
106
+ states=['stopped', 'running']
107
+ )
108
+
109
+ if not hasattr(__class__, "received_metric"):
110
+ __class__.received_metric = Counter(
111
+ 'received_count', 'Received count',
112
+ ["processor", "flow", "name"],
113
+ )
114
+
115
+ if not hasattr(__class__, "dropped_metric"):
116
+ __class__.dropped_metric = Counter(
117
+ 'dropped_count', 'Dropped messages count',
118
+ ["processor", "flow", "name"],
119
+ )
120
+
121
+ def received(self):
122
+ __class__.received_metric.labels(
123
+ processor = self.processor, flow = self.flow, name = self.name,
124
+ ).inc()
125
+
126
+ def state(self, state):
127
+
128
+ __class__.state_metric.labels(
129
+ processor = self.processor, flow = self.flow, name = self.name,
130
+ ).state(state)
131
+
132
+ def dropped(self, state):
133
+ __class__.dropped_metric.labels(
134
+ processor = self.processor, flow = self.flow, name = self.name,
135
+ ).inc()
136
+
@@ -11,11 +11,11 @@ class ProducerSpec(Spec):
11
11
  def add(self, flow, processor, definition):
12
12
 
13
13
  producer_metrics = ProducerMetrics(
14
- flow.id, f"{flow.name}-{self.name}"
14
+ processor = flow.id, flow = flow.name, name = self.name
15
15
  )
16
16
 
17
17
  producer = Producer(
18
- client = processor.client,
18
+ client = processor.pulsar_client,
19
19
  topic = definition[self.name],
20
20
  schema = self.schema,
21
21
  metrics = producer_metrics,
@@ -5,7 +5,7 @@ import asyncio
5
5
  from . subscriber import Subscriber
6
6
  from . producer import Producer
7
7
  from . spec import Spec
8
- from . metrics import ConsumerMetrics, ProducerMetrics
8
+ from . metrics import ConsumerMetrics, ProducerMetrics, SubscriberMetrics
9
9
 
10
10
  class RequestResponse(Subscriber):
11
11
 
@@ -23,6 +23,7 @@ class RequestResponse(Subscriber):
23
23
  consumer_name = consumer_name,
24
24
  topic = response_topic,
25
25
  schema = response_schema,
26
+ metrics = response_metrics,
26
27
  )
27
28
 
28
29
  self.producer = Producer(
@@ -116,20 +117,24 @@ class RequestResponseSpec(Spec):
116
117
 
117
118
  def add(self, flow, processor, definition):
118
119
 
119
- producer_metrics = ProducerMetrics(
120
- flow.id, f"{flow.name}-{self.response_name}"
120
+ request_metrics = ProducerMetrics(
121
+ processor = flow.id, flow = flow.name, name = self.request_name
122
+ )
123
+
124
+ response_metrics = SubscriberMetrics(
125
+ processor = flow.id, flow = flow.name, name = self.request_name
121
126
  )
122
127
 
123
128
  rr = self.impl(
124
- client = processor.client,
129
+ client = processor.pulsar_client,
125
130
  subscription = flow.id,
126
131
  consumer_name = flow.id,
127
132
  request_topic = definition[self.request_name],
128
133
  request_schema = self.request_schema,
129
- request_metrics = producer_metrics,
134
+ request_metrics = request_metrics,
130
135
  response_topic = definition[self.response_name],
131
136
  response_schema = self.response_schema,
132
- response_metrics = None,
137
+ response_metrics = response_metrics,
133
138
  )
134
139
 
135
140
  flow.consumer[self.request_name] = rr
@@ -7,7 +7,7 @@ import time
7
7
  class Subscriber:
8
8
 
9
9
  def __init__(self, client, topic, subscription, consumer_name,
10
- schema=None, max_size=100):
10
+ schema=None, max_size=100, metrics=None):
11
11
  self.client = client
12
12
  self.topic = topic
13
13
  self.subscription = subscription
@@ -18,6 +18,7 @@ class Subscriber:
18
18
  self.max_size = max_size
19
19
  self.lock = asyncio.Lock()
20
20
  self.running = True
21
+ self.metrics = metrics
21
22
 
22
23
  async def __del__(self):
23
24
  self.running = False
@@ -36,6 +37,9 @@ class Subscriber:
36
37
 
37
38
  while self.running:
38
39
 
40
+ if self.metrics:
41
+ self.metrics.state("stopped")
42
+
39
43
  try:
40
44
 
41
45
  consumer = self.client.subscribe(
@@ -45,6 +49,9 @@ class Subscriber:
45
49
  schema = JsonSchema(self.schema),
46
50
  )
47
51
 
52
+ if self.metrics:
53
+ self.metrics.state("running")
54
+
48
55
  print("Subscriber running...", flush=True)
49
56
 
50
57
  while self.running:
@@ -61,6 +68,9 @@ class Subscriber:
61
68
  print(type(e))
62
69
  raise e
63
70
 
71
+ if self.metrics:
72
+ self.metrics.received()
73
+
64
74
  # Acknowledge successful reception of the message
65
75
  consumer.acknowledge(msg)
66
76
 
@@ -83,7 +93,9 @@ class Subscriber:
83
93
  self.q[id].put(value),
84
94
  timeout=2
85
95
  )
96
+
86
97
  except Exception as e:
98
+ self.metrics.dropped()
87
99
  print("Q Put:", e, flush=True)
88
100
 
89
101
  for q in self.full.values():
@@ -94,6 +106,7 @@ class Subscriber:
94
106
  timeout=2
95
107
  )
96
108
  except Exception as e:
109
+ self.metrics.dropped()
97
110
  print("Q Put:", e, flush=True)
98
111
 
99
112
  except Exception as e:
@@ -101,6 +114,9 @@ class Subscriber:
101
114
 
102
115
  consumer.close()
103
116
 
117
+ if self.metrics:
118
+ self.metrics.state("stopped")
119
+
104
120
  # If handler drops out, sleep a retry
105
121
  time.sleep(2)
106
122
 
@@ -1,5 +1,5 @@
1
1
 
2
- from . metrics import ConsumerMetrics
2
+ from . metrics import SubscriberMetrics
3
3
  from . subscriber import Subscriber
4
4
  from . spec import Spec
5
5
 
@@ -11,17 +11,17 @@ class SubscriberSpec(Spec):
11
11
 
12
12
  def add(self, flow, processor, definition):
13
13
 
14
- # FIXME: Metrics not used
15
- subscriber_metrics = ConsumerMetrics(
16
- flow.id, f"{flow.name}-{self.name}"
14
+ subscriber_metrics = SubscriberMetrics(
15
+ processor = flow.id, flow = flow.name, name = self.name
17
16
  )
18
17
 
19
18
  subscriber = Subscriber(
20
- client = processor.client,
19
+ client = processor.pulsar_client,
21
20
  topic = definition[self.name],
22
21
  subscription = flow.id,
23
22
  consumer_name = flow.id,
24
23
  schema = self.schema,
24
+ metrics = subscriber_metrics,
25
25
  )
26
26
 
27
27
  # Put it in the consumer map, does that work?
@@ -0,0 +1 @@
1
+ __version__ = "0.22.7"
@@ -12,5 +12,5 @@ from . agent import *
12
12
  from . lookup import *
13
13
  from . library import *
14
14
  from . config import *
15
-
15
+ from . flows import *
16
16
 
@@ -20,14 +20,14 @@ from . types import Error
20
20
  # Prompt services, abstract the prompt generation
21
21
  class FlowRequest(Record):
22
22
 
23
- operation = String() # list_classes, get_class, put_class, delete_class
24
- # list_flows, get_flow, start_flow, stop_flow
23
+ operation = String() # list-classes, get-class, put-class, delete-class
24
+ # list-flows, get-flow, start-flow, stop-flow
25
25
 
26
26
  # get_class, put_class, delete_class, start_flow
27
27
  class_name = String()
28
28
 
29
29
  # put_class
30
- class = String()
30
+ class_definition = String()
31
31
 
32
32
  # start_flow
33
33
  description = String()
@@ -44,7 +44,7 @@ class FlowResponse(Record):
44
44
  flow_ids = Array(String())
45
45
 
46
46
  # get_class
47
- class = String()
47
+ class_definition = String()
48
48
 
49
49
  # get_flow
50
50
  flow = String()
@@ -18,8 +18,6 @@ class EntityContexts(Record):
18
18
  metadata = Metadata()
19
19
  entities = Array(EntityContext())
20
20
 
21
- entity_contexts_ingest_queue = topic('entity-contexts-load')
22
-
23
21
  ############################################################################
24
22
 
25
23
  # Graph embeddings are embeddings associated with a graph entity
@@ -33,8 +31,6 @@ class GraphEmbeddings(Record):
33
31
  metadata = Metadata()
34
32
  entities = Array(EntityEmbeddings())
35
33
 
36
- graph_embeddings_store_queue = topic('graph-embeddings-store')
37
-
38
34
  ############################################################################
39
35
 
40
36
  # Graph embeddings query
@@ -49,13 +45,6 @@ class GraphEmbeddingsResponse(Record):
49
45
  error = Error()
50
46
  entities = Array(Value())
51
47
 
52
- graph_embeddings_request_queue = topic(
53
- 'graph-embeddings', kind='non-persistent', namespace='request'
54
- )
55
- graph_embeddings_response_queue = topic(
56
- 'graph-embeddings', kind='non-persistent', namespace='response'
57
- )
58
-
59
48
  ############################################################################
60
49
 
61
50
  # Graph triples
@@ -64,8 +53,6 @@ class Triples(Record):
64
53
  metadata = Metadata()
65
54
  triples = Array(Triple())
66
55
 
67
- triples_store_queue = topic('triples-store')
68
-
69
56
  ############################################################################
70
57
 
71
58
  # Triples query
@@ -82,9 +69,3 @@ class TriplesQueryResponse(Record):
82
69
  error = Error()
83
70
  triples = Array(Triple())
84
71
 
85
- triples_request_queue = topic(
86
- 'triples', kind='non-persistent', namespace='request'
87
- )
88
- triples_response_queue = topic(
89
- 'triples', kind='non-persistent', namespace='response'
90
- )
@@ -0,0 +1,21 @@
1
+
2
+ from pulsar.schema import Record, String
3
+
4
+ from . types import Error, Value, Triple
5
+ from . topic import topic
6
+ from . metadata import Metadata
7
+
8
+ ############################################################################
9
+
10
+ # Lookups
11
+
12
+ class LookupRequest(Record):
13
+ kind = String()
14
+ term = String()
15
+
16
+ class LookupResponse(Record):
17
+ text = String()
18
+ error = Error()
19
+
20
+ ############################################################################
21
+
@@ -19,13 +19,6 @@ class TextCompletionResponse(Record):
19
19
  out_token = Integer()
20
20
  model = String()
21
21
 
22
- text_completion_request_queue = topic(
23
- 'text-completion', kind='non-persistent', namespace='request'
24
- )
25
- text_completion_response_queue = topic(
26
- 'text-completion', kind='non-persistent', namespace='response'
27
- )
28
-
29
22
  ############################################################################
30
23
 
31
24
  # Embeddings
@@ -37,9 +30,3 @@ class EmbeddingsResponse(Record):
37
30
  error = Error()
38
31
  vectors = Array(Array(Double()))
39
32
 
40
- embeddings_request_queue = topic(
41
- 'embeddings', kind='non-persistent', namespace='request'
42
- )
43
- embeddings_response_queue = topic(
44
- 'embeddings', kind='non-persistent', namespace='response'
45
- )
@@ -18,8 +18,6 @@ class ObjectEmbeddings(Record):
18
18
  key_name = String()
19
19
  id = String()
20
20
 
21
- object_embeddings_store_queue = topic('object-embeddings-store')
22
-
23
21
  ############################################################################
24
22
 
25
23
  # Stores rows of information
@@ -29,5 +27,5 @@ class Rows(Record):
29
27
  row_schema = RowSchema()
30
28
  rows = Array(Map(String()))
31
29
 
32
- rows_store_queue = topic('rows-store')
30
+
33
31
 
@@ -55,12 +55,5 @@ class PromptResponse(Record):
55
55
  # JSON encoded
56
56
  object = String()
57
57
 
58
- prompt_request_queue = topic(
59
- 'prompt', kind='non-persistent', namespace='request'
60
- )
61
- prompt_response_queue = topic(
62
- 'prompt', kind='non-persistent', namespace='response'
63
- )
64
-
65
58
  ############################################################################
66
59
 
@@ -20,13 +20,6 @@ class GraphRagResponse(Record):
20
20
  error = Error()
21
21
  response = String()
22
22
 
23
- graph_rag_request_queue = topic(
24
- 'graph-rag', kind='non-persistent', namespace='request'
25
- )
26
- graph_rag_response_queue = topic(
27
- 'graph-rag', kind='non-persistent', namespace='response'
28
- )
29
-
30
23
  ############################################################################
31
24
 
32
25
  # Document RAG text retrieval
@@ -41,9 +34,3 @@ class DocumentRagResponse(Record):
41
34
  error = Error()
42
35
  response = String()
43
36
 
44
- document_rag_request_queue = topic(
45
- 'doc-rag', kind='non-persistent', namespace='request'
46
- )
47
- document_rag_response_queue = topic(
48
- 'doc-rag', kind='non-persistent', namespace='response'
49
- )
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: trustgraph-base
3
- Version: 0.22.6
3
+ Version: 0.22.7
4
4
  Summary: TrustGraph provides a means to run a pipeline of flexible AI processing components in a flexible means to achieve a processing pipeline.
5
5
  Home-page: https://github.com/trustgraph-ai/trustgraph
6
- Download-URL: https://github.com/trustgraph-ai/trustgraph/archive/refs/tags/v0.22.6.tar.gz
6
+ Download-URL: https://github.com/trustgraph-ai/trustgraph/archive/refs/tags/v0.22.7.tar.gz
7
7
  Author: trustgraph.ai
8
8
  Author-email: security@trustgraph.ai
9
9
  Classifier: Programming Language :: Python :: 3
@@ -1,82 +0,0 @@
1
-
2
- from prometheus_client import start_http_server, Info, Enum, Histogram
3
- from prometheus_client import Counter
4
-
5
- class ConsumerMetrics:
6
-
7
- def __init__(self, id, flow=None):
8
-
9
- self.id = id
10
- self.flow = flow
11
-
12
- if not hasattr(__class__, "state_metric"):
13
- __class__.state_metric = Enum(
14
- 'consumer_state', 'Consumer state',
15
- ["id", "flow"],
16
- states=['stopped', 'running']
17
- )
18
- if not hasattr(__class__, "request_metric"):
19
- __class__.request_metric = Histogram(
20
- 'request_latency', 'Request latency (seconds)',
21
- ["id", "flow"],
22
- )
23
- if not hasattr(__class__, "processing_metric"):
24
- __class__.processing_metric = Counter(
25
- 'processing_count', 'Processing count',
26
- ["id", "flow", "status"]
27
- )
28
- if not hasattr(__class__, "rate_limit_metric"):
29
- __class__.rate_limit_metric = Counter(
30
- 'rate_limit_count', 'Rate limit event count',
31
- ["id", "flow"]
32
- )
33
-
34
- def process(self, status):
35
- __class__.processing_metric.labels(
36
- id=self.id, flow=self.flow, status=status
37
- ).inc()
38
-
39
- def rate_limit(self):
40
- __class__.rate_limit_metric.labels(
41
- id=self.id, flow=self.flow
42
- ).inc()
43
-
44
- def state(self, state):
45
- __class__.state_metric.labels(
46
- id=self.id, flow=self.flow
47
- ).state(state)
48
-
49
- def record_time(self):
50
- return __class__.request_metric.labels(
51
- id=self.id, flow=self.flow
52
- ).time()
53
-
54
- class ProducerMetrics:
55
- def __init__(self, id, flow=None):
56
-
57
- self.id = id
58
- self.flow = flow
59
-
60
- if not hasattr(__class__, "output_metric"):
61
- __class__.output_metric = Counter(
62
- 'output_count', 'Output items created',
63
- ["id", "flow"]
64
- )
65
-
66
- def inc(self):
67
- __class__.output_metric.labels(id=self.id, flow=self.flow).inc()
68
-
69
- class ProcessorMetrics:
70
- def __init__(self, id):
71
-
72
- self.id = id
73
-
74
- if not hasattr(__class__, "processor_metric"):
75
- __class__.processor_metric = Info(
76
- 'processor', 'Processor configuration',
77
- ["id"]
78
- )
79
-
80
- def info(self, info):
81
- __class__.processor_metric.labels(id=self.id).info(info)
82
-
@@ -1 +0,0 @@
1
- __version__ = "0.22.6"
@@ -1,42 +0,0 @@
1
-
2
- from pulsar.schema import Record, String
3
-
4
- from . types import Error, Value, Triple
5
- from . topic import topic
6
- from . metadata import Metadata
7
-
8
- ############################################################################
9
-
10
- # Lookups
11
-
12
- class LookupRequest(Record):
13
- kind = String()
14
- term = String()
15
-
16
- class LookupResponse(Record):
17
- text = String()
18
- error = Error()
19
-
20
- encyclopedia_lookup_request_queue = topic(
21
- 'encyclopedia', kind='non-persistent', namespace='request'
22
- )
23
- encyclopedia_lookup_response_queue = topic(
24
- 'encyclopedia', kind='non-persistent', namespace='response',
25
- )
26
-
27
- dbpedia_lookup_request_queue = topic(
28
- 'dbpedia', kind='non-persistent', namespace='request'
29
- )
30
- dbpedia_lookup_response_queue = topic(
31
- 'dbpedia', kind='non-persistent', namespace='response',
32
- )
33
-
34
- internet_search_request_queue = topic(
35
- 'internet-search', kind='non-persistent', namespace='request'
36
- )
37
- internet_search_response_queue = topic(
38
- 'internet-search', kind='non-persistent', namespace='response',
39
- )
40
-
41
- ############################################################################
42
-