hyperpocket 0.1.9__py3-none-any.whl → 0.2.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.
Files changed (92) hide show
  1. hyperpocket/__init__.py +4 -4
  2. hyperpocket/auth/__init__.py +12 -7
  3. hyperpocket/auth/calendly/oauth2_handler.py +24 -17
  4. hyperpocket/auth/calendly/oauth2_schema.py +3 -1
  5. hyperpocket/auth/context.py +2 -1
  6. hyperpocket/auth/github/oauth2_handler.py +13 -8
  7. hyperpocket/auth/github/token_handler.py +27 -21
  8. hyperpocket/auth/google/context.py +1 -3
  9. hyperpocket/auth/google/oauth2_context.py +1 -1
  10. hyperpocket/auth/google/oauth2_handler.py +22 -17
  11. hyperpocket/auth/gumloop/token_context.py +1 -4
  12. hyperpocket/auth/gumloop/token_handler.py +48 -20
  13. hyperpocket/auth/gumloop/token_schema.py +2 -1
  14. hyperpocket/auth/handler.py +21 -6
  15. hyperpocket/auth/linear/token_context.py +2 -5
  16. hyperpocket/auth/linear/token_handler.py +45 -21
  17. hyperpocket/auth/notion/context.py +2 -2
  18. hyperpocket/auth/notion/token_context.py +2 -4
  19. hyperpocket/auth/notion/token_handler.py +45 -21
  20. hyperpocket/auth/notion/token_schema.py +0 -1
  21. hyperpocket/auth/reddit/oauth2_handler.py +9 -10
  22. hyperpocket/auth/reddit/oauth2_schema.py +0 -2
  23. hyperpocket/auth/schema.py +4 -1
  24. hyperpocket/auth/slack/oauth2_context.py +3 -1
  25. hyperpocket/auth/slack/oauth2_handler.py +55 -35
  26. hyperpocket/auth/slack/token_context.py +2 -4
  27. hyperpocket/auth/slack/token_handler.py +42 -19
  28. hyperpocket/builtin.py +4 -2
  29. hyperpocket/cli/__main__.py +4 -2
  30. hyperpocket/cli/auth.py +59 -28
  31. hyperpocket/cli/codegen/auth/auth_context_template.py +3 -2
  32. hyperpocket/cli/codegen/auth/auth_token_context_template.py +3 -2
  33. hyperpocket/cli/codegen/auth/auth_token_handler_template.py +6 -5
  34. hyperpocket/cli/codegen/auth/auth_token_schema_template.py +3 -2
  35. hyperpocket/cli/codegen/auth/server_auth_template.py +3 -2
  36. hyperpocket/cli/pull.py +5 -5
  37. hyperpocket/config/__init__.py +3 -8
  38. hyperpocket/config/auth.py +3 -1
  39. hyperpocket/config/logger.py +20 -15
  40. hyperpocket/config/session.py +4 -2
  41. hyperpocket/config/settings.py +19 -2
  42. hyperpocket/futures/__init__.py +1 -1
  43. hyperpocket/futures/futurestore.py +3 -2
  44. hyperpocket/pocket_auth.py +171 -84
  45. hyperpocket/pocket_core.py +51 -33
  46. hyperpocket/pocket_main.py +122 -93
  47. hyperpocket/prompts.py +2 -2
  48. hyperpocket/repository/__init__.py +1 -1
  49. hyperpocket/repository/lock.py +47 -33
  50. hyperpocket/repository/lockfile.py +2 -2
  51. hyperpocket/repository/repository.py +1 -1
  52. hyperpocket/server/__init__.py +1 -1
  53. hyperpocket/server/auth/github.py +2 -1
  54. hyperpocket/server/auth/linear.py +1 -3
  55. hyperpocket/server/auth/notion.py +2 -5
  56. hyperpocket/server/auth/slack.py +1 -3
  57. hyperpocket/server/auth/token.py +17 -11
  58. hyperpocket/server/proxy.py +29 -13
  59. hyperpocket/server/server.py +75 -31
  60. hyperpocket/server/tool/dto/script.py +15 -10
  61. hyperpocket/server/tool/wasm.py +14 -11
  62. hyperpocket/session/__init__.py +6 -2
  63. hyperpocket/session/in_memory.py +44 -24
  64. hyperpocket/session/interface.py +42 -24
  65. hyperpocket/session/redis.py +48 -31
  66. hyperpocket/tool/__init__.py +10 -10
  67. hyperpocket/tool/function/__init__.py +1 -5
  68. hyperpocket/tool/function/annotation.py +11 -9
  69. hyperpocket/tool/function/tool.py +37 -27
  70. hyperpocket/tool/tool.py +59 -36
  71. hyperpocket/tool/wasm/__init__.py +1 -1
  72. hyperpocket/tool/wasm/browser.py +15 -10
  73. hyperpocket/tool/wasm/invoker.py +16 -16
  74. hyperpocket/tool/wasm/script.py +27 -14
  75. hyperpocket/tool/wasm/templates/__init__.py +22 -15
  76. hyperpocket/tool/wasm/templates/node.py +2 -2
  77. hyperpocket/tool/wasm/templates/python.py +2 -2
  78. hyperpocket/tool/wasm/tool.py +27 -14
  79. hyperpocket/tool_like.py +3 -3
  80. hyperpocket/util/__init__.py +1 -1
  81. hyperpocket/util/extract_func_param_desc_from_docstring.py +33 -14
  82. hyperpocket/util/find_all_leaf_class_in_package.py +4 -3
  83. hyperpocket/util/find_all_subclass_in_package.py +4 -2
  84. hyperpocket/util/flatten_json_schema.py +10 -6
  85. hyperpocket/util/function_to_model.py +33 -12
  86. hyperpocket/util/get_objects_from_subpackage.py +1 -1
  87. hyperpocket/util/json_schema_to_model.py +14 -5
  88. {hyperpocket-0.1.9.dist-info → hyperpocket-0.2.0.dist-info}/METADATA +29 -24
  89. hyperpocket-0.2.0.dist-info/RECORD +137 -0
  90. hyperpocket-0.1.9.dist-info/RECORD +0 -137
  91. {hyperpocket-0.1.9.dist-info → hyperpocket-0.2.0.dist-info}/WHEEL +0 -0
  92. {hyperpocket-0.1.9.dist-info → hyperpocket-0.2.0.dist-info}/entry_points.txt +0 -0
@@ -1,21 +1,26 @@
1
1
  from typing import Optional
2
- from urllib.parse import urljoin, urlencode
2
+ from urllib.parse import urlencode, urljoin
3
3
 
4
4
  from hyperpocket.auth import AuthProvider
5
5
  from hyperpocket.auth.context import AuthContext
6
6
  from hyperpocket.auth.handler import AuthHandlerInterface
7
7
  from hyperpocket.auth.linear.token_context import LinearTokenAuthContext
8
- from hyperpocket.auth.linear.token_schema import LinearTokenResponse, LinearTokenRequest
8
+ from hyperpocket.auth.linear.token_schema import LinearTokenRequest, LinearTokenResponse
9
9
  from hyperpocket.config import config
10
10
  from hyperpocket.futures import FutureStore
11
11
 
12
12
 
13
13
  class LinearTokenAuthHandler(AuthHandlerInterface):
14
14
  name: str = "linear-token"
15
- description: str = "This handler is used to authenticate users using the Linear token."
15
+ description: str = (
16
+ "This handler is used to authenticate users using the Linear token."
17
+ )
16
18
  scoped: bool = False
17
19
 
18
- _TOKEN_URL: str = urljoin(config.public_base_url + "/", f"{config.callback_url_rewrite_prefix}/auth/token")
20
+ _TOKEN_URL: str = urljoin(
21
+ config().public_base_url + "/",
22
+ f"{config().callback_url_rewrite_prefix}/auth/token",
23
+ )
19
24
 
20
25
  @staticmethod
21
26
  def provider() -> AuthProvider:
@@ -29,24 +34,37 @@ class LinearTokenAuthHandler(AuthHandlerInterface):
29
34
  def recommended_scopes() -> set[str]:
30
35
  return set()
31
36
 
32
- def prepare(self, auth_req: LinearTokenRequest, thread_id: str, profile: str,
33
- future_uid: str, *args, **kwargs) -> str:
37
+ def prepare(
38
+ self,
39
+ auth_req: LinearTokenRequest,
40
+ thread_id: str,
41
+ profile: str,
42
+ future_uid: str,
43
+ *args,
44
+ **kwargs,
45
+ ) -> str:
34
46
  redirect_uri = urljoin(
35
- config.public_base_url + "/",
36
- f"{config.callback_url_rewrite_prefix}/auth/linear/token/callback",
47
+ config().public_base_url + "/",
48
+ f"{config().callback_url_rewrite_prefix}/auth/linear/token/callback",
49
+ )
50
+ auth_url = self._make_auth_url(
51
+ auth_req=auth_req, redirect_uri=redirect_uri, state=future_uid
52
+ )
53
+ FutureStore.create_future(
54
+ future_uid,
55
+ data={
56
+ "redirect_uri": redirect_uri,
57
+ "thread_id": thread_id,
58
+ "profile": profile,
59
+ },
37
60
  )
38
- auth_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
61
 
45
- return f'User needs to authenticate using the following URL: {auth_url}'
62
+ return f"User needs to authenticate using the following URL: {auth_url}"
46
63
 
47
- async def authenticate(self, auth_req: LinearTokenResponse, future_uid: str, *args,
48
- **kwargs) -> LinearTokenAuthContext:
49
- future_data = FutureStore.get_future( future_uid)
64
+ async def authenticate(
65
+ self, auth_req: LinearTokenResponse, future_uid: str, *args, **kwargs
66
+ ) -> LinearTokenAuthContext:
67
+ future_data = FutureStore.get_future(future_uid)
50
68
  access_token = await future_data.future
51
69
 
52
70
  response = LinearTokenResponse(access_token=access_token)
@@ -54,15 +72,21 @@ class LinearTokenAuthHandler(AuthHandlerInterface):
54
72
 
55
73
  return context
56
74
 
57
- async def refresh(self, auth_req: LinearTokenRequest, context: AuthContext, *args, **kwargs) -> AuthContext:
75
+ async def refresh(
76
+ self, auth_req: LinearTokenRequest, context: AuthContext, *args, **kwargs
77
+ ) -> AuthContext:
58
78
  raise Exception("Linear token doesn't support refresh")
59
79
 
60
- def _make_auth_url(self, auth_req: LinearTokenRequest, redirect_uri: str, state: str):
80
+ def _make_auth_url(
81
+ self, auth_req: LinearTokenRequest, redirect_uri: str, state: str
82
+ ):
61
83
  params = {
62
84
  "redirect_uri": redirect_uri,
63
85
  "state": state,
64
86
  }
65
87
  return f"{self._TOKEN_URL}?{urlencode(params)}"
66
88
 
67
- def make_request(self, auth_scopes: Optional[list[str]] = None, **kwargs) -> LinearTokenRequest:
89
+ def make_request(
90
+ self, auth_scopes: Optional[list[str]] = None, **kwargs
91
+ ) -> LinearTokenRequest:
68
92
  return LinearTokenRequest()
@@ -1,6 +1,6 @@
1
-
2
1
  from hyperpocket.auth.context import AuthContext
3
2
 
3
+
4
4
  class NotionAuthContext(AuthContext):
5
5
  _ACCESS_TOKEN_KEY: str = "NOTION_TOKEN"
6
6
 
@@ -12,4 +12,4 @@ class NotionAuthContext(AuthContext):
12
12
  def to_profiled_dict(self, profile: str) -> dict[str, str]:
13
13
  return {
14
14
  f"{profile.upper()}_{self._ACCESS_TOKEN_KEY}": self.access_token,
15
- }
15
+ }
@@ -5,10 +5,8 @@ from hyperpocket.auth.notion.token_schema import NotionTokenResponse
5
5
  class NotionTokenAuthContext(NotionAuthContext):
6
6
  @classmethod
7
7
  def from_notion_token_response(cls, response: NotionTokenResponse):
8
- description = 'Notion Token Context logged in'
8
+ description = "Notion Token Context logged in"
9
9
 
10
10
  return cls(
11
- access_token=response.access_token,
12
- description=description,
13
- expires_at=None
11
+ access_token=response.access_token, description=description, expires_at=None
14
12
  )
@@ -1,22 +1,26 @@
1
-
2
1
  from typing import Optional
3
- from urllib.parse import urljoin, urlencode
2
+ from urllib.parse import urlencode, urljoin
4
3
 
5
4
  from hyperpocket.auth import AuthProvider
6
5
  from hyperpocket.auth.context import AuthContext
7
6
  from hyperpocket.auth.handler import AuthHandlerInterface
8
7
  from hyperpocket.auth.notion.token_context import NotionTokenAuthContext
9
- from hyperpocket.auth.notion.token_schema import NotionTokenResponse, NotionTokenRequest
8
+ from hyperpocket.auth.notion.token_schema import NotionTokenRequest, NotionTokenResponse
10
9
  from hyperpocket.config import config
11
10
  from hyperpocket.futures import FutureStore
12
11
 
13
12
 
14
13
  class NotionTokenAuthHandler(AuthHandlerInterface):
15
14
  name: str = "notion-token"
16
- description: str = "This handler is used to authenticate users using the Notion token."
15
+ description: str = (
16
+ "This handler is used to authenticate users using the Notion token."
17
+ )
17
18
  scoped: bool = False
18
19
 
19
- _TOKEN_URL: str = urljoin(config.public_base_url + "/", f"{config.callback_url_rewrite_prefix}/auth/token")
20
+ _TOKEN_URL: str = urljoin(
21
+ config().public_base_url + "/",
22
+ f"{config().callback_url_rewrite_prefix}/auth/token",
23
+ )
20
24
 
21
25
  @staticmethod
22
26
  def provider() -> AuthProvider:
@@ -26,22 +30,36 @@ class NotionTokenAuthHandler(AuthHandlerInterface):
26
30
  def recommended_scopes() -> set[str]:
27
31
  return set()
28
32
 
29
- def prepare(self, auth_req: NotionTokenRequest, thread_id: str, profile: str,
30
- future_uid: str, *args, **kwargs) -> str:
33
+ def prepare(
34
+ self,
35
+ auth_req: NotionTokenRequest,
36
+ thread_id: str,
37
+ profile: str,
38
+ future_uid: str,
39
+ *args,
40
+ **kwargs,
41
+ ) -> str:
31
42
  redirect_uri = urljoin(
32
- config.public_base_url + "/",
33
- f"{config.callback_url_rewrite_prefix}/auth/notion/token/callback",
43
+ config().public_base_url + "/",
44
+ f"{config().callback_url_rewrite_prefix}/auth/notion/token/callback",
45
+ )
46
+ url = self._make_auth_url(
47
+ auth_req=auth_req, redirect_uri=redirect_uri, state=future_uid
48
+ )
49
+ FutureStore.create_future(
50
+ future_uid,
51
+ data={
52
+ "redirect_uri": redirect_uri,
53
+ "thread_id": thread_id,
54
+ "profile": profile,
55
+ },
34
56
  )
35
- url = self._make_auth_url(auth_req=auth_req, redirect_uri=redirect_uri, state=future_uid)
36
- FutureStore.create_future(future_uid, data={
37
- "redirect_uri": redirect_uri,
38
- "thread_id": thread_id,
39
- "profile": profile,
40
- })
41
57
 
42
- return f'User needs to authenticate using the following URL: {url}'
58
+ return f"User needs to authenticate using the following URL: {url}"
43
59
 
44
- async def authenticate(self, auth_req: NotionTokenRequest, future_uid: str, *args, **kwargs) -> AuthContext:
60
+ async def authenticate(
61
+ self, auth_req: NotionTokenRequest, future_uid: str, *args, **kwargs
62
+ ) -> AuthContext:
45
63
  future_data = FutureStore.get_future(future_uid)
46
64
  access_token = await future_data.future
47
65
 
@@ -50,10 +68,14 @@ class NotionTokenAuthHandler(AuthHandlerInterface):
50
68
 
51
69
  return context
52
70
 
53
- async def refresh(self, auth_req: NotionTokenRequest, context: AuthContext, *args, **kwargs) -> AuthContext:
71
+ async def refresh(
72
+ self, auth_req: NotionTokenRequest, context: AuthContext, *args, **kwargs
73
+ ) -> AuthContext:
54
74
  raise Exception("Notion token doesn't support refresh")
55
75
 
56
- def _make_auth_url(self, auth_req: NotionTokenRequest, redirect_uri: str, state: str):
76
+ def _make_auth_url(
77
+ self, auth_req: NotionTokenRequest, redirect_uri: str, state: str
78
+ ):
57
79
  params = {
58
80
  "redirect_uri": redirect_uri,
59
81
  "state": state,
@@ -61,5 +83,7 @@ class NotionTokenAuthHandler(AuthHandlerInterface):
61
83
  auth_url = f"{self._TOKEN_URL}?{urlencode(params)}"
62
84
  return auth_url
63
85
 
64
- def make_request(self, auth_scopes: Optional[list[str]] = None, **kwargs) -> NotionTokenRequest:
65
- return NotionTokenRequest()
86
+ def make_request(
87
+ self, auth_scopes: Optional[list[str]] = None, **kwargs
88
+ ) -> NotionTokenRequest:
89
+ return NotionTokenRequest()
@@ -1,4 +1,3 @@
1
-
2
1
  from hyperpocket.auth.schema import AuthenticateRequest, AuthenticateResponse
3
2
 
4
3
 
@@ -1,7 +1,6 @@
1
1
  import base64
2
- from os import access
3
2
  from typing import Optional
4
- from urllib.parse import urljoin, urlencode
3
+ from urllib.parse import urlencode, urljoin
5
4
 
6
5
  import httpx
7
6
 
@@ -10,8 +9,8 @@ from hyperpocket.auth.context import AuthContext
10
9
  from hyperpocket.auth.handler import AuthHandlerInterface
11
10
  from hyperpocket.auth.reddit.oauth2_context import RedditOAuth2AuthContext
12
11
  from hyperpocket.auth.reddit.oauth2_schema import (
13
- RedditOAuth2Response,
14
12
  RedditOAuth2Request,
13
+ RedditOAuth2Response,
15
14
  )
16
15
  from hyperpocket.config import config as config
17
16
  from hyperpocket.futures import FutureStore
@@ -35,7 +34,7 @@ class RedditOAuth2AuthHandler(AuthHandlerInterface):
35
34
 
36
35
  @staticmethod
37
36
  def recommended_scopes() -> set[str]:
38
- if config.auth.reddit.use_recommended_scope:
37
+ if config().auth.reddit.use_recommended_scope:
39
38
  recommended_scopes = {"account", "identity", "read"}
40
39
  else:
41
40
  recommended_scopes = {}
@@ -51,8 +50,8 @@ class RedditOAuth2AuthHandler(AuthHandlerInterface):
51
50
  **kwargs,
52
51
  ) -> str:
53
52
  redirect_uri = urljoin(
54
- config.public_base_url + "/",
55
- f"{config.callback_url_rewrite_prefix}/auth/reddit/oauth2/callback",
53
+ config().public_base_url + "/",
54
+ f"{config().callback_url_rewrite_prefix}/auth/reddit/oauth2/callback",
56
55
  )
57
56
  print(f"redirect_uri: {redirect_uri}")
58
57
  auth_url = self._make_auth_url(
@@ -108,8 +107,8 @@ class RedditOAuth2AuthHandler(AuthHandlerInterface):
108
107
  resp = await client.post(
109
108
  url=self._REDDIT_TOKEN_URL,
110
109
  data={
111
- "client_id": config.auth.reddit.client_id,
112
- "client_secret": config.auth.reddit.client_secret,
110
+ "client_id": config().auth.reddit.client_id,
111
+ "client_secret": config().auth.reddit.client_secret,
113
112
  "grant_type": "refresh_token",
114
113
  "refresh_token": refresh_token,
115
114
  },
@@ -146,6 +145,6 @@ class RedditOAuth2AuthHandler(AuthHandlerInterface):
146
145
  ) -> RedditOAuth2Request:
147
146
  return RedditOAuth2Request(
148
147
  auth_scopes=auth_scopes,
149
- client_id=config.auth.reddit.client_id,
150
- client_secret=config.auth.reddit.client_secret,
148
+ client_id=config().auth.reddit.client_id,
149
+ client_secret=config().auth.reddit.client_secret,
151
150
  )
@@ -1,7 +1,5 @@
1
1
  from typing import Optional
2
2
 
3
- from pydantic import BaseModel
4
-
5
3
  from hyperpocket.auth.schema import AuthenticateRequest, AuthenticateResponse
6
4
 
7
5
 
@@ -7,13 +7,16 @@ class AuthenticateRequest(BaseModel):
7
7
  """
8
8
  This class is used to define the interface of the authentication request.
9
9
  """
10
+
10
11
  auth_scopes: Optional[list[str]] = Field(
11
12
  default_factory=list,
12
- description="authentication scopes. if the authentication handler is non scoped, it isn't needed")
13
+ description="authentication scopes. if the authentication handler is non scoped, it isn't needed",
14
+ )
13
15
 
14
16
 
15
17
  class AuthenticateResponse(BaseModel):
16
18
  """
17
19
  This class is used to define the interface of the authentication response.
18
20
  """
21
+
19
22
  pass
@@ -12,7 +12,9 @@ class SlackOAuth2AuthContext(SlackAuthContext):
12
12
 
13
13
  @classmethod
14
14
  def from_slack_oauth2_response(cls, response: SlackOAuth2Response):
15
- description = f'Slack OAuth2 Context logged in as a user {response.authed_user.id}'
15
+ description = (
16
+ f"Slack OAuth2 Context logged in as a user {response.authed_user.id}"
17
+ )
16
18
  now = datetime.now(tz=timezone.utc)
17
19
 
18
20
  # user token
@@ -1,5 +1,5 @@
1
1
  from typing import Optional
2
- from urllib.parse import urljoin, urlencode
2
+ from urllib.parse import urlencode, urljoin
3
3
 
4
4
  import httpx
5
5
 
@@ -7,7 +7,7 @@ from hyperpocket.auth import AuthProvider
7
7
  from hyperpocket.auth.context import AuthContext
8
8
  from hyperpocket.auth.handler import AuthHandlerInterface
9
9
  from hyperpocket.auth.slack.oauth2_context import SlackOAuth2AuthContext
10
- from hyperpocket.auth.slack.oauth2_schema import SlackOAuth2Response, SlackOAuth2Request
10
+ from hyperpocket.auth.slack.oauth2_schema import SlackOAuth2Request, SlackOAuth2Response
11
11
  from hyperpocket.config import config as config
12
12
  from hyperpocket.futures import FutureStore
13
13
 
@@ -30,7 +30,7 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
30
30
 
31
31
  @staticmethod
32
32
  def recommended_scopes() -> set[str]:
33
- if config.auth.slack.use_recommended_scope:
33
+ if config().auth.slack.use_recommended_scope:
34
34
  recommended_scopes = {
35
35
  "channels:history",
36
36
  "channels:read",
@@ -46,24 +46,38 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
46
46
  recommended_scopes = {}
47
47
  return recommended_scopes
48
48
 
49
- def prepare(self, auth_req: SlackOAuth2Request, thread_id: str, profile: str,
50
- future_uid: str, *args, **kwargs) -> str:
49
+ def prepare(
50
+ self,
51
+ auth_req: SlackOAuth2Request,
52
+ thread_id: str,
53
+ profile: str,
54
+ future_uid: str,
55
+ *args,
56
+ **kwargs,
57
+ ) -> str:
51
58
  redirect_uri = urljoin(
52
- config.public_base_url + "/",
53
- f"{config.callback_url_rewrite_prefix}/auth/slack/oauth2/callback",
59
+ config().public_base_url + "/",
60
+ f"{config().callback_url_rewrite_prefix}/auth/slack/oauth2/callback",
54
61
  )
55
62
  print(f"redirect_uri: {redirect_uri}")
56
- auth_url = self._make_auth_url(req=auth_req, redirect_uri=redirect_uri, state=future_uid)
63
+ auth_url = self._make_auth_url(
64
+ req=auth_req, redirect_uri=redirect_uri, state=future_uid
65
+ )
57
66
 
58
- FutureStore.create_future(future_uid, data={
59
- "redirect_uri": redirect_uri,
60
- "thread_id": thread_id,
61
- "profile": profile,
62
- })
67
+ FutureStore.create_future(
68
+ future_uid,
69
+ data={
70
+ "redirect_uri": redirect_uri,
71
+ "thread_id": thread_id,
72
+ "profile": profile,
73
+ },
74
+ )
63
75
 
64
- return f'User needs to authenticate using the following URL: {auth_url}'
76
+ return f"User needs to authenticate using the following URL: {auth_url}"
65
77
 
66
- async def authenticate(self, auth_req: SlackOAuth2Request, future_uid: str, *args, **kwargs) -> AuthContext:
78
+ async def authenticate(
79
+ self, auth_req: SlackOAuth2Request, future_uid: str, *args, **kwargs
80
+ ) -> AuthContext:
67
81
  future_data = FutureStore.get_future(future_uid)
68
82
  auth_code = await future_data.future
69
83
 
@@ -71,11 +85,11 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
71
85
  resp = await client.post(
72
86
  url=self._SLACK_TOKEN_URL,
73
87
  data={
74
- 'client_id': auth_req.client_id,
75
- 'client_secret': auth_req.client_secret,
76
- 'code': auth_code,
77
- 'redirect_uri': future_data.data["redirect_uri"],
78
- }
88
+ "client_id": auth_req.client_id,
89
+ "client_secret": auth_req.client_secret,
90
+ "code": auth_code,
91
+ "redirect_uri": future_data.data["redirect_uri"],
92
+ },
79
93
  )
80
94
  if resp.status_code != 200:
81
95
  raise Exception(f"failed to authenticate. status_code : {resp.status_code}")
@@ -87,7 +101,9 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
87
101
  resp_typed = SlackOAuth2Response(**resp_json)
88
102
  return SlackOAuth2AuthContext.from_slack_oauth2_response(resp_typed)
89
103
 
90
- async def refresh(self, auth_req: SlackOAuth2Request, context: AuthContext, *args, **kwargs) -> AuthContext:
104
+ async def refresh(
105
+ self, auth_req: SlackOAuth2Request, context: AuthContext, *args, **kwargs
106
+ ) -> AuthContext:
91
107
  slack_context: SlackOAuth2AuthContext = context
92
108
  last_oauth2_resp: SlackOAuth2Response = slack_context.detail
93
109
  refresh_token = slack_context.refresh_token
@@ -96,10 +112,10 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
96
112
  resp = await client.post(
97
113
  url=self._SLACK_TOKEN_URL,
98
114
  data={
99
- 'client_id': config.auth.slack.client_id,
100
- 'client_secret': config.auth.slack.client_secret,
101
- 'grant_type': 'refresh_token',
102
- 'refresh_token': refresh_token,
115
+ "client_id": config().auth.slack.client_id,
116
+ "client_secret": config().auth.slack.client_secret,
117
+ "grant_type": "refresh_token",
118
+ "refresh_token": refresh_token,
103
119
  },
104
120
  )
105
121
 
@@ -113,12 +129,14 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
113
129
  if last_oauth2_resp.authed_user:
114
130
  new_resp = last_oauth2_resp.model_copy(
115
131
  update={
116
- "authed_user": SlackOAuth2Response.AuthedUser(**{
117
- **last_oauth2_resp.authed_user.model_dump(),
118
- "access_token": resp_json["access_token"],
119
- "refresh_token": resp_json["refresh_token"],
120
- "expires_in": resp_json["expires_in"],
121
- })
132
+ "authed_user": SlackOAuth2Response.AuthedUser(
133
+ **{
134
+ **last_oauth2_resp.authed_user.model_dump(),
135
+ "access_token": resp_json["access_token"],
136
+ "refresh_token": resp_json["refresh_token"],
137
+ "expires_in": resp_json["expires_in"],
138
+ }
139
+ )
122
140
  }
123
141
  )
124
142
  else:
@@ -135,7 +153,7 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
135
153
 
136
154
  def _make_auth_url(self, req: SlackOAuth2Request, redirect_uri: str, state: str):
137
155
  params = {
138
- "user_scope": ','.join(req.auth_scopes),
156
+ "user_scope": ",".join(req.auth_scopes),
139
157
  "client_id": req.client_id,
140
158
  "redirect_uri": redirect_uri,
141
159
  "state": state,
@@ -143,9 +161,11 @@ class SlackOAuth2AuthHandler(AuthHandlerInterface):
143
161
  auth_url = f"{self._SLACK_OAUTH_URL}?{urlencode(params)}"
144
162
  return auth_url
145
163
 
146
- def make_request(self, auth_scopes: Optional[list[str]] = None, **kwargs) -> SlackOAuth2Request:
164
+ def make_request(
165
+ self, auth_scopes: Optional[list[str]] = None, **kwargs
166
+ ) -> SlackOAuth2Request:
147
167
  return SlackOAuth2Request(
148
168
  auth_scopes=auth_scopes,
149
- client_id=config.auth.slack.client_id,
150
- client_secret=config.auth.slack.client_secret,
169
+ client_id=config().auth.slack.client_id,
170
+ client_secret=config().auth.slack.client_secret,
151
171
  )
@@ -5,10 +5,8 @@ from hyperpocket.auth.slack.token_schema import SlackTokenResponse
5
5
  class SlackTokenAuthContext(SlackAuthContext):
6
6
  @classmethod
7
7
  def from_slack_token_response(cls, response: SlackTokenResponse):
8
- description = 'Slack Token Context logged in'
8
+ description = "Slack Token Context logged in"
9
9
 
10
10
  return cls(
11
- access_token=response.access_token,
12
- description=description,
13
- expires_at=None
11
+ access_token=response.access_token, description=description, expires_at=None
14
12
  )
@@ -1,21 +1,26 @@
1
1
  from typing import Optional
2
- from urllib.parse import urljoin, urlencode
2
+ from urllib.parse import urlencode, urljoin
3
3
 
4
4
  from hyperpocket.auth import AuthProvider
5
5
  from hyperpocket.auth.context import AuthContext
6
6
  from hyperpocket.auth.handler import AuthHandlerInterface
7
7
  from hyperpocket.auth.slack.token_context import SlackTokenAuthContext
8
- from hyperpocket.auth.slack.token_schema import SlackTokenResponse, SlackTokenRequest
8
+ from hyperpocket.auth.slack.token_schema import SlackTokenRequest, SlackTokenResponse
9
9
  from hyperpocket.config import config
10
10
  from hyperpocket.futures import FutureStore
11
11
 
12
12
 
13
13
  class SlackTokenAuthHandler(AuthHandlerInterface):
14
14
  name: str = "slack-token"
15
- description: str = "This handler is used to authenticate users using the Slack token."
15
+ description: str = (
16
+ "This handler is used to authenticate users using the Slack token."
17
+ )
16
18
  scoped: bool = False
17
19
 
18
- _TOKEN_URL: str = urljoin(config.public_base_url + "/", f"{config.callback_url_rewrite_prefix}/auth/token")
20
+ _TOKEN_URL: str = urljoin(
21
+ config().public_base_url + "/",
22
+ f"{config().callback_url_rewrite_prefix}/auth/token",
23
+ )
19
24
 
20
25
  @staticmethod
21
26
  def provider() -> AuthProvider:
@@ -25,23 +30,37 @@ class SlackTokenAuthHandler(AuthHandlerInterface):
25
30
  def recommended_scopes() -> set[str]:
26
31
  return set()
27
32
 
28
- def prepare(self, auth_req: SlackTokenRequest, thread_id: str, profile: str,
29
- future_uid: str, *args, **kwargs) -> str:
33
+ def prepare(
34
+ self,
35
+ auth_req: SlackTokenRequest,
36
+ thread_id: str,
37
+ profile: str,
38
+ future_uid: str,
39
+ *args,
40
+ **kwargs,
41
+ ) -> str:
30
42
  redirect_uri = urljoin(
31
- config.public_base_url + "/",
32
- f"{config.callback_url_rewrite_prefix}/auth/slack/token/callback",
43
+ config().public_base_url + "/",
44
+ f"{config().callback_url_rewrite_prefix}/auth/slack/token/callback",
45
+ )
46
+ url = self._make_auth_url(
47
+ req=auth_req, redirect_uri=redirect_uri, state=future_uid
48
+ )
49
+ FutureStore.create_future(
50
+ future_uid,
51
+ data={
52
+ "redirect_uri": redirect_uri,
53
+ "thread_id": thread_id,
54
+ "profile": profile,
55
+ },
33
56
  )
34
- url = self._make_auth_url(req=auth_req, redirect_uri=redirect_uri, state=future_uid)
35
- FutureStore.create_future(future_uid, data={
36
- "redirect_uri": redirect_uri,
37
- "thread_id": thread_id,
38
- "profile": profile,
39
- })
40
57
 
41
- return f'User needs to authenticate using the following URL: {url}'
58
+ return f"User needs to authenticate using the following URL: {url}"
42
59
 
43
- async def authenticate(self, auth_req: SlackTokenRequest, future_uid: str, *args, **kwargs) -> AuthContext:
44
- future_data = FutureStore.get_future( future_uid)
60
+ async def authenticate(
61
+ self, auth_req: SlackTokenRequest, future_uid: str, *args, **kwargs
62
+ ) -> AuthContext:
63
+ future_data = FutureStore.get_future(future_uid)
45
64
  access_token = await future_data.future
46
65
 
47
66
  response = SlackTokenResponse(access_token=access_token)
@@ -49,7 +68,9 @@ class SlackTokenAuthHandler(AuthHandlerInterface):
49
68
 
50
69
  return context
51
70
 
52
- async def refresh(self, auth_req: SlackTokenRequest, context: AuthContext, *args, **kwargs) -> AuthContext:
71
+ async def refresh(
72
+ self, auth_req: SlackTokenRequest, context: AuthContext, *args, **kwargs
73
+ ) -> AuthContext:
53
74
  raise Exception("Slack token doesn't support refresh")
54
75
 
55
76
  def _make_auth_url(self, req: SlackTokenRequest, redirect_uri: str, state: str):
@@ -60,5 +81,7 @@ class SlackTokenAuthHandler(AuthHandlerInterface):
60
81
  auth_url = f"{self._TOKEN_URL}?{urlencode(params)}"
61
82
  return auth_url
62
83
 
63
- def make_request(self, auth_scopes: Optional[list[str]] = None, **kwargs) -> SlackTokenRequest:
84
+ def make_request(
85
+ self, auth_scopes: Optional[list[str]] = None, **kwargs
86
+ ) -> SlackTokenRequest:
64
87
  return SlackTokenRequest()
hyperpocket/builtin.py CHANGED
@@ -2,7 +2,7 @@ from typing import List
2
2
 
3
3
  from hyperpocket.auth import AuthProvider
4
4
  from hyperpocket.pocket_auth import PocketAuth
5
- from hyperpocket.tool import from_func, Tool
5
+ from hyperpocket.tool import Tool, from_func
6
6
 
7
7
 
8
8
  def get_builtin_tools(pocket_auth: PocketAuth) -> List[Tool]:
@@ -34,7 +34,9 @@ def get_builtin_tools(pocket_auth: PocketAuth) -> List[Tool]:
34
34
  session_list = pocket_auth.list_session_state(thread_id)
35
35
  return str(session_list)
36
36
 
37
- def __delete_session(auth_provider_name: str, thread_id: str = "default", profile: str = "default") -> str:
37
+ def __delete_session(
38
+ auth_provider_name: str, thread_id: str = "default", profile: str = "default"
39
+ ) -> str:
38
40
  """
39
41
  This tool deletes a saved session for a specified authentication provider in the given thread and profile.
40
42