中文汉化
Deploy to Staging / deploy (push) Has been cancelled
Conflict detector / main (push) Has been cancelled
Lint Backend / lint-backend (push) Has been cancelled
Playwright Tests / changes (push) Has been cancelled
Test Backend / test-backend (push) Has been cancelled
Test Docker Compose / test-docker-compose (push) Has been cancelled
Playwright Tests / test-playwright (1, 4) (push) Has been cancelled
Playwright Tests / test-playwright (2, 4) (push) Has been cancelled
Playwright Tests / test-playwright (3, 4) (push) Has been cancelled
Playwright Tests / test-playwright (4, 4) (push) Has been cancelled
Playwright Tests / merge-playwright-reports (push) Has been cancelled
Playwright Tests / alls-green-playwright (push) Has been cancelled
Issue Manager / issue-manager (push) Has been cancelled
Deploy to Staging / deploy (push) Has been cancelled
Conflict detector / main (push) Has been cancelled
Lint Backend / lint-backend (push) Has been cancelled
Playwright Tests / changes (push) Has been cancelled
Test Backend / test-backend (push) Has been cancelled
Test Docker Compose / test-docker-compose (push) Has been cancelled
Playwright Tests / test-playwright (1, 4) (push) Has been cancelled
Playwright Tests / test-playwright (2, 4) (push) Has been cancelled
Playwright Tests / test-playwright (3, 4) (push) Has been cancelled
Playwright Tests / test-playwright (4, 4) (push) Has been cancelled
Playwright Tests / merge-playwright-reports (push) Has been cancelled
Playwright Tests / alls-green-playwright (push) Has been cancelled
Issue Manager / issue-manager (push) Has been cancelled
This commit is contained in:
+64
-54
@@ -1,172 +1,182 @@
|
||||
# FastAPI Project - Backend
|
||||
# FastAPI 项目 - 后端(Backend)
|
||||
|
||||
## Requirements
|
||||
## 前置要求
|
||||
|
||||
* [Docker](https://www.docker.com/).
|
||||
* [uv](https://docs.astral.sh/uv/) for Python package and environment management.
|
||||
* 已安装 [Docker](https://www.docker.com/)。
|
||||
* 已安装 [uv](https://docs.astral.sh/uv/),用于管理 Python 包与虚拟环境。
|
||||
|
||||
## Docker Compose
|
||||
## 使用 Docker Compose
|
||||
|
||||
Start the local development environment with Docker Compose following the guide in [../development.md](../development.md).
|
||||
按照 [../development.md](../development.md) 中的说明,使用 Docker Compose 启动本地开发环境。
|
||||
|
||||
## General Workflow
|
||||
## 一般工作流
|
||||
|
||||
By default, the dependencies are managed with [uv](https://docs.astral.sh/uv/), go there and install it.
|
||||
本项目默认使用 [uv](https://docs.astral.sh/uv/) 管理依赖,请先安装它。
|
||||
|
||||
From `./backend/` you can install all the dependencies with:
|
||||
在 `./backend/` 目录下安装所有依赖:
|
||||
|
||||
```console
|
||||
$ uv sync
|
||||
```
|
||||
|
||||
Then you can activate the virtual environment with:
|
||||
然后激活虚拟环境:
|
||||
|
||||
```console
|
||||
$ source .venv/bin/activate
|
||||
```
|
||||
|
||||
Make sure your editor is using the correct Python virtual environment, with the interpreter at `backend/.venv/bin/python`.
|
||||
请确保你的编辑器使用的是该虚拟环境中的 Python 解释器:`backend/.venv/bin/python`。
|
||||
|
||||
Modify or add SQLModel models for data and SQL tables in `./backend/app/models.py`, API endpoints in `./backend/app/api/`, CRUD (Create, Read, Update, Delete) utils in `./backend/app/crud.py`.
|
||||
你可以在 `./backend/app/models.py` 中修改或新增 SQLModel 模型(数据表结构),在 `./backend/app/api/` 中添加 API 路由,在 `./backend/app/crud.py` 中添加 / 修改 CRUD(创建、读取、更新、删除)工具函数。
|
||||
|
||||
## VS Code
|
||||
|
||||
There are already configurations in place to run the backend through the VS Code debugger, so that you can use breakpoints, pause and explore variables, etc.
|
||||
项目中已经包含了 VS Code 的调试配置,你可以直接使用断点、单步调试、查看变量等功能来运行后端。
|
||||
|
||||
The setup is also already configured so you can run the tests through the VS Code Python tests tab.
|
||||
测试相关配置也已就绪,可以通过 VS Code 的 Python 测试面板直接运行测试。
|
||||
|
||||
## Docker Compose Override
|
||||
## Docker Compose 覆盖配置
|
||||
|
||||
During development, you can change Docker Compose settings that will only affect the local development environment in the file `docker-compose.override.yml`.
|
||||
开发阶段,你可以在 `docker-compose.override.yml` 中修改仅作用于本地开发环境的 Docker Compose 配置。
|
||||
|
||||
The changes to that file only affect the local development environment, not the production environment. So, you can add "temporary" changes that help the development workflow.
|
||||
这些改动只影响本地开发环境,不会影响生产环境。因此你可以在这里加入一些“临时”设置来提升本地开发效率。
|
||||
|
||||
For example, the directory with the backend code is synchronized in the Docker container, copying the code you change live to the directory inside the container. That allows you to test your changes right away, without having to build the Docker image again. It should only be done during development, for production, you should build the Docker image with a recent version of the backend code. But during development, it allows you to iterate very fast.
|
||||
例如:后端代码目录会以 volume 形式挂载进容器,你在本机修改代码后会实时同步到容器中,无需重新构建镜像即可看到效果。生产环境则应该基于最新代码重新构建镜像,而不是使用挂载的源码。
|
||||
|
||||
There is also a command override that runs `fastapi run --reload` instead of the default `fastapi run`. It starts a single server process (instead of multiple, as would be for production) and reloads the process whenever the code changes. Have in mind that if you have a syntax error and save the Python file, it will break and exit, and the container will stop. After that, you can restart the container by fixing the error and running again:
|
||||
配置中还包含一个覆盖命令,将默认的 `fastapi run` 改为 `fastapi run --reload`。它只启动一个进程(适合开发环境),并在检测到代码变更时自动重载。注意,如果保存了含语法错误的 Python 文件,进程会直接退出、容器也会停止。修复错误后,可以再次运行:
|
||||
|
||||
```console
|
||||
$ docker compose watch
|
||||
```
|
||||
|
||||
There is also a commented out `command` override, you can uncomment it and comment the default one. It makes the backend container run a process that does "nothing", but keeps the container alive. That allows you to get inside your running container and execute commands inside, for example a Python interpreter to test installed dependencies, or start the development server that reloads when it detects changes.
|
||||
文件中还提供了一个被注释掉的 `command` 覆盖项,你可以取消注释它并注释掉默认命令。该命令会让后端容器运行一个“空转”的进程,只是保持容器存活,方便你进入容器内部执行命令,例如打开 Python 交互解释器测试依赖,或手动启动支持热重载的开发服务器。
|
||||
|
||||
To get inside the container with a `bash` session you can start the stack with:
|
||||
如果你想通过 `bash` 进入容器,可以先启动整个 stack:
|
||||
|
||||
```console
|
||||
$ docker compose watch
|
||||
```
|
||||
|
||||
and then in another terminal, `exec` inside the running container:
|
||||
然后在另一个终端中执行:
|
||||
|
||||
```console
|
||||
$ docker compose exec backend bash
|
||||
```
|
||||
|
||||
You should see an output like:
|
||||
你会看到类似输出:
|
||||
|
||||
```console
|
||||
root@7f2607af31c3:/app#
|
||||
```
|
||||
|
||||
that means that you are in a `bash` session inside your container, as a `root` user, under the `/app` directory, this directory has another directory called "app" inside, that's where your code lives inside the container: `/app/app`.
|
||||
这说明你已经以 `root` 用户进入了容器中的 `/app` 目录,该目录下还有一个 `app` 子目录,即你的后端代码在容器中的位置:`/app/app`。
|
||||
|
||||
There you can use the `fastapi run --reload` command to run the debug live reloading server.
|
||||
在这里可以运行支持热重载的开发服务器:
|
||||
|
||||
```console
|
||||
$ fastapi run --reload app/main.py
|
||||
```
|
||||
|
||||
...it will look like:
|
||||
终端看起来会类似:
|
||||
|
||||
```console
|
||||
root@7f2607af31c3:/app# fastapi run --reload app/main.py
|
||||
```
|
||||
|
||||
and then hit enter. That runs the live reloading server that auto reloads when it detects code changes.
|
||||
然后按回车即可启动,它会在检测到代码变化时自动重载。
|
||||
|
||||
Nevertheless, if it doesn't detect a change but a syntax error, it will just stop with an error. But as the container is still alive and you are in a Bash session, you can quickly restart it after fixing the error, running the same command ("up arrow" and "Enter").
|
||||
如果碰到的不是代码变更而是语法错误,进程会直接退出。不过因为容器还在且你仍在 Bash 会话中,修复错误后按方向键上翻历史命令并回车即可快速重启。
|
||||
|
||||
...this previous detail is what makes it useful to have the container alive doing nothing and then, in a Bash session, make it run the live reload server.
|
||||
正是因为这一点,让“容器空转 + Bash 中手动启动热重载服务”的方式在开发中非常实用。
|
||||
|
||||
## Backend tests
|
||||
## 后端测试
|
||||
|
||||
To test the backend run:
|
||||
运行后端测试:
|
||||
|
||||
```console
|
||||
$ bash ./scripts/test.sh
|
||||
```
|
||||
|
||||
The tests run with Pytest, modify and add tests to `./backend/tests/`.
|
||||
测试使用 Pytest,测试文件位于 `./backend/tests/`,你可以在其中新增或修改测试。
|
||||
|
||||
If you use GitHub Actions the tests will run automatically.
|
||||
如果你使用 GitHub Actions,推送代码后测试会自动运行。
|
||||
|
||||
### Test running stack
|
||||
### 在已运行的 stack 中执行测试
|
||||
|
||||
If your stack is already up and you just want to run the tests, you can use:
|
||||
如果 Docker Compose 已经启动,只想在当前 stack 中运行测试,可以使用:
|
||||
|
||||
```bash
|
||||
docker compose exec backend bash scripts/tests-start.sh
|
||||
```
|
||||
|
||||
That `/app/scripts/tests-start.sh` script just calls `pytest` after making sure that the rest of the stack is running. If you need to pass extra arguments to `pytest`, you can pass them to that command and they will be forwarded.
|
||||
`/app/scripts/tests-start.sh` 脚本会在确认依赖服务已就绪后调用 `pytest`。如果需要给 `pytest` 传额外参数,可以直接附加在命令后面,它们会被转发给 `pytest`。
|
||||
|
||||
For example, to stop on first error:
|
||||
例如,遇到第一个错误就停止:
|
||||
|
||||
```bash
|
||||
docker compose exec backend bash scripts/tests-start.sh -x
|
||||
```
|
||||
|
||||
### Test Coverage
|
||||
### 测试覆盖率
|
||||
|
||||
When the tests are run, a file `htmlcov/index.html` is generated, you can open it in your browser to see the coverage of the tests.
|
||||
测试运行后会生成 `htmlcov/index.html` 文件,可在浏览器中打开查看覆盖率报告。
|
||||
|
||||
## Migrations
|
||||
## 数据库迁移(Migrations)
|
||||
|
||||
As during local development your app directory is mounted as a volume inside the container, you can also run the migrations with `alembic` commands inside the container and the migration code will be in your app directory (instead of being only inside the container). So you can add it to your git repository.
|
||||
本地开发时,应用代码目录以 volume 形式挂载到容器中,因此可以在容器内使用 `alembic` 命令生成迁移文件,这些文件会直接写入你的项目目录,方便你提交到 git 仓库。
|
||||
|
||||
Make sure you create a "revision" of your models and that you "upgrade" your database with that revision every time you change them. As this is what will update the tables in your database. Otherwise, your application will have errors.
|
||||
每次修改模型后,请确保:
|
||||
|
||||
* Start an interactive session in the backend container:
|
||||
1. 创建新的迁移“revision”,描述本次模型变更;
|
||||
2. 使用该 revision 升级数据库。
|
||||
|
||||
否则数据库表结构不会更新,应用就会报错。
|
||||
|
||||
基本流程如下:
|
||||
|
||||
* 在后端容器中启动交互会话:
|
||||
|
||||
```console
|
||||
$ docker compose exec backend bash
|
||||
```
|
||||
|
||||
* Alembic is already configured to import your SQLModel models from `./backend/app/models.py`.
|
||||
* `alembic` 已配置好从 `./backend/app/models.py` 导入 SQLModel 模型。
|
||||
|
||||
* After changing a model (for example, adding a column), inside the container, create a revision, e.g.:
|
||||
* 修改模型(例如新增字段)后,在容器内创建迁移 revision,例如:
|
||||
|
||||
```console
|
||||
$ alembic revision --autogenerate -m "Add column last_name to User model"
|
||||
```
|
||||
|
||||
* Commit to the git repository the files generated in the alembic directory.
|
||||
* 将 Alembic 目录中生成的 Python 迁移文件提交到 git。
|
||||
|
||||
* After creating the revision, run the migration in the database (this is what will actually change the database):
|
||||
* 创建完 revision 后,在数据库中执行迁移(真正修改数据库结构):
|
||||
|
||||
```console
|
||||
$ alembic upgrade head
|
||||
```
|
||||
|
||||
If you don't want to use migrations at all, uncomment the lines in the file at `./backend/app/core/db.py` that end in:
|
||||
如果你完全不想使用迁移,可以在 `./backend/app/core/db.py` 中取消注释以 `SQLModel.metadata.create_all(engine)` 结尾的代码:
|
||||
|
||||
```python
|
||||
SQLModel.metadata.create_all(engine)
|
||||
```
|
||||
|
||||
and comment the line in the file `scripts/prestart.sh` that contains:
|
||||
同时在 `scripts/prestart.sh` 中注释掉包含以下内容的那一行:
|
||||
|
||||
```console
|
||||
$ alembic upgrade head
|
||||
```
|
||||
|
||||
If you don't want to start with the default models and want to remove them / modify them, from the beginning, without having any previous revision, you can remove the revision files (`.py` Python files) under `./backend/app/alembic/versions/`. And then create a first migration as described above.
|
||||
如果你不想从默认模型开始,而是从零开始定义自己的模型,并且不希望有任何已有迁移,可以删除 `./backend/app/alembic/versions/` 下的所有迁移文件(`.py`),然后按上述步骤创建第一条迁移。
|
||||
|
||||
## Email Templates
|
||||
## 邮件模板
|
||||
|
||||
The email templates are in `./backend/app/email-templates/`. Here, there are two directories: `build` and `src`. The `src` directory contains the source files that are used to build the final email templates. The `build` directory contains the final email templates that are used by the application.
|
||||
邮件模板位于 `./backend/app/email-templates/` 目录,其中:
|
||||
|
||||
Before continuing, ensure you have the [MJML extension](https://marketplace.visualstudio.com/items?itemName=attilabuti.vscode-mjml) installed in your VS Code.
|
||||
- `src`:存放源模板(`.mjml` 文件等),用于生成最终 HTML 模板;
|
||||
- `build`:存放构建后的 HTML 邮件模板,实际由应用使用。
|
||||
|
||||
Once you have the MJML extension installed, you can create a new email template in the `src` directory. After creating the new email template and with the `.mjml` file open in your editor, open the command palette with `Ctrl+Shift+P` and search for `MJML: Export to HTML`. This will convert the `.mjml` file to a `.html` file and now you can save it in the build directory.
|
||||
继续之前,请先在 VS Code 中安装 [MJML 扩展](https://marketplace.visualstudio.com/items?itemName=attilabuti.vscode-mjml)。
|
||||
|
||||
安装完成后,你可以在 `src` 目录中创建新的邮件模板。创建好 `.mjml` 文件并在编辑器中打开后,按 `Ctrl+Shift+P` 打开命令面板,搜索 `MJML: Export to HTML`。该命令会将 `.mjml` 文件转换为 `.html` 文件,然后你可以将其保存到 `build` 目录中供应用使用。
|
||||
|
||||
Reference in New Issue
Block a user