全局 Rules
---
## Cursor Rules for Comment Standards(注释规范 Cursor 规则)
### 1. 总体注释原则
- **目的**:注释应解释代码的**意图**(为什么这样做)、**复杂逻辑**或**非显而易见的实现细节**,而不是重复代码的字面含义。
- **简洁性**:注释应简明扼要,避免冗长或无意义的描述。
- **语言**:注释使用**中文**,确保团队成员一致理解;必要时可结合英文(如引用第三方库文档)。
- **维护性**:注释需与代码同步更新,避免过时或误导性注释。
- **格式**:遵循 PEP 8 规范,注释与代码对齐,使用适当的缩进和空行。
### 2. 注释类型与规范
以下是项目中常用的注释类型及其具体规范,适用于 `src/`、`scripts/`、`tests/` 等目录中的 Python 代码。
#### 2.1 模块级注释(Module-Level Comments)
- **位置**:位于模块顶部,紧跟 `import` 语句之前或之后。
- **内容**:描述模块的**功能**、**主要职责**和**使用场景**。
- **格式**:使用多行注释(`"""` 或 `#`),以 `#` 开头每行对齐。
- **示例**(`src/modules/adspower/client.py`):
```python
# 本模块封装 AdsPower 本地 API 客户端,用于管理浏览器实例的启动、停止和状态检查。
# 主要功能包括速率限制、多进程同步和错误重试机制。
# 使用时需配置 config.yaml 中的 adspower 字段。
```
#### 2.2 函数与方法注释(Function/Method Comments)
- **位置**:使用 **Docstring**,位于函数或方法定义下方。
- **内容**:
- 简要描述函数功能。
- 列出所有参数(`Args`)、返回值(`Returns`)和可能的异常(`Raises`)。
- 可选:补充使用场景或注意事项。
- **格式**:采用 **Google 风格** Docstring,使用三引号(`"""`)。
- **规范**:
- 参数和返回值需包含类型注解。
- 每个部分(Args、Returns、Raises)使用缩进对齐。
- **示例**(`src/utils/config.py`):
```python
def load_config(config_path: str) -> dict:
"""加载 YAML 配置文件并解析路径
Args:
config_path (str): 配置文件路径
Returns:
dict: 解析后的配置字典
Raises:
FileNotFoundError: 配置文件不存在
yaml.YAMLError: 配置文件格式错误
"""
```
- **注意**:简单函数(如 getter/setter)可使用单行 Docstring,但仍需说明功能:
```python
def get_logger(module_name: str) -> logging.Logger:
"""获取指定模块的日志记录器"""
```
#### 2.3 类注释(Class Comments)
- **位置**:使用 Docstring,位于类定义下方。
- **内容**:
- 描述类的**职责**和**主要功能**。
- 列出关键属性(`Attributes`)和初始化参数(`Args`)。
- 可选:说明类的主要方法或使用场景。
- **格式**:Google 风格 Docstring。
- **示例**(`src/modules/adspower/client.py`):
```python
class AdsPowerLocalApi:
"""AdsPower 本地 API 客户端,支持多进程速率限制
Attributes:
user_id (str): AdsPower 环境 ID
base_url (str): API 基础 URL,从 config.yaml 加载
Args:
user_id (str): AdsPower 环境 ID(必需)
acc_id (str, optional): 账户标识符,默认为 user_id
headless (int, optional): 无头模式(0=有界面,1=无界面),默认为 0
timeout (int, optional): 请求超时时间(秒),默认为 10
"""
```
#### 2.4 行内注释(Inline Comments)
- **位置**:位于代码行末尾,与代码间隔至少两个空格。
- **内容**:解释**复杂逻辑**、**魔法数字**或**特殊处理**,避免描述显而易见的内容。
- **格式**:使用 `#` 开头,简短且清晰。
- **规范**:
- 行内注释应少用,仅在必要时添加。
- 避免过长,超 40 字符的注释建议改为块注释。
- **示例**(`src/modules/adspower/client.py`):
```python
interval = RATE_LIMIT_INTERVALS.get(endpoint, RATE_LIMIT_INTERVALS['default']) # 获取端点特定间隔,默认为 1.0 秒
```
#### 2.5 块注释(Block Comments)
- **位置**:位于代码段之前,描述一段逻辑的**目的**或**步骤**。
- **内容**:解释多行代码的整体意图,适用于复杂算法或流程。
- **格式**:每行以 `#` 开头,与代码缩进对齐,上下各空一行。
- **示例**(`src/modules/adspower/client.py`):
```python
# 全局同步速率限制,确保多进程环境下 API 调用不超频
try:
with RATE_LIMIT_LOCK.acquire(timeout=5):
with open(RATE_LIMIT_FILE, 'r') as f:
state = json.load(f)
```
#### 2.6 TODO 注释
- **位置**:位于需要后续处理的地方,可为行内或块注释。
- **内容**:说明待完成的任务、优化点或问题,包含负责人(可选)和预期完成时间(推荐)。
- **格式**:使用 `# TODO:` 前缀,清晰描述任务。
- **示例**:
```python
# TODO: 添加对 AdsPower API 新端点 /restart 的支持 (负责人: 张三, 预计: 2025-08-15)
```
### 3. 注释使用场景
- **资源路径处理**:
- 在使用 `resource_path` 的地方,注释说明路径用途和打包环境兼容性。
- 示例(`src/utils/helpers.py`):
```python
def resource_path(relative_path: str) -> str:
"""获取资源文件的绝对路径,支持开发和 PyInstaller 打包环境
Args:
relative_path (str): 相对路径,如 'config/config.yaml'
Returns:
str: 绝对路径
"""
# 检查是否为 PyInstaller 打包环境
if hasattr(sys, '_MEIPASS'):
base_path = Path(sys._MEIPASS) # 打包后的临时目录
else:
base_path = Path(__file__).resolve().parent.parent.parent # 开发环境根目录
return str(base_path / relative_path)
```
- **配置加载**:
- 在 `load_config` 中,注释说明配置字段的默认值和异常处理逻辑。
- 示例(`src/utils/config.py`):
```python
# 设置默认 rate_limit_intervals,防止配置文件缺失
if 'rate_limit_intervals' not in config['adspower']:
config['adspower']['rate_limit_intervals'] = {'default': 1.0, 'start': 1.0, 'stop': 1.0, 'active': 0.5}
```
- **API 请求**:
- 在 AdsPower API 调用(如 `start_remote_browser`)中,注释说明重试机制和错误处理。
- 示例(`src/modules/adspower/client.py`):
```python
# 重试 3 次以处理网络波动,每次间隔 1 秒
for attempt in range(3):
try:
response = requests.get(url, params=params, timeout=self.timeout)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
if attempt < 2:
time.sleep(1.0) # 等待 1 秒后重试
continue
logger.error(f"请求失败: {e}")
return None
```
- **日志管理**:
- 在 `logger.py` 中,注释说明日志轮转机制和敏感信息过滤。
- 示例(`src/utils/logger.py`):
```python
# 配置日志轮转,限制文件大小为 10MB,保留最近 30 个文件
handler = RotatingFileHandler(
f"{log_dir}/{datetime.today().isoformat()}.log",
maxBytes=10*1024*1024, # 10MB
backupCount=30
)
```
### 4. 注释注意事项
- **避免冗余**:
- 不要注释显而易见的代码,如 `x = 1 # 设置 x 为 1`。
- 示例(不推荐):
```python
config = yaml.safe_load(f) # 加载 YAML 文件
```
- 改为(推荐):
```python
config = yaml.safe_load(f) # 解析 config.yaml 并返回字典
```
- **保持同步**:
- 修改代码时,同步更新相关注释,特别是在更改函数参数或逻辑时。
- 示例:若 `load_config` 新增参数,需更新 Docstring:
```python
def load_config(config_path: str, env: str = "dev") -> dict:
"""加载 YAML 配置文件并解析路径
Args:
config_path (str): 配置文件路径
env (str, optional): 环境名称,默认为 'dev'
Returns:
dict: 解析后的配置字典
"""
```
- **敏感信息**:
- 注释中不得包含敏感信息(如 API 密钥、用户 ID)。
- 示例(不推荐):
```python
# 使用密钥 ABC123 调用 API
```
- 改为(推荐):
```python
# 使用 config.yaml 中的 API 密钥调用接口
```
- **一致性**:
- 统一使用中文注释,除非引用英文文档或第三方库术语(如 `PyInstaller` 的 `_MEIPASS`)。
- 所有 Docstring 使用 Google 风格,避免混用其他风格(如 reStructuredText)。
### 5. Cursor 提示示例
在 Cursor 中编写代码时,可使用以下提示,确保注释符合规范:
- **添加函数注释**:
```
为 src/modules/my_module.py 中的新函数 process_data 添加 Google 风格 Docstring,说明功能、参数、返回值和异常,注释复杂逻辑。
```
- **更新模块注释**:
```
为 src/modules/adspower/client.py 添加模块级注释,描述模块职责和配置要求,使用 # 格式。
```
- **添加 TODO 注释**:
```
在 src/utils/config.py 的 load_config 函数中添加 TODO 注释,说明计划支持 JSON 格式配置,包含负责人和截止日期。
```
---
感谢您的要求!以下是基于您提供的项目目录结构和代码,针对**使用安全的第三方库**的 **Cursor Rules** 补充说明。这些规则专注于在开发本地化可执行文件时选择和使用安全的第三方库,确保项目的安全性、稳定性和兼容性,同时符合注释规范和项目结构要求。内容以中文表述,适用于 Cursor 或其他代码编辑器,并特别考虑 PyInstaller 打包环境。
---
## Cursor Rules for Using Safe Third-Party Libraries(使用安全的第三方库 Cursor 规则)
### 1. 第三方库选择原则
- **安全性**:
- 优先选择经过广泛使用和社区维护的成熟库,避免使用未经充分验证或长期未更新的库。
- 检查库的 GitHub 仓库活跃度(最近提交时间、问题响应速度)和安全漏洞报告(如通过 `pip-audit` 或 GitHub Dependabot)。
- 避免使用包含已知安全漏洞的库版本,定期更新到最新稳定版本。
- **兼容性**:
- 确保库与项目使用的 Python 版本(推荐 Python 3.8+)和 PyInstaller 打包环境兼容。
- 检查库是否支持跨平台(Windows、macOS、Linux),特别是针对 `data/` 和 `config/` 文件的路径处理。
- **许可证**:
- 选择与项目许可证(如 MIT/Apache 2.0)兼容的库,避免使用限制性许可证(如 GPL)导致分发问题。
- 记录使用的第三方库及其许可证信息,更新 `docs/README.md` 或 `LICENSE` 文件。
- **最小化依赖**:
- 仅引入必要的库,减少打包体积和潜在的安全风险。
- 示例:优先使用标准库(如 `pathlib`、`json`)替代第三方库(如 `os.path` 的替代品)。
### 2. 当前使用的第三方库
根据您提供的代码,以下是项目中已使用的第三方库及其安全使用建议:
- **`pyyaml`**:用于解析 `config.yaml`。
- **安全建议**:
- 使用 `yaml.safe_load`(已实现),避免 `yaml.load` 以防止代码注入风险。
- 示例(`src/utils/config.py`):
```python
import yaml
def load_config(config_path: str) -> dict:
"""加载 YAML 配置文件并解析路径"""
with open(config_path, 'r') as f:
config = yaml.safe_load(f) or {} # 使用 safe_load 防止代码注入
return config
```
- 确保版本为最新(如 `pyyaml>=6.0`),检查漏洞(如 CVE-2020-1747)。
- **`requests`**:用于 AdsPower API 调用。
- **安全建议**:
- 确保使用 HTTPS 协议(如 `http://localhost:50325` 改为 `https://` 如果支持)。
- 配置合理的超时时间(已实现,`timeout=self.timeout`)。
- 示例(`src/modules/adspower/client.py`):
```python
response = requests.get(
f"{self.base_url}/api/v1/browser/start",
params={"user_id": self.user_id, "headless": self.headless},
timeout=self.timeout # 设置超时防止挂起
)
```
- 定期更新到最新版本(如 `requests>=2.28`),检查漏洞(如 CVE-2023-32681)。
- **`filelock`**:用于多进程速率限制。
- **安全建议**:
- 确保锁文件(如 `ads_power_rate_limit.json.lock`)存储在 `data/adspower/`,通过 `resource_path` 访问。
- 处理 `Timeout` 异常并记录日志。
- 示例(`src/modules/adspower/client.py`):
```python
from filelock import FileLock, Timeout
from src.utils.helpers import resource_path
RATE_LIMIT_FILE = resource_path(config['adspower']['rate_limit_file'])
RATE_LIMIT_LOCK = FileLock(str(RATE_LIMIT_FILE) + ".lock")
def _init_rate_limit_file(self):
"""初始化速率控制文件"""
try:
with RATE_LIMIT_LOCK.acquire(timeout=5):
if not RATE_LIMIT_FILE.exists():
with open(RATE_LIMIT_FILE, 'w') as f:
json.dump({"start": 0, "stop": 0, "active": 0}, f)
except Timeout:
logger.warning(f"初始化 {RATE_LIMIT_FILE} 超时,重置文件") # 记录超时情况
```
- 使用最新版本(如 `filelock>=3.12`)。
- **`python-dotenv`**:加载 `.env` 文件中的环境变量。
- **安全建议**:
- 确保 `.env` 文件在 `.gitignore` 中,避免泄露敏感信息。
- 验证环境变量是否存在并设置默认值。
- 示例:
```python
from dotenv import load_dotenv
import os
load_dotenv()
env = os.getenv("ENV", "dev") # 设置默认环境为 dev
```
- 使用最新版本(如 `python-dotenv>=1.0`)。
- **`pyinstaller`**:用于打包可执行文件。
- **安全建议**:
- 确保 `pyinstaller` 版本与 Python 版本兼容(如 `pyinstaller>=5.0`)。
- 使用 `--clean` 选项清理缓存,减少打包错误。
- 示例打包命令:
```bash
pyinstaller --clean build.spec
```
### 3. 第三方库管理规范
- **记录依赖**:
- 将所有第三方库记录在 `requirements.txt` 和 `pyproject.toml` 中,确保版本明确。
- 示例 `requirements.txt`:
```
pyyaml>=6.0
requests>=2.28
filelock>=3.12
python-dotenv>=1.0
pyinstaller>=5.0
```
- 示例 `pyproject.toml`:
```toml
[project]
name = "project_name"
version = "0.1.0"
dependencies = [
"pyyaml>=6.0",
"requests>=2.28",
"filelock>=3.12",
"python-dotenv>=1.0",
"pyinstaller>=5.0",
]
```
- **依赖安装**:
- 使用 `pip install -r requirements.txt` 安装依赖。
- 推荐使用虚拟环境(如 `venv`)隔离项目依赖:
```bash
python -m venv venv
source venv/bin/activate # Linux/macOS
venv\Scripts\activate # Windows
pip install -r requirements.txt
```
- **依赖更新**:
- 定期运行 `pip-audit` 检查依赖的安全漏洞:
```bash
pip install pip-audit
pip-audit -r requirements.txt
```
- 更新到最新安全版本,使用 `pip install --upgrade <package>`。
- **PyInstaller 兼容性**:
- 确保第三方库在打包后正常工作,测试 `data/` 和 `config/` 文件访问。
- 在 `build.spec` 中显式包含第三方库的数据文件:
```python
from PyInstaller.utils.hooks import collect_data_files
a = Analysis(
['src/main.py'],
datas=[
('config/*', 'config'),
('data/input/*', 'data/input'),
('data/adspower/*', 'data/adspower')
],
hiddenimports=['yaml', 'requests', 'filelock', 'python-dotenv']
)
```
### 4. 安全使用第三方库的代码规范
- **配置加载(`pyyaml`)**:
- 始终使用 `yaml.safe_load` 解析 YAML 文件,防止代码注入。
- 添加注释说明安全措施:
```python
import yaml
from src.utils.helpers import resource_path
def load_config(config_path: str) -> dict:
"""加载 YAML 配置文件并解析路径
Args:
config_path (str): 配置文件路径
Returns:
dict: 解析后的配置字典
Raises:
FileNotFoundError: 配置文件不存在
yaml.YAMLError: 配置文件格式错误
"""
config_path = resource_path(config_path) # 确保兼容 PyInstaller
try:
with open(config_path, 'r') as f:
config = yaml.safe_load(f) or {} # 使用 safe_load 防止代码注入
except FileNotFoundError:
raise FileNotFoundError(f"配置文件 {config_path} 不存在")
except yaml.YAMLError as e:
raise yaml.YAMLError(f"解析配置文件 {config_path} 失败: {e}")
return config
```
- **API 请求(`requests`)**:
- 使用 HTTPS 协议,设置超时,处理异常。
- 添加注释说明安全性和重试逻辑:
```python
import requests
from src.utils.logger import get_logger
logger = get_logger(__name__)
def start_remote_browser(self):
"""启动浏览器实例
Returns:
str: 浏览器 WebSocket 地址(成功时)
None: 失败时
"""
self._rate_limit("start") # 确保速率限制
for attempt in range(3):
try:
response = requests.get(
f"{self.base_url}/api/v1/browser/start",
params={"user_id": self.user_id, "headless": self.headless},
timeout=self.timeout # 设置超时防止挂起
)
response.raise_for_status() # 检查 HTTP 状态码
data = response.json()
if data.get("code") != 0:
logger.error(f"启动浏览器失败: {data.get('msg', '未知错误')}")
return None
return data["data"]["ws"]["puppeteer"]
except requests.RequestException as e:
if attempt < 2:
time.sleep(1.0) # 重试间隔 1 秒
continue
logger.error(f"启动浏览器失败: {e}")
return None
```
- **文件锁(`filelock`)**:
- 使用 `resource_path` 确保锁文件路径正确。
- 处理 `Timeout` 异常并记录日志:
```python
from filelock import FileLock, Timeout
from src.utils.helpers import resource_path
RATE_LIMIT_FILE = resource_path(config['adspower']['rate_limit_file'])
RATE_LIMIT_LOCK = FileLock(str(RATE_LIMIT_FILE) + ".lock")
def _init_rate_limit_file(self):
"""初始化速率控制文件,确保多进程安全"""
try:
with RATE_LIMIT_LOCK.acquire(timeout=5): # 设置 5 秒超时
if not RATE_LIMIT_FILE.exists():
with open(RATE_LIMIT_FILE, 'w') as f:
json.dump({"start": 0, "stop": 0, "active": 0}, f)
except Timeout:
logger.warning(f"初始化 {RATE_LIMIT_FILE} 超时,重置文件")
with open(RATE_LIMIT_FILE, 'w') as f:
json.dump({"start": 0, "stop": 0, "active": 0}, f)
```
- **环境变量(`python-dotenv`)**:
- 确保 `.env` 文件安全加载,注释说明敏感信息处理:
```python
from dotenv import load_dotenv
import os
load_dotenv() # 加载 .env 文件中的环境变量
BASE_URL = os.getenv("ADPOWER_URL", "http://localhost:50325") # 默认值防止缺失
```
### 5. 注释规范(与第三方库相关)
- **库用途**:在模块级注释中说明使用的第三方库及其功能。
- 示例(`src/modules/adspower/client.py`):
```python
# 本模块封装 AdsPower 本地 API 客户端,依赖 requests(HTTP 请求)、filelock(多进程锁)和 pyyaml(配置解析)。
# 所有文件路径通过 resource_path 处理,确保 PyInstaller 打包兼容。
```
- **安全措施**:在代码中注释说明第三方库的安全使用方式。
- 示例(`src/utils/config.py`):
```python
config = yaml.safe_load(f) # 使用 safe_load 防止 YAML 代码注入风险
```
- **版本说明**:在 `docs/README.md` 或模块注释中记录推荐的库版本。
- 示例(`docs/README.md`):
```markdown
## 依赖
- pyyaml>=6.0: 安全的 YAML 解析
- requests>=2.28: HTTP 请求,支持超时和重试
- filelock>=3.12: 多进程文件锁
- python-dotenv>=1.0: 环境变量加载
- pyinstaller>=5.0: 打包为可执行文件
```
### 6. PyInstaller 打包与第三方库
- **包含依赖**:
- 在 `build.spec` 中通过 `hiddenimports` 显式包含第三方库:
```python
a = Analysis(
['src/main.py'],
hiddenimports=['yaml', 'requests', 'filelock', 'python-dotenv'],
datas=[
('config/*', 'config'),
('data/input/*', 'data/input'),
('data/adspower/*', 'data/adspower')
]
)
```
- **测试打包**:
- 打包后运行可执行文件,验证第三方库功能:
- 检查 `yaml.safe_load` 是否正确解析 `config.yaml`。
- 验证 `requests` 是否能正常访问 AdsPower API。
- 确保 `filelock` 正确管理 `ads_power_rate_limit.json`。
- **日志记录**:
- 在打包环境中记录第三方库相关错误:
```python
try:
import yaml
except ImportError:
logger.error("未找到 pyyaml 库,请确保已安装 pyyaml>=6.0")
raise
```
### 7. Cursor 提示示例
在 Cursor 中使用以下提示,确保第三方库安全集成:
- **添加新库**:
```
在 src/utils/ 中添加新模块 crypto.py,使用 cryptography 库(版本>=40.0)进行数据加密,添加 Google 风格 Docstring,说明安全措施,并在 requirements.txt 中记录。
```
- **安全配置**:
```
修改 src/utils/config.py,使用 yaml.safe_load 解析 config.yaml,添加注释说明安全性和 resource_path 使用。
```
- **打包配置**:
```
更新 build.spec,确保包含 pyyaml、requests 和 data/adspower/ 目录,验证 resource_path 在打包后正常工作。
```
### 8. 其他注意事项
- **安全扫描**:
- 定期使用 `pip-audit` 检查依赖漏洞:
```bash
pip-audit -r requirements.txt
```
- **最小化权限**:
- 限制第三方库的权限,如避免 `requests` 访问非必要 URL。
- 示例:
```python
if not self.base_url.startswith("https://"):
logger.warning(f"非 HTTPS 协议 URL: {self.base_url},建议启用 HTTPS")
```
- **文档更新**:
- 在 `docs/README.md` 中记录新增第三方库的用途、版本和安全注意事项。
- 示例:
```markdown
### 新增依赖
- cryptography>=40.0: 用于加密敏感数据,需确保使用安全的密钥管理。
```
最新发布