naas-abi-core 1.4.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.
Files changed (124) hide show
  1. assets/favicon.ico +0 -0
  2. assets/logo.png +0 -0
  3. naas_abi_core/__init__.py +1 -0
  4. naas_abi_core/apps/api/api.py +245 -0
  5. naas_abi_core/apps/api/api_test.py +281 -0
  6. naas_abi_core/apps/api/openapi_doc.py +144 -0
  7. naas_abi_core/apps/mcp/Dockerfile.mcp +35 -0
  8. naas_abi_core/apps/mcp/mcp_server.py +243 -0
  9. naas_abi_core/apps/mcp/mcp_server_test.py +163 -0
  10. naas_abi_core/apps/terminal_agent/main.py +555 -0
  11. naas_abi_core/apps/terminal_agent/terminal_style.py +175 -0
  12. naas_abi_core/engine/Engine.py +87 -0
  13. naas_abi_core/engine/EngineProxy.py +109 -0
  14. naas_abi_core/engine/Engine_test.py +6 -0
  15. naas_abi_core/engine/IEngine.py +91 -0
  16. naas_abi_core/engine/conftest.py +45 -0
  17. naas_abi_core/engine/engine_configuration/EngineConfiguration.py +216 -0
  18. naas_abi_core/engine/engine_configuration/EngineConfiguration_Deploy.py +7 -0
  19. naas_abi_core/engine/engine_configuration/EngineConfiguration_GenericLoader.py +49 -0
  20. naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService.py +159 -0
  21. naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService_test.py +26 -0
  22. naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService.py +138 -0
  23. naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService_test.py +74 -0
  24. naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService.py +224 -0
  25. naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService_test.py +109 -0
  26. naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService.py +76 -0
  27. naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService_test.py +33 -0
  28. naas_abi_core/engine/engine_configuration/EngineConfiguration_test.py +9 -0
  29. naas_abi_core/engine/engine_configuration/utils/PydanticModelValidator.py +15 -0
  30. naas_abi_core/engine/engine_loaders/EngineModuleLoader.py +302 -0
  31. naas_abi_core/engine/engine_loaders/EngineOntologyLoader.py +16 -0
  32. naas_abi_core/engine/engine_loaders/EngineServiceLoader.py +47 -0
  33. naas_abi_core/integration/__init__.py +7 -0
  34. naas_abi_core/integration/integration.py +28 -0
  35. naas_abi_core/models/Model.py +198 -0
  36. naas_abi_core/models/OpenRouter.py +18 -0
  37. naas_abi_core/models/OpenRouter_test.py +36 -0
  38. naas_abi_core/module/Module.py +252 -0
  39. naas_abi_core/module/ModuleAgentLoader.py +50 -0
  40. naas_abi_core/module/ModuleUtils.py +20 -0
  41. naas_abi_core/modules/templatablesparqlquery/README.md +196 -0
  42. naas_abi_core/modules/templatablesparqlquery/__init__.py +39 -0
  43. naas_abi_core/modules/templatablesparqlquery/ontologies/TemplatableSparqlQueryOntology.ttl +116 -0
  44. naas_abi_core/modules/templatablesparqlquery/workflows/GenericWorkflow.py +48 -0
  45. naas_abi_core/modules/templatablesparqlquery/workflows/TemplatableSparqlQueryLoader.py +192 -0
  46. naas_abi_core/pipeline/__init__.py +6 -0
  47. naas_abi_core/pipeline/pipeline.py +70 -0
  48. naas_abi_core/services/__init__.py +0 -0
  49. naas_abi_core/services/agent/Agent.py +1619 -0
  50. naas_abi_core/services/agent/AgentMemory_test.py +28 -0
  51. naas_abi_core/services/agent/Agent_test.py +214 -0
  52. naas_abi_core/services/agent/IntentAgent.py +1179 -0
  53. naas_abi_core/services/agent/IntentAgent_test.py +139 -0
  54. naas_abi_core/services/agent/beta/Embeddings.py +181 -0
  55. naas_abi_core/services/agent/beta/IntentMapper.py +120 -0
  56. naas_abi_core/services/agent/beta/LocalModel.py +88 -0
  57. naas_abi_core/services/agent/beta/VectorStore.py +89 -0
  58. naas_abi_core/services/agent/test_agent_memory.py +278 -0
  59. naas_abi_core/services/agent/test_postgres_integration.py +145 -0
  60. naas_abi_core/services/cache/CacheFactory.py +31 -0
  61. naas_abi_core/services/cache/CachePort.py +63 -0
  62. naas_abi_core/services/cache/CacheService.py +246 -0
  63. naas_abi_core/services/cache/CacheService_test.py +85 -0
  64. naas_abi_core/services/cache/adapters/secondary/CacheFSAdapter.py +39 -0
  65. naas_abi_core/services/object_storage/ObjectStorageFactory.py +57 -0
  66. naas_abi_core/services/object_storage/ObjectStoragePort.py +47 -0
  67. naas_abi_core/services/object_storage/ObjectStorageService.py +41 -0
  68. naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterFS.py +52 -0
  69. naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterNaas.py +131 -0
  70. naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterS3.py +171 -0
  71. naas_abi_core/services/ontology/OntologyPorts.py +36 -0
  72. naas_abi_core/services/ontology/OntologyService.py +17 -0
  73. naas_abi_core/services/ontology/adaptors/secondary/OntologyService_SecondaryAdaptor_NERPort.py +37 -0
  74. naas_abi_core/services/secret/Secret.py +138 -0
  75. naas_abi_core/services/secret/SecretPorts.py +45 -0
  76. naas_abi_core/services/secret/Secret_test.py +65 -0
  77. naas_abi_core/services/secret/adaptors/secondary/Base64Secret.py +57 -0
  78. naas_abi_core/services/secret/adaptors/secondary/Base64Secret_test.py +39 -0
  79. naas_abi_core/services/secret/adaptors/secondary/NaasSecret.py +88 -0
  80. naas_abi_core/services/secret/adaptors/secondary/NaasSecret_test.py +25 -0
  81. naas_abi_core/services/secret/adaptors/secondary/dotenv_secret_secondaryadaptor.py +29 -0
  82. naas_abi_core/services/triple_store/TripleStoreFactory.py +116 -0
  83. naas_abi_core/services/triple_store/TripleStorePorts.py +223 -0
  84. naas_abi_core/services/triple_store/TripleStoreService.py +419 -0
  85. naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune.py +1300 -0
  86. naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune_test.py +284 -0
  87. naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph.py +597 -0
  88. naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph_test.py +1474 -0
  89. naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__Filesystem.py +223 -0
  90. naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__ObjectStorage.py +234 -0
  91. naas_abi_core/services/triple_store/adaptors/secondary/base/TripleStoreService__SecondaryAdaptor__FileBase.py +18 -0
  92. naas_abi_core/services/vector_store/IVectorStorePort.py +101 -0
  93. naas_abi_core/services/vector_store/IVectorStorePort_test.py +189 -0
  94. naas_abi_core/services/vector_store/VectorStoreFactory.py +47 -0
  95. naas_abi_core/services/vector_store/VectorStoreService.py +171 -0
  96. naas_abi_core/services/vector_store/VectorStoreService_test.py +185 -0
  97. naas_abi_core/services/vector_store/__init__.py +13 -0
  98. naas_abi_core/services/vector_store/adapters/QdrantAdapter.py +251 -0
  99. naas_abi_core/services/vector_store/adapters/QdrantAdapter_test.py +57 -0
  100. naas_abi_core/tests/test_services_imports.py +69 -0
  101. naas_abi_core/utils/Expose.py +55 -0
  102. naas_abi_core/utils/Graph.py +182 -0
  103. naas_abi_core/utils/JSON.py +49 -0
  104. naas_abi_core/utils/LazyLoader.py +44 -0
  105. naas_abi_core/utils/Logger.py +12 -0
  106. naas_abi_core/utils/OntologyReasoner.py +141 -0
  107. naas_abi_core/utils/OntologyYaml.py +681 -0
  108. naas_abi_core/utils/SPARQL.py +256 -0
  109. naas_abi_core/utils/Storage.py +33 -0
  110. naas_abi_core/utils/StorageUtils.py +398 -0
  111. naas_abi_core/utils/String.py +52 -0
  112. naas_abi_core/utils/Workers.py +114 -0
  113. naas_abi_core/utils/__init__.py +0 -0
  114. naas_abi_core/utils/onto2py/README.md +0 -0
  115. naas_abi_core/utils/onto2py/__init__.py +10 -0
  116. naas_abi_core/utils/onto2py/__main__.py +29 -0
  117. naas_abi_core/utils/onto2py/onto2py.py +611 -0
  118. naas_abi_core/utils/onto2py/tests/ttl2py_test.py +271 -0
  119. naas_abi_core/workflow/__init__.py +5 -0
  120. naas_abi_core/workflow/workflow.py +48 -0
  121. naas_abi_core-1.4.1.dist-info/METADATA +630 -0
  122. naas_abi_core-1.4.1.dist-info/RECORD +124 -0
  123. naas_abi_core-1.4.1.dist-info/WHEEL +4 -0
  124. naas_abi_core-1.4.1.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,271 @@
1
+ from io import StringIO
2
+
3
+ import pytest
4
+ import requests
5
+ from naas_abi_core.utils.onto2py.onto2py import onto2py
6
+ from pydantic import ValidationError
7
+
8
+
9
+ def ttl_to_module(ttl_file, module_name):
10
+ # Generate Python code from TTL
11
+ python_code = onto2py(ttl_file)
12
+
13
+ with open(module_name + ".py", "w") as f:
14
+ f.write(python_code)
15
+
16
+ import importlib.util
17
+
18
+ spec = importlib.util.spec_from_file_location(module_name, module_name + ".py")
19
+ module = importlib.util.module_from_spec(spec)
20
+ spec.loader.exec_module(module)
21
+
22
+ return module
23
+
24
+
25
+ def test_cco_to_py():
26
+ """Test conversion of CCO ontology to Python classes"""
27
+ response = requests.get(
28
+ "https://raw.githubusercontent.com/CommonCoreOntology/CommonCoreOntologies/refs/heads/develop/src/cco-merged/CommonCoreOntologiesMerged.ttl"
29
+ )
30
+
31
+ assert response.status_code == 200, f"Failed to fetch TTL file: {response.text}"
32
+
33
+ ttl_file = StringIO(response.text)
34
+ module = ttl_to_module(ttl_file, "cco_merged")
35
+
36
+ e = module.Ont00000671()
37
+ assert e.rdf().serialize(format="turtle") == e.rdf().serialize(format="turtle")
38
+
39
+
40
+ def test_bfo_to_py():
41
+ """Test conversion of BFO core ontology to Python classes"""
42
+ response = requests.get(
43
+ "https://raw.githubusercontent.com/BFO-ontology/BFO-2020/refs/heads/master/src/owl/bfo-core.ttl"
44
+ )
45
+
46
+ assert response.status_code == 200, f"Failed to fetch TTL file: {response.text}"
47
+
48
+ ttl_file = StringIO(response.text)
49
+
50
+ # Generate Python code from TTL
51
+ python_code = onto2py(ttl_file)
52
+
53
+ with open("bfo-core.py", "w") as f:
54
+ f.write(python_code)
55
+
56
+ import importlib.util
57
+
58
+ spec = importlib.util.spec_from_file_location("bfo_core", "bfo-core.py")
59
+ module = importlib.util.module_from_spec(spec)
60
+ spec.loader.exec_module(module)
61
+
62
+ # Verify we got some generated code
63
+ assert python_code, "No Python code was generated"
64
+ assert "class" in python_code, "No classes found in generated code"
65
+ assert "BaseModel" in python_code, "Pydantic BaseModel missing"
66
+
67
+ print("Generated Python code:")
68
+ print("=" * 50)
69
+ print(python_code)
70
+ print("=" * 50)
71
+
72
+ module.BFO_0000001()
73
+
74
+
75
+ def test_simple_ttl():
76
+ """Test with a simple TTL example"""
77
+ simple_ttl = """@prefix ex: <http://example.org/> .
78
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
79
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
80
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
81
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
82
+
83
+ # Define classes
84
+ ex:Person rdf:type owl:Class ;
85
+ rdfs:label "Person" ;
86
+ rdfs:comment "A human being" .
87
+
88
+ ex:Organization rdf:type owl:Class ;
89
+ rdfs:label "Organization" ;
90
+ rdfs:comment "A group or institution" .
91
+
92
+ # Define properties
93
+ ex:hasName rdf:type owl:DatatypeProperty ;
94
+ rdfs:domain ex:Person ;
95
+ rdfs:range xsd:string ;
96
+ rdfs:label "has name" .
97
+
98
+ ex:hasAge rdf:type owl:DatatypeProperty ;
99
+ rdfs:domain ex:Person ;
100
+ rdfs:range xsd:integer ;
101
+ rdfs:label "has age" .
102
+
103
+ ex:worksFor rdf:type owl:ObjectProperty ;
104
+ rdfs:domain ex:Person ;
105
+ rdfs:range ex:Organization ;
106
+ rdfs:label "works for" .
107
+ """
108
+
109
+ ttl_file = StringIO(simple_ttl)
110
+ python_code = onto2py(ttl_file)
111
+
112
+ print("Generated Python code from simple TTL:")
113
+ print("=" * 50)
114
+ print(python_code)
115
+ print("=" * 50)
116
+
117
+ # Verify expected content
118
+ assert "class Person(RDFEntity):" in python_code
119
+ assert "class Organization(RDFEntity):" in python_code
120
+ assert "hasName: Optional[str] = Field(default=None)" in python_code
121
+ assert "hasAge: Optional[int] = Field(default=None)" in python_code
122
+ assert "worksFor: Optional[Organization] = Field(default=None)" in python_code
123
+
124
+
125
+ def test_shacl_ttl():
126
+ """Test with a TTL example using SHACL constraints"""
127
+ shacl_ttl = """@prefix ex: <http://example.org/> .
128
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
129
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
130
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
131
+ @prefix sh: <http://www.w3.org/ns/shacl#> .
132
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
133
+
134
+ # Define classes
135
+ ex:Person rdf:type owl:Class ;
136
+ rdfs:label "Person" ;
137
+ rdfs:comment "A human being" .
138
+
139
+ ex:Pet rdf:type owl:Class ;
140
+ rdfs:label "Pet" ;
141
+ rdfs:comment "A domesticated animal kept for companionship" .
142
+
143
+ ex:PetOwner rdf:type owl:Class ;
144
+ rdfs:subClassOf ex:Person ;
145
+ rdfs:label "Pet Owner" ;
146
+ rdfs:comment "A person who owns a pet" .
147
+
148
+ # Define data properties
149
+ ex:hasName rdf:type owl:DatatypeProperty ;
150
+ rdfs:domain ex:Person ;
151
+ rdfs:range xsd:string ;
152
+ rdfs:label "has name" .
153
+
154
+ ex:hasAge rdf:type owl:DatatypeProperty ;
155
+ rdfs:domain ex:Person ;
156
+ rdfs:range xsd:integer ;
157
+ rdfs:label "has age" .
158
+
159
+ ex:petName rdf:type owl:DatatypeProperty ;
160
+ rdfs:domain ex:Pet ;
161
+ rdfs:range xsd:string ;
162
+ rdfs:label "pet name" .
163
+
164
+ # Define object properties
165
+ ex:hasPet rdf:type owl:ObjectProperty ;
166
+ rdfs:domain ex:PetOwner ;
167
+ rdfs:range ex:Pet ;
168
+ rdfs:label "has pet" .
169
+
170
+ # SHACL constraints
171
+ ex:PersonShape rdf:type sh:NodeShape ;
172
+ sh:targetClass ex:Person ;
173
+ sh:property [
174
+ sh:path ex:hasName ;
175
+ sh:minCount 1 ;
176
+ sh:maxCount 1 ;
177
+ sh:datatype xsd:string
178
+ ] ;
179
+ sh:property [
180
+ sh:path ex:hasAge ;
181
+ sh:minCount 1 ;
182
+ sh:maxCount 1 ;
183
+ sh:datatype xsd:integer ;
184
+ sh:minInclusive 0 ;
185
+ sh:maxInclusive 150
186
+ ] .
187
+
188
+ ex:PetShape rdf:type sh:NodeShape ;
189
+ sh:targetClass ex:Pet ;
190
+ sh:property [
191
+ sh:path ex:petName ;
192
+ sh:minCount 1 ;
193
+ sh:maxCount 1 ;
194
+ sh:datatype xsd:string
195
+ ] .
196
+
197
+ ex:PetOwnerShape rdf:type sh:NodeShape ;
198
+ sh:targetClass ex:PetOwner ;
199
+ sh:property [
200
+ sh:path ex:hasPet ;
201
+ sh:minCount 1 ;
202
+ sh:class ex:Pet
203
+ ] .
204
+ """
205
+
206
+ ttl_file = StringIO(shacl_ttl)
207
+ python_code = onto2py(ttl_file)
208
+
209
+ print("Generated Python code from SHACL TTL:")
210
+ print("=" * 50)
211
+ print(python_code)
212
+ print("=" * 50)
213
+
214
+ # Verify expected content
215
+ assert "class Person(RDFEntity):" in python_code
216
+ assert "class Pet(RDFEntity):" in python_code
217
+ assert "class PetOwner(Person, RDFEntity):" in python_code
218
+ assert "hasName: str = Field(...)" in python_code # Required property
219
+ assert "hasAge: int = Field(...)" in python_code # Required property
220
+ assert "petName: str = Field(...)" in python_code # Required property for Pet
221
+ assert "hasPet: Pet = Field(...)" in python_code # Required property for PetOwner
222
+
223
+ import os
224
+ import tempfile
225
+
226
+ temp_dir = tempfile.mkdtemp()
227
+ temp_file = os.path.join(temp_dir, "shacl_ttl.py")
228
+
229
+ with open(temp_file, "w") as f:
230
+ f.write(python_code)
231
+
232
+ with open("shacl_ttl.py", "w") as f:
233
+ f.write(python_code)
234
+
235
+ # Load the generated code
236
+ import importlib.util
237
+
238
+ spec = importlib.util.spec_from_file_location("shacl_ttl", temp_file)
239
+ module = importlib.util.module_from_spec(spec)
240
+ spec.loader.exec_module(module)
241
+
242
+ # assert module.Person.hasName is not None, module.Person
243
+ # assert module.Person.hasAge is not None, module.Person
244
+ # assert module.Pet.petName is not None, module.Pet
245
+ # assert module.PetOwner.hasPet is not None, module.PetOwner
246
+
247
+ person = module.Person(hasName="John Doe", hasAge=30)
248
+ print(person)
249
+ assert person.hasName == "John Doe"
250
+ assert person.hasAge == 30
251
+
252
+ pet = module.Pet(petName="Fluffy")
253
+ print(pet)
254
+ assert pet.petName == "Fluffy"
255
+
256
+ pet_owner = module.PetOwner(hasPet=pet, hasName="John Doe", hasAge=30)
257
+ print(pet_owner)
258
+ assert pet_owner.hasPet == pet
259
+
260
+ g = pet_owner.rdf()
261
+ for s, p, o in g:
262
+ print(s, p, o)
263
+ print(g.serialize(format="turtle"))
264
+ # Should have 6 triples: 2 type declarations + 4 property assertions
265
+ # PetOwner: type, hasName, hasAge, hasPet
266
+ # Pet: type, petName
267
+ assert len(list(g)) == 6, list(g)
268
+
269
+ # Assert this is raising a validation error
270
+ with pytest.raises(ValidationError):
271
+ module.PetOwner(hasName="John Doe", hasAge=30)
@@ -0,0 +1,5 @@
1
+ from naas_abi_core.workflow.workflow import Workflow as Workflow
2
+ from naas_abi_core.workflow.workflow import (
3
+ WorkflowConfiguration as WorkflowConfiguration,
4
+ )
5
+ from naas_abi_core.workflow.workflow import WorkflowParameters as WorkflowParameters
@@ -0,0 +1,48 @@
1
+ from dataclasses import dataclass
2
+ from typing import Generic, TypeVar
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from naas_abi_core.utils.Expose import Expose
7
+
8
+
9
+ @dataclass
10
+ class WorkflowConfiguration:
11
+ pass
12
+
13
+
14
+ class WorkflowParameters(BaseModel):
15
+ pass
16
+
17
+
18
+ P = TypeVar("P", bound=WorkflowParameters)
19
+
20
+
21
+ class Workflow(Expose, Generic[P]):
22
+ """A workflow represents a sequence of operations that can be exposed in multiple ways.
23
+
24
+ Workflows encapsulate business logic that can be:
25
+ - Scheduled as background jobs
26
+ - Exposed as tools for AI agents
27
+ - Served via API endpoints
28
+ - Run directly as Python code
29
+
30
+ The workflow pattern provides a consistent way to package functionality
31
+ that needs to be accessible through multiple interfaces.
32
+
33
+ Attributes:
34
+ __configuration (WorkflowConfiguration): Configuration parameters for the workflow
35
+
36
+ Example:
37
+ >>> config = MyWorkflowConfig(param1="value1")
38
+ >>> workflow = MyWorkflow(config)
39
+ >>> result = workflow.run()
40
+ """
41
+
42
+ __configuration: WorkflowConfiguration
43
+
44
+ def __init__(self, configuration: WorkflowConfiguration):
45
+ self.__configuration = configuration
46
+
47
+ def run(self, parameters: P):
48
+ pass