feat: simplify node selection, enhance gRPC execution logic, and improve CLI aggregate summaries

This commit is contained in:
2026-04-30 14:18:41 -03:00
parent 96049b4028
commit 7967c413c9
71 changed files with 1762 additions and 524 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.ai_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -371,7 +371,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.api_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -193,7 +193,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.config_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -482,7 +482,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.context_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -249,7 +249,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.forms API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -517,7 +517,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+4 -9
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.help_text API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -215,9 +215,7 @@ tasks:
nodes: #List of nodes to work on. Mandatory
- &#39;router1@office&#39; #You can add specific nodes
- &#39;@aws&#39; #entire folders or subfolders
- &#39;@office&#39;: #or filter inside a folder or subfolder
- &#39;router2&#39;
- &#39;router7&#39;
- &#39;router.*@office&#39; #or use regex to filter inside a folder
commands: #List of commands to send, use {name} to pass variables
- &#39;term len 0&#39;
@@ -243,7 +241,7 @@ tasks:
vrouterN@aws:
id: 5
output: /home/user/logs #Type of output, if null you only get Connection and test result. Choices are: null,stdout,/path/to/folder. Folder path only works on &#39;run&#39; action.
output: /home/user/logs #Type of output, if null you only get Connection and test result. Choices are: null,stdout,/path/to/folder. Folder path works on both &#39;run&#39; and &#39;test&#39; actions.
options:
prompt: r&#39;&gt;$|#$|\$$|&gt;.$|#.$|\$.$&#39; #Optional prompt to check on your devices, default should work on most devices.
@@ -255,9 +253,6 @@ tasks:
nodes:
- &#39;router1@office&#39;
- &#39;@aws&#39;
- &#39;@office&#39;:
- &#39;router2&#39;
- &#39;router7&#39;
commands:
- &#39;ping 10.100.100.{id}&#39;
expected: &#39;!&#39; #Expected text to find when running test action. Mandatory for &#39;test&#39;
@@ -304,7 +299,7 @@ tasks:
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.helpers API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -207,7 +207,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.import_export_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -272,7 +272,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -137,7 +137,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.node_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -606,7 +606,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.plugin_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -385,7 +385,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.profile_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -314,7 +314,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+155 -64
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.run_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -58,6 +58,7 @@ el.replaceWith(d);
<pre><code class="python">class RunHandler:
def __init__(self, app):
self.app = app
self.print_lock = threading.Lock()
def dispatch(self, args):
if len(args.data) &gt; 1:
@@ -68,22 +69,43 @@ el.replaceWith(d);
def node_run(self, args):
nodes_filter = args.data[0]
commands = [&#34; &#34;.join(args.data[1:])]
try:
header_printed = False
# Inline execution with streaming results
def _on_node_complete(unique, node_output, node_status):
nonlocal header_printed
if not header_printed:
printer.console.print(Rule(&#34;OUTPUT&#34;, style=&#34;header&#34;))
header_printed = True
printer.node_panel(unique, node_output, node_status)
self.app.services.execution.run_commands(
nodes_filter=nodes_filter,
commands=commands,
on_node_complete=_on_node_complete
)
if hasattr(args, &#39;test_expected&#39;) and args.test_expected:
# Mode: Test
def _on_node_complete(unique, node_output, node_status, node_result):
nonlocal header_printed
with self.print_lock:
if not header_printed:
printer.console.print(Rule(&#34;OUTPUT&#34;, style=&#34;header&#34;))
header_printed = True
printer.test_panel(unique, node_output, node_status, node_result)
results = self.app.services.execution.test_commands(
nodes_filter=nodes_filter,
commands=commands,
expected=args.test_expected,
on_node_complete=_on_node_complete
)
printer.test_summary(results)
else:
# Mode: Normal Run
def _on_node_complete(unique, node_output, node_status):
nonlocal header_printed
with self.print_lock:
if not header_printed:
printer.console.print(Rule(&#34;OUTPUT&#34;, style=&#34;header&#34;))
header_printed = True
printer.node_panel(unique, node_output, node_status)
results = self.app.services.execution.run_commands(
nodes_filter=nodes_filter,
commands=commands,
on_node_complete=_on_node_complete
)
printer.run_summary(results)
except ConnpyError as e:
printer.error(str(e))
@@ -104,36 +126,44 @@ el.replaceWith(d);
try:
with open(path, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
for task in playbook.get(&#34;tasks&#34;, []):
self.cli_run(task)
except Exception as e:
printer.error(f&#34;Failed to run playbook {path}: {e}&#34;)
sys.exit(10)
def cli_run(self, script):
name = script.get(&#34;name&#34;, &#34;Task&#34;)
try:
action = script[&#34;action&#34;]
nodelist = script[&#34;nodes&#34;]
commands = script[&#34;commands&#34;]
variables = script.get(&#34;variables&#34;)
output_cfg = script[&#34;output&#34;]
name = script.get(&#34;name&#34;, &#34;Task&#34;)
options = script.get(&#34;options&#34;, {})
except KeyError as e:
printer.error(f&#34;&#39;{e.args[0]}&#39; is mandatory in script&#34;)
printer.error(f&#34;[{name}] &#39;{e.args[0]}&#39; is mandatory in script&#34;)
sys.exit(11)
stdout = (output_cfg == &#34;stdout&#34;)
folder = output_cfg if output_cfg not in [None, &#34;stdout&#34;] else None
prompt = options.get(&#34;prompt&#34;)
printer.header(name.upper())
try:
header_printed = False
if action == &#34;run&#34;:
# If stdout is true, we stream results as they arrive
on_complete = printer.node_panel if stdout else None
def _on_run_complete(unique, node_output, node_status):
nonlocal header_printed
if stdout:
with self.print_lock:
if not header_printed:
printer.console.print(Rule(name.upper(), style=&#34;header&#34;))
header_printed = True
printer.node_panel(unique, node_output, node_status)
results = self.app.services.execution.run_commands(
nodes_filter=nodelist,
commands=commands,
@@ -142,16 +172,31 @@ el.replaceWith(d);
timeout=options.get(&#34;timeout&#34;, 10),
folder=folder,
prompt=prompt,
on_node_complete=on_complete
on_node_complete=_on_run_complete
)
# If not streaming, we could print a summary table here if needed
if not stdout:
for unique, output in results.items():
# Final Summary
if not stdout and not folder:
with self.print_lock:
printer.console.print(Rule(name.upper(), style=&#34;header&#34;))
for unique, data in results.items():
output = data[&#34;output&#34;] if isinstance(data, dict) else data
printer.node_panel(unique, output, 0)
# ALWAYS show the aggregate execution summary at the end
printer.run_summary(results)
elif action == &#34;test&#34;:
expected = script.get(&#34;expected&#34;, [])
on_complete = printer.test_panel if stdout else None
# Show test_panel per node ONLY if stdout is True
def _on_test_complete(unique, node_output, node_status, node_result):
nonlocal header_printed
if stdout:
with self.print_lock:
if not header_printed:
printer.console.print(Rule(name.upper(), style=&#34;header&#34;))
header_printed = True
printer.test_panel(unique, node_output, node_status, node_result)
results = self.app.services.execution.test_commands(
nodes_filter=nodelist,
commands=commands,
@@ -159,12 +204,13 @@ el.replaceWith(d);
variables=variables,
parallel=options.get(&#34;parallel&#34;, 10),
timeout=options.get(&#34;timeout&#34;, 10),
folder=folder,
prompt=prompt,
on_node_complete=on_complete
on_node_complete=_on_test_complete
)
if not stdout:
printer.test_summary(results)
# ALWAYS show the aggregate summary at the end
printer.test_summary(results)
except ConnpyError as e:
printer.error(str(e))</code></pre>
</details>
@@ -180,27 +226,35 @@ el.replaceWith(d);
<span>Expand source code</span>
</summary>
<pre><code class="python">def cli_run(self, script):
name = script.get(&#34;name&#34;, &#34;Task&#34;)
try:
action = script[&#34;action&#34;]
nodelist = script[&#34;nodes&#34;]
commands = script[&#34;commands&#34;]
variables = script.get(&#34;variables&#34;)
output_cfg = script[&#34;output&#34;]
name = script.get(&#34;name&#34;, &#34;Task&#34;)
options = script.get(&#34;options&#34;, {})
except KeyError as e:
printer.error(f&#34;&#39;{e.args[0]}&#39; is mandatory in script&#34;)
printer.error(f&#34;[{name}] &#39;{e.args[0]}&#39; is mandatory in script&#34;)
sys.exit(11)
stdout = (output_cfg == &#34;stdout&#34;)
folder = output_cfg if output_cfg not in [None, &#34;stdout&#34;] else None
prompt = options.get(&#34;prompt&#34;)
printer.header(name.upper())
try:
header_printed = False
if action == &#34;run&#34;:
# If stdout is true, we stream results as they arrive
on_complete = printer.node_panel if stdout else None
def _on_run_complete(unique, node_output, node_status):
nonlocal header_printed
if stdout:
with self.print_lock:
if not header_printed:
printer.console.print(Rule(name.upper(), style=&#34;header&#34;))
header_printed = True
printer.node_panel(unique, node_output, node_status)
results = self.app.services.execution.run_commands(
nodes_filter=nodelist,
commands=commands,
@@ -209,16 +263,31 @@ el.replaceWith(d);
timeout=options.get(&#34;timeout&#34;, 10),
folder=folder,
prompt=prompt,
on_node_complete=on_complete
on_node_complete=_on_run_complete
)
# If not streaming, we could print a summary table here if needed
if not stdout:
for unique, output in results.items():
# Final Summary
if not stdout and not folder:
with self.print_lock:
printer.console.print(Rule(name.upper(), style=&#34;header&#34;))
for unique, data in results.items():
output = data[&#34;output&#34;] if isinstance(data, dict) else data
printer.node_panel(unique, output, 0)
# ALWAYS show the aggregate execution summary at the end
printer.run_summary(results)
elif action == &#34;test&#34;:
expected = script.get(&#34;expected&#34;, [])
on_complete = printer.test_panel if stdout else None
# Show test_panel per node ONLY if stdout is True
def _on_test_complete(unique, node_output, node_status, node_result):
nonlocal header_printed
if stdout:
with self.print_lock:
if not header_printed:
printer.console.print(Rule(name.upper(), style=&#34;header&#34;))
header_printed = True
printer.test_panel(unique, node_output, node_status, node_result)
results = self.app.services.execution.test_commands(
nodes_filter=nodelist,
commands=commands,
@@ -226,12 +295,13 @@ el.replaceWith(d);
variables=variables,
parallel=options.get(&#34;parallel&#34;, 10),
timeout=options.get(&#34;timeout&#34;, 10),
folder=folder,
prompt=prompt,
on_node_complete=on_complete
on_node_complete=_on_test_complete
)
if not stdout:
printer.test_summary(results)
# ALWAYS show the aggregate summary at the end
printer.test_summary(results)
except ConnpyError as e:
printer.error(str(e))</code></pre>
</details>
@@ -264,22 +334,43 @@ el.replaceWith(d);
<pre><code class="python">def node_run(self, args):
nodes_filter = args.data[0]
commands = [&#34; &#34;.join(args.data[1:])]
try:
header_printed = False
# Inline execution with streaming results
def _on_node_complete(unique, node_output, node_status):
nonlocal header_printed
if not header_printed:
printer.console.print(Rule(&#34;OUTPUT&#34;, style=&#34;header&#34;))
header_printed = True
printer.node_panel(unique, node_output, node_status)
self.app.services.execution.run_commands(
nodes_filter=nodes_filter,
commands=commands,
on_node_complete=_on_node_complete
)
if hasattr(args, &#39;test_expected&#39;) and args.test_expected:
# Mode: Test
def _on_node_complete(unique, node_output, node_status, node_result):
nonlocal header_printed
with self.print_lock:
if not header_printed:
printer.console.print(Rule(&#34;OUTPUT&#34;, style=&#34;header&#34;))
header_printed = True
printer.test_panel(unique, node_output, node_status, node_result)
results = self.app.services.execution.test_commands(
nodes_filter=nodes_filter,
commands=commands,
expected=args.test_expected,
on_node_complete=_on_node_complete
)
printer.test_summary(results)
else:
# Mode: Normal Run
def _on_node_complete(unique, node_output, node_status):
nonlocal header_printed
with self.print_lock:
if not header_printed:
printer.console.print(Rule(&#34;OUTPUT&#34;, style=&#34;header&#34;))
header_printed = True
printer.node_panel(unique, node_output, node_status)
results = self.app.services.execution.run_commands(
nodes_filter=nodes_filter,
commands=commands,
on_node_complete=_on_node_complete
)
printer.run_summary(results)
except ConnpyError as e:
printer.error(str(e))
@@ -320,10 +411,10 @@ el.replaceWith(d);
try:
with open(path, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
for task in playbook.get(&#34;tasks&#34;, []):
self.cli_run(task)
except Exception as e:
printer.error(f&#34;Failed to run playbook {path}: {e}&#34;)
sys.exit(10)</code></pre>
@@ -363,7 +454,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.sync_handler API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -427,7 +427,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.cli.validators API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -508,7 +508,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+734 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.connpy_pb2 API documentation</title>
<meta name="description" content="Generated protocol buffer code.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -45,6 +45,560 @@ el.replaceWith(d);
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.AIResponse"><code class="flex name class">
<span>class <span class="ident">AIResponse</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.AIResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.AskRequest"><code class="flex name class">
<span>class <span class="ident">AskRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.AskRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.BoolResponse"><code class="flex name class">
<span>class <span class="ident">BoolResponse</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.BoolResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.BulkRequest"><code class="flex name class">
<span>class <span class="ident">BulkRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.BulkRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.DeleteRequest"><code class="flex name class">
<span>class <span class="ident">DeleteRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.DeleteRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.ExportRequest"><code class="flex name class">
<span>class <span class="ident">ExportRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.ExportRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.FilterRequest"><code class="flex name class">
<span>class <span class="ident">FilterRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.FilterRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.FullReplaceRequest"><code class="flex name class">
<span>class <span class="ident">FullReplaceRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.FullReplaceRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.IdRequest"><code class="flex name class">
<span>class <span class="ident">IdRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.IdRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.IntRequest"><code class="flex name class">
<span>class <span class="ident">IntRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.IntRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.InteractRequest"><code class="flex name class">
<span>class <span class="ident">InteractRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.InteractRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.InteractResponse"><code class="flex name class">
<span>class <span class="ident">InteractResponse</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.InteractResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.ListRequest"><code class="flex name class">
<span>class <span class="ident">ListRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.ListRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.MessageValue"><code class="flex name class">
<span>class <span class="ident">MessageValue</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.MessageValue.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.MoveRequest"><code class="flex name class">
<span>class <span class="ident">MoveRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.MoveRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.NodeRequest"><code class="flex name class">
<span>class <span class="ident">NodeRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.NodeRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.NodeRunResult"><code class="flex name class">
<span>class <span class="ident">NodeRunResult</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.NodeRunResult.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.PluginRequest"><code class="flex name class">
<span>class <span class="ident">PluginRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.PluginRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.ProfileRequest"><code class="flex name class">
<span>class <span class="ident">ProfileRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.ProfileRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.ProviderRequest"><code class="flex name class">
<span>class <span class="ident">ProviderRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.ProviderRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.RunRequest"><code class="flex name class">
<span>class <span class="ident">RunRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.RunRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.ScriptRequest"><code class="flex name class">
<span>class <span class="ident">ScriptRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.ScriptRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.StringRequest"><code class="flex name class">
<span>class <span class="ident">StringRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.StringRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.StringResponse"><code class="flex name class">
<span>class <span class="ident">StringResponse</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.StringResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.StructRequest"><code class="flex name class">
<span>class <span class="ident">StructRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.StructRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.StructResponse"><code class="flex name class">
<span>class <span class="ident">StructResponse</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.StructResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.TestRequest"><code class="flex name class">
<span>class <span class="ident">TestRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.TestRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.UpdateRequest"><code class="flex name class">
<span>class <span class="ident">UpdateRequest</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.UpdateRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
<dt id="connpy.grpc_layer.connpy_pb2.ValueResponse"><code class="flex name class">
<span>class <span class="ident">ValueResponse</span></span>
<span>(</span><span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>A ProtocolMessage</p></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>google._upb._message.Message</li>
<li>google.protobuf.message.Message</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="connpy.grpc_layer.connpy_pb2.ValueResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
@@ -57,11 +611,189 @@ el.replaceWith(d);
<li><code><a title="connpy.grpc_layer" href="index.html">connpy.grpc_layer</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.AIResponse" href="#connpy.grpc_layer.connpy_pb2.AIResponse">AIResponse</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.AIResponse.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.AIResponse.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.AskRequest" href="#connpy.grpc_layer.connpy_pb2.AskRequest">AskRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.AskRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.AskRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.BoolResponse" href="#connpy.grpc_layer.connpy_pb2.BoolResponse">BoolResponse</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.BoolResponse.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.BoolResponse.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.BulkRequest" href="#connpy.grpc_layer.connpy_pb2.BulkRequest">BulkRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.BulkRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.BulkRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.DeleteRequest" href="#connpy.grpc_layer.connpy_pb2.DeleteRequest">DeleteRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.DeleteRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.DeleteRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.ExportRequest" href="#connpy.grpc_layer.connpy_pb2.ExportRequest">ExportRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.ExportRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.ExportRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.FilterRequest" href="#connpy.grpc_layer.connpy_pb2.FilterRequest">FilterRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.FilterRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.FilterRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.FullReplaceRequest" href="#connpy.grpc_layer.connpy_pb2.FullReplaceRequest">FullReplaceRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.FullReplaceRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.FullReplaceRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.IdRequest" href="#connpy.grpc_layer.connpy_pb2.IdRequest">IdRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.IdRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.IdRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.IntRequest" href="#connpy.grpc_layer.connpy_pb2.IntRequest">IntRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.IntRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.IntRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.InteractRequest" href="#connpy.grpc_layer.connpy_pb2.InteractRequest">InteractRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.InteractRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.InteractRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.InteractResponse" href="#connpy.grpc_layer.connpy_pb2.InteractResponse">InteractResponse</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.InteractResponse.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.InteractResponse.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.ListRequest" href="#connpy.grpc_layer.connpy_pb2.ListRequest">ListRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.ListRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.ListRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.MessageValue" href="#connpy.grpc_layer.connpy_pb2.MessageValue">MessageValue</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.MessageValue.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.MessageValue.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.MoveRequest" href="#connpy.grpc_layer.connpy_pb2.MoveRequest">MoveRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.MoveRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.MoveRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.NodeRequest" href="#connpy.grpc_layer.connpy_pb2.NodeRequest">NodeRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.NodeRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.NodeRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.NodeRunResult" href="#connpy.grpc_layer.connpy_pb2.NodeRunResult">NodeRunResult</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.NodeRunResult.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.NodeRunResult.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.PluginRequest" href="#connpy.grpc_layer.connpy_pb2.PluginRequest">PluginRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.PluginRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.PluginRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.ProfileRequest" href="#connpy.grpc_layer.connpy_pb2.ProfileRequest">ProfileRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.ProfileRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.ProfileRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.ProviderRequest" href="#connpy.grpc_layer.connpy_pb2.ProviderRequest">ProviderRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.ProviderRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.ProviderRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.RunRequest" href="#connpy.grpc_layer.connpy_pb2.RunRequest">RunRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.RunRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.RunRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.ScriptRequest" href="#connpy.grpc_layer.connpy_pb2.ScriptRequest">ScriptRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.ScriptRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.ScriptRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.StringRequest" href="#connpy.grpc_layer.connpy_pb2.StringRequest">StringRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.StringRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.StringRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.StringResponse" href="#connpy.grpc_layer.connpy_pb2.StringResponse">StringResponse</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.StringResponse.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.StringResponse.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.StructRequest" href="#connpy.grpc_layer.connpy_pb2.StructRequest">StructRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.StructRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.StructRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.StructResponse" href="#connpy.grpc_layer.connpy_pb2.StructResponse">StructResponse</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.StructResponse.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.StructResponse.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.TestRequest" href="#connpy.grpc_layer.connpy_pb2.TestRequest">TestRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.TestRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.TestRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.UpdateRequest" href="#connpy.grpc_layer.connpy_pb2.UpdateRequest">UpdateRequest</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.UpdateRequest.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.UpdateRequest.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="connpy.grpc_layer.connpy_pb2.ValueResponse" href="#connpy.grpc_layer.connpy_pb2.ValueResponse">ValueResponse</a></code></h4>
<ul class="">
<li><code><a title="connpy.grpc_layer.connpy_pb2.ValueResponse.DESCRIPTOR" href="#connpy.grpc_layer.connpy_pb2.ValueResponse.DESCRIPTOR">DESCRIPTOR</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.connpy_pb2_grpc API documentation</title>
<meta name="description" content="Client and server classes corresponding to protobuf-defined services.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -5735,7 +5735,7 @@ def stop_api(request,
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -102,7 +102,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.remote_plugin_pb2 API documentation</title>
<meta name="description" content="Generated protocol buffer code.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -62,7 +62,7 @@ el.replaceWith(d);
<dl>
<dt id="connpy.grpc_layer.remote_plugin_pb2.IdRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"></div>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
@@ -81,7 +81,7 @@ el.replaceWith(d);
<dl>
<dt id="connpy.grpc_layer.remote_plugin_pb2.OutputChunk.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"></div>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
@@ -100,7 +100,7 @@ el.replaceWith(d);
<dl>
<dt id="connpy.grpc_layer.remote_plugin_pb2.PluginInvokeRequest.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"></div>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
@@ -119,7 +119,7 @@ el.replaceWith(d);
<dl>
<dt id="connpy.grpc_layer.remote_plugin_pb2.StringResponse.DESCRIPTOR"><code class="name">var <span class="ident">DESCRIPTOR</span></code></dt>
<dd>
<div class="desc"></div>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
</dd>
@@ -168,7 +168,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.remote_plugin_pb2_grpc API documentation</title>
<meta name="description" content="Client and server classes corresponding to protobuf-defined services.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -366,7 +366,7 @@ def invoke_plugin(request,
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+19 -7
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.server API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -367,14 +367,20 @@ el.replaceWith(d);
def _worker():
try:
# Set task name in thread state for printer if available
if request.name:
printer.console.print(f&#34;[debug][DEBUG][/debug] Executing task: [bold cyan]{request.name}[/bold cyan]&#34;)
self.service.run_commands(
nodes_filter=nodes_filter,
commands=list(request.commands),
folder=request.folder if request.folder else None,
prompt=request.prompt if request.prompt else None,
parallel=request.parallel,
timeout=request.timeout if request.timeout &gt; 0 else 10,
variables=from_struct(request.vars) if request.HasField(&#34;vars&#34;) else None,
on_node_complete=_on_complete
on_node_complete=_on_complete,
name=request.name if request.name else None
)
except Exception as e:
# Optionally pass error to stream, but handle_errors decorator covers top-level.
@@ -407,20 +413,26 @@ el.replaceWith(d);
q = queue.Queue()
def _on_complete(unique, output, status, result):
q.put({&#34;unique_id&#34;: unique, &#34;output&#34;: output, &#34;status&#34;: status, &#34;result&#34;: result})
def _on_complete(unique, node_output, node_status, node_result):
q.put({&#34;unique_id&#34;: unique, &#34;output&#34;: node_output, &#34;status&#34;: node_status, &#34;result&#34;: node_result})
def _worker():
try:
# Set task name in thread state for printer if available
if request.name:
printer.console.print(f&#34;[debug][DEBUG][/debug] Executing task: [bold cyan]{request.name}[/bold cyan]&#34;)
self.service.test_commands(
nodes_filter=nodes_filter,
commands=list(request.commands),
expected=request.expected,
expected=list(request.expected),
folder=request.folder if request.folder else None,
prompt=request.prompt if request.prompt else None,
parallel=request.parallel,
timeout=request.timeout if request.timeout &gt; 0 else 10,
variables=from_struct(request.vars) if request.HasField(&#34;vars&#34;) else None,
on_node_complete=_on_complete
on_node_complete=_on_complete,
name=request.name if request.name else None
)
except Exception as e:
q.put(e)
@@ -1313,7 +1325,7 @@ interceptor chooses to service this RPC, or None otherwise.</p></div>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+20 -10
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.stubs API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -642,9 +642,9 @@ def update_setting(self, key, value):
folder=folder or &#34;&#34;,
prompt=prompt or &#34;&#34;,
parallel=parallel,
timeout=timeout,
name=kwargs.get(&#34;name&#34;, &#34;&#34;)
)
# Note: &#39;timeout&#39;, &#39;on_node_complete&#39;, and &#39;logger&#39; are currently not
# sent over gRPC in the current proto definition.
if variables is not None:
req.vars.CopyFrom(to_struct(variables))
@@ -654,7 +654,10 @@ def update_setting(self, key, value):
for response in self.stub.run_commands(req):
if on_complete:
on_complete(response.unique_id, response.output, response.status)
final_results[response.unique_id] = response.output
final_results[response.unique_id] = {
&#34;output&#34;: response.output,
&#34;status&#34;: response.status
}
return final_results
@@ -664,10 +667,12 @@ def update_setting(self, key, value):
req = connpy_pb2.TestRequest(
nodes=nodes_list,
commands=commands,
expected=expected,
expected=expected if isinstance(expected, list) else [expected],
folder=kwargs.get(&#34;folder&#34;, &#34;&#34;),
prompt=prompt or &#34;&#34;,
parallel=parallel,
timeout=timeout,
name=kwargs.get(&#34;name&#34;, &#34;&#34;)
)
if variables is not None:
req.vars.CopyFrom(to_struct(variables))
@@ -728,9 +733,9 @@ def run_commands(self, nodes_filter, commands, variables=None, parallel=10, time
folder=folder or &#34;&#34;,
prompt=prompt or &#34;&#34;,
parallel=parallel,
timeout=timeout,
name=kwargs.get(&#34;name&#34;, &#34;&#34;)
)
# Note: &#39;timeout&#39;, &#39;on_node_complete&#39;, and &#39;logger&#39; are currently not
# sent over gRPC in the current proto definition.
if variables is not None:
req.vars.CopyFrom(to_struct(variables))
@@ -740,7 +745,10 @@ def run_commands(self, nodes_filter, commands, variables=None, parallel=10, time
for response in self.stub.run_commands(req):
if on_complete:
on_complete(response.unique_id, response.output, response.status)
final_results[response.unique_id] = response.output
final_results[response.unique_id] = {
&#34;output&#34;: response.output,
&#34;status&#34;: response.status
}
return final_results</code></pre>
</details>
@@ -775,10 +783,12 @@ def test_commands(self, nodes_filter, commands, expected, variables=None, parall
req = connpy_pb2.TestRequest(
nodes=nodes_list,
commands=commands,
expected=expected,
expected=expected if isinstance(expected, list) else [expected],
folder=kwargs.get(&#34;folder&#34;, &#34;&#34;),
prompt=prompt or &#34;&#34;,
parallel=parallel,
timeout=timeout,
name=kwargs.get(&#34;name&#34;, &#34;&#34;)
)
if variables is not None:
req.vars.CopyFrom(to_struct(variables))
@@ -2102,7 +2112,7 @@ def stop_api(self):
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.grpc_layer.utils API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -138,7 +138,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+122 -48
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy API documentation</title>
<meta name="description" content="Connection manager …">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -2077,7 +2077,7 @@ class ai:
<dl>
<dt id="connpy.ai.SAFE_COMMANDS"><code class="name">var <span class="ident">SAFE_COMMANDS</span></code></dt>
<dd>
<div class="desc"></div>
<div class="desc"><p>The type of the None singleton.</p></div>
</dd>
</dl>
<h3>Instance variables</h3>
@@ -3170,15 +3170,7 @@ class configfile:
if isinstance(uniques, str):
uniques = [uniques]
for i in uniques:
if isinstance(i, dict):
name = list(i.keys())[0]
mylist = i[name]
if not self.config[&#34;case&#34;]:
name = name.lower()
mylist = [item.lower() for item in mylist]
this = self.getitem(name, mylist, extract = extract)
nodes.update(this)
elif i.startswith(&#34;@&#34;):
if i.startswith(&#34;@&#34;):
if not self.config[&#34;case&#34;]:
i = i.lower()
this = self.getitem(i, extract = extract)
@@ -3257,13 +3249,17 @@ class configfile:
layer3 = [k + &#34;@&#34; + s + &#34;@&#34; + f for k,v in self.connections[f][s].items() if isinstance(v, dict) and v.get(&#34;type&#34;) == &#34;connection&#34;]
nodes.extend(layer3)
if filter:
flat_filter = []
if isinstance(filter, str):
nodes = [item for item in nodes if re.search(filter, item)]
flat_filter = [filter]
elif isinstance(filter, list):
nodes = [item for item in nodes if any(re.search(pattern, item) for pattern in filter)]
for item in filter:
if isinstance(item, str):
flat_filter.append(item)
else:
printer.error(&#34;Invalid filter: must be a string or a list of strings.&#34;)
printer.error(&#34;Filter must be a string or a list of strings&#34;)
sys.exit(1)
nodes = [item for item in nodes if any(re.search(pattern, item) for pattern in flat_filter)]
return nodes
@MethodHook
@@ -3281,15 +3277,18 @@ class configfile:
layer3 = {k + &#34;@&#34; + s + &#34;@&#34; + f:v for k,v in self.connections[f][s].items() if isinstance(v, dict) and v.get(&#34;type&#34;) == &#34;connection&#34;}
nodes.update(layer3)
if filter:
flat_filter = []
if isinstance(filter, str):
filter = &#34;^(?!.*@).+$&#34; if filter == &#34;@&#34; else filter
nodes = {k: v for k, v in nodes.items() if re.search(filter, k)}
flat_filter = [filter]
elif isinstance(filter, list):
filter = [&#34;^(?!.*@).+$&#34; if item == &#34;@&#34; else item for item in filter]
nodes = {k: v for k, v in nodes.items() if any(re.search(pattern, k) for pattern in filter)}
for item in filter:
if isinstance(item, str):
flat_filter.append(item)
else:
printer.error(&#34;Invalid filter: must be a string or a list of strings.&#34;)
printer.error(&#34;Filter must be a string or a list of strings&#34;)
sys.exit(1)
flat_filter = [&#34;^(?!.*@).+$&#34; if item == &#34;@&#34; else item for item in flat_filter]
nodes = {k: v for k, v in nodes.items() if any(re.search(pattern, k) for pattern in flat_filter)}
if extract:
for node, keys in nodes.items():
for key, value in keys.items():
@@ -3586,15 +3585,7 @@ def getitems(self, uniques, extract = False):
if isinstance(uniques, str):
uniques = [uniques]
for i in uniques:
if isinstance(i, dict):
name = list(i.keys())[0]
mylist = i[name]
if not self.config[&#34;case&#34;]:
name = name.lower()
mylist = [item.lower() for item in mylist]
this = self.getitem(name, mylist, extract = extract)
nodes.update(this)
elif i.startswith(&#34;@&#34;):
if i.startswith(&#34;@&#34;):
if not self.config[&#34;case&#34;]:
i = i.lower()
this = self.getitem(i, extract = extract)
@@ -3759,6 +3750,10 @@ class node:
self.jumphost = f&#34;-o ProxyCommand=\&#34;{jumphost_cmd}\&#34;&#34;
else:
self.jumphost = &#34;&#34;
self.output = &#34;&#34;
self.status = 1
self.result = {}
@MethodHook
def _passtx(self, passwords, *, keyfile=None):
@@ -4159,7 +4154,12 @@ class node:
self.child.logfile_read = self.mylog
for c in commands:
if vars is not None:
c = c.format(**vars)
try:
c = c.format(**vars)
except KeyError as e:
self.output = f&#34;Error: Variable {e} not defined in task or inventory&#34;
self.status = 1
return self.output
result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c)
if result == 2:
@@ -4193,7 +4193,7 @@ class node:
return connect
@MethodHook
def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&gt;.$|#.$|\$.$&#39;, timeout = 10, logger = None):
def test(self, commands, expected, vars = None,*, folder = &#39;&#39;, prompt = r&#39;&gt;$|#$|\$$|&gt;.$|#.$|\$.$&#39;, timeout = 10, logger = None):
&#39;&#39;&#39;
Run a command or list of commands on the node, then check if expected value appears on the output after the last command.
@@ -4219,6 +4219,9 @@ class node:
### Optional Named Parameters:
- folder (str): Path where output log should be stored, leave
empty to not store logs.
- prompt (str): Prompt to be expected after a command is finished
running. Usually linux uses &#34;&gt;&#34; or EOF while
routers use &#34;&gt;&#34; or &#34;#&#34;. The default value should
@@ -4233,6 +4236,7 @@ class node:
false if prompt is found before.
&#39;&#39;&#39;
now = datetime.datetime.now().strftime(&#34;%Y-%m-%d_%H-%M-%S&#34;)
connect = self._connect(timeout = timeout, logger = logger)
if connect == True:
if logger:
@@ -4250,6 +4254,7 @@ class node:
if &#34;prompt&#34; in self.tags:
prompt = self.tags[&#34;prompt&#34;]
expects = [prompt, pexpect.EOF, pexpect.TIMEOUT]
output = &#39;&#39;
if not isinstance(commands, list):
commands = [commands]
@@ -4261,7 +4266,12 @@ class node:
self.child.logfile_read = self.mylog
for c in commands:
if vars is not None:
c = c.format(**vars)
try:
c = c.format(**vars)
except KeyError as e:
self.output = f&#34;Error: Variable {e} not defined in task or inventory&#34;
self.status = 1
return self.output
result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c)
if result == 2:
@@ -4270,6 +4280,12 @@ class node:
result = self.child.expect(expects, timeout = timeout)
self.child.close()
output = self._logclean(self.mylog.getvalue().decode(), True)
if logger:
logger(&#34;output&#34;, output)
if folder != &#39;&#39;:
with open(folder + &#34;/&#34; + self.unique + &#34;_&#34; + now + &#34;.txt&#34;, &#34;w&#34;) as f:
f.write(output)
f.close()
self.output = output
if result in [0, 1]:
# lastcommand = commands[-1]
@@ -4654,7 +4670,12 @@ def run(self, commands, vars = None,*, folder = &#39;&#39;, prompt = r&#39;&gt;$
self.child.logfile_read = self.mylog
for c in commands:
if vars is not None:
c = c.format(**vars)
try:
c = c.format(**vars)
except KeyError as e:
self.output = f&#34;Error: Variable {e} not defined in task or inventory&#34;
self.status = 1
return self.output
result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c)
if result == 2:
@@ -4721,7 +4742,7 @@ def run(self, commands, vars = None,*, folder = &#39;&#39;, prompt = r&#39;&gt;$
</code></pre></div>
</dd>
<dt id="connpy.node.test"><code class="name flex">
<span>def <span class="ident">test</span></span>(<span>self,<br>commands,<br>expected,<br>vars=None,<br>*,<br>prompt=&#x27;&gt;$|#$|\\$$|&gt;.$|#.$|\\$.$&#x27;,<br>timeout=10,<br>logger=None)</span>
<span>def <span class="ident">test</span></span>(<span>self,<br>commands,<br>expected,<br>vars=None,<br>*,<br>folder='',<br>prompt=&#x27;&gt;$|#$|\\$$|&gt;.$|#.$|\\$.$&#x27;,<br>timeout=10,<br>logger=None)</span>
</code></dt>
<dd>
<details class="source">
@@ -4729,7 +4750,7 @@ def run(self, commands, vars = None,*, folder = &#39;&#39;, prompt = r&#39;&gt;$
<span>Expand source code</span>
</summary>
<pre><code class="python">@MethodHook
def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&gt;.$|#.$|\$.$&#39;, timeout = 10, logger = None):
def test(self, commands, expected, vars = None,*, folder = &#39;&#39;, prompt = r&#39;&gt;$|#$|\$$|&gt;.$|#.$|\$.$&#39;, timeout = 10, logger = None):
&#39;&#39;&#39;
Run a command or list of commands on the node, then check if expected value appears on the output after the last command.
@@ -4755,6 +4776,9 @@ def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&g
### Optional Named Parameters:
- folder (str): Path where output log should be stored, leave
empty to not store logs.
- prompt (str): Prompt to be expected after a command is finished
running. Usually linux uses &#34;&gt;&#34; or EOF while
routers use &#34;&gt;&#34; or &#34;#&#34;. The default value should
@@ -4769,6 +4793,7 @@ def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&g
false if prompt is found before.
&#39;&#39;&#39;
now = datetime.datetime.now().strftime(&#34;%Y-%m-%d_%H-%M-%S&#34;)
connect = self._connect(timeout = timeout, logger = logger)
if connect == True:
if logger:
@@ -4786,6 +4811,7 @@ def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&g
if &#34;prompt&#34; in self.tags:
prompt = self.tags[&#34;prompt&#34;]
expects = [prompt, pexpect.EOF, pexpect.TIMEOUT]
output = &#39;&#39;
if not isinstance(commands, list):
commands = [commands]
@@ -4797,7 +4823,12 @@ def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&g
self.child.logfile_read = self.mylog
for c in commands:
if vars is not None:
c = c.format(**vars)
try:
c = c.format(**vars)
except KeyError as e:
self.output = f&#34;Error: Variable {e} not defined in task or inventory&#34;
self.status = 1
return self.output
result = self.child.expect(expects, timeout = timeout)
self.child.sendline(c)
if result == 2:
@@ -4806,6 +4837,12 @@ def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&g
result = self.child.expect(expects, timeout = timeout)
self.child.close()
output = self._logclean(self.mylog.getvalue().decode(), True)
if logger:
logger(&#34;output&#34;, output)
if folder != &#39;&#39;:
with open(folder + &#34;/&#34; + self.unique + &#34;_&#34; + now + &#34;.txt&#34;, &#34;w&#34;) as f:
f.write(output)
f.close()
self.output = output
if result in [0, 1]:
# lastcommand = commands[-1]
@@ -4856,7 +4893,10 @@ def test(self, commands, expected, vars = None,*, prompt = r&#39;&gt;$|#$|\$$|&g
Values: strings.
</code></pre>
<h3 id="optional-named-parameters">Optional Named Parameters:</h3>
<pre><code>- prompt (str): Prompt to be expected after a command is finished
<pre><code>- folder (str): Path where output log should be stored, leave
empty to not store logs.
- prompt (str): Prompt to be expected after a command is finished
running. Usually linux uses "&gt;" or EOF while
routers use "&gt;" or "#". The default value should
work for most nodes. Change it if your connection
@@ -5022,8 +5062,15 @@ class nodes:
nodesargs[n.unique][&#34;vars&#34;] = {}
if &#34;__global__&#34; in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[&#34;__global__&#34;])
if n.unique in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[n.unique])
for var_key, var_val in vars.items():
if var_key == &#34;__global__&#34;:
continue
try:
if re.search(var_key, n.unique, re.IGNORECASE):
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
except re.error:
if var_key == n.unique:
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
# Pass the logger to the node
nodesargs[n.unique][&#34;logger&#34;] = logger
@@ -5048,7 +5095,7 @@ class nodes:
return output
@MethodHook
def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10, timeout = None, on_complete = None, logger = None):
def test(self, commands, expected, vars = None,*, folder = None, prompt = None, parallel = 10, timeout = None, on_complete = None, logger = None):
&#39;&#39;&#39;
Run a command or list of commands on all the nodes in nodelist, then check if expected value appears on the output after the last command.
@@ -5103,6 +5150,9 @@ class nodes:
nodesargs = {}
args[&#34;commands&#34;] = commands
args[&#34;expected&#34;] = expected
if folder != None:
args[&#34;folder&#34;] = folder
Path(folder).mkdir(parents=True, exist_ok=True)
if prompt != None:
args[&#34;prompt&#34;] = prompt
if timeout != None:
@@ -5124,8 +5174,15 @@ class nodes:
nodesargs[n.unique][&#34;vars&#34;] = {}
if &#34;__global__&#34; in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[&#34;__global__&#34;])
if n.unique in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[n.unique])
for var_key, var_val in vars.items():
if var_key == &#34;__global__&#34;:
continue
try:
if re.search(var_key, n.unique, re.IGNORECASE):
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
except re.error:
if var_key == n.unique:
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
nodesargs[n.unique][&#34;logger&#34;] = logger
if on_complete:
@@ -5275,8 +5332,15 @@ def run(self, commands, vars = None,*, folder = None, prompt = None, stdout = No
nodesargs[n.unique][&#34;vars&#34;] = {}
if &#34;__global__&#34; in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[&#34;__global__&#34;])
if n.unique in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[n.unique])
for var_key, var_val in vars.items():
if var_key == &#34;__global__&#34;:
continue
try:
if re.search(var_key, n.unique, re.IGNORECASE):
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
except re.error:
if var_key == n.unique:
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
# Pass the logger to the node
nodesargs[n.unique][&#34;logger&#34;] = logger
@@ -5346,7 +5410,7 @@ def run(self, commands, vars = None,*, folder = None, prompt = None, stdout = No
</code></pre></div>
</dd>
<dt id="connpy.nodes.test"><code class="name flex">
<span>def <span class="ident">test</span></span>(<span>self,<br>commands,<br>expected,<br>vars=None,<br>*,<br>prompt=None,<br>parallel=10,<br>timeout=None,<br>on_complete=None,<br>logger=None)</span>
<span>def <span class="ident">test</span></span>(<span>self,<br>commands,<br>expected,<br>vars=None,<br>*,<br>folder=None,<br>prompt=None,<br>parallel=10,<br>timeout=None,<br>on_complete=None,<br>logger=None)</span>
</code></dt>
<dd>
<details class="source">
@@ -5354,7 +5418,7 @@ def run(self, commands, vars = None,*, folder = None, prompt = None, stdout = No
<span>Expand source code</span>
</summary>
<pre><code class="python">@MethodHook
def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10, timeout = None, on_complete = None, logger = None):
def test(self, commands, expected, vars = None,*, folder = None, prompt = None, parallel = 10, timeout = None, on_complete = None, logger = None):
&#39;&#39;&#39;
Run a command or list of commands on all the nodes in nodelist, then check if expected value appears on the output after the last command.
@@ -5409,6 +5473,9 @@ def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10,
nodesargs = {}
args[&#34;commands&#34;] = commands
args[&#34;expected&#34;] = expected
if folder != None:
args[&#34;folder&#34;] = folder
Path(folder).mkdir(parents=True, exist_ok=True)
if prompt != None:
args[&#34;prompt&#34;] = prompt
if timeout != None:
@@ -5430,8 +5497,15 @@ def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10,
nodesargs[n.unique][&#34;vars&#34;] = {}
if &#34;__global__&#34; in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[&#34;__global__&#34;])
if n.unique in vars.keys():
nodesargs[n.unique][&#34;vars&#34;].update(vars[n.unique])
for var_key, var_val in vars.items():
if var_key == &#34;__global__&#34;:
continue
try:
if re.search(var_key, n.unique, re.IGNORECASE):
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
except re.error:
if var_key == n.unique:
nodesargs[n.unique][&#34;vars&#34;].update(var_val)
nodesargs[n.unique][&#34;logger&#34;] = logger
if on_complete:
@@ -5626,7 +5700,7 @@ def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10,
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.proto API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -60,7 +60,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.ai_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -265,7 +265,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.base API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -152,7 +152,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.config_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -311,7 +311,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.context_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -370,7 +370,7 @@ def current_context(self) -&gt; str:
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.exceptions API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -268,7 +268,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+112 -58
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.execution_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -68,7 +68,8 @@ el.replaceWith(d);
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, str]:
&#34;&#34;&#34;Execute commands on a set of nodes.&#34;&#34;&#34;
@@ -92,7 +93,15 @@ el.replaceWith(d);
logger=logger
)
return results
# Combine output and status for the caller
full_results = {}
for unique in results:
full_results[unique] = {
&#34;output&#34;: results[unique],
&#34;status&#34;: executor.status.get(unique, 1)
}
return full_results
except Exception as e:
raise ConnpyError(f&#34;Execution failed: {e}&#34;)
@@ -104,9 +113,11 @@ el.replaceWith(d);
variables: Optional[Dict[str, Any]] = None,
parallel: int = 10,
timeout: int = 10,
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, Dict[str, bool]]:
&#34;&#34;&#34;Run commands and verify expected output on a set of nodes.&#34;&#34;&#34;
@@ -125,6 +136,7 @@ el.replaceWith(d);
vars=variables,
parallel=parallel,
timeout=timeout,
folder=folder,
prompt=prompt,
on_complete=on_node_complete,
logger=logger
@@ -146,37 +158,52 @@ el.replaceWith(d);
return self.run_commands(nodes_filter, commands, parallel=parallel)
def run_yaml_playbook(self, playbook_path: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook.&#34;&#34;&#34;
if not os.path.exists(playbook_path):
raise ConnpyError(f&#34;Playbook file not found: {playbook_path}&#34;)
try:
with open(playbook_path, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_path}: {e}&#34;)
def run_yaml_playbook(self, playbook_data: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook (from path or content).&#34;&#34;&#34;
playbook = None
if playbook_data.startswith(&#34;---YAML---\n&#34;):
try:
content = playbook_data[len(&#34;---YAML---\n&#34;):]
playbook = yaml.load(content, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to parse YAML content: {e}&#34;)
else:
if not os.path.exists(playbook_data):
raise ConnpyError(f&#34;Playbook file not found: {playbook_data}&#34;)
try:
with open(playbook_data, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_data}: {e}&#34;)
# Basic validation
if not isinstance(playbook, dict) or &#34;nodes&#34; not in playbook or &#34;commands&#34; not in playbook:
raise ConnpyError(&#34;Invalid playbook format: missing &#39;nodes&#39; or &#39;commands&#39; keys.&#34;)
action = playbook.get(&#34;action&#34;, &#34;run&#34;)
options = playbook.get(&#34;options&#34;, {})
# Extract all fields similar to RunHandler.cli_run
exec_args = {
&#34;nodes_filter&#34;: playbook[&#34;nodes&#34;],
&#34;commands&#34;: playbook[&#34;commands&#34;],
&#34;variables&#34;: playbook.get(&#34;variables&#34;),
&#34;parallel&#34;: options.get(&#34;parallel&#34;, parallel),
&#34;timeout&#34;: playbook.get(&#34;timeout&#34;, options.get(&#34;timeout&#34;, 10)),
&#34;prompt&#34;: options.get(&#34;prompt&#34;),
&#34;name&#34;: playbook.get(&#34;name&#34;, &#34;Task&#34;)
}
# Map &#39;output&#39; field to folder path if it&#39;s not stdout/null
output_cfg = playbook.get(&#34;output&#34;)
if output_cfg not in [None, &#34;stdout&#34;]:
exec_args[&#34;folder&#34;] = output_cfg
if action == &#34;run&#34;:
return self.run_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
return self.run_commands(**exec_args)
elif action == &#34;test&#34;:
return self.test_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
expected=playbook.get(&#34;expected&#34;, []),
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
exec_args[&#34;expected&#34;] = playbook.get(&#34;expected&#34;, [])
return self.test_commands(**exec_args)
else:
raise ConnpyError(f&#34;Unsupported playbook action: {action}&#34;)</code></pre>
</details>
@@ -217,7 +244,7 @@ el.replaceWith(d);
<div class="desc"><p>Run a plain-text script containing one command per line.</p></div>
</dd>
<dt id="connpy.services.execution_service.ExecutionService.run_commands"><code class="name flex">
<span>def <span class="ident">run_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>folder: str | None = None,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None) > Dict[str, str]</span>
<span>def <span class="ident">run_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>folder: str | None = None,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None,<br>name: str | None = None) > Dict[str, str]</span>
</code></dt>
<dd>
<details class="source">
@@ -234,7 +261,8 @@ el.replaceWith(d);
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, str]:
&#34;&#34;&#34;Execute commands on a set of nodes.&#34;&#34;&#34;
@@ -258,58 +286,81 @@ el.replaceWith(d);
logger=logger
)
return results
# Combine output and status for the caller
full_results = {}
for unique in results:
full_results[unique] = {
&#34;output&#34;: results[unique],
&#34;status&#34;: executor.status.get(unique, 1)
}
return full_results
except Exception as e:
raise ConnpyError(f&#34;Execution failed: {e}&#34;)</code></pre>
</details>
<div class="desc"><p>Execute commands on a set of nodes.</p></div>
</dd>
<dt id="connpy.services.execution_service.ExecutionService.run_yaml_playbook"><code class="name flex">
<span>def <span class="ident">run_yaml_playbook</span></span>(<span>self, playbook_path: str, parallel: int = 10) > Dict[str, Any]</span>
<span>def <span class="ident">run_yaml_playbook</span></span>(<span>self, playbook_data: str, parallel: int = 10) > Dict[str, Any]</span>
</code></dt>
<dd>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def run_yaml_playbook(self, playbook_path: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook.&#34;&#34;&#34;
if not os.path.exists(playbook_path):
raise ConnpyError(f&#34;Playbook file not found: {playbook_path}&#34;)
try:
with open(playbook_path, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_path}: {e}&#34;)
<pre><code class="python">def run_yaml_playbook(self, playbook_data: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook (from path or content).&#34;&#34;&#34;
playbook = None
if playbook_data.startswith(&#34;---YAML---\n&#34;):
try:
content = playbook_data[len(&#34;---YAML---\n&#34;):]
playbook = yaml.load(content, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to parse YAML content: {e}&#34;)
else:
if not os.path.exists(playbook_data):
raise ConnpyError(f&#34;Playbook file not found: {playbook_data}&#34;)
try:
with open(playbook_data, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_data}: {e}&#34;)
# Basic validation
if not isinstance(playbook, dict) or &#34;nodes&#34; not in playbook or &#34;commands&#34; not in playbook:
raise ConnpyError(&#34;Invalid playbook format: missing &#39;nodes&#39; or &#39;commands&#39; keys.&#34;)
action = playbook.get(&#34;action&#34;, &#34;run&#34;)
options = playbook.get(&#34;options&#34;, {})
# Extract all fields similar to RunHandler.cli_run
exec_args = {
&#34;nodes_filter&#34;: playbook[&#34;nodes&#34;],
&#34;commands&#34;: playbook[&#34;commands&#34;],
&#34;variables&#34;: playbook.get(&#34;variables&#34;),
&#34;parallel&#34;: options.get(&#34;parallel&#34;, parallel),
&#34;timeout&#34;: playbook.get(&#34;timeout&#34;, options.get(&#34;timeout&#34;, 10)),
&#34;prompt&#34;: options.get(&#34;prompt&#34;),
&#34;name&#34;: playbook.get(&#34;name&#34;, &#34;Task&#34;)
}
# Map &#39;output&#39; field to folder path if it&#39;s not stdout/null
output_cfg = playbook.get(&#34;output&#34;)
if output_cfg not in [None, &#34;stdout&#34;]:
exec_args[&#34;folder&#34;] = output_cfg
if action == &#34;run&#34;:
return self.run_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
return self.run_commands(**exec_args)
elif action == &#34;test&#34;:
return self.test_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
expected=playbook.get(&#34;expected&#34;, []),
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
exec_args[&#34;expected&#34;] = playbook.get(&#34;expected&#34;, [])
return self.test_commands(**exec_args)
else:
raise ConnpyError(f&#34;Unsupported playbook action: {action}&#34;)</code></pre>
</details>
<div class="desc"><p>Run a structured Connpy YAML automation playbook.</p></div>
<div class="desc"><p>Run a structured Connpy YAML automation playbook (from path or content).</p></div>
</dd>
<dt id="connpy.services.execution_service.ExecutionService.test_commands"><code class="name flex">
<span>def <span class="ident">test_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>expected: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None) > Dict[str, Dict[str, bool]]</span>
<span>def <span class="ident">test_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>expected: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>folder: str | None = None,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None,<br>name: str | None = None) > Dict[str, Dict[str, bool]]</span>
</code></dt>
<dd>
<details class="source">
@@ -324,9 +375,11 @@ el.replaceWith(d);
variables: Optional[Dict[str, Any]] = None,
parallel: int = 10,
timeout: int = 10,
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, Dict[str, bool]]:
&#34;&#34;&#34;Run commands and verify expected output on a set of nodes.&#34;&#34;&#34;
@@ -345,6 +398,7 @@ el.replaceWith(d);
vars=variables,
parallel=parallel,
timeout=timeout,
folder=folder,
prompt=prompt,
on_complete=on_node_complete,
logger=logger
@@ -395,7 +449,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.import_export_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -279,7 +279,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+112 -58
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -594,7 +594,8 @@ el.replaceWith(d);
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, str]:
&#34;&#34;&#34;Execute commands on a set of nodes.&#34;&#34;&#34;
@@ -618,7 +619,15 @@ el.replaceWith(d);
logger=logger
)
return results
# Combine output and status for the caller
full_results = {}
for unique in results:
full_results[unique] = {
&#34;output&#34;: results[unique],
&#34;status&#34;: executor.status.get(unique, 1)
}
return full_results
except Exception as e:
raise ConnpyError(f&#34;Execution failed: {e}&#34;)
@@ -630,9 +639,11 @@ el.replaceWith(d);
variables: Optional[Dict[str, Any]] = None,
parallel: int = 10,
timeout: int = 10,
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, Dict[str, bool]]:
&#34;&#34;&#34;Run commands and verify expected output on a set of nodes.&#34;&#34;&#34;
@@ -651,6 +662,7 @@ el.replaceWith(d);
vars=variables,
parallel=parallel,
timeout=timeout,
folder=folder,
prompt=prompt,
on_complete=on_node_complete,
logger=logger
@@ -672,37 +684,52 @@ el.replaceWith(d);
return self.run_commands(nodes_filter, commands, parallel=parallel)
def run_yaml_playbook(self, playbook_path: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook.&#34;&#34;&#34;
if not os.path.exists(playbook_path):
raise ConnpyError(f&#34;Playbook file not found: {playbook_path}&#34;)
try:
with open(playbook_path, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_path}: {e}&#34;)
def run_yaml_playbook(self, playbook_data: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook (from path or content).&#34;&#34;&#34;
playbook = None
if playbook_data.startswith(&#34;---YAML---\n&#34;):
try:
content = playbook_data[len(&#34;---YAML---\n&#34;):]
playbook = yaml.load(content, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to parse YAML content: {e}&#34;)
else:
if not os.path.exists(playbook_data):
raise ConnpyError(f&#34;Playbook file not found: {playbook_data}&#34;)
try:
with open(playbook_data, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_data}: {e}&#34;)
# Basic validation
if not isinstance(playbook, dict) or &#34;nodes&#34; not in playbook or &#34;commands&#34; not in playbook:
raise ConnpyError(&#34;Invalid playbook format: missing &#39;nodes&#39; or &#39;commands&#39; keys.&#34;)
action = playbook.get(&#34;action&#34;, &#34;run&#34;)
options = playbook.get(&#34;options&#34;, {})
# Extract all fields similar to RunHandler.cli_run
exec_args = {
&#34;nodes_filter&#34;: playbook[&#34;nodes&#34;],
&#34;commands&#34;: playbook[&#34;commands&#34;],
&#34;variables&#34;: playbook.get(&#34;variables&#34;),
&#34;parallel&#34;: options.get(&#34;parallel&#34;, parallel),
&#34;timeout&#34;: playbook.get(&#34;timeout&#34;, options.get(&#34;timeout&#34;, 10)),
&#34;prompt&#34;: options.get(&#34;prompt&#34;),
&#34;name&#34;: playbook.get(&#34;name&#34;, &#34;Task&#34;)
}
# Map &#39;output&#39; field to folder path if it&#39;s not stdout/null
output_cfg = playbook.get(&#34;output&#34;)
if output_cfg not in [None, &#34;stdout&#34;]:
exec_args[&#34;folder&#34;] = output_cfg
if action == &#34;run&#34;:
return self.run_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
return self.run_commands(**exec_args)
elif action == &#34;test&#34;:
return self.test_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
expected=playbook.get(&#34;expected&#34;, []),
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
exec_args[&#34;expected&#34;] = playbook.get(&#34;expected&#34;, [])
return self.test_commands(**exec_args)
else:
raise ConnpyError(f&#34;Unsupported playbook action: {action}&#34;)</code></pre>
</details>
@@ -743,7 +770,7 @@ el.replaceWith(d);
<div class="desc"><p>Run a plain-text script containing one command per line.</p></div>
</dd>
<dt id="connpy.services.ExecutionService.run_commands"><code class="name flex">
<span>def <span class="ident">run_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>folder: str | None = None,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None) > Dict[str, str]</span>
<span>def <span class="ident">run_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>folder: str | None = None,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None,<br>name: str | None = None) > Dict[str, str]</span>
</code></dt>
<dd>
<details class="source">
@@ -760,7 +787,8 @@ el.replaceWith(d);
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, str]:
&#34;&#34;&#34;Execute commands on a set of nodes.&#34;&#34;&#34;
@@ -784,58 +812,81 @@ el.replaceWith(d);
logger=logger
)
return results
# Combine output and status for the caller
full_results = {}
for unique in results:
full_results[unique] = {
&#34;output&#34;: results[unique],
&#34;status&#34;: executor.status.get(unique, 1)
}
return full_results
except Exception as e:
raise ConnpyError(f&#34;Execution failed: {e}&#34;)</code></pre>
</details>
<div class="desc"><p>Execute commands on a set of nodes.</p></div>
</dd>
<dt id="connpy.services.ExecutionService.run_yaml_playbook"><code class="name flex">
<span>def <span class="ident">run_yaml_playbook</span></span>(<span>self, playbook_path: str, parallel: int = 10) > Dict[str, Any]</span>
<span>def <span class="ident">run_yaml_playbook</span></span>(<span>self, playbook_data: str, parallel: int = 10) > Dict[str, Any]</span>
</code></dt>
<dd>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def run_yaml_playbook(self, playbook_path: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook.&#34;&#34;&#34;
if not os.path.exists(playbook_path):
raise ConnpyError(f&#34;Playbook file not found: {playbook_path}&#34;)
try:
with open(playbook_path, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_path}: {e}&#34;)
<pre><code class="python">def run_yaml_playbook(self, playbook_data: str, parallel: int = 10) -&gt; Dict[str, Any]:
&#34;&#34;&#34;Run a structured Connpy YAML automation playbook (from path or content).&#34;&#34;&#34;
playbook = None
if playbook_data.startswith(&#34;---YAML---\n&#34;):
try:
content = playbook_data[len(&#34;---YAML---\n&#34;):]
playbook = yaml.load(content, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to parse YAML content: {e}&#34;)
else:
if not os.path.exists(playbook_data):
raise ConnpyError(f&#34;Playbook file not found: {playbook_data}&#34;)
try:
with open(playbook_data, &#34;r&#34;) as f:
playbook = yaml.load(f, Loader=yaml.FullLoader)
except Exception as e:
raise ConnpyError(f&#34;Failed to load playbook {playbook_data}: {e}&#34;)
# Basic validation
if not isinstance(playbook, dict) or &#34;nodes&#34; not in playbook or &#34;commands&#34; not in playbook:
raise ConnpyError(&#34;Invalid playbook format: missing &#39;nodes&#39; or &#39;commands&#39; keys.&#34;)
action = playbook.get(&#34;action&#34;, &#34;run&#34;)
options = playbook.get(&#34;options&#34;, {})
# Extract all fields similar to RunHandler.cli_run
exec_args = {
&#34;nodes_filter&#34;: playbook[&#34;nodes&#34;],
&#34;commands&#34;: playbook[&#34;commands&#34;],
&#34;variables&#34;: playbook.get(&#34;variables&#34;),
&#34;parallel&#34;: options.get(&#34;parallel&#34;, parallel),
&#34;timeout&#34;: playbook.get(&#34;timeout&#34;, options.get(&#34;timeout&#34;, 10)),
&#34;prompt&#34;: options.get(&#34;prompt&#34;),
&#34;name&#34;: playbook.get(&#34;name&#34;, &#34;Task&#34;)
}
# Map &#39;output&#39; field to folder path if it&#39;s not stdout/null
output_cfg = playbook.get(&#34;output&#34;)
if output_cfg not in [None, &#34;stdout&#34;]:
exec_args[&#34;folder&#34;] = output_cfg
if action == &#34;run&#34;:
return self.run_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
return self.run_commands(**exec_args)
elif action == &#34;test&#34;:
return self.test_commands(
nodes_filter=playbook[&#34;nodes&#34;],
commands=playbook[&#34;commands&#34;],
expected=playbook.get(&#34;expected&#34;, []),
parallel=parallel,
timeout=playbook.get(&#34;timeout&#34;, 10)
)
exec_args[&#34;expected&#34;] = playbook.get(&#34;expected&#34;, [])
return self.test_commands(**exec_args)
else:
raise ConnpyError(f&#34;Unsupported playbook action: {action}&#34;)</code></pre>
</details>
<div class="desc"><p>Run a structured Connpy YAML automation playbook.</p></div>
<div class="desc"><p>Run a structured Connpy YAML automation playbook (from path or content).</p></div>
</dd>
<dt id="connpy.services.ExecutionService.test_commands"><code class="name flex">
<span>def <span class="ident">test_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>expected: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None) > Dict[str, Dict[str, bool]]</span>
<span>def <span class="ident">test_commands</span></span>(<span>self,<br>nodes_filter: str,<br>commands: List[str],<br>expected: List[str],<br>variables: Dict[str, Any] | None = None,<br>parallel: int = 10,<br>timeout: int = 10,<br>folder: str | None = None,<br>prompt: str | None = None,<br>on_node_complete: Callable | None = None,<br>logger: Callable | None = None,<br>name: str | None = None) > Dict[str, Dict[str, bool]]</span>
</code></dt>
<dd>
<details class="source">
@@ -850,9 +901,11 @@ el.replaceWith(d);
variables: Optional[Dict[str, Any]] = None,
parallel: int = 10,
timeout: int = 10,
folder: Optional[str] = None,
prompt: Optional[str] = None,
on_node_complete: Optional[Callable] = None,
logger: Optional[Callable] = None
logger: Optional[Callable] = None,
name: Optional[str] = None
) -&gt; Dict[str, Dict[str, bool]]:
&#34;&#34;&#34;Run commands and verify expected output on a set of nodes.&#34;&#34;&#34;
@@ -871,6 +924,7 @@ el.replaceWith(d);
vars=variables,
parallel=parallel,
timeout=timeout,
folder=folder,
prompt=prompt,
on_complete=on_node_complete,
logger=logger
@@ -3215,7 +3269,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.node_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -760,7 +760,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.plugin_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -671,7 +671,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.profile_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -429,7 +429,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.provider API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -164,7 +164,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.sync_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -964,7 +964,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.services.system_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -325,7 +325,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.conftest API documentation</title>
<meta name="description" content="Shared fixtures for connpy tests …">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -258,7 +258,7 @@ def tmp_config_dir(tmp_path):
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -152,7 +152,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_ai API documentation</title>
<meta name="description" content="Tests for connpy.ai module.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -1731,7 +1731,7 @@ def myai(self, ai_config, mock_litellm):
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_capture API documentation</title>
<meta name="description" content="Tests for connpy.core_plugins.capture">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -245,7 +245,7 @@ def mock_connapp():
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_completion API documentation</title>
<meta name="description" content="Tests for connpy.completion module.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -257,7 +257,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_configfile API documentation</title>
<meta name="description" content="Tests for connpy.configfile module.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -2005,7 +2005,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_connapp API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -699,7 +699,7 @@ def test_run(mock_run_commands, app):
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_core API documentation</title>
<meta name="description" content="Tests for connpy.core module — node and nodes classes.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -1369,7 +1369,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_execution_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -142,7 +142,7 @@ Regression: ExecutionService.test_commands currently ignores on_node_complete.</
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_grpc_layer API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -709,7 +709,7 @@ def test_connect_dynamic_msg_formatting_ssm(self, mock_select, mock_read, mock_s
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_hooks API documentation</title>
<meta name="description" content="Tests for connpy.hooks module — MethodHook and ClassHook.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -673,7 +673,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_node_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -178,7 +178,7 @@ Regression: connapp._mod calls add_node instead of update_node.</p></div>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_plugins API documentation</title>
<meta name="description" content="Tests for connpy.plugins module.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -917,7 +917,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_printer API documentation</title>
<meta name="description" content="Tests for connpy.printer module.">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -459,7 +459,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_printer_concurrency API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -148,7 +148,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_profile_service API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -192,7 +192,7 @@ Regression: ProfileService currently doesn't resolve inheritance within profiles
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_provider API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -139,7 +139,7 @@ el.replaceWith(d);
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tests.test_sync API documentation</title>
<meta name="description" content="Tests for connpy.services.sync_service">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -354,7 +354,7 @@ def test_perform_restore(self, mock_remove, mock_dirname, mock_exists, MockZipFi
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>
+2 -2
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.5">
<meta name="generator" content="pdoc3 0.11.6">
<title>connpy.tunnels API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
@@ -460,7 +460,7 @@ Bridges the blocking gRPC iterators with the async _async_interact_loop.</p></di
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.5</a>.</p>
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.6</a>.</p>
</footer>
</body>
</html>