rhapsody-cli 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rhapsody_cli-0.2.0/src/rhapsody_cli.egg-info → rhapsody_cli-0.2.1}/PKG-INFO +51 -18
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/README.md +50 -17
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/pyproject.toml +9 -1
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/__init__.py +2 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/abstract_action.py +46 -26
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/attribute_action.py +75 -67
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/class_action.py +85 -76
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/operation_action.py +80 -72
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/package_action.py +57 -47
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/port_action.py +63 -55
- rhapsody_cli-0.2.1/src/rhapsody_cli/actions/session_action.py +244 -0
- rhapsody_cli-0.2.1/src/rhapsody_cli/cli/cli.py +158 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/cli/formatters.py +9 -9
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/com_utils.py +6 -2
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exchange/core.py +1 -3
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exchange/exporter.py +45 -45
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exchange/importer.py +81 -69
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exchange/yaml_utils.py +4 -4
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/core.py +76 -66
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/activity/model_actions.py +2 -2
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/activity/model_activity.py +39 -39
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_actor.py +3 -3
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_class.py +7 -20
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_classifier.py +13 -45
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_operation.py +8 -7
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_statechart.py +10 -10
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_stereotype.py +5 -5
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_usecase.py +20 -9
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/common/model_misc.py +8 -8
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_collaboration.py +3 -2
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_component.py +10 -10
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_configuration.py +14 -14
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_node.py +1 -1
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_package.py +51 -51
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_project.py +17 -17
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/diagrams/model_diagram_types.py +2 -9
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/diagrams/model_diagrams.py +2 -2
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/graphics/model_graphics.py +73 -73
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/interactions/model_interactions.py +2 -2
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_dependency.py +5 -5
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_hyperlink.py +3 -3
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_instance.py +3 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_relation.py +1 -1
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/statemachine/model_statemachine.py +16 -16
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/templates/model_templates.py +3 -3
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/values/model_values.py +9 -9
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/variables/model_variables.py +8 -7
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/support/model_codegen.py +25 -25
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/support/model_files.py +2 -2
- rhapsody_cli-0.2.1/src/rhapsody_cli/session.py +119 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1/src/rhapsody_cli.egg-info}/PKG-INFO +51 -18
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli.egg-info/SOURCES.txt +2 -0
- rhapsody_cli-0.2.0/src/rhapsody_cli/cli/cli.py +0 -102
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/LICENSE +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/setup.cfg +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/actions/project_action.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/application.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/cli/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/cli/logging_config.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/cli/main.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/cli/path_resolver.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/abstract_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/attribute_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/class_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/operation_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/package_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/port_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/commands/project_command.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exceptions/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exceptions/core.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exchange/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/exchange/schema.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/activity/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_association_class.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_exception.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/classifiers/model_interface_item.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/common/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/common/model_other_model.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_component_instance.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_module.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/containment/model_profile.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/diagrams/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/graphics/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/interactions/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_association_role.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_generalization.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/relations/model_port.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/requirements/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/requirements/model_requirements.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/statemachine/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/templates/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/values/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/elements/variables/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/support/__init__.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/models/support/model_ide.py +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli/py.typed +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli.egg-info/dependency_links.txt +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli.egg-info/entry_points.txt +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli.egg-info/requires.txt +0 -0
- {rhapsody_cli-0.2.0 → rhapsody_cli-0.2.1}/src/rhapsody_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rhapsody-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Pythonic wrapper around the IBM Rhapsody COM API, mirroring the Rhapsody Java API
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.8
|
|
@@ -21,7 +21,7 @@ Dynamic: license-file
|
|
|
21
21
|
|
|
22
22
|
# rhapsody-cli
|
|
23
23
|
|
|
24
|
-
[](https://github.com/user/rhapsody-cli)
|
|
25
25
|
[](LICENSE)
|
|
26
26
|
[](https://www.python.org/downloads/)
|
|
27
27
|
[](https://www.microsoft.com/windows)
|
|
@@ -36,7 +36,7 @@ knowledge and documentation transfer directly.
|
|
|
36
36
|
- **Complete API Mirroring**: Method names and signatures match the Rhapsody Java API exactly (converted to snake_case)
|
|
37
37
|
- **Object-Oriented Design**: Clean Python classes wrapping COM objects with proper type hints
|
|
38
38
|
- **Comprehensive Element Support**: 96 Rhapsody element types wrapped with full method coverage
|
|
39
|
-
- **CLI Tools**:
|
|
39
|
+
- **CLI Tools**: Single-level commands for session management (connect, disconnect, status, version) and two-level commands for project, package, class, operation, attribute, and port management
|
|
40
40
|
- **Multi-Level Path Navigation**: Navigate hierarchical model structures using `/` or `\` separators
|
|
41
41
|
- **Bulk Operations**: Create multiple elements, list recursively, and delete with safety confirmations
|
|
42
42
|
- **Robust Error Handling**: Automatic COM error translation with user-friendly exception messages
|
|
@@ -105,7 +105,32 @@ app.quit()
|
|
|
105
105
|
|
|
106
106
|
### Command-Line Interface
|
|
107
107
|
|
|
108
|
-
The CLI provides
|
|
108
|
+
The CLI provides **single-level commands** for session management and **two-level commands** for model element operations:
|
|
109
|
+
|
|
110
|
+
**Single-Level Commands**: `connect`, `disconnect`, `status`, `version`
|
|
111
|
+
|
|
112
|
+
**Two-Level Commands**: `project`, `package`, `class`, `attribute`, `operation`, `port`
|
|
113
|
+
|
|
114
|
+
#### Session Management (Single-Level Commands)
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Connect to Rhapsody
|
|
118
|
+
rhapsody-cli connect
|
|
119
|
+
|
|
120
|
+
# Connect with options
|
|
121
|
+
rhapsody-cli connect --attach-only # Only attach to existing instance
|
|
122
|
+
rhapsody-cli connect --timeout 30 # Set session timeout (minutes)
|
|
123
|
+
rhapsody-cli connect --no-gui # Keep GUI hidden
|
|
124
|
+
|
|
125
|
+
# Show connection status
|
|
126
|
+
rhapsody-cli status
|
|
127
|
+
|
|
128
|
+
# Disconnect from Rhapsody
|
|
129
|
+
rhapsody-cli disconnect
|
|
130
|
+
|
|
131
|
+
# Show CLI version
|
|
132
|
+
rhapsody-cli version
|
|
133
|
+
```
|
|
109
134
|
|
|
110
135
|
#### Project Management
|
|
111
136
|
|
|
@@ -161,30 +186,28 @@ rhapsody-cli attribute update --path Sensors/TemperatureSensor --name threshold
|
|
|
161
186
|
rhapsody-cli attribute delete --path Sensors/TemperatureSensor --name threshold
|
|
162
187
|
```
|
|
163
188
|
|
|
164
|
-
|
|
189
|
+
### Command Options
|
|
190
|
+
|
|
191
|
+
#### Two-Level Commands
|
|
165
192
|
|
|
166
|
-
|
|
193
|
+
`--verbose`/`-v` and `--format {table,json,csv}` are specified **after** the command group name:
|
|
167
194
|
|
|
168
195
|
```bash
|
|
169
|
-
#
|
|
170
|
-
rhapsody-cli
|
|
171
|
-
rhapsody-cli export package --path Sensors "C:\Models\Sensors.yaml"
|
|
196
|
+
# Enable verbose logging
|
|
197
|
+
rhapsody-cli class list --path Sensors --verbose
|
|
172
198
|
|
|
173
|
-
#
|
|
174
|
-
rhapsody-cli
|
|
175
|
-
rhapsody-cli import package "C:\Models\Sensors.yaml"
|
|
199
|
+
# Specify output format
|
|
200
|
+
rhapsody-cli package view --path Sensors --format json
|
|
176
201
|
```
|
|
177
202
|
|
|
178
|
-
|
|
203
|
+
#### Single-Level Commands
|
|
179
204
|
|
|
180
|
-
`--verbose`/`-v`
|
|
205
|
+
`--verbose`/`-v` is available on all session management commands:
|
|
181
206
|
|
|
182
207
|
```bash
|
|
183
208
|
# Enable verbose logging
|
|
184
|
-
rhapsody-cli
|
|
185
|
-
|
|
186
|
-
# Specify output format
|
|
187
|
-
rhapsody-cli package view --path Sensors --format json
|
|
209
|
+
rhapsody-cli status --verbose
|
|
210
|
+
rhapsody-cli connect --verbose
|
|
188
211
|
```
|
|
189
212
|
|
|
190
213
|
### Multi-Instance Support
|
|
@@ -392,6 +415,16 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
392
415
|
|
|
393
416
|
## Changelog
|
|
394
417
|
|
|
418
|
+
### v0.2.1 (2026-07-26)
|
|
419
|
+
|
|
420
|
+
- **Fixed**: Resolved all mypy type annotation errors in formatters and test files for strict type checking
|
|
421
|
+
- **Fixed**: Corrected lazy import placement to comply with coding rules (moved to file beginning)
|
|
422
|
+
- **Fixed**: Resolved coding rule violations across entire source codebase
|
|
423
|
+
- **Improved**: Enhanced integration/system test GUI visibility and session management
|
|
424
|
+
- **Improved**: Applied black formatting to test fixture files for consistent code style
|
|
425
|
+
- **Updated**: Documentation and coding guidelines now include comprehensive best practices
|
|
426
|
+
- **Quality**: Test suite now passes strict mypy validation across all Python versions
|
|
427
|
+
|
|
395
428
|
### v0.2.0 (2026-07-20)
|
|
396
429
|
|
|
397
430
|
- **Breaking**: Renamed all wrapper methods from camelCase to snake_case (`addClass` → `add_class`, `getName` → `get_name`, etc.) for consistent Pythonic naming
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# rhapsody-cli
|
|
2
2
|
|
|
3
|
-
[](https://github.com/user/rhapsody-cli)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.python.org/downloads/)
|
|
6
6
|
[](https://www.microsoft.com/windows)
|
|
@@ -15,7 +15,7 @@ knowledge and documentation transfer directly.
|
|
|
15
15
|
- **Complete API Mirroring**: Method names and signatures match the Rhapsody Java API exactly (converted to snake_case)
|
|
16
16
|
- **Object-Oriented Design**: Clean Python classes wrapping COM objects with proper type hints
|
|
17
17
|
- **Comprehensive Element Support**: 96 Rhapsody element types wrapped with full method coverage
|
|
18
|
-
- **CLI Tools**:
|
|
18
|
+
- **CLI Tools**: Single-level commands for session management (connect, disconnect, status, version) and two-level commands for project, package, class, operation, attribute, and port management
|
|
19
19
|
- **Multi-Level Path Navigation**: Navigate hierarchical model structures using `/` or `\` separators
|
|
20
20
|
- **Bulk Operations**: Create multiple elements, list recursively, and delete with safety confirmations
|
|
21
21
|
- **Robust Error Handling**: Automatic COM error translation with user-friendly exception messages
|
|
@@ -84,7 +84,32 @@ app.quit()
|
|
|
84
84
|
|
|
85
85
|
### Command-Line Interface
|
|
86
86
|
|
|
87
|
-
The CLI provides
|
|
87
|
+
The CLI provides **single-level commands** for session management and **two-level commands** for model element operations:
|
|
88
|
+
|
|
89
|
+
**Single-Level Commands**: `connect`, `disconnect`, `status`, `version`
|
|
90
|
+
|
|
91
|
+
**Two-Level Commands**: `project`, `package`, `class`, `attribute`, `operation`, `port`
|
|
92
|
+
|
|
93
|
+
#### Session Management (Single-Level Commands)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Connect to Rhapsody
|
|
97
|
+
rhapsody-cli connect
|
|
98
|
+
|
|
99
|
+
# Connect with options
|
|
100
|
+
rhapsody-cli connect --attach-only # Only attach to existing instance
|
|
101
|
+
rhapsody-cli connect --timeout 30 # Set session timeout (minutes)
|
|
102
|
+
rhapsody-cli connect --no-gui # Keep GUI hidden
|
|
103
|
+
|
|
104
|
+
# Show connection status
|
|
105
|
+
rhapsody-cli status
|
|
106
|
+
|
|
107
|
+
# Disconnect from Rhapsody
|
|
108
|
+
rhapsody-cli disconnect
|
|
109
|
+
|
|
110
|
+
# Show CLI version
|
|
111
|
+
rhapsody-cli version
|
|
112
|
+
```
|
|
88
113
|
|
|
89
114
|
#### Project Management
|
|
90
115
|
|
|
@@ -140,30 +165,28 @@ rhapsody-cli attribute update --path Sensors/TemperatureSensor --name threshold
|
|
|
140
165
|
rhapsody-cli attribute delete --path Sensors/TemperatureSensor --name threshold
|
|
141
166
|
```
|
|
142
167
|
|
|
143
|
-
|
|
168
|
+
### Command Options
|
|
169
|
+
|
|
170
|
+
#### Two-Level Commands
|
|
144
171
|
|
|
145
|
-
|
|
172
|
+
`--verbose`/`-v` and `--format {table,json,csv}` are specified **after** the command group name:
|
|
146
173
|
|
|
147
174
|
```bash
|
|
148
|
-
#
|
|
149
|
-
rhapsody-cli
|
|
150
|
-
rhapsody-cli export package --path Sensors "C:\Models\Sensors.yaml"
|
|
175
|
+
# Enable verbose logging
|
|
176
|
+
rhapsody-cli class list --path Sensors --verbose
|
|
151
177
|
|
|
152
|
-
#
|
|
153
|
-
rhapsody-cli
|
|
154
|
-
rhapsody-cli import package "C:\Models\Sensors.yaml"
|
|
178
|
+
# Specify output format
|
|
179
|
+
rhapsody-cli package view --path Sensors --format json
|
|
155
180
|
```
|
|
156
181
|
|
|
157
|
-
|
|
182
|
+
#### Single-Level Commands
|
|
158
183
|
|
|
159
|
-
`--verbose`/`-v`
|
|
184
|
+
`--verbose`/`-v` is available on all session management commands:
|
|
160
185
|
|
|
161
186
|
```bash
|
|
162
187
|
# Enable verbose logging
|
|
163
|
-
rhapsody-cli
|
|
164
|
-
|
|
165
|
-
# Specify output format
|
|
166
|
-
rhapsody-cli package view --path Sensors --format json
|
|
188
|
+
rhapsody-cli status --verbose
|
|
189
|
+
rhapsody-cli connect --verbose
|
|
167
190
|
```
|
|
168
191
|
|
|
169
192
|
### Multi-Instance Support
|
|
@@ -371,6 +394,16 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
371
394
|
|
|
372
395
|
## Changelog
|
|
373
396
|
|
|
397
|
+
### v0.2.1 (2026-07-26)
|
|
398
|
+
|
|
399
|
+
- **Fixed**: Resolved all mypy type annotation errors in formatters and test files for strict type checking
|
|
400
|
+
- **Fixed**: Corrected lazy import placement to comply with coding rules (moved to file beginning)
|
|
401
|
+
- **Fixed**: Resolved coding rule violations across entire source codebase
|
|
402
|
+
- **Improved**: Enhanced integration/system test GUI visibility and session management
|
|
403
|
+
- **Improved**: Applied black formatting to test fixture files for consistent code style
|
|
404
|
+
- **Updated**: Documentation and coding guidelines now include comprehensive best practices
|
|
405
|
+
- **Quality**: Test suite now passes strict mypy validation across all Python versions
|
|
406
|
+
|
|
374
407
|
### v0.2.0 (2026-07-20)
|
|
375
408
|
|
|
376
409
|
- **Breaking**: Renamed all wrapper methods from camelCase to snake_case (`addClass` → `add_class`, `getName` → `get_name`, etc.) for consistent Pythonic naming
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rhapsody-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Pythonic wrapper around the IBM Rhapsody COM API, mirroring the Rhapsody Java API"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -68,6 +68,14 @@ ignore_missing_imports = true
|
|
|
68
68
|
module = "yaml"
|
|
69
69
|
ignore_missing_imports = true
|
|
70
70
|
|
|
71
|
+
[[tool.mypy.overrides]]
|
|
72
|
+
module = "pytest.*"
|
|
73
|
+
follow_imports = "skip"
|
|
74
|
+
|
|
75
|
+
[[tool.mypy.overrides]]
|
|
76
|
+
module = "tests.*"
|
|
77
|
+
disallow_untyped_decorators = false
|
|
78
|
+
|
|
71
79
|
[tool.pytest.ini_options]
|
|
72
80
|
testpaths = ["tests"]
|
|
73
81
|
markers = [
|
|
@@ -6,6 +6,8 @@ knowledge transfers directly. Importing this package registers all core
|
|
|
6
6
|
element wrappers with the internal ``AbstractRPModelElement.wrap()`` dispatch factory.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
__version__ = "0.2.1"
|
|
10
|
+
|
|
9
11
|
from rhapsody_cli import models # noqa: F401
|
|
10
12
|
from rhapsody_cli.application import RhapsodyApplication
|
|
11
13
|
from rhapsody_cli.exceptions import RhapsodyConnectionError, RhapsodyRuntimeException
|
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
import logging
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import List, NoReturn, Optional, cast
|
|
6
6
|
|
|
7
7
|
from rhapsody_cli.application import RhapsodyApplication
|
|
8
8
|
from rhapsody_cli.cli.formatters import OutputFormatter
|
|
9
9
|
from rhapsody_cli.cli.path_resolver import PathResolver, PathResolverError
|
|
10
10
|
from rhapsody_cli.exceptions import CliExecutionError, RhapsodyConnectionError
|
|
11
|
+
from rhapsody_cli.models.core import RPModelElement
|
|
11
12
|
from rhapsody_cli.models.elements.containment import RPProject
|
|
13
|
+
from rhapsody_cli.session import SessionManager
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class AbstractAction:
|
|
@@ -97,14 +99,7 @@ class RhapsodyContextAction(AbstractAction):
|
|
|
97
99
|
self._app = RhapsodyApplication.connect()
|
|
98
100
|
return self._app
|
|
99
101
|
|
|
100
|
-
def _print_formatted_output(
|
|
101
|
-
self,
|
|
102
|
-
data: Any,
|
|
103
|
-
headers: List[str],
|
|
104
|
-
table_rows: List[List[Any]],
|
|
105
|
-
*,
|
|
106
|
-
force_table: bool = False,
|
|
107
|
-
) -> None:
|
|
102
|
+
def _print_formatted_output(self, data: object, headers: List[str], table_rows: List[List[str]], *, force_table: bool = False) -> None:
|
|
108
103
|
"""Format `data` per this action's output_format and print to stdout.
|
|
109
104
|
|
|
110
105
|
Result data goes to stdout (not the logger) so it stays safe for
|
|
@@ -122,6 +117,7 @@ class RhapsodyContextAction(AbstractAction):
|
|
|
122
117
|
output = OutputFormatter.json_format(data)
|
|
123
118
|
else:
|
|
124
119
|
output = OutputFormatter.table(headers, table_rows)
|
|
120
|
+
# NOTE: Result data to stdout (not logger) so it stays safe for piping/redirection.
|
|
125
121
|
print(output)
|
|
126
122
|
|
|
127
123
|
def _handle_connection_error(self, error: RhapsodyConnectionError, context_msg: str = "") -> NoReturn:
|
|
@@ -155,6 +151,42 @@ class RhapsodyContextAction(AbstractAction):
|
|
|
155
151
|
raise CliExecutionError(f"Error: {error}") from error
|
|
156
152
|
|
|
157
153
|
|
|
154
|
+
class SessionAwareAction(RhapsodyContextAction):
|
|
155
|
+
"""Base class for actions that require a valid session.
|
|
156
|
+
|
|
157
|
+
Extends RhapsodyContextAction to enforce session pre-check before execution.
|
|
158
|
+
All element actions (project, package, class, etc.) should inherit from this class.
|
|
159
|
+
|
|
160
|
+
Usage:
|
|
161
|
+
Subclasses should call super().execute(args) at the start of their execute()
|
|
162
|
+
method to trigger the session check.
|
|
163
|
+
|
|
164
|
+
Raises:
|
|
165
|
+
CliExecutionError: If session is not valid or not connected.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
def execute(self, args: argparse.Namespace) -> None:
|
|
169
|
+
"""Check session validity before allowing execution.
|
|
170
|
+
|
|
171
|
+
This method does NOT call super().execute() - it only performs the session
|
|
172
|
+
check and returns. Subclasses should call this via super().execute(args)
|
|
173
|
+
at the start of their execute() method.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
args: Parsed command-line arguments.
|
|
177
|
+
|
|
178
|
+
Raises:
|
|
179
|
+
CliExecutionError: If not connected or session timed out.
|
|
180
|
+
"""
|
|
181
|
+
session_manager = SessionManager()
|
|
182
|
+
session = session_manager.load()
|
|
183
|
+
|
|
184
|
+
if not session or not session_manager.is_valid(session):
|
|
185
|
+
raise CliExecutionError("Not connected. Run 'rhapsody-cli connect' first.")
|
|
186
|
+
|
|
187
|
+
session_manager.update_activity(session)
|
|
188
|
+
|
|
189
|
+
|
|
158
190
|
class ElementManagementAction(RhapsodyContextAction):
|
|
159
191
|
"""Base class for element management actions (add, delete, query, view).
|
|
160
192
|
|
|
@@ -167,12 +199,7 @@ class ElementManagementAction(RhapsodyContextAction):
|
|
|
167
199
|
_RECURSIVE_DELETE_HELP = "Delete the element and all elements nested within it"
|
|
168
200
|
|
|
169
201
|
@staticmethod
|
|
170
|
-
def add_path_argument(
|
|
171
|
-
parser: argparse.ArgumentParser,
|
|
172
|
-
*,
|
|
173
|
-
required: bool = False,
|
|
174
|
-
help_text: str = _PATH_ARGUMENT_HELP,
|
|
175
|
-
) -> None:
|
|
202
|
+
def add_path_argument(parser: argparse.ArgumentParser, *, required: bool = False, help_text: str = _PATH_ARGUMENT_HELP) -> None:
|
|
176
203
|
"""Add the shared --path argument to a subcommand parser.
|
|
177
204
|
|
|
178
205
|
Args:
|
|
@@ -210,7 +237,7 @@ class ElementManagementAction(RhapsodyContextAction):
|
|
|
210
237
|
except RhapsodyConnectionError as e:
|
|
211
238
|
self._handle_connection_error(e)
|
|
212
239
|
|
|
213
|
-
def _get_active_root(self) ->
|
|
240
|
+
def _get_active_root(self) -> RPModelElement:
|
|
214
241
|
"""Return the root element of the active project.
|
|
215
242
|
|
|
216
243
|
Returns:
|
|
@@ -218,14 +245,7 @@ class ElementManagementAction(RhapsodyContextAction):
|
|
|
218
245
|
"""
|
|
219
246
|
return self._get_active_project().get_root()
|
|
220
247
|
|
|
221
|
-
def _resolve_container_or_element(
|
|
222
|
-
self,
|
|
223
|
-
root: Any,
|
|
224
|
-
path: Optional[str],
|
|
225
|
-
*,
|
|
226
|
-
resolve_element: bool,
|
|
227
|
-
operation: str = "resolve path",
|
|
228
|
-
) -> Any:
|
|
248
|
+
def _resolve_container_or_element(self, root: RPModelElement, path: Optional[str], *, resolve_element: bool, operation: str = "resolve path") -> RPModelElement:
|
|
229
249
|
"""Resolve `path` to a container or element, mapping errors to CliExecutionError.
|
|
230
250
|
|
|
231
251
|
Args:
|
|
@@ -250,8 +270,8 @@ class ElementManagementAction(RhapsodyContextAction):
|
|
|
250
270
|
if resolve_element:
|
|
251
271
|
if path is None:
|
|
252
272
|
raise CliExecutionError(f"A path is required to {operation}")
|
|
253
|
-
return PathResolver.resolve_element(root, path)
|
|
254
|
-
return PathResolver.resolve_container(root, path)
|
|
273
|
+
return cast(RPModelElement, PathResolver.resolve_element(root, path))
|
|
274
|
+
return cast(RPModelElement, PathResolver.resolve_container(root, path))
|
|
255
275
|
except PathResolverError as e:
|
|
256
276
|
self.logger.error("%s", e)
|
|
257
277
|
raise CliExecutionError(str(e)) from e
|