hyperpocket 0.3.7__py3-none-any.whl → 0.4.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- hyperpocket/auth/activeloop/token_handler.py +4 -0
- hyperpocket/auth/adobe/token_handler.py +4 -0
- hyperpocket/auth/affinity/token_handler.py +4 -0
- hyperpocket/auth/agentql/token_handler.py +4 -0
- hyperpocket/auth/ahrefs/token_handler.py +4 -0
- hyperpocket/auth/airtable/token_handler.py +4 -0
- hyperpocket/auth/alchemy/token_handler.py +4 -0
- hyperpocket/auth/altoviz/token_handler.py +4 -0
- hyperpocket/auth/bamboohr/token_handler.py +4 -0
- hyperpocket/auth/bitwarden/token_handler.py +4 -0
- hyperpocket/auth/brevo/README.md +1 -1
- hyperpocket/auth/brevo/token_handler.py +4 -0
- hyperpocket/auth/brex/token_handler.py +4 -0
- hyperpocket/auth/cal/token_handler.py +4 -0
- hyperpocket/auth/canvas/token_handler.py +4 -0
- hyperpocket/auth/clickup/token_handler.py +4 -0
- hyperpocket/auth/cloudflare/token_handler.py +4 -0
- hyperpocket/auth/dailybot/token_handler.py +4 -0
- hyperpocket/auth/datadog/token_handler.py +4 -0
- hyperpocket/auth/discordbot/README.md +0 -1
- hyperpocket/auth/discordbot/token_handler.py +4 -0
- hyperpocket/auth/elevenlabs/token_handler.py +4 -0
- hyperpocket/auth/exa/token_handler.py +4 -0
- hyperpocket/auth/facebook/oauth2_handler.py +4 -0
- hyperpocket/auth/finage/token_handler.py +4 -0
- hyperpocket/auth/happyrobot/token_handler.py +4 -0
- hyperpocket/auth/heygen/token_handler.py +4 -0
- hyperpocket/auth/klaviyo/token_handler.py +4 -0
- hyperpocket/auth/lever/token_handler.py +4 -0
- hyperpocket/auth/lever_sandbox/token_handler.py +4 -0
- hyperpocket/auth/listennotes/token_handler.py +4 -0
- hyperpocket/auth/mem0/token_handler.py +4 -0
- hyperpocket/auth/microsoft_clarity/token_handler.py +4 -0
- hyperpocket/auth/neon/token_handler.py +4 -0
- hyperpocket/auth/ngrok/token_handler.py +4 -0
- hyperpocket/auth/oncehub/token_handler.py +4 -0
- hyperpocket/auth/pagerduty/token_handler.py +4 -0
- hyperpocket/auth/pandadoc/token_handler.py +4 -0
- hyperpocket/auth/pipedrive/token_handler.py +4 -0
- hyperpocket/auth/posthog/token_handler.py +4 -0
- hyperpocket/auth/provider.py +1 -0
- hyperpocket/auth/ravenseotools/token_handler.py +4 -0
- hyperpocket/auth/semantic_scholar/token_handler.py +4 -0
- hyperpocket/auth/sendgrid/token_handler.py +4 -0
- hyperpocket/auth/stripe/token_handler.py +4 -0
- hyperpocket/auth/supabase/token_handler.py +4 -0
- hyperpocket/auth/tavily/token_handler.py +4 -0
- hyperpocket/auth/timekit/token_handler.py +4 -0
- hyperpocket/auth/trello/token_handler.py +4 -0
- hyperpocket/auth/wandb/token_handler.py +4 -0
- hyperpocket/auth/weaviate/context.py +12 -0
- hyperpocket/auth/weaviate/token_context.py +11 -0
- hyperpocket/auth/weaviate/token_handler.py +68 -0
- hyperpocket/auth/weaviate/token_schema.py +7 -0
- hyperpocket/auth/workiom/token_handler.py +4 -0
- hyperpocket/auth/zinc/token_handler.py +4 -0
- hyperpocket/cli/eject.py +2 -7
- hyperpocket/cli/pull.py +2 -7
- hyperpocket/config/settings.py +2 -1
- hyperpocket/pocket_core.py +41 -68
- hyperpocket/pocket_main.py +37 -16
- hyperpocket/repository/__init__.py +3 -4
- hyperpocket/repository/repository.py +6 -41
- hyperpocket/repository/tool_reference.py +28 -0
- hyperpocket/server/auth/weaviate.py +27 -0
- hyperpocket/server/server.py +127 -61
- hyperpocket/session/in_memory.py +13 -3
- hyperpocket/tool/__init__.py +0 -3
- hyperpocket/tool/dock/__init__.py +3 -0
- hyperpocket/tool/dock/dock.py +34 -0
- hyperpocket/tool/function/__init__.py +1 -1
- hyperpocket/tool/function/tool.py +62 -32
- hyperpocket/tool/tool.py +1 -9
- hyperpocket/tool_like.py +2 -1
- hyperpocket/util/generate_slug.py +4 -0
- hyperpocket/util/json_schema_to_model.py +5 -1
- {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.1.dist-info}/METADATA +4 -1
- {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.1.dist-info}/RECORD +81 -87
- hyperpocket/cli/sync.py +0 -17
- hyperpocket/repository/lock.py +0 -240
- hyperpocket/repository/lockfile.py +0 -62
- hyperpocket/server/tool/__init__.py +0 -10
- hyperpocket/server/tool/dto/script.py +0 -33
- hyperpocket/server/tool/wasm.py +0 -46
- hyperpocket/tool/wasm/README.md +0 -166
- hyperpocket/tool/wasm/__init__.py +0 -3
- hyperpocket/tool/wasm/browser.py +0 -63
- hyperpocket/tool/wasm/invoker.py +0 -41
- hyperpocket/tool/wasm/script.py +0 -134
- hyperpocket/tool/wasm/templates/__init__.py +0 -35
- hyperpocket/tool/wasm/templates/node.py +0 -87
- hyperpocket/tool/wasm/templates/python.py +0 -93
- hyperpocket/tool/wasm/tool.py +0 -163
- /hyperpocket/{server/tool/dto → auth/weaviate}/__init__.py +0 -0
- {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.1.dist-info}/WHEEL +0 -0
- {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.1.dist-info}/entry_points.txt +0 -0
hyperpocket/tool/wasm/script.py
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
import base64
|
2
|
-
import enum
|
3
|
-
import pathlib
|
4
|
-
from typing import Optional
|
5
|
-
|
6
|
-
import toml
|
7
|
-
from pydantic import BaseModel
|
8
|
-
|
9
|
-
from hyperpocket.config import pocket_logger
|
10
|
-
|
11
|
-
|
12
|
-
class ScriptRuntime(enum.Enum):
|
13
|
-
Node = "node"
|
14
|
-
Python = "python"
|
15
|
-
Wasm = "wasm"
|
16
|
-
|
17
|
-
|
18
|
-
_RuntimePackageFiles = {
|
19
|
-
ScriptRuntime.Node: ["dist/index.js"],
|
20
|
-
ScriptRuntime.Python: ["main.py", "requirements.txt"],
|
21
|
-
ScriptRuntime.Wasm: ["dist/index.wasm"],
|
22
|
-
}
|
23
|
-
|
24
|
-
|
25
|
-
class ScriptFileNodeContent(BaseModel):
|
26
|
-
contents: str
|
27
|
-
|
28
|
-
|
29
|
-
class ScriptFileNode(BaseModel):
|
30
|
-
directory: Optional[dict[str, "ScriptFileNode"]] = None
|
31
|
-
file: Optional[ScriptFileNodeContent] = None
|
32
|
-
|
33
|
-
@classmethod
|
34
|
-
def create_file_tree(cls, path: str, contents: str) -> dict[str, "ScriptFileNode"]:
|
35
|
-
path_split = path.split("/")
|
36
|
-
if len(path_split) == 1:
|
37
|
-
return {
|
38
|
-
path_split[0]: ScriptFileNode(
|
39
|
-
file=ScriptFileNodeContent(contents=contents)
|
40
|
-
)
|
41
|
-
}
|
42
|
-
node = cls.create_file_tree("/".join(path_split[1:]), contents)
|
43
|
-
return {path_split[0]: ScriptFileNode(directory=node)}
|
44
|
-
|
45
|
-
@staticmethod
|
46
|
-
def merge(
|
47
|
-
a: dict[str, "ScriptFileNode"], b: [str, "ScriptFileNode"]
|
48
|
-
) -> dict[str, "ScriptFileNode"]:
|
49
|
-
for k, v in b.items():
|
50
|
-
if k in a:
|
51
|
-
if a[k].directory and v.directory:
|
52
|
-
a[k].directory = ScriptFileNode.merge(a[k].directory, v.directory)
|
53
|
-
elif a[k].file and v.file:
|
54
|
-
a[k].file = v.file
|
55
|
-
else:
|
56
|
-
a[k] = v
|
57
|
-
return a
|
58
|
-
|
59
|
-
|
60
|
-
class Script(BaseModel):
|
61
|
-
id: str
|
62
|
-
tool_path: str
|
63
|
-
rendered_html: str
|
64
|
-
runtime: ScriptRuntime
|
65
|
-
|
66
|
-
def load_file_tree(self) -> dict[str, ScriptFileNode]:
|
67
|
-
relpaths = _RuntimePackageFiles[self.runtime]
|
68
|
-
file_tree = dict()
|
69
|
-
for p in relpaths:
|
70
|
-
filepath = pathlib.Path(self.tool_path) / p
|
71
|
-
with filepath.open("r") as f:
|
72
|
-
contents = f.read().encode("utf-8")
|
73
|
-
encoded_bytes = base64.b64encode(contents)
|
74
|
-
encoded_str = encoded_bytes.decode()
|
75
|
-
file_tree = ScriptFileNode.merge(
|
76
|
-
file_tree, ScriptFileNode.create_file_tree(p, encoded_str)
|
77
|
-
)
|
78
|
-
return file_tree
|
79
|
-
|
80
|
-
@property
|
81
|
-
def package_name(self) -> Optional[str]:
|
82
|
-
if self.runtime != ScriptRuntime.Python:
|
83
|
-
return
|
84
|
-
pyproject = toml.load(pathlib.Path(self.tool_path) / "pyproject.toml")
|
85
|
-
if "project" in pyproject:
|
86
|
-
name = pyproject["project"]["name"]
|
87
|
-
if "tool" in pyproject and "poetry" in pyproject["tool"]:
|
88
|
-
name = pyproject["tool"]["poetry"]["name"]
|
89
|
-
if not name:
|
90
|
-
raise ValueError("Could not find package name")
|
91
|
-
return name.replace("-", "_")
|
92
|
-
|
93
|
-
@property
|
94
|
-
def entrypoint(self) -> str:
|
95
|
-
pocket_logger.info(self.tool_path)
|
96
|
-
if self.runtime == ScriptRuntime.Node:
|
97
|
-
return "dist/index.js"
|
98
|
-
elif self.runtime == ScriptRuntime.Wasm:
|
99
|
-
return "dist/main.wasm"
|
100
|
-
pyproject = toml.load(pathlib.Path(self.tool_path) / "pyproject.toml")
|
101
|
-
version = None
|
102
|
-
if "project" in pyproject:
|
103
|
-
version = pyproject["project"]["version"]
|
104
|
-
elif "tool" in pyproject and "poetry" in pyproject["tool"]:
|
105
|
-
version = pyproject["tool"]["poetry"]["version"]
|
106
|
-
else:
|
107
|
-
raise ValueError("Could not find package version")
|
108
|
-
wheel_name = f"{self.package_name}-{version}-py3-none-any.whl"
|
109
|
-
wheel_path = pathlib.Path(self.tool_path) / "dist" / wheel_name
|
110
|
-
if not wheel_path.exists():
|
111
|
-
raise ValueError(f"Wheel file {wheel_path} does not exist")
|
112
|
-
return wheel_name
|
113
|
-
|
114
|
-
def dist_file_path(self, file_name: str) -> str:
|
115
|
-
return str(pathlib.Path(self.tool_path) / "dist" / file_name)
|
116
|
-
|
117
|
-
|
118
|
-
class _ScriptStore(object):
|
119
|
-
scripts: dict[str, Script] = {}
|
120
|
-
|
121
|
-
def __init__(self):
|
122
|
-
self.rendered_html = {}
|
123
|
-
|
124
|
-
def add_script(self, script: Script):
|
125
|
-
if script.id in self.scripts:
|
126
|
-
raise ValueError("Script id already exists")
|
127
|
-
self.scripts[script.id] = script
|
128
|
-
|
129
|
-
def get_script(self, script_id: str) -> Script:
|
130
|
-
# ValueError exception is intentional
|
131
|
-
return self.scripts[script_id]
|
132
|
-
|
133
|
-
|
134
|
-
ScriptStore = _ScriptStore()
|
@@ -1,35 +0,0 @@
|
|
1
|
-
import base64
|
2
|
-
import json
|
3
|
-
|
4
|
-
from jinja2 import DictLoader, Environment
|
5
|
-
|
6
|
-
from hyperpocket.tool.wasm.templates.node import node_template
|
7
|
-
from hyperpocket.tool.wasm.templates.python import python_template
|
8
|
-
|
9
|
-
TemplateEnvironments = Environment(
|
10
|
-
loader=DictLoader(
|
11
|
-
{
|
12
|
-
"python.html": python_template,
|
13
|
-
"node.html": node_template,
|
14
|
-
}
|
15
|
-
),
|
16
|
-
autoescape=False,
|
17
|
-
)
|
18
|
-
|
19
|
-
|
20
|
-
def render(
|
21
|
-
language: str, script_id: str, env: dict[str, str], body: str, **kwargs
|
22
|
-
) -> str:
|
23
|
-
env_json = json.dumps(env)
|
24
|
-
template = TemplateEnvironments.get_template(f"{language.lower()}.html")
|
25
|
-
body_bytes = body.encode("utf-8")
|
26
|
-
body_b64_bytes = base64.b64encode(body_bytes)
|
27
|
-
body_b64 = body_b64_bytes.decode("ascii")
|
28
|
-
return template.render(
|
29
|
-
**{
|
30
|
-
"SCRIPT_ID": script_id,
|
31
|
-
"ENV_JSON": env_json,
|
32
|
-
"BODY_JSON_B64": body_b64,
|
33
|
-
}
|
34
|
-
| kwargs
|
35
|
-
)
|
@@ -1,87 +0,0 @@
|
|
1
|
-
node_template = """
|
2
|
-
<!DOCTYPE html>
|
3
|
-
<html lang="en">
|
4
|
-
<head>
|
5
|
-
<meta charset="UTF-8">
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
-
<title>PyScript Offline</title>
|
8
|
-
</head>
|
9
|
-
<body>
|
10
|
-
<script type="module">
|
11
|
-
function loadConfig() {
|
12
|
-
globalThis.toolConfigs = {
|
13
|
-
envs: `{{ ENV_JSON }}`,
|
14
|
-
body: `{{ BODY_JSON_B64 }}`,
|
15
|
-
scriptID: `{{ SCRIPT_ID }}`
|
16
|
-
}
|
17
|
-
}
|
18
|
-
import { WebContainer } from 'https://esm.run/@webcontainer/api@1.5.1';
|
19
|
-
function decodeContent(content) {
|
20
|
-
return Uint8Array.from(atob(content), c => c.charCodeAt(0));
|
21
|
-
}
|
22
|
-
function decodeFileTree(filetree) {
|
23
|
-
const decoded = {};
|
24
|
-
for (const [key, value] of Object.entries(filetree)) {
|
25
|
-
if (value.file) {
|
26
|
-
decoded[key] = {
|
27
|
-
file: {
|
28
|
-
contents: decodeContent(value.file.contents)
|
29
|
-
}
|
30
|
-
}
|
31
|
-
} else if (value.directory) {
|
32
|
-
decoded[key] = {
|
33
|
-
directory: decodeFileTree(value.directory)
|
34
|
-
}
|
35
|
-
} else if (value.symlink) {
|
36
|
-
decoded[key] = {
|
37
|
-
symlink: value.symlink
|
38
|
-
}
|
39
|
-
}
|
40
|
-
}
|
41
|
-
return decoded;
|
42
|
-
}
|
43
|
-
async function main() {
|
44
|
-
loadConfig();
|
45
|
-
const b64FilesResp = await fetch(`/tools/wasm/scripts/${globalThis.toolConfigs.scriptID}/file_tree`);
|
46
|
-
const b64Files = await b64FilesResp.json();
|
47
|
-
const files = decodeFileTree(b64Files.tree);
|
48
|
-
const webcontainer = await WebContainer.boot();
|
49
|
-
|
50
|
-
await webcontainer.mount(files)
|
51
|
-
const envs = JSON.parse(globalThis.toolConfigs.envs)
|
52
|
-
envs['DEPLOYED'] = 'true'
|
53
|
-
const runProcess = await webcontainer.spawn('node', ['dist/index.js'], {
|
54
|
-
output: true,
|
55
|
-
env: envs,
|
56
|
-
});
|
57
|
-
const stdin = runProcess.input.getWriter();
|
58
|
-
const decodedBytes = atob(globalThis.toolConfigs.body);
|
59
|
-
await (async () => {
|
60
|
-
await stdin.ready
|
61
|
-
await stdin.write(decodedBytes);
|
62
|
-
})()
|
63
|
-
let stdout = '';
|
64
|
-
runProcess.output.pipeTo(
|
65
|
-
new WritableStream({
|
66
|
-
write(chunk) {
|
67
|
-
stdout += chunk;
|
68
|
-
}
|
69
|
-
})
|
70
|
-
)
|
71
|
-
await runProcess.exit;
|
72
|
-
if (stdout.startsWith(decodedBytes)) {
|
73
|
-
stdout = stdout.slice(decodedBytes);
|
74
|
-
}
|
75
|
-
await fetch(`/tools/wasm/scripts/${globalThis.toolConfigs.scriptID}/done`, {
|
76
|
-
method: 'POST',
|
77
|
-
headers: {
|
78
|
-
'Content-Type': 'application/json'
|
79
|
-
},
|
80
|
-
body: JSON.stringify({ stdout })
|
81
|
-
});
|
82
|
-
}
|
83
|
-
main();
|
84
|
-
</script>
|
85
|
-
</body>
|
86
|
-
</html>
|
87
|
-
"""
|
@@ -1,93 +0,0 @@
|
|
1
|
-
python_template = """
|
2
|
-
<!DOCTYPE html>
|
3
|
-
<html lang="en">
|
4
|
-
<head>
|
5
|
-
<meta charset="UTF-8">
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
-
<title>PyScript Offline</title>
|
8
|
-
<script src="https://cdn.jsdelivr.net/pyodide/v0.26.4/full/pyodide.js"></script>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
<script type="module">
|
12
|
-
function loadConfig() {
|
13
|
-
globalThis.toolConfigs = {
|
14
|
-
envs: `{{ ENV_JSON }}`,
|
15
|
-
body: `{{ BODY_JSON_B64 }}`,
|
16
|
-
scriptID: `{{ SCRIPT_ID }}`
|
17
|
-
}
|
18
|
-
}
|
19
|
-
async function _main() {
|
20
|
-
// load the script configs
|
21
|
-
loadConfig();
|
22
|
-
|
23
|
-
// get entrypoint wheel
|
24
|
-
const entrypointResp = await fetch(`/tools/wasm/scripts/${globalThis.toolConfigs.scriptID}/entrypoint`);
|
25
|
-
const { package_name: packageName, entrypoint } = await entrypointResp.json();
|
26
|
-
|
27
|
-
// initialize pyodide
|
28
|
-
const pyodide = await loadPyodide({
|
29
|
-
env: JSON.parse(globalThis.toolConfigs.envs),
|
30
|
-
});
|
31
|
-
await pyodide.loadPackage("micropip");
|
32
|
-
await pyodide.loadPackage("ssl");
|
33
|
-
const micropip = pyodide.pyimport("micropip");
|
34
|
-
await micropip.install(entrypoint);
|
35
|
-
await micropip.install("pyodide-http")
|
36
|
-
|
37
|
-
let emitted = false;
|
38
|
-
const decodedBytes = atob(globalThis.toolConfigs.body);
|
39
|
-
pyodide.setStdin({
|
40
|
-
stdin: () => {
|
41
|
-
if (emitted) {
|
42
|
-
return null;
|
43
|
-
}
|
44
|
-
emitted = true;
|
45
|
-
return decodedBytes;
|
46
|
-
},
|
47
|
-
autoEOF: true,
|
48
|
-
})
|
49
|
-
let stdout = "";
|
50
|
-
let stderr = "";
|
51
|
-
pyodide.setStdout({
|
52
|
-
batched: (x) => { stdout += x; },
|
53
|
-
})
|
54
|
-
pyodide.setStderr({
|
55
|
-
batched: (x) => { stderr += x; },
|
56
|
-
})
|
57
|
-
await pyodide.runPythonAsync(`
|
58
|
-
import pyodide_http
|
59
|
-
pyodide_http.patch_all()
|
60
|
-
|
61
|
-
import ${packageName}
|
62
|
-
${packageName}.main()
|
63
|
-
`);
|
64
|
-
console.log(stdout)
|
65
|
-
await fetch(`/tools/wasm/scripts/${globalThis.toolConfigs.scriptID}/done`, {
|
66
|
-
method: 'POST',
|
67
|
-
headers: {
|
68
|
-
'Content-Type': 'application/json'
|
69
|
-
},
|
70
|
-
body: JSON.stringify({ stdout, stderr })
|
71
|
-
});
|
72
|
-
}
|
73
|
-
|
74
|
-
async function main() {
|
75
|
-
try {
|
76
|
-
await _main();
|
77
|
-
} catch (e) {
|
78
|
-
console.error(e);
|
79
|
-
await fetch(`/tools/wasm/scripts/${globalThis.toolConfigs.scriptID}/done`, {
|
80
|
-
method: 'POST',
|
81
|
-
headers: {
|
82
|
-
'Content-Type': 'application/json'
|
83
|
-
},
|
84
|
-
body: JSON.stringify({ error: e.message })
|
85
|
-
});
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
main();
|
90
|
-
</script>
|
91
|
-
</body>
|
92
|
-
</html>
|
93
|
-
"""
|
hyperpocket/tool/wasm/tool.py
DELETED
@@ -1,163 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import pathlib
|
3
|
-
from typing import Any, Optional
|
4
|
-
|
5
|
-
import toml
|
6
|
-
|
7
|
-
from hyperpocket.auth import AuthProvider
|
8
|
-
from hyperpocket.config import pocket_logger
|
9
|
-
from hyperpocket.repository import Lock, Lockfile
|
10
|
-
from hyperpocket.repository.lock import GitLock, LocalLock
|
11
|
-
from hyperpocket.tool import Tool, ToolRequest
|
12
|
-
from hyperpocket.tool.tool import ToolAuth
|
13
|
-
from hyperpocket.tool.wasm.invoker import WasmInvoker
|
14
|
-
from hyperpocket.tool.wasm.script import ScriptRuntime
|
15
|
-
|
16
|
-
|
17
|
-
class WasmToolRequest(ToolRequest):
|
18
|
-
lock: Lock
|
19
|
-
rel_path: str
|
20
|
-
|
21
|
-
def __init__(self, lock: Lock, rel_path: str, tool_vars: dict):
|
22
|
-
self.lock = lock
|
23
|
-
self.rel_path = rel_path
|
24
|
-
self.overridden_tool_vars = tool_vars
|
25
|
-
|
26
|
-
def __str__(self):
|
27
|
-
return f"ToolRequest(lock={self.lock}, rel_path={self.rel_path})"
|
28
|
-
|
29
|
-
|
30
|
-
def from_local(
|
31
|
-
path: str, tool_vars: Optional[dict[str, str]] = None
|
32
|
-
) -> WasmToolRequest:
|
33
|
-
if tool_vars is None:
|
34
|
-
tool_vars = dict()
|
35
|
-
return WasmToolRequest(LocalLock(path), "", tool_vars)
|
36
|
-
|
37
|
-
|
38
|
-
def from_git(
|
39
|
-
repository: str, ref: str, rel_path: str, tool_vars: Optional[dict[str, str]] = None
|
40
|
-
) -> WasmToolRequest:
|
41
|
-
if not tool_vars:
|
42
|
-
tool_vars = dict()
|
43
|
-
return WasmToolRequest(
|
44
|
-
GitLock(repository_url=repository, git_ref=ref), rel_path, tool_vars
|
45
|
-
)
|
46
|
-
|
47
|
-
|
48
|
-
class WasmTool(Tool):
|
49
|
-
"""
|
50
|
-
WasmTool is Tool executing local python method.
|
51
|
-
"""
|
52
|
-
|
53
|
-
_invoker: WasmInvoker = None
|
54
|
-
pkg_lock: Lock = None
|
55
|
-
rel_path: str
|
56
|
-
runtime: ScriptRuntime = None
|
57
|
-
json_schema: Optional[dict] = None
|
58
|
-
readme: Optional[str] = None
|
59
|
-
|
60
|
-
@property
|
61
|
-
def invoker(self) -> WasmInvoker:
|
62
|
-
if not self._invoker:
|
63
|
-
self._invoker = WasmInvoker()
|
64
|
-
return self._invoker
|
65
|
-
|
66
|
-
@classmethod
|
67
|
-
def from_tool_request(
|
68
|
-
cls, tool_req: WasmToolRequest, lockfile: Lockfile = None, **kwargs
|
69
|
-
) -> "WasmTool":
|
70
|
-
if not lockfile:
|
71
|
-
raise ValueError("lockfile is required")
|
72
|
-
tool_req.lock = lockfile.get_lock(tool_req.lock.key())
|
73
|
-
toolpkg_path = tool_req.lock.toolpkg_path()
|
74
|
-
rel_path = tool_req.rel_path
|
75
|
-
rootpath = pathlib.Path(toolpkg_path) / rel_path
|
76
|
-
schema_path = rootpath / "schema.json"
|
77
|
-
config_path = rootpath / "config.toml"
|
78
|
-
readme_path = rootpath / "README.md"
|
79
|
-
|
80
|
-
try:
|
81
|
-
with schema_path.open("r") as f:
|
82
|
-
json_schema = json.load(f)
|
83
|
-
except Exception as e:
|
84
|
-
pocket_logger.warning(
|
85
|
-
f"{toolpkg_path} failed to load json schema. error : {e}"
|
86
|
-
)
|
87
|
-
json_schema = None
|
88
|
-
|
89
|
-
default_tool_vars = dict()
|
90
|
-
try:
|
91
|
-
with config_path.open("r") as f:
|
92
|
-
config = toml.load(f)
|
93
|
-
name = config.get("name")
|
94
|
-
description = config.get("description")
|
95
|
-
if language := config.get("language"):
|
96
|
-
lang = language.lower()
|
97
|
-
if lang == "python":
|
98
|
-
runtime = ScriptRuntime.Python
|
99
|
-
elif lang == "node":
|
100
|
-
runtime = ScriptRuntime.Node
|
101
|
-
else:
|
102
|
-
raise ValueError(f"The language `{lang}` is not supported.")
|
103
|
-
else:
|
104
|
-
raise ValueError("`language` field is required in config.toml")
|
105
|
-
auth = cls._get_auth(config)
|
106
|
-
default_tool_vars = config.get("tool_vars", {})
|
107
|
-
except Exception as e:
|
108
|
-
raise ValueError(f"Failed to load config.toml: {e}")
|
109
|
-
|
110
|
-
if readme_path.exists():
|
111
|
-
with readme_path.open("r") as f:
|
112
|
-
readme = f.read()
|
113
|
-
else:
|
114
|
-
readme = None
|
115
|
-
|
116
|
-
return cls(
|
117
|
-
name=name,
|
118
|
-
description=description,
|
119
|
-
argument_json_schema=json_schema,
|
120
|
-
auth=auth,
|
121
|
-
runtime=runtime,
|
122
|
-
readme=readme,
|
123
|
-
pkg_lock=tool_req.lock,
|
124
|
-
rel_path=tool_req.rel_path,
|
125
|
-
postprocessings=tool_req.postprocessings,
|
126
|
-
default_tool_vars=default_tool_vars,
|
127
|
-
overridden_tool_vars=tool_req.overridden_tool_vars,
|
128
|
-
)
|
129
|
-
|
130
|
-
@classmethod
|
131
|
-
def _get_auth(cls, config: dict) -> Optional[ToolAuth]:
|
132
|
-
auth = config.get("auth")
|
133
|
-
if not auth:
|
134
|
-
return
|
135
|
-
auth_provider = auth.get("auth_provider")
|
136
|
-
auth_handler = auth.get("auth_handler")
|
137
|
-
scopes = auth.get("scopes", [])
|
138
|
-
return ToolAuth(
|
139
|
-
auth_provider=AuthProvider.get_auth_provider(auth_provider),
|
140
|
-
auth_handler=auth_handler,
|
141
|
-
scopes=scopes,
|
142
|
-
)
|
143
|
-
|
144
|
-
def template_arguments(self) -> dict[str, str]:
|
145
|
-
return {}
|
146
|
-
|
147
|
-
def invoke(self, body: Any, envs: dict, **kwargs) -> str:
|
148
|
-
return self.invoker.invoke(
|
149
|
-
str(self.pkg_lock.toolpkg_path() / self.rel_path),
|
150
|
-
self.runtime,
|
151
|
-
body,
|
152
|
-
envs | self.tool_vars,
|
153
|
-
**kwargs,
|
154
|
-
)
|
155
|
-
|
156
|
-
async def ainvoke(self, body: Any, envs: dict, **kwargs) -> str:
|
157
|
-
return await self.invoker.ainvoke(
|
158
|
-
str(self.pkg_lock.toolpkg_path() / self.rel_path),
|
159
|
-
self.runtime,
|
160
|
-
body,
|
161
|
-
envs | self.tool_vars,
|
162
|
-
**kwargs,
|
163
|
-
)
|
File without changes
|
File without changes
|
File without changes
|