Skip to content

Commit 12c9b2e

Browse files
authored
Merge pull request #12 from ni-kismet/users/fvisser/add-function-support
Add function support
2 parents c65b127 + 6a8e7ca commit 12c9b2e

File tree

10 files changed

+2613
-3
lines changed

10 files changed

+2613
-3
lines changed

.env.example

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# SystemLink Function Services Configuration
2+
# These environment variables can be set in this .env file for local development
3+
4+
# Unified Function Management Service URL (definitions + executions)
5+
# FUNCTION_SERVICE_URL=http://localhost:8080
6+
7+
# Legacy separate execution service URL is no longer used:
8+
# (FUNCTION_EXECUTION_SERVICE_URL has been deprecated)
9+
10+
# Or specify a common base URL used to derive the unified service path
11+
# SYSTEMLINK_API_URL=http://localhost:8080
12+
13+
# API Key for authentication
14+
# SYSTEMLINK_API_KEY=your_api_key_here
15+
16+
# SSL Verification (set to false for local development with self-signed certificates)
17+
# SLCLI_SSL_VERIFY=false

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,4 @@ tests/unit/__pycache__/
8383

8484
# E2E test configuration
8585
tests/e2e/e2e_config.json
86+
.env

README.md

Lines changed: 578 additions & 0 deletions
Large diffs are not rendered by default.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ authors = ["Fred Visser <fred.visser@emerson.com>"]
99
slcli = "slcli.__main__:cli"
1010
build-pyinstaller = "scripts.build_pyinstaller:main"
1111
update-version = "scripts.update_version:main"
12+
lint = "scripts.lint:main"
1213

1314
[tool.poetry.dependencies]
1415
python = ">=3.11.1,<3.14"

scripts/lint.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""Convenience script to run style linting and formatting.
2+
3+
Default (no flags):
4+
- Run style guide lint checks (non-modifying)
5+
- Run black in check mode (no file changes)
6+
7+
With --fix:
8+
- Run style guide lint checks (still non-modifying; separate fixer not provided)
9+
- Run black to auto-format the codebase
10+
11+
Equivalent commands:
12+
Check: ni-python-styleguide lint && black --check .
13+
Fix: ni-python-styleguide lint && black .
14+
15+
Exposed as `poetry run lint` via pyproject.toml.
16+
"""
17+
18+
from __future__ import annotations
19+
20+
import subprocess
21+
import sys
22+
from typing import List
23+
24+
25+
def _run(cmd: List[str]) -> int:
26+
"""Run a subprocess command and return its exit code."""
27+
proc = subprocess.run(cmd, stdout=sys.stdout, stderr=sys.stderr) # noqa: S603,S607
28+
return proc.returncode
29+
30+
31+
def main() -> None:
32+
"""Execute lint steps; optionally format when --fix provided."""
33+
fix = "--fix" in sys.argv[1:]
34+
# Remove our flag so tools don't see it
35+
if fix:
36+
sys.argv = [sys.argv[0]] + [a for a in sys.argv[1:] if a != "--fix"]
37+
38+
code = 0
39+
# Lint (non-modifying)
40+
if _run([sys.executable, "-m", "ni_python_styleguide", "lint"]) != 0:
41+
code = 1
42+
43+
# Formatting
44+
black_cmd = [sys.executable, "-m", "black"]
45+
if fix:
46+
black_cmd.append(".")
47+
else:
48+
black_cmd.extend(["--check", "."])
49+
50+
if _run(black_cmd) != 0:
51+
code = 1
52+
53+
sys.exit(code)
54+
55+
56+
if __name__ == "__main__": # pragma: no cover
57+
main()

slcli/config.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""Configuration management for slcli."""
2+
3+
import json
4+
import os
5+
from pathlib import Path
6+
from typing import Dict, Optional
7+
8+
9+
def get_config_file_path() -> Path:
10+
"""Get the path to the slcli configuration file."""
11+
# Use XDG_CONFIG_HOME if set, otherwise use ~/.config
12+
if "XDG_CONFIG_HOME" in os.environ:
13+
config_dir = Path(os.environ["XDG_CONFIG_HOME"]) / "slcli"
14+
else:
15+
config_dir = Path.home() / ".config" / "slcli"
16+
17+
config_dir.mkdir(parents=True, exist_ok=True)
18+
return config_dir / "config.json"
19+
20+
21+
def load_config() -> Dict[str, str]:
22+
"""Load configuration from the config file.
23+
24+
Returns:
25+
Dictionary containing configuration values
26+
"""
27+
config_file = get_config_file_path()
28+
29+
if not config_file.exists():
30+
return {}
31+
32+
try:
33+
with open(config_file, "r", encoding="utf-8") as f:
34+
return json.load(f)
35+
except (json.JSONDecodeError, OSError):
36+
# If config file is corrupted or unreadable, return empty config
37+
return {}
38+
39+
40+
def save_config(config: Dict[str, str]) -> None:
41+
"""Save configuration to the config file.
42+
43+
Args:
44+
config: Dictionary containing configuration values to save
45+
"""
46+
config_file = get_config_file_path()
47+
48+
try:
49+
with open(config_file, "w", encoding="utf-8") as f:
50+
json.dump(config, f, indent=2)
51+
except OSError as e:
52+
raise RuntimeError(f"Failed to save configuration: {e}")
53+
54+
55+
def get_function_service_url() -> Optional[str]:
56+
"""Get the configured URL for the Function Service.
57+
58+
Returns:
59+
The configured function service URL, or None if not configured
60+
"""
61+
config = load_config()
62+
return config.get("function_service_url")
63+
64+
65+
def set_function_service_url(url: str) -> None:
66+
"""Set the URL for the Function Service.
67+
68+
Args:
69+
url: The URL to use for function commands
70+
"""
71+
config = load_config()
72+
config["function_service_url"] = url
73+
save_config(config)
74+
75+
76+
def remove_function_service_url() -> None:
77+
"""Remove the configured Function Service URL."""
78+
config = load_config()
79+
if "function_service_url" in config:
80+
del config["function_service_url"]
81+
save_config(config)

0 commit comments

Comments
 (0)