This commit is contained in:
jack
2025-11-26 18:06:29 +08:00
parent 0b84cb8222
commit d4e55e9aca
32 changed files with 1303 additions and 1886 deletions
View File
+60
View File
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
"""Alpha表达式服务"""
import time
import httpx
from typing import List, Dict, Any
from config.settings import settings
class AlphaService:
"""Alpha表达式服务类"""
def __init__(self, client: httpx.Client):
self.client = client
def simulate_alpha(self, expression: str) -> Dict[str, Any]:
"""模拟单个Alpha表达式"""
simulation_data = {
'type': 'REGULAR',
'settings': settings.SIMULATION_SETTINGS,
'regular': expression
}
sim_resp = self.client.post(f'{settings.BRAIN_API_URL}/simulations', json=simulation_data)
print(f"模拟提交状态: {sim_resp.status_code}")
if 'location' not in sim_resp.headers:
return {"status": "err", "message": "No location header in response"}
sim_progress_url = sim_resp.headers['location']
return self._wait_for_simulation_result(sim_progress_url)
def _wait_for_simulation_result(self, progress_url: str) -> Dict[str, Any]:
"""等待模拟结果"""
while True:
sim_progress_resp = self.client.get(progress_url)
retry_after_sec = float(sim_progress_resp.headers.get("Retry-After", 0))
if retry_after_sec == 0:
break
if sim_progress_resp.json():
result = sim_progress_resp.json()
progress = result.get('progress', 0)
print(f"模拟进度: {float(progress) * 100}%")
print(f"等待 {retry_after_sec} 秒...")
time.sleep(retry_after_sec)
result_data = sim_progress_resp.json()
if result_data.get("status") == "ERROR":
error_message = result_data.get("message", "未知错误")
print(f"因子模拟失败: {error_message}")
return {"status": "err", "message": error_message}
alpha_id = result_data.get("alpha")
print(f"生成的Alpha ID: {alpha_id}")
return {"status": "ok", "alpha_id": alpha_id}
+57
View File
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""认证服务"""
import os
import httpx
from httpx import BasicAuth
from typing import Tuple, Dict, Any
from config.settings import settings
from models.entities import TokenInfo
class AuthService:
"""认证服务类"""
def __init__(self):
self.credentials_file = settings.credentials_file
def load_credentials(self) -> Tuple[str, str]:
"""加载凭证"""
if not os.path.exists(self.credentials_file):
self._create_credentials_file()
with open(self.credentials_file, 'r', encoding='utf-8') as f:
credentials = eval(f.read())
return credentials[0], credentials[1]
def _create_credentials_file(self) -> None:
"""创建凭证文件"""
print("未找到 account.txt 文件")
with open(self.credentials_file, 'w', encoding='utf-8') as f:
f.write("")
print("account.txt 文件已创建,请填写账号密码, 格式: ['username', 'password']")
exit(1)
def login(self, client: httpx.Client) -> TokenInfo:
"""登录并获取token"""
username, password = self.load_credentials()
# 设置 BasicAuth
client.auth = BasicAuth(username, password)
response = client.post(f'{settings.BRAIN_API_URL}/authentication')
print(f"登录状态: {response.status_code}")
if response.status_code == 201:
login_data = response.json()
print(f"登录成功!: {login_data}")
return TokenInfo(
token=login_data['token'],
expiry=int(login_data['token']['expiry'])
)
elif response.status_code == 429:
print("API rate limit exceeded")
exit(1)
else:
print(f"登录失败: {response.json()}")
raise Exception(f"登录失败: {response.json()}")
+27
View File
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
"""通知服务"""
import httpx
from datetime import datetime
from config.settings import settings
class NotificationService:
"""通知服务类"""
@staticmethod
def send_to_gotify(success_count: int, fail_count: int) -> None:
"""发送结果到Gotify"""
now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
text = f"总计: 成功 {success_count} 个, 失败 {fail_count} 个\n\n完成时间: {now}"
title = f"alpha模拟结果 时间: {now}"
try:
resp = httpx.post(
settings.GOTIFY_URL,
json={'title': title, 'message': text},
timeout=10
)
print("通知发送成功")
except Exception as e:
print(f"通知发送失败: {e}")