Skip to content

Commit b5cfbd4

Browse files
committed
Route runtime errors to main bot
1 parent 1d73e60 commit b5cfbd4

11 files changed

Lines changed: 453 additions & 428 deletions

.github/workflows/execution-report-heartbeat.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ jobs:
5454
RUNTIME_HEARTBEAT_REJECT_STATUSES: ${{ vars.RUNTIME_HEARTBEAT_REJECT_STATUSES }}
5555
CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}
5656
GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}
57-
CRISIS_ALERT_TELEGRAM_CHAT_IDS: ${{ vars.CRISIS_ALERT_TELEGRAM_CHAT_IDS }}
58-
CRISIS_ALERT_TELEGRAM_API_BASE_URL: ${{ vars.CRISIS_ALERT_TELEGRAM_API_BASE_URL }}
5957
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
60-
CRISIS_ALERT_TELEGRAM_BOT_TOKEN: ${{ secrets.CRISIS_ALERT_TELEGRAM_BOT_TOKEN }}
6158
steps:
6259
- name: Checkout repository
6360
uses: actions/checkout@v6

.github/workflows/runtime-guard.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ jobs:
5959
RUNTIME_GUARD_SCHEDULER_JOB_PATTERN: ${{ vars.RUNTIME_GUARD_SCHEDULER_JOB_PATTERN || vars.CLOUD_RUN_SERVICE }}
6060
CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}
6161
GLOBAL_TELEGRAM_CHAT_ID: ${{ vars.GLOBAL_TELEGRAM_CHAT_ID }}
62-
CRISIS_ALERT_TELEGRAM_CHAT_IDS: ${{ vars.CRISIS_ALERT_TELEGRAM_CHAT_IDS }}
63-
CRISIS_ALERT_TELEGRAM_API_BASE_URL: ${{ vars.CRISIS_ALERT_TELEGRAM_API_BASE_URL }}
6462
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
65-
CRISIS_ALERT_TELEGRAM_BOT_TOKEN: ${{ secrets.CRISIS_ALERT_TELEGRAM_BOT_TOKEN }}
6663
steps:
6764
- name: Checkout repository
6865
uses: actions/checkout@v6

.github/workflows/sync-cloud-run-env.yml

Lines changed: 185 additions & 150 deletions
Large diffs are not rendered by default.

main.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,6 @@ def _runtime_error_notification_targets() -> tuple[tuple[str, str], ...]:
313313
targets: list[tuple[str, str]] = []
314314
if TG_TOKEN and TG_CHAT_ID:
315315
targets.append((TG_TOKEN, TG_CHAT_ID))
316-
crisis_token = os.getenv("CRISIS_ALERT_TELEGRAM_BOT_TOKEN")
317-
for chat_id in _split_env_list(os.getenv("CRISIS_ALERT_TELEGRAM_CHAT_IDS")):
318-
if crisis_token and chat_id:
319-
targets.append((crisis_token, chat_id))
320316

321317
seen: set[tuple[str, str]] = set()
322318
unique_targets: list[tuple[str, str]] = []

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
flask
22
gunicorn
3-
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@v0.7.37
3+
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@3b6a0a9bedde72773e188041e0dc48516b38aadc
44
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@v0.7.52
55
hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@v0.4.3
66
pandas

runtime_config_support.py

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -69,36 +69,36 @@ class PlatformRuntimeSettings:
6969
strategy_config_path: str | None = None
7070
strategy_config_source: str | None = None
7171
strategy_plugin_mounts_json: str | None = None
72-
crisis_alert_channels: tuple[str, ...] = ()
73-
crisis_alert_email_recipients: tuple[str, ...] = ()
74-
crisis_alert_email_sender_email: str | None = None
75-
crisis_alert_email_sender_password: str | None = None
76-
crisis_alert_email_smtp_host: str | None = None
77-
crisis_alert_email_smtp_port: str | None = None
78-
crisis_alert_email_smtp_security: str | None = None
79-
crisis_alert_sms_recipients: tuple[str, ...] = ()
80-
crisis_alert_sms_provider: str | None = None
81-
crisis_alert_sms_account_id: str | None = None
82-
crisis_alert_sms_auth_token: str | None = None
83-
crisis_alert_sms_sender: str | None = None
84-
crisis_alert_sms_messaging_service_id: str | None = None
85-
crisis_alert_sms_api_base_url: str | None = None
86-
crisis_alert_sms_body_max_chars: str | None = None
87-
crisis_alert_push_recipients: tuple[str, ...] = ()
88-
crisis_alert_push_provider: str | None = None
89-
crisis_alert_push_app_token: str | None = None
90-
crisis_alert_push_access_token: str | None = None
91-
crisis_alert_push_api_base_url: str | None = None
92-
crisis_alert_push_device: str | None = None
93-
crisis_alert_push_priority: str | None = None
94-
crisis_alert_push_tags: str | None = None
95-
crisis_alert_push_body_max_chars: str | None = None
96-
crisis_alert_telegram_chat_ids: tuple[str, ...] = ()
97-
crisis_alert_telegram_bot_token: str | None = None
98-
crisis_alert_telegram_api_base_url: str | None = None
99-
crisis_alert_telegram_parse_mode: str | None = None
100-
crisis_alert_telegram_disable_web_page_preview: str | None = None
101-
crisis_alert_telegram_body_max_chars: str | None = None
72+
strategy_plugin_alert_channels: tuple[str, ...] = ()
73+
strategy_plugin_alert_email_recipients: tuple[str, ...] = ()
74+
strategy_plugin_alert_email_sender_email: str | None = None
75+
strategy_plugin_alert_email_sender_password: str | None = None
76+
strategy_plugin_alert_email_smtp_host: str | None = None
77+
strategy_plugin_alert_email_smtp_port: str | None = None
78+
strategy_plugin_alert_email_smtp_security: str | None = None
79+
strategy_plugin_alert_sms_recipients: tuple[str, ...] = ()
80+
strategy_plugin_alert_sms_provider: str | None = None
81+
strategy_plugin_alert_sms_account_id: str | None = None
82+
strategy_plugin_alert_sms_auth_token: str | None = None
83+
strategy_plugin_alert_sms_sender: str | None = None
84+
strategy_plugin_alert_sms_messaging_service_id: str | None = None
85+
strategy_plugin_alert_sms_api_base_url: str | None = None
86+
strategy_plugin_alert_sms_body_max_chars: str | None = None
87+
strategy_plugin_alert_push_recipients: tuple[str, ...] = ()
88+
strategy_plugin_alert_push_provider: str | None = None
89+
strategy_plugin_alert_push_app_token: str | None = None
90+
strategy_plugin_alert_push_access_token: str | None = None
91+
strategy_plugin_alert_push_api_base_url: str | None = None
92+
strategy_plugin_alert_push_device: str | None = None
93+
strategy_plugin_alert_push_priority: str | None = None
94+
strategy_plugin_alert_push_tags: str | None = None
95+
strategy_plugin_alert_push_body_max_chars: str | None = None
96+
strategy_plugin_alert_telegram_chat_ids: tuple[str, ...] = ()
97+
strategy_plugin_alert_telegram_bot_token: str | None = None
98+
strategy_plugin_alert_telegram_api_base_url: str | None = None
99+
strategy_plugin_alert_telegram_parse_mode: str | None = None
100+
strategy_plugin_alert_telegram_disable_web_page_preview: str | None = None
101+
strategy_plugin_alert_telegram_body_max_chars: str | None = None
102102
runtime_target: RuntimeTarget | None = None
103103

104104

@@ -255,57 +255,57 @@ def load_platform_runtime_settings(
255255
os.getenv("LONGBRIDGE_STRATEGY_PLUGIN_MOUNTS_JSON")
256256
or os.getenv("STRATEGY_PLUGIN_MOUNTS_JSON")
257257
),
258-
crisis_alert_channels=_split_env_list(os.getenv("CRISIS_ALERT_CHANNELS")),
259-
crisis_alert_email_recipients=_split_env_list(os.getenv("CRISIS_ALERT_EMAIL_RECIPIENTS")),
260-
crisis_alert_email_sender_email=_first_non_empty(os.getenv("CRISIS_ALERT_EMAIL_SENDER_EMAIL")),
261-
crisis_alert_email_sender_password=_first_non_empty(
262-
os.getenv("CRISIS_ALERT_EMAIL_SENDER_PASSWORD")
258+
strategy_plugin_alert_channels=_split_env_list(os.getenv("STRATEGY_PLUGIN_ALERT_CHANNELS")),
259+
strategy_plugin_alert_email_recipients=_split_env_list(os.getenv("STRATEGY_PLUGIN_ALERT_EMAIL_RECIPIENTS")),
260+
strategy_plugin_alert_email_sender_email=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_EMAIL_SENDER_EMAIL")),
261+
strategy_plugin_alert_email_sender_password=_first_non_empty(
262+
os.getenv("STRATEGY_PLUGIN_ALERT_EMAIL_SENDER_PASSWORD")
263263
),
264-
crisis_alert_email_smtp_host=_first_non_empty(os.getenv("CRISIS_ALERT_EMAIL_SMTP_HOST")),
265-
crisis_alert_email_smtp_port=_first_non_empty(os.getenv("CRISIS_ALERT_EMAIL_SMTP_PORT")),
266-
crisis_alert_email_smtp_security=_first_non_empty(
267-
os.getenv("CRISIS_ALERT_EMAIL_SMTP_SECURITY")
264+
strategy_plugin_alert_email_smtp_host=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_EMAIL_SMTP_HOST")),
265+
strategy_plugin_alert_email_smtp_port=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_EMAIL_SMTP_PORT")),
266+
strategy_plugin_alert_email_smtp_security=_first_non_empty(
267+
os.getenv("STRATEGY_PLUGIN_ALERT_EMAIL_SMTP_SECURITY")
268268
),
269-
crisis_alert_sms_recipients=_split_env_list(os.getenv("CRISIS_ALERT_SMS_RECIPIENTS")),
270-
crisis_alert_sms_provider=_first_non_empty(os.getenv("CRISIS_ALERT_SMS_PROVIDER")),
271-
crisis_alert_sms_account_id=_first_non_empty(os.getenv("CRISIS_ALERT_SMS_ACCOUNT_ID")),
272-
crisis_alert_sms_auth_token=_first_non_empty(os.getenv("CRISIS_ALERT_SMS_AUTH_TOKEN")),
273-
crisis_alert_sms_sender=_first_non_empty(os.getenv("CRISIS_ALERT_SMS_SENDER")),
274-
crisis_alert_sms_messaging_service_id=_first_non_empty(
275-
os.getenv("CRISIS_ALERT_SMS_MESSAGING_SERVICE_ID")
269+
strategy_plugin_alert_sms_recipients=_split_env_list(os.getenv("STRATEGY_PLUGIN_ALERT_SMS_RECIPIENTS")),
270+
strategy_plugin_alert_sms_provider=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_SMS_PROVIDER")),
271+
strategy_plugin_alert_sms_account_id=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_SMS_ACCOUNT_ID")),
272+
strategy_plugin_alert_sms_auth_token=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_SMS_AUTH_TOKEN")),
273+
strategy_plugin_alert_sms_sender=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_SMS_SENDER")),
274+
strategy_plugin_alert_sms_messaging_service_id=_first_non_empty(
275+
os.getenv("STRATEGY_PLUGIN_ALERT_SMS_MESSAGING_SERVICE_ID")
276276
),
277-
crisis_alert_sms_api_base_url=_first_non_empty(os.getenv("CRISIS_ALERT_SMS_API_BASE_URL")),
278-
crisis_alert_sms_body_max_chars=_first_non_empty(
279-
os.getenv("CRISIS_ALERT_SMS_BODY_MAX_CHARS")
277+
strategy_plugin_alert_sms_api_base_url=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_SMS_API_BASE_URL")),
278+
strategy_plugin_alert_sms_body_max_chars=_first_non_empty(
279+
os.getenv("STRATEGY_PLUGIN_ALERT_SMS_BODY_MAX_CHARS")
280280
),
281-
crisis_alert_push_recipients=_split_env_list(os.getenv("CRISIS_ALERT_PUSH_RECIPIENTS")),
282-
crisis_alert_push_provider=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_PROVIDER")),
283-
crisis_alert_push_app_token=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_APP_TOKEN")),
284-
crisis_alert_push_access_token=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_ACCESS_TOKEN")),
285-
crisis_alert_push_api_base_url=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_API_BASE_URL")),
286-
crisis_alert_push_device=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_DEVICE")),
287-
crisis_alert_push_priority=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_PRIORITY")),
288-
crisis_alert_push_tags=_first_non_empty(os.getenv("CRISIS_ALERT_PUSH_TAGS")),
289-
crisis_alert_push_body_max_chars=_first_non_empty(
290-
os.getenv("CRISIS_ALERT_PUSH_BODY_MAX_CHARS")
281+
strategy_plugin_alert_push_recipients=_split_env_list(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_RECIPIENTS")),
282+
strategy_plugin_alert_push_provider=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_PROVIDER")),
283+
strategy_plugin_alert_push_app_token=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_APP_TOKEN")),
284+
strategy_plugin_alert_push_access_token=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_ACCESS_TOKEN")),
285+
strategy_plugin_alert_push_api_base_url=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_API_BASE_URL")),
286+
strategy_plugin_alert_push_device=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_DEVICE")),
287+
strategy_plugin_alert_push_priority=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_PRIORITY")),
288+
strategy_plugin_alert_push_tags=_first_non_empty(os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_TAGS")),
289+
strategy_plugin_alert_push_body_max_chars=_first_non_empty(
290+
os.getenv("STRATEGY_PLUGIN_ALERT_PUSH_BODY_MAX_CHARS")
291291
),
292-
crisis_alert_telegram_chat_ids=_split_env_list(
293-
os.getenv("CRISIS_ALERT_TELEGRAM_CHAT_IDS")
292+
strategy_plugin_alert_telegram_chat_ids=_split_env_list(
293+
os.getenv("STRATEGY_PLUGIN_ALERT_TELEGRAM_CHAT_IDS")
294294
),
295-
crisis_alert_telegram_bot_token=_first_non_empty(
296-
os.getenv("CRISIS_ALERT_TELEGRAM_BOT_TOKEN")
295+
strategy_plugin_alert_telegram_bot_token=_first_non_empty(
296+
os.getenv("STRATEGY_PLUGIN_ALERT_TELEGRAM_BOT_TOKEN")
297297
),
298-
crisis_alert_telegram_api_base_url=_first_non_empty(
299-
os.getenv("CRISIS_ALERT_TELEGRAM_API_BASE_URL")
298+
strategy_plugin_alert_telegram_api_base_url=_first_non_empty(
299+
os.getenv("STRATEGY_PLUGIN_ALERT_TELEGRAM_API_BASE_URL")
300300
),
301-
crisis_alert_telegram_parse_mode=_first_non_empty(
302-
os.getenv("CRISIS_ALERT_TELEGRAM_PARSE_MODE")
301+
strategy_plugin_alert_telegram_parse_mode=_first_non_empty(
302+
os.getenv("STRATEGY_PLUGIN_ALERT_TELEGRAM_PARSE_MODE")
303303
),
304-
crisis_alert_telegram_disable_web_page_preview=_first_non_empty(
305-
os.getenv("CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW")
304+
strategy_plugin_alert_telegram_disable_web_page_preview=_first_non_empty(
305+
os.getenv("STRATEGY_PLUGIN_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW")
306306
),
307-
crisis_alert_telegram_body_max_chars=_first_non_empty(
308-
os.getenv("CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS")
307+
strategy_plugin_alert_telegram_body_max_chars=_first_non_empty(
308+
os.getenv("STRATEGY_PLUGIN_ALERT_TELEGRAM_BODY_MAX_CHARS")
309309
),
310310
runtime_target=runtime_target,
311311
)

scripts/cloud_run_runtime_guard.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,6 @@ def _summarize(entry: dict[str, Any]) -> str:
168168

169169
def _send_telegram(message: str) -> bool:
170170
targets: list[tuple[str, str]] = []
171-
crisis_token = os.environ.get("CRISIS_ALERT_TELEGRAM_BOT_TOKEN")
172-
for chat_id in _split_values(os.environ.get("CRISIS_ALERT_TELEGRAM_CHAT_IDS")):
173-
if crisis_token:
174-
targets.append((crisis_token, chat_id))
175171

176172
token = os.environ.get("TELEGRAM_TOKEN") or os.environ.get("TG_TOKEN")
177173
for chat_id in _split_values(os.environ.get("GLOBAL_TELEGRAM_CHAT_ID")):
@@ -184,7 +180,7 @@ def _send_telegram(message: str) -> bool:
184180
return False
185181

186182
ok = True
187-
base_url = os.environ.get("CRISIS_ALERT_TELEGRAM_API_BASE_URL") or "https://api.telegram.org"
183+
base_url = "https://api.telegram.org"
188184
for token_value, chat_id in unique_targets:
189185
body = urllib.parse.urlencode({"chat_id": chat_id, "text": message}).encode()
190186
request = urllib.request.Request(

scripts/execution_report_heartbeat.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,6 @@ def _is_accepted_report(payload: dict[str, Any]) -> tuple[bool, str]:
289289

290290
def _send_telegram(message: str) -> bool:
291291
targets: list[tuple[str, str]] = []
292-
crisis_token = os.environ.get("CRISIS_ALERT_TELEGRAM_BOT_TOKEN")
293-
for chat_id in _split_values(os.environ.get("CRISIS_ALERT_TELEGRAM_CHAT_IDS")):
294-
if crisis_token:
295-
targets.append((crisis_token, chat_id))
296292
token = os.environ.get("TELEGRAM_TOKEN") or os.environ.get("TG_TOKEN")
297293
for chat_id in _split_values(os.environ.get("GLOBAL_TELEGRAM_CHAT_ID")):
298294
if token:
@@ -301,7 +297,7 @@ def _send_telegram(message: str) -> bool:
301297
if not unique_targets:
302298
print("No Telegram token/chat configured; unable to send heartbeat alert.", file=sys.stderr)
303299
return False
304-
base_url = os.environ.get("CRISIS_ALERT_TELEGRAM_API_BASE_URL") or "https://api.telegram.org"
300+
base_url = "https://api.telegram.org"
305301
ok = True
306302
for token_value, chat_id in unique_targets:
307303
body = urllib.parse.urlencode({"chat_id": chat_id, "text": message}).encode()

tests/test_request_handling.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ def run(self, *args, **kwargs):
7171
tg_token=None,
7272
tg_chat_id="shared-chat-id",
7373
dry_run_only=False,
74-
crisis_alert_email_recipients=(),
75-
crisis_alert_email_sender_email=None,
76-
crisis_alert_email_sender_password=None,
77-
crisis_alert_sms_recipients=(),
78-
crisis_alert_sms_account_id=None,
79-
crisis_alert_sms_auth_token=None,
74+
strategy_plugin_alert_email_recipients=(),
75+
strategy_plugin_alert_email_sender_email=None,
76+
strategy_plugin_alert_email_sender_password=None,
77+
strategy_plugin_alert_sms_recipients=(),
78+
strategy_plugin_alert_sms_account_id=None,
79+
strategy_plugin_alert_sms_auth_token=None,
8080
runtime_target=build_runtime_target(
8181
platform_id="longbridge",
8282
strategy_profile="soxl_soxx_trend_income",
@@ -209,8 +209,16 @@ def fake_run_strategy():
209209

210210
module.run_strategy = fake_run_strategy
211211

212-
with module.app.test_request_context("/", method="POST"):
213-
body, status = module.handle_trigger()
212+
with patch.dict(
213+
os.environ,
214+
{
215+
"STRATEGY_PLUGIN_ALERT_TELEGRAM_BOT_TOKEN": "plugin-token",
216+
"STRATEGY_PLUGIN_ALERT_TELEGRAM_CHAT_IDS": "plugin-chat",
217+
},
218+
clear=False,
219+
):
220+
with module.app.test_request_context("/", method="POST"):
221+
body, status = module.handle_trigger()
214222

215223
self.assertEqual(status, 200)
216224
self.assertEqual(body, "OK",)

0 commit comments

Comments
 (0)