forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathintegration_base.py
More file actions
173 lines (152 loc) · 5.35 KB
/
Copy pathintegration_base.py
File metadata and controls
173 lines (152 loc) · 5.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import contextvars
from typing import Any, Awaitable, Callable, Dict, Optional, Tuple
from datetime import datetime
import database.users as users_db
import logging
logger = logging.getLogger(__name__)
try:
from utils.retrieval.agentic import agent_config_context
except ImportError:
agent_config_context = contextvars.ContextVar('agent_config', default=None)
def resolve_config_uid(config: Optional[Dict[str, Any]]) -> Tuple[Optional[str], Optional[str]]:
if config is None:
try:
config = agent_config_context.get()
except LookupError:
config = None
if config is None:
return None, "Error: Configuration not available"
try:
configurable: Any = config.get('configurable', {})
uid = configurable.get('user_id')
except Exception:
return None, "Error: Configuration not available"
if not uid:
return None, "Error: User ID not found in configuration"
return uid, None
def get_integration_checked(
uid: str,
key: str,
connection_name: str,
not_connected_msg: str,
error_prefix: str,
) -> Tuple[Optional[Dict[str, Any]], Optional[str]]:
try:
integration = users_db.get_integration(uid, key)
except Exception as e:
return None, f"{error_prefix}: {str(e)}"
if not integration or not integration.get('connected'):
return None, not_connected_msg
return integration, None
def get_access_token_checked(
integration: Optional[Dict[str, Any]], missing_msg: str
) -> Tuple[Optional[str], Optional[str]]:
token = integration.get('access_token') if integration else None
if not token:
return None, missing_msg
return token, None
def cap_limit(value: int, cap: int) -> int:
return value if value <= cap else cap
def ensure_capped(value: int, cap: int, warn_msg: str) -> int:
if value > cap:
try:
logger.info(warn_msg.format(value, cap))
except Exception:
logger.info(warn_msg)
return cap
return value
def parse_iso_with_tz(
field_name: str, value: Optional[str], tz_required_msg: str
) -> Tuple[Optional[datetime], Optional[str]]:
if not value:
return None, None
try:
dt = datetime.fromisoformat(value.replace('Z', '+00:00'))
if dt.tzinfo is None:
return None, f"Error: {field_name} must include timezone {tz_required_msg}: {value}"
return dt, None
except ValueError as e:
return None, f"Error: Invalid {field_name} format. Expected {tz_required_msg}: {value} - {str(e)}"
def prepare_access(
config: Optional[Dict[str, Any]],
provider_key: str,
provider_label: str,
not_connected_msg: str,
missing_token_msg: str,
error_prefix: str,
) -> Tuple[Optional[str], Optional[Dict[str, Any]], Optional[str], Optional[str]]:
uid, uid_err = resolve_config_uid(config)
if uid_err:
return None, None, None, uid_err
assert uid is not None # resolve_config_uid guarantees uid is non-None when uid_err is None
integration, int_err = get_integration_checked(
uid,
provider_key,
provider_label,
not_connected_msg,
error_prefix,
)
if int_err:
return uid, None, None, int_err
token, token_err = get_access_token_checked(integration, missing_token_msg)
if token_err:
return uid, integration, None, token_err
return uid, integration, token, None
def retry_on_auth(
call_fn: Callable[..., Any],
call_kwargs: Dict[str, Any],
refresh_fn: Callable[..., Any],
uid: str,
integration: Dict[str, Any],
expired_msg: str,
markers: Tuple[str, ...] = (
"Authentication failed",
"401",
"token may be expired",
"token may be expired or invalid",
),
) -> Tuple[Any, Optional[str]]:
try:
return call_fn(**call_kwargs), None
except Exception as e:
msg = str(e)
if any(m in msg for m in markers):
new_token = refresh_fn(uid, integration)
if new_token:
call_kwargs = dict(call_kwargs)
call_kwargs['access_token'] = new_token
try:
return call_fn(**call_kwargs), None
except Exception as e2:
return None, f"Error after token refresh: {str(e2)}"
return None, expired_msg
return None, f"Error: {msg}"
async def retry_on_auth_async(
call_fn: Callable[..., Awaitable[Any]],
call_kwargs: Dict[str, Any],
refresh_fn: Callable[..., Awaitable[Any]],
uid: str,
integration: Dict[str, Any],
expired_msg: str,
markers: Tuple[str, ...] = (
"Authentication failed",
"401",
"token may be expired",
"token may be expired or invalid",
),
) -> Tuple[Any, Optional[str]]:
try:
return await call_fn(**call_kwargs), None
except Exception as e:
msg = str(e)
if any(m in msg for m in markers):
new_token = await refresh_fn(uid, integration)
if new_token:
call_kwargs = dict(call_kwargs)
call_kwargs['access_token'] = new_token
try:
return await call_fn(**call_kwargs), None
except Exception as e2:
return None, f"Error after token refresh: {str(e2)}"
return None, expired_msg
return None, f"Error: {msg}"