stepxmlclient 1.0.0__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.
- stepxmlclient/__init__.py +22 -0
- stepxmlclient/client.py +373 -0
- stepxmlclient/creator.py +317 -0
- stepxmlclient/model/__init__.py +418 -0
- stepxmlclient/model/asset.py +250 -0
- stepxmlclient/model/attribute.py +288 -0
- stepxmlclient/model/business.py +233 -0
- stepxmlclient/model/classification.py +409 -0
- stepxmlclient/model/complex_elements.py +260 -0
- stepxmlclient/model/deletion.py +87 -0
- stepxmlclient/model/entity.py +368 -0
- stepxmlclient/model/metadata.py +199 -0
- stepxmlclient/model/organization.py +167 -0
- stepxmlclient/model/product.py +519 -0
- stepxmlclient/model/relations.py +105 -0
- stepxmlclient/model/replacement.py +417 -0
- stepxmlclient/parser.py +2805 -0
- stepxmlclient/rest_client/__init__.py +16 -0
- stepxmlclient/rest_client/base.py +388 -0
- stepxmlclient/rest_client/client.py +127 -0
- stepxmlclient/rest_client/exceptions.py +97 -0
- stepxmlclient/rest_client/models/__init__.py +175 -0
- stepxmlclient/rest_client/models/asset.py +253 -0
- stepxmlclient/rest_client/models/attribute.py +112 -0
- stepxmlclient/rest_client/models/background_process.py +23 -0
- stepxmlclient/rest_client/models/batch.py +41 -0
- stepxmlclient/rest_client/models/classification.py +57 -0
- stepxmlclient/rest_client/models/collection.py +26 -0
- stepxmlclient/rest_client/models/common.py +192 -0
- stepxmlclient/rest_client/models/context.py +16 -0
- stepxmlclient/rest_client/models/data_type_group.py +15 -0
- stepxmlclient/rest_client/models/entity.py +63 -0
- stepxmlclient/rest_client/models/event_processor.py +15 -0
- stepxmlclient/rest_client/models/import_export.py +43 -0
- stepxmlclient/rest_client/models/integration_endpoint.py +16 -0
- stepxmlclient/rest_client/models/product.py +200 -0
- stepxmlclient/rest_client/models/relations.py +280 -0
- stepxmlclient/rest_client/models/system_information.py +11 -0
- stepxmlclient/rest_client/models/user.py +28 -0
- stepxmlclient/rest_client/models/workflow.py +30 -0
- stepxmlclient/rest_client/operations/__init__.py +54 -0
- stepxmlclient/rest_client/operations/assets.py +652 -0
- stepxmlclient/rest_client/operations/attributes.py +252 -0
- stepxmlclient/rest_client/operations/background_processes.py +84 -0
- stepxmlclient/rest_client/operations/batch.py +28 -0
- stepxmlclient/rest_client/operations/classifications.py +248 -0
- stepxmlclient/rest_client/operations/collection_groups.py +46 -0
- stepxmlclient/rest_client/operations/collections.py +67 -0
- stepxmlclient/rest_client/operations/contexts.py +88 -0
- stepxmlclient/rest_client/operations/data_type_groups.py +68 -0
- stepxmlclient/rest_client/operations/entities.py +295 -0
- stepxmlclient/rest_client/operations/event_processors.py +109 -0
- stepxmlclient/rest_client/operations/exports.py +153 -0
- stepxmlclient/rest_client/operations/gateway.py +53 -0
- stepxmlclient/rest_client/operations/inbound.py +472 -0
- stepxmlclient/rest_client/operations/outbound.py +64 -0
- stepxmlclient/rest_client/operations/products.py +489 -0
- stepxmlclient/rest_client/operations/relations.py +349 -0
- stepxmlclient/rest_client/operations/reports.py +27 -0
- stepxmlclient/rest_client/operations/system_information.py +28 -0
- stepxmlclient/rest_client/operations/user_groups.py +79 -0
- stepxmlclient/rest_client/operations/users.py +119 -0
- stepxmlclient/rest_client/operations/workflow_tasks.py +61 -0
- stepxmlclient/rest_client/operations/workflows.py +50 -0
- stepxmlclient/upload.py +293 -0
- stepxmlclient-1.0.0.dist-info/METADATA +666 -0
- stepxmlclient-1.0.0.dist-info/RECORD +70 -0
- stepxmlclient-1.0.0.dist-info/WHEEL +5 -0
- stepxmlclient-1.0.0.dist-info/licenses/LICENSE +21 -0
- stepxmlclient-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
"""Classification model for STEP XML Client.
|
|
2
|
+
|
|
3
|
+
Defines the Classification entity class for representing hierarchical product categorization
|
|
4
|
+
in STEP MDM. Classifications organize products into taxonomies and support cross-references.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional, Any, Dict, TYPE_CHECKING
|
|
8
|
+
from . import BaseObject
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from .relations import ProductCrossReference, ClassificationCrossReference, EntityCrossReference, AssetCrossReference
|
|
12
|
+
from .deletion import DeleteProductCrossReference, DeleteClassificationCrossReference, DeleteEntityCrossReference, DeleteAssetCrossReference
|
|
13
|
+
from .asset import Asset
|
|
14
|
+
from .complex_elements import SequenceProduct, CurrentTasks, Task, Terms, Term, Tables
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Classification(BaseObject):
|
|
18
|
+
"""Classification entity in STEP MDM.
|
|
19
|
+
|
|
20
|
+
Common ``data`` keys:
|
|
21
|
+
- ``ID``, ``ParentID``, ``UserTypeID``, ``QualifierID``
|
|
22
|
+
- ``Name``
|
|
23
|
+
- ``KeyValue`` / ``ParentKeyValue``
|
|
24
|
+
- ``Values``
|
|
25
|
+
|
|
26
|
+
Additional supported children include ``SequenceProduct``, ``Tables``,
|
|
27
|
+
embedded ``Asset``, ``CurrentTasks`` and standard cross-references.
|
|
28
|
+
|
|
29
|
+
Usage examples:
|
|
30
|
+
Dict-first style::
|
|
31
|
+
|
|
32
|
+
cls = Classification({"ID": "C100", "UserTypeID": "UT_CLASS"})
|
|
33
|
+
cls.add_sequence_product(product_id="P100")
|
|
34
|
+
cls.add_current_task({
|
|
35
|
+
"STEPWorkflowID": "WF1",
|
|
36
|
+
"StateID": "S1",
|
|
37
|
+
"AssigneeID": "U1",
|
|
38
|
+
"AssignedToGroup": True,
|
|
39
|
+
"EntryTime": "2026-01-01T00:00:00Z",
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
Pre-built object style::
|
|
43
|
+
|
|
44
|
+
from stepxmlclient.model import SequenceProduct, Tables
|
|
45
|
+
cls = Classification({"ID": "C101", "UserTypeID": "UT_CLASS"})
|
|
46
|
+
cls.add_sequence_product(sequence_object=SequenceProduct({"ID": "P101"}))
|
|
47
|
+
cls.add_table(tables_object=Tables({"Table": [{"ID": "T1"}]}))
|
|
48
|
+
"""
|
|
49
|
+
_GROUP_NAME: str = 'classifications'
|
|
50
|
+
_TAG_NAME: str = 'Classification'
|
|
51
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "ParentID", "UserTypeID", "QualifierID", "Changed", "Republished", "Selected", "Referenced"]
|
|
52
|
+
_TEXT_NAMES: List[str] = ["Name"]
|
|
53
|
+
_CHILDREN_NAMES: List[str] = [
|
|
54
|
+
"KeyValue",
|
|
55
|
+
"ParentKeyValue",
|
|
56
|
+
"SequenceProduct",
|
|
57
|
+
"Classification", # Nested classifications
|
|
58
|
+
"DeleteSuppressedProductReference",
|
|
59
|
+
"DeleteProductReference",
|
|
60
|
+
"ProductReference",
|
|
61
|
+
"DeleteProductCrossReference",
|
|
62
|
+
"DeleteSuppressedProductCrossReference",
|
|
63
|
+
"SuppressedProductCrossReference",
|
|
64
|
+
"ProductCrossReference",
|
|
65
|
+
"DeleteSuppressedClassificationCrossReference",
|
|
66
|
+
"DeleteClassificationCrossReference",
|
|
67
|
+
"SuppressedClassificationCrossReference",
|
|
68
|
+
"ClassificationCrossReference",
|
|
69
|
+
"DeleteSuppressedEntityCrossReference",
|
|
70
|
+
"DeleteEntityCrossReference",
|
|
71
|
+
"SuppressedEntityCrossReference",
|
|
72
|
+
"EntityCrossReference",
|
|
73
|
+
"DeleteSuppressedAssetCrossReference",
|
|
74
|
+
"DeleteAssetCrossReference",
|
|
75
|
+
"SuppressedAssetCrossReference",
|
|
76
|
+
"AssetCrossReference",
|
|
77
|
+
"DeleteAttributeLink",
|
|
78
|
+
"AttributeLink",
|
|
79
|
+
"DeleteDataContainerTypeLink",
|
|
80
|
+
"DataContainerTypeLink",
|
|
81
|
+
"MetaData",
|
|
82
|
+
"Tables",
|
|
83
|
+
"Asset",
|
|
84
|
+
"PublicationGroup",
|
|
85
|
+
"CurrentTasks",
|
|
86
|
+
"Values"
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
def __init__(self, data: Dict[str, Any]) -> None:
|
|
90
|
+
super().__init__(data)
|
|
91
|
+
# Initialize relation lists if not provided
|
|
92
|
+
for rel_name in ["SequenceProduct", "ProductReference", "ProductCrossReference",
|
|
93
|
+
"DeleteSuppressedProductReference", "DeleteProductReference", "DeleteProductCrossReference",
|
|
94
|
+
"DeleteSuppressedProductCrossReference", "SuppressedProductCrossReference",
|
|
95
|
+
"ClassificationCrossReference", "DeleteClassificationCrossReference",
|
|
96
|
+
"SuppressedClassificationCrossReference", "DeleteSuppressedClassificationCrossReference",
|
|
97
|
+
"EntityCrossReference", "DeleteEntityCrossReference",
|
|
98
|
+
"SuppressedEntityCrossReference", "DeleteSuppressedEntityCrossReference",
|
|
99
|
+
"AssetCrossReference", "DeleteAssetCrossReference", "DeleteSuppressedAssetCrossReference",
|
|
100
|
+
"SuppressedAssetCrossReference", "DeleteAttributeLink", "AttributeLink",
|
|
101
|
+
"DeleteDataContainerTypeLink", "DataContainerTypeLink", "Tables", "Asset",
|
|
102
|
+
"PublicationGroup", "CurrentTasks", "Values"]:
|
|
103
|
+
if rel_name not in self._data:
|
|
104
|
+
self._data[rel_name] = []
|
|
105
|
+
|
|
106
|
+
# Initialize nested classifications list
|
|
107
|
+
if "Classification" not in self._data:
|
|
108
|
+
self._data["Classification"] = []
|
|
109
|
+
|
|
110
|
+
# ===== Product Reference Methods =====
|
|
111
|
+
|
|
112
|
+
def add_product_reference(self, product_id: Optional[str] = None,
|
|
113
|
+
type_: Optional[str] = None,
|
|
114
|
+
qualifier_id: Optional[str] = None,
|
|
115
|
+
mount_location: Optional[str] = None,
|
|
116
|
+
ref_object: Optional['ProductCrossReference'] = None) -> None:
|
|
117
|
+
"""Add ``ProductCrossReference``.
|
|
118
|
+
|
|
119
|
+
Fields: ``ProductID``, ``Type``, ``QualifierID``, ``MountLocation``.
|
|
120
|
+
"""
|
|
121
|
+
from .relations import ProductCrossReference
|
|
122
|
+
|
|
123
|
+
if ref_object is not None:
|
|
124
|
+
ref = ref_object
|
|
125
|
+
else:
|
|
126
|
+
ref = ProductCrossReference({
|
|
127
|
+
"ProductID": product_id,
|
|
128
|
+
"Type": type_,
|
|
129
|
+
"QualifierID": qualifier_id,
|
|
130
|
+
"MountLocation": mount_location
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
if not isinstance(self._data["ProductCrossReference"], list):
|
|
134
|
+
self._data["ProductCrossReference"] = []
|
|
135
|
+
self._data["ProductCrossReference"].append(ref)
|
|
136
|
+
|
|
137
|
+
def delete_product_reference(self, product_id: Optional[str] = None,
|
|
138
|
+
type_: Optional[str] = None,
|
|
139
|
+
qualifier_id: Optional[str] = None,
|
|
140
|
+
mount_location: Optional[str] = None,
|
|
141
|
+
delete_ref_object: Optional['DeleteProductCrossReference'] = None) -> None:
|
|
142
|
+
"""Add ``DeleteProductCrossReference``.
|
|
143
|
+
|
|
144
|
+
Fields: ``ProductID``, ``Type``, ``QualifierID``, ``MountLocation``.
|
|
145
|
+
"""
|
|
146
|
+
from .deletion import DeleteProductCrossReference
|
|
147
|
+
|
|
148
|
+
if delete_ref_object is not None:
|
|
149
|
+
delete_ref = delete_ref_object
|
|
150
|
+
else:
|
|
151
|
+
delete_ref = DeleteProductCrossReference({
|
|
152
|
+
"ProductID": product_id,
|
|
153
|
+
"Type": type_,
|
|
154
|
+
"QualifierID": qualifier_id,
|
|
155
|
+
"MountLocation": mount_location
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
if not isinstance(self._data["DeleteProductCrossReference"], list):
|
|
159
|
+
self._data["DeleteProductCrossReference"] = []
|
|
160
|
+
self._data["DeleteProductCrossReference"].append(delete_ref)
|
|
161
|
+
|
|
162
|
+
# ===== Classification Reference Methods =====
|
|
163
|
+
|
|
164
|
+
def add_classification_reference(self, classification_id: Optional[str] = None,
|
|
165
|
+
type_: Optional[str] = None,
|
|
166
|
+
qualifier_id: Optional[str] = None,
|
|
167
|
+
mount_location: Optional[str] = None,
|
|
168
|
+
ref_object: Optional['ClassificationCrossReference'] = None) -> None:
|
|
169
|
+
"""Add ``ClassificationCrossReference``.
|
|
170
|
+
|
|
171
|
+
Fields: ``ClassificationID``, ``Type``, ``QualifierID``,
|
|
172
|
+
``MountLocation``.
|
|
173
|
+
"""
|
|
174
|
+
from .relations import ClassificationCrossReference
|
|
175
|
+
|
|
176
|
+
if ref_object is not None:
|
|
177
|
+
ref = ref_object
|
|
178
|
+
else:
|
|
179
|
+
ref = ClassificationCrossReference({
|
|
180
|
+
"ClassificationID": classification_id,
|
|
181
|
+
"Type": type_,
|
|
182
|
+
"QualifierID": qualifier_id,
|
|
183
|
+
"MountLocation": mount_location
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
if not isinstance(self._data["ClassificationCrossReference"], list):
|
|
187
|
+
self._data["ClassificationCrossReference"] = []
|
|
188
|
+
self._data["ClassificationCrossReference"].append(ref)
|
|
189
|
+
|
|
190
|
+
def delete_classification_reference(self, classification_id: Optional[str] = None,
|
|
191
|
+
type_: Optional[str] = None,
|
|
192
|
+
qualifier_id: Optional[str] = None,
|
|
193
|
+
mount_location: Optional[str] = None,
|
|
194
|
+
delete_ref_object: Optional['DeleteClassificationCrossReference'] = None) -> None:
|
|
195
|
+
"""Add ``DeleteClassificationCrossReference``.
|
|
196
|
+
|
|
197
|
+
Fields: ``ClassificationID``, ``Type``, ``QualifierID``,
|
|
198
|
+
``MountLocation``.
|
|
199
|
+
"""
|
|
200
|
+
from .deletion import DeleteClassificationCrossReference
|
|
201
|
+
|
|
202
|
+
if delete_ref_object is not None:
|
|
203
|
+
delete_ref = delete_ref_object
|
|
204
|
+
else:
|
|
205
|
+
delete_ref = DeleteClassificationCrossReference({
|
|
206
|
+
"ClassificationID": classification_id,
|
|
207
|
+
"Type": type_,
|
|
208
|
+
"QualifierID": qualifier_id,
|
|
209
|
+
"MountLocation": mount_location
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
if not isinstance(self._data["DeleteClassificationCrossReference"], list):
|
|
213
|
+
self._data["DeleteClassificationCrossReference"] = []
|
|
214
|
+
self._data["DeleteClassificationCrossReference"].append(delete_ref)
|
|
215
|
+
|
|
216
|
+
# ===== Entity Reference Methods =====
|
|
217
|
+
|
|
218
|
+
def add_entity_reference(self, entity_id: Optional[str] = None,
|
|
219
|
+
type_: Optional[str] = None,
|
|
220
|
+
qualifier_id: Optional[str] = None,
|
|
221
|
+
mount_location: Optional[str] = None,
|
|
222
|
+
ref_object: Optional['EntityCrossReference'] = None) -> None:
|
|
223
|
+
"""Add ``EntityCrossReference``.
|
|
224
|
+
|
|
225
|
+
Fields: ``EntityID``, ``Type``, ``QualifierID``, ``MountLocation``.
|
|
226
|
+
"""
|
|
227
|
+
from .relations import EntityCrossReference
|
|
228
|
+
|
|
229
|
+
if ref_object is not None:
|
|
230
|
+
ref = ref_object
|
|
231
|
+
else:
|
|
232
|
+
ref = EntityCrossReference({
|
|
233
|
+
"EntityID": entity_id,
|
|
234
|
+
"Type": type_,
|
|
235
|
+
"QualifierID": qualifier_id,
|
|
236
|
+
"MountLocation": mount_location
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
if not isinstance(self._data["EntityCrossReference"], list):
|
|
240
|
+
self._data["EntityCrossReference"] = []
|
|
241
|
+
self._data["EntityCrossReference"].append(ref)
|
|
242
|
+
|
|
243
|
+
def delete_entity_reference(self, entity_id: Optional[str] = None,
|
|
244
|
+
type_: Optional[str] = None,
|
|
245
|
+
qualifier_id: Optional[str] = None,
|
|
246
|
+
mount_location: Optional[str] = None,
|
|
247
|
+
delete_ref_object: Optional['DeleteEntityCrossReference'] = None) -> None:
|
|
248
|
+
"""Add ``DeleteEntityCrossReference``.
|
|
249
|
+
|
|
250
|
+
Fields: ``EntityID``, ``Type``, ``QualifierID``, ``MountLocation``.
|
|
251
|
+
"""
|
|
252
|
+
from .deletion import DeleteEntityCrossReference
|
|
253
|
+
|
|
254
|
+
if delete_ref_object is not None:
|
|
255
|
+
delete_ref = delete_ref_object
|
|
256
|
+
else:
|
|
257
|
+
delete_ref = DeleteEntityCrossReference({
|
|
258
|
+
"EntityID": entity_id,
|
|
259
|
+
"Type": type_,
|
|
260
|
+
"QualifierID": qualifier_id,
|
|
261
|
+
"MountLocation": mount_location
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
if not isinstance(self._data["DeleteEntityCrossReference"], list):
|
|
265
|
+
self._data["DeleteEntityCrossReference"] = []
|
|
266
|
+
self._data["DeleteEntityCrossReference"].append(delete_ref)
|
|
267
|
+
|
|
268
|
+
# ===== Asset Reference Methods =====
|
|
269
|
+
|
|
270
|
+
def add_asset_reference(self, asset_id: Optional[str] = None,
|
|
271
|
+
type_: Optional[str] = None,
|
|
272
|
+
qualifier_id: Optional[str] = None,
|
|
273
|
+
ref_object: Optional['AssetCrossReference'] = None) -> None:
|
|
274
|
+
"""Add ``AssetCrossReference``.
|
|
275
|
+
|
|
276
|
+
Fields: ``AssetID``, ``Type``, ``QualifierID``.
|
|
277
|
+
"""
|
|
278
|
+
from .relations import AssetCrossReference
|
|
279
|
+
|
|
280
|
+
if ref_object is not None:
|
|
281
|
+
ref = ref_object
|
|
282
|
+
else:
|
|
283
|
+
ref = AssetCrossReference({
|
|
284
|
+
"AssetID": asset_id,
|
|
285
|
+
"Type": type_,
|
|
286
|
+
"QualifierID": qualifier_id
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
if not isinstance(self._data["AssetCrossReference"], list):
|
|
290
|
+
self._data["AssetCrossReference"] = []
|
|
291
|
+
self._data["AssetCrossReference"].append(ref)
|
|
292
|
+
|
|
293
|
+
def delete_asset_reference(self, asset_id: Optional[str] = None,
|
|
294
|
+
type_: Optional[str] = None,
|
|
295
|
+
qualifier_id: Optional[str] = None,
|
|
296
|
+
delete_ref_object: Optional['DeleteAssetCrossReference'] = None) -> None:
|
|
297
|
+
"""Add ``DeleteAssetCrossReference``.
|
|
298
|
+
|
|
299
|
+
Fields: ``AssetID``, ``Type``, ``QualifierID``.
|
|
300
|
+
"""
|
|
301
|
+
from .deletion import DeleteAssetCrossReference
|
|
302
|
+
|
|
303
|
+
if delete_ref_object is not None:
|
|
304
|
+
delete_ref = delete_ref_object
|
|
305
|
+
else:
|
|
306
|
+
delete_ref = DeleteAssetCrossReference({
|
|
307
|
+
"AssetID": asset_id,
|
|
308
|
+
"Type": type_,
|
|
309
|
+
"QualifierID": qualifier_id
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
if not isinstance(self._data["DeleteAssetCrossReference"], list):
|
|
313
|
+
self._data["DeleteAssetCrossReference"] = []
|
|
314
|
+
self._data["DeleteAssetCrossReference"].append(delete_ref)
|
|
315
|
+
|
|
316
|
+
def add_nested_classification(self, classification: Optional['Classification'] = None,
|
|
317
|
+
**kwargs) -> None:
|
|
318
|
+
"""Add nested ``Classification``.
|
|
319
|
+
|
|
320
|
+
Either pass ``classification`` object or provide kwargs like
|
|
321
|
+
``ID`` and ``Name``.
|
|
322
|
+
"""
|
|
323
|
+
if classification is not None:
|
|
324
|
+
nested = classification
|
|
325
|
+
else:
|
|
326
|
+
nested = Classification(kwargs)
|
|
327
|
+
|
|
328
|
+
if not isinstance(self._data["Classification"], list):
|
|
329
|
+
self._data["Classification"] = []
|
|
330
|
+
self._data["Classification"].append(nested)
|
|
331
|
+
|
|
332
|
+
def add_sequence_product(self,
|
|
333
|
+
product_id: Optional[str] = None,
|
|
334
|
+
changed: Optional[bool] = None,
|
|
335
|
+
key_values: Optional[List[Dict[str, Any]]] = None,
|
|
336
|
+
sequence_data: Optional[Dict[str, Any]] = None,
|
|
337
|
+
sequence_object: Optional['SequenceProduct'] = None) -> None:
|
|
338
|
+
"""Add ``SequenceProduct`` entry.
|
|
339
|
+
|
|
340
|
+
XSD fields: ``ID`` (required), ``Changed`` (optional), ``KeyValue``
|
|
341
|
+
(optional list).
|
|
342
|
+
"""
|
|
343
|
+
if sequence_object is not None:
|
|
344
|
+
entry: Any = sequence_object
|
|
345
|
+
elif sequence_data is not None:
|
|
346
|
+
entry = sequence_data
|
|
347
|
+
else:
|
|
348
|
+
entry = {"ID": product_id, "Changed": changed, "KeyValue": key_values}
|
|
349
|
+
|
|
350
|
+
if not isinstance(self._data.get("SequenceProduct"), list):
|
|
351
|
+
self._data["SequenceProduct"] = []
|
|
352
|
+
self._data["SequenceProduct"].append(entry)
|
|
353
|
+
|
|
354
|
+
def add_current_task(self,
|
|
355
|
+
task_data: Optional[Dict[str, Any]] = None,
|
|
356
|
+
task_object: Optional['Task'] = None,
|
|
357
|
+
current_tasks_object: Optional['CurrentTasks'] = None) -> None:
|
|
358
|
+
"""Add ``CurrentTasks`` with task entries.
|
|
359
|
+
|
|
360
|
+
Task keys: ``STEPWorkflowID``, ``StateID``, ``AssigneeID``,
|
|
361
|
+
``AssignedToGroup``, ``EntryTime``, optional ``Deadline``, ``Priority``,
|
|
362
|
+
``StatusID``.
|
|
363
|
+
"""
|
|
364
|
+
from .complex_elements import CurrentTasks, Task
|
|
365
|
+
|
|
366
|
+
if current_tasks_object is not None:
|
|
367
|
+
entry: Any = current_tasks_object
|
|
368
|
+
else:
|
|
369
|
+
task = task_object or Task(task_data or {})
|
|
370
|
+
entry = CurrentTasks({"Task": [task]})
|
|
371
|
+
|
|
372
|
+
if not isinstance(self._data.get("CurrentTasks"), list):
|
|
373
|
+
self._data["CurrentTasks"] = []
|
|
374
|
+
self._data["CurrentTasks"].append(entry)
|
|
375
|
+
|
|
376
|
+
def add_table(self,
|
|
377
|
+
table_data: Optional[Dict[str, Any]] = None,
|
|
378
|
+
tables_object: Optional['Tables'] = None) -> None:
|
|
379
|
+
"""Add ``Tables`` wrapper.
|
|
380
|
+
|
|
381
|
+
``table_data`` supports container forms like:
|
|
382
|
+
- ``{"Table": {...}}``
|
|
383
|
+
- ``{"TableDefinition": {...}}``
|
|
384
|
+
"""
|
|
385
|
+
from .complex_elements import Tables
|
|
386
|
+
|
|
387
|
+
if tables_object is not None:
|
|
388
|
+
entry: Any = tables_object
|
|
389
|
+
else:
|
|
390
|
+
payload = table_data or {}
|
|
391
|
+
if "Table" not in payload and "TableDefinition" not in payload:
|
|
392
|
+
payload = {"Table": [payload]}
|
|
393
|
+
entry = Tables(payload)
|
|
394
|
+
|
|
395
|
+
if not isinstance(self._data.get("Tables"), list):
|
|
396
|
+
self._data["Tables"] = []
|
|
397
|
+
self._data["Tables"].append(entry)
|
|
398
|
+
|
|
399
|
+
def add_asset(self, asset: Optional['Asset'] = None, **kwargs) -> None:
|
|
400
|
+
"""Add embedded ``Asset`` child.
|
|
401
|
+
|
|
402
|
+
Pass either a pre-built ``Asset`` object or kwargs for ``Asset(...)``.
|
|
403
|
+
"""
|
|
404
|
+
from .asset import Asset
|
|
405
|
+
|
|
406
|
+
entry = asset if asset is not None else Asset(kwargs)
|
|
407
|
+
if not isinstance(self._data.get("Asset"), list):
|
|
408
|
+
self._data["Asset"] = []
|
|
409
|
+
self._data["Asset"].append(entry)
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"""Complex reusable STEP XML child element models.
|
|
2
|
+
|
|
3
|
+
These classes are intended for payloads that are too complex or too easy to
|
|
4
|
+
mis-shape as plain dictionaries. They can be passed directly to Product/Asset
|
|
5
|
+
helper methods as pre-built objects.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import List, Optional
|
|
9
|
+
from . import BaseObject
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class STEPWorkflowStateBind(BaseObject):
|
|
13
|
+
"""Workflow binding for Product.
|
|
14
|
+
|
|
15
|
+
Required attributes (STEP.xsd STEPWorkflowStateBindType):
|
|
16
|
+
- WorkflowID
|
|
17
|
+
- StateID
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
_GROUP_NAME: Optional[str] = None
|
|
21
|
+
_TAG_NAME: str = "STEPWorkflowStateBind"
|
|
22
|
+
_ATTRIBUTE_NAMES: List[str] = ["WorkflowID", "StateID"]
|
|
23
|
+
_TEXT_NAMES: List[str] = []
|
|
24
|
+
_CHILDREN_NAMES: List[str] = []
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SequenceProduct(BaseObject):
|
|
28
|
+
"""Sequence information for a child product.
|
|
29
|
+
|
|
30
|
+
Required/optional fields (SequenceProductType):
|
|
31
|
+
- ID (required)
|
|
32
|
+
- Changed (optional)
|
|
33
|
+
- KeyValue (optional, repeatable)
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
_GROUP_NAME: Optional[str] = None
|
|
37
|
+
_TAG_NAME: str = "SequenceProduct"
|
|
38
|
+
_ATTRIBUTE_NAMES: List[str] = ["ID", "Changed"]
|
|
39
|
+
_TEXT_NAMES: List[str] = []
|
|
40
|
+
_CHILDREN_NAMES: List[str] = ["KeyValue"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class OverrideSubProduct(BaseObject):
|
|
44
|
+
"""Product override link.
|
|
45
|
+
|
|
46
|
+
Fields (OverrideSubProductType):
|
|
47
|
+
- ProductID (required)
|
|
48
|
+
- AnalyzerResult (optional, deprecated in XSD)
|
|
49
|
+
- Product (optional embedded object list)
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
_GROUP_NAME: Optional[str] = None
|
|
53
|
+
_TAG_NAME: str = "OverrideSubProduct"
|
|
54
|
+
_ATTRIBUTE_NAMES: List[str] = ["ProductID", "AnalyzerResult"]
|
|
55
|
+
_TEXT_NAMES: List[str] = []
|
|
56
|
+
_CHILDREN_NAMES: List[str] = ["Product"]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class PackagingReference(BaseObject):
|
|
60
|
+
"""Packaging link with quantity.
|
|
61
|
+
|
|
62
|
+
Required fields (PackagingReferenceType):
|
|
63
|
+
- ProductID
|
|
64
|
+
- Quantity
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
_GROUP_NAME: Optional[str] = None
|
|
68
|
+
_TAG_NAME: str = "PackagingReference"
|
|
69
|
+
_ATTRIBUTE_NAMES: List[str] = ["ProductID", "Quantity"]
|
|
70
|
+
_TEXT_NAMES: List[str] = []
|
|
71
|
+
_CHILDREN_NAMES: List[str] = []
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class AssetPushLocation(BaseObject):
|
|
75
|
+
"""Push status information for an asset.
|
|
76
|
+
|
|
77
|
+
Fields (AssetPushLocationType, mixed content):
|
|
78
|
+
- ConfigurationID (required)
|
|
79
|
+
- Status (optional)
|
|
80
|
+
- QualifierID (optional)
|
|
81
|
+
- value/text (optional element text)
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
_GROUP_NAME: Optional[str] = None
|
|
85
|
+
_TAG_NAME: str = "AssetPushLocation"
|
|
86
|
+
_ATTRIBUTE_NAMES: List[str] = ["Status", "ConfigurationID", "QualifierID"]
|
|
87
|
+
_TEXT_NAMES: List[str] = []
|
|
88
|
+
_VALUE_NAME: str = "value"
|
|
89
|
+
_CHILDREN_NAMES: List[str] = []
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class AssetContentSpecification(BaseObject):
|
|
93
|
+
"""Single asset conversion descriptor.
|
|
94
|
+
|
|
95
|
+
Fields (AssetContentSpecificationType):
|
|
96
|
+
- ImageConversionConfigurationID (optional)
|
|
97
|
+
- IncludesBinaryContent (optional)
|
|
98
|
+
- RelativeURL (optional)
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
_GROUP_NAME: Optional[str] = None
|
|
102
|
+
_TAG_NAME: str = "AssetContentSpecification"
|
|
103
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
104
|
+
"ImageConversionConfigurationID",
|
|
105
|
+
"IncludesBinaryContent",
|
|
106
|
+
"RelativeURL",
|
|
107
|
+
]
|
|
108
|
+
_TEXT_NAMES: List[str] = []
|
|
109
|
+
_CHILDREN_NAMES: List[str] = []
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class AssetContent(BaseObject):
|
|
113
|
+
"""Container for conversion metadata.
|
|
114
|
+
|
|
115
|
+
Fields (AssetContentType):
|
|
116
|
+
- QualifierID (optional)
|
|
117
|
+
- AssetContentSpecification (optional, repeatable)
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
_GROUP_NAME: Optional[str] = None
|
|
121
|
+
_TAG_NAME: str = "AssetContent"
|
|
122
|
+
_ATTRIBUTE_NAMES: List[str] = ["QualifierID"]
|
|
123
|
+
_TEXT_NAMES: List[str] = []
|
|
124
|
+
_CHILDREN_NAMES: List[str] = ["AssetContentSpecification"]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class BinaryContent(BaseObject):
|
|
128
|
+
"""Binary content payload wrapper.
|
|
129
|
+
|
|
130
|
+
``BinaryContent`` is a ``ConfigurationType`` element and is represented as
|
|
131
|
+
element text in this client.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
_GROUP_NAME: Optional[str] = None
|
|
135
|
+
_TAG_NAME: str = "BinaryContent"
|
|
136
|
+
_ATTRIBUTE_NAMES: List[str] = []
|
|
137
|
+
_TEXT_NAMES: List[str] = []
|
|
138
|
+
_VALUE_NAME: str = "value"
|
|
139
|
+
_CHILDREN_NAMES: List[str] = []
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class AssetBinaryContent(BaseObject):
|
|
143
|
+
"""Container for base64/binary source content metadata.
|
|
144
|
+
|
|
145
|
+
Fields (AssetBinaryContentType):
|
|
146
|
+
- QualifierID (optional)
|
|
147
|
+
- ImageConversionConfigurationID (optional)
|
|
148
|
+
- MIMEType (optional)
|
|
149
|
+
- Checksum (optional)
|
|
150
|
+
- Filename (optional)
|
|
151
|
+
- BinaryContent (required for full XSD compliance)
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
_GROUP_NAME: Optional[str] = None
|
|
155
|
+
_TAG_NAME: str = "AssetBinaryContent"
|
|
156
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
157
|
+
"QualifierID",
|
|
158
|
+
"ImageConversionConfigurationID",
|
|
159
|
+
"MIMEType",
|
|
160
|
+
"Checksum",
|
|
161
|
+
"Filename",
|
|
162
|
+
]
|
|
163
|
+
_TEXT_NAMES: List[str] = []
|
|
164
|
+
_CHILDREN_NAMES: List[str] = ["BinaryContent"]
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class Task(BaseObject):
|
|
168
|
+
"""Single workflow task entry.
|
|
169
|
+
|
|
170
|
+
Required TaskType fields:
|
|
171
|
+
- STEPWorkflowID
|
|
172
|
+
- StateID
|
|
173
|
+
- AssigneeID
|
|
174
|
+
- AssignedToGroup
|
|
175
|
+
- EntryTime
|
|
176
|
+
|
|
177
|
+
Optional fields:
|
|
178
|
+
- Deadline
|
|
179
|
+
- Priority
|
|
180
|
+
- StatusID
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
_GROUP_NAME: Optional[str] = None
|
|
184
|
+
_TAG_NAME: str = "Task"
|
|
185
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
186
|
+
"STEPWorkflowID",
|
|
187
|
+
"StateID",
|
|
188
|
+
"AssigneeID",
|
|
189
|
+
"AssignedToGroup",
|
|
190
|
+
"EntryTime",
|
|
191
|
+
"Deadline",
|
|
192
|
+
"Priority",
|
|
193
|
+
"StatusID",
|
|
194
|
+
]
|
|
195
|
+
_TEXT_NAMES: List[str] = []
|
|
196
|
+
_CHILDREN_NAMES: List[str] = []
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class CurrentTasks(BaseObject):
|
|
200
|
+
"""Container for one or more Task entries (CurrentTasksType)."""
|
|
201
|
+
|
|
202
|
+
_GROUP_NAME: Optional[str] = None
|
|
203
|
+
_TAG_NAME: str = "CurrentTasks"
|
|
204
|
+
_ATTRIBUTE_NAMES: List[str] = []
|
|
205
|
+
_TEXT_NAMES: List[str] = []
|
|
206
|
+
_CHILDREN_NAMES: List[str] = ["Task"]
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class Term(BaseObject):
|
|
210
|
+
"""Single commercial term entry (TermType, mixed text + attributes).
|
|
211
|
+
|
|
212
|
+
Optional attributes:
|
|
213
|
+
- MaximumQuantity
|
|
214
|
+
- EndDate
|
|
215
|
+
- TermsListID
|
|
216
|
+
- MinimumQuantity
|
|
217
|
+
- LeadTime
|
|
218
|
+
- UnitID
|
|
219
|
+
- StartDate
|
|
220
|
+
- LotSize
|
|
221
|
+
|
|
222
|
+
Optional text content:
|
|
223
|
+
- value
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
_GROUP_NAME: Optional[str] = None
|
|
227
|
+
_TAG_NAME: str = "Term"
|
|
228
|
+
_ATTRIBUTE_NAMES: List[str] = [
|
|
229
|
+
"MaximumQuantity",
|
|
230
|
+
"EndDate",
|
|
231
|
+
"TermsListID",
|
|
232
|
+
"MinimumQuantity",
|
|
233
|
+
"LeadTime",
|
|
234
|
+
"UnitID",
|
|
235
|
+
"StartDate",
|
|
236
|
+
"LotSize",
|
|
237
|
+
]
|
|
238
|
+
_TEXT_NAMES: List[str] = []
|
|
239
|
+
_VALUE_NAME: str = "value"
|
|
240
|
+
_CHILDREN_NAMES: List[str] = []
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class Terms(BaseObject):
|
|
244
|
+
"""Container for one or more Term entries (TermsType)."""
|
|
245
|
+
|
|
246
|
+
_GROUP_NAME: Optional[str] = None
|
|
247
|
+
_TAG_NAME: str = "Terms"
|
|
248
|
+
_ATTRIBUTE_NAMES: List[str] = []
|
|
249
|
+
_TEXT_NAMES: List[str] = []
|
|
250
|
+
_CHILDREN_NAMES: List[str] = ["Term"]
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class Tables(BaseObject):
|
|
254
|
+
"""Container for TableDefinition or Table entries (TablesType)."""
|
|
255
|
+
|
|
256
|
+
_GROUP_NAME: Optional[str] = None
|
|
257
|
+
_TAG_NAME: str = "Tables"
|
|
258
|
+
_ATTRIBUTE_NAMES: List[str] = []
|
|
259
|
+
_TEXT_NAMES: List[str] = []
|
|
260
|
+
_CHILDREN_NAMES: List[str] = ["TableDefinition", "Table"]
|