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,666 @@
1
+ Metadata-Version: 2.4
2
+ Name: stepxmlclient
3
+ Version: 1.0.0
4
+ Summary: Python client for Stibo Systems STEP XML and REST API v2
5
+ Author-email: everleah <everleah@hansch.info>
6
+ Maintainer-email: everleah <everleah@hansch.info>
7
+ License-Expression: MIT
8
+ Project-URL: Source, https://git.claudiapps.de/Hoerl-IM/StepXML-Client
9
+ Keywords: stibo,step,mdm,xml,rest,pim
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Text Processing :: Markup :: XML
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: requests-openapi
20
+ Requires-Dist: requests
21
+ Requires-Dist: pydantic>=2.0
22
+ Dynamic: license-file
23
+
24
+ # STEP XML Client
25
+
26
+ Python client library for Stibo Systems STEP MDM (Master Data Management), supporting the STEP-XML protocol and STEP REST API v2.
27
+
28
+ ## Overview
29
+
30
+ This library enables seamless integration with STEP systems via:
31
+ - **OIEP (Outbound Integration Endpoint)**: Retrieve data from STEP as STEP-XML
32
+ - **IIEP (Inbound Integration Endpoint)**: Send data to STEP as STEP-XML
33
+ - **REST API v2**: Grouped, typed client for STEP REST API v2
34
+
35
+ ## Current Features
36
+
37
+
38
+ **REST API v2 Client**
39
+ - 22 operation groups for STEP REST API v2
40
+ - Full CRUD, approval, values, children, data containers, purge for Products/Assets/Classifications/Entities
41
+ - Contexts, Users, User Groups, Collections, Workflows, Background Processes, Event Processors
42
+ - Inbound/Outbound/Gateway integration endpoints
43
+ - Type-safe Pydantic models, unified authentication, OpenAPI caching
44
+ - ✅ See [docs/REST_API_USAGE.md](docs/REST_API_USAGE.md) for full usage guide
45
+
46
+ STEP-XML parsing for a broad set of STEP entities, with XML generation for core entities.
47
+
48
+ ### Core Capabilities
49
+ - ✅ **STEP-XML Parsing**: Parse 20+ STEP entity types including Products, Assets, Classifications, Entities, Attributes, and more
50
+ - ✅ **STEP-XML Generation**: Create and serialize XML documents for core entities (Phase 1 complete)
51
+ - ✅ **Relationship Management**: Full support for all cross-reference types (Asset, Product, Classification, Entity)
52
+ - ✅ **REST API Integration**: Client for STEP REST API v2 authentication and operations
53
+ - ✅ **Asset Binary Upload/Download**: Upload files (images, documents) and retrieve asset content via REST API
54
+ - **Schema Validation**: XML can be validated against a STEP XSD obtained from Stibo Systems
55
+ - ✅ **Deletion Operations**: Support for product and asset deletions, link severance
56
+ - ✅ **Product Replacement Rules**: Create and manage product replacement configurations
57
+
58
+ ### Parsed Entity Types (Phase 2-14)
59
+ - **Products** - Full support with all attributes and relationships ✅
60
+ - **Assets** - Full support with key values and cross-references ✅
61
+ - **Classifications** - Full hierarchical parsing ✅
62
+ - **Entities** - Complete entity structure parsing ✅
63
+ - **Attributes** - Full attribute definition parsing ✅
64
+ - **AttributeGroups** - Hierarchical group definitions ✅
65
+ - **ListOfValues** - LOV items and associations ✅
66
+ - **Contexts, Qualifiers, Dimensions** - Configuration elements ✅
67
+ - **UserTypes, LinkTypes** - Type definitions ✅
68
+ - **Tags, TagGroups, Units** - Metadata and classification ✅
69
+ - **BusinessRules, Workflows** - Advanced configuration ✅
70
+ - **Collections, CollectionGroups** - Collection management ✅
71
+ - **Delete Operations** - Products, Assets, and link severance ✅
72
+ - **Replacement Rules** - Product replacement configurations ✅
73
+
74
+ ### Generation Capabilities (Phase 1 Complete)
75
+ - **Products** - Create with attributes, values, and cross-references
76
+ - **Assets** - Create with key values and cross-references
77
+ - **Cross-References** - All relationship types (Asset, Product, Classification, Entity)
78
+ - **Deletion Operations** - Delete products/assets and sever links
79
+ - **Product Replacement Rules** - Create replacement configurations
80
+
81
+ ## Installation
82
+
83
+
84
+ **First public release**: `1.0.0`. Package metadata and the release version are defined in `pyproject.toml`.
85
+
86
+ ```bash
87
+ # Install from PyPI (or your package repository)
88
+ pip install stepxmlclient
89
+
90
+ # Or build from source
91
+ pip install -r requirements-release.txt
92
+ python -m build
93
+ pip install dist/stepxmlclient-x.x.x-py3-none-any.whl
94
+ ```
95
+
96
+ **Requirements**:
97
+ - Python 3.9+
98
+ - requests-openapi
99
+ - requests
100
+ - pydantic>=2.0
101
+ - xml.etree.ElementTree (built-in)
102
+
103
+ ## Quick Start
104
+
105
+
106
+ ### REST API Client (Full Usage)
107
+
108
+ ```python
109
+ from stepxmlclient.client import StiboStepRestClient, BasicAuthorisation
110
+ from stepxmlclient.rest_client import StepRestClient
111
+ from stepxmlclient.rest_client.models.product import ProductCreateRequest
112
+
113
+ # Shared authentication
114
+ auth = BasicAuthorisation(user="your-username", pwd="your-password")
115
+
116
+ # 1) Direct OpenAPI access (raw operation IDs)
117
+ raw_client = StiboStepRestClient(
118
+ location_base="https://your-step-server/restapiv2",
119
+ authorisation=auth,
120
+ context="Context1"
121
+ )
122
+
123
+ # 2) Grouped wrapper access (recommended for most usage)
124
+ ops_client = StepRestClient(
125
+ location_base="https://your-step-server/restapiv2",
126
+ authorisation=auth,
127
+ context="Context1"
128
+ )
129
+
130
+ created = ops_client.products.create_product(
131
+ ProductCreateRequest(
132
+ objectType="SalesItem",
133
+ parent="RootProduct",
134
+ name="Sample Product"
135
+ )
136
+ )
137
+ retrieved = ops_client.products.get_product(created.id)
138
+ ```
139
+
140
+ See [docs/REST_API_USAGE.md](docs/REST_API_USAGE.md) for detailed usage and all operation/model examples.
141
+
142
+ ### Asset Binary Upload & Download
143
+
144
+ ```python
145
+ from stepxmlclient.client import StiboStepRestClient, BasicAuthorisation
146
+ from stepxmlclient.upload import AssetUploader
147
+
148
+ # Create authenticated client
149
+ auth = BasicAuthorisation('username', 'password')
150
+ client = StiboStepRestClient(
151
+ 'https://your-step-server.com/restapiv2',
152
+ auth
153
+ )
154
+
155
+ # Initialize uploader
156
+ uploader = AssetUploader(client)
157
+
158
+ # Upload local file to asset
159
+ result = uploader.upload_file(
160
+ file_path='product_image.jpg',
161
+ asset_id='ASSET_001',
162
+ context_id='Context1',
163
+ workspace_id='Main'
164
+ )
165
+ print(f"Upload successful: {result['asset_id']}")
166
+
167
+ # Upload from URL
168
+ result = uploader.upload_file(
169
+ file_path='https://example.com/image.jpg',
170
+ asset_id='ASSET_002',
171
+ context_id='Context1'
172
+ )
173
+
174
+ # Download asset content
175
+ content = uploader.get_content(
176
+ asset_id='ASSET_001',
177
+ context_id='Context1'
178
+ )
179
+ with open('downloaded.jpg', 'wb') as f:
180
+ f.write(content)
181
+
182
+ # Download OIEP REST delivery result by ResultURI (uses same client credentials)
183
+ result_uri = "restapi/integrationendpoints/asdf/BGP_213226/result.zip"
184
+ downloaded_file = client.download_result_uri(
185
+ result_uri,
186
+ target_dir="./downloads"
187
+ )
188
+ print(f"Result file downloaded to: {downloaded_file}")
189
+
190
+ # Or pass the complete OIEP response directly
191
+ oiep_response = {"ResultURI": "restapi/integrationendpoints/asdf/BGP_213226/result.zip"}
192
+ downloaded_file = client.download_oiep_result(
193
+ oiep_response,
194
+ target_dir="./downloads"
195
+ )
196
+ print(f"Result file downloaded to: {downloaded_file}")
197
+ ```
198
+
199
+ ### XML Parsing (Comprehensive)
200
+
201
+ ```python
202
+ from stepxmlclient.parser import Parser
203
+
204
+ # Parse STEP-XML from file
205
+ parser = Parser()
206
+ parser.parse_file('step_export.xml')
207
+
208
+ # Access parsed entities (20+ types supported)
209
+ products = parser.products
210
+ assets = parser.assets
211
+ classifications = parser.classifications
212
+ entities = parser.entities
213
+ attributes = parser.attributes
214
+ attribute_groups = parser.attribute_groups
215
+ list_of_values = parser.list_of_values
216
+ tags = parser.tags
217
+ workflows = parser.workflows
218
+ business_rules = parser.business_rules
219
+
220
+ # Handle deletion operations
221
+ deleted_products = parser.delete_products
222
+ deleted_assets = parser.delete_assets
223
+
224
+ # Example: Navigate product relationships
225
+ for product in products:
226
+ print(f"Product: {product['ID']}")
227
+ print(f" Name: {product.get('Name')}")
228
+
229
+ # Check for asset relationships
230
+ if 'AssetCrossReference' in product:
231
+ asset_ref = product['AssetCrossReference']
232
+ print(f" Asset: {asset_ref['AssetID']}")
233
+
234
+ # Check for product relationships
235
+ if 'ProductCrossReference' in product:
236
+ prod_ref = product['ProductCrossReference']
237
+ print(f" Related Product: {prod_ref['ProductID']}")
238
+
239
+ # Check for classification relationships
240
+ if 'ClassificationCrossReference' in product:
241
+ class_ref = product['ClassificationCrossReference']
242
+ print(f" Classification: {class_ref['ClassificationID']}")
243
+
244
+ # Access attribute values
245
+ if 'Values' in product:
246
+ for value in product['Values']:
247
+ print(f" {value['AttributeID']}: {value.get('Value')}")
248
+ ```
249
+
250
+ ### XML Creation
251
+
252
+ ```python
253
+ from stepxmlclient.creator import Creator
254
+ from stepxmlclient.model import Product, Asset
255
+
256
+ # Create XML document for specific context and workspace
257
+ creator = Creator(
258
+ context_id="Context1",
259
+ workspace_id="Main"
260
+ )
261
+
262
+ # Create a product with asset relationship
263
+ product = Product({
264
+ "ID": "PROD_001",
265
+ "Name": "Sample Product",
266
+ "UserTypeID": "StandardProduct",
267
+ "AssetCrossReference": {
268
+ "AssetID": "ASSET_001",
269
+ "Changed": True,
270
+ "Type": "Primary Image"
271
+ }
272
+ })
273
+
274
+ # Create an asset
275
+ asset = Asset({
276
+ "ID": "ASSET_001",
277
+ "Name": "Product Image",
278
+ "KeyValue": "IMG_001"
279
+ })
280
+
281
+ # Add entities to creator
282
+ creator.add(product)
283
+ creator.add(asset)
284
+
285
+ # Generate XML document
286
+ creator.build()
287
+
288
+ # Export as string or tree
289
+ xml_string = creator.to_string()
290
+ print(xml_string)
291
+
292
+ # Or save to file
293
+ creator.tree.write('output.xml', encoding='utf-8')
294
+ ```
295
+
296
+ ### Product Replacement Rules
297
+
298
+ ```python
299
+ from stepxmlclient.creator import Creator
300
+ from stepxmlclient.model import ProductReplacementRule
301
+
302
+ creator = Creator(context_id="Context1", workspace_id="Main")
303
+
304
+ # Create replacement rule
305
+ replacement = ProductReplacementRule({
306
+ "ID": "RULE_001",
307
+ "SourceProductID": "OLD_PROD",
308
+ "ReplacementProductID": "NEW_PROD"
309
+ })
310
+
311
+ creator.add(replacement)
312
+ creator.build()
313
+ xml_string = creator.to_string()
314
+ ```
315
+
316
+ ## Project Structure
317
+
318
+ ```
319
+ stepxmlclient/
320
+ ├── __init__.py # Namespace definitions (STEPXML_NS)
321
+ ├── client.py # StiboStepRestClient (Base client)
322
+ ├── parser.py # STEP-XML parsing engine (~2800 lines)
323
+ ├── creator.py # STEP-XML document generator
324
+ ├── upload.py # Asset binary upload/download via REST API
325
+ ├── rest_client/ # REST API v2 typed wrapper layer
326
+ │ ├── __init__.py
327
+ │ ├── client.py # StepRestClient (grouped operation wrappers)
328
+ │ ├── base.py # BaseOperation, handle_rest_errors
329
+ │ ├── exceptions.py
330
+ │ ├── models/ # Pydantic models (20 files)
331
+ │ └── operations/ # Operation groups (22 files)
332
+ └── model/ # STEP-XML object models (BaseObject)
333
+
334
+ docs/
335
+ ├── AGENTS.md
336
+ ├── REST_API_STATE.md, REST_API_USAGE.md
337
+ ├── PARSER_STATUS.md, PARSER_USAGE.md
338
+ ├── CREATOR_STATUS.md, CREATOR_USAGE.md
339
+ └── INBOUND_OPERATIONS_SUMMARY.md
340
+
341
+ examples/
342
+ ├── step_products_only.xml, step_assets_only.xml
343
+ ├── step_products_assets_refs.xml, step_asset_pixxio.xml
344
+
345
+ tests/
346
+ ├── __init__.py
347
+ ├── test.py # Manual connectivity script
348
+ ├── test_parser_phaseX_*.py # Parser phase tests
349
+ ├── test_rest_client_phaseX_*.py # REST client tests
350
+ ├── test_creator_*.py # Creator tests
351
+ ├── test_inbound_*.py # Inbound endpoint tests
352
+ └── validate_xml_xsd.py # XSD validation
353
+
354
+ ## Development
355
+
356
+ ### Build & Test
357
+
358
+ ```bash
359
+ # Install development dependencies
360
+ pip install -r requirements.txt
361
+ pip install -r requirements-release.txt
362
+
363
+ # Build wheel package
364
+ ./build_wheel.bat # Windows
365
+ # or
366
+ python -m build # Cross-platform; creates an sdist and a wheel from that sdist
367
+
368
+ # Run the unit test suite
369
+ python -m unittest discover -s tests -p "test_*.py"
370
+
371
+ # Optional: validate if STEP.xsd has been obtained from Stibo Systems
372
+ python tests/validate_xml_xsd.py
373
+ ```
374
+
375
+ The distribution does not include Stibo Systems' OpenAPI specification or XML schema. The REST client fetches the OpenAPI specification from the configured STEP server by default; alternatively, supply a licensed specification using `openapi_file`. Obtain the STEP XSD separately from Stibo Systems if you want to run schema validation.
376
+
377
+ ### Publishing to PyPI
378
+
379
+ The PyPI package is `stepxmlclient`, maintained by **everleah**
380
+ (`everleah@hansch.info`). The first successful upload creates the PyPI project;
381
+ the owner is the PyPI account that issued the upload token, not the author
382
+ metadata. Sign in as `everleah`, verify the account email and enable PyPI's
383
+ required two-factor authentication before creating a token.
384
+
385
+ From the repository root, using your Python environment:
386
+
387
+ ```powershell
388
+ .\.venv\Scripts\python.exe -m pip install -r requirements-release.txt
389
+
390
+ # Once: enter a NEW token locally at the hidden prompt, never in chat or a command.
391
+ .\upload_wheel_to_pypi.bat --configure-token
392
+
393
+ # Build and validate only; does not contact the upload endpoint.
394
+ .\upload_wheel_to_pypi.bat --check-only
395
+
396
+ # Publish the freshly built and checked wheel AND source distribution.
397
+ .\upload_wheel_to_pypi.bat
398
+ ```
399
+
400
+ Cross-platform equivalents are `python publish_pypi.py --configure-token`,
401
+ `python publish_pypi.py --check-only`, and `python publish_pypi.py --publish`.
402
+ Without an action, the Python script only builds and checks.
403
+
404
+ - Tokens are saved by `keyring` in the local OS credential store (Windows
405
+ Credential Manager on Windows), never in the repository or a `.pypirc`.
406
+ The existing Forgejo credentials remain separate; Forgejo uses the shared
407
+ modern build script when it needs to build a wheel.
408
+ - Revoke any token previously shared in chat. An account-wide token is needed
409
+ for a new project. After the first upload, replace it with a token scoped to
410
+ `stepxmlclient` by running `--configure-token` again.
411
+ - Every release uses an isolated build, builds the wheel from the sdist, checks
412
+ metadata with `twine check --strict`, and rejects specifications and credential
413
+ files in either archive. Only the two newly checked files are uploaded.
414
+ - Validated artifacts are retained in `dist\pypi\<version>`. Old files elsewhere
415
+ in `dist` are not uploaded. Failures return a nonzero exit code; existing
416
+ PyPI versions are not silently skipped.
417
+ - Before subsequent releases, update `project.version` in `pyproject.toml`,
418
+ run the relevant tests, and run `--check-only`. PyPI releases cannot be
419
+ overwritten; use a new version for changed content.
420
+ - To remove the locally saved token:
421
+ `python -m keyring delete https://upload.pypi.org/legacy/ __token__`.
422
+
423
+ ### Architecture Highlights
424
+
425
+ **Parser Architecture**:
426
+ - Stateful parser maintains separate typed lists (products, assets, classifications, etc.)
427
+ - Namespace-aware tag handling with `_get_local_tag()` for robust XML processing
428
+ - Parser functions strictly named `_parse_<element_name>()` for consistency
429
+ - Boolean conversion with `_str_to_bool()` for XML "true"/"false" strings
430
+ - ~80% STEP-XML schema coverage across 14 phases
431
+
432
+ **Creator Architecture**:
433
+ - BaseObject declarative model with `_TAG_NAME`, `_GROUP_NAME`, `_ATTRIBUTE_NAMES`, `_TEXT_NAMES`, `_CHILDREN_NAMES`
434
+ - Auto-serialization via `to_element()` based on model configuration
435
+ - Automatic routing of objects to correct collection lists via `_GROUP_NAME`
436
+ - Support for 20+ entity types with full relationship mapping
437
+
438
+ **REST Client**:
439
+ - Wraps `requests-openapi` for type-safe API calls
440
+ - Basic authentication with configurable SSL/proxy support
441
+ - OpenAPI specification caching for improved performance
442
+ - No method wrappers—access underlying client directly
443
+
444
+ ### Key Patterns
445
+
446
+ **XML Namespace Handling**:
447
+ ```python
448
+ from stepxmlclient import STEPXML_NS
449
+
450
+ # Use namespace dictionary for find operations
451
+ element.find('Products', STEPXML_NS)
452
+ element.findall('Product', STEPXML_NS)
453
+ ```
454
+
455
+ **Model Class Configuration**:
456
+ ```python
457
+ from stepxmlclient.model import BaseObject
458
+
459
+ class MyEntity(BaseObject):
460
+ _GROUP_NAME = 'my_entities' # Collection name in Creator
461
+ _TAG_NAME = 'MyEntity' # XML element tag name
462
+ _ATTRIBUTE_NAMES = ("ID", "UserTypeID") # XML attributes
463
+ _TEXT_NAMES = ("Name",) # Child text elements
464
+ _CHILDREN_NAMES = ("Values",) # Ordered child elements
465
+ ```
466
+
467
+ **Parser Function Pattern**:
468
+ ```python
469
+ def _parse_my_entity(element: ET.Element) -> dict:
470
+ """Parse MyEntity element into dictionary."""
471
+ data = {}
472
+ # Extract attributes
473
+ data['ID'] = element.get('ID')
474
+ # Extract text content
475
+ name_elem = element.find('Name', STEPXML_NS)
476
+ if name_elem is not None:
477
+ data['Name'] = name_elem.text
478
+ # Process children
479
+ data['Values'] = self._parse_item_list(element, 'Value', self._parse_value)
480
+ return data
481
+ ```
482
+
483
+ ### Testing Strategy
484
+
485
+ The project uses a phased testing approach with all test modules under `tests/`:
486
+ - **Primary coverage**: phase suites (`tests/test_parser_phaseX_*.py`, `tests/test_rest_client_phaseX_*.py`) plus focused `tests/test_*.py` modules
487
+ - **Utility script**: `tests/test.py` is a simple manual connectivity/example script
488
+ - **Phase tests**: `tests/test_parser_phaseX_*.py` target specific entity types
489
+ - **Validation**: `tests/validate_xml_xsd.py` checks generated XML when an authorized STEP XSD is available locally
490
+ - **Roundtrip tests**: `tests/test_creator_roundtrip.py` parses generated XML
491
+
492
+ When adding new functionality:
493
+ 1. Extend existing phase test or create new `tests/test_parser_phaseX_*.py`
494
+ 2. Add corresponding model class in `stepxmlclient/model/`
495
+ 3. Add parser function in `stepxmlclient/parser.py`
496
+ 4. Optionally add creator support in `stepxmlclient/creator.py`
497
+ 5. Validate with `tests/validate_xml_xsd.py`
498
+
499
+ ## Configuration
500
+
501
+ ### REST API Client
502
+
503
+ ```python
504
+ from stepxmlclient.client import StiboStepRestClient, BasicAuthorisation
505
+
506
+ # Standard configuration
507
+ auth = BasicAuthorisation('username', 'password')
508
+ client = StiboStepRestClient(
509
+ 'https://your-step-server.com/restapiv2',
510
+ auth
511
+ )
512
+
513
+ # Development - disable SSL verification
514
+ client = StiboStepRestClient(..., nocert=True)
515
+
516
+ # Or create 'nocert' file in working directory to disable SSL globally
517
+ # Production - proper certificates handled by OS certificate store
518
+
519
+ # Proxy support
520
+ client = StiboStepRestClient(
521
+ ...,
522
+ proxies={'http': 'proxy.company.com:8080',
523
+ 'https': 'proxy.company.com:8080'}
524
+ )
525
+
526
+ # OpenAPI caching for better performance
527
+ client = StiboStepRestClient(
528
+ ...,
529
+ cache_openapi=True
530
+ # Creates/uses 'openapi.json' in working directory
531
+ )
532
+ ```
533
+
534
+ ### XML Parsing Configuration
535
+
536
+ ```python
537
+ from stepxmlclient.parser import Parser
538
+
539
+ parser = Parser()
540
+
541
+ # Parse from file
542
+ parser.parse_file('data.xml')
543
+
544
+ # Parse from string
545
+ parser.parse_str(xml_string)
546
+
547
+ # Access results
548
+ products = parser.products
549
+ classifications = parser.classifications
550
+ # ... all 20+ entity types
551
+ ```
552
+
553
+ ### XML Creation Configuration
554
+
555
+ ```python
556
+ from stepxmlclient.creator import Creator
557
+
558
+ # Specify context and workspace
559
+ creator = Creator(
560
+ context_id='YourContext',
561
+ workspace_id='Main' # Default: 'Main'
562
+ )
563
+
564
+ # Generate XML with specific encoding
565
+ creator.build()
566
+ xml_bytes = creator.to_bytes(encoding='utf-8')
567
+ ```
568
+
569
+ ## Roadmap
570
+
571
+
572
+ ### REST API v2 Client (22 operation groups)
573
+
574
+ The typed wrappers cover the operations documented in the STEP REST API specification.
575
+ See [docs/REST_API_STATE.md](docs/REST_API_STATE.md) for the full coverage matrix.
576
+
577
+ ### ✅ Parser - Complete (Phase 14, ~80% coverage)
578
+
579
+ **Implemented**:
580
+ - Core entities: Products, Assets, Classifications, Entities
581
+ - Attributes system: Attributes, AttributeGroups, ListOfValues
582
+ - Configuration: Contexts, Qualifiers, Dimensions, LinkTypes, UserTypes
583
+ - Metadata: Tags, TagGroups, Units
584
+ - Advanced: BusinessRules, Workflows, Collections
585
+ - Operations: Deletion, Replacement Rules
586
+ - Relations: All cross-reference types (Asset, Product, Classification, Entity)
587
+
588
+ **Next**: Remaining 20% of STEP-XML schema (minor/specialized elements)
589
+
590
+ ### 🔄 Creator - Phase 1 Complete, Expanding (~10% coverage)
591
+
592
+ **Phase 1 Complete (Core Entities)**:
593
+ - ✅ Products with all attributes and cross-references
594
+ - ✅ Assets with key values and cross-references
595
+ - ✅ All cross-reference types
596
+ - ✅ Deletion operations
597
+ - ✅ Product replacement rules
598
+
599
+ **Phase 2 Planning (Attributes & Classification)**:
600
+ - Classifications and hierarchies
601
+ - Attributes and AttributeGroups
602
+ - ListOfValues with proper associations
603
+
604
+ **Future Phases**:
605
+ - Entities and EntityTypes
606
+ - Tags, Units, and Metadata
607
+ - Workflows and BusinessRules
608
+ - Collections and CollectionGroups
609
+ - Full parity with Parser coverage
610
+
611
+ ### Current Status Summary
612
+ - **REST API v2 Client**: 22 operation groups for STEP REST API v2
613
+ - **Parser**: Supports the documented STEP-XML entity types for data export and analysis
614
+ - **Creator**: Core functionality complete, suitable for basic import scenarios
615
+ - **Testing**: Extensive phase-based test coverage with unit and integration tests
616
+
617
+ For detailed phase status, see:
618
+ - [docs/PARSER_STATUS.md](docs/PARSER_STATUS.md)
619
+ - [docs/CREATOR_STATUS.md](docs/CREATOR_STATUS.md)
620
+ - [docs/REST_API_USAGE.md](docs/REST_API_USAGE.md)
621
+ - [docs/REST_API_STATE.md](docs/REST_API_STATE.md)
622
+
623
+ ## Core References
624
+
625
+ ### STEP Schema
626
+
627
+ The STEP XML schema is provided by Stibo Systems and is not included in this distribution. Obtain an authorized copy from Stibo Systems for schema reference or validation.
628
+
629
+ ### Documentation
630
+ - [PARSER_STATUS.md](docs/PARSER_STATUS.md) - Detailed parser feature coverage and phase breakdown
631
+ - [CREATOR_STATUS.md](docs/CREATOR_STATUS.md) - Creator implementation status and expansion roadmap
632
+ - [PARSER_USAGE.md](docs/PARSER_USAGE.md) - Parser implementation guide and patterns
633
+ - [CREATOR_USAGE.md](docs/CREATOR_USAGE.md) - Creator implementation guide and patterns
634
+
635
+ ### Requirements
636
+
637
+ - Python 3.9+
638
+ - requests-openapi - OpenAPI client generation
639
+ - requests - HTTP library
640
+ - xml.etree.ElementTree (built-in)
641
+
642
+ ## Contributing
643
+
644
+ When extending functionality:
645
+ 1. **Parser**: Add `_parse_<element>()` function, create phase test in `test_parser_phaseX_*.py`
646
+ 2. **Model**: Extend `BaseObject` with declarative configuration per project conventions
647
+ 3. **Creator**: Implement serialization in model class `to_element()` method
648
+ 4. **Schema**: Validate against a locally available, authorized STEP XSD when applicable
649
+ 5. **Tests**: Ensure coverage with roundtrip parsing + XSD validation
650
+
651
+ Follow established patterns from:
652
+ - Existing parser functions in [stepxmlclient/parser.py](stepxmlclient/parser.py)
653
+ - Model classes in [stepxmlclient/model/](stepxmlclient/model/)
654
+ - Phase tests in [tests/](tests/)
655
+
656
+ ## License
657
+
658
+ This project is licensed under the MIT License. See [LICENSE](LICENSE).
659
+
660
+ ## Security
661
+
662
+ Please report suspected vulnerabilities privately to [everleah@hansch.info](mailto:everleah@hansch.info) rather than opening a public issue.
663
+
664
+ ## Maintainer
665
+
666
+ Everleah — [everleah@hansch.info](mailto:everleah@hansch.info)