hyperpocket 0.3.3__py3-none-any.whl → 0.3.4__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ ### API Token Auth
2
+
3
+ This module provides authentication using simple API tokens.
4
+
5
+ 1. To use this authentication in your tool, include the following in your `config.toml`:
6
+
7
+ ```toml
8
+ [auth]
9
+ auth_provider = "apitoken"
10
+ auth_handler = "apitoken"
11
+ scopes = []
12
+ ```
13
+
14
+ 2. To use it with `function_tool`, you can define your function as follows:
15
+
16
+ ```python
17
+ from hyperpocket.tool import function_tool
18
+ from hyperpocket.auth import AuthProvider
19
+
20
+
21
+ @function_tool(
22
+ auth_provider=AuthProvider.API_TOKEN
23
+ )
24
+ def my_function(**kwargs):
25
+ token = kwargs["API_TOKEN"]
26
+
27
+ # ...
28
+ ```
File without changes
@@ -0,0 +1,15 @@
1
+ from hyperpocket.auth.context import AuthContext
2
+
3
+
4
+ class ApiTokenAuthContext(AuthContext):
5
+ _ACCESS_TOKEN_KEY: str = "API_TOKEN"
6
+
7
+ def to_dict(self) -> dict[str, str]:
8
+ return {
9
+ self._ACCESS_TOKEN_KEY: self.access_token,
10
+ }
11
+
12
+ def to_profiled_dict(self, profile: str) -> dict[str, str]:
13
+ return {
14
+ f"{profile.upper()}_{self._ACCESS_TOKEN_KEY}": self.access_token,
15
+ }
@@ -0,0 +1,12 @@
1
+ from hyperpocket.auth.apitoken.context import ApiTokenAuthContext
2
+ from hyperpocket.auth.apitoken.token_schema import ApiTokenResponse
3
+
4
+
5
+ class ApiTokenAuthContext(ApiTokenAuthContext):
6
+ @classmethod
7
+ def from_api_token_response(cls, response: ApiTokenResponse):
8
+ description = "Api Token Context logged in"
9
+
10
+ return cls(
11
+ access_token=response.access_token, description=description, expires_at=None
12
+ )
@@ -0,0 +1,89 @@
1
+ from typing import Optional
2
+ from urllib.parse import urlencode, urljoin
3
+
4
+ from hyperpocket.auth import AuthProvider
5
+ from hyperpocket.auth.context import AuthContext
6
+ from hyperpocket.auth.handler import AuthHandlerInterface
7
+ from hyperpocket.auth.apitoken.token_context import ApiTokenAuthContext
8
+ from hyperpocket.auth.apitoken.token_schema import ApiTokenRequest, ApiTokenResponse
9
+ from hyperpocket.config import config
10
+ from hyperpocket.futures import FutureStore
11
+
12
+
13
+ class ApiTokenAuthHandler(AuthHandlerInterface):
14
+ name: str = "apitoken"
15
+ description: str = "This handler is used to authenticate users using the Api token."
16
+ scoped: bool = False
17
+
18
+ _TOKEN_URL: str = urljoin(
19
+ config().public_base_url + "/",
20
+ f"{config().callback_url_rewrite_prefix}/auth/token",
21
+ )
22
+
23
+ @staticmethod
24
+ def provider() -> AuthProvider:
25
+ return AuthProvider.APITOKEN
26
+
27
+ @staticmethod
28
+ def recommended_scopes() -> set[str]:
29
+ return set()
30
+
31
+ @staticmethod
32
+ def provider_default() -> bool:
33
+ return True
34
+
35
+ def prepare(
36
+ self,
37
+ auth_req: ApiTokenRequest,
38
+ thread_id: str,
39
+ profile: str,
40
+ future_uid: str,
41
+ *args,
42
+ **kwargs,
43
+ ) -> str:
44
+ redirect_uri = urljoin(
45
+ config().public_base_url + "/",
46
+ f"{config().callback_url_rewrite_prefix}/auth/apitoken/token/callback",
47
+ )
48
+ url = self._make_auth_url(
49
+ auth_req=auth_req, redirect_uri=redirect_uri, state=future_uid
50
+ )
51
+ FutureStore.create_future(
52
+ future_uid,
53
+ data={
54
+ "redirect_uri": redirect_uri,
55
+ "thread_id": thread_id,
56
+ "profile": profile,
57
+ },
58
+ )
59
+
60
+ return f"User needs to authenticate using the following URL: {url}"
61
+
62
+ async def authenticate(
63
+ self, auth_req: ApiTokenRequest, future_uid: str, *args, **kwargs
64
+ ) -> AuthContext:
65
+ future_data = FutureStore.get_future(future_uid)
66
+ access_token = await future_data.future
67
+
68
+ response = ApiTokenResponse(access_token=access_token)
69
+ context = ApiTokenAuthContext.from_api_token_response(response)
70
+
71
+ return context
72
+
73
+ async def refresh(
74
+ self, auth_req: ApiTokenRequest, context: AuthContext, *args, **kwargs
75
+ ) -> AuthContext:
76
+ raise Exception("Api token doesn't support refresh")
77
+
78
+ def _make_auth_url(self, auth_req: ApiTokenRequest, redirect_uri: str, state: str):
79
+ params = {
80
+ "redirect_uri": redirect_uri,
81
+ "state": state,
82
+ }
83
+ auth_url = f"{self._TOKEN_URL}?{urlencode(params)}"
84
+ return auth_url
85
+
86
+ def make_request(
87
+ self, auth_scopes: Optional[list[str]] = None, **kwargs
88
+ ) -> ApiTokenRequest:
89
+ return ApiTokenRequest()
@@ -0,0 +1,9 @@
1
+ from hyperpocket.auth.schema import AuthenticateRequest, AuthenticateResponse
2
+
3
+
4
+ class ApiTokenRequest(AuthenticateRequest):
5
+ pass
6
+
7
+
8
+ class ApiTokenResponse(AuthenticateResponse):
9
+ access_token: str
@@ -10,7 +10,9 @@ class AuthProvider(Enum):
10
10
  NOTION = "notion"
11
11
  REDDIT = "reddit"
12
12
  GUMLOOP = "gumloop"
13
+ SERPAPI = "serpapi"
13
14
  X = "x"
15
+ APITOKEN = "apitoken"
14
16
 
15
17
  @classmethod
16
18
  def get_auth_provider(cls, auth_provider_name: str) -> "AuthProvider":
File without changes
@@ -0,0 +1,15 @@
1
+ from hyperpocket.auth.context import AuthContext
2
+
3
+
4
+ class SerpapiAuthContext(AuthContext):
5
+ _ACCESS_TOKEN_KEY: str = "SERPAPI_TOKEN"
6
+
7
+ def to_dict(self) -> dict[str, str]:
8
+ return {
9
+ self._ACCESS_TOKEN_KEY: self.access_token,
10
+ }
11
+
12
+ def to_profiled_dict(self, profile: str) -> dict[str, str]:
13
+ return {
14
+ f"{profile.upper()}_{self._ACCESS_TOKEN_KEY}": self.access_token,
15
+ }
@@ -0,0 +1,13 @@
1
+ from hyperpocket.auth.serpapi.context import SerpapiAuthContext
2
+ from hyperpocket.auth.serpapi.token_schema import SerpapiTokenResponse
3
+
4
+
5
+ class SerpapiTokenAuthContext(SerpapiAuthContext):
6
+ @classmethod
7
+ def from_serpapi_token_response(cls, response: SerpapiTokenResponse):
8
+ description = f'Serpapi Token Context logged in'
9
+ return cls(
10
+ access_token=response.access_token,
11
+ description=description,
12
+ expires_at=None
13
+ )
@@ -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.serpapi.token_context import SerpapiTokenAuthContext
8
+ from hyperpocket.auth.serpapi.token_schema import SerpapiTokenResponse, SerpapiTokenRequest
9
+ from hyperpocket.config import config
10
+ from hyperpocket.futures import FutureStore
11
+
12
+
13
+ class SerpapiTokenAuthHandler(AuthHandlerInterface):
14
+ name: str = "serpapi-token"
15
+ description: str = "This handler is used to authenticate users using the Serpapi 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_default() -> bool:
22
+ return True
23
+
24
+ @staticmethod
25
+ def provider() -> AuthProvider:
26
+ return AuthProvider.SERPAPI
27
+
28
+ @staticmethod
29
+ def recommended_scopes() -> set[str]:
30
+ return set()
31
+
32
+ def prepare(self, auth_req: SerpapiTokenRequest, 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/serpapi/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: SerpapiTokenRequest, future_uid: str, *args, **kwargs) -> AuthContext:
48
+ future_data = FutureStore.get_future(future_uid)
49
+ access_token = await future_data.future
50
+
51
+ response = SerpapiTokenResponse(access_token=access_token)
52
+ context = SerpapiTokenAuthContext.from_serpapi_token_response(response)
53
+
54
+ return context
55
+
56
+ async def refresh(self, auth_req: SerpapiTokenRequest, context: AuthContext, *args, **kwargs) -> AuthContext:
57
+ raise Exception("Serpapi token doesn't support refresh")
58
+
59
+ def _make_auth_url(self, auth_req: SerpapiTokenRequest, 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) -> SerpapiTokenRequest:
68
+ return SerpapiTokenRequest()
@@ -0,0 +1,11 @@
1
+ from typing import List, Optional
2
+ from pydantic import BaseModel
3
+ from hyperpocket.auth.schema import AuthenticateRequest, AuthenticateResponse
4
+
5
+
6
+ class SerpapiTokenRequest(AuthenticateRequest):
7
+ pass
8
+
9
+
10
+ class SerpapiTokenResponse(AuthenticateResponse):
11
+ access_token: str
@@ -0,0 +1,16 @@
1
+ from fastapi import APIRouter
2
+ from starlette.responses import HTMLResponse
3
+
4
+ from hyperpocket.futures import FutureStore
5
+
6
+ api_token_auth_router = APIRouter(prefix="/apitoken")
7
+
8
+
9
+ @api_token_auth_router.get("/token/callback")
10
+ async def notion_token_callback(state: str, token: str):
11
+ try:
12
+ FutureStore.resolve_future(state, token)
13
+ except ValueError:
14
+ return HTMLResponse(content="failed")
15
+
16
+ return HTMLResponse(content="success")
@@ -0,0 +1,14 @@
1
+
2
+ from fastapi import APIRouter
3
+ from starlette.responses import HTMLResponse
4
+ from hyperpocket.futures import FutureStore
5
+ serpapi_auth_router = APIRouter(
6
+ prefix="/serpapi"
7
+ )
8
+ @serpapi_auth_router.get("/token/callback")
9
+ async def serpapi_token_callback(state: str, token: str):
10
+ try:
11
+ FutureStore.resolve_future(state, token)
12
+ except ValueError:
13
+ return HTMLResponse(content="failed")
14
+ return HTMLResponse(content="success")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperpocket
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: Building AI agent with hyperpocket tool in a flash
5
5
  Project-URL: Homepage, https://vessl-ai.github.io/hyperpocket
6
6
  Project-URL: Repository, https://github.com/vessl-ai/hyperpocket
@@ -10,8 +10,14 @@ hyperpocket/auth/README.md,sha256=zn4QqnFZCA_4X3x8Wb6lE3OP5otYxpByZaCiUkBvaNs,11
10
10
  hyperpocket/auth/__init__.py,sha256=pO8M6SAuq0EPqi848_Iy650wqaLekx98e3RRnEAM_r0,607
11
11
  hyperpocket/auth/context.py,sha256=m-j2gDYUKBMsiakLHsu9thhM4dYyFiXP0Wp0S_iC0bU,1303
12
12
  hyperpocket/auth/handler.py,sha256=5cusl9ANEyG3gORVFjqh709txC0alw6eKtxgV6wjf6k,6683
13
- hyperpocket/auth/provider.py,sha256=Fe5kYX093sd9K0fakPVXYqXL6oIhdPU530W8pkVzZHU,515
13
+ hyperpocket/auth/provider.py,sha256=oy00TuxaQk51nsXnOimLvY3gQzn-jOFgIywSlGuWa1Q,565
14
14
  hyperpocket/auth/schema.py,sha256=pl4oRTNj8PdqQg6UVPWf8ei2uYQ4DtOmmD58cVFMYQw,537
15
+ hyperpocket/auth/apitoken/README.md,sha256=Sq5w_v3_JVp2k3Jaywmx_y_-ytw2Cs_oEeYveoXZVA0,564
16
+ hyperpocket/auth/apitoken/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ hyperpocket/auth/apitoken/context.py,sha256=uIXQsR7iiJEETOMcAy7s74Fob8N55FqWfUMQPfWGKY4,426
18
+ hyperpocket/auth/apitoken/token_context.py,sha256=3Uet_XfJBi7p8fkgwkT63uFJozq84TzFRpziUEoQVac,439
19
+ hyperpocket/auth/apitoken/token_handler.py,sha256=-BrBgkrPegNaA-03I1I7pBtHHfImbqM6UtlHVR-2zmY,2813
20
+ hyperpocket/auth/apitoken/token_schema.py,sha256=MGaOcRzuobpAPyMBjbwvy32RHhjOOr7D0lXIlkpX7jM,203
15
21
  hyperpocket/auth/calendly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
22
  hyperpocket/auth/calendly/context.py,sha256=oUQzLy_w5NPvbXjFPOhLD-ggONVSy9VVpFabvX4ZpsY,408
17
23
  hyperpocket/auth/calendly/oauth2_context.py,sha256=SiMeZaoWh3aneZVH_MXsT_cZ8qCSVeL-pWHVbfYUS6g,848
@@ -51,6 +57,11 @@ hyperpocket/auth/reddit/context.py,sha256=WlOvIb4u1PvfrbkYbEq5cSRnXxmIEFuHa4LlKj
51
57
  hyperpocket/auth/reddit/oauth2_context.py,sha256=v1u_uy6O52REp2anteTPNgvb_nX-hI6bM7jNngBZXq4,1015
52
58
  hyperpocket/auth/reddit/oauth2_handler.py,sha256=X_lzoyhYnjEFriBuorGdn977uD5GjphPiXi8W9SYdy0,5166
53
59
  hyperpocket/auth/reddit/oauth2_schema.py,sha256=MOcA8VTvjjwewxhyIn_-DRNf6H_5GjsN6C7gV8sDyiI,436
60
+ hyperpocket/auth/serpapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
+ hyperpocket/auth/serpapi/context.py,sha256=c1CuL53q22kyewrdc4Ae3zNclR87i_WWZ3n46aY3uoA,429
62
+ hyperpocket/auth/serpapi/token_context.py,sha256=0sK9FSAA4takB02EdHEiYvLs46aN_Es8QZ7e4nQo3ec,479
63
+ hyperpocket/auth/serpapi/token_handler.py,sha256=JFXm99eQUmMWfOhJcIqiJ4DIQEMKePou-Pft17PRkFA,2710
64
+ hyperpocket/auth/serpapi/token_schema.py,sha256=gJ2ONKEwVI057U2lyFD7RQJs3HVSoCwN2lMxiU4mEOU,276
54
65
  hyperpocket/auth/slack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
66
  hyperpocket/auth/slack/context.py,sha256=f8dMs7QtSSyissOlPGw8rCZXsVUckFnZWjZ_LAmNXpA,429
56
67
  hyperpocket/auth/slack/oauth2_context.py,sha256=kwahsgxtDo5Wg_nrF8mFv16ijIu6biiGe_qz2JlEKjM,1398
@@ -100,6 +111,7 @@ hyperpocket/server/__init__.py,sha256=8laNl098-IkFkarqwOZs_gm6yG0q3NAObq4cCUxK_T
100
111
  hyperpocket/server/proxy.py,sha256=ItM1qfuUBs6QiPqIpErBWUZWdtsEf0twPJY5r2UUFBU,2042
101
112
  hyperpocket/server/server.py,sha256=KQxspdmw7SQtJpXZYbwaE5z9QwQRAQgXGaixYi6JlI0,8756
102
113
  hyperpocket/server/auth/__init__.py,sha256=IMjz9PCzD7qh4QIf2g-gWIdkDeU36jt-9F55vaHvLoM,286
114
+ hyperpocket/server/auth/apitoken.py,sha256=I-ZDEehzwh7WsoHBnNTW1MZDRcmzNucNVBvGNHFjaao,451
103
115
  hyperpocket/server/auth/calendly.py,sha256=mi9_ysn0SffhnEgaoNa2jcHWCcD_yzqkS0rvzpJG2Qg,478
104
116
  hyperpocket/server/auth/github.py,sha256=5ZdKYoq_1Bh6aLUbSB5RWvr3o5DihZ5Gz5AfRWd4aCg,761
105
117
  hyperpocket/server/auth/google.py,sha256=_C33Bzow7yzjnvf0WUObu8p-dSU5rXqBgSPrENORAmY,470
@@ -107,6 +119,7 @@ hyperpocket/server/auth/gumloop.py,sha256=t_BUQ7RR8_x-ogqXnQ3iNHTVthzJyUTN03iqtR
107
119
  hyperpocket/server/auth/linear.py,sha256=Awd7GC5dIrwKnVthjW_MxutYIUz38DgC9L7BUcVfB04,442
108
120
  hyperpocket/server/auth/notion.py,sha256=NUKwCK61UADhO4FmFpNYjh1vsDzFZoFRDHdcMIBGb6M,443
109
121
  hyperpocket/server/auth/reddit.py,sha256=UloBQNEdhU1_eXaF8qVSQ5ivq5xtWINsHvBDGwgFSLM,443
122
+ hyperpocket/server/auth/serpapi.py,sha256=YCyUAYXNEoXQ3nkPiyrDs-WguUo2lfO-pEZTpHoWwr8,448
110
123
  hyperpocket/server/auth/slack.py,sha256=frMNtBEfe3fbeNzsQ8udapeau45NZmS8guATmS46qyA,710
111
124
  hyperpocket/server/auth/token.py,sha256=Yq5Ym-uEO_3cBpQOsmCBuqtFIdImrNcVUgF5ozs5NHk,1763
112
125
  hyperpocket/server/auth/x.py,sha256=CYCD_ajBY6Jt04E2bSEBZFRRIUZmNjF2gn6F0ZV5XuA,450
@@ -144,7 +157,7 @@ hyperpocket/util/flatten_json_schema.py,sha256=iuNBEmMSKFtPi-uqo6fb3RWN0koHOAihW
144
157
  hyperpocket/util/function_to_model.py,sha256=TXUs-qPbzL8C9-qqpz4Ad4D9MOPP61n_p0iPU6SoBeM,2318
145
158
  hyperpocket/util/get_objects_from_subpackage.py,sha256=4mR_S8eaJSdU68YfCkiXeIcXxb6q7LjFGsY_IHeNIZw,929
146
159
  hyperpocket/util/json_schema_to_model.py,sha256=PqI87pU5dWwcrQWB8eQxRdfgAEvvC1x_DKZnhcsRV-o,3586
147
- hyperpocket-0.3.3.dist-info/METADATA,sha256=SyPQKiQ-LsCfP9vHGwHw-PQOz_wlwjh2o2lSSngYn8w,12958
148
- hyperpocket-0.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
149
- hyperpocket-0.3.3.dist-info/entry_points.txt,sha256=KpBleaYr0SaENXOa-dFvJ_cvFCHYFEQ4LMl11ShAcBI,61
150
- hyperpocket-0.3.3.dist-info/RECORD,,
160
+ hyperpocket-0.3.4.dist-info/METADATA,sha256=x-XIo1chvunVMxpg7jiSok5x6W1cWj2QAFjMlo_g0zU,12958
161
+ hyperpocket-0.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
+ hyperpocket-0.3.4.dist-info/entry_points.txt,sha256=KpBleaYr0SaENXOa-dFvJ_cvFCHYFEQ4LMl11ShAcBI,61
163
+ hyperpocket-0.3.4.dist-info/RECORD,,