Skip to content

Commit d7e7f15

Browse files
authored
UV migration. (#238)
1 parent c236a2f commit d7e7f15

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1247
-1786
lines changed

.github/workflows/release.yml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,28 @@ jobs:
99
pypi:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v2
13-
- name: Install poetry
14-
run: pipx install poetry
12+
- uses: actions/checkout@v5
1513
- name: Set up Python
16-
uses: actions/setup-python@v4
14+
uses: actions/setup-python@v6
1715
with:
18-
python-version: "3.11"
19-
- name: Install deps
20-
run: poetry install
21-
- name: Set version
22-
run: poetry version "${{ github.ref_name }}"
16+
python-version: "3.12"
17+
- name: Install the latest version of uv
18+
uses: astral-sh/setup-uv@v7
2319
- name: Release package
2420
env:
25-
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
26-
run: poetry publish --build
21+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
22+
run: |
23+
uv version "${{ github.ref_name }}"
24+
uv build
25+
uv publish
2726
docker:
2827
runs-on: ubuntu-latest
2928
permissions:
3029
packages: write
3130
contents: read
3231
steps:
3332
- name: Checkout
34-
uses: actions/checkout@v4
33+
uses: actions/checkout@v5
3534
- name: Set up Docker
3635
uses: docker/setup-qemu-action@v3
3736
- name: Set up Docker Buildx

.github/workflows/test.yml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,16 @@ jobs:
2525
steps:
2626
- uses: actions/checkout@v4
2727
- name: Set up Python
28-
uses: actions/setup-python@v2
28+
uses: actions/setup-python@v6
2929
with:
3030
python-version: '3.12'
31-
- name: Install deps
32-
run: |
33-
pip install -U pip
34-
pip install poetry==1.8.2
35-
poetry install
3631
env:
3732
POETRY_VIRTUALENVS_CREATE: "False"
33+
- name: Set up UV
34+
uses: astral-sh/setup-uv@v6
3835
- name: Setup GIT
3936
run: |
4037
git config --global user.name "fastapi_template"
4138
git config --global user.email "[email protected]"
4239
- name: Run tests
43-
run: pytest -vv -n auto
40+
run: uv run pytest -vv -n auto

Dockerfile

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
FROM python:3.11.4-alpine
1+
FROM ghcr.io/astral-sh/uv:0.9.12-python3.13-alpine
22

3-
RUN apk add --no-cache \
3+
RUN apk update && apk add --no-cache \
44
curl \
55
# For building dependencies. \
66
gcc \
@@ -16,23 +16,27 @@ RUN apk add --no-cache \
1616
ncurses \
1717
bash
1818

19-
RUN adduser --disabled-password fastapi_template
19+
RUN adduser -u 1000 --disabled-password fastapi_template
2020
RUN mkdir /projects /src
21-
RUN chown -R fastapi_template:fastapi_template /projects /src
22-
USER fastapi_template
2321

24-
WORKDIR /src
22+
ENV UV_COMPILE_BYTECODE=1
23+
ENV UV_LINK_MODE=copy
24+
ENV UV_PROJECT_ENVIRONMENT=/usr/local
25+
ENV UV_PYTHON_DOWNLOADS=never
26+
ENV UV_NO_MANAGED_PYTHON=1
2527

26-
ENV PATH ${PATH}:/home/fastapi_template/.local/bin
28+
WORKDIR /src
29+
COPY . .
2730

28-
RUN pip install poetry==1.5.1
31+
ENV PATH="${PATH}:/usr/local/bin"
2932

30-
COPY . /src/
31-
RUN pip install .
33+
RUN --mount=type=cache,target=/root/.cache/uv \
34+
uv sync --locked --no-dev
3235

33-
USER root
34-
RUN rm -rfv /src
3536
RUN apk del curl
37+
38+
RUN chown -R fastapi_template:fastapi_template /projects /src /usr/local/lib/
39+
3640
USER fastapi_template
3741

3842
RUN git config --global user.name "Fastapi Template"
@@ -41,5 +45,4 @@ RUN git config --global user.email "[email protected]"
4145
VOLUME /projects
4246
WORKDIR /projects
4347

44-
ENTRYPOINT ["/home/fastapi_template/.local/bin/fastapi_template"]
45-
48+
ENTRYPOINT ["python", "-m", "fastapi_template"]

README.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@
77

88
## Usage
99

10-
⚠️ [Git](https://git-scm.com/downloads), [Python](https://www.python.org/) and [Poetry](https://python-poetry.org/) must be installed and accessible ⚠️
11-
12-
Poetry version must be greater or equal than 1.1.8. Otherwise it won't be able to install SQLAlchemy.
10+
⚠️ [Git](https://git-scm.com/downloads), [Python](https://www.python.org/) and [UV](https://docs.astral.sh/uv/) must be installed and accessible ⚠️
1311

1412
<div align="center">
1513
<a href="https://asciinema.org/a/ig0oi0fOq1hxqnW5X49XaaHIT" target="_blank"><img src="https://asciinema.org/a/ig0oi0fOq1hxqnW5X49XaaHIT.svg" /></a>
@@ -29,7 +27,7 @@ docker-compose up --build
2927

3028
If you want to install it from sources, try this:
3129
```shell
32-
python3 -m pip install poetry
30+
python3 -m pip install uv
3331
python3 -m pip install .
3432
python3 -m fastapi_template
3533
```
@@ -58,7 +56,6 @@ Generator features:
5856
- Optional redis support;
5957
- Optional rabbitmq support;
6058
- different CI\CD;
61-
- Optional Kubernetes config generation;
6259
- Optional Demo routers and models (This helps you to see how project is structured);
6360
- Pre-commit integration;
6461
- Generated tests with almost 90% coverage;
@@ -93,7 +90,6 @@ Options:
9390
--rabbit Add RabbitMQ support
9491
--taskiq Add Taskiq support
9592
--migrations Add Migrations
96-
--kube Add kubernetes configs
9793
--dummy Add dummy model
9894
--routers Add example routers
9995
--swagger Add self hosted swagger

fastapi_template/cli.py

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ def checker(ctx: BuilderContext) -> bool:
8080
"Choose this option if you want to create a service with {name}.\n"
8181
"It's more suitable for {generic} web-services or services without databases.".format(
8282
name=colored("REST API", color="green"),
83-
generic=colored("generic", color="cyan",
84-
attrs=["underline"]),
83+
generic=colored("generic", color="cyan", attrs=["underline"]),
8584
)
8685
),
8786
),
@@ -152,8 +151,7 @@ def checker(ctx: BuilderContext) -> bool:
152151
"{name} is the most popular database made by oracle.\n"
153152
"It's a good fit for {prod} application.".format(
154153
name=colored("MySQL", color="green"),
155-
prod=colored("production-grade", color="cyan",
156-
attrs=["underline"]),
154+
prod=colored("production-grade", color="cyan", attrs=["underline"]),
157155
)
158156
),
159157
additional_info=Database(
@@ -172,13 +170,12 @@ def checker(ctx: BuilderContext) -> bool:
172170
"{name} is second most popular open-source relational database.\n"
173171
"It's a good fit for {prod} application.".format(
174172
name=colored("PostgreSQL", color="green"),
175-
prod=colored("production-grade", color="cyan",
176-
attrs=["underline"]),
173+
prod=colored("production-grade", color="cyan", attrs=["underline"]),
177174
)
178175
),
179176
additional_info=Database(
180177
name="postgresql",
181-
image="postgres:16.3-bullseye",
178+
image="postgres:18.1-bookworm",
182179
async_driver="postgresql+asyncpg",
183180
driver_short="postgres",
184181
driver="postgresql",
@@ -199,9 +196,9 @@ def checker(ctx: BuilderContext) -> bool:
199196
async_driver="beanie",
200197
driver_short="mongodb",
201198
driver="mongodb",
202-
port=27017
199+
port=27017,
203200
),
204-
)
201+
),
205202
],
206203
)
207204

@@ -265,8 +262,7 @@ def checker(ctx: BuilderContext) -> bool:
265262
"If you select this option, you will get only {what}.\n"
266263
"The rest {warn}.".format(
267264
what=colored("raw database", color="green"),
268-
warn=colored("is up to you", color="red",
269-
attrs=["underline"]),
265+
warn=colored("is up to you", color="red", attrs=["underline"]),
270266
)
271267
),
272268
),
@@ -342,7 +338,6 @@ def checker(ctx: BuilderContext) -> bool:
342338
)
343339
),
344340
),
345-
346341
],
347342
)
348343

@@ -365,8 +360,7 @@ def checker(ctx: BuilderContext) -> bool:
365360
color="green",
366361
),
367362
purpose1=colored("caching", color="cyan"),
368-
purpose2=colored(
369-
"storing temporary variables", color="cyan"),
363+
purpose2=colored("storing temporary variables", color="cyan"),
370364
)
371365
),
372366
),
@@ -419,7 +413,7 @@ def checker(ctx: BuilderContext) -> bool:
419413
code="enable_migrations",
420414
cli_name="migrations",
421415
user_view="Add Migrations",
422-
is_hidden=lambda ctx: ctx.db == "none",
416+
is_hidden=lambda ctx: ctx.db == "none" or ctx.orm == "psycopg",
423417
description=(
424418
"Add database {what} config.\n"
425419
"This options adds ability to {why} database schema.".format(
@@ -428,19 +422,6 @@ def checker(ctx: BuilderContext) -> bool:
428422
)
429423
),
430424
),
431-
MenuEntry(
432-
code="enable_kube",
433-
cli_name="kube",
434-
user_view="Add kubernetes configs",
435-
description=(
436-
"This option will add {what} manifests to your project.\n"
437-
"But this option is {warn}, since if you want to use k8s, please create helm.".format(
438-
what=colored("kubernetes", color="green"),
439-
warn=colored("deprecated", color="red",
440-
attrs=["underline"]),
441-
)
442-
),
443-
),
444425
MenuEntry(
445426
code="add_dummy",
446427
cli_name="dummy",
@@ -641,7 +622,6 @@ def inner_callback(**cli_args: Any):
641622
"Project name: ",
642623
validator=SnakeCaseValidator(),
643624
)
644-
context.kube_name = context.project_name.replace("_", "-")
645625

646626
for menu in menus:
647627
if menu.need_ask(context):
@@ -699,7 +679,7 @@ def run_command(callback: Callable[[BuilderContext], None]) -> None:
699679
for menu in menus:
700680
cmd.params.extend(menu.get_cli_options())
701681
required_commands = {
702-
"poetry": "https://python-poetry.org/docs/#installation",
682+
"uv": "https://docs.astral.sh/uv/",
703683
"git": "https://git-scm.com/",
704684
}
705685
for prog, link in required_commands.items():

fastapi_template/template/cookiecutter.json

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@
2323
"enable_taskiq": {
2424
"type": "bool"
2525
},
26-
"enable_kube": {
27-
"type": "bool"
28-
},
29-
"kube_name": {
30-
"type": "string"
31-
},
3226
"enable_routers": {
3327
"type": "bool"
3428
},

fastapi_template/template/hooks/post_gen_project.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ def init_repo():
6161
cprint("Git repository initialized.", "green")
6262
subprocess.run(["git", "add", "."], stdout=subprocess.PIPE)
6363
cprint("Added files to index.", "green")
64-
subprocess.run(["poetry", "install", "-n"])
65-
subprocess.run(["poetry", "run", "pre-commit", "install"])
64+
subprocess.run(["uv", "sync"])
65+
subprocess.run(["uv", "run", "pre-commit", "install"])
6666
cprint("pre-commit installed.", "green")
67-
subprocess.run(["poetry", "run", "pre-commit", "run", "-a"])
67+
subprocess.run(["uv", "run", "pre-commit", "run", "-a"])
6868
subprocess.run(["git", "add", "."], stdout=subprocess.PIPE)
6969
subprocess.run(["git", "commit", "-m", "Initial commit"], stdout=subprocess.PIPE)
7070

fastapi_template/template/{{cookiecutter.project_name}}/.gitlab-ci.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,21 @@ stages:
33

44
.test-template:
55
stage: test
6-
image: python:3.11.4-slim-bullseye
6+
image: ghcr.io/astral-sh/uv:0.9.12-python3.13-bookworm-slim
77
tags:
88
- kubernetes-runner
99
- docker-runner
1010
except:
1111
- tags
1212
before_script:
1313
- apt update && apt install -y git
14-
- pip install poetry==1.8.2
15-
- poetry config virtualenvs.create false
16-
- poetry install
14+
- uv sync
1715

1816
black:
1917
extends:
2018
- .test-template
2119
script:
22-
- pre-commit run black -a
20+
- pre-commit run ruff-format -a
2321

2422
ruff:
2523
extends:
@@ -31,5 +29,5 @@ mypy:
3129
extends:
3230
- .test-template
3331
script:
34-
- pre-commit run ruff -a
32+
- pre-commit run mypy -a
3533

fastapi_template/template/{{cookiecutter.project_name}}/.pre-commit-config.yaml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,27 @@ repos:
55
- repo: local
66
hooks:
77

8-
- id: black
9-
name: Format with Black
10-
entry: poetry run black
8+
- id: ruff-format
9+
name: Format with Ruff
10+
entry: uv run ruff format
1111
language: system
12-
types: [python]
12+
pass_filenames: false
13+
always_run: true
1314

1415
- id: ruff
1516
name: Check with Ruff
16-
entry: poetry run ruff
17+
entry: uv run ruff
1718
language: system
1819
pass_filenames: false
1920
always_run: true
2021
args: ["check", "{{cookiecutter.project_name}}", "tests", "--fix"]
2122

2223
- id: mypy
2324
name: Validate types with MyPy
24-
entry: poetry run mypy
25+
entry: uv run mypy
2526
language: system
2627
types: [python]
2728
pass_filenames: false
2829
args:
2930
- "{{cookiecutter.project_name}}"
31+
- "tests"

0 commit comments

Comments
 (0)