hyperpocket 0.1.9__py3-none-any.whl → 0.2.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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