"""用量查询 — Tavily 剩余额度 + 百度 VDB 免费额度""" import time import hmac import hashlib import datetime import requests def check_tavily_usage(api_key: str) -> dict: if not api_key: return {'error': '未配置 API Key', 'available': False} try: resp = requests.get( 'https://api.tavily.com/usage', headers={'Authorization': f'Bearer {api_key}'}, timeout=10, ) if resp.status_code == 429: return {'error': '查询过于频繁(10分钟内限10次)', 'available': False} if resp.status_code != 200: return {'error': f'API 返回 {resp.status_code}', 'available': False} data = resp.json() key_data = data.get('key', {}) acct = data.get('account', {}) usage = key_data.get('usage', 0) or 0 limit = key_data.get('limit', 0) or 0 remaining = max(limit - usage, 0) if limit else 0 return { 'available': True, 'key': {'usage': usage, 'limit': limit, 'remaining': remaining}, 'account': { 'plan_limit': acct.get('plan_limit', 0) or 0, 'search_usage': acct.get('search_usage', 0) or 0, 'paygo_usage': acct.get('paygo_usage', 0) or 0, }, } except requests.exceptions.Timeout: return {'error': '请求超时', 'available': False} except requests.exceptions.RequestException as e: return {'error': f'网络错误: {e}', 'available': False} def _bce_sign(access_key: str, secret_key: str, method: str, path: str, headers: dict, params: dict = None) -> str: timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ') expiration = 1800 auth_string = f'bce-auth-v1/{access_key}/{timestamp}/{expiration}' signing_key = hmac.new( secret_key.encode('utf-8'), auth_string.encode('utf-8'), hashlib.sha256, ).hexdigest() signed_headers = sorted(headers.keys(), key=lambda k: k.lower()) canonical_headers = ''.join( f'{k.lower()}:{headers[k].strip()}\n' for k in signed_headers ) canonical_uri = path if params: canonical_query = '&'.join( f'{k}={v}' for k, v in sorted(params.items()) ) else: canonical_query = '' canonical_request = f'{method}\n{canonical_uri}\n{canonical_query}\n{canonical_headers}' signature = hmac.new( signing_key.encode('utf-8'), canonical_request.encode('utf-8'), hashlib.sha256, ).hexdigest() return (f'bce-auth-v1/{access_key}/{timestamp}/{expiration}/' f'{";".join(k.lower() for k in signed_headers)}/{signature}') def check_baidu_vdb_quota(access_key: str, secret_key: str) -> dict: if not access_key or not secret_key: return {'error': '未配置 VDB Access Key / Secret Key', 'available': False} host = 'vdb.bj.baidubce.com' path = '/v1/vdb/instance/freeQuota' method = 'GET' headers = { 'host': host, } auth = _bce_sign(access_key, secret_key, method, path, headers) headers['Authorization'] = auth headers['Content-Type'] = 'application/json' try: resp = requests.get( f'https://{host}{path}', headers=headers, timeout=10, ) if resp.status_code != 200: return {'error': f'API 返回 {resp.status_code}', 'available': False} data = resp.json() free_quota = data.get('freeQuota', 0) return { 'available': True, 'freeQuota': free_quota, } except requests.exceptions.Timeout: return {'error': '请求超时', 'available': False} except requests.exceptions.RequestException as e: return {'error': f'网络错误: {e}', 'available': False}