shellsmith 0.2.1__tar.gz → 0.3.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.
- shellsmith-0.3.0/PKG-INFO +343 -0
- shellsmith-0.3.0/README.md +285 -0
- shellsmith-0.3.0/pyproject.toml +91 -0
- shellsmith-0.3.0/src/shellsmith/__init__.py +30 -0
- shellsmith-0.3.0/src/shellsmith/__main__.py +6 -0
- shellsmith-0.3.0/src/shellsmith/cli/app.py +44 -0
- shellsmith-0.3.0/src/shellsmith/cli/args.py +30 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/decode.py +13 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/encode.py +13 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/groups/__init__.py +0 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/groups/create.py +79 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/groups/delete.py +83 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/groups/get.py +165 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/groups/update.py +111 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/info.py +71 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/nuke.py +66 -0
- shellsmith-0.3.0/src/shellsmith/cli/commands/upload.py +32 -0
- shellsmith-0.3.0/src/shellsmith/cli/formats.py +13 -0
- shellsmith-0.3.0/src/shellsmith/cli/handlers.py +31 -0
- shellsmith-0.3.0/src/shellsmith/cli/opts.py +41 -0
- shellsmith-0.3.0/src/shellsmith/cli/pretty.py +142 -0
- shellsmith-0.3.0/src/shellsmith/cli/resolve.py +30 -0
- shellsmith-0.3.0/src/shellsmith/cli/simplify.py +74 -0
- shellsmith-0.3.0/src/shellsmith/config.py +41 -0
- shellsmith-0.3.0/src/shellsmith/crud/__init__.py +29 -0
- shellsmith-0.3.0/src/shellsmith/crud/shells.py +205 -0
- shellsmith-0.3.0/src/shellsmith/crud/submodels.py +434 -0
- shellsmith-0.3.0/src/shellsmith/extract.py +13 -0
- shellsmith-0.3.0/src/shellsmith/neo4j.py +163 -0
- shellsmith-0.3.0/src/shellsmith/services.py +191 -0
- shellsmith-0.3.0/src/shellsmith/upload.py +62 -0
- shellsmith-0.3.0/src/shellsmith/utils.py +95 -0
- shellsmith-0.3.0/src/shellsmith.egg-info/PKG-INFO +343 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/src/shellsmith.egg-info/SOURCES.txt +17 -8
- shellsmith-0.3.0/src/shellsmith.egg-info/entry_points.txt +2 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/src/shellsmith.egg-info/requires.txt +6 -3
- {shellsmith-0.2.1 → shellsmith-0.3.0}/tests/test_neo4j.py +0 -1
- shellsmith-0.3.0/tests/test_services.py +65 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/tests/test_utils.py +13 -1
- shellsmith-0.2.1/PKG-INFO +0 -221
- shellsmith-0.2.1/README.md +0 -174
- shellsmith-0.2.1/pyproject.toml +0 -41
- shellsmith-0.2.1/src/shellsmith/__init__.py +0 -18
- shellsmith-0.2.1/src/shellsmith/__main__.py +0 -4
- shellsmith-0.2.1/src/shellsmith/cli/commands/__init__.py +0 -6
- shellsmith-0.2.1/src/shellsmith/cli/commands/info.py +0 -52
- shellsmith-0.2.1/src/shellsmith/cli/commands/nuke.py +0 -9
- shellsmith-0.2.1/src/shellsmith/cli/commands/shell.py +0 -17
- shellsmith-0.2.1/src/shellsmith/cli/commands/sme.py +0 -13
- shellsmith-0.2.1/src/shellsmith/cli/commands/submodel.py +0 -16
- shellsmith-0.2.1/src/shellsmith/cli/commands/upload.py +0 -14
- shellsmith-0.2.1/src/shellsmith/cli/main.py +0 -62
- shellsmith-0.2.1/src/shellsmith/cli/parser.py +0 -97
- shellsmith-0.2.1/src/shellsmith/config.py +0 -19
- shellsmith-0.2.1/src/shellsmith/crud/shells.py +0 -61
- shellsmith-0.2.1/src/shellsmith/crud/submodels.py +0 -126
- shellsmith-0.2.1/src/shellsmith/neo4j.py +0 -115
- shellsmith-0.2.1/src/shellsmith/services.py +0 -131
- shellsmith-0.2.1/src/shellsmith/upload.py +0 -40
- shellsmith-0.2.1/src/shellsmith/utils.py +0 -35
- shellsmith-0.2.1/src/shellsmith.egg-info/PKG-INFO +0 -221
- shellsmith-0.2.1/src/shellsmith.egg-info/entry_points.txt +0 -2
- shellsmith-0.2.1/tests/test_cli.py +0 -110
- shellsmith-0.2.1/tests/test_cli_integration.py +0 -59
- shellsmith-0.2.1/tests/test_crud.py +0 -123
- {shellsmith-0.2.1 → shellsmith-0.3.0}/LICENSE +0 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/setup.cfg +0 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/src/shellsmith/cli/__init__.py +0 -0
- {shellsmith-0.2.1/src/shellsmith/crud → shellsmith-0.3.0/src/shellsmith/cli/commands}/__init__.py +0 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/src/shellsmith.egg-info/dependency_links.txt +0 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/src/shellsmith.egg-info/top_level.txt +0 -0
- {shellsmith-0.2.1 → shellsmith-0.3.0}/tests/test_upload.py +0 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: shellsmith
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Python client and CLI for Eclipse BaSyx to manage Asset Administration Shells (AAS)
|
|
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
|
+
Keywords: aas,asset-administration-shell,basyx,eclipse-basyx,industry40,i40,digital-twin,cli,typer,rest-client,python
|
|
31
|
+
Classifier: Programming Language :: Python :: 3
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
36
|
+
Classifier: Operating System :: OS Independent
|
|
37
|
+
Classifier: Intended Audience :: Developers
|
|
38
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
39
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
40
|
+
Requires-Python: >=3.10
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
License-File: LICENSE
|
|
43
|
+
Requires-Dist: pydantic-settings
|
|
44
|
+
Requires-Dist: pyyaml
|
|
45
|
+
Requires-Dist: requests
|
|
46
|
+
Requires-Dist: typer
|
|
47
|
+
Provides-Extra: test
|
|
48
|
+
Requires-Dist: mkdocs; extra == "test"
|
|
49
|
+
Requires-Dist: mkdocs-material; extra == "test"
|
|
50
|
+
Requires-Dist: pytest; extra == "test"
|
|
51
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
52
|
+
Requires-Dist: pytest-dotenv; extra == "test"
|
|
53
|
+
Requires-Dist: ruff; extra == "test"
|
|
54
|
+
Requires-Dist: termynal; extra == "test"
|
|
55
|
+
Provides-Extra: neo4j
|
|
56
|
+
Requires-Dist: neo4j; extra == "neo4j"
|
|
57
|
+
Dynamic: license-file
|
|
58
|
+
|
|
59
|
+
<div align="center">
|
|
60
|
+
<img src="docs/images/logo-purple.png" alt="shellsmith" style="max-width: 100%; width: 600px;">
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div align="center">
|
|
64
|
+
<a href="https://github.com/ptrstn/shellsmith/actions/workflows/test.yaml"><img src="https://github.com/ptrstn/shellsmith/actions/workflows/test.yaml/badge.svg" alt="Test"></a>
|
|
65
|
+
<a href="https://codecov.io/gh/ptrstn/shellsmith"><img src="https://codecov.io/gh/ptrstn/shellsmith/branch/main/graph/badge.svg" alt="codecov"></a>
|
|
66
|
+
<a href="https://pypi.org/project/shellsmith"><img src="https://img.shields.io/pypi/v/shellsmith?color=%2334D058" alt="PyPI - Version"></a>
|
|
67
|
+
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff"></a>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<p align="center">
|
|
71
|
+
<b>Documentation</b>: <a href="https://shellsmith.pages.dev/" target="_blank">https://shellsmith.pages.dev</a>
|
|
72
|
+
</p>
|
|
73
|
+
|
|
74
|
+
**Shellsmith** is a Python SDK and CLI for managing [Asset Administration Shells (AAS)](https://industrialdigitaltwin.org/en/content-hub/aasspecifications), Submodels, and Submodel Elements via the [Eclipse BaSyx](https://www.eclipse.org/basyx/) REST API.
|
|
75
|
+
|
|
76
|
+
It provides full client-side access to AAS resources with a clean Python interface and a powerful `typer`-based CLI — ideal for scripting, automation, and digital twin integration workflows.
|
|
77
|
+
|
|
78
|
+
### Features
|
|
79
|
+
|
|
80
|
+
- 🐍 **Python SDK** for full CRUD access to Shells, Submodels, and Submodel Elements
|
|
81
|
+
- ⚡ **CLI tool** powered by [Typer](https://typer.tiangolo.com/) for fast scripting and automation
|
|
82
|
+
- ⚙️ Simple `.env`-based configuration for flexible environment switching
|
|
83
|
+
- 🔁 Seamless integration with the [Eclipse BaSyx](https://www.eclipse.org/basyx/) Environment REST API
|
|
84
|
+
|
|
85
|
+
## 🚀 Installation
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pip install shellsmith
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Requires**: Python 3.10+
|
|
92
|
+
|
|
93
|
+
## 🔧 Configuration
|
|
94
|
+
|
|
95
|
+
The default AAS environment host is:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
http://localhost:8081
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
You can override it by setting the `SHELLSMITH_BASYX_ENV_HOST` environment variable, or by creating a `.env` file in the current working directory or your project root.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
SHELLSMITH_BASYX_ENV_HOST=http://your-host:1234
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 🧠 CLI Usage
|
|
108
|
+
|
|
109
|
+
Shellsmith provides a powerful command-line interface:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
aas --help
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
| Command | Description |
|
|
116
|
+
|----------|----------------------------------------------------------|
|
|
117
|
+
| `info` | Display the current Shell tree and identify issues. |
|
|
118
|
+
| `upload` | Upload a single AAS file or all AAS files from a folder. |
|
|
119
|
+
| `nuke` | ☢️ Delete all Shells and Submodels (irrevocable). |
|
|
120
|
+
| `encode` | Encode a value (e.g. Shell ID) to Base64. |
|
|
121
|
+
| `decode` | Decode a Base64-encoded value. |
|
|
122
|
+
| `get` | Get Shells, Submodels, and Submodel Elements. |
|
|
123
|
+
| `delete` | Delete Shells, Submodels, or Submodel Elements. |
|
|
124
|
+
| `update` | Update Shells, Submodels, or Submodel Elements. |
|
|
125
|
+
| `create` | Create new Shells, Submodels, or Submodel Elements. |
|
|
126
|
+
|
|
127
|
+
> ℹ️ Run `aas <command> --help` to view subcommands and options.
|
|
128
|
+
|
|
129
|
+
### 🔎 Get Commands
|
|
130
|
+
|
|
131
|
+
| Command | Description |
|
|
132
|
+
|---------------------------|---------------------------------------------|
|
|
133
|
+
| `aas get shells` | 🔹 Get all available Shells. |
|
|
134
|
+
| `aas get shell` | 🔹 Get a specific Shell by ID. |
|
|
135
|
+
| `aas get submodel-refs` | 🔹 Get all Submodel References of a Shell. |
|
|
136
|
+
| `aas get submodels` | 🔸 Get all Submodels. |
|
|
137
|
+
| `aas get submodel ` | 🔸 Get a specific Submodel by ID. |
|
|
138
|
+
| `aas get submodel-value ` | 🔸 Get the `$value` of a Submodel. |
|
|
139
|
+
| `aas get submodel-meta` | 🔸 Get the `$metadata` of a Submodel. |
|
|
140
|
+
| `aas get elements` | 🔻 Get all Submodel Elements of a Submodel. |
|
|
141
|
+
| `aas get element` | 🔻 Get a specific Submodel Element. |
|
|
142
|
+
| `aas get element-value` | 🔻 Get the `$value` of a Submodel Element. |
|
|
143
|
+
|
|
144
|
+
### 🛠️ Create Commands
|
|
145
|
+
|
|
146
|
+
| Command | Description |
|
|
147
|
+
|----------------------------|-----------------------------------------|
|
|
148
|
+
| `aas create shell ` | 🔹 Create a new Shell. |
|
|
149
|
+
| `aas create submodel-ref ` | 🔹 Add a Submodel Reference to a Shell. |
|
|
150
|
+
| `aas create submodel` | 🔸 Create a new Submodel. |
|
|
151
|
+
| `aas create element ` | 🔻 Create a new Submodel Element. |
|
|
152
|
+
| `aas create element` | 🔻 Create an Element at a nested path. |
|
|
153
|
+
|
|
154
|
+
> ℹ️ Input can be passed via `--data "<json>"` or `--file <*.json|*.yaml>`, but **not both**
|
|
155
|
+
|
|
156
|
+
### 🧬 Update Commands
|
|
157
|
+
|
|
158
|
+
| Command | Description |
|
|
159
|
+
|------------------------------|----------------------------------------------------------------|
|
|
160
|
+
| `aas update shell ` | 🔹 Update a Shell (full replacement). |
|
|
161
|
+
| `aas update submodel` | 🔸 Update a Submodel (full replacement). |
|
|
162
|
+
| `aas update submodel-value ` | 🔸 Update the `$value` of a Submodel (partial update). |
|
|
163
|
+
| `aas update element ` | 🔻 Update a Submodel Element (full replacement). |
|
|
164
|
+
| `aas update element-value ` | 🔻 Update the `$value` of a Submodel Element (partial update). |
|
|
165
|
+
|
|
166
|
+
> ℹ️ All updates are either full replacements (`PUT`) or partial updates (`PATCH`)
|
|
167
|
+
|
|
168
|
+
### 🧹 Delete Commands
|
|
169
|
+
|
|
170
|
+
| Command | Description |
|
|
171
|
+
|---------------------------|----------------------------------------------------------------|
|
|
172
|
+
| `aas delete shell` | 🔹 Delete a Shell and optionally all referenced Submodels. |
|
|
173
|
+
| `aas delete submodel-ref` | 🔹 Remove a Submodel reference from a Shell. |
|
|
174
|
+
| `aas delete submodel` | 🔸 Delete a Submodel and optionally unlink it from all Shells. |
|
|
175
|
+
| `aas delete element` | 🔻 Delete a Submodel Element. |
|
|
176
|
+
|
|
177
|
+
> ℹ️ You can pass `--cascade` to also remove the Submodels the Shell references
|
|
178
|
+
|
|
179
|
+
> ℹ️ You can pass `--remove-refs` to also remove all references to that Submodel
|
|
180
|
+
|
|
181
|
+
## 🐍 Python API Usage
|
|
182
|
+
|
|
183
|
+
You can also use `shellsmith` as a Python client library to interact with the BaSyx Environment REST API.
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
import shellsmith
|
|
187
|
+
|
|
188
|
+
# List all AAS Shells
|
|
189
|
+
shells = shellsmith.get_shells()
|
|
190
|
+
|
|
191
|
+
# Fetch a specific Shell by ID
|
|
192
|
+
shell = shellsmith.get_shell("https://example.com/shells/my-shell")
|
|
193
|
+
|
|
194
|
+
# List Submodels or Submodel References of a Shell
|
|
195
|
+
submodels = shellsmith.get_submodels()
|
|
196
|
+
refs = shellsmith.get_submodel_refs("https://example.com/shells/my-shell")
|
|
197
|
+
|
|
198
|
+
# Fetch a specific Submodel
|
|
199
|
+
submodel = shellsmith.get_submodel("https://example.com/submodels/my-submodel")
|
|
200
|
+
|
|
201
|
+
# Read and update a Submodel Element's value
|
|
202
|
+
value = shellsmith.get_submodel_element_value(submodel["id"], "temperature")
|
|
203
|
+
shellsmith.patch_submodel_element_value(submodel["id"], "temperature", "42.0")
|
|
204
|
+
|
|
205
|
+
# Upload a single AAS file or an entire folder (.aasx / .json / .xml)
|
|
206
|
+
shellsmith.upload_aas("MyAsset.aasx")
|
|
207
|
+
shellsmith.upload_aas_folder("aas_folder/")
|
|
208
|
+
|
|
209
|
+
# Delete a Shell or Submodel by ID
|
|
210
|
+
shellsmith.delete_shell("https://example.com/aas/my-asset")
|
|
211
|
+
shellsmith.delete_submodel("https://example.com/submodels/my-submodel")
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
> ℹ️ `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.
|
|
215
|
+
|
|
216
|
+
The tables below show the mapping between BaSyx AAS REST API endpoints and the implemented client functions.
|
|
217
|
+
|
|
218
|
+
> 📚 See [Plattform_i40 API reference](https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection) for endpoint details.
|
|
219
|
+
|
|
220
|
+
### Shells
|
|
221
|
+
|
|
222
|
+
| Method | BaSyx Endpoint | `shellsmith` Function |
|
|
223
|
+
|--------|--------------------------------------------------------------|-----------------------|
|
|
224
|
+
| GET | `/shells` | `get_shells` |
|
|
225
|
+
| POST | `/shells` | `post_shell` |
|
|
226
|
+
| GET | `/shells/{aasIdentifier}` | `get_shell` |
|
|
227
|
+
| PUT | `/shells/{aasIdentifier}` | `put_shell` |
|
|
228
|
+
| DELETE | `/shells/{aasIdentifier}` | `delete_shell` |
|
|
229
|
+
| GET | `/shells/{aasIdentifier}/submodel-refs` | `get_submodel_refs` |
|
|
230
|
+
| POST | `/shells/{aasIdentifier}/submodel-refs` | `post_submodel_ref` |
|
|
231
|
+
| DELETE | `/shells/{aasIdentifier}/submodel-refs/{submodelIdentifier}` | `delete_submodel_ref` |
|
|
232
|
+
|
|
233
|
+
### Submodels
|
|
234
|
+
|
|
235
|
+
| Method | BaSyx Endpoint | Shellsmith Function |
|
|
236
|
+
|--------|---------------------------------------------|-------------------------|
|
|
237
|
+
| GET | `/submodels` | `get_submodels` |
|
|
238
|
+
| POST | `/submodels` | `post_submodel` |
|
|
239
|
+
| GET | `/submodels/{submodelIdentifier}` | `get_submodel` |
|
|
240
|
+
| PUT | `/submodels/{submodelIdentifier}` | `put_submodel` |
|
|
241
|
+
| DELETE | `/submodels/{submodelIdentifier}` | `delete_submodel` |
|
|
242
|
+
| GET | `/submodels/{submodelIdentifier}/$value` | `get_submodel_value` |
|
|
243
|
+
| PATCH | `/submodels/{submodelIdentifier}/$value` | `patch_submodel_value` |
|
|
244
|
+
| GET | `/submodels/{submodelIdentifier}/$metadata` | `get_submodel_metadata` |
|
|
245
|
+
|
|
246
|
+
### Submodel Elements
|
|
247
|
+
|
|
248
|
+
| Method | BaSyx Endpoint | Shellsmith Function |
|
|
249
|
+
|--------|--------------------------------------------------------------------------|--------------------------------|
|
|
250
|
+
| GET | `/submodels/{submodelIdentifier}/submodel-elements` | `get_submodel_elements` |
|
|
251
|
+
| POST | `/submodels/{submodelIdentifier}/submodel-elements` | `post_submodel_element` |
|
|
252
|
+
| GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `get_submodel_element` |
|
|
253
|
+
| PUT | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `put_submodel_element` |
|
|
254
|
+
| POST | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `post_submodel_element` |
|
|
255
|
+
| DELETE | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `delete_submodel_element` |
|
|
256
|
+
| GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | `get_submodel_element_value` |
|
|
257
|
+
| PATCH | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | `patch_submodel_element_value` |
|
|
258
|
+
|
|
259
|
+
### Upload
|
|
260
|
+
|
|
261
|
+
| Method | BaSyx Endpoint | Shellsmith Function |
|
|
262
|
+
|--------|----------------|-----------------------------------------------------|
|
|
263
|
+
| POST | `/upload` | `upload.upload_aas` <br> `upload.upload_aas_folder` |
|
|
264
|
+
|
|
265
|
+
> ℹ️ Upload functions are available under the `shellsmith.upload` submodule.
|
|
266
|
+
|
|
267
|
+
## ⚙️ Development
|
|
268
|
+
|
|
269
|
+
Clone the repository and set up the virtual environment:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
git clone https://github.com/ptrstn/shellsmith
|
|
273
|
+
cd shellsmith
|
|
274
|
+
python -m venv .venv
|
|
275
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
276
|
+
pip install -e .[test]
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### ✅ Testing
|
|
280
|
+
|
|
281
|
+
Start the BaSyx stack (if needed):
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
docker compose up -d
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Run the test suite with coverage:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
pytest --cov
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Generate an HTML coverage report:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
pytest --cov --cov-report=html
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Then open `htmlcov/index.html` in your web browser to explore which lines are covered and which are missing.
|
|
300
|
+
|
|
301
|
+
### 🧼 Code Quality
|
|
302
|
+
|
|
303
|
+
We use [Ruff](https://docs.astral.sh/ruff/) for linting, formatting, and import sorting.
|
|
304
|
+
|
|
305
|
+
Check code style:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
ruff check
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Auto-fix issues:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
ruff check --fix
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Format code:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
ruff format
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### 📚 Documentation
|
|
324
|
+
|
|
325
|
+
Serve the docs locally:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
mkdocs serve
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Then visit [http://127.0.0.1:8000](http://127.0.0.1:8000) to preview.
|
|
332
|
+
|
|
333
|
+
Build the static site:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
mkdocs build
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Resources
|
|
340
|
+
|
|
341
|
+
- https://github.com/eclipse-basyx/basyx-java-server-sdk
|
|
342
|
+
- https://github.com/admin-shell-io/aas-specs-api
|
|
343
|
+
- https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="docs/images/logo-purple.png" alt="shellsmith" style="max-width: 100%; width: 600px;">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<div align="center">
|
|
6
|
+
<a href="https://github.com/ptrstn/shellsmith/actions/workflows/test.yaml"><img src="https://github.com/ptrstn/shellsmith/actions/workflows/test.yaml/badge.svg" alt="Test"></a>
|
|
7
|
+
<a href="https://codecov.io/gh/ptrstn/shellsmith"><img src="https://codecov.io/gh/ptrstn/shellsmith/branch/main/graph/badge.svg" alt="codecov"></a>
|
|
8
|
+
<a href="https://pypi.org/project/shellsmith"><img src="https://img.shields.io/pypi/v/shellsmith?color=%2334D058" alt="PyPI - Version"></a>
|
|
9
|
+
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff"></a>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<b>Documentation</b>: <a href="https://shellsmith.pages.dev/" target="_blank">https://shellsmith.pages.dev</a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
**Shellsmith** is a Python SDK and CLI for managing [Asset Administration Shells (AAS)](https://industrialdigitaltwin.org/en/content-hub/aasspecifications), Submodels, and Submodel Elements via the [Eclipse BaSyx](https://www.eclipse.org/basyx/) REST API.
|
|
17
|
+
|
|
18
|
+
It provides full client-side access to AAS resources with a clean Python interface and a powerful `typer`-based CLI — ideal for scripting, automation, and digital twin integration workflows.
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
- 🐍 **Python SDK** for full CRUD access to Shells, Submodels, and Submodel Elements
|
|
23
|
+
- ⚡ **CLI tool** powered by [Typer](https://typer.tiangolo.com/) for fast scripting and automation
|
|
24
|
+
- ⚙️ Simple `.env`-based configuration for flexible environment switching
|
|
25
|
+
- 🔁 Seamless integration with the [Eclipse BaSyx](https://www.eclipse.org/basyx/) Environment REST API
|
|
26
|
+
|
|
27
|
+
## 🚀 Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install shellsmith
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Requires**: Python 3.10+
|
|
34
|
+
|
|
35
|
+
## 🔧 Configuration
|
|
36
|
+
|
|
37
|
+
The default AAS environment host is:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
http://localhost:8081
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
You can override it by setting the `SHELLSMITH_BASYX_ENV_HOST` environment variable, or by creating a `.env` file in the current working directory or your project root.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
SHELLSMITH_BASYX_ENV_HOST=http://your-host:1234
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 🧠 CLI Usage
|
|
50
|
+
|
|
51
|
+
Shellsmith provides a powerful command-line interface:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
aas --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Command | Description |
|
|
58
|
+
|----------|----------------------------------------------------------|
|
|
59
|
+
| `info` | Display the current Shell tree and identify issues. |
|
|
60
|
+
| `upload` | Upload a single AAS file or all AAS files from a folder. |
|
|
61
|
+
| `nuke` | ☢️ Delete all Shells and Submodels (irrevocable). |
|
|
62
|
+
| `encode` | Encode a value (e.g. Shell ID) to Base64. |
|
|
63
|
+
| `decode` | Decode a Base64-encoded value. |
|
|
64
|
+
| `get` | Get Shells, Submodels, and Submodel Elements. |
|
|
65
|
+
| `delete` | Delete Shells, Submodels, or Submodel Elements. |
|
|
66
|
+
| `update` | Update Shells, Submodels, or Submodel Elements. |
|
|
67
|
+
| `create` | Create new Shells, Submodels, or Submodel Elements. |
|
|
68
|
+
|
|
69
|
+
> ℹ️ Run `aas <command> --help` to view subcommands and options.
|
|
70
|
+
|
|
71
|
+
### 🔎 Get Commands
|
|
72
|
+
|
|
73
|
+
| Command | Description |
|
|
74
|
+
|---------------------------|---------------------------------------------|
|
|
75
|
+
| `aas get shells` | 🔹 Get all available Shells. |
|
|
76
|
+
| `aas get shell` | 🔹 Get a specific Shell by ID. |
|
|
77
|
+
| `aas get submodel-refs` | 🔹 Get all Submodel References of a Shell. |
|
|
78
|
+
| `aas get submodels` | 🔸 Get all Submodels. |
|
|
79
|
+
| `aas get submodel ` | 🔸 Get a specific Submodel by ID. |
|
|
80
|
+
| `aas get submodel-value ` | 🔸 Get the `$value` of a Submodel. |
|
|
81
|
+
| `aas get submodel-meta` | 🔸 Get the `$metadata` of a Submodel. |
|
|
82
|
+
| `aas get elements` | 🔻 Get all Submodel Elements of a Submodel. |
|
|
83
|
+
| `aas get element` | 🔻 Get a specific Submodel Element. |
|
|
84
|
+
| `aas get element-value` | 🔻 Get the `$value` of a Submodel Element. |
|
|
85
|
+
|
|
86
|
+
### 🛠️ Create Commands
|
|
87
|
+
|
|
88
|
+
| Command | Description |
|
|
89
|
+
|----------------------------|-----------------------------------------|
|
|
90
|
+
| `aas create shell ` | 🔹 Create a new Shell. |
|
|
91
|
+
| `aas create submodel-ref ` | 🔹 Add a Submodel Reference to a Shell. |
|
|
92
|
+
| `aas create submodel` | 🔸 Create a new Submodel. |
|
|
93
|
+
| `aas create element ` | 🔻 Create a new Submodel Element. |
|
|
94
|
+
| `aas create element` | 🔻 Create an Element at a nested path. |
|
|
95
|
+
|
|
96
|
+
> ℹ️ Input can be passed via `--data "<json>"` or `--file <*.json|*.yaml>`, but **not both**
|
|
97
|
+
|
|
98
|
+
### 🧬 Update Commands
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
|------------------------------|----------------------------------------------------------------|
|
|
102
|
+
| `aas update shell ` | 🔹 Update a Shell (full replacement). |
|
|
103
|
+
| `aas update submodel` | 🔸 Update a Submodel (full replacement). |
|
|
104
|
+
| `aas update submodel-value ` | 🔸 Update the `$value` of a Submodel (partial update). |
|
|
105
|
+
| `aas update element ` | 🔻 Update a Submodel Element (full replacement). |
|
|
106
|
+
| `aas update element-value ` | 🔻 Update the `$value` of a Submodel Element (partial update). |
|
|
107
|
+
|
|
108
|
+
> ℹ️ All updates are either full replacements (`PUT`) or partial updates (`PATCH`)
|
|
109
|
+
|
|
110
|
+
### 🧹 Delete Commands
|
|
111
|
+
|
|
112
|
+
| Command | Description |
|
|
113
|
+
|---------------------------|----------------------------------------------------------------|
|
|
114
|
+
| `aas delete shell` | 🔹 Delete a Shell and optionally all referenced Submodels. |
|
|
115
|
+
| `aas delete submodel-ref` | 🔹 Remove a Submodel reference from a Shell. |
|
|
116
|
+
| `aas delete submodel` | 🔸 Delete a Submodel and optionally unlink it from all Shells. |
|
|
117
|
+
| `aas delete element` | 🔻 Delete a Submodel Element. |
|
|
118
|
+
|
|
119
|
+
> ℹ️ You can pass `--cascade` to also remove the Submodels the Shell references
|
|
120
|
+
|
|
121
|
+
> ℹ️ You can pass `--remove-refs` to also remove all references to that Submodel
|
|
122
|
+
|
|
123
|
+
## 🐍 Python API Usage
|
|
124
|
+
|
|
125
|
+
You can also use `shellsmith` as a Python client library to interact with the BaSyx Environment REST API.
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
import shellsmith
|
|
129
|
+
|
|
130
|
+
# List all AAS Shells
|
|
131
|
+
shells = shellsmith.get_shells()
|
|
132
|
+
|
|
133
|
+
# Fetch a specific Shell by ID
|
|
134
|
+
shell = shellsmith.get_shell("https://example.com/shells/my-shell")
|
|
135
|
+
|
|
136
|
+
# List Submodels or Submodel References of a Shell
|
|
137
|
+
submodels = shellsmith.get_submodels()
|
|
138
|
+
refs = shellsmith.get_submodel_refs("https://example.com/shells/my-shell")
|
|
139
|
+
|
|
140
|
+
# Fetch a specific Submodel
|
|
141
|
+
submodel = shellsmith.get_submodel("https://example.com/submodels/my-submodel")
|
|
142
|
+
|
|
143
|
+
# Read and update a Submodel Element's value
|
|
144
|
+
value = shellsmith.get_submodel_element_value(submodel["id"], "temperature")
|
|
145
|
+
shellsmith.patch_submodel_element_value(submodel["id"], "temperature", "42.0")
|
|
146
|
+
|
|
147
|
+
# Upload a single AAS file or an entire folder (.aasx / .json / .xml)
|
|
148
|
+
shellsmith.upload_aas("MyAsset.aasx")
|
|
149
|
+
shellsmith.upload_aas_folder("aas_folder/")
|
|
150
|
+
|
|
151
|
+
# Delete a Shell or Submodel by ID
|
|
152
|
+
shellsmith.delete_shell("https://example.com/aas/my-asset")
|
|
153
|
+
shellsmith.delete_submodel("https://example.com/submodels/my-submodel")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
> ℹ️ `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.
|
|
157
|
+
|
|
158
|
+
The tables below show the mapping between BaSyx AAS REST API endpoints and the implemented client functions.
|
|
159
|
+
|
|
160
|
+
> 📚 See [Plattform_i40 API reference](https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection) for endpoint details.
|
|
161
|
+
|
|
162
|
+
### Shells
|
|
163
|
+
|
|
164
|
+
| Method | BaSyx Endpoint | `shellsmith` Function |
|
|
165
|
+
|--------|--------------------------------------------------------------|-----------------------|
|
|
166
|
+
| GET | `/shells` | `get_shells` |
|
|
167
|
+
| POST | `/shells` | `post_shell` |
|
|
168
|
+
| GET | `/shells/{aasIdentifier}` | `get_shell` |
|
|
169
|
+
| PUT | `/shells/{aasIdentifier}` | `put_shell` |
|
|
170
|
+
| DELETE | `/shells/{aasIdentifier}` | `delete_shell` |
|
|
171
|
+
| GET | `/shells/{aasIdentifier}/submodel-refs` | `get_submodel_refs` |
|
|
172
|
+
| POST | `/shells/{aasIdentifier}/submodel-refs` | `post_submodel_ref` |
|
|
173
|
+
| DELETE | `/shells/{aasIdentifier}/submodel-refs/{submodelIdentifier}` | `delete_submodel_ref` |
|
|
174
|
+
|
|
175
|
+
### Submodels
|
|
176
|
+
|
|
177
|
+
| Method | BaSyx Endpoint | Shellsmith Function |
|
|
178
|
+
|--------|---------------------------------------------|-------------------------|
|
|
179
|
+
| GET | `/submodels` | `get_submodels` |
|
|
180
|
+
| POST | `/submodels` | `post_submodel` |
|
|
181
|
+
| GET | `/submodels/{submodelIdentifier}` | `get_submodel` |
|
|
182
|
+
| PUT | `/submodels/{submodelIdentifier}` | `put_submodel` |
|
|
183
|
+
| DELETE | `/submodels/{submodelIdentifier}` | `delete_submodel` |
|
|
184
|
+
| GET | `/submodels/{submodelIdentifier}/$value` | `get_submodel_value` |
|
|
185
|
+
| PATCH | `/submodels/{submodelIdentifier}/$value` | `patch_submodel_value` |
|
|
186
|
+
| GET | `/submodels/{submodelIdentifier}/$metadata` | `get_submodel_metadata` |
|
|
187
|
+
|
|
188
|
+
### Submodel Elements
|
|
189
|
+
|
|
190
|
+
| Method | BaSyx Endpoint | Shellsmith Function |
|
|
191
|
+
|--------|--------------------------------------------------------------------------|--------------------------------|
|
|
192
|
+
| GET | `/submodels/{submodelIdentifier}/submodel-elements` | `get_submodel_elements` |
|
|
193
|
+
| POST | `/submodels/{submodelIdentifier}/submodel-elements` | `post_submodel_element` |
|
|
194
|
+
| GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `get_submodel_element` |
|
|
195
|
+
| PUT | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `put_submodel_element` |
|
|
196
|
+
| POST | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `post_submodel_element` |
|
|
197
|
+
| DELETE | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}` | `delete_submodel_element` |
|
|
198
|
+
| GET | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | `get_submodel_element_value` |
|
|
199
|
+
| PATCH | `/submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/$value` | `patch_submodel_element_value` |
|
|
200
|
+
|
|
201
|
+
### Upload
|
|
202
|
+
|
|
203
|
+
| Method | BaSyx Endpoint | Shellsmith Function |
|
|
204
|
+
|--------|----------------|-----------------------------------------------------|
|
|
205
|
+
| POST | `/upload` | `upload.upload_aas` <br> `upload.upload_aas_folder` |
|
|
206
|
+
|
|
207
|
+
> ℹ️ Upload functions are available under the `shellsmith.upload` submodule.
|
|
208
|
+
|
|
209
|
+
## ⚙️ Development
|
|
210
|
+
|
|
211
|
+
Clone the repository and set up the virtual environment:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
git clone https://github.com/ptrstn/shellsmith
|
|
215
|
+
cd shellsmith
|
|
216
|
+
python -m venv .venv
|
|
217
|
+
source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
218
|
+
pip install -e .[test]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### ✅ Testing
|
|
222
|
+
|
|
223
|
+
Start the BaSyx stack (if needed):
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
docker compose up -d
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Run the test suite with coverage:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pytest --cov
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Generate an HTML coverage report:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
pytest --cov --cov-report=html
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Then open `htmlcov/index.html` in your web browser to explore which lines are covered and which are missing.
|
|
242
|
+
|
|
243
|
+
### 🧼 Code Quality
|
|
244
|
+
|
|
245
|
+
We use [Ruff](https://docs.astral.sh/ruff/) for linting, formatting, and import sorting.
|
|
246
|
+
|
|
247
|
+
Check code style:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
ruff check
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Auto-fix issues:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
ruff check --fix
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Format code:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
ruff format
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### 📚 Documentation
|
|
266
|
+
|
|
267
|
+
Serve the docs locally:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
mkdocs serve
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Then visit [http://127.0.0.1:8000](http://127.0.0.1:8000) to preview.
|
|
274
|
+
|
|
275
|
+
Build the static site:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
mkdocs build
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Resources
|
|
282
|
+
|
|
283
|
+
- https://github.com/eclipse-basyx/basyx-java-server-sdk
|
|
284
|
+
- https://github.com/admin-shell-io/aas-specs-api
|
|
285
|
+
- https://app.swaggerhub.com/apis/Plattform_i40/Entire-API-Collection
|