mdtpy 0.2.3__tar.gz → 0.2.4__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.
- {mdtpy-0.2.3 → mdtpy-0.2.4}/PKG-INFO +10 -3
- {mdtpy-0.2.3 → mdtpy-0.2.4}/pyproject.toml +12 -3
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/__init__.py +1 -1
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/airflow/invocation.py +4 -19
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/value.py +7 -6
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy.egg-info/PKG-INFO +10 -3
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy.egg-info/requires.txt +0 -1
- mdtpy-0.2.4/src/samples/sample_instance.py +40 -0
- mdtpy-0.2.3/src/samples/sample_instance.py +0 -20
- {mdtpy-0.2.3 → mdtpy-0.2.4}/README.md +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/setup.cfg +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/aas_misc.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/airflow/__init__.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/airflow/argument_spec.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/airflow/dag_context.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/basyx/__init__.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/basyx/serde.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/basyx/utils.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/descriptor.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/exceptions.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/fa3st.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/http_client.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/instance.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/operation.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/parameter.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/reference.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/submodel.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/timeseries.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy/utils.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy.egg-info/SOURCES.txt +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy.egg-info/dependency_links.txt +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/mdtpy.egg-info/top_level.txt +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_add_and_sleep.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_inspector_simiulation.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_multi_ops.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_operations.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_parameters.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_reference.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_submodel_elements.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/src/samples/sample_timeseries.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_aas_misc.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_descriptor.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_fa3st.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_http_client.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_instance.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_operation.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_parameter.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_submodel.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_timeseries.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_utils.py +0 -0
- {mdtpy-0.2.3 → mdtpy-0.2.4}/tests/test_value.py +0 -0
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mdtpy
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: A Python client library for the MDT (Manufacturing Digital Twin) Platform.
|
|
5
|
+
Author-email: Kang-Woo Lee <kwlee@etri.re.kr>
|
|
6
|
+
Keywords: MDT,AAS,digital-twin,manufacturing,basyx
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
5
13
|
Requires-Python: >=3.10
|
|
6
14
|
Description-Content-Type: text/markdown
|
|
7
15
|
Requires-Dist: basyx-python-sdk<3.0.0,>=2.0.0
|
|
@@ -10,7 +18,6 @@ Requires-Dist: isodate>=0.7.2
|
|
|
10
18
|
Requires-Dist: jinja2>=3.1.6
|
|
11
19
|
Requires-Dist: pandas>=2.3.3
|
|
12
20
|
Requires-Dist: requests>=2.32.5
|
|
13
|
-
Requires-Dist: tika>=3.1.0
|
|
14
21
|
Requires-Dist: typing_extensions>=4.2.0
|
|
15
22
|
Requires-Dist: urllib3<3.0.0,>=2.6.2
|
|
16
23
|
|
|
@@ -4,10 +4,20 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mdtpy"
|
|
7
|
-
version = "0.2.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.2.4"
|
|
8
|
+
description = "A Python client library for the MDT (Manufacturing Digital Twin) Platform."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
|
+
authors = [{ name = "Kang-Woo Lee", email = "kwlee@etri.re.kr" }]
|
|
12
|
+
keywords = ["MDT", "AAS", "digital-twin", "manufacturing", "basyx"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.10",
|
|
16
|
+
"Programming Language :: Python :: 3.11",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Topic :: Scientific/Engineering",
|
|
20
|
+
]
|
|
11
21
|
dependencies = [
|
|
12
22
|
"basyx-python-sdk>=2.0.0,<3.0.0",
|
|
13
23
|
"dataclass-wizard>=0.22,<1",
|
|
@@ -15,7 +25,6 @@ dependencies = [
|
|
|
15
25
|
"jinja2>=3.1.6",
|
|
16
26
|
"pandas>=2.3.3",
|
|
17
27
|
"requests>=2.32.5",
|
|
18
|
-
"tika>=3.1.0",
|
|
19
28
|
"typing_extensions>=4.2.0",
|
|
20
29
|
"urllib3>=2.6.2,<3.0.0",
|
|
21
30
|
]
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass, field
|
|
4
3
|
from typing import Optional, TypedDict
|
|
5
4
|
from typing_extensions import NotRequired
|
|
6
5
|
|
|
7
6
|
from abc import ABC, abstractmethod
|
|
8
7
|
|
|
8
|
+
import logging
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
9
11
|
from ..reference import ElementReference
|
|
10
12
|
from ..operation import OperationSubmodelService
|
|
11
13
|
from .argument_spec import ElementReferenceArgumentSpec, LiteralArgumentSpec, TaskOutputArgumentSpec
|
|
@@ -58,6 +60,7 @@ class AASOperationTaskInvocation(Invocation):
|
|
|
58
60
|
self.argument_specs = argument_specs
|
|
59
61
|
|
|
60
62
|
def run(self, context:Optional[DagContext]=None) -> None:
|
|
63
|
+
logger.info(f"Invoking operation {self.instance}:{self.submodel} with arguments {self.argument_specs}")
|
|
61
64
|
if context is None:
|
|
62
65
|
context = AirflowDagContext()
|
|
63
66
|
|
|
@@ -75,21 +78,3 @@ class AASOperationTaskInvocation(Invocation):
|
|
|
75
78
|
return ( f"{self.__class__.__name__}(task={self.instance}:{self.submodel}, "
|
|
76
79
|
f"inputs={self.argument_specs['inputs']}, "
|
|
77
80
|
f"outputs={get_output_argument_specs(self.argument_specs)})" )
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# def add_task_output_values(context:DagContext, out_arg_values:ElementValueDict,
|
|
81
|
-
# out_arg_specs_dict:dict[str, OutputArgumentSpecType]) -> None:
|
|
82
|
-
# task_id = context.task_id
|
|
83
|
-
# for arg_id, arg_value in out_arg_values.items():
|
|
84
|
-
# if arg_id not in out_arg_specs_dict:
|
|
85
|
-
# continue
|
|
86
|
-
|
|
87
|
-
# out_arg_specs = out_arg_specs_dict[arg_id]
|
|
88
|
-
# if isinstance(out_arg_specs, list):
|
|
89
|
-
# for arg_spec in out_arg_specs:
|
|
90
|
-
# if isinstance(arg_spec, OutputArgumentSpec):
|
|
91
|
-
# context.add_task_output_value(task_id, arg_id, arg_value)
|
|
92
|
-
# break
|
|
93
|
-
# else:
|
|
94
|
-
# if isinstance(out_arg_specs, OutputArgumentSpec):
|
|
95
|
-
# context.add_task_output_value(task_id, arg_id, arg_value)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import mimetypes
|
|
3
4
|
from typing import TYPE_CHECKING, Union, Optional, TypedDict, cast
|
|
4
5
|
from collections.abc import Mapping
|
|
5
6
|
|
|
@@ -120,20 +121,20 @@ def to_file_value(path: str, content_type: Optional[str] = None) -> FileValue:
|
|
|
120
121
|
"""
|
|
121
122
|
파일 경로로부터 `FileValue` TypedDict를 만든다.
|
|
122
123
|
|
|
123
|
-
`content_type`이 주어지지 않으면
|
|
124
|
-
추정한다 (
|
|
124
|
+
`content_type`이 주어지지 않으면 파일명(확장자)으로부터 MIME type을
|
|
125
|
+
추정한다 (`mimetypes.guess_type`). 확장자로 판별되지 않으면
|
|
126
|
+
`application/octet-stream`을 사용한다.
|
|
125
127
|
|
|
126
128
|
Args:
|
|
127
129
|
path (str): 파일 경로.
|
|
128
130
|
content_type (Optional[str]): 명시적 MIME type.
|
|
129
|
-
None이면
|
|
131
|
+
None이면 파일명(확장자)으로 자동 추정.
|
|
130
132
|
Returns:
|
|
131
133
|
FileValue: `{'content_type': str, 'value': <파일명>}`.
|
|
132
134
|
"""
|
|
133
135
|
if content_type is None:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
mime_type = parsed["metadata"]["Content-Type"] # type: ignore
|
|
136
|
+
guessed, _ = mimetypes.guess_type(path)
|
|
137
|
+
mime_type = guessed or "application/octet-stream"
|
|
137
138
|
else:
|
|
138
139
|
mime_type = content_type
|
|
139
140
|
return {'content_type': mime_type, 'value': Path(path).name}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mdtpy
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: A Python client library for the MDT (Manufacturing Digital Twin) Platform.
|
|
5
|
+
Author-email: Kang-Woo Lee <kwlee@etri.re.kr>
|
|
6
|
+
Keywords: MDT,AAS,digital-twin,manufacturing,basyx
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
5
13
|
Requires-Python: >=3.10
|
|
6
14
|
Description-Content-Type: text/markdown
|
|
7
15
|
Requires-Dist: basyx-python-sdk<3.0.0,>=2.0.0
|
|
@@ -10,7 +18,6 @@ Requires-Dist: isodate>=0.7.2
|
|
|
10
18
|
Requires-Dist: jinja2>=3.1.6
|
|
11
19
|
Requires-Dist: pandas>=2.3.3
|
|
12
20
|
Requires-Dist: requests>=2.32.5
|
|
13
|
-
Requires-Dist: tika>=3.1.0
|
|
14
21
|
Requires-Dist: typing_extensions>=4.2.0
|
|
15
22
|
Requires-Dist: urllib3<3.0.0,>=2.6.2
|
|
16
23
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import mdtpy
|
|
2
|
+
from mdtpy.descriptor import MDTInstanceStatus
|
|
3
|
+
from mdtpy import InvalidResourceStateError
|
|
4
|
+
|
|
5
|
+
manager = mdtpy.connect("http://localhost:12985/instance-manager")
|
|
6
|
+
|
|
7
|
+
# for inst in manager.instances:
|
|
8
|
+
# print(f"Instance: {inst.id}")
|
|
9
|
+
# print(f" Status: {inst.status}")
|
|
10
|
+
# print(f" AAS_ID: {inst.aas_id}")
|
|
11
|
+
# print(f" ServiceUrl: {inst.base_endpoint}")
|
|
12
|
+
|
|
13
|
+
# for inst in manager.instances:
|
|
14
|
+
# try:
|
|
15
|
+
# inst.start()
|
|
16
|
+
# print(f"Started instance {inst.id}")
|
|
17
|
+
# except InvalidResourceStateError as e:
|
|
18
|
+
# assert (inst.status == MDTInstanceStatus.RUNNING
|
|
19
|
+
# or inst.status == MDTInstanceStatus.FAILED)
|
|
20
|
+
# print(f"Instance {inst.id} is already running.")
|
|
21
|
+
|
|
22
|
+
for inst in manager.instances.find("instance_id = 'HEAT-01'"):
|
|
23
|
+
print(f"Instance: {inst.id}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
condition = f"parameter.id='CurrentLotNo'"
|
|
27
|
+
for inst in manager.instances.find(condition):
|
|
28
|
+
print(f"Instance {inst.id}")
|
|
29
|
+
print("----")
|
|
30
|
+
|
|
31
|
+
condition = f"parameter.id='FurnaceRecipe'"
|
|
32
|
+
for inst in manager.instances.find(condition):
|
|
33
|
+
print(f"Instance {inst.id}")
|
|
34
|
+
print("----")
|
|
35
|
+
|
|
36
|
+
condition = f"parameter.id='CurrentLotNo'"
|
|
37
|
+
for inst in manager.instances.find(condition):
|
|
38
|
+
value = inst.parameters["CurrentLotNo"].read_value()
|
|
39
|
+
print(f"Instance {inst.id} has CurrentLotNo={value}")
|
|
40
|
+
print("----")
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import mdtpy
|
|
2
|
-
from mdtpy.descriptor import MDTInstanceStatus
|
|
3
|
-
from mdtpy import InvalidResourceStateError
|
|
4
|
-
|
|
5
|
-
manager = mdtpy.connect("http://localhost:12985/instance-manager")
|
|
6
|
-
|
|
7
|
-
for inst in manager.instances:
|
|
8
|
-
print(f"Instance: {inst.id}")
|
|
9
|
-
print(f" Status: {inst.status}")
|
|
10
|
-
print(f" AAS_ID: {inst.aas_id}")
|
|
11
|
-
print(f" ServiceUrl: {inst.base_endpoint}")
|
|
12
|
-
|
|
13
|
-
for inst in manager.instances:
|
|
14
|
-
try:
|
|
15
|
-
inst.start()
|
|
16
|
-
print(f"Started instance {inst.id}")
|
|
17
|
-
except InvalidResourceStateError as e:
|
|
18
|
-
assert (inst.status == MDTInstanceStatus.RUNNING
|
|
19
|
-
or inst.status == MDTInstanceStatus.FAILED)
|
|
20
|
-
print(f"Instance {inst.id} is already running.")
|
|
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
|