botrun-flow-lang 5.12.263__py3-none-any.whl → 6.2.21__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.
- botrun_flow_lang/api/auth_api.py +39 -39
- botrun_flow_lang/api/auth_utils.py +183 -183
- botrun_flow_lang/api/botrun_back_api.py +65 -65
- botrun_flow_lang/api/flow_api.py +3 -3
- botrun_flow_lang/api/hatch_api.py +508 -508
- botrun_flow_lang/api/langgraph_api.py +816 -811
- botrun_flow_lang/api/langgraph_constants.py +11 -0
- botrun_flow_lang/api/line_bot_api.py +1484 -1484
- botrun_flow_lang/api/model_api.py +300 -300
- botrun_flow_lang/api/rate_limit_api.py +32 -32
- botrun_flow_lang/api/routes.py +79 -79
- botrun_flow_lang/api/search_api.py +53 -53
- botrun_flow_lang/api/storage_api.py +395 -395
- botrun_flow_lang/api/subsidy_api.py +290 -290
- botrun_flow_lang/api/subsidy_api_system_prompt.txt +109 -109
- botrun_flow_lang/api/user_setting_api.py +70 -70
- botrun_flow_lang/api/version_api.py +31 -31
- botrun_flow_lang/api/youtube_api.py +26 -26
- botrun_flow_lang/constants.py +13 -13
- botrun_flow_lang/langgraph_agents/agents/agent_runner.py +178 -178
- botrun_flow_lang/langgraph_agents/agents/agent_tools/step_planner.py +77 -77
- botrun_flow_lang/langgraph_agents/agents/checkpointer/firestore_checkpointer.py +666 -666
- botrun_flow_lang/langgraph_agents/agents/gov_researcher/GOV_RESEARCHER_PRD.md +192 -192
- botrun_flow_lang/langgraph_agents/agents/gov_researcher/gemini_subsidy_graph.py +460 -460
- botrun_flow_lang/langgraph_agents/agents/gov_researcher/gov_researcher_2_graph.py +1002 -1002
- botrun_flow_lang/langgraph_agents/agents/gov_researcher/gov_researcher_graph.py +822 -822
- botrun_flow_lang/langgraph_agents/agents/langgraph_react_agent.py +730 -723
- botrun_flow_lang/langgraph_agents/agents/search_agent_graph.py +864 -864
- botrun_flow_lang/langgraph_agents/agents/tools/__init__.py +4 -4
- botrun_flow_lang/langgraph_agents/agents/tools/gemini_code_execution.py +376 -376
- botrun_flow_lang/langgraph_agents/agents/util/gemini_grounding.py +66 -66
- botrun_flow_lang/langgraph_agents/agents/util/html_util.py +316 -316
- botrun_flow_lang/langgraph_agents/agents/util/img_util.py +336 -294
- botrun_flow_lang/langgraph_agents/agents/util/local_files.py +419 -419
- botrun_flow_lang/langgraph_agents/agents/util/mermaid_util.py +86 -86
- botrun_flow_lang/langgraph_agents/agents/util/model_utils.py +143 -143
- botrun_flow_lang/langgraph_agents/agents/util/pdf_analyzer.py +562 -486
- botrun_flow_lang/langgraph_agents/agents/util/pdf_cache.py +250 -250
- botrun_flow_lang/langgraph_agents/agents/util/pdf_processor.py +204 -204
- botrun_flow_lang/langgraph_agents/agents/util/perplexity_search.py +464 -464
- botrun_flow_lang/langgraph_agents/agents/util/plotly_util.py +59 -59
- botrun_flow_lang/langgraph_agents/agents/util/tavily_search.py +199 -199
- botrun_flow_lang/langgraph_agents/agents/util/usage_metadata.py +34 -0
- botrun_flow_lang/langgraph_agents/agents/util/youtube_util.py +90 -90
- botrun_flow_lang/langgraph_agents/cache/langgraph_botrun_cache.py +197 -197
- botrun_flow_lang/llm_agent/llm_agent.py +19 -19
- botrun_flow_lang/llm_agent/llm_agent_util.py +83 -83
- botrun_flow_lang/log/.gitignore +2 -2
- botrun_flow_lang/main.py +61 -61
- botrun_flow_lang/main_fast.py +51 -51
- botrun_flow_lang/mcp_server/__init__.py +10 -10
- botrun_flow_lang/mcp_server/default_mcp.py +854 -744
- botrun_flow_lang/models/nodes/utils.py +205 -205
- botrun_flow_lang/models/token_usage.py +34 -34
- botrun_flow_lang/requirements.txt +21 -21
- botrun_flow_lang/services/base/firestore_base.py +30 -30
- botrun_flow_lang/services/hatch/hatch_factory.py +11 -11
- botrun_flow_lang/services/hatch/hatch_fs_store.py +419 -419
- botrun_flow_lang/services/storage/storage_cs_store.py +206 -206
- botrun_flow_lang/services/storage/storage_factory.py +12 -12
- botrun_flow_lang/services/storage/storage_store.py +65 -65
- botrun_flow_lang/services/user_setting/user_setting_factory.py +9 -9
- botrun_flow_lang/services/user_setting/user_setting_fs_store.py +66 -66
- botrun_flow_lang/static/docs/tools/index.html +926 -926
- botrun_flow_lang/tests/api_functional_tests.py +1525 -1525
- botrun_flow_lang/tests/api_stress_test.py +357 -357
- botrun_flow_lang/tests/shared_hatch_tests.py +333 -333
- botrun_flow_lang/tests/test_botrun_app.py +46 -46
- botrun_flow_lang/tests/test_html_util.py +31 -31
- botrun_flow_lang/tests/test_img_analyzer.py +190 -190
- botrun_flow_lang/tests/test_img_util.py +39 -39
- botrun_flow_lang/tests/test_local_files.py +114 -114
- botrun_flow_lang/tests/test_mermaid_util.py +103 -103
- botrun_flow_lang/tests/test_pdf_analyzer.py +104 -104
- botrun_flow_lang/tests/test_plotly_util.py +151 -151
- botrun_flow_lang/tests/test_run_workflow_engine.py +65 -65
- botrun_flow_lang/tools/generate_docs.py +133 -133
- botrun_flow_lang/tools/templates/tools.html +153 -153
- botrun_flow_lang/utils/__init__.py +7 -7
- botrun_flow_lang/utils/botrun_logger.py +344 -344
- botrun_flow_lang/utils/clients/rate_limit_client.py +209 -209
- botrun_flow_lang/utils/clients/token_verify_client.py +153 -153
- botrun_flow_lang/utils/google_drive_utils.py +654 -654
- botrun_flow_lang/utils/langchain_utils.py +324 -324
- botrun_flow_lang/utils/yaml_utils.py +9 -9
- {botrun_flow_lang-5.12.263.dist-info → botrun_flow_lang-6.2.21.dist-info}/METADATA +6 -6
- botrun_flow_lang-6.2.21.dist-info/RECORD +104 -0
- botrun_flow_lang-5.12.263.dist-info/RECORD +0 -102
- {botrun_flow_lang-5.12.263.dist-info → botrun_flow_lang-6.2.21.dist-info}/WHEEL +0 -0
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import aiohttp
|
|
3
|
-
from typing import Dict, Any, Optional
|
|
4
|
-
|
|
5
|
-
# Import necessary libraries for IAP authentication
|
|
6
|
-
from google.auth.transport.requests import Request
|
|
7
|
-
from google.oauth2 import service_account
|
|
8
|
-
import json
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class RateLimitClient:
|
|
12
|
-
"""Client for interacting with Botrun rate limit API."""
|
|
13
|
-
|
|
14
|
-
def __init__(self, api_base: Optional[str] = None):
|
|
15
|
-
"""
|
|
16
|
-
Initialize the rate limit client.
|
|
17
|
-
|
|
18
|
-
Args:
|
|
19
|
-
api_base: Base URL for the Botrun API. If None, will use BOTRUN_BACK_API_BASE env var.
|
|
20
|
-
"""
|
|
21
|
-
if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
|
|
22
|
-
return
|
|
23
|
-
self.api_base = api_base or os.getenv("BOTRUN_BACK_API_BASE")
|
|
24
|
-
if not self.api_base:
|
|
25
|
-
raise ValueError("BOTRUN_BACK_API_BASE environment variable not set")
|
|
26
|
-
|
|
27
|
-
# Get IAP configuration from environment variables
|
|
28
|
-
self.iap_client_id = os.getenv("IAP_CLIENT_ID")
|
|
29
|
-
self.iap_service_account_key_file = os.getenv("IAP_SERVICE_ACCOUNT_KEY_FILE")
|
|
30
|
-
from botrun_flow_lang.utils.botrun_logger import get_default_botrun_logger
|
|
31
|
-
|
|
32
|
-
self.logger = get_default_botrun_logger()
|
|
33
|
-
|
|
34
|
-
def _get_iap_jwt(self) -> str:
|
|
35
|
-
"""
|
|
36
|
-
Generate a JWT token for IAP authentication.
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
JWT token as string
|
|
40
|
-
|
|
41
|
-
Raises:
|
|
42
|
-
ValueError: If the service account file can't be read or token generation fails
|
|
43
|
-
"""
|
|
44
|
-
try:
|
|
45
|
-
credentials = service_account.IDTokenCredentials.from_service_account_file(
|
|
46
|
-
self.iap_service_account_key_file,
|
|
47
|
-
target_audience=self.iap_client_id,
|
|
48
|
-
)
|
|
49
|
-
credentials.refresh(Request())
|
|
50
|
-
return credentials.token
|
|
51
|
-
except Exception as e:
|
|
52
|
-
raise ValueError(f"Error generating IAP JWT token: {str(e)}")
|
|
53
|
-
|
|
54
|
-
async def _make_iap_request(self, url: str, method: str = "GET") -> Dict[Any, Any]:
|
|
55
|
-
"""
|
|
56
|
-
Make an authenticated request to an IAP-protected endpoint.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
url: The URL to request
|
|
60
|
-
method: HTTP method to use (default: GET)
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
JSON response as dictionary
|
|
64
|
-
|
|
65
|
-
Raises:
|
|
66
|
-
ValueError: If the request fails
|
|
67
|
-
"""
|
|
68
|
-
try:
|
|
69
|
-
token = self._get_iap_jwt()
|
|
70
|
-
headers = {"Authorization": f"Bearer {token}"}
|
|
71
|
-
|
|
72
|
-
async with aiohttp.ClientSession() as session:
|
|
73
|
-
if method.upper() == "GET":
|
|
74
|
-
async with session.get(url, headers=headers) as response:
|
|
75
|
-
response.raise_for_status()
|
|
76
|
-
return await response.json()
|
|
77
|
-
elif method.upper() == "PUT":
|
|
78
|
-
async with session.put(url, headers=headers) as response:
|
|
79
|
-
response.raise_for_status()
|
|
80
|
-
return await response.json()
|
|
81
|
-
else:
|
|
82
|
-
raise ValueError(f"Unsupported HTTP method: {method}")
|
|
83
|
-
except aiohttp.ClientResponseError as e:
|
|
84
|
-
raise ValueError(f"IAP API error: {e.status} - {e.message}")
|
|
85
|
-
except Exception as e:
|
|
86
|
-
raise ValueError(f"Error making IAP request: {str(e)}")
|
|
87
|
-
|
|
88
|
-
async def get_rate_limit(self, username: str) -> Dict[Any, Any]:
|
|
89
|
-
"""
|
|
90
|
-
Get rate limit information for a user from the Botrun backend API.
|
|
91
|
-
|
|
92
|
-
Uses IAP authentication if IAP_CLIENT_ID and IAP_SERVICE_ACCOUNT_KEY_FILE
|
|
93
|
-
environment variables are set, otherwise falls back to standard authentication.
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
username: The username to get rate limit information for
|
|
97
|
-
|
|
98
|
-
Returns:
|
|
99
|
-
Dictionary containing rate limit information
|
|
100
|
-
|
|
101
|
-
Raises:
|
|
102
|
-
ValueError: If the API call fails
|
|
103
|
-
"""
|
|
104
|
-
self.logger.info(f"get_rate_limit username: {username}")
|
|
105
|
-
if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
|
|
106
|
-
self.logger.info(
|
|
107
|
-
"BOTRUN_BACK_API_BASE is not set, return default rate limit"
|
|
108
|
-
)
|
|
109
|
-
return {
|
|
110
|
-
"drawing": {"daily_limit": 999, "current_usage": 0, "can_use": True},
|
|
111
|
-
"voice": {"max_size": 1024},
|
|
112
|
-
"document": {"max_size": 1024},
|
|
113
|
-
}
|
|
114
|
-
url = f"{self.api_base}/botrun/rate_limit/{username}"
|
|
115
|
-
self.logger.info(f"IAP URL: {url}")
|
|
116
|
-
|
|
117
|
-
# Use IAP authentication if both required environment variables are set
|
|
118
|
-
if self.iap_client_id and self.iap_service_account_key_file:
|
|
119
|
-
self.logger.info("IAP authentication is used")
|
|
120
|
-
return await self._make_iap_request(url)
|
|
121
|
-
|
|
122
|
-
# Otherwise, use standard authentication
|
|
123
|
-
async with aiohttp.ClientSession() as session:
|
|
124
|
-
try:
|
|
125
|
-
async with session.get(url) as response:
|
|
126
|
-
response.raise_for_status()
|
|
127
|
-
self.logger.info(
|
|
128
|
-
f"Rate limit data fetched successfully response:{response}"
|
|
129
|
-
)
|
|
130
|
-
text = await response.text()
|
|
131
|
-
self.logger.info(
|
|
132
|
-
f"Rate limit data fetched successfully text:{text}"
|
|
133
|
-
)
|
|
134
|
-
return json.loads(text)
|
|
135
|
-
except aiohttp.ClientResponseError as e:
|
|
136
|
-
self.logger.error(
|
|
137
|
-
f"API error: {e.status} - {e.message}",
|
|
138
|
-
error=str(e),
|
|
139
|
-
exc_info=True,
|
|
140
|
-
)
|
|
141
|
-
raise ValueError(f"API error: {e.status} - {e.message}")
|
|
142
|
-
except Exception as e:
|
|
143
|
-
self.logger.error(
|
|
144
|
-
f"Error fetching rate limit data: {str(e)}",
|
|
145
|
-
error=str(e),
|
|
146
|
-
exc_info=True,
|
|
147
|
-
)
|
|
148
|
-
raise ValueError(f"Error fetching rate limit data: {str(e)}")
|
|
149
|
-
|
|
150
|
-
async def update_drawing_usage(self, username: str) -> Dict[Any, Any]:
|
|
151
|
-
"""
|
|
152
|
-
Update drawing usage counter for a user via the Botrun backend API.
|
|
153
|
-
|
|
154
|
-
Uses IAP authentication if IAP_CLIENT_ID and IAP_SERVICE_ACCOUNT_KEY_FILE
|
|
155
|
-
environment variables are set, otherwise falls back to standard authentication.
|
|
156
|
-
|
|
157
|
-
Args:
|
|
158
|
-
username: The username to update drawing usage for
|
|
159
|
-
|
|
160
|
-
Returns:
|
|
161
|
-
Dictionary with update status information:
|
|
162
|
-
{
|
|
163
|
-
"username": "example@gmail.com",
|
|
164
|
-
"is_success": true,
|
|
165
|
-
"message": "Usage counter updated successfully"
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
Raises:
|
|
169
|
-
ValueError: If the API call fails with status code 404 (user not found)
|
|
170
|
-
or 500 (server error)
|
|
171
|
-
"""
|
|
172
|
-
self.logger.info(f"update_drawing_usage username: {username}")
|
|
173
|
-
if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
|
|
174
|
-
self.logger.info("BOTRUN_BACK_API_BASE is not set, return ")
|
|
175
|
-
return {}
|
|
176
|
-
|
|
177
|
-
url = f"{self.api_base}/botrun/rate_limit/{username}/drawing_usage"
|
|
178
|
-
self.logger.info(f"Update drawing usage URL: {url}")
|
|
179
|
-
|
|
180
|
-
# Use IAP authentication if both required environment variables are set
|
|
181
|
-
if self.iap_client_id and self.iap_service_account_key_file:
|
|
182
|
-
self.logger.info("IAP authentication is used")
|
|
183
|
-
return await self._make_iap_request(url, method="PUT")
|
|
184
|
-
|
|
185
|
-
# Otherwise, use standard authentication
|
|
186
|
-
async with aiohttp.ClientSession() as session:
|
|
187
|
-
try:
|
|
188
|
-
async with session.put(url) as response:
|
|
189
|
-
response.raise_for_status()
|
|
190
|
-
text = await response.text()
|
|
191
|
-
self.logger.info(f"Update drawing usage response: {text}")
|
|
192
|
-
return json.loads(text)
|
|
193
|
-
except aiohttp.ClientResponseError as e:
|
|
194
|
-
self.logger.error(
|
|
195
|
-
f"API error: {e.status} - {e.message}",
|
|
196
|
-
error=str(e),
|
|
197
|
-
exc_info=True,
|
|
198
|
-
)
|
|
199
|
-
if e.status == 404:
|
|
200
|
-
raise ValueError(f"User not found: {username}")
|
|
201
|
-
else:
|
|
202
|
-
raise ValueError(f"API error: {e.status} - {e.message}")
|
|
203
|
-
except Exception as e:
|
|
204
|
-
self.logger.error(
|
|
205
|
-
f"Error updating drawing usage: {str(e)}",
|
|
206
|
-
error=str(e),
|
|
207
|
-
exc_info=True,
|
|
208
|
-
)
|
|
209
|
-
raise ValueError(f"Error updating drawing usage: {str(e)}")
|
|
1
|
+
import os
|
|
2
|
+
import aiohttp
|
|
3
|
+
from typing import Dict, Any, Optional
|
|
4
|
+
|
|
5
|
+
# Import necessary libraries for IAP authentication
|
|
6
|
+
from google.auth.transport.requests import Request
|
|
7
|
+
from google.oauth2 import service_account
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RateLimitClient:
|
|
12
|
+
"""Client for interacting with Botrun rate limit API."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, api_base: Optional[str] = None):
|
|
15
|
+
"""
|
|
16
|
+
Initialize the rate limit client.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
api_base: Base URL for the Botrun API. If None, will use BOTRUN_BACK_API_BASE env var.
|
|
20
|
+
"""
|
|
21
|
+
if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
|
|
22
|
+
return
|
|
23
|
+
self.api_base = api_base or os.getenv("BOTRUN_BACK_API_BASE")
|
|
24
|
+
if not self.api_base:
|
|
25
|
+
raise ValueError("BOTRUN_BACK_API_BASE environment variable not set")
|
|
26
|
+
|
|
27
|
+
# Get IAP configuration from environment variables
|
|
28
|
+
self.iap_client_id = os.getenv("IAP_CLIENT_ID")
|
|
29
|
+
self.iap_service_account_key_file = os.getenv("IAP_SERVICE_ACCOUNT_KEY_FILE")
|
|
30
|
+
from botrun_flow_lang.utils.botrun_logger import get_default_botrun_logger
|
|
31
|
+
|
|
32
|
+
self.logger = get_default_botrun_logger()
|
|
33
|
+
|
|
34
|
+
def _get_iap_jwt(self) -> str:
|
|
35
|
+
"""
|
|
36
|
+
Generate a JWT token for IAP authentication.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
JWT token as string
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
ValueError: If the service account file can't be read or token generation fails
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
credentials = service_account.IDTokenCredentials.from_service_account_file(
|
|
46
|
+
self.iap_service_account_key_file,
|
|
47
|
+
target_audience=self.iap_client_id,
|
|
48
|
+
)
|
|
49
|
+
credentials.refresh(Request())
|
|
50
|
+
return credentials.token
|
|
51
|
+
except Exception as e:
|
|
52
|
+
raise ValueError(f"Error generating IAP JWT token: {str(e)}")
|
|
53
|
+
|
|
54
|
+
async def _make_iap_request(self, url: str, method: str = "GET") -> Dict[Any, Any]:
|
|
55
|
+
"""
|
|
56
|
+
Make an authenticated request to an IAP-protected endpoint.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
url: The URL to request
|
|
60
|
+
method: HTTP method to use (default: GET)
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
JSON response as dictionary
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
ValueError: If the request fails
|
|
67
|
+
"""
|
|
68
|
+
try:
|
|
69
|
+
token = self._get_iap_jwt()
|
|
70
|
+
headers = {"Authorization": f"Bearer {token}"}
|
|
71
|
+
|
|
72
|
+
async with aiohttp.ClientSession() as session:
|
|
73
|
+
if method.upper() == "GET":
|
|
74
|
+
async with session.get(url, headers=headers) as response:
|
|
75
|
+
response.raise_for_status()
|
|
76
|
+
return await response.json()
|
|
77
|
+
elif method.upper() == "PUT":
|
|
78
|
+
async with session.put(url, headers=headers) as response:
|
|
79
|
+
response.raise_for_status()
|
|
80
|
+
return await response.json()
|
|
81
|
+
else:
|
|
82
|
+
raise ValueError(f"Unsupported HTTP method: {method}")
|
|
83
|
+
except aiohttp.ClientResponseError as e:
|
|
84
|
+
raise ValueError(f"IAP API error: {e.status} - {e.message}")
|
|
85
|
+
except Exception as e:
|
|
86
|
+
raise ValueError(f"Error making IAP request: {str(e)}")
|
|
87
|
+
|
|
88
|
+
async def get_rate_limit(self, username: str) -> Dict[Any, Any]:
|
|
89
|
+
"""
|
|
90
|
+
Get rate limit information for a user from the Botrun backend API.
|
|
91
|
+
|
|
92
|
+
Uses IAP authentication if IAP_CLIENT_ID and IAP_SERVICE_ACCOUNT_KEY_FILE
|
|
93
|
+
environment variables are set, otherwise falls back to standard authentication.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
username: The username to get rate limit information for
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Dictionary containing rate limit information
|
|
100
|
+
|
|
101
|
+
Raises:
|
|
102
|
+
ValueError: If the API call fails
|
|
103
|
+
"""
|
|
104
|
+
self.logger.info(f"get_rate_limit username: {username}")
|
|
105
|
+
if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
|
|
106
|
+
self.logger.info(
|
|
107
|
+
"BOTRUN_BACK_API_BASE is not set, return default rate limit"
|
|
108
|
+
)
|
|
109
|
+
return {
|
|
110
|
+
"drawing": {"daily_limit": 999, "current_usage": 0, "can_use": True},
|
|
111
|
+
"voice": {"max_size": 1024},
|
|
112
|
+
"document": {"max_size": 1024},
|
|
113
|
+
}
|
|
114
|
+
url = f"{self.api_base}/botrun/rate_limit/{username}"
|
|
115
|
+
self.logger.info(f"IAP URL: {url}")
|
|
116
|
+
|
|
117
|
+
# Use IAP authentication if both required environment variables are set
|
|
118
|
+
if self.iap_client_id and self.iap_service_account_key_file:
|
|
119
|
+
self.logger.info("IAP authentication is used")
|
|
120
|
+
return await self._make_iap_request(url)
|
|
121
|
+
|
|
122
|
+
# Otherwise, use standard authentication
|
|
123
|
+
async with aiohttp.ClientSession() as session:
|
|
124
|
+
try:
|
|
125
|
+
async with session.get(url) as response:
|
|
126
|
+
response.raise_for_status()
|
|
127
|
+
self.logger.info(
|
|
128
|
+
f"Rate limit data fetched successfully response:{response}"
|
|
129
|
+
)
|
|
130
|
+
text = await response.text()
|
|
131
|
+
self.logger.info(
|
|
132
|
+
f"Rate limit data fetched successfully text:{text}"
|
|
133
|
+
)
|
|
134
|
+
return json.loads(text)
|
|
135
|
+
except aiohttp.ClientResponseError as e:
|
|
136
|
+
self.logger.error(
|
|
137
|
+
f"API error: {e.status} - {e.message}",
|
|
138
|
+
error=str(e),
|
|
139
|
+
exc_info=True,
|
|
140
|
+
)
|
|
141
|
+
raise ValueError(f"API error: {e.status} - {e.message}")
|
|
142
|
+
except Exception as e:
|
|
143
|
+
self.logger.error(
|
|
144
|
+
f"Error fetching rate limit data: {str(e)}",
|
|
145
|
+
error=str(e),
|
|
146
|
+
exc_info=True,
|
|
147
|
+
)
|
|
148
|
+
raise ValueError(f"Error fetching rate limit data: {str(e)}")
|
|
149
|
+
|
|
150
|
+
async def update_drawing_usage(self, username: str) -> Dict[Any, Any]:
|
|
151
|
+
"""
|
|
152
|
+
Update drawing usage counter for a user via the Botrun backend API.
|
|
153
|
+
|
|
154
|
+
Uses IAP authentication if IAP_CLIENT_ID and IAP_SERVICE_ACCOUNT_KEY_FILE
|
|
155
|
+
environment variables are set, otherwise falls back to standard authentication.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
username: The username to update drawing usage for
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Dictionary with update status information:
|
|
162
|
+
{
|
|
163
|
+
"username": "example@gmail.com",
|
|
164
|
+
"is_success": true,
|
|
165
|
+
"message": "Usage counter updated successfully"
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
Raises:
|
|
169
|
+
ValueError: If the API call fails with status code 404 (user not found)
|
|
170
|
+
or 500 (server error)
|
|
171
|
+
"""
|
|
172
|
+
self.logger.info(f"update_drawing_usage username: {username}")
|
|
173
|
+
if os.getenv("BOTRUN_BACK_API_BASE", "") == "":
|
|
174
|
+
self.logger.info("BOTRUN_BACK_API_BASE is not set, return ")
|
|
175
|
+
return {}
|
|
176
|
+
|
|
177
|
+
url = f"{self.api_base}/botrun/rate_limit/{username}/drawing_usage"
|
|
178
|
+
self.logger.info(f"Update drawing usage URL: {url}")
|
|
179
|
+
|
|
180
|
+
# Use IAP authentication if both required environment variables are set
|
|
181
|
+
if self.iap_client_id and self.iap_service_account_key_file:
|
|
182
|
+
self.logger.info("IAP authentication is used")
|
|
183
|
+
return await self._make_iap_request(url, method="PUT")
|
|
184
|
+
|
|
185
|
+
# Otherwise, use standard authentication
|
|
186
|
+
async with aiohttp.ClientSession() as session:
|
|
187
|
+
try:
|
|
188
|
+
async with session.put(url) as response:
|
|
189
|
+
response.raise_for_status()
|
|
190
|
+
text = await response.text()
|
|
191
|
+
self.logger.info(f"Update drawing usage response: {text}")
|
|
192
|
+
return json.loads(text)
|
|
193
|
+
except aiohttp.ClientResponseError as e:
|
|
194
|
+
self.logger.error(
|
|
195
|
+
f"API error: {e.status} - {e.message}",
|
|
196
|
+
error=str(e),
|
|
197
|
+
exc_info=True,
|
|
198
|
+
)
|
|
199
|
+
if e.status == 404:
|
|
200
|
+
raise ValueError(f"User not found: {username}")
|
|
201
|
+
else:
|
|
202
|
+
raise ValueError(f"API error: {e.status} - {e.message}")
|
|
203
|
+
except Exception as e:
|
|
204
|
+
self.logger.error(
|
|
205
|
+
f"Error updating drawing usage: {str(e)}",
|
|
206
|
+
error=str(e),
|
|
207
|
+
exc_info=True,
|
|
208
|
+
)
|
|
209
|
+
raise ValueError(f"Error updating drawing usage: {str(e)}")
|