From d5241a2eb88590be1c741c2c4258fbff8208fb14 Mon Sep 17 00:00:00 2001 From: InfinityPacer <160988576+InfinityPacer@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:52:07 +0800 Subject: [PATCH] chore: Integrate pip-tools and safety, upgrade vulnerable dependencies --- .gitignore | 1 + app/main.py | 17 +- docs/development-setup.md | 108 ++++++++++++ requirements.in | 62 +++++++ requirements.txt | 353 +++++++++++++++++++++++++++++++------- safety.policy.yml | 9 + 6 files changed, 486 insertions(+), 64 deletions(-) create mode 100644 docs/development-setup.md create mode 100644 requirements.in create mode 100644 safety.policy.yml diff --git a/.gitignore b/.gitignore index f7305d1a..9d135e49 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build/ dist/ nginx/ test.py +safety_report.txt app/helper/sites.py app/helper/*.so app/helper/*.pyd diff --git a/app/main.py b/app/main.py index bb1bc4c8..94d5bdf8 100644 --- a/app/main.py +++ b/app/main.py @@ -3,6 +3,7 @@ import os import signal import sys import threading +from contextlib import asynccontextmanager from types import FrameType import uvicorn as uvicorn @@ -41,9 +42,21 @@ from app.command import Command, CommandChian from app.schemas import Notification, NotificationType +@asynccontextmanager +async def lifespan(app: FastAPI): + try: + print("Starting up...") + start_module() + yield + finally: + print("Shutting down...") + shutdown_server() + + # App App = FastAPI(title=settings.PROJECT_NAME, - openapi_url=f"{settings.API_V1_STR}/openapi.json") + openapi_url=f"{settings.API_V1_STR}/openapi.json", + lifespan=lifespan) # 跨域 App.add_middleware( @@ -189,7 +202,6 @@ def singal_handle(): signal.signal(signal.SIGINT, stop_event) -@App.on_event("shutdown") def shutdown_server(): """ 服务关闭 @@ -213,7 +225,6 @@ def shutdown_server(): stop_frontend() -@App.on_event("startup") def start_module(): """ 启动模块 diff --git a/docs/development-setup.md b/docs/development-setup.md new file mode 100644 index 00000000..cb728e93 --- /dev/null +++ b/docs/development-setup.md @@ -0,0 +1,108 @@ +## 开发环境设置指南 + +本文档旨在帮助开发者快速设置开发环境,并介绍如何使用 `pip-tools` 管理依赖项和使用 `safety` 进行安全检查。 + +### 环境准备 + +在开始之前,请确保您的系统已安装以下软件: + +- **Python 3.11 或更高版本** +- **pip** (Python 包管理器) +- **Git** (用于版本控制) + +### 1. 创建虚拟环境 + +在项目根目录下创建并激活虚拟环境: + +- 在 Windows 上: + + ```bash + python -m venv venv + .\venv\Scripts\activate + ``` + +- 在 macOS/Linux 上: + + ```bash + python3 -m venv venv + source venv/bin/activate + ``` + +虚拟环境确保项目的依赖项与系统全局环境隔离,防止冲突。 + +### 2. 使用 pip-tools 管理依赖项 + +我们使用 `pip-tools` 来管理项目的 Python 依赖项,这有助于保持 `requirements.txt` 文件的一致性和更新性。 + +#### 安装 pip-tools + +首先,您需要安装 `pip-tools` 以便管理依赖项: + +```bash +pip install pip-tools +``` + +#### 管理依赖项 + +1. **修改 `requirements.in` 文件**: + + `requirements.in` 文件是项目依赖项的源文件。要添加或更新依赖项,请直接编辑该文件。 + +2. **生成 `requirements.txt` 文件**: + + 编辑完 `requirements.in` 文件后,运行以下命令生成或更新 `requirements.txt` 文件: + + ```bash + pip-compile requirements.in + ``` + + 这将根据 `requirements.in` 中指定的依赖项生成一个锁定的 `requirements.txt` 文件。 + +3. **安装依赖项**: + + 使用以下命令安装 `requirements.txt` 文件中列出的依赖项: + + ```bash + pip install -r requirements.txt + ``` + +### 3. 运行安全检查 + +我们使用 `safety` 工具来检查依赖项中是否存在已知的安全漏洞。请确保在每次更新依赖项后都运行安全检查,以确保项目的安全性。 + +#### 安装 safety + +您可以使用以下命令安装 `safety`: + +```bash +pip install safety +``` + +#### 执行安全检查 + +运行以下命令以检查 `requirements.txt` 文件中列出的依赖项是否存在安全漏洞: + +```bash +safety check -r requirements.txt --policy-file=safety.policy.yml > safety_report.txt +``` + +这将生成一个名为 `safety_report.txt` 的报告文件,您可以查看其中的漏洞报告并进行相应处理。 + +### 4. 提交代码前的检查 + +在提交代码之前,请确保完成以下步骤: + +1. **确保依赖项已更新**:如果您对 `requirements.in` 进行了更改,请重新生成 `requirements.txt` 并安装依赖项。 + +2. **运行安全检查**:确保 `safety` 检查通过,没有新的安全漏洞。 + +3. **运行测试**:如果项目中包含测试,请确保所有测试都通过。运行以下命令以执行测试: + + ```bash + pytest + ``` + +### 5. 参考资源 + +- [pip-tools 官方文档](https://github.com/jazzband/pip-tools) +- [safety 官方文档](https://pyup.io/safety/) \ No newline at end of file diff --git a/requirements.in b/requirements.in new file mode 100644 index 00000000..db02fd69 --- /dev/null +++ b/requirements.in @@ -0,0 +1,62 @@ +Cython~=3.0.2 +pydantic~=1.10.13 +SQLAlchemy~=2.0.15 +uvicorn~=0.22.0 +fastapi~=0.112.1 +passlib~=1.7.4 +PyJWT~=2.7.0 +python-multipart~=0.0.9 +alembic~=1.11.1 +bcrypt~=4.0.1 +regex~=2023.6.3 +cn2an~=0.5.19 +dateparser~=1.1.8 +python-dateutil~=2.8.2 +zhconv~=1.4.3 +anitopy~=2.1.1 +requests[socks]~=2.32.3 +urllib3~=2.2.2 +lxml~=4.9.2 +pyquery~=2.0.0 +ruamel.yaml~=0.17.31 +APScheduler~=3.10.1 +cryptography~=43.0.0 +pytz~=2023.3 +pycryptodome~=3.20.0 +qbittorrent-api==2023.5.48 +plexapi~=4.15.16 +transmission-rpc~=4.3.0 +Jinja2~=3.1.4 +pyparsing~=3.0.9 +func_timeout==4.3.5 +bs4~=0.0.1 +beautifulsoup4~=4.12.2 +pillow~=10.4.0 +pyTelegramBotAPI~=4.12.0 +playwright~=1.37.0 +cf-clearance~=0.31.0 +torrentool~=1.2.0 +slack-bolt~=1.18.0 +slack-sdk~=3.21.3 +chardet~=4.0.0 +starlette~=0.38.2 +PyVirtualDisplay~=3.0 +psutil~=5.9.4 +python-dotenv~=1.0.1 +python-hosts~=1.0.7 +watchdog~=3.0.0 +tailer~=0.4.1 +openai~=0.27.2 +cacheout~=0.14.1 +click~=8.1.6 +requests-cache~=0.5.2 +parse~=1.19.0 +docker~=6.1.3 +cachetools~=5.3.1 +fast-bencode~=1.1.3 +pystray~=0.19.5 +pyotp~=2.9.0 +Pinyin2Hanzi~=0.1.1 +pywebpush~=2.0.0 +py115~=0.0.4 +oss2~=2.18.6 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 7b1edaf8..4db2a4f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,62 +1,293 @@ -Cython~=3.0.2 -pydantic~=1.10.8 -SQLAlchemy~=2.0.15 -uvicorn~=0.22.0 -fastapi~=0.96.0 -passlib~=1.7.4 -PyJWT~=2.7.0 -python-multipart~=0.0.6 -alembic~=1.11.1 -bcrypt~=4.0.1 -regex~=2023.6.3 -cn2an~=0.5.19 -dateparser~=1.1.8 -python-dateutil~=2.8.2 -zhconv~=1.4.3 -anitopy~=2.1.1 -requests[socks]~=2.31.0 -urllib3~=2.0.2 -lxml~=4.9.2 -pyquery~=2.0.0 -ruamel.yaml~=0.17.31 -APScheduler~=3.10.1 -cryptography~=41.0.1 -pytz~=2023.3 -pycryptodome~=3.18.0 +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile requirements.in +# +aiohappyeyeballs==2.4.0 + # via aiohttp +aiohttp==3.10.5 + # via + # openai + # pywebpush +aiosignal==1.3.1 + # via aiohttp +alembic==1.11.3 + # via -r requirements.in +aliyun-python-sdk-core==2.15.1 + # via + # aliyun-python-sdk-kms + # oss2 +aliyun-python-sdk-kms==2.16.4 + # via oss2 +anitopy==2.1.1 + # via -r requirements.in +anyio==4.4.0 + # via starlette +apscheduler==3.10.4 + # via -r requirements.in +attrs==24.2.0 + # via aiohttp +bcrypt==4.0.1 + # via -r requirements.in +beautifulsoup4==4.12.3 + # via + # -r requirements.in + # bs4 +bs4==0.0.2 + # via -r requirements.in +cacheout==0.14.1 + # via -r requirements.in +cachetools==5.3.3 + # via -r requirements.in +certifi==2024.7.4 + # via requests +cf-clearance==0.31.0 + # via -r requirements.in +cffi==1.17.0 + # via cryptography +chardet==4.0.0 + # via -r requirements.in +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via + # -r requirements.in + # uvicorn +cn2an==0.5.22 + # via -r requirements.in +colorama==0.4.6 + # via + # click + # tqdm +crcmod==1.7 + # via oss2 +cryptography==43.0.0 + # via + # -r requirements.in + # aliyun-python-sdk-core + # http-ece + # py-vapid + # pywebpush +cssselect==1.2.0 + # via pyquery +cython==3.0.11 + # via -r requirements.in +dateparser==1.1.8 + # via -r requirements.in +docker==6.1.3 + # via -r requirements.in +fast-bencode==1.1.6 + # via -r requirements.in +fastapi==0.112.1 + # via -r requirements.in +frozenlist==1.4.1 + # via + # aiohttp + # aiosignal +func-timeout==4.3.5 + # via -r requirements.in +greenlet==2.0.2 + # via + # playwright + # sqlalchemy +h11==0.14.0 + # via uvicorn +http-ece==1.2.1 + # via pywebpush +idna==3.7 + # via + # anyio + # requests + # yarl +jinja2==3.1.4 + # via -r requirements.in +jmespath==0.10.0 + # via aliyun-python-sdk-core +lxml==4.9.4 + # via + # -r requirements.in + # pyquery +lz4==4.3.3 + # via py115 +mako==1.3.5 + # via alembic +markupsafe==2.1.5 + # via + # jinja2 + # mako +multidict==6.0.5 + # via + # aiohttp + # yarl +openai==0.27.10 + # via -r requirements.in +oss2==2.18.6 + # via -r requirements.in +packaging==24.1 + # via docker +parse==1.19.1 + # via -r requirements.in +passlib==1.7.4 + # via -r requirements.in +pillow==10.4.0 + # via + # -r requirements.in + # pystray +pinyin2hanzi==0.1.1 + # via -r requirements.in +playwright==1.37.0 + # via + # -r requirements.in + # cf-clearance +plexapi==4.15.16 + # via -r requirements.in +proces==0.1.7 + # via cn2an +psutil==5.9.8 + # via -r requirements.in +py-vapid==1.9.1 + # via pywebpush +py115==0.0.4 + # via -r requirements.in +pycparser==2.22 + # via cffi +pycryptodome==3.20.0 + # via + # -r requirements.in + # oss2 + # py115 +pydantic==1.10.17 + # via + # -r requirements.in + # fastapi +pyee==9.0.4 + # via playwright +pyjwt==2.7.0 + # via -r requirements.in +pyotp==2.9.0 + # via -r requirements.in +pyparsing==3.0.9 + # via -r requirements.in +pyquery==2.0.0 + # via -r requirements.in +pysocks==1.7.1 + # via requests +pystray==0.19.5 + # via -r requirements.in +pytelegrambotapi==4.12.0 + # via -r requirements.in +python-dateutil==2.8.2 + # via + # -r requirements.in + # dateparser +python-dotenv==1.0.1 + # via -r requirements.in +python-hosts==1.0.7 + # via -r requirements.in +python-multipart==0.0.9 + # via -r requirements.in +pytz==2023.4 + # via + # -r requirements.in + # apscheduler + # dateparser + # py115 +pyvirtualdisplay==3.0 + # via -r requirements.in +pywebpush==2.0.0 + # via -r requirements.in +pywin32==306 + # via docker qbittorrent-api==2023.5.48 -plexapi~=4.15.12 -transmission-rpc~=4.3.0 -Jinja2~=3.1.2 -pyparsing~=3.0.9 -func_timeout==4.3.5 -bs4~=0.0.1 -beautifulsoup4~=4.12.2 -pillow~=9.5.0 -pyTelegramBotAPI~=4.12.0 -playwright~=1.37.0 -cf_clearance~=0.29.2 -torrentool~=1.2.0 -slack_bolt~=1.18.0 -slack_sdk~=3.21.3 -chardet~=4.0.0 -starlette~=0.27.0 -PyVirtualDisplay~=3.0 -psutil~=5.9.4 -python_dotenv~=1.0.0 -python_hosts~=1.0.3 -watchdog~=3.0.0 -tailer~=0.4.1 -openai~=0.27.2 -cacheout~=0.14.1 -click~=8.1.6 -requests_cache~=0.5.2 -parse~=1.19.0 -docker~=6.1.3 -cachetools~=5.3.1 -fast-bencode~=1.1.3 -pystray~=0.19.5 -pyotp~=2.9.0 -Pinyin2Hanzi~=0.1.1 -pywebpush~=2.0.0 -py115~=0.0.4 -oss2~=2.18.6 \ No newline at end of file + # via -r requirements.in +regex==2023.6.3 + # via + # -r requirements.in + # dateparser +requests[socks]==2.32.3 + # via + # -r requirements.in + # docker + # openai + # oss2 + # plexapi + # py115 + # pytelegrambotapi + # pywebpush + # qbittorrent-api + # requests-cache + # transmission-rpc +requests-cache==0.5.2 + # via -r requirements.in +ruamel-yaml==0.17.40 + # via -r requirements.in +ruamel-yaml-clib==0.2.8 + # via ruamel-yaml +six==1.16.0 + # via + # apscheduler + # oss2 + # pystray + # python-dateutil + # pywebpush + # qbittorrent-api +slack-bolt==1.18.0 + # via -r requirements.in +slack-sdk==3.21.3 + # via + # -r requirements.in + # slack-bolt +sniffio==1.3.1 + # via anyio +soupsieve==2.6 + # via beautifulsoup4 +sqlalchemy==2.0.32 + # via + # -r requirements.in + # alembic +starlette==0.38.2 + # via + # -r requirements.in + # fastapi +tailer==0.4.1 + # via -r requirements.in +torrentool==1.2.0 + # via -r requirements.in +tqdm==4.66.5 + # via openai +transmission-rpc==4.3.1 + # via -r requirements.in +typing-extensions==4.12.2 + # via + # alembic + # fastapi + # pydantic + # pyee + # sqlalchemy + # transmission-rpc +tzdata==2024.1 + # via tzlocal +tzlocal==5.2 + # via + # apscheduler + # dateparser +urllib3==2.2.2 + # via + # -r requirements.in + # docker + # qbittorrent-api + # requests +uvicorn==0.22.0 + # via -r requirements.in +watchdog==3.0.0 + # via -r requirements.in +websocket-client==1.8.0 + # via docker +yarl==1.9.4 + # via aiohttp +zhconv==1.4.3 + # via -r requirements.in + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/safety.policy.yml b/safety.policy.yml new file mode 100644 index 00000000..5b2b2d74 --- /dev/null +++ b/safety.policy.yml @@ -0,0 +1,9 @@ +security: + ignore-unpinned-requirements: False + ignore-vulnerabilities: + 70612: + reason: The official statement indicates that this vulnerability is not valid because users should use sandboxing when handling untrusted templates. + 65532: + reason: Legacy issue related to tvdbapi usage. + 40100: + reason: Legacy issue related to tvdbapi usage.