systemlink-cli 1.6.5__tar.gz → 1.8.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.
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/PKG-INFO +2 -1
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/pyproject.toml +2 -1
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/_version.py +1 -1
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skill_click.py +3 -3
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/slcli/SKILL.md +15 -2
- systemlink_cli-1.8.0/slcli/skills/systemlink-notebook/SKILL.md +310 -0
- systemlink_cli-1.8.0/slcli/skills/systemlink-notebook/references/interfaces.md +82 -0
- systemlink_cli-1.8.0/slcli/skills/systemlink-notebook/references/notebook-patterns.md +252 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/system_click.py +483 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/LICENSE +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/dff-editor/editor.js +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/dff-editor/index.html +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/__init__.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/__main__.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/asset_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/cli_formatters.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/cli_utils.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/comment_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/completion_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/config.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/config_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/dff_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/dff_decorators.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/example_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/example_loader.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/example_provisioner.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/README.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/_schema/schema-v1.0.json +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/demo-complete-workflow/README.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/demo-complete-workflow/config.yaml +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/demo-test-plans/README.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/demo-test-plans/config.yaml +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/exercise-5-1-parametric-insights/README.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/exercise-5-1-parametric-insights/config.yaml +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/exercise-7-1-test-plans/README.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/exercise-7-1-test-plans/config.yaml +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/spec-compliance-notebooks/README.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/spec-compliance-notebooks/config.yaml +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/spec-compliance-notebooks/notebooks/SpecAnalysis_ComplianceCalculation.ipynb +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/spec-compliance-notebooks/notebooks/SpecComplianceCalculation.ipynb +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/spec-compliance-notebooks/notebooks/SpecfileExtractionAndIngestion.ipynb +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/examples/spec-compliance-notebooks/spec_template.xlsx +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/feed_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/file_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/function_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/function_templates.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/main.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/mcp_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/mcp_server.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/notebook_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/platform.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/policy_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/policy_utils.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/profiles.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/response_handlers.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/rich_output.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/routine_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/slcli/references/analysis-recipes.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/slcli/references/filtering.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/systemlink-webapp/SKILL.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/systemlink-webapp/references/deployment.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/systemlink-webapp/references/layout-patterns.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/systemlink-webapp/references/nimble-angular.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/skills/systemlink-webapp/references/systemlink-services.md +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/ssl_trust.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/table_utils.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/tag_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/templates_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/testmonitor_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/universal_handlers.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/user_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/utils.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/web_editor.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/webapp_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/workflow_preview.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/workflows_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/workitem_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/workspace_click.py +0 -0
- {systemlink_cli-1.6.5 → systemlink_cli-1.8.0}/slcli/workspace_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: systemlink-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.0
|
|
4
4
|
Summary: SystemLink Integrator CLI - cross-platform CLI for SystemLink workflows and templates.
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Author: Fred Visser
|
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.14
|
|
13
13
|
Requires-Dist: click (>=7.1.2)
|
|
14
14
|
Requires-Dist: keyring (>=25.6.0,<26.0.0)
|
|
15
|
+
Requires-Dist: packaging (>=21.0)
|
|
15
16
|
Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
|
|
16
17
|
Requires-Dist: questionary (>=2.1.1,<3.0.0)
|
|
17
18
|
Requires-Dist: requests (>=2.32.4,<3.0.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "systemlink-cli"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.8.0"
|
|
4
4
|
description = "SystemLink Integrator CLI - cross-platform CLI for SystemLink workflows and templates."
|
|
5
5
|
authors = ["Fred Visser <fred.visser@emerson.com>"]
|
|
6
6
|
packages = [{ include = "slcli" }]
|
|
@@ -35,6 +35,7 @@ truststore = ">=0.9,<0.11"
|
|
|
35
35
|
watchdog = "^6.0.0"
|
|
36
36
|
pyyaml = "^6.0.3"
|
|
37
37
|
questionary = "^2.1.1"
|
|
38
|
+
packaging = ">=21.0"
|
|
38
39
|
rich = ">=13.7,<15"
|
|
39
40
|
rich-click = ">=1.8,<2"
|
|
40
41
|
|
|
@@ -11,7 +11,7 @@ import questionary
|
|
|
11
11
|
from .utils import ExitCodes
|
|
12
12
|
|
|
13
13
|
SKILL_NAME = "slcli"
|
|
14
|
-
SKILL_CHOICES = ["slcli", "systemlink-webapp"]
|
|
14
|
+
SKILL_CHOICES = ["slcli", "systemlink-webapp", "systemlink-notebook"]
|
|
15
15
|
|
|
16
16
|
# Mapping of client name -> (personal skills dir, project subdir relative to repo root)
|
|
17
17
|
# personal dir uses Path.home() so it's always resolved at call time via _personal_dir().
|
|
@@ -178,7 +178,7 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
178
178
|
"-k",
|
|
179
179
|
type=click.Choice(SKILL_CHOICES + ["all"], case_sensitive=False),
|
|
180
180
|
default=None,
|
|
181
|
-
help="Skill to install (slcli, systemlink-webapp, or all).",
|
|
181
|
+
help="Skill to install (slcli, systemlink-webapp, systemlink-notebook, or all).",
|
|
182
182
|
)
|
|
183
183
|
@click.option(
|
|
184
184
|
"--client",
|
|
@@ -207,7 +207,7 @@ def register_skill_commands(cli: Any) -> None:
|
|
|
207
207
|
"""Install agent skills for AI coding assistants.
|
|
208
208
|
|
|
209
209
|
Copies bundled skills into the skills directory of one or more AI clients.
|
|
210
|
-
Available skills: slcli, systemlink-webapp.
|
|
210
|
+
Available skills: slcli, systemlink-webapp, systemlink-notebook.
|
|
211
211
|
Supported clients and their skill locations:
|
|
212
212
|
|
|
213
213
|
\b
|
|
@@ -227,6 +227,15 @@ slcli system report --type [SOFTWARE|HARDWARE] -o FILE # Generate CSV report
|
|
|
227
227
|
slcli system update <SYSTEM_ID> [OPTIONS] # Update system metadata
|
|
228
228
|
slcli system remove <SYSTEM_ID> # Remove a system
|
|
229
229
|
|
|
230
|
+
# Compare two systems (by ID or alias)
|
|
231
|
+
slcli system compare <SYSTEM_A> <SYSTEM_B> [-f json]
|
|
232
|
+
# Compares installed software (packages, versions) and connected assets
|
|
233
|
+
# (model, vendor, slot number). Accepts system IDs or alias names.
|
|
234
|
+
# Output sections:
|
|
235
|
+
# Software: packages unique to each system, version differences
|
|
236
|
+
# Assets: assets unique to each system, count mismatches, slot differences
|
|
237
|
+
# Assets are matched by (modelName, vendorName) identity.
|
|
238
|
+
|
|
230
239
|
# System jobs
|
|
231
240
|
slcli system job list [OPTIONS]
|
|
232
241
|
slcli system job get <JOB_ID>
|
|
@@ -249,6 +258,7 @@ slcli tag delete <TAG_PATH> # Delete a tag
|
|
|
249
258
|
### routine — Event-action and notebook routine management
|
|
250
259
|
|
|
251
260
|
Two API versions are supported:
|
|
261
|
+
|
|
252
262
|
- **v2** (default): General event-action routines — monitor tags, work-item changes, and more; trigger alarms, emails, or notebook executions.
|
|
253
263
|
- **v1**: Notebook-execution routines with SCHEDULED or TRIGGERED types.
|
|
254
264
|
|
|
@@ -580,7 +590,7 @@ slcli customfield edit [--directory DIR] # Interactively edit +
|
|
|
580
590
|
### template — Test plan template management
|
|
581
591
|
|
|
582
592
|
> **Note:** Work item templates are managed separately via `slcli workitem template`.
|
|
583
|
-
> The `slcli template` command manages test plan
|
|
593
|
+
> The `slcli template` command manages test plan _configuration_ templates used
|
|
584
594
|
> when provisioning new test plan instances.
|
|
585
595
|
|
|
586
596
|
```bash
|
|
@@ -641,6 +651,7 @@ slcli workitem workflow preview [--file PATH] [--id WORKFLOW_ID] [--html] [--no-
|
|
|
641
651
|
```
|
|
642
652
|
|
|
643
653
|
**Create work item options:**
|
|
654
|
+
|
|
644
655
|
```bash
|
|
645
656
|
slcli workitem create \
|
|
646
657
|
--name "Battery Cycle Test" \
|
|
@@ -692,15 +703,17 @@ generated `.nipkg`, and emits a thin `manifest.json` with `schemaVersion`, `nipk
|
|
|
692
703
|
Install bundled skills for supported AI clients.
|
|
693
704
|
|
|
694
705
|
```bash
|
|
695
|
-
slcli skill install --skill [slcli|systemlink-webapp|all] --client [agents|claude|all] --scope [personal|project|both]
|
|
706
|
+
slcli skill install --skill [slcli|systemlink-webapp|systemlink-notebook|all] --client [agents|claude|all] --scope [personal|project|both]
|
|
696
707
|
```
|
|
697
708
|
|
|
698
709
|
Client paths:
|
|
710
|
+
|
|
699
711
|
- `agents` — personal: `~/.agents/skills/`, project: `.agents/skills/` (most agents)
|
|
700
712
|
- `claude` — personal: `~/.claude/skills/`, project: `.claude/skills/`
|
|
701
713
|
- `all` — install to both the `agents` and `claude` locations for the selected scope
|
|
702
714
|
|
|
703
715
|
Notes:
|
|
716
|
+
|
|
704
717
|
- `agents` is the default client in interactive mode.
|
|
705
718
|
- `webapp init` installs project-scoped skills into `.agents/skills/` by default.
|
|
706
719
|
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: systemlink-notebook
|
|
3
|
+
description: >-
|
|
4
|
+
Create, structure, and deploy Jupyter Notebooks for NI SystemLink.
|
|
5
|
+
Use when the user asks to create a notebook, report, or analysis that runs on
|
|
6
|
+
SystemLink — including Systems Grid reports, test data analysis notebooks,
|
|
7
|
+
asset reports, scheduled notebooks, or any notebook that uses scrapbook (sb.glue)
|
|
8
|
+
to return results. Covers parameter cells, systemlink metadata, output formats,
|
|
9
|
+
papermill integration, and deployment via slcli.
|
|
10
|
+
argument-hint: 'Describe the notebook purpose and what data it should report on'
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# SystemLink Notebook Creation
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- Creating a new Jupyter Notebook that will run on SystemLink
|
|
18
|
+
- Adding parameters or outputs to a notebook for the SystemLink Notebook Execution Service
|
|
19
|
+
- Building a Systems Grid column report
|
|
20
|
+
- Creating a test data analysis notebook
|
|
21
|
+
- Deploying a notebook to SystemLink via `slcli`
|
|
22
|
+
|
|
23
|
+
## Notebook Structure
|
|
24
|
+
|
|
25
|
+
Every SystemLink notebook follows this cell pattern:
|
|
26
|
+
|
|
27
|
+
1. **Imports (markdown)** — describe dependencies
|
|
28
|
+
2. **Imports (code)** — import modules
|
|
29
|
+
3. **Parameters (markdown)** — describe each parameter
|
|
30
|
+
4. **Parameters (code)** — declare parameter variables with defaults *(requires special metadata)*
|
|
31
|
+
5. **Logic (markdown + code)** — one or more pairs of markdown/code cells
|
|
32
|
+
6. **Output (markdown)** — describe the output format
|
|
33
|
+
7. **Output (code)** — format results and call `sb.glue('result', result)`
|
|
34
|
+
8. **Instructions (markdown)** — how to use the notebook in SystemLink UI
|
|
35
|
+
|
|
36
|
+
## Parameters Cell Metadata
|
|
37
|
+
|
|
38
|
+
The parameters cell is the most critical part. It **must** have this metadata structure
|
|
39
|
+
in the cell's `.metadata` field for SystemLink to recognize the parameters and outputs.
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"papermill": {
|
|
44
|
+
"parameters": {
|
|
45
|
+
"param_name": "default_value"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"systemlink": {
|
|
49
|
+
"namespaces": [],
|
|
50
|
+
"outputs": [
|
|
51
|
+
{
|
|
52
|
+
"display_name": "Human Readable Output Name",
|
|
53
|
+
"id": "output_snake_case_id",
|
|
54
|
+
"type": "data_frame"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"parameters": [
|
|
58
|
+
{
|
|
59
|
+
"display_name": "Human Readable Param Name",
|
|
60
|
+
"id": "param_name",
|
|
61
|
+
"type": "string"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"version": 2
|
|
65
|
+
},
|
|
66
|
+
"tags": ["parameters"]
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Key rules for parameter metadata
|
|
71
|
+
|
|
72
|
+
- `papermill.parameters` keys **must** match the variable names in the code cell
|
|
73
|
+
- `systemlink.parameters[].id` **must** match the variable names in the code cell
|
|
74
|
+
- `systemlink.outputs[].id` **must** match the key used in the result dict passed to `sb.glue`
|
|
75
|
+
- `tags: ["parameters"]` is **required** — this is how papermill identifies the cell
|
|
76
|
+
- `systemlink.version` must be `2` for most notebooks, or `1` for **Work Item Automations**
|
|
77
|
+
- Supported parameter types: `string`, `integer`, `float`, `boolean`, `string[]`
|
|
78
|
+
- Supported output types: `data_frame`, `scalar`, `string`, `string[]`
|
|
79
|
+
|
|
80
|
+
### Work Item Automations pattern
|
|
81
|
+
|
|
82
|
+
Notebooks with the **Work Item Automations** interface receive work item IDs as a
|
|
83
|
+
**list** (`string[]`), not a comma-separated string. Key differences from other notebooks:
|
|
84
|
+
|
|
85
|
+
- `systemlink.version` must be `1`
|
|
86
|
+
- `work_item_ids` parameter type is `"string[]"` and its default value in
|
|
87
|
+
`papermill.parameters` is `[]` (empty list)
|
|
88
|
+
- The Python variable must also default to a list: `work_item_ids = []`
|
|
89
|
+
- Do NOT split by comma — the parameter is already a list of strings
|
|
90
|
+
|
|
91
|
+
Example parameters cell metadata for Work Item Automations:
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"papermill": {
|
|
95
|
+
"parameters": {
|
|
96
|
+
"work_item_ids": []
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"systemlink": {
|
|
100
|
+
"outputs": [...],
|
|
101
|
+
"parameters": [
|
|
102
|
+
{
|
|
103
|
+
"display_name": "Work item IDs",
|
|
104
|
+
"id": "work_item_ids",
|
|
105
|
+
"type": "string[]"
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"version": 1
|
|
109
|
+
},
|
|
110
|
+
"tags": ["parameters"]
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Output Format (sb.glue)
|
|
115
|
+
|
|
116
|
+
All notebooks must use `scrapbook` to return results. The output cell should:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
import scrapbook as sb
|
|
120
|
+
|
|
121
|
+
# For data_frame outputs:
|
|
122
|
+
result = [{
|
|
123
|
+
"display_name": "Human Readable Name",
|
|
124
|
+
"id": "output_id", # Must match systemlink.outputs[].id
|
|
125
|
+
"type": "data_frame",
|
|
126
|
+
"data": {
|
|
127
|
+
"columns": ["column1", "column2"],
|
|
128
|
+
"values": df.reset_index().values.tolist()
|
|
129
|
+
}
|
|
130
|
+
}]
|
|
131
|
+
sb.glue('result', result)
|
|
132
|
+
|
|
133
|
+
# For scalar outputs:
|
|
134
|
+
result = [{
|
|
135
|
+
"display_name": "Count",
|
|
136
|
+
"id": "count_output",
|
|
137
|
+
"type": "scalar",
|
|
138
|
+
"data": 42
|
|
139
|
+
}]
|
|
140
|
+
sb.glue('result', result)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Systems Grid reports
|
|
144
|
+
|
|
145
|
+
When the notebook is used as a Systems Grid column, the `data_frame` output
|
|
146
|
+
**must** include `minion id` as the first column. This maps rows to systems.
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
df_dict = {
|
|
150
|
+
'columns': ['minion id', 'your column name'],
|
|
151
|
+
'values': df.reset_index().values.tolist() # index = system IDs
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Common Imports
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
# Always needed
|
|
159
|
+
import pandas as pd
|
|
160
|
+
import scrapbook as sb
|
|
161
|
+
|
|
162
|
+
# Systems queries
|
|
163
|
+
from systemlink.clients.nisysmgmt.api.systems_api import SystemsApi
|
|
164
|
+
from systemlink.clients.nisysmgmt.models.query_systems_request import QuerySystemsRequest
|
|
165
|
+
|
|
166
|
+
# Test results
|
|
167
|
+
from nisystemlink.clients.testmonitor import TestMonitorClient
|
|
168
|
+
from nisystemlink.clients.core import HttpConfigurationManager
|
|
169
|
+
|
|
170
|
+
# Assets
|
|
171
|
+
from nisystemlink.clients.assetmanagement import AssetManagementClient
|
|
172
|
+
|
|
173
|
+
# Direct HTTP (when no typed client exists)
|
|
174
|
+
import requests
|
|
175
|
+
from nisystemlink.clients.core import HttpConfigurationManager
|
|
176
|
+
config = HttpConfigurationManager.get_configuration()
|
|
177
|
+
base_url = config.server_uri.rstrip("/")
|
|
178
|
+
headers = {"x-ni-api-key": config.api_keys[0]}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Systems Query Pattern
|
|
182
|
+
|
|
183
|
+
The `SystemsApi` uses a projection/filter pattern for querying:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
api = SystemsApi()
|
|
187
|
+
|
|
188
|
+
# Projection selects which fields to return
|
|
189
|
+
projection = 'new(id, alias, state, packages.data["ni-daqmx"].displayversion)'
|
|
190
|
+
|
|
191
|
+
# Filter selects which systems to include
|
|
192
|
+
filter = '!string.IsNullOrEmpty(id) && packages.data.keys.Contains("ni-daqmx")'
|
|
193
|
+
|
|
194
|
+
query = QuerySystemsRequest(skip=0, projection=projection, filter=filter)
|
|
195
|
+
query_result = api.get_systems_by_query(query=query)
|
|
196
|
+
data = await query_result
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Common filter expressions
|
|
200
|
+
|
|
201
|
+
| Filter | Description |
|
|
202
|
+
|--------|-------------|
|
|
203
|
+
| `!string.IsNullOrEmpty(id)` | All systems (default/fallback) |
|
|
204
|
+
| `connected.data.state == "CONNECTED"` | Connected systems only |
|
|
205
|
+
| `packages.data.keys.Contains("pkg")` | Systems with a specific package |
|
|
206
|
+
| `grains.data.kernel == "Windows"` | Windows systems |
|
|
207
|
+
|
|
208
|
+
## Notebook Interfaces
|
|
209
|
+
|
|
210
|
+
When deploying, set the notebook interface to tell SystemLink how it will be used.
|
|
211
|
+
See [interfaces reference](./references/interfaces.md) for the full list.
|
|
212
|
+
|
|
213
|
+
Common interfaces:
|
|
214
|
+
- **Systems Grid** — report that adds a column to the Systems management grid
|
|
215
|
+
- **Test Data Analysis** — analysis of test monitor results
|
|
216
|
+
- **Periodic Execution** — scheduled recurring notebook
|
|
217
|
+
- **Work Item Automations** — triggered by work item state changes
|
|
218
|
+
|
|
219
|
+
## Setting Cell Metadata
|
|
220
|
+
|
|
221
|
+
The VS Code notebook editor tools do **not** persist custom cell metadata (like
|
|
222
|
+
`papermill`, `systemlink`, `tags`). You must write cell metadata directly into
|
|
223
|
+
the `.ipynb` JSON file using a Python script:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
import json
|
|
227
|
+
|
|
228
|
+
with open('notebook.ipynb') as f:
|
|
229
|
+
nb = json.load(f)
|
|
230
|
+
|
|
231
|
+
# Find the parameters cell and set its metadata
|
|
232
|
+
for cell in nb['cells']:
|
|
233
|
+
src = ''.join(cell.get('source', []))
|
|
234
|
+
if 'parameters' in src and cell['cell_type'] == 'code':
|
|
235
|
+
cell['metadata'] = {
|
|
236
|
+
"papermill": {
|
|
237
|
+
"parameters": {
|
|
238
|
+
"param_name": "default_value"
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
"systemlink": {
|
|
242
|
+
"namespaces": [],
|
|
243
|
+
"outputs": [...],
|
|
244
|
+
"parameters": [...],
|
|
245
|
+
"version": 2
|
|
246
|
+
},
|
|
247
|
+
"tags": ["parameters"],
|
|
248
|
+
"trusted": False,
|
|
249
|
+
"editable": True,
|
|
250
|
+
"slideshow": {"slide_type": ""}
|
|
251
|
+
}
|
|
252
|
+
break
|
|
253
|
+
|
|
254
|
+
with open('notebook.ipynb', 'w') as f:
|
|
255
|
+
json.dump(nb, f, indent=1)
|
|
256
|
+
f.write('\n')
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Critical:** Without this metadata, SystemLink will not display parameters or
|
|
260
|
+
outputs in the UI. Always verify metadata was written by inspecting the raw JSON.
|
|
261
|
+
|
|
262
|
+
Also ensure the notebook-level `kernelspec` metadata is set. Papermill requires
|
|
263
|
+
this to execute the notebook — without it you get
|
|
264
|
+
`ValueError: No kernel name found in notebook`. The VS Code notebook editor may
|
|
265
|
+
clear this when editing cells. Always verify and restore if needed:
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
nb['metadata']['kernelspec'] = {
|
|
269
|
+
'display_name': 'Python 3',
|
|
270
|
+
'language': 'python',
|
|
271
|
+
'name': 'python3'
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Deployment
|
|
276
|
+
|
|
277
|
+
Deploy via `slcli`. **Always read the user's configured workspace** from `slcli info`
|
|
278
|
+
and pass it with `--workspace` so the notebook lands in the correct workspace:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# 1. Read the configured workspace name from the active slcli profile
|
|
282
|
+
# (look for the "Workspace" row in `slcli info` output)
|
|
283
|
+
|
|
284
|
+
# Create a new notebook with interface and workspace set at creation time (preferred)
|
|
285
|
+
slcli notebook manage create --file notebook.ipynb --name "My Notebook" --interface "Systems Grid" --workspace "<WORKSPACE_NAME>"
|
|
286
|
+
|
|
287
|
+
# Update content of an existing notebook
|
|
288
|
+
slcli notebook manage update --id <NOTEBOOK_ID> --content notebook.ipynb
|
|
289
|
+
|
|
290
|
+
# Update interface or metadata in place when needed
|
|
291
|
+
slcli notebook manage update --id <NOTEBOOK_ID> --interface "Systems Grid"
|
|
292
|
+
|
|
293
|
+
# Delete and re-create only as a fallback if the server rejects the update
|
|
294
|
+
slcli notebook manage delete --id <NOTEBOOK_ID> --yes
|
|
295
|
+
slcli notebook manage create --file notebook.ipynb --name "My Notebook" --interface "Systems Grid" --workspace "<WORKSPACE_NAME>"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Important:** Prefer setting `--interface` at creation time, but use
|
|
299
|
+
`slcli notebook manage update --interface ...` for in-place interface changes when
|
|
300
|
+
you are updating an existing notebook. Delete and re-create only as a fallback if
|
|
301
|
+
the server rejects the update.
|
|
302
|
+
|
|
303
|
+
**Important:** Always determine the target workspace by running `slcli info` and
|
|
304
|
+
reading the `Workspace` field from the active profile. Do not assume "Default" or
|
|
305
|
+
prompt the user unless `slcli info` shows no workspace configured.
|
|
306
|
+
|
|
307
|
+
## Example
|
|
308
|
+
|
|
309
|
+
See [notebook-patterns.md](./references/notebook-patterns.md) for a complete
|
|
310
|
+
annotated example based on the NI PackageVersionExample pattern.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Notebook Interfaces
|
|
2
|
+
|
|
3
|
+
When deploying a notebook to SystemLink, you can assign an **interface** that tells
|
|
4
|
+
SystemLink how the notebook will be used. This affects how parameters are presented
|
|
5
|
+
and how the notebook is triggered.
|
|
6
|
+
|
|
7
|
+
Set the interface during creation or update:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
slcli notebook manage update --id <ID> --interface "Systems Grid"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Prefer `create --interface ...` when you are creating a new notebook. Use
|
|
14
|
+
`update --interface ...` for in-place interface changes on an existing notebook.
|
|
15
|
+
Delete and re-create only if the server rejects the update.
|
|
16
|
+
|
|
17
|
+
## Available Interfaces
|
|
18
|
+
|
|
19
|
+
| Interface | Use Case |
|
|
20
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
21
|
+
| **Assets Grid** | Report that adds a column to the Assets management grid |
|
|
22
|
+
| **Data Table Analysis** | Analysis of data table contents |
|
|
23
|
+
| **Data Space Analysis** | Analysis of data space contents |
|
|
24
|
+
| **File Analysis** | Analysis of uploaded files |
|
|
25
|
+
| **Periodic Execution** | Scheduled recurring notebook (e.g. daily/hourly reports) |
|
|
26
|
+
| **Resource Changed Routine** | Triggered when a resource changes (via v1 routines) |
|
|
27
|
+
| **Specification Analysis** | Analysis against specifications/limits |
|
|
28
|
+
| **Systems Grid** | Report that adds a column to the Systems management grid |
|
|
29
|
+
| **Test Data Analysis** | Analysis of test monitor results |
|
|
30
|
+
| **Test Data Extraction** | Extract and transform test data |
|
|
31
|
+
| **Work Item Automations** | Notebooks that can be manually executed on selected work items, or triggered by work item lifecycle events. **Use this for any notebook that acts on work items** (e.g. close, update status, assign). |
|
|
32
|
+
| **Work Item Operations** | Internal operations performed on work items by the system |
|
|
33
|
+
| **Work Item Scheduler** | Scheduling logic for work items |
|
|
34
|
+
|
|
35
|
+
## Common Interface Patterns
|
|
36
|
+
|
|
37
|
+
### Systems Grid
|
|
38
|
+
|
|
39
|
+
Parameters typically include:
|
|
40
|
+
|
|
41
|
+
- `group_by` (string) — always support "System"
|
|
42
|
+
- `systems_filter` (string) — filter expression for which systems
|
|
43
|
+
- Domain-specific params (e.g. `package` for package version)
|
|
44
|
+
|
|
45
|
+
Output must be `data_frame` with `minion id` as the first column.
|
|
46
|
+
|
|
47
|
+
### Test Data Analysis
|
|
48
|
+
|
|
49
|
+
Parameters typically include:
|
|
50
|
+
|
|
51
|
+
- `group_by` (string)
|
|
52
|
+
- `program_name` (string)
|
|
53
|
+
- `status_filter` (string)
|
|
54
|
+
- `systems_filter` (string)
|
|
55
|
+
|
|
56
|
+
### Periodic Execution
|
|
57
|
+
|
|
58
|
+
No special parameter requirements. Typically uses fixed configuration
|
|
59
|
+
or reads from tags/files. Can be scheduled via routines:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
slcli routine create --api-version v1 \
|
|
63
|
+
--name "Daily Report" \
|
|
64
|
+
--type SCHEDULED \
|
|
65
|
+
--notebook-id <NOTEBOOK_ID> \
|
|
66
|
+
--schedule '{"startTime":"2026-01-01T00:00:00Z","repeat":"DAY"}'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Work Item Automations
|
|
70
|
+
|
|
71
|
+
Use this interface for notebooks that act on selected work items (close, update,
|
|
72
|
+
assign, etc.). The notebook appears in the work items UI and can be manually
|
|
73
|
+
triggered on one or more selected work items.
|
|
74
|
+
|
|
75
|
+
Parameters are injected by the work item system:
|
|
76
|
+
|
|
77
|
+
- `work_item_ids` (string[]) — list of selected work item IDs. Default: `[]`
|
|
78
|
+
- `workspace` (string) — workspace context (optional)
|
|
79
|
+
|
|
80
|
+
**Critical:** `work_item_ids` must be typed as `"string[]"` (not `"string"`),
|
|
81
|
+
default to `[]` in both papermill and the code cell, and `systemlink.version`
|
|
82
|
+
must be `1`. See the systemlink-notebook skill for the full metadata example.
|