Skip to content

Commit cf90552

Browse files
Merge branch 'fastapi:master' into refactor-status-code
2 parents 9007661 + 1f666c4 commit cf90552

20 files changed

+1784
-2366
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
version: 2
22
updates:
33
# GitHub Actions
4-
- package-ecosystem: "github-actions"
5-
directory: "/"
4+
- package-ecosystem: github-actions
5+
directory: /
66
schedule:
7-
interval: "daily"
7+
interval: daily
88
commit-message:
99
prefix:
1010
# Python
11-
- package-ecosystem: "pip"
12-
directory: "/"
11+
- package-ecosystem: pip
12+
directory: /
1313
schedule:
14-
interval: "daily"
14+
interval: daily
1515
commit-message:
1616
prefix:

.github/workflows/generate-client.yml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,23 @@ jobs:
2121
node-version: lts/*
2222
- uses: actions/setup-python@v5
2323
with:
24-
python-version: '3.10'
24+
python-version: "3.10"
25+
- name: Install uv
26+
uses: astral-sh/setup-uv@v2
27+
with:
28+
version: "0.4.15"
2529
- name: Install dependencies
2630
run: npm ci
2731
working-directory: frontend
28-
- run: pip install ./backend
29-
- run: bash scripts/generate-client.sh
32+
- run: uv sync
33+
working-directory: backend
34+
- run: uv run bash scripts/generate-client.sh
35+
env:
36+
VIRTUAL_ENV: backend/.venv
3037
- name: Commit changes
3138
run: |
3239
git config --local user.email "[email protected]"
3340
git config --local user.name "github-actions"
3441
git add frontend/src/client
3542
git diff --staged --quiet || git commit -m "✨ Autogenerate frontend client"
3643
git push
37-
38-
# https://github.com/marketplace/actions/alls-green#why
39-
generate-client-alls-green: # This job does nothing and is only used for the branch protection
40-
if: always()
41-
needs:
42-
- generate-client
43-
runs-on: ubuntu-latest
44-
steps:
45-
- name: Decide whether the needed jobs succeeded or failed
46-
uses: re-actors/alls-green@release/v1
47-
with:
48-
jobs: ${{ toJSON(needs) }}
49-

.github/workflows/latest-changes.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ on:
1212
description: PR number
1313
required: true
1414
debug_enabled:
15-
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
15+
description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
1616
required: false
17-
default: 'false'
17+
default: "false"
1818

1919
jobs:
2020
latest-changes:
@@ -34,7 +34,7 @@ jobs:
3434
with:
3535
token: ${{ secrets.GITHUB_TOKEN }}
3636
latest_changes_file: ./release-notes.md
37-
latest_changes_header: '## Latest Changes'
38-
end_regex: '^## '
37+
latest_changes_header: "## Latest Changes"
38+
end_regex: "^## "
3939
debug_logs: true
40-
label_header_prefix: '### '
40+
label_header_prefix: "### "

.github/workflows/lint-backend.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Lint Backend
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
types:
9+
- opened
10+
- synchronize
11+
12+
jobs:
13+
lint-backend:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.10"
22+
- name: Install uv
23+
uses: astral-sh/setup-uv@v2
24+
with:
25+
version: "0.4.15"
26+
- run: uv run bash scripts/lint.sh
27+
working-directory: backend

.github/workflows/smokeshow.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Smokeshow
22

33
on:
44
workflow_run:
5-
workflows: [Test]
5+
workflows: [Test Backend]
66
types: [completed]
77

88
jobs:
@@ -16,17 +16,14 @@ jobs:
1616
steps:
1717
- uses: actions/setup-python@v5
1818
with:
19-
python-version: '3.9'
20-
19+
python-version: "3.10"
2120
- run: pip install smokeshow
22-
2321
- uses: actions/download-artifact@v4
2422
with:
2523
name: coverage-html
2624
path: backend/htmlcov
2725
github-token: ${{ secrets.GITHUB_TOKEN }}
2826
run-id: ${{ github.event.workflow_run.id }}
29-
3027
- run: smokeshow upload backend/htmlcov
3128
env:
3229
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}

.github/workflows/test-backend.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Test Backend
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
types:
9+
- opened
10+
- synchronize
11+
12+
jobs:
13+
test-backend:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version: "3.10"
22+
- name: Install uv
23+
uses: astral-sh/setup-uv@v2
24+
with:
25+
version: "0.4.15"
26+
- run: docker compose down -v --remove-orphans
27+
- run: docker compose up -d db mailcatcher
28+
- name: Migrate DB
29+
run: uv run bash scripts/prestart.sh
30+
working-directory: backend
31+
- name: Run tests
32+
run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}"
33+
working-directory: backend
34+
- run: docker compose down -v --remove-orphans
35+
- name: Store coverage files
36+
uses: actions/upload-artifact@v4
37+
with:
38+
name: coverage-html
39+
path: backend/htmlcov
40+
include-hidden-files: true
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Test Docker Compose
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
types:
9+
- opened
10+
- synchronize
11+
12+
jobs:
13+
14+
test-docker-compose:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
- run: docker compose build
20+
- run: docker compose down -v --remove-orphans
21+
- run: docker compose up -d --wait
22+
- name: Test backend is up
23+
run: curl http://localhost:8000/api/v1/utils/health-check
24+
- name: Test frontend is up
25+
run: curl http://localhost:5173
26+
- run: docker compose down -v --remove-orphans

.github/workflows/test.yml

Lines changed: 0 additions & 50 deletions
This file was deleted.

backend/Dockerfile

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,40 @@ FROM python:3.10
22

33
WORKDIR /app/
44

5-
# Install Poetry
6-
RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python && \
7-
cd /usr/local/bin && \
8-
ln -s /opt/poetry/bin/poetry && \
9-
poetry config virtualenvs.create false
5+
# Install uv
6+
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-uv
7+
COPY --from=ghcr.io/astral-sh/uv:0.4.15 /uv /bin/uv
108

11-
# Copy poetry.lock* in case it doesn't exist in the repo
12-
COPY ./pyproject.toml ./poetry.lock* /app/
9+
# Place executables in the environment at the front of the path
10+
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#using-the-environment
11+
ENV PATH="/app/.venv/bin:$PATH"
1312

14-
# Allow installing dev dependencies to run tests
15-
ARG INSTALL_DEV=false
16-
RUN bash -c "if [ $INSTALL_DEV == 'true' ] ; then poetry install --no-root ; else poetry install --no-root --only main ; fi"
13+
# Compile bytecode
14+
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#compiling-bytecode
15+
ENV UV_COMPILE_BYTECODE=1
16+
17+
# uv Cache
18+
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#caching
19+
ENV UV_LINK_MODE=copy
20+
21+
# Install dependencies
22+
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
23+
RUN --mount=type=cache,target=/root/.cache/uv \
24+
--mount=type=bind,source=uv.lock,target=uv.lock \
25+
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
26+
uv sync --frozen --no-install-project
1727

1828
ENV PYTHONPATH=/app
1929

2030
COPY ./scripts /app/scripts
2131

22-
COPY ./alembic.ini /app/
32+
COPY ./pyproject.toml ./uv.lock ./alembic.ini /app/
2333

2434
COPY ./app /app/app
2535

36+
# Sync the project
37+
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
38+
RUN --mount=type=cache,target=/root/.cache/uv \
39+
uv sync
40+
2641
CMD ["fastapi", "run", "--workers", "4", "app/main.py"]

backend/README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,29 @@
33
## Requirements
44

55
* [Docker](https://www.docker.com/).
6-
* [Poetry](https://python-poetry.org/) for Python package and environment management.
6+
* [uv](https://docs.astral.sh/uv/) for Python package and environment management.
77

88
## Docker Compose
99

1010
Start the local development environment with Docker Compose following the guide in [../development.md](../development.md).
1111

1212
## General Workflow
1313

14-
By default, the dependencies are managed with [Poetry](https://python-poetry.org/), go there and install it.
14+
By default, the dependencies are managed with [uv](https://docs.astral.sh/uv/), go there and install it.
1515

1616
From `./backend/` you can install all the dependencies with:
1717

1818
```console
19-
$ poetry install
19+
$ uv sync
2020
```
2121

22-
Then you can start a shell session with the new environment with:
22+
Then you can activate the virtual environment with:
2323

2424
```console
25-
$ poetry shell
25+
$ source .venv/bin/activate
2626
```
2727

28-
Make sure your editor is using the correct Python virtual environment.
28+
Make sure your editor is using the correct Python virtual environment, with the interpreter at `backend/.venv/bin/python`.
2929

3030
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`.
3131

@@ -41,23 +41,23 @@ During development, you can change Docker Compose settings that will only affect
4141

4242
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.
4343

44-
For example, the directory with the backend code is mounted as a Docker "host volume", mapping 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.
44+
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.
4545

46-
There is also a command override that runs `/start-reload.sh` (included in the base image) instead of the default `/start.sh` (also included in the base image). 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:
46+
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:
4747

4848
```console
49-
$ docker compose up -d
49+
$ docker compose watch
5050
```
5151

5252
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.
5353

5454
To get inside the container with a `bash` session you can start the stack with:
5555

5656
```console
57-
$ docker compose up -d
57+
$ docker compose watch
5858
```
5959

60-
and then `exec` inside the running container:
60+
and then in another terminal, `exec` inside the running container:
6161

6262
```console
6363
$ docker compose exec backend bash
@@ -71,16 +71,16 @@ root@7f2607af31c3:/app#
7171

7272
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`.
7373

74-
There you can use the script `/start-reload.sh` to run the debug live reloading server. You can run that script from inside the container with:
74+
There you can use the `fastapi run --reload` command to run the debug live reloading server.
7575

7676
```console
77-
$ bash /start-reload.sh
77+
$ fastapi run --reload app/main.py
7878
```
7979

8080
...it will look like:
8181

8282
```console
83-
root@7f2607af31c3:/app# bash /start-reload.sh
83+
root@7f2607af31c3:/app# fastapi run --reload app/main.py
8484
```
8585

8686
and then hit enter. That runs the live reloading server that auto reloads when it detects code changes.

0 commit comments

Comments
 (0)