shellsmith 0.1.0__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.
Files changed (34) hide show
  1. shellsmith-0.1.0/LICENSE +21 -0
  2. shellsmith-0.1.0/PKG-INFO +215 -0
  3. shellsmith-0.1.0/README.md +170 -0
  4. shellsmith-0.1.0/pyproject.toml +37 -0
  5. shellsmith-0.1.0/setup.cfg +4 -0
  6. shellsmith-0.1.0/src/shellsmith/__init__.py +18 -0
  7. shellsmith-0.1.0/src/shellsmith/__main__.py +4 -0
  8. shellsmith-0.1.0/src/shellsmith/cli/__init__.py +0 -0
  9. shellsmith-0.1.0/src/shellsmith/cli/commands/__init__.py +5 -0
  10. shellsmith-0.1.0/src/shellsmith/cli/commands/info.py +47 -0
  11. shellsmith-0.1.0/src/shellsmith/cli/commands/nuke.py +9 -0
  12. shellsmith-0.1.0/src/shellsmith/cli/commands/shell.py +17 -0
  13. shellsmith-0.1.0/src/shellsmith/cli/commands/submodel.py +16 -0
  14. shellsmith-0.1.0/src/shellsmith/cli/commands/upload.py +14 -0
  15. shellsmith-0.1.0/src/shellsmith/cli/main.py +44 -0
  16. shellsmith-0.1.0/src/shellsmith/cli/parser.py +63 -0
  17. shellsmith-0.1.0/src/shellsmith/config.py +15 -0
  18. shellsmith-0.1.0/src/shellsmith/crud/__init__.py +0 -0
  19. shellsmith-0.1.0/src/shellsmith/crud/shells.py +61 -0
  20. shellsmith-0.1.0/src/shellsmith/crud/submodels.py +126 -0
  21. shellsmith-0.1.0/src/shellsmith/services.py +131 -0
  22. shellsmith-0.1.0/src/shellsmith/upload.py +40 -0
  23. shellsmith-0.1.0/src/shellsmith/utils.py +35 -0
  24. shellsmith-0.1.0/src/shellsmith.egg-info/PKG-INFO +215 -0
  25. shellsmith-0.1.0/src/shellsmith.egg-info/SOURCES.txt +32 -0
  26. shellsmith-0.1.0/src/shellsmith.egg-info/dependency_links.txt +1 -0
  27. shellsmith-0.1.0/src/shellsmith.egg-info/entry_points.txt +2 -0
  28. shellsmith-0.1.0/src/shellsmith.egg-info/requires.txt +10 -0
  29. shellsmith-0.1.0/src/shellsmith.egg-info/top_level.txt +1 -0
  30. shellsmith-0.1.0/tests/test_cli.py +110 -0
  31. shellsmith-0.1.0/tests/test_cli_integration.py +59 -0
  32. shellsmith-0.1.0/tests/test_crud.py +123 -0
  33. shellsmith-0.1.0/tests/test_upload.py +12 -0
  34. shellsmith-0.1.0/tests/test_utils.py +27 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Peter Stein
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,215 @@
1
+ Metadata-Version: 2.4
2
+ Name: shellsmith
3
+ Version: 0.1.0
4
+ Summary: A Python toolkit and CLI for managing Asset Administration Shells
5
+ Author-email: Peter Stein <peterstein@dfki.de>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Peter Stein
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/ptrstn/shellsmith
29
+ Project-URL: Issues, https://github.com/ptrstn/shellsmith/issues
30
+ Classifier: Programming Language :: Python :: 3
31
+ Classifier: Operating System :: OS Independent
32
+ Requires-Python: >=3.10
33
+ Description-Content-Type: text/markdown
34
+ License-File: LICENSE
35
+ Requires-Dist: pydantic-settings
36
+ Requires-Dist: requests
37
+ Provides-Extra: test
38
+ Requires-Dist: black; extra == "test"
39
+ Requires-Dist: flake8; extra == "test"
40
+ Requires-Dist: isort; extra == "test"
41
+ Requires-Dist: pytest; extra == "test"
42
+ Requires-Dist: pytest-cov; extra == "test"
43
+ Requires-Dist: pytest-dotenv; extra == "test"
44
+ Dynamic: license-file
45
+
46
+ [![Python Package](https://github.com/ptrstn/shellsmith/actions/workflows/python-package.yaml/badge.svg)](https://github.com/ptrstn/shellsmith/actions/workflows/python-package.yaml)
47
+ [![codecov](https://codecov.io/gh/ptrstn/shellsmith/branch/main/graph/badge.svg)](https://codecov.io/gh/ptrstn/shellsmith)
48
+ [![PyPI version](https://badge.fury.io/py/shellsmith.svg)](https://badge.fury.io/py/shellsmith)
49
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
50
+
51
+ # Shellsmith
52
+
53
+ Shellsmith is a Python toolkit and CLI for managing Asset Administration Shells (AAS), Submodels, and related resources.
54
+ It is designed to interact with [Eclipse BaSyx](https://www.eclipse.org/basyx/), a middleware platform for AAS that follows the [Industry 4.0 standard](https://industrialdigitaltwin.org/en/content-hub/aasspecifications).
55
+
56
+ ### Features
57
+
58
+ - Python API for CRUD operations on shells, submodels, and submodel elements
59
+ - CLI interface for quick scripting
60
+ - `.env`-based configuration
61
+
62
+ ## 🚀 Installation
63
+
64
+ ```bash
65
+ pip install shellsmith
66
+ ```
67
+
68
+ **Requires**: Python 3.10+
69
+
70
+ ## 🔧 Configuration
71
+
72
+ The default AAS environment host is:
73
+
74
+ ```
75
+ http://localhost:8081
76
+ ```
77
+
78
+ You can override it by setting the `SHELLSMITH_BASYX_ENV_HOST` environment variable, or by creating a `.env` file in your project root with:
79
+
80
+ ```bash
81
+ SHELLSMITH_BASYX_ENV_HOST=http://your-host:1234
82
+ ```
83
+
84
+ ## 🛠️ Usage
85
+
86
+ ```bash
87
+ aas --help
88
+ ```
89
+
90
+ Common commands:
91
+
92
+ ```bash
93
+ aas info # Show all shells and submodels
94
+ aas upload <file|folder> # Upload AAS file or folder
95
+ aas shell delete <id> # Delete a shell
96
+ aas submodel delete <id> # Delete a submodel
97
+ ```
98
+
99
+ Use `--cascade` or `--unlink` to control deletion behavior:
100
+
101
+ ```bash
102
+ aas shell delete <id> --cascade # Also delete referenced submodels
103
+ aas submodel delete <id> --unlink # Remove references from shells
104
+ ```
105
+
106
+ ## 📡 API Usage
107
+
108
+ You can also use `shellsmith` as a Python package:
109
+
110
+ ```python
111
+ import shellsmith
112
+
113
+ # Get all available shells
114
+ shells = shellsmith.get_shells()
115
+
116
+ # Get a specific shell by ID (automatically base64-encoded)
117
+ shell = shellsmith.get_shell("example_aas_id")
118
+
119
+ # Disable base64 encoding if your ID is already encoded
120
+ submodel = shellsmith.get_submodel("ZXhhbXBsZV9hYXNfaWQ=", encode=False)
121
+
122
+ # Use a custom AAS environment host
123
+ submodel_refs = shellsmith.get_submodel_refs("example_aas_id", host="http://localhost:8081")
124
+ ```
125
+
126
+ > ℹ️ `shell_id` and `submodel_id` are automatically base64-encoded unless you set `encode=False`. This is required by the BaSyx API for identifier-based URLs.
127
+
128
+ The tables below show the mapping between BaSyx AAS REST API endpoints and the implemented client functions.
129
+
130
+ > 📚 See [Plattform_i40 API reference](https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection) for endpoint details.
131
+
132
+ ### Shells
133
+
134
+ | Method | BaSyx Endpoint | Shellsmith Function |
135
+ |--------|--------------------------------------------------------------|-----------------------|
136
+ | GET | `/shells` | `get_shells` |
137
+ | POST | `/shells` | ❌ |
138
+ | GET | `/shells/{aasIdentifier}` | `get_shell` |
139
+ | PUT | `/shells/{aasIdentifier}` | ❌ |
140
+ | DELETE | `/shells/{aasIdentifier}` | `delete_shell` |
141
+ | GET | `/shells/{aasIdentifier}/submodel-refs` | `get_submodel_refs` |
142
+ | POST | `/shells/{aasIdentifier}/submodel-refs` | ❌ |
143
+ | DELETE | `/shells/{aasIdentifier}/submodel-refs/{submodelIdentifier}` | `delete_submodel_ref` |
144
+
145
+ ### Submodels
146
+
147
+ | Method | BaSyx Endpoint | Shellsmith Function |
148
+ |--------|---------------------------------------------|---------------------|
149
+ | GET | `/submodels` | `get_submodels` |
150
+ | POST | `/submodels` | ❌ |
151
+ | GET | `/submodels/{submodelIdentifier}` | `get_submodel` |
152
+ | PUT | `/submodels/{submodelIdentifier}` | ❌ |
153
+ | DELETE | `/submodels/{submodelIdentifier}` | `delete_submodel` |
154
+ | GET | `/submodels/{submodelIdentifier}/$value` | ❌ |
155
+ | PATCH | `/submodels/{submodelIdentifier}/$value` | ❌ |
156
+ | GET | `/submodels/{submodelIdentifier}/$metadata` | ❌ |
157
+
158
+ ### Submodel Elements
159
+
160
+ | Method | BaSyx Endpoint | Shellsmith Function |
161
+ |--------|--------------------------------------------------------------------------|--------------------------------|
162
+ | GET | `/submodels/{submodelIdentifier}/submodel-elements` | `get_submodel_elements` |
163
+ | POST | `/submodels/{submodelIdentifier}/submodel-elements` | ❌ |
164
+ | GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `get_submodel_element` |
165
+ | PUT | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | ❌ |
166
+ | POST | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | ❌ |
167
+ | DELETE | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `delete_submodel_element` |
168
+ | GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | ❌ |
169
+ | PATCH | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | `patch_submodel_element_value` |
170
+
171
+ ### Upload
172
+
173
+ | Method | BaSyx Endpoint | Shellsmith Function |
174
+ |--------|----------------|-----------------------------------------------------|
175
+ | POST | `/upload` | `upload.upload_aas` <br> `upload.upload_aas_folder` |
176
+
177
+ > ℹ️ Upload functions are available under the `shellsmith.upload` submodule.
178
+
179
+ ## ⚙️ Development
180
+
181
+ ```bash
182
+ git clone https://github.com/ptrstn/shellsmith
183
+ cd shellsmith
184
+ python -m venv .venv
185
+ source .venv/bin/activate # or .venv\Scripts\activate on Windows
186
+ pip install -e .[test]
187
+ ```
188
+
189
+ ### ✅ Testing
190
+
191
+ Before running the tests, make sure the BaSyx stack is up and running:
192
+
193
+ ```bash
194
+ docker compose up -d
195
+ ```
196
+
197
+ Then run the test suite with coverage:
198
+
199
+ ```bash
200
+ pytest --cov
201
+ ```
202
+
203
+ To view a detailed, visual coverage report:
204
+
205
+ ```bash
206
+ pytest --cov --cov-report=html
207
+ ```
208
+
209
+ Then open `htmlcov/index.html` in your web browser to explore which lines are covered and which are missing.
210
+
211
+ ## Resources
212
+
213
+ - https://github.com/eclipse-basyx/basyx-java-server-sdk
214
+ - https://github.com/admin-shell-io/aas-specs-api
215
+ - https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection
@@ -0,0 +1,170 @@
1
+ [![Python Package](https://github.com/ptrstn/shellsmith/actions/workflows/python-package.yaml/badge.svg)](https://github.com/ptrstn/shellsmith/actions/workflows/python-package.yaml)
2
+ [![codecov](https://codecov.io/gh/ptrstn/shellsmith/branch/main/graph/badge.svg)](https://codecov.io/gh/ptrstn/shellsmith)
3
+ [![PyPI version](https://badge.fury.io/py/shellsmith.svg)](https://badge.fury.io/py/shellsmith)
4
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
5
+
6
+ # Shellsmith
7
+
8
+ Shellsmith is a Python toolkit and CLI for managing Asset Administration Shells (AAS), Submodels, and related resources.
9
+ It is designed to interact with [Eclipse BaSyx](https://www.eclipse.org/basyx/), a middleware platform for AAS that follows the [Industry 4.0 standard](https://industrialdigitaltwin.org/en/content-hub/aasspecifications).
10
+
11
+ ### Features
12
+
13
+ - Python API for CRUD operations on shells, submodels, and submodel elements
14
+ - CLI interface for quick scripting
15
+ - `.env`-based configuration
16
+
17
+ ## 🚀 Installation
18
+
19
+ ```bash
20
+ pip install shellsmith
21
+ ```
22
+
23
+ **Requires**: Python 3.10+
24
+
25
+ ## 🔧 Configuration
26
+
27
+ The default AAS environment host is:
28
+
29
+ ```
30
+ http://localhost:8081
31
+ ```
32
+
33
+ You can override it by setting the `SHELLSMITH_BASYX_ENV_HOST` environment variable, or by creating a `.env` file in your project root with:
34
+
35
+ ```bash
36
+ SHELLSMITH_BASYX_ENV_HOST=http://your-host:1234
37
+ ```
38
+
39
+ ## 🛠️ Usage
40
+
41
+ ```bash
42
+ aas --help
43
+ ```
44
+
45
+ Common commands:
46
+
47
+ ```bash
48
+ aas info # Show all shells and submodels
49
+ aas upload <file|folder> # Upload AAS file or folder
50
+ aas shell delete <id> # Delete a shell
51
+ aas submodel delete <id> # Delete a submodel
52
+ ```
53
+
54
+ Use `--cascade` or `--unlink` to control deletion behavior:
55
+
56
+ ```bash
57
+ aas shell delete <id> --cascade # Also delete referenced submodels
58
+ aas submodel delete <id> --unlink # Remove references from shells
59
+ ```
60
+
61
+ ## 📡 API Usage
62
+
63
+ You can also use `shellsmith` as a Python package:
64
+
65
+ ```python
66
+ import shellsmith
67
+
68
+ # Get all available shells
69
+ shells = shellsmith.get_shells()
70
+
71
+ # Get a specific shell by ID (automatically base64-encoded)
72
+ shell = shellsmith.get_shell("example_aas_id")
73
+
74
+ # Disable base64 encoding if your ID is already encoded
75
+ submodel = shellsmith.get_submodel("ZXhhbXBsZV9hYXNfaWQ=", encode=False)
76
+
77
+ # Use a custom AAS environment host
78
+ submodel_refs = shellsmith.get_submodel_refs("example_aas_id", host="http://localhost:8081")
79
+ ```
80
+
81
+ > ℹ️ `shell_id` and `submodel_id` are automatically base64-encoded unless you set `encode=False`. This is required by the BaSyx API for identifier-based URLs.
82
+
83
+ The tables below show the mapping between BaSyx AAS REST API endpoints and the implemented client functions.
84
+
85
+ > 📚 See [Plattform_i40 API reference](https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection) for endpoint details.
86
+
87
+ ### Shells
88
+
89
+ | Method | BaSyx Endpoint | Shellsmith Function |
90
+ |--------|--------------------------------------------------------------|-----------------------|
91
+ | GET | `/shells` | `get_shells` |
92
+ | POST | `/shells` | ❌ |
93
+ | GET | `/shells/{aasIdentifier}` | `get_shell` |
94
+ | PUT | `/shells/{aasIdentifier}` | ❌ |
95
+ | DELETE | `/shells/{aasIdentifier}` | `delete_shell` |
96
+ | GET | `/shells/{aasIdentifier}/submodel-refs` | `get_submodel_refs` |
97
+ | POST | `/shells/{aasIdentifier}/submodel-refs` | ❌ |
98
+ | DELETE | `/shells/{aasIdentifier}/submodel-refs/{submodelIdentifier}` | `delete_submodel_ref` |
99
+
100
+ ### Submodels
101
+
102
+ | Method | BaSyx Endpoint | Shellsmith Function |
103
+ |--------|---------------------------------------------|---------------------|
104
+ | GET | `/submodels` | `get_submodels` |
105
+ | POST | `/submodels` | ❌ |
106
+ | GET | `/submodels/{submodelIdentifier}` | `get_submodel` |
107
+ | PUT | `/submodels/{submodelIdentifier}` | ❌ |
108
+ | DELETE | `/submodels/{submodelIdentifier}` | `delete_submodel` |
109
+ | GET | `/submodels/{submodelIdentifier}/$value` | ❌ |
110
+ | PATCH | `/submodels/{submodelIdentifier}/$value` | ❌ |
111
+ | GET | `/submodels/{submodelIdentifier}/$metadata` | ❌ |
112
+
113
+ ### Submodel Elements
114
+
115
+ | Method | BaSyx Endpoint | Shellsmith Function |
116
+ |--------|--------------------------------------------------------------------------|--------------------------------|
117
+ | GET | `/submodels/{submodelIdentifier}/submodel-elements` | `get_submodel_elements` |
118
+ | POST | `/submodels/{submodelIdentifier}/submodel-elements` | ❌ |
119
+ | GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `get_submodel_element` |
120
+ | PUT | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | ❌ |
121
+ | POST | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | ❌ |
122
+ | DELETE | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `delete_submodel_element` |
123
+ | GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | ❌ |
124
+ | PATCH | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | `patch_submodel_element_value` |
125
+
126
+ ### Upload
127
+
128
+ | Method | BaSyx Endpoint | Shellsmith Function |
129
+ |--------|----------------|-----------------------------------------------------|
130
+ | POST | `/upload` | `upload.upload_aas` <br> `upload.upload_aas_folder` |
131
+
132
+ > ℹ️ Upload functions are available under the `shellsmith.upload` submodule.
133
+
134
+ ## ⚙️ Development
135
+
136
+ ```bash
137
+ git clone https://github.com/ptrstn/shellsmith
138
+ cd shellsmith
139
+ python -m venv .venv
140
+ source .venv/bin/activate # or .venv\Scripts\activate on Windows
141
+ pip install -e .[test]
142
+ ```
143
+
144
+ ### ✅ Testing
145
+
146
+ Before running the tests, make sure the BaSyx stack is up and running:
147
+
148
+ ```bash
149
+ docker compose up -d
150
+ ```
151
+
152
+ Then run the test suite with coverage:
153
+
154
+ ```bash
155
+ pytest --cov
156
+ ```
157
+
158
+ To view a detailed, visual coverage report:
159
+
160
+ ```bash
161
+ pytest --cov --cov-report=html
162
+ ```
163
+
164
+ Then open `htmlcov/index.html` in your web browser to explore which lines are covered and which are missing.
165
+
166
+ ## Resources
167
+
168
+ - https://github.com/eclipse-basyx/basyx-java-server-sdk
169
+ - https://github.com/admin-shell-io/aas-specs-api
170
+ - https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "shellsmith"
7
+ version = "0.1.0"
8
+ description = "A Python toolkit and CLI for managing Asset Administration Shells"
9
+ authors = [{ name = "Peter Stein", email = "peterstein@dfki.de" }]
10
+ license = { file = "LICENSE" }
11
+ readme = { file = "README.md", content-type = "text/markdown" }
12
+ requires-python = ">=3.10"
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ dependencies = [
18
+ "pydantic-settings",
19
+ "requests",
20
+ ]
21
+
22
+ [project.optional-dependencies]
23
+ test = [
24
+ "black",
25
+ "flake8",
26
+ "isort",
27
+ "pytest",
28
+ "pytest-cov",
29
+ "pytest-dotenv",
30
+ ]
31
+
32
+ [project.scripts]
33
+ aas = "shellsmith.cli.main:main"
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/ptrstn/shellsmith"
37
+ Issues = "https://github.com/ptrstn/shellsmith/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,18 @@
1
+ __version__ = "0.1.0"
2
+
3
+ from .crud.shells import ( # noqa: F401
4
+ delete_shell,
5
+ delete_submodel_ref,
6
+ get_shell,
7
+ get_shells,
8
+ get_submodel_refs,
9
+ )
10
+ from .crud.submodels import ( # noqa: F401
11
+ delete_submodel,
12
+ delete_submodel_element,
13
+ get_submodel,
14
+ get_submodel_element,
15
+ get_submodel_elements,
16
+ get_submodels,
17
+ patch_submodel_element_value,
18
+ )
@@ -0,0 +1,4 @@
1
+ from shellsmith.cli.main import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
File without changes
@@ -0,0 +1,5 @@
1
+ from .info import info # noqa: F401
2
+ from .nuke import nuke # noqa: F401
3
+ from .shell import shell_delete # noqa: F401
4
+ from .submodel import submodel_delete # noqa: F401
5
+ from .upload import upload # noqa: F401
@@ -0,0 +1,47 @@
1
+ import shellsmith
2
+ from shellsmith import services
3
+
4
+
5
+ def info():
6
+ print("ℹ️ Showing all shells")
7
+ print_shells_tree()
8
+ print_unreferenced_submodels()
9
+ print_dangling_submodel_refs()
10
+
11
+
12
+ def print_unreferenced_submodels():
13
+ submodel_ids = services.find_unreferenced_submodels()
14
+
15
+ if submodel_ids:
16
+ print()
17
+ print("⚠️ Unreferenced Submodels:")
18
+ for submodel_id in submodel_ids:
19
+ submodel = shellsmith.get_submodel(submodel_id)
20
+ id_short = submodel["idShort"]
21
+ print(f"- {id_short} ({submodel_id})")
22
+
23
+
24
+ def print_shells_tree():
25
+ shells = shellsmith.get_shells()
26
+ for shell in shells:
27
+ print(f"{shell['idShort']}: {shell['id']}")
28
+
29
+ submodels = services.get_shell_submodels(shell["id"])
30
+
31
+ for i, submodel in enumerate(submodels):
32
+ is_last = i == len(submodels) - 1
33
+ prefix = "└──" if is_last else "├──"
34
+ print(f"{prefix} {submodel['idShort']}: {submodel['id']}")
35
+
36
+
37
+ def print_dangling_submodel_refs():
38
+ dangling = services.find_dangling_submodel_refs()
39
+
40
+ if dangling:
41
+ print()
42
+ print("⚠️ Dangling Submodel References:")
43
+ for shell_id, submodel_ids in dangling.items():
44
+ shell = shellsmith.get_shell(shell_id)
45
+ print(f"- {shell['idShort']}: {shell_id}")
46
+ for submodel_id in submodel_ids:
47
+ print(f" └── {submodel_id}")
@@ -0,0 +1,9 @@
1
+ from shellsmith import services
2
+
3
+
4
+ def nuke():
5
+ print("☣️ Deleting all Shells and Submodels!")
6
+ print("☢️ Deleting all Shells and Submodels!")
7
+ print("⚠️ Deleting all Shells and Submodels!")
8
+ services.delete_all_shells()
9
+ services.delete_all_submodels()
@@ -0,0 +1,17 @@
1
+ import requests.exceptions
2
+
3
+ import shellsmith
4
+ from shellsmith import services
5
+
6
+
7
+ def shell_delete(shell_id: str, cascade: bool = False):
8
+ print(f"🗑️ Deleting Shell: {shell_id}")
9
+ try:
10
+ if cascade:
11
+ services.delete_shell_cascading(shell_id)
12
+ print(f"✅ Shell '{shell_id}' and its submodels deleted.")
13
+ else:
14
+ shellsmith.delete_shell(shell_id)
15
+ print(f"✅ Shell '{shell_id}' deleted.")
16
+ except requests.exceptions.HTTPError as e:
17
+ print(f"❌ Failed to delete Shell '{shell_id}': {e}")
@@ -0,0 +1,16 @@
1
+ import requests
2
+
3
+ import shellsmith
4
+ from shellsmith import services
5
+
6
+
7
+ def submodel_delete(submodel_id: str, unlink: bool = False):
8
+ print(f"🗑️ Deleting Submodel: {submodel_id}")
9
+ try:
10
+ shellsmith.delete_submodel(submodel_id)
11
+ print(f"✅ Submodel '{submodel_id}' deleted.")
12
+ except requests.exceptions.HTTPError:
13
+ print(f"❌ Submodel '{submodel_id}' doesn't exist.")
14
+ if unlink:
15
+ services.remove_submodel_references(submodel_id)
16
+ print(f"✅ Removed Shell references to Submodel '{submodel_id}'.")
@@ -0,0 +1,14 @@
1
+ from pathlib import Path
2
+
3
+ from shellsmith.upload import upload_aas, upload_aas_folder
4
+
5
+
6
+ def upload(path: Path):
7
+ if path.is_file():
8
+ print(f"ℹ️ Uploading file: {path}")
9
+ upload_aas(path)
10
+ elif path.is_dir():
11
+ print(f"ℹ️ Uploading all AAS files in folder: {path}")
12
+ upload_aas_folder(path)
13
+ else:
14
+ print(f"❌ Path '{path}' does not exist or is invalid.")
@@ -0,0 +1,44 @@
1
+ import requests
2
+
3
+ from shellsmith import __version__, services
4
+ from shellsmith.config import config
5
+
6
+ from .commands import info, nuke, shell_delete, submodel_delete, upload
7
+ from .parser import build_parser
8
+
9
+
10
+ def print_header():
11
+ print("===============================================")
12
+ print(f"Shellsmith - AAS Toolkit v{__version__}")
13
+ print(f"Host: {config.host} ({services.health()})")
14
+ print("===============================================")
15
+ print()
16
+
17
+
18
+ def main():
19
+ print_header()
20
+ parser = build_parser()
21
+ args = parser.parse_args()
22
+
23
+ commands = {
24
+ "upload": lambda _args: upload(args.path),
25
+ "info": lambda _args: info(),
26
+ "nuke": lambda _args: nuke(),
27
+ "shell.delete": lambda _args: shell_delete(args.id, cascade=args.cascade),
28
+ "submodel.delete": lambda _args: submodel_delete(args.id, unlink=args.unlink),
29
+ }
30
+
31
+ try:
32
+ key = args.command
33
+ if key == "shell" and args.shell_command:
34
+ key += f".{args.shell_command}"
35
+ elif key == "submodel" and args.submodel_command:
36
+ key += f".{args.submodel_command}"
37
+
38
+ handler = commands.get(key)
39
+ if handler:
40
+ handler(args)
41
+ else:
42
+ parser.print_help()
43
+ except requests.exceptions.ConnectionError as e:
44
+ print(f"😩 Cannot reach {config.host}: {e}")