hyperpocket 0.3.7__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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")
|