This repository has been archived on 2026-10-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
NeteaseUrl/web/routers/system.py
T
snowy-yang 9f56f68b66 chore(async-infra): 异步基础层 + 工具链 + 清理
异步基础层(core/):
- db.py   aiosqlite + WAL:读路径无锁并发、写路径 asyncio.Lock 串行,
          busy_timeout 自旋——实现「读写同时进行」(旧实现用 RLock 全读串行)
- http_client.py  aiohttp 连接池 + 有界重试(5xx 重试 / 4xx 不重试)+
          响应体上限 + 流式接口;按事件循环隔离 session(支持迁移期双 loop)

工具链:
- pyproject.toml   ruff(E/F/W/I/B/UP/C4/ASYNC/S/RUF) + pyright(basic) + pytest(asyncio auto)
- requirements-fastapi.txt  FastAPI/aiohttp/aiosqlite/aiofiles 等目标栈
- requirements-dev.txt      开发依赖(pytest/ruff/pyright)

清理:删除无用脚本 _csscheck.py 与产物标记 _css_ok.txt/_pkg_ok.txt,同步 .gitignore

验证:pytest 10/10(含「写 200 条同时 4 读协程零异常」并发用例);
ruff All checks passed;pyright 0 errors。
2026-09-26 00:24:00 +08:00

80 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""系统端点(迁移样板):/health、/api/info。
/flask 侧的这两个端点无鉴权、无状态、无任务依赖,是最安全的迁移起点。
此处实现与 main.py 的 health_check / api_info **响应契约逐字段对齐**,
用于验证双框架一致性(见 .zcode/refactor/parity.py)。
"""
import sys
import time
from fastapi import APIRouter
from core.config import APP_VERSION
from web.response import error, success
router = APIRouter()
# 与 main.py api_info 的 endpoints 表保持一致(迁移期以 Flask 侧为准,逐字对齐)
_ENDPOINTS = {
'/health': 'GET - 健康检查',
'/song': 'GET/POST - 获取歌曲信息',
'/search': 'GET/POST - 搜索音乐',
'/playlist': 'GET/POST - 获取歌单详情',
'/album': 'GET/POST - 获取专辑详情',
'/download': 'POST - 下载音乐(付费动作仅接受 POST)',
'/podcast/parse': 'GET/POST - 播客解析(电台/单集)',
'/podcast/programs': 'GET/POST - 播客单集列表(分页)',
'/podcast/search': 'GET/POST - 播客搜索',
'/podcast/hot': 'GET/POST - 热门播客与分类',
'/podcast/download': 'POST - 播客单集下载',
'/podcast/download/batch_zip': 'POST - 整台播客打包ZIP',
'/global/playlists': 'GET/POST - 全局账号歌单列表',
'/global/playlist': 'GET/POST - 全局账号歌单详情',
'/api/playlist/play': 'GET/POST - 公开歌单播放API(id/level/limit)',
'/api/info': 'GET - API信息',
}
@router.get('/health')
def health_check():
"""健康检查API(对应 Flask health_check)"""
try:
from music_api import load_cookies
cookies = load_cookies()
cookie_status = 'valid' if cookies else 'invalid'
health_info = {
'service': 'running',
'timestamp': int(time.time()) if 'time' in sys.modules else None,
'cookie_status': cookie_status,
'cookie_count': len(cookies),
'downloads_dir': 'configured', # R5-P3:不向匿名访客回显服务器绝对路径
'version': APP_VERSION,
}
return success(health_info, "API服务运行正常")
except Exception:
return error("服务暂时不可用,请稍后再试", 500)
@router.get('/api/info')
def api_info():
"""API信息接口(对应 Flask api_info)"""
try:
info = {
'name': '云村小助手API服务',
'version': APP_VERSION,
'description': '云村小助手 · 网易云音乐解析/下载服务',
'endpoints': dict(_ENDPOINTS),
'supported_qualities': ['standard', 'exhigh', 'lossless', 'hires', 'sky', 'jyeffect', 'jymaster', 'dolby'],
'config': {
'downloads_dir': 'configured',
'max_body_bytes': '2MB(备份上传 200MB)',
},
}
return success(info, "API信息获取成功")
except Exception:
return error("服务暂时不可用,请稍后再试", 500)