🔧 chore(config): 移动配置文件到Python目录

- 将.pre-commit-config.yaml移动到Python目录以便于管理
- 其他相关文件也进行了相应的重命名和移动
This commit is contained in:
2025-03-29 21:11:10 +08:00
parent f1aca8531a
commit 580dafb9af
6 changed files with 25 additions and 25 deletions

View File

@@ -0,0 +1,25 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-merge-conflict
- id: check-symlinks
- id: mixed-line-ending
- id: debug-statements
- repo: https://github.com/psf/black
rev: 24.3.0
hooks:
- id: black
language_version: python3.12
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
args: ["--profile", "black"]

View File

@@ -0,0 +1,81 @@
---
description: Python 库项目开发最佳实践与规范
---
# Python 库项目开发规范
## 依赖管理
- 使用`uv`管理依赖
## 项目结构
- 项目整体结构如下:
```markdown
$PROJECT_ROOT/
├── lib_name/ # 主应用目录
│ ├── module1/ # 模块1
│ │ ├── __init__.py
│ │ ├── schemas.py # 模型
│ │ ├── utils.py # 工具函数
├── tests/ # 测试目录
│ ├── test_module1.py
│ └── __init__.py
├── docs/ # 文档目录
│ ├── __init__.py
│ └── index.md # 主页
└── examples/ # 示例目录
├── __init__.py
└── example1.py # 示例1
```
- 采用模块化设计,每个模块位于`$PROJECT_ROOT/lib_name`目录下,其结构如下:
```markdown
module_name
├── sub_module1 # 子模块1
│ ├── __init__.py
│ ├── schemas.py # Pydantic模型
│ └── utils.py # 工具函数
├── sub_module2 # 子模块2
│ ├── __init__.py
│ ├── schemas.py # Pydantic模型
│ └── utils.py # 工具函数
├── __init__.py
└── schemas.py # 模块公共模型
```
## 示例
- 在完成一个功能时,询问是否需要添加示例代码
- 示例代码应位于`$PROJECT_ROOT/examples`目录下,结构如下:
```markdown
examples
├── module_name # 模块名
│ ├── __init__.py
│ ├── feature_name_example.py # 功能名示例
│ └── ...
└── ...
```
- 示例和测试不是一个东西,示例代码不要用`test_`开头
- 在`$PROJECT_ROOT/examples/README.md`文件中记录示例代码的运行方法,内容格式如下:
```markdown
## $MODULE_NAME
### $EXAMPLE_NAME
```powershell
$env:PYTHONPATH=$PROJECT_ROOT
uv run examples/module_name/feature_name_example.py
```
```bash
export PYTHONPATH=$PROJECT_ROOT
uv run examples/module_name/feature_name_example.py
```
```
## 自述文件
- 在`$PROJECT_ROOT/README.md`文件中记录项目的重要信息
- 涉及重要变更时,更新`$PROJECT_ROOT/CHANGELOG.md`文件

81
Python/Web/.cursorrules Normal file
View File

@@ -0,0 +1,81 @@
---
description: Python Web开发最佳实践与规范
---
# Python Web开发规范
## 依赖管理
- 使用`uv`管理依赖
## 项目结构
- 项目整体结构如下:
```markdown
$PROJECT_ROOT
├── app # 项目根目录
├── tests # 测试目录
├── .env # 环境变量
├── .gitignore # git忽略文件
├── README.md # 项目说明
├── uv.lock # uv锁文件
├── .clinerules # 项目规范/ClineRules
├── .windsurfrules # 项目规范/WindsurfRules
├── .cursorrules # 项目规范/CursorRules
├── Dockerfile # docker构建文件
├── pyproject.toml # uv项目配置
├── main.py # 主程序
```
- 采用模块化设计,每个模块位于`$PROJECT_ROOT/app`目录下,其结构如下:
```markdown
module_name
├── admin # 管理端
│ ├── __init__.py
│ ├── routes.py # 路由
│ ├── schemas.py # Pydantic模型
│ └── crud.py # 数据库操作
│ └── utils.py # 工具函数
├── api # 接口
│ ├── __init__.py
│ ├── crud.py # 数据库操作
│ ├── routes.py # 路由
│ ├── schemas.py # Pydantic模型
│ └── utils.py # 工具函数
├── __init__.py
└── schemas.py # 模块公共模型
```
## 数据库
- 使用`sqlmodel`作为数据库ORM框架
## 示例
- 在完成一个功能时,询问是否需要添加示例代码
- 示例代码应位于`$PROJECT_ROOT/examples`目录下,结构如下:
```markdown
examples
├── module_name # 模块名
│ ├── __init__.py
│ ├── feature_name_example.py # 功能名示例
│ └── ...
└── ...
```
- 示例和测试不是一个东西,示例代码不要用`test_`开头
- 运行示例代码时,需要先设置`PYTHONPATH`环境变量到`$PROJECT_ROOT`目录,然后使用`uv run examples/module_name/feature_name_example.py`运行
## 日志
- 使用`loguru`作为日志框架
- 日志文件位于`$PROJECT_ROOT/logs`目录下
- 日志文件按天轮转,保留30天,以`zip`格式压缩
- 为每个模块创建单独的日志记录器,并保存到`$PROJECT_ROOT/logs/module_name.log`文件中
## 装饰器
- 使用[wrapt](https://wrapt.readthedocs.io/en/latest/)库创建装饰器
- 装饰器应位于`$PROJECT_ROOT/app/$MODULE_NAME/utils.py`文件中

9
Python/Web/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
.idea
.venv
.logs
__pycache__
repomix-output.txt
.env
tmp_audio
*.egg-info
.pytest_cache

30
Python/Web/Dockerfile Normal file
View File

@@ -0,0 +1,30 @@
FROM python:3.12-slim-bookworm
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
# 安装系统依赖
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY pyproject.toml .
# 安装项目依赖
RUN uv pip compile pyproject.toml -o requirements.txt && pip install --no-cache-dir -r requirements.txt
# 复制项目文件
COPY . .
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000","--workers", "8","--timeout-keep-alive", "30"]

126
Python/Web/Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,126 @@
pipeline {
agent any
parameters {
choice(name: 'TYPE', choices: ['client', 'admin'], description: '选择要部署的应用类型')
choice(name: 'APP_NAME', choices: ['client-api', 'admin-api'], description: '选择要部署的应用名称')
}
environment {
// 远程服务器信息
REMOTE_HOST = '47.238.171.2'
REMOTE_USER = 'root'
// 应用信息
APP_NAME = "${params.APP_NAME}"
TYPE = "${params.TYPE}"
// 远程服务器应用目录
REMOTE_APP_DIR = '/app'
}
stages {
stage('打印环境信息') {
steps {
echo "开始部署流程..."
echo "应用名称: ${APP_NAME}"
echo "应用类型: ${TYPE}"
echo "远程服务器: ${REMOTE_USER}@${REMOTE_HOST}"
echo "远程应用目录: ${REMOTE_APP_DIR}"
echo "当前工作目录: ${WORKSPACE}"
}
}
stage('构建Docker镜像') {
steps {
echo "正在构建 ${APP_NAME} Docker镜像..."
sh "docker build -t ${APP_NAME} -f Dockerfile ."
// 列出Docker镜像以确认构建成功
sh "docker images | grep ${APP_NAME}"
}
}
stage('导出Docker镜像') {
steps {
echo "正在导出 ${APP_NAME} Docker镜像..."
sh "docker save ${APP_NAME} > ${APP_NAME}.tar"
// 检查tar文件大小以确认导出成功
sh "ls -lh ${APP_NAME}.tar"
}
}
stage('传输镜像到远程服务器') {
steps {
echo "正在传输镜像到远程服务器 ${REMOTE_USER}@${REMOTE_HOST}..."
// 使用withCredentials为scp命令提供SSH凭据
// 注意需要在Jenkins中配置名为'remote-server'的SSH凭据
withCredentials([sshUserPrivateKey(credentialsId: 'ssh-private-key', keyFileVariable: 'SSH_KEY')]) {
sh """
scp -i ${SSH_KEY} -o StrictHostKeyChecking=no ${WORKSPACE}/${APP_NAME}.tar ${REMOTE_USER}@${REMOTE_HOST}:/app/
"""
}
}
}
stage('在远程服务器上加载镜像') {
steps {
echo "在远程服务器上加载Docker镜像..."
// 使用withCredentials为ssh命令提供SSH凭据
withCredentials([sshUserPrivateKey(credentialsId: 'ssh-private-key', keyFileVariable: 'SSH_KEY')]) {
sh """
ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} '
docker load < /app/${APP_NAME}.tar &&
rm /app/${APP_NAME}.tar
'
"""
}
}
}
stage('在远程服务器上部署应用') {
steps {
echo "在远程服务器上重新部署应用..."
// 使用withCredentials为ssh命令提供SSH凭据
withCredentials([sshUserPrivateKey(credentialsId: 'ssh-private-key', keyFileVariable: 'SSH_KEY')]) {
sh """
ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} '
cd ${REMOTE_APP_DIR} &&
docker compose up -d --force-recreate ${APP_NAME}
'
"""
}
}
}
stage('执行数据库迁移') {
steps {
echo "在${APP_NAME}容器中执行数据库迁移..."
// 使用withCredentials为ssh命令提供SSH凭据
withCredentials([sshUserPrivateKey(credentialsId: 'ssh-private-key', keyFileVariable: 'SSH_KEY')]) {
sh """
ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} '
cd ${REMOTE_APP_DIR} &&
docker exec ${APP_NAME} alembic upgrade head
'
"""
}
}
}
}
post {
success {
echo "流水线成功执行! ${APP_NAME} 已成功部署到 ${REMOTE_HOST}"
}
failure {
echo "流水线执行失败,请检查日志获取详细信息"
}
always {
// 清理本地Docker镜像以节省空间
sh "docker rmi ${APP_NAME} || true"
cleanWs()
}
}
}