pyMetaModel 0.5.3__tar.gz → 0.6.1__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.
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/.github/workflows/build.yml +4 -2
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/PKG-INFO +4 -6
- pymetamodel-0.6.1/meta/__init__.py +1 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/metamodel.py +124 -115
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/metamodel_cmd.py +1 -1
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/mw.py +4 -2
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/sidif2linkml.py +4 -1
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/smw_type.py +3 -19
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/uml.py +1 -1
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/version.py +1 -1
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/pyproject.toml +11 -14
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/test_linkml.py +1 -1
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/test_metamodel.py +4 -4
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/test_mw.py +10 -6
- pymetamodel-0.5.3/meta/__init__.py +0 -1
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/.github/workflows/upload-to-pypi.yml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/.gitignore +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/.project +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/.pydevproject +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/LICENSE +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/README.md +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/docs/index.md +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/ceur-ws/ceur-ws_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/city/city_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/family/FamilyContext_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/infrastructure/infrastructure_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/metamodel/metamodel_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smartRQM/smartRQM.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smartRQM/smartRQM.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smartRQM/smartRQM.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smartRQM/smartRQM.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smartRQM/smartRQM.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smartRQM/smartRQM_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/smwcon/smwcon_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/teaching/TeachingSchema_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki.mermaid +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki.sidif +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki.xlsx +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki.yaml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/wiki/wiki_puml.txt +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/meta/profiler.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/metamodel.puml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/mkdocs.yml +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/scripts/blackisort +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/scripts/doc +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/scripts/genexamples +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/scripts/install +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/scripts/release +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/scripts/test +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/__init__.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/basemwtest.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/basesmwtest.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/basetest.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/test_generators.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/test_plantuml.py +0 -0
- {pymetamodel-0.5.3 → pymetamodel-0.6.1}/tests/test_sidif.py +0 -0
|
@@ -18,8 +18,10 @@ jobs:
|
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
19
|
strategy:
|
|
20
20
|
matrix:
|
|
21
|
-
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
22
|
-
|
|
21
|
+
#os: [ubuntu-latest, macos-latest, windows-latest]
|
|
22
|
+
os: [ubuntu-latest]
|
|
23
|
+
#python-version: [ '3.9', '3.10', '3.11', '3.12' ]
|
|
24
|
+
python-version: [ '3.12' ]
|
|
23
25
|
|
|
24
26
|
steps:
|
|
25
27
|
- uses: actions/checkout@v4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyMetaModel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Dynamic: Summary
|
|
5
5
|
Project-URL: Home, https://github.com/WolfgangFahl/pyMetaModel
|
|
6
6
|
Project-URL: Documentation, https://wiki.bitplan.com/index.php/PyMetaModel
|
|
@@ -216,20 +216,18 @@ Classifier: Intended Audience :: Science/Research
|
|
|
216
216
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
217
217
|
Classifier: Operating System :: OS Independent
|
|
218
218
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
219
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
220
219
|
Classifier: Programming Language :: Python :: 3.10
|
|
221
220
|
Classifier: Programming Language :: Python :: 3.11
|
|
222
221
|
Classifier: Programming Language :: Python :: 3.12
|
|
222
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
223
223
|
Classifier: Topic :: Software Development
|
|
224
|
-
Requires-Python: >=3.
|
|
225
|
-
Requires-Dist: dacite>=1.8.1
|
|
224
|
+
Requires-Python: >=3.10
|
|
226
225
|
Requires-Dist: py-sidif>=0.2.0
|
|
226
|
+
Requires-Dist: pybasemkit>=0.0.4
|
|
227
227
|
Requires-Dist: urllib3
|
|
228
228
|
Provides-Extra: linkml
|
|
229
229
|
Requires-Dist: linkml-runtime>=1.8.3; extra == 'linkml'
|
|
230
230
|
Requires-Dist: linkml>=1.8.5; extra == 'linkml'
|
|
231
|
-
Provides-Extra: lodstorage
|
|
232
|
-
Requires-Dist: pylodstorage>=0.13.3; extra == 'lodstorage'
|
|
233
231
|
Provides-Extra: smw
|
|
234
232
|
Requires-Dist: mwparserfromhell>=0.6.6; extra == 'smw'
|
|
235
233
|
Requires-Dist: py-3rdparty-mediawiki>=0.14.0; extra == 'smw'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.1"
|
|
@@ -4,66 +4,40 @@ Created on 2022-11-23
|
|
|
4
4
|
@author: wf
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from dataclasses import field
|
|
8
|
+
from datetime import datetime
|
|
7
9
|
import sys
|
|
10
|
+
from typing import List, Optional, Tuple, Dict
|
|
8
11
|
import typing
|
|
9
|
-
from datetime import datetime
|
|
10
|
-
from typing import List, Optional, Tuple
|
|
11
|
-
|
|
12
|
-
import urllib3
|
|
13
|
-
from lodstorage.jsonable import JSONAble
|
|
14
|
-
from sidif.sidif import SiDIFParser
|
|
15
12
|
|
|
13
|
+
from basemkit.persistent_log import Log
|
|
14
|
+
from basemkit.yamlable import lod_storable
|
|
16
15
|
from meta.mw import MediaWikiContext
|
|
16
|
+
from meta.smw_type import SMW_Type
|
|
17
|
+
from sidif.sidif import SiDIFParser
|
|
18
|
+
import urllib3
|
|
17
19
|
|
|
18
20
|
|
|
19
|
-
class MetaModelElement(JSONAble):
|
|
20
|
-
"""
|
|
21
|
-
a generic MetaModelElement
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
def __init__(self):
|
|
28
|
-
"""
|
|
29
|
-
construct me
|
|
30
|
-
"""
|
|
31
|
-
self.__metamodel_props = {}
|
|
32
|
-
cls = self.__class__
|
|
33
|
-
if hasattr(cls, "getSamples"):
|
|
34
|
-
for sample in cls.getSamples():
|
|
35
|
-
for key in sample.keys():
|
|
36
|
-
if not key in self.__metamodel_props:
|
|
37
|
-
self.__metamodel_props[key] = key # Property(self,key)
|
|
38
|
-
|
|
39
|
-
def __str__(self):
|
|
40
|
-
"""
|
|
41
|
-
get a string representation of me
|
|
42
|
-
"""
|
|
43
|
-
text = self.__class__.__name__
|
|
44
|
-
for prop_name in self.__metamodel_props.keys():
|
|
45
|
-
if not isinstance(prop_name, str):
|
|
46
|
-
pass
|
|
47
|
-
elif hasattr(self, prop_name):
|
|
48
|
-
value = getattr(self, prop_name)
|
|
49
|
-
text += f"\n {prop_name}={str(value)}"
|
|
50
|
-
return text
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class Context(MetaModelElement):
|
|
22
|
+
@lod_storable
|
|
23
|
+
class Context:
|
|
54
24
|
"""
|
|
55
25
|
A Context groups some topics like a Namespace/Package.
|
|
56
26
|
This class provides helper functions and constants to render a Context to corresponding wiki pages
|
|
57
27
|
"""
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
28
|
+
name: Optional[str] = None
|
|
29
|
+
since: Optional[str] = None # isodate string
|
|
30
|
+
updated: Optional[str] = None # isodate string
|
|
31
|
+
copyright: Optional[str] = None
|
|
32
|
+
master: Optional[str] = None
|
|
33
|
+
demo: Optional[str] = None
|
|
34
|
+
topics: Dict[str, 'Topic'] = field(default_factory=dict)
|
|
35
|
+
types: Dict[str, 'Topic'] = field(default_factory=dict)
|
|
36
|
+
errors: List[str] = field(default_factory=list)
|
|
37
|
+
|
|
38
|
+
def __post_init__(self):
|
|
39
|
+
self.log=Log()
|
|
40
|
+
pass
|
|
67
41
|
|
|
68
42
|
@classmethod
|
|
69
43
|
def getSamples(cls):
|
|
@@ -72,7 +46,7 @@ class Context(MetaModelElement):
|
|
|
72
46
|
"name": "MetaModel",
|
|
73
47
|
"since": datetime.strptime("2015-01-23", "%Y-%m-%d"),
|
|
74
48
|
"updated": datetime.strptime("2024-08-07", "%Y-%m-%d"),
|
|
75
|
-
"copyright": "2015-
|
|
49
|
+
"copyright": "2015-2025 BITPlan GmbH",
|
|
76
50
|
"master": "https://contexts.bitplan.com",
|
|
77
51
|
"demo": "https://wiki.bitplan.com/index.php/List_of_Contexts"
|
|
78
52
|
}
|
|
@@ -226,51 +200,53 @@ class Context(MetaModelElement):
|
|
|
226
200
|
"""
|
|
227
201
|
context = None
|
|
228
202
|
for key, record in did.items():
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
203
|
+
try:
|
|
204
|
+
isA = record.get("isA")
|
|
205
|
+
if isA == "Context":
|
|
206
|
+
context = Context.from_dict2(record)
|
|
207
|
+
context.sanitize(key)
|
|
208
|
+
elif isA == "TopicLink":
|
|
209
|
+
"""
|
|
210
|
+
# Event n : 1 City
|
|
211
|
+
Event_in_City isA TopicLink
|
|
212
|
+
"eventInCity" is name of it
|
|
213
|
+
"city" is sourceRole of it
|
|
214
|
+
false is sourceMultiple of it
|
|
215
|
+
"City" is source of it
|
|
216
|
+
"event" is targetRole of it
|
|
217
|
+
true is targetMultiple of it
|
|
218
|
+
"Event" is target of it
|
|
219
|
+
"""
|
|
220
|
+
tl = TopicLink.from_dict2(record)
|
|
221
|
+
context.addLink(tl)
|
|
222
|
+
elif isA == "Property":
|
|
223
|
+
prop = Property.from_dict2(record)
|
|
224
|
+
prop.sanitize()
|
|
225
|
+
context.addProperty(prop)
|
|
226
|
+
elif isA == "SMW_Type":
|
|
227
|
+
smw_type=SMW_Type.from_dict2(record) # @UndefinedVariable
|
|
228
|
+
context.types[smw_type.type]=smw_type
|
|
229
|
+
else: # isA == Topic or in declared topics
|
|
230
|
+
topic = Topic.from_dict2(record)
|
|
231
|
+
topic.sanitize()
|
|
232
|
+
if context is None:
|
|
233
|
+
context = Context()
|
|
234
|
+
context.name = "GlobalContext"
|
|
235
|
+
context.since = "2022-11-26"
|
|
236
|
+
context.master = "http://contexts.bitplan.com"
|
|
237
|
+
context.error(f"topic {topic.name} has no defined context")
|
|
238
|
+
if hasattr(topic, "name") and topic.name:
|
|
239
|
+
context.topics[topic.name] = topic
|
|
240
|
+
topic.context_obj=context
|
|
241
|
+
else:
|
|
242
|
+
# potential foreign or extends declaration
|
|
243
|
+
context.error(f"missing name for topic {topic} {key} - foreign declaration?")
|
|
244
|
+
except Exception as ex:
|
|
245
|
+
if context:
|
|
246
|
+
msg=f"invalid dict {record}: {str(ex)}"
|
|
247
|
+
context.log.log("❌","dict",msg)
|
|
270
248
|
else:
|
|
271
|
-
|
|
272
|
-
context.error(f"missing name for topic {topic} {key} - foreign declaration?")
|
|
273
|
-
|
|
249
|
+
raise ex
|
|
274
250
|
# link topic to concepts and add topicLinks
|
|
275
251
|
for topic in context.topics.values():
|
|
276
252
|
topic.setConceptProperty()
|
|
@@ -356,8 +332,9 @@ class Context(MetaModelElement):
|
|
|
356
332
|
error = None
|
|
357
333
|
errMsg = None
|
|
358
334
|
sidif = None
|
|
335
|
+
msg=f"reading sidif for {mw_context.context} from {mw_context.wikiId}"
|
|
359
336
|
if debug:
|
|
360
|
-
print(
|
|
337
|
+
print(msg)
|
|
361
338
|
try:
|
|
362
339
|
sidif = mw_context.read_sidif()
|
|
363
340
|
except BaseException as ex:
|
|
@@ -367,24 +344,32 @@ class Context(MetaModelElement):
|
|
|
367
344
|
context, error, errMsg = cls.fromSiDIF(
|
|
368
345
|
sidif=sidif, title=mw_context.wikiId, depth=depth, debug=debug
|
|
369
346
|
)
|
|
347
|
+
else:
|
|
348
|
+
errMsg=f"{msg} failed"
|
|
349
|
+
error=ValueError(msg)
|
|
370
350
|
return context, error, errMsg
|
|
371
351
|
|
|
372
|
-
|
|
373
|
-
class Topic
|
|
352
|
+
@lod_storable
|
|
353
|
+
class Topic:
|
|
374
354
|
"""
|
|
375
355
|
A Topic is a Concept/Class/Thing/Entity
|
|
376
356
|
"""
|
|
357
|
+
name: Optional[str] = None
|
|
358
|
+
icon: Optional[str] = None
|
|
359
|
+
context: Optional[str] = None
|
|
360
|
+
_pluralName: Optional[str] = None
|
|
361
|
+
documentation: Optional[str] = None
|
|
362
|
+
wikiDocumentation: Optional[str] = None
|
|
363
|
+
defaultstoremode: str = "property"
|
|
364
|
+
extends: Optional[str] = None
|
|
365
|
+
listLimit: int = 200
|
|
366
|
+
properties: Dict[str, 'Property'] = field(default_factory=dict)
|
|
367
|
+
sourceTopicLinks: Dict[str, 'TopicLink'] = field(default_factory=dict)
|
|
368
|
+
targetTopicLinks: Dict[str, 'TopicLink'] = field(default_factory=dict)
|
|
369
|
+
# object references
|
|
370
|
+
context_obj: Optional[Context] = None
|
|
371
|
+
conceptProperty: Optional['Property'] = None
|
|
377
372
|
|
|
378
|
-
def __init__(self):
|
|
379
|
-
"""
|
|
380
|
-
constructor
|
|
381
|
-
"""
|
|
382
|
-
MetaModelElement.__init__(self)
|
|
383
|
-
self._pluralName = None # Initialize with underscore to indicate a protected attribute
|
|
384
|
-
|
|
385
|
-
self.properties = {}
|
|
386
|
-
self.sourceTopicLinks = {}
|
|
387
|
-
self.targetTopicLinks = {}
|
|
388
373
|
|
|
389
374
|
def get_extends_topics(self, l: List['Topic'] = None) -> List['Topic']:
|
|
390
375
|
"""
|
|
@@ -441,6 +426,7 @@ class Topic(MetaModelElement):
|
|
|
441
426
|
self.wikiDocumentation=doc
|
|
442
427
|
if not hasattr(self,"defaultstoremode"):
|
|
443
428
|
self.defaultstoremode="property"
|
|
429
|
+
pass
|
|
444
430
|
|
|
445
431
|
@classmethod
|
|
446
432
|
def getSamples(cls):
|
|
@@ -570,7 +556,7 @@ class Topic(MetaModelElement):
|
|
|
570
556
|
props_count = len(props)
|
|
571
557
|
|
|
572
558
|
# Sort properties locally by index
|
|
573
|
-
sorted_props = sorted(props, key=lambda p:
|
|
559
|
+
sorted_props = sorted(props, key=lambda p: p.index or props_count)
|
|
574
560
|
|
|
575
561
|
return sorted_props
|
|
576
562
|
|
|
@@ -638,16 +624,26 @@ class Topic(MetaModelElement):
|
|
|
638
624
|
markup += f"""{self.askSort()}}}}}"""
|
|
639
625
|
return markup
|
|
640
626
|
|
|
641
|
-
|
|
627
|
+
@lod_storable
|
|
628
|
+
class Property:
|
|
642
629
|
"""
|
|
643
630
|
Provides helper functions and constants for properties
|
|
644
631
|
"""
|
|
632
|
+
name: Optional[str] = None
|
|
633
|
+
label: Optional[str] = None
|
|
634
|
+
type: Optional[str] = None
|
|
635
|
+
topic: Optional[str] = None
|
|
636
|
+
documentation: Optional[str] = None
|
|
637
|
+
namespace: str = "Property"
|
|
638
|
+
showInGrid: bool = True
|
|
639
|
+
isLink: bool = False
|
|
640
|
+
topicLink: Optional['TopicLink'] = None
|
|
641
|
+
index: Optional[int] = None
|
|
642
|
+
sortPos: Optional[int] = None
|
|
643
|
+
primaryKey: bool = False
|
|
644
|
+
mandatory: bool = False
|
|
645
|
+
sortAscending: bool = True
|
|
645
646
|
|
|
646
|
-
def __init__(self):
|
|
647
|
-
"""
|
|
648
|
-
constructor
|
|
649
|
-
"""
|
|
650
|
-
MetaModelElement.__init__(self)
|
|
651
647
|
|
|
652
648
|
@classmethod
|
|
653
649
|
def getSamples(cls):
|
|
@@ -702,11 +698,24 @@ class Property(MetaModelElement):
|
|
|
702
698
|
self.showInGrid=True
|
|
703
699
|
pass
|
|
704
700
|
|
|
705
|
-
|
|
701
|
+
@lod_storable
|
|
702
|
+
class TopicLink:
|
|
706
703
|
"""
|
|
707
704
|
A TopicLink links two Concepts/Topics
|
|
708
705
|
"""
|
|
709
706
|
|
|
707
|
+
name: Optional[str] = None
|
|
708
|
+
source: Optional[str] = None
|
|
709
|
+
target: Optional[str] = None
|
|
710
|
+
sourceRole: Optional[str] = None
|
|
711
|
+
targetRole: Optional[str] = None
|
|
712
|
+
sourceMultiple: bool = False
|
|
713
|
+
targetMultiple: bool = False
|
|
714
|
+
sourceDocumentation: Optional[str] = None
|
|
715
|
+
targetDocumentation: Optional[str] = None
|
|
716
|
+
sourceTopic: Optional[Topic] = None
|
|
717
|
+
targetTopic: Optional[Topic] = None
|
|
718
|
+
|
|
710
719
|
@classmethod
|
|
711
720
|
def getSamples(cls):
|
|
712
721
|
samples = [
|
|
@@ -43,7 +43,7 @@ class MetaModelCmd:
|
|
|
43
43
|
program_license = """%s
|
|
44
44
|
|
|
45
45
|
Created by %s on %s.
|
|
46
|
-
Copyright 2022-
|
|
46
|
+
Copyright 2022-2025 Wolfgang Fahl. All rights reserved.
|
|
47
47
|
|
|
48
48
|
Licensed under the Apache License 2.0
|
|
49
49
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Created on 23
|
|
2
|
+
Created on 2022-11-23
|
|
3
3
|
|
|
4
4
|
@author: wf
|
|
5
5
|
"""
|
|
@@ -40,7 +40,9 @@ class MediaWikiContext:
|
|
|
40
40
|
"""
|
|
41
41
|
sidif = None
|
|
42
42
|
wikiusers = WikiUser.getWikiUsers(lenient=True)
|
|
43
|
-
if self.wikiId in wikiusers:
|
|
43
|
+
if not self.wikiId in wikiusers:
|
|
44
|
+
raise ValueError(f"unknown wiki {self.wikiId}")
|
|
45
|
+
else:
|
|
44
46
|
wikiUser = wikiusers[self.wikiId]
|
|
45
47
|
self.wikiClient = WikiClient.ofWikiId(wikiUser.wikiId)
|
|
46
48
|
if self.wikiClient.needsLogin():
|
|
@@ -50,6 +50,8 @@ class SiDIF2LinkML:
|
|
|
50
50
|
master = "http://example.com"
|
|
51
51
|
uri = f"{master}/{context.name}"
|
|
52
52
|
for topic in self.context.topics.values():
|
|
53
|
+
if not topic.name:
|
|
54
|
+
continue
|
|
53
55
|
cd = ClassDefinition(name=topic.name)
|
|
54
56
|
cd.description = topic.documentation
|
|
55
57
|
sv.add_class(cd)
|
|
@@ -59,7 +61,8 @@ class SiDIF2LinkML:
|
|
|
59
61
|
qname = prop.name
|
|
60
62
|
if prop.name in sd.slots:
|
|
61
63
|
slot = sd.slots[prop.name]
|
|
62
|
-
|
|
64
|
+
if prop.documentation:
|
|
65
|
+
slot.description += "," + prop.documentation
|
|
63
66
|
else:
|
|
64
67
|
qname = f"{topic.name}{delim}{prop.name}"
|
|
65
68
|
if slot is None:
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
1
|
from typing import Optional
|
|
3
2
|
|
|
4
|
-
import
|
|
3
|
+
from basemkit.yamlable import lod_storable
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
@dataclass
|
|
5
|
+
@lod_storable
|
|
8
6
|
class SMW_Type:
|
|
9
7
|
"""
|
|
10
8
|
an SMW_Type is a data type which determines the possible values for that type e.g. a Boolean can hold true/false values while a Number can hold 3.1459 or 20. A Page can hold the name of a Wiki page see https://semantic-mediawiki.org/wiki/Help:List_of_datatypes
|
|
@@ -40,18 +38,4 @@ class SMW_Type:
|
|
|
40
38
|
|?SMW_Type javaType = javaType
|
|
41
39
|
| limit=200
|
|
42
40
|
}}"""
|
|
43
|
-
return ask
|
|
44
|
-
|
|
45
|
-
@classmethod
|
|
46
|
-
def fromDict(cls, data: dict)->'SMW_Type':
|
|
47
|
-
"""
|
|
48
|
-
create a SMW_Type from the given dict
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
data (dict): the dict to create the SMW_Type from
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
SMW_Type: the freshly created SMW_Type
|
|
55
|
-
"""
|
|
56
|
-
smw_type = dacite.from_dict(data_class=cls, data=data)
|
|
57
|
-
return smw_type
|
|
41
|
+
return ask
|
|
@@ -17,7 +17,7 @@ class PlantUml(object):
|
|
|
17
17
|
# redundant to skinparams in pylodstorage.uml
|
|
18
18
|
skinparams = """
|
|
19
19
|
' BITPlan Corporate identity skin params
|
|
20
|
-
' Copyright (c) 2015-
|
|
20
|
+
' Copyright (c) 2015-2025 BITPlan GmbH
|
|
21
21
|
' see http://wiki.bitplan.com/PlantUmlSkinParams#BITPlanCI
|
|
22
22
|
' skinparams generated by com.bitplan.restmodelmanager
|
|
23
23
|
skinparam note {
|
|
@@ -16,7 +16,7 @@ class Version(object):
|
|
|
16
16
|
description = "pyMetaModel: MetaModel for Knowledge Graphs"
|
|
17
17
|
version = meta.__version__
|
|
18
18
|
date = "2022-11-30"
|
|
19
|
-
updated = "2025-
|
|
19
|
+
updated = "2025-08-20"
|
|
20
20
|
authors = "Wolfgang Fahl"
|
|
21
21
|
doc_url = "https://wiki.bitplan.com/index.php/pyMetaModel"
|
|
22
22
|
chat_url = "https://github.com/WolfgangFahl/pyMetaModel/discussions"
|
|
@@ -17,23 +17,25 @@ readme = "README.md"
|
|
|
17
17
|
# flit_core.config.ConfigError: license field should be <class 'dict'>, not <class 'str'>
|
|
18
18
|
license = { file="LICENSE" }
|
|
19
19
|
dependencies = [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
# https://pypi.org/project/pybasemkit/
|
|
21
|
+
# https://github.com/WolfgangFahl/pybasemkit
|
|
22
|
+
# Python base module kit: YAML/JSON I/O, structured logging, CLI tooling, shell execution, and remote pydevd debug support.
|
|
23
|
+
"pybasemkit>=0.0.4",
|
|
24
|
+
# https://pypi.org/project/py-sidif/
|
|
25
|
+
'py-sidif>=0.2.0',
|
|
26
|
+
# https://github.com/urllib3/urllib3
|
|
27
|
+
'urllib3',
|
|
28
|
+
]
|
|
27
29
|
|
|
28
|
-
requires-python = ">=3.
|
|
30
|
+
requires-python = ">=3.10"
|
|
29
31
|
classifiers=[
|
|
30
32
|
"Development Status :: 4 - Beta",
|
|
31
33
|
"Environment :: Web Environment",
|
|
32
34
|
"Programming Language :: Python :: 3 :: Only",
|
|
33
|
-
"Programming Language :: Python :: 3.9",
|
|
34
35
|
"Programming Language :: Python :: 3.10",
|
|
35
36
|
"Programming Language :: Python :: 3.11",
|
|
36
37
|
"Programming Language :: Python :: 3.12",
|
|
38
|
+
"Programming Language :: Python :: 3.13",
|
|
37
39
|
"Operating System :: OS Independent",
|
|
38
40
|
"Topic :: Software Development",
|
|
39
41
|
"Intended Audience :: Developers",
|
|
@@ -53,11 +55,6 @@ Source = "https://github.com/WolfgangFahl/pyMetaModel"
|
|
|
53
55
|
test = [
|
|
54
56
|
"green",
|
|
55
57
|
]
|
|
56
|
-
# python List of Dict (Table) Storage library
|
|
57
|
-
lodstorage = [
|
|
58
|
-
# https://pypi.org/project/pylodstorage/
|
|
59
|
-
'pyLodStorage>=0.13.3',
|
|
60
|
-
]
|
|
61
58
|
# LinkML support
|
|
62
59
|
# https://linkml.io/
|
|
63
60
|
linkml = [
|
|
@@ -29,7 +29,7 @@ class TestLinkML(BaseMediawikiTest):
|
|
|
29
29
|
test conversion from SiDIF to LinkML
|
|
30
30
|
"""
|
|
31
31
|
debug = self.debug
|
|
32
|
-
debug = True
|
|
32
|
+
#debug = True
|
|
33
33
|
parser = MetaModelCmd.getArgParser()
|
|
34
34
|
mm_cmd = MetaModelCmd(debug=debug)
|
|
35
35
|
for wikiId, context_name in [("wiki", "MetaModel"), ("cr", "CrSchema")]:
|
|
@@ -25,12 +25,12 @@ class TestMetaModel(BaseMediawikiTest):
|
|
|
25
25
|
"""
|
|
26
26
|
test SMW_Type handling
|
|
27
27
|
"""
|
|
28
|
-
debug =
|
|
28
|
+
debug = self.debug
|
|
29
29
|
smwAccess = self.smwAccessMap["wiki"]
|
|
30
30
|
ask_query = SMW_Type.askQuery()
|
|
31
31
|
did = smwAccess.smw.query(ask_query)
|
|
32
32
|
for record in did.values():
|
|
33
|
-
|
|
33
|
+
smw_type = SMW_Type.from_dict(record) # @UndefinedVariable
|
|
34
34
|
if debug:
|
|
35
|
-
print(
|
|
36
|
-
|
|
35
|
+
print(smw_type)
|
|
36
|
+
self.assertIsInstance(smw_type, SMW_Type)
|
|
@@ -7,7 +7,7 @@ Created on 2022-11-23
|
|
|
7
7
|
import json
|
|
8
8
|
|
|
9
9
|
from wikibot3rd.wikiuser import WikiUser
|
|
10
|
-
|
|
10
|
+
from tqdm import tqdm
|
|
11
11
|
from meta.metamodel import Context
|
|
12
12
|
from tests.basesmwtest import BaseSemanticMediawikiTest
|
|
13
13
|
|
|
@@ -137,13 +137,17 @@ class TestMediawiki(BaseSemanticMediawikiTest):
|
|
|
137
137
|
"""
|
|
138
138
|
test reading meta models from wikis
|
|
139
139
|
"""
|
|
140
|
-
debug =
|
|
140
|
+
debug = False
|
|
141
141
|
lenient = True
|
|
142
|
-
|
|
142
|
+
with_progress=False
|
|
143
|
+
wiki_users = WikiUser.getWikiUsers(lenient=True)
|
|
144
|
+
wiki_iter = tqdm(wiki_users, desc="Wikis") if with_progress else wiki_users
|
|
145
|
+
for wikiId in wiki_iter:
|
|
143
146
|
_smwAccess, mw_contexts = self.check_contexts(wikiId)
|
|
144
147
|
for context_name in mw_contexts:
|
|
148
|
+
context_info=f"{context_name}@{wikiId}"
|
|
145
149
|
if debug:
|
|
146
|
-
print(f"reading context {
|
|
150
|
+
print(f"reading context {context_info}")
|
|
147
151
|
cc = self.getContextContext(wikiId=wikiId, context_name=context_name)
|
|
148
152
|
context = cc.context
|
|
149
153
|
if not lenient:
|
|
@@ -156,8 +160,8 @@ class TestMediawiki(BaseSemanticMediawikiTest):
|
|
|
156
160
|
print(context)
|
|
157
161
|
for _name, topic in context.topics.items():
|
|
158
162
|
print(topic)
|
|
159
|
-
for _name,
|
|
160
|
-
print(
|
|
163
|
+
for _name, prop in topic.properties.items():
|
|
164
|
+
print(prop)
|
|
161
165
|
if len(context.errors) > 0:
|
|
162
166
|
for error in context.errors:
|
|
163
167
|
print(error)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.5.3"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events.mermaid
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pymetamodel-0.5.3 → pymetamodel-0.6.1}/examples/scientific-events/scientific-events_puml.txt
RENAMED
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|