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.
Files changed (45) hide show
  1. hyperpocket/auth/provider.py +1 -0
  2. hyperpocket/auth/weaviate/context.py +12 -0
  3. hyperpocket/auth/weaviate/token_context.py +11 -0
  4. hyperpocket/auth/weaviate/token_handler.py +68 -0
  5. hyperpocket/auth/weaviate/token_schema.py +7 -0
  6. hyperpocket/cli/eject.py +2 -7
  7. hyperpocket/cli/pull.py +2 -7
  8. hyperpocket/config/settings.py +2 -1
  9. hyperpocket/pocket_core.py +41 -68
  10. hyperpocket/pocket_main.py +37 -16
  11. hyperpocket/repository/__init__.py +3 -4
  12. hyperpocket/repository/repository.py +6 -41
  13. hyperpocket/repository/tool_reference.py +28 -0
  14. hyperpocket/server/auth/weaviate.py +27 -0
  15. hyperpocket/server/server.py +127 -61
  16. hyperpocket/session/in_memory.py +13 -3
  17. hyperpocket/tool/__init__.py +0 -3
  18. hyperpocket/tool/dock/__init__.py +3 -0
  19. hyperpocket/tool/dock/dock.py +34 -0
  20. hyperpocket/tool/function/__init__.py +1 -1
  21. hyperpocket/tool/function/tool.py +62 -32
  22. hyperpocket/tool/tool.py +1 -9
  23. hyperpocket/tool_like.py +2 -1
  24. hyperpocket/util/generate_slug.py +4 -0
  25. hyperpocket/util/json_schema_to_model.py +5 -1
  26. {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.0.dist-info}/METADATA +4 -1
  27. {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.0.dist-info}/RECORD +30 -36
  28. hyperpocket/cli/sync.py +0 -17
  29. hyperpocket/repository/lock.py +0 -240
  30. hyperpocket/repository/lockfile.py +0 -62
  31. hyperpocket/server/tool/__init__.py +0 -10
  32. hyperpocket/server/tool/dto/script.py +0 -33
  33. hyperpocket/server/tool/wasm.py +0 -46
  34. hyperpocket/tool/wasm/README.md +0 -166
  35. hyperpocket/tool/wasm/__init__.py +0 -3
  36. hyperpocket/tool/wasm/browser.py +0 -63
  37. hyperpocket/tool/wasm/invoker.py +0 -41
  38. hyperpocket/tool/wasm/script.py +0 -134
  39. hyperpocket/tool/wasm/templates/__init__.py +0 -35
  40. hyperpocket/tool/wasm/templates/node.py +0 -87
  41. hyperpocket/tool/wasm/templates/python.py +0 -93
  42. hyperpocket/tool/wasm/tool.py +0 -163
  43. /hyperpocket/{server/tool/dto → auth/weaviate}/__init__.py +0 -0
  44. {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.0.dist-info}/WHEEL +0 -0
  45. {hyperpocket-0.3.7.dist-info → hyperpocket-0.4.0.dist-info}/entry_points.txt +0 -0
@@ -72,6 +72,7 @@ class AuthProvider(Enum):
72
72
  APITOKEN = "apitoken"
73
73
  ZINC = "zinc"
74
74
  SEMANTIC_SCHOLAR = "semantic_scholar"
75
+ WEAVIATE = "weaviate"
75
76
 
76
77
  @classmethod
77
78
  def get_auth_provider(cls, auth_provider_name: str) -> "AuthProvider":
@@ -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
- @click.option("--lockfile", envvar="PATHS", type=click.Path(exists=True))
14
- def eject(url: str, ref: str, remote_path: str, lockfile: Optional[pathlib.Path]):
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, lockfile: Optional[pathlib.Path], git_ref: str):
14
- if not lockfile:
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)
@@ -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):
@@ -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.repository import Lockfile
9
- from hyperpocket.repository.lock import GitLock, LocalLock
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
- lockfile: Lockfile
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
- # init lockfile
34
- if lockfile_path is None:
35
- lockfile_path = "./pocket.lock"
36
- lockfile_pathlib_path = pathlib.Path(lockfile_path)
37
- self.lockfile = Lockfile(lockfile_pathlib_path)
38
-
39
- # parse tool_likes and add lock of the tool like to the lockfile
40
- tool_likes = []
41
- for tool_like in tools:
42
- parsed_tool_like = self._parse_tool_like(tool_like)
43
- tool_likes.append(parsed_tool_like)
44
- self._add_tool_like_lock_to_lockfile(parsed_tool_like)
45
- self.lockfile.sync(force_update=force_update, referenced_only=True)
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
- for tool_like in tool_likes:
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
@@ -1,5 +1,6 @@
1
1
  import asyncio
2
- from typing import Any, List, Optional, Union
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
- if self.__dict__.get("server"):
323
- self.server.teardown()
345
+ self.server.refcnt_down(self._uid)
324
346
 
325
347
  def __del__(self):
326
- if self.__dict__.get("server"):
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.lock import Lock
2
- from hyperpocket.repository.lockfile import Lockfile
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__ = ["Lock", "Lockfile", "pull", "sync", "eject"]
4
+ __all__ = ["ToolReference", "pull", "eject"]
@@ -1,43 +1,8 @@
1
- import pathlib
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
- def pull(lockfile: Lockfile, urllike: str, git_ref: str):
8
- path = pathlib.Path(urllike)
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")