""" 代码托管平台 API 的统一网络层(GitHub / Gitea)。 - 所有出站请求集中在此,按 flavor 注入对应平台的推荐请求头与鉴权方式; - 代理支持显式传入(GitHub 用 GH_PROXY、Gitea 用 GITEA_PROXY); - 未显式配置代理时 requests 仍会自动遵循容器的 HTTPS_PROXY/HTTP_PROXY 环境变量。 """ import requests from . import app_settings GITHUB_API = 'https://api.github.com' API_VERSION = '2026-03-10' DEFAULT_TIMEOUT = 15 def proxies(proxy=None): """返回 requests 使用的 proxies 字典。 proxy=None 时沿用 GitHub 的 GH_PROXY(历史默认); 显式传 '' 表示直连(环境变量仍生效),传具体地址则使用该代理。 """ if proxy is None: proxy = app_settings.get_value('GH_PROXY').strip() if proxy: return {'http': proxy, 'https': proxy} return {} def build_headers(token=None, json_content=False, flavor='github'): """按平台风格构建请求头。 - github:application/vnd.github+json + 版本头 + Bearer 鉴权; - gitea:application/json + Gitea 官方文档主推的 token 鉴权方案。 """ flavor = (flavor or 'github').lower() if flavor == 'gitea': headers = {'Accept': 'application/json'} if token: headers['Authorization'] = f'token {token}' else: headers = { 'Accept': 'application/vnd.github+json', 'X-GitHub-Api-Version': API_VERSION, } if token: headers['Authorization'] = f'Bearer {token}' if json_content: headers['Content-Type'] = 'application/json' return headers def request(method, url, *, token=None, timeout=DEFAULT_TIMEOUT, headers=None, flavor='github', proxy=None, **kwargs): """发起平台 API 请求,自动注入代理、超时与标准请求头。""" kwargs.setdefault('proxies', proxies(proxy)) kwargs.setdefault('timeout', timeout) merged_headers = build_headers( token=token, json_content=kwargs.get('json') is not None, flavor=flavor, ) if headers: merged_headers.update(headers) kwargs['headers'] = merged_headers return requests.request(method, url, **kwargs) def get(url, **kwargs): return request('GET', url, **kwargs) def post(url, **kwargs): return request('POST', url, **kwargs)