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.
- assets/favicon.ico +0 -0
- assets/logo.png +0 -0
- naas_abi_core/__init__.py +1 -0
- naas_abi_core/apps/api/api.py +245 -0
- naas_abi_core/apps/api/api_test.py +281 -0
- naas_abi_core/apps/api/openapi_doc.py +144 -0
- naas_abi_core/apps/mcp/Dockerfile.mcp +35 -0
- naas_abi_core/apps/mcp/mcp_server.py +243 -0
- naas_abi_core/apps/mcp/mcp_server_test.py +163 -0
- naas_abi_core/apps/terminal_agent/main.py +555 -0
- naas_abi_core/apps/terminal_agent/terminal_style.py +175 -0
- naas_abi_core/engine/Engine.py +87 -0
- naas_abi_core/engine/EngineProxy.py +109 -0
- naas_abi_core/engine/Engine_test.py +6 -0
- naas_abi_core/engine/IEngine.py +91 -0
- naas_abi_core/engine/conftest.py +45 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration.py +216 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_Deploy.py +7 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_GenericLoader.py +49 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService.py +159 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService_test.py +26 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService.py +138 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_SecretService_test.py +74 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService.py +224 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_TripleStoreService_test.py +109 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService.py +76 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_VectorStoreService_test.py +33 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration_test.py +9 -0
- naas_abi_core/engine/engine_configuration/utils/PydanticModelValidator.py +15 -0
- naas_abi_core/engine/engine_loaders/EngineModuleLoader.py +302 -0
- naas_abi_core/engine/engine_loaders/EngineOntologyLoader.py +16 -0
- naas_abi_core/engine/engine_loaders/EngineServiceLoader.py +47 -0
- naas_abi_core/integration/__init__.py +7 -0
- naas_abi_core/integration/integration.py +28 -0
- naas_abi_core/models/Model.py +198 -0
- naas_abi_core/models/OpenRouter.py +18 -0
- naas_abi_core/models/OpenRouter_test.py +36 -0
- naas_abi_core/module/Module.py +252 -0
- naas_abi_core/module/ModuleAgentLoader.py +50 -0
- naas_abi_core/module/ModuleUtils.py +20 -0
- naas_abi_core/modules/templatablesparqlquery/README.md +196 -0
- naas_abi_core/modules/templatablesparqlquery/__init__.py +39 -0
- naas_abi_core/modules/templatablesparqlquery/ontologies/TemplatableSparqlQueryOntology.ttl +116 -0
- naas_abi_core/modules/templatablesparqlquery/workflows/GenericWorkflow.py +48 -0
- naas_abi_core/modules/templatablesparqlquery/workflows/TemplatableSparqlQueryLoader.py +192 -0
- naas_abi_core/pipeline/__init__.py +6 -0
- naas_abi_core/pipeline/pipeline.py +70 -0
- naas_abi_core/services/__init__.py +0 -0
- naas_abi_core/services/agent/Agent.py +1619 -0
- naas_abi_core/services/agent/AgentMemory_test.py +28 -0
- naas_abi_core/services/agent/Agent_test.py +214 -0
- naas_abi_core/services/agent/IntentAgent.py +1179 -0
- naas_abi_core/services/agent/IntentAgent_test.py +139 -0
- naas_abi_core/services/agent/beta/Embeddings.py +181 -0
- naas_abi_core/services/agent/beta/IntentMapper.py +120 -0
- naas_abi_core/services/agent/beta/LocalModel.py +88 -0
- naas_abi_core/services/agent/beta/VectorStore.py +89 -0
- naas_abi_core/services/agent/test_agent_memory.py +278 -0
- naas_abi_core/services/agent/test_postgres_integration.py +145 -0
- naas_abi_core/services/cache/CacheFactory.py +31 -0
- naas_abi_core/services/cache/CachePort.py +63 -0
- naas_abi_core/services/cache/CacheService.py +246 -0
- naas_abi_core/services/cache/CacheService_test.py +85 -0
- naas_abi_core/services/cache/adapters/secondary/CacheFSAdapter.py +39 -0
- naas_abi_core/services/object_storage/ObjectStorageFactory.py +57 -0
- naas_abi_core/services/object_storage/ObjectStoragePort.py +47 -0
- naas_abi_core/services/object_storage/ObjectStorageService.py +41 -0
- naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterFS.py +52 -0
- naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterNaas.py +131 -0
- naas_abi_core/services/object_storage/adapters/secondary/ObjectStorageSecondaryAdapterS3.py +171 -0
- naas_abi_core/services/ontology/OntologyPorts.py +36 -0
- naas_abi_core/services/ontology/OntologyService.py +17 -0
- naas_abi_core/services/ontology/adaptors/secondary/OntologyService_SecondaryAdaptor_NERPort.py +37 -0
- naas_abi_core/services/secret/Secret.py +138 -0
- naas_abi_core/services/secret/SecretPorts.py +45 -0
- naas_abi_core/services/secret/Secret_test.py +65 -0
- naas_abi_core/services/secret/adaptors/secondary/Base64Secret.py +57 -0
- naas_abi_core/services/secret/adaptors/secondary/Base64Secret_test.py +39 -0
- naas_abi_core/services/secret/adaptors/secondary/NaasSecret.py +88 -0
- naas_abi_core/services/secret/adaptors/secondary/NaasSecret_test.py +25 -0
- naas_abi_core/services/secret/adaptors/secondary/dotenv_secret_secondaryadaptor.py +29 -0
- naas_abi_core/services/triple_store/TripleStoreFactory.py +116 -0
- naas_abi_core/services/triple_store/TripleStorePorts.py +223 -0
- naas_abi_core/services/triple_store/TripleStoreService.py +419 -0
- naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune.py +1300 -0
- naas_abi_core/services/triple_store/adaptors/secondary/AWSNeptune_test.py +284 -0
- naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph.py +597 -0
- naas_abi_core/services/triple_store/adaptors/secondary/Oxigraph_test.py +1474 -0
- naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__Filesystem.py +223 -0
- naas_abi_core/services/triple_store/adaptors/secondary/TripleStoreService__SecondaryAdaptor__ObjectStorage.py +234 -0
- naas_abi_core/services/triple_store/adaptors/secondary/base/TripleStoreService__SecondaryAdaptor__FileBase.py +18 -0
- naas_abi_core/services/vector_store/IVectorStorePort.py +101 -0
- naas_abi_core/services/vector_store/IVectorStorePort_test.py +189 -0
- naas_abi_core/services/vector_store/VectorStoreFactory.py +47 -0
- naas_abi_core/services/vector_store/VectorStoreService.py +171 -0
- naas_abi_core/services/vector_store/VectorStoreService_test.py +185 -0
- naas_abi_core/services/vector_store/__init__.py +13 -0
- naas_abi_core/services/vector_store/adapters/QdrantAdapter.py +251 -0
- naas_abi_core/services/vector_store/adapters/QdrantAdapter_test.py +57 -0
- naas_abi_core/tests/test_services_imports.py +69 -0
- naas_abi_core/utils/Expose.py +55 -0
- naas_abi_core/utils/Graph.py +182 -0
- naas_abi_core/utils/JSON.py +49 -0
- naas_abi_core/utils/LazyLoader.py +44 -0
- naas_abi_core/utils/Logger.py +12 -0
- naas_abi_core/utils/OntologyReasoner.py +141 -0
- naas_abi_core/utils/OntologyYaml.py +681 -0
- naas_abi_core/utils/SPARQL.py +256 -0
- naas_abi_core/utils/Storage.py +33 -0
- naas_abi_core/utils/StorageUtils.py +398 -0
- naas_abi_core/utils/String.py +52 -0
- naas_abi_core/utils/Workers.py +114 -0
- naas_abi_core/utils/__init__.py +0 -0
- naas_abi_core/utils/onto2py/README.md +0 -0
- naas_abi_core/utils/onto2py/__init__.py +10 -0
- naas_abi_core/utils/onto2py/__main__.py +29 -0
- naas_abi_core/utils/onto2py/onto2py.py +611 -0
- naas_abi_core/utils/onto2py/tests/ttl2py_test.py +271 -0
- naas_abi_core/workflow/__init__.py +5 -0
- naas_abi_core/workflow/workflow.py +48 -0
- naas_abi_core-1.4.1.dist-info/METADATA +630 -0
- naas_abi_core-1.4.1.dist-info/RECORD +124 -0
- naas_abi_core-1.4.1.dist-info/WHEEL +4 -0
- 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,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
|