hyperpocket 0.3.7__py3-none-any.whl → 0.4.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- hyperpocket/auth/provider.py +1 -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/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.0.dist-info}/METADATA +4 -1
- {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.0.dist-info}/RECORD +30 -36
- 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.0.dist-info}/WHEEL +0 -0
- {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.0.dist-info}/entry_points.txt +0 -0
hyperpocket/auth/provider.py
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
from hyperpocket.auth.context import AuthContext
|
3
|
+
class WeaviateAuthContext(AuthContext):
|
4
|
+
_ACCESS_TOKEN_KEY: str = "WEAVIATE_TOKEN"
|
5
|
+
def to_dict(self) -> dict[str, str]:
|
6
|
+
return {
|
7
|
+
self._ACCESS_TOKEN_KEY: self.access_token,
|
8
|
+
}
|
9
|
+
def to_profiled_dict(self, profile: str) -> dict[str, str]:
|
10
|
+
return {
|
11
|
+
f"{profile.upper()}_{self._ACCESS_TOKEN_KEY}": self.access_token,
|
12
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from hyperpocket.auth.weaviate.context import WeaviateAuthContext
|
2
|
+
from hyperpocket.auth.weaviate.token_schema import WeaviateTokenResponse
|
3
|
+
class WeaviateTokenAuthContext(WeaviateAuthContext):
|
4
|
+
@classmethod
|
5
|
+
def from_weaviate_token_response(cls, response: WeaviateTokenResponse):
|
6
|
+
description = f'Weaviate Token Context logged in'
|
7
|
+
return cls(
|
8
|
+
access_token=response.access_token,
|
9
|
+
description=description,
|
10
|
+
expires_at=None
|
11
|
+
)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
from urllib.parse import urljoin, urlencode
|
3
|
+
|
4
|
+
from hyperpocket.auth import AuthProvider
|
5
|
+
from hyperpocket.auth.context import AuthContext
|
6
|
+
from hyperpocket.auth.handler import AuthHandlerInterface, AuthenticateRequest
|
7
|
+
from hyperpocket.auth.weaviate.token_context import WeaviateTokenAuthContext
|
8
|
+
from hyperpocket.auth.weaviate.token_schema import WeaviateTokenResponse, WeaviateTokenRequest
|
9
|
+
from hyperpocket.config import config
|
10
|
+
from hyperpocket.futures import FutureStore
|
11
|
+
|
12
|
+
|
13
|
+
class WeaviateTokenAuthHandler(AuthHandlerInterface):
|
14
|
+
name: str = "weaviate-token"
|
15
|
+
description: str = "This handler is used to authenticate users using the Weaviate token."
|
16
|
+
scoped: bool = False
|
17
|
+
|
18
|
+
_TOKEN_URL: str = urljoin(config().public_base_url + "/", f"{config().callback_url_rewrite_prefix}/auth/token")
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def provider() -> AuthProvider:
|
22
|
+
return AuthProvider.WEAVIATE
|
23
|
+
|
24
|
+
@staticmethod
|
25
|
+
def provider_default() -> bool:
|
26
|
+
return True
|
27
|
+
|
28
|
+
@staticmethod
|
29
|
+
def recommended_scopes() -> set[str]:
|
30
|
+
return set()
|
31
|
+
|
32
|
+
def prepare(self, auth_req: WeaviateTokenRequest, thread_id: str, profile: str,
|
33
|
+
future_uid: str, *args, **kwargs) -> str:
|
34
|
+
redirect_uri = urljoin(
|
35
|
+
config().public_base_url + "/",
|
36
|
+
f"{config().callback_url_rewrite_prefix}/auth/weaviate/token/callback",
|
37
|
+
)
|
38
|
+
url = self._make_auth_url(auth_req=auth_req, redirect_uri=redirect_uri, state=future_uid)
|
39
|
+
FutureStore.create_future(future_uid, data={
|
40
|
+
"redirect_uri": redirect_uri,
|
41
|
+
"thread_id": thread_id,
|
42
|
+
"profile": profile,
|
43
|
+
})
|
44
|
+
|
45
|
+
return f'User needs to authenticate using the following URL: {url}'
|
46
|
+
|
47
|
+
async def authenticate(self, auth_req: WeaviateTokenRequest, future_uid: str, *args, **kwargs) -> AuthContext:
|
48
|
+
future_data = FutureStore.get_future(future_uid)
|
49
|
+
access_token = await future_data.future
|
50
|
+
|
51
|
+
response = WeaviateTokenResponse(access_token=access_token)
|
52
|
+
context = WeaviateTokenAuthContext.from_weaviate_token_response(response)
|
53
|
+
|
54
|
+
return context
|
55
|
+
|
56
|
+
async def refresh(self, auth_req: WeaviateTokenRequest, context: AuthContext, *args, **kwargs) -> AuthContext:
|
57
|
+
raise Exception("Weaviate token doesn't support refresh")
|
58
|
+
|
59
|
+
def _make_auth_url(self, auth_req: WeaviateTokenRequest, redirect_uri: str, state: str):
|
60
|
+
params = {
|
61
|
+
"redirect_uri": redirect_uri,
|
62
|
+
"state": state,
|
63
|
+
}
|
64
|
+
auth_url = f"{self._TOKEN_URL}?{urlencode(params)}"
|
65
|
+
return auth_url
|
66
|
+
|
67
|
+
def make_request(self, auth_scopes: Optional[list[str]] = None, **kwargs) -> WeaviateTokenRequest:
|
68
|
+
return WeaviateTokenRequest()
|
@@ -0,0 +1,7 @@
|
|
1
|
+
from typing import List, Optional
|
2
|
+
from pydantic import BaseModel
|
3
|
+
from hyperpocket.auth.schema import AuthenticateRequest, AuthenticateResponse
|
4
|
+
class WeaviateTokenRequest(AuthenticateRequest):
|
5
|
+
pass
|
6
|
+
class WeaviateTokenResponse(AuthenticateResponse):
|
7
|
+
access_token: str
|
hyperpocket/cli/eject.py
CHANGED
@@ -10,10 +10,5 @@ import hyperpocket.repository as repository
|
|
10
10
|
@click.argument("url", type=str)
|
11
11
|
@click.argument("ref", type=str)
|
12
12
|
@click.argument("remote_path", type=str)
|
13
|
-
|
14
|
-
|
15
|
-
if not lockfile:
|
16
|
-
lockfile = pathlib.Path.cwd() / "pocket.lock"
|
17
|
-
if not lockfile.exists():
|
18
|
-
raise ValueError("To eject a tool, you first need to pull it")
|
19
|
-
repository.eject(url, ref, remote_path, repository.Lockfile(lockfile))
|
13
|
+
def eject(url: str, ref: str, remote_path: str):
|
14
|
+
repository.eject(url, ref, remote_path)
|
hyperpocket/cli/pull.py
CHANGED
@@ -8,11 +8,6 @@ import hyperpocket.repository as repository
|
|
8
8
|
|
9
9
|
@click.command()
|
10
10
|
@click.argument("url", type=str)
|
11
|
-
@click.option("--lockfile", envvar="PATHS", type=click.Path(exists=True))
|
12
11
|
@click.option("--git-ref", type=str, default="HEAD")
|
13
|
-
def pull(url: str,
|
14
|
-
|
15
|
-
lockfile = pathlib.Path.cwd() / "pocket.lock"
|
16
|
-
if not lockfile.exists():
|
17
|
-
lockfile.touch()
|
18
|
-
repository.pull(repository.Lockfile(path=lockfile), url, git_ref)
|
12
|
+
def pull(url: str, git_ref: str):
|
13
|
+
repository.pull(url, git_ref)
|
hyperpocket/config/settings.py
CHANGED
@@ -2,7 +2,7 @@ import os
|
|
2
2
|
from pathlib import Path
|
3
3
|
|
4
4
|
from dynaconf import Dynaconf
|
5
|
-
from pydantic import BaseModel, Field
|
5
|
+
from pydantic import BaseModel, Field, Extra
|
6
6
|
|
7
7
|
from hyperpocket.config.auth import AuthConfig, DefaultAuthConfig
|
8
8
|
from hyperpocket.config.session import DefaultSessionConfig, SessionConfig
|
@@ -47,6 +47,7 @@ class Config(BaseModel):
|
|
47
47
|
auth: AuthConfig = DefaultAuthConfig
|
48
48
|
session: SessionConfig = DefaultSessionConfig
|
49
49
|
tool_vars: dict[str, str] = Field(default_factory=dict)
|
50
|
+
docks: dict[str, dict] = Field(default_factory=dict)
|
50
51
|
|
51
52
|
@property
|
52
53
|
def internal_base_url(self):
|
hyperpocket/pocket_core.py
CHANGED
@@ -1,53 +1,69 @@
|
|
1
1
|
import asyncio
|
2
|
-
import pathlib
|
3
2
|
from typing import Any, Callable, List, Optional, Union
|
4
3
|
|
5
4
|
from hyperpocket.builtin import get_builtin_tools
|
6
5
|
from hyperpocket.config import pocket_logger
|
7
6
|
from hyperpocket.pocket_auth import PocketAuth
|
8
|
-
from hyperpocket.
|
9
|
-
from hyperpocket.
|
10
|
-
from hyperpocket.tool import Tool, ToolRequest
|
7
|
+
from hyperpocket.tool import Tool
|
8
|
+
from hyperpocket.tool.dock import Dock
|
11
9
|
from hyperpocket.tool.function import from_func
|
12
|
-
from hyperpocket.tool.wasm import WasmTool
|
13
|
-
from hyperpocket.tool.wasm.tool import WasmToolRequest
|
14
10
|
from hyperpocket.tool_like import ToolLike
|
15
11
|
|
16
12
|
|
17
13
|
class PocketCore:
|
18
14
|
auth: PocketAuth
|
19
15
|
tools: dict[str, Tool]
|
20
|
-
|
16
|
+
docks: list[Dock]
|
21
17
|
|
18
|
+
@staticmethod
|
19
|
+
def _default_dock() -> Dock:
|
20
|
+
try:
|
21
|
+
from hyperdock_container.dock import ContainerDock
|
22
|
+
pocket_logger.info("hyperdock-container is loaded.")
|
23
|
+
return ContainerDock()
|
24
|
+
except ImportError:
|
25
|
+
pocket_logger.warning("Failed to import hyperdock_container.")
|
26
|
+
|
27
|
+
try:
|
28
|
+
from hyperdock_wasm.dock import WasmDock
|
29
|
+
pocket_logger.info("hyperdock-wasm is loaded.")
|
30
|
+
return WasmDock()
|
31
|
+
except ImportError:
|
32
|
+
raise ImportError("No default dock available. To register a remote tool, you need to install either hyperdock_wasm or hyperdock_container.")
|
33
|
+
|
34
|
+
|
22
35
|
def __init__(
|
23
36
|
self,
|
24
37
|
tools: list[ToolLike],
|
25
38
|
auth: PocketAuth = None,
|
26
|
-
lockfile_path: Optional[str] = None,
|
27
|
-
force_update: bool = False,
|
28
39
|
):
|
29
40
|
if auth is None:
|
30
41
|
auth = PocketAuth()
|
31
42
|
self.auth = auth
|
32
43
|
|
33
|
-
#
|
34
|
-
if
|
35
|
-
|
36
|
-
|
37
|
-
self.
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
self.
|
45
|
-
|
46
|
-
|
47
|
-
# load tool from tool_like
|
44
|
+
# filter strs out first and register the tools to default dock
|
45
|
+
str_tool_likes = [tool for tool in tools if (isinstance(tool, str) or isinstance(tool, tuple))]
|
46
|
+
function_tool_likes = [tool for tool in tools if (not isinstance(tool, str) and not isinstance(tool, Dock) and not isinstance(tool, tuple))]
|
47
|
+
# especially, docks are maintained by core
|
48
|
+
self.docks = [dock for dock in tools if isinstance(dock, Dock)]
|
49
|
+
|
50
|
+
if len(str_tool_likes) > 0:
|
51
|
+
default_dock = self._default_dock()
|
52
|
+
for str_tool_like in str_tool_likes:
|
53
|
+
default_dock.plug(req_like=str_tool_like)
|
54
|
+
# append default dock
|
55
|
+
self.docks.append(default_dock)
|
56
|
+
|
48
57
|
self.tools = dict()
|
49
|
-
|
58
|
+
|
59
|
+
# for each tool like, load the tool
|
60
|
+
for tool_like in function_tool_likes:
|
50
61
|
self._load_tool(tool_like)
|
62
|
+
|
63
|
+
for dock in self.docks:
|
64
|
+
tools = dock.tools()
|
65
|
+
for tool in tools:
|
66
|
+
self._load_tool(tool)
|
51
67
|
|
52
68
|
pocket_logger.info(
|
53
69
|
f"All Registered Tools Loaded successfully. total registered tools : {len(self.tools)}"
|
@@ -253,8 +269,6 @@ class PocketCore:
|
|
253
269
|
pocket_logger.info(f"Loading Tool {tool_like}")
|
254
270
|
if isinstance(tool_like, Tool):
|
255
271
|
tool = tool_like
|
256
|
-
elif isinstance(tool_like, ToolRequest):
|
257
|
-
tool = Tool.from_tool_request(tool_like, lockfile=self.lockfile)
|
258
272
|
elif isinstance(tool_like, Callable):
|
259
273
|
tool = from_func(tool_like)
|
260
274
|
else:
|
@@ -267,44 +281,3 @@ class PocketCore:
|
|
267
281
|
|
268
282
|
pocket_logger.info(f"Complete Loading Tool {tool.name}")
|
269
283
|
return tool
|
270
|
-
|
271
|
-
def _add_tool_like_lock_to_lockfile(self, tool_like: ToolLike):
|
272
|
-
if isinstance(tool_like, WasmToolRequest): # lock is only in WasmToolRequest
|
273
|
-
self.lockfile.add_lock(tool_like.lock)
|
274
|
-
return
|
275
|
-
|
276
|
-
@classmethod
|
277
|
-
def _parse_tool_like(cls, tool_like: ToolLike) -> ToolLike:
|
278
|
-
if isinstance(tool_like, str):
|
279
|
-
return cls._parse_str_tool_like(tool_like)
|
280
|
-
|
281
|
-
elif isinstance(tool_like, WasmToolRequest):
|
282
|
-
return tool_like
|
283
|
-
|
284
|
-
elif isinstance(tool_like, ToolRequest):
|
285
|
-
raise ValueError(f"unreachable. tool_like:{tool_like}")
|
286
|
-
elif isinstance(tool_like, WasmTool):
|
287
|
-
raise ValueError("WasmTool should pass ToolRequest instance instead.")
|
288
|
-
else: # Callable, Tool
|
289
|
-
return tool_like
|
290
|
-
|
291
|
-
@classmethod
|
292
|
-
def _parse_str_tool_like(cls, tool_like: str) -> ToolLike:
|
293
|
-
if pathlib.Path(tool_like).exists():
|
294
|
-
lock = LocalLock(tool_like)
|
295
|
-
parsed_tool_like = WasmToolRequest(lock=lock, rel_path="", tool_vars={})
|
296
|
-
elif tool_like.startswith("https://github.com"):
|
297
|
-
base_repo_url, git_ref, rel_path = GitLock.parse_repo_url(
|
298
|
-
repo_url=tool_like
|
299
|
-
)
|
300
|
-
lock = GitLock(repository_url=base_repo_url, git_ref=git_ref)
|
301
|
-
parsed_tool_like = WasmToolRequest(
|
302
|
-
lock=lock, rel_path=rel_path, tool_vars={}
|
303
|
-
)
|
304
|
-
else:
|
305
|
-
parsed_tool_like = None
|
306
|
-
RuntimeError(
|
307
|
-
f"Can't convert to ToolRequest. it might be wrong github url or local path. path: {tool_like}"
|
308
|
-
)
|
309
|
-
|
310
|
-
return parsed_tool_like
|
hyperpocket/pocket_main.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import asyncio
|
2
|
-
|
2
|
+
import uuid
|
3
|
+
from typing import Any, List, Union
|
3
4
|
|
4
5
|
from hyperpocket.config import pocket_logger
|
5
6
|
from hyperpocket.pocket_auth import PocketAuth
|
@@ -11,29 +12,39 @@ from hyperpocket.tool_like import ToolLike
|
|
11
12
|
class Pocket(object):
|
12
13
|
server: PocketServer
|
13
14
|
core: PocketCore
|
15
|
+
_uid: str
|
14
16
|
|
15
17
|
def __init__(
|
16
18
|
self,
|
17
19
|
tools: list[ToolLike],
|
18
20
|
auth: PocketAuth = None,
|
19
|
-
lockfile_path: Optional[str] = None,
|
20
|
-
force_update: bool = False,
|
21
21
|
use_profile: bool = False,
|
22
22
|
):
|
23
|
-
self.use_profile = use_profile
|
24
|
-
self.core = PocketCore(
|
25
|
-
tools=tools,
|
26
|
-
auth=auth,
|
27
|
-
lockfile_path=lockfile_path,
|
28
|
-
force_update=force_update,
|
29
|
-
)
|
30
|
-
self.server = PocketServer()
|
31
|
-
self.server.run(self.core)
|
32
23
|
try:
|
24
|
+
self._uid = str(uuid.uuid4())
|
25
|
+
self.use_profile = use_profile
|
26
|
+
self.server = PocketServer.get_instance_and_refcnt_up(self._uid)
|
33
27
|
self.server.wait_initialized()
|
28
|
+
self.core = PocketCore(
|
29
|
+
tools=tools,
|
30
|
+
auth=auth,
|
31
|
+
)
|
34
32
|
except Exception as e:
|
33
|
+
if hasattr(self, "server"):
|
34
|
+
self.server.refcnt_down(self._uid)
|
35
35
|
pocket_logger.error(f"Failed to initialize pocket server. error : {e}")
|
36
36
|
self._teardown_server()
|
37
|
+
raise e
|
38
|
+
|
39
|
+
try:
|
40
|
+
asyncio.get_running_loop()
|
41
|
+
except RuntimeError:
|
42
|
+
loop = asyncio.new_event_loop()
|
43
|
+
else:
|
44
|
+
import nest_asyncio
|
45
|
+
loop = asyncio.new_event_loop()
|
46
|
+
nest_asyncio.apply(loop=loop)
|
47
|
+
loop.run_until_complete(self.server.plug_core(self._uid, self.core))
|
37
48
|
|
38
49
|
def invoke(
|
39
50
|
self,
|
@@ -158,8 +169,17 @@ class Pocket(object):
|
|
158
169
|
Returns:
|
159
170
|
tuple[str, bool]: tool result and state.
|
160
171
|
"""
|
172
|
+
_kwargs = {
|
173
|
+
"tool_name": tool_name,
|
174
|
+
"body": body,
|
175
|
+
"thread_id": thread_id,
|
176
|
+
"profile": profile,
|
177
|
+
**kwargs,
|
178
|
+
}
|
179
|
+
|
161
180
|
result, paused = await self.server.call_in_subprocess(
|
162
181
|
PocketServerOperations.CALL,
|
182
|
+
self._uid,
|
163
183
|
args,
|
164
184
|
{
|
165
185
|
"tool_name": tool_name,
|
@@ -257,6 +277,7 @@ class Pocket(object):
|
|
257
277
|
):
|
258
278
|
prepare = await self.server.call_in_subprocess(
|
259
279
|
PocketServerOperations.PREPARE_AUTH,
|
280
|
+
self._uid,
|
260
281
|
args,
|
261
282
|
{
|
262
283
|
"tool_name": tool_name,
|
@@ -278,6 +299,7 @@ class Pocket(object):
|
|
278
299
|
):
|
279
300
|
credentials = await self.server.call_in_subprocess(
|
280
301
|
PocketServerOperations.AUTHENTICATE,
|
302
|
+
self._uid,
|
281
303
|
args,
|
282
304
|
{
|
283
305
|
"tool_name": tool_name,
|
@@ -300,6 +322,7 @@ class Pocket(object):
|
|
300
322
|
):
|
301
323
|
result = await self.server.call_in_subprocess(
|
302
324
|
PocketServerOperations.TOOL_CALL,
|
325
|
+
self._uid,
|
303
326
|
args,
|
304
327
|
{
|
305
328
|
"tool_name": tool_name,
|
@@ -319,12 +342,10 @@ class Pocket(object):
|
|
319
342
|
return self
|
320
343
|
|
321
344
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
322
|
-
|
323
|
-
self.server.teardown()
|
345
|
+
self.server.refcnt_down(self._uid)
|
324
346
|
|
325
347
|
def __del__(self):
|
326
|
-
|
327
|
-
self.server.teardown()
|
348
|
+
self.server.refcnt_down(self._uid)
|
328
349
|
|
329
350
|
def __getstate__(self):
|
330
351
|
state = self.__dict__.copy()
|
@@ -1,5 +1,4 @@
|
|
1
|
-
from hyperpocket.repository.
|
2
|
-
from hyperpocket.repository.
|
3
|
-
from hyperpocket.repository.repository import eject, pull, sync
|
1
|
+
from hyperpocket.repository.tool_reference import ToolReference
|
2
|
+
from hyperpocket.repository.repository import eject, pull
|
4
3
|
|
5
|
-
__all__ = ["
|
4
|
+
__all__ = ["ToolReference", "pull", "eject"]
|
@@ -1,43 +1,8 @@
|
|
1
|
-
|
1
|
+
def pull(urllike: str, git_ref: str):
|
2
|
+
# TODO
|
3
|
+
pass
|
2
4
|
|
3
|
-
from hyperpocket.repository.lock import GitLock, LocalLock
|
4
|
-
from hyperpocket.repository.lockfile import Lockfile
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if path.exists():
|
10
|
-
lockfile.add_lock(LocalLock(tool_path=str(path)))
|
11
|
-
else:
|
12
|
-
lockfile.add_lock(GitLock(repository_url=urllike, git_ref=git_ref))
|
13
|
-
lockfile.sync(force_update=False)
|
14
|
-
lockfile.write()
|
15
|
-
|
16
|
-
|
17
|
-
def sync(lockfile: Lockfile, force_update: bool):
|
18
|
-
lockfile.sync(force_update=force_update)
|
19
|
-
lockfile.write()
|
20
|
-
|
21
|
-
|
22
|
-
def eject(url: str, ref: str, remote_path: str, lockfile: Lockfile):
|
23
|
-
path = pathlib.Path(url)
|
24
|
-
if path.exists():
|
25
|
-
raise ValueError("Local tools are already ejected")
|
26
|
-
else:
|
27
|
-
lock = lockfile.get_lock(GitLock(repository_url=url, git_ref=ref).key())
|
28
|
-
|
29
|
-
# first copy source to ejected directory
|
30
|
-
working_dir = pathlib.Path.cwd()
|
31
|
-
ejected_dir = working_dir / "ejected_tools"
|
32
|
-
if not ejected_dir.exists():
|
33
|
-
ejected_dir.mkdir()
|
34
|
-
|
35
|
-
tool_name = pathlib.Path(remote_path).name
|
36
|
-
eject_path = ejected_dir / tool_name
|
37
|
-
lock.eject_to_path(eject_path, remote_path)
|
38
|
-
|
39
|
-
# then update lockfile
|
40
|
-
lockfile.remove_lock(lock.key())
|
41
|
-
lockfile.add_lock(LocalLock(tool_path=str(eject_path)))
|
42
|
-
lockfile.sync(force_update=True)
|
43
|
-
lockfile.write()
|
6
|
+
def eject(url: str, ref: str, remote_path: str):
|
7
|
+
# TODO
|
8
|
+
pass
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import abc
|
2
|
+
import pathlib
|
3
|
+
|
4
|
+
from pydantic import BaseModel
|
5
|
+
|
6
|
+
|
7
|
+
class ToolReference(BaseModel, abc.ABC):
|
8
|
+
tool_source: str = None
|
9
|
+
|
10
|
+
@abc.abstractmethod
|
11
|
+
def __str__(self):
|
12
|
+
raise NotImplementedError
|
13
|
+
|
14
|
+
@abc.abstractmethod
|
15
|
+
def key(self) -> str:
|
16
|
+
raise NotImplementedError
|
17
|
+
|
18
|
+
@abc.abstractmethod
|
19
|
+
def sync(self, **kwargs):
|
20
|
+
raise NotImplementedError
|
21
|
+
|
22
|
+
def eject_to_path(self, dest_path: pathlib.Path, src_sub_path: str = None):
|
23
|
+
## local locks are already tracked by git
|
24
|
+
raise NotImplementedError
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from fastapi import APIRouter
|
2
|
+
from starlette.responses import HTMLResponse
|
3
|
+
from hyperpocket.futures import FutureStore
|
4
|
+
|
5
|
+
weaviate_auth_router = APIRouter(
|
6
|
+
prefix="/weaviate"
|
7
|
+
)
|
8
|
+
|
9
|
+
|
10
|
+
@weaviate_auth_router.get("/oauth2/callback")
|
11
|
+
async def weaviate_oauth2_callback(state: str, code: str):
|
12
|
+
try:
|
13
|
+
FutureStore.resolve_future(state, code)
|
14
|
+
except ValueError:
|
15
|
+
return HTMLResponse(content="failed")
|
16
|
+
|
17
|
+
return HTMLResponse(content="success")
|
18
|
+
|
19
|
+
|
20
|
+
@weaviate_auth_router.get("/token/callback")
|
21
|
+
async def weaviate_token_callback(state: str, token: str):
|
22
|
+
try:
|
23
|
+
FutureStore.resolve_future(state, token)
|
24
|
+
except ValueError:
|
25
|
+
return HTMLResponse(content="failed")
|
26
|
+
|
27
|
+
return HTMLResponse(content="success")
|