Skip to content

Commit d8488ad

Browse files
committed
trim the fat on parameter parsing
1 parent 74a776d commit d8488ad

File tree

1 file changed

+63
-30
lines changed

1 file changed

+63
-30
lines changed

src/warnet/plugin.py

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import os
66
import sys
77
import tempfile
8+
from dataclasses import dataclass
9+
from enum import Enum, auto
810
from importlib.metadata import PackageNotFoundError, version
911
from pathlib import Path
1012
from types import ModuleType
@@ -32,6 +34,17 @@ class PluginError(Exception):
3234
pass
3335

3436

37+
class ParamStrategy(Enum):
38+
POSITIONAL = auto()
39+
NAMED = auto()
40+
41+
42+
@dataclass
43+
class Params:
44+
params: list | dict
45+
type: ParamStrategy
46+
47+
3548
hook_registry: set[Callable[..., Any]] = set()
3649
imported_modules: dict[str, ModuleType] = {}
3750

@@ -103,24 +116,40 @@ def toggle(plugin: str):
103116
@plugin.command()
104117
@click.argument("plugin_name", type=str, default="")
105118
@click.argument("function_name", type=str, default="")
106-
@click.option("--params", type=str, default="")
107-
@click.option("--json-input", type=str, default="")
108-
def run(plugin_name: str, function_name: str, params: str, json_input: str):
109-
"""Explore and run plugins"""
119+
@click.option(
120+
"--params", type=str, default="", help="Paramter data to be fed to the plugin function"
121+
)
122+
def run(plugin_name: str, function_name: str, params: str):
123+
"""Explore and run plugins
124+
125+
Use `--params` to pass a JSON list for positional arguments or a JSON object for named arguments.
126+
127+
Like this:
128+
129+
Positional - '["first element", 2, 3.0]'
130+
131+
Named - '{"first": "first_element", "second": 2, "third": 3.0}'
132+
"""
110133
show_explainer = False
111134

112135
plugin_dir = _get_plugin_directory()
113136
if plugin_dir is None:
114137
direct_user_to_plugin_directory_and_exit()
115138

116139
plugins = get_plugins_with_status(plugin_dir)
140+
plugin_was_found = False
117141
for plugin_path, status in plugins:
142+
if plugin_path.stem == plugin_name:
143+
plugin_was_found = True
118144
if plugin_path.stem == plugin_name and not status:
119145
click.secho(f"The plugin '{plugin_path.stem}' is not enabled", fg="yellow")
120146
click.secho("Please toggle it on to use it.")
121147
sys.exit(0)
148+
if plugin_name and not plugin_was_found:
149+
click.secho(f"The plugin '{plugin_name}' was not found.", fg="yellow")
150+
sys.exit(0)
122151

123-
if plugin_name == "" and sys.stdin.isatty():
152+
if plugin_name == "":
124153
show_explainer = True
125154
plugin_names = [
126155
plugin_name.stem for plugin_name, status in get_plugins_with_status() if status
@@ -132,7 +161,7 @@ def run(plugin_name: str, function_name: str, params: str, json_input: str):
132161
sys.exit(0)
133162
plugin_name = plugin_answer.get("plugin")
134163

135-
if function_name == "" and sys.stdin.isatty():
164+
if function_name == "":
136165
show_explainer = True
137166
module = imported_modules.get(f"plugins.{plugin_name}")
138167
funcs = [
@@ -152,20 +181,7 @@ def run(plugin_name: str, function_name: str, params: str, json_input: str):
152181
if not func:
153182
sys.exit(0)
154183

155-
if params:
156-
print(params)
157-
params = json.loads(params)
158-
try:
159-
return_value = func(*params)
160-
if return_value is not None:
161-
jsonified = json.dumps(return_value)
162-
print(f"'{jsonified}'")
163-
sys.exit(0)
164-
except Exception as e:
165-
click.secho(f"Exception: {e}", fg="yellow")
166-
sys.exit(1)
167-
168-
if not json_input and not params:
184+
if not params:
169185
params = {}
170186
sig = inspect.signature(func)
171187
for name, param in sig.parameters.items():
@@ -207,18 +223,35 @@ def run(plugin_name: str, function_name: str, params: str, json_input: str):
207223
f"\nwarnet plugin run {plugin_name} {function_name} --json-input '{json.dumps(params)}'",
208224
fg="green",
209225
)
210-
211226
else:
212-
params = json.loads(json_input)
227+
params = json.loads(params)
213228

214-
try:
215-
return_value = func(**params)
216-
if return_value is not None:
217-
jsonified = json.dumps(return_value)
218-
print(f"'{jsonified}'")
219-
except Exception as e:
220-
click.secho(f"Exception: {e}", fg="yellow")
221-
sys.exit(1)
229+
execute_function_with_params(func, params)
230+
231+
232+
def execute_function_with_params(func: Callable[..., Any], params: dict | list):
233+
match params:
234+
case dict():
235+
try:
236+
return_value = func(**params)
237+
if return_value is not None:
238+
jsonified = json.dumps(return_value)
239+
print(f"'{jsonified}'")
240+
except Exception as e:
241+
click.secho(f"Exception: {e}", fg="yellow")
242+
sys.exit(1)
243+
case list():
244+
try:
245+
return_value = func(*params)
246+
if return_value is not None:
247+
jsonified = json.dumps(return_value)
248+
print(f"'{jsonified}'")
249+
except Exception as e:
250+
click.secho(f"Exception: {e}", fg="yellow")
251+
sys.exit(1)
252+
case _:
253+
click.secho(f"Did not anticipate this type: {params} --> {type(params)}")
254+
sys.exit(1)
222255

223256

224257
def process_obj(some_obj, func) -> dict:

0 commit comments

Comments
 (0)