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.
Files changed (70) hide show
  1. stepxmlclient/__init__.py +22 -0
  2. stepxmlclient/client.py +373 -0
  3. stepxmlclient/creator.py +317 -0
  4. stepxmlclient/model/__init__.py +418 -0
  5. stepxmlclient/model/asset.py +250 -0
  6. stepxmlclient/model/attribute.py +288 -0
  7. stepxmlclient/model/business.py +233 -0
  8. stepxmlclient/model/classification.py +409 -0
  9. stepxmlclient/model/complex_elements.py +260 -0
  10. stepxmlclient/model/deletion.py +87 -0
  11. stepxmlclient/model/entity.py +368 -0
  12. stepxmlclient/model/metadata.py +199 -0
  13. stepxmlclient/model/organization.py +167 -0
  14. stepxmlclient/model/product.py +519 -0
  15. stepxmlclient/model/relations.py +105 -0
  16. stepxmlclient/model/replacement.py +417 -0
  17. stepxmlclient/parser.py +2805 -0
  18. stepxmlclient/rest_client/__init__.py +16 -0
  19. stepxmlclient/rest_client/base.py +388 -0
  20. stepxmlclient/rest_client/client.py +127 -0
  21. stepxmlclient/rest_client/exceptions.py +97 -0
  22. stepxmlclient/rest_client/models/__init__.py +175 -0
  23. stepxmlclient/rest_client/models/asset.py +253 -0
  24. stepxmlclient/rest_client/models/attribute.py +112 -0
  25. stepxmlclient/rest_client/models/background_process.py +23 -0
  26. stepxmlclient/rest_client/models/batch.py +41 -0
  27. stepxmlclient/rest_client/models/classification.py +57 -0
  28. stepxmlclient/rest_client/models/collection.py +26 -0
  29. stepxmlclient/rest_client/models/common.py +192 -0
  30. stepxmlclient/rest_client/models/context.py +16 -0
  31. stepxmlclient/rest_client/models/data_type_group.py +15 -0
  32. stepxmlclient/rest_client/models/entity.py +63 -0
  33. stepxmlclient/rest_client/models/event_processor.py +15 -0
  34. stepxmlclient/rest_client/models/import_export.py +43 -0
  35. stepxmlclient/rest_client/models/integration_endpoint.py +16 -0
  36. stepxmlclient/rest_client/models/product.py +200 -0
  37. stepxmlclient/rest_client/models/relations.py +280 -0
  38. stepxmlclient/rest_client/models/system_information.py +11 -0
  39. stepxmlclient/rest_client/models/user.py +28 -0
  40. stepxmlclient/rest_client/models/workflow.py +30 -0
  41. stepxmlclient/rest_client/operations/__init__.py +54 -0
  42. stepxmlclient/rest_client/operations/assets.py +652 -0
  43. stepxmlclient/rest_client/operations/attributes.py +252 -0
  44. stepxmlclient/rest_client/operations/background_processes.py +84 -0
  45. stepxmlclient/rest_client/operations/batch.py +28 -0
  46. stepxmlclient/rest_client/operations/classifications.py +248 -0
  47. stepxmlclient/rest_client/operations/collection_groups.py +46 -0
  48. stepxmlclient/rest_client/operations/collections.py +67 -0
  49. stepxmlclient/rest_client/operations/contexts.py +88 -0
  50. stepxmlclient/rest_client/operations/data_type_groups.py +68 -0
  51. stepxmlclient/rest_client/operations/entities.py +295 -0
  52. stepxmlclient/rest_client/operations/event_processors.py +109 -0
  53. stepxmlclient/rest_client/operations/exports.py +153 -0
  54. stepxmlclient/rest_client/operations/gateway.py +53 -0
  55. stepxmlclient/rest_client/operations/inbound.py +472 -0
  56. stepxmlclient/rest_client/operations/outbound.py +64 -0
  57. stepxmlclient/rest_client/operations/products.py +489 -0
  58. stepxmlclient/rest_client/operations/relations.py +349 -0
  59. stepxmlclient/rest_client/operations/reports.py +27 -0
  60. stepxmlclient/rest_client/operations/system_information.py +28 -0
  61. stepxmlclient/rest_client/operations/user_groups.py +79 -0
  62. stepxmlclient/rest_client/operations/users.py +119 -0
  63. stepxmlclient/rest_client/operations/workflow_tasks.py +61 -0
  64. stepxmlclient/rest_client/operations/workflows.py +50 -0
  65. stepxmlclient/upload.py +293 -0
  66. stepxmlclient-1.0.0.dist-info/METADATA +666 -0
  67. stepxmlclient-1.0.0.dist-info/RECORD +70 -0
  68. stepxmlclient-1.0.0.dist-info/WHEEL +5 -0
  69. stepxmlclient-1.0.0.dist-info/licenses/LICENSE +21 -0
  70. 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"]