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,317 @@
1
+ """
2
+ STEP-XML Creator module.
3
+
4
+ This module provides the Creator class for serializing Python objects into STEP-XML documents.
5
+ It takes BaseObject instances representing STEP entities (Products, Assets, Attributes, etc.)
6
+ and generates valid STEP-XML that can be imported into STEP MDM systems.
7
+
8
+ The Creator maintains separate lists for each entity type and handles the complex hierarchical
9
+ structure of STEP-XML documents, including replacement rules, nested relationships, and
10
+ multi-workspace support.
11
+
12
+ Example:
13
+ Basic workflow for creating STEP-XML documents::
14
+
15
+ from stepxmlclient.creator import Creator
16
+ from stepxmlclient.model import Product, Attribute
17
+
18
+ # Create a creator for a specific context
19
+ creator = Creator(context_id='Context1', workspace_id='Main')
20
+
21
+ # Add entities
22
+ product = Product({'ID': 'P1', 'Name': {'en_US': 'Example Product'}})
23
+ creator.add(product)
24
+
25
+ # Generate XML
26
+ creator.build()
27
+ xml_string = creator.to_string()
28
+ """
29
+
30
+ import xml.etree.ElementTree as ET
31
+ from typing import List, Optional
32
+ from . import STEPXML_NS
33
+ from .model import BaseObject
34
+
35
+ class Creator:
36
+ """STEP-XML document creator for serializing Python objects.
37
+
38
+ Generates valid STEP-XML documents from BaseObject instances organized by entity type.
39
+ Supports all STEP entity types and handles the complex XML structure including
40
+ replacement rules, deletions, and multi-context/workspace configurations.
41
+
42
+ Attributes:
43
+ context_id: STEP Context ID for the document
44
+ workspace_id: STEP Workspace ID for the document
45
+ products: List of Product objects to include
46
+ assets: List of Asset objects to include
47
+ classifications: List of Classification objects to include
48
+ entities: List of Entity objects to include
49
+ attributes: List of Attribute definitions to include
50
+ attributegroups: List of Attribute Group definitions to include
51
+ listofvalues: List of List-of-Values items to include
52
+ contexts: List of Context definitions to include
53
+ qualifiers: List of Qualifier definitions to include
54
+ dimensions: List of Dimension definitions to include
55
+ usertypes: List of User Type definitions to include
56
+ linktypes: List of Link Type definitions to include
57
+ tags: List of Tag definitions to include
58
+ taggroups: List of Tag Group definitions to include
59
+ units: List of Unit definitions to include
60
+ businessrules: List of Business Rule definitions to include
61
+ workflows: List of Workflow definitions to include
62
+ collections: List of Collection objects to include
63
+ collectiongroups: List of Collection Group definitions to include
64
+ deletedproducts: List of Product deletion specifications
65
+ deletedassets: List of Asset deletion specifications
66
+ product_replacement_rules: List of Product replacement rules
67
+ replace_products: List of Products to replace
68
+ replace_classifications: List of Classifications to replace
69
+ replace_entities: List of Entities to replace
70
+ replace_assets: List of Assets to replace
71
+ replace_attributes: List of Attributes to replace
72
+ """
73
+
74
+ def __init__(
75
+ self,
76
+ context_id: str,
77
+ workspace_id: str = 'Main') -> None:
78
+ """Initialize a Creator instance.
79
+
80
+ Creates a new Creator for generating STEP-XML documents. All entity lists are
81
+ initialized as empty; populate them by calling add() or add_list() methods.
82
+
83
+ Args:
84
+ context_id: STEP Context ID to use in the generated document
85
+ (required, identifies the STEP context for import)
86
+ workspace_id: STEP Workspace ID (default: 'Main')
87
+ identifies the workspace for multi-workspace environments
88
+ """
89
+ self.context_id: str = context_id
90
+ self.workspace_id: str = workspace_id
91
+ self.root: Optional[ET.Element] = None
92
+ self.tree: Optional[ET.ElementTree] = None
93
+ self.products: List[BaseObject] = []
94
+ self.assets: List[BaseObject] = []
95
+ self.classifications: List[BaseObject] = []
96
+ self.entities: List[BaseObject] = []
97
+ self.attributes: List[BaseObject] = []
98
+ self.attributegroups: List[BaseObject] = []
99
+ self.listofvalues: List[BaseObject] = []
100
+ self.contexts: List[BaseObject] = []
101
+ self.qualifiers: List[BaseObject] = []
102
+ self.dimensions: List[BaseObject] = []
103
+ self.usertypes: List[BaseObject] = []
104
+ self.linktypes: List[BaseObject] = []
105
+ self.tags: List[BaseObject] = []
106
+ self.taggroups: List[BaseObject] = []
107
+ self.units: List[BaseObject] = []
108
+ self.businessrules: List[BaseObject] = []
109
+ self.workflows: List[BaseObject] = []
110
+ self.collections: List[BaseObject] = []
111
+ self.collectiongroups: List[BaseObject] = []
112
+ self.deletedproducts: List[BaseObject] = []
113
+ self.deletedassets: List[BaseObject] = []
114
+ self.product_replacement_rules: List[BaseObject] = []
115
+ self.replace_products: List[BaseObject] = []
116
+ self.replace_classifications: List[BaseObject] = []
117
+ self.replace_entities: List[BaseObject] = []
118
+ self.replace_assets: List[BaseObject] = []
119
+ self.replace_attributes: List[BaseObject] = []
120
+ return
121
+
122
+ def build(self) -> None:
123
+ """Build the XML document structure from added entities.
124
+
125
+ Generates the ElementTree representation of the STEP-XML document based on all
126
+ entities currently in the creator's lists. Must be called before to_string()
127
+ or to_bytes(). This method:
128
+
129
+ 1. Creates the root STEP-ProductInformation element
130
+ 2. Adds ReplacementRules section if any replacement rules exist
131
+ 3. Adds all entity sections in the correct STEP-XML order
132
+ 4. Sets the ContextID and WorkspaceID attributes
133
+
134
+ After calling build(), the XML can be accessed via to_string() or to_bytes().
135
+
136
+ Note:
137
+ The method only includes sections for entity types that have items.
138
+ Empty lists do not generate corresponding XML elements.
139
+ """
140
+ self.root = ET.Element(
141
+ 'STEP-ProductInformation',
142
+ {
143
+ "ContextID": self.context_id,
144
+ "WorkspaceID": self.workspace_id
145
+ }
146
+ )
147
+ self.tree = ET.ElementTree(self.root)
148
+ # replacement rules section (Phase 1 + Phase 7)
149
+ replacement_rules_collections = {
150
+ "Products": self.product_replacement_rules,
151
+ "Classifications": self.replace_classifications,
152
+ "Entities": self.replace_entities,
153
+ "Assets": self.replace_assets,
154
+ "Attributes": self.replace_attributes
155
+ }
156
+ # Check if any replacement rules exist
157
+ has_replacement_rules = any(replacement_rules_collections.values())
158
+ if has_replacement_rules:
159
+ rules = ET.SubElement(self.root, 'ReplacementRules')
160
+ for xml_name, collection in replacement_rules_collections.items():
161
+ if collection:
162
+ self._build_element_list(rules, xml_name, collection)
163
+ # others - map XML element names to attribute names
164
+ element_mapping = {
165
+ "Assets": "assets",
166
+ "Products": "products",
167
+ "Classifications": "classifications",
168
+ "Entities": "entities",
169
+ "Attributes": "attributes",
170
+ "AttributeGroups": "attributegroups",
171
+ "ListOfValues": "listofvalues",
172
+ "Contexts": "contexts",
173
+ "Qualifiers": "qualifiers",
174
+ "Dimensions": "dimensions",
175
+ "UserTypes": "usertypes",
176
+ "LinkTypes": "linktypes",
177
+ "Tags": "tags",
178
+ "TagGroups": "taggroups",
179
+ "Units": "units",
180
+ "BusinessRules": "businessrules",
181
+ "Workflows": "workflows",
182
+ "Collections": "collections",
183
+ "CollectionGroups": "collectiongroups",
184
+ "DeletedAssets": "deletedassets",
185
+ "DeletedProducts": "deletedproducts"
186
+ }
187
+ for xml_name, attr_name in element_mapping.items():
188
+ values = getattr(self, attr_name)
189
+ if values:
190
+ self._build_element_list(self.root, xml_name, values)
191
+ return
192
+
193
+ def _build_element_list(self, parent: ET.Element,
194
+ list_name: str,
195
+ objs: List[BaseObject]) -> None:
196
+ """Add a collection of objects as child elements to a parent element.
197
+
198
+ Internal helper method that creates a container element and populates it with
199
+ the serialized representations of the provided objects.
200
+
201
+ Args:
202
+ parent: Parent ElementTree Element to add the collection to
203
+ list_name: XML tag name for the collection container
204
+ objs: List of BaseObject instances to serialize
205
+ """
206
+ list_element = ET.SubElement(parent, list_name)
207
+ for obj in objs:
208
+ obj.to_element(list_element)
209
+ return
210
+
211
+ def add(self, obj: BaseObject) -> bool:
212
+ """Add a single object to the appropriate collection list.
213
+
214
+ Automatically routes the object to the correct list based on its _GROUP_NAME.
215
+ Objects must be instances of BaseObject subclasses with a valid _GROUP_NAME.
216
+
217
+ Args:
218
+ obj: BaseObject instance to add
219
+
220
+ Returns:
221
+ True if the object was successfully added, False if _GROUP_NAME not found
222
+ or is not a list attribute
223
+
224
+ Example:
225
+ creator = Creator('Context1')
226
+ product = Product({'ID': 'P1', 'Name': {'en_US': 'Product'}})
227
+ if creator.add(product):
228
+ print("Product added successfully")
229
+ """
230
+ if obj._GROUP_NAME is None:
231
+ return False
232
+ list_attr = getattr(self, obj._GROUP_NAME)
233
+ if isinstance(list_attr, list):
234
+ list_attr.append(obj)
235
+ return True
236
+ return False
237
+
238
+ def add_list(self, obj_list: List[BaseObject]) -> List[BaseObject]:
239
+ """Add multiple objects at once.
240
+
241
+ Attempts to add all objects in the provided list. Returns a list of any objects
242
+ that failed to be added (typically due to missing _GROUP_NAME).
243
+
244
+ Args:
245
+ obj_list: List of BaseObject instances to add
246
+
247
+ Returns:
248
+ List of objects that failed to be added (empty list if all succeeded)
249
+
250
+ Example:
251
+ creator = Creator('Context1')
252
+ products = [Product({...}), Product({...})]
253
+ failed = creator.add_list(products)
254
+ if not failed:
255
+ print("All products added successfully")
256
+ """
257
+ not_added: List[BaseObject] = []
258
+ for obj in obj_list:
259
+ if not self.add(obj):
260
+ not_added.append(obj)
261
+ return not_added
262
+
263
+ def to_bytes(self, encoding: str = 'utf-8') -> bytes:
264
+ """Serialize the XML document to bytes.
265
+
266
+ Converts the generated ElementTree to bytes with optional encoding and
267
+ XML declaration.
268
+
269
+ Args:
270
+ encoding: Character encoding for the output (default: 'utf-8')
271
+
272
+ Returns:
273
+ Bytes representation of the XML document with declaration
274
+
275
+ Raises:
276
+ RuntimeError: If build() has not been called yet
277
+
278
+ Example:
279
+ creator = Creator('Context1')
280
+ creator.add(product)
281
+ creator.build()
282
+ xml_bytes = creator.to_bytes()
283
+ """
284
+ if self.root is None:
285
+ raise RuntimeError("XML tree not built yet. Call build() first.")
286
+ return ET.tostring(
287
+ self.root,
288
+ encoding=encoding,
289
+ xml_declaration=True
290
+ )
291
+
292
+ def to_string(self, encoding: str = 'utf-8') -> str:
293
+ """Serialize the XML document to a string.
294
+
295
+ Converts the generated ElementTree to a string representation.
296
+
297
+ Args:
298
+ encoding: Character encoding to use (default: 'utf-8')
299
+
300
+ Returns:
301
+ String representation of the XML document
302
+
303
+ Raises:
304
+ RuntimeError: If build() has not been called yet
305
+
306
+ Example:
307
+ creator = Creator('Context1')
308
+ creator.add(product)
309
+ creator.build()
310
+ xml_str = creator.to_string()
311
+ print(xml_str)
312
+ """
313
+ return self.to_bytes(encoding).decode(encoding)
314
+
315
+
316
+
317
+