Skip to content

Commit c5d223e

Browse files
authored
Merge pull request #72 from grillazz/70-switch-to-uv-for-project-and-deps-managment
70 switch to uv for project and deps managment
2 parents 0980d8a + adab40c commit c5d223e

File tree

12 files changed

+968
-128
lines changed

12 files changed

+968
-128
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ MONGODB_DATABASE=greenhouse
1515
MONGODB_COLLECTION=greens
1616
MONGODB_TEST=farmland
1717
MONGO_URL=mongodb://farmer:tractor@mongodb:27017/?retryWrites=true&w=majority
18+
MONGODB_PARAMS: ?authSource=admin&authMechanism=SCRAM-SHA-1&retryWrites=true&w=majority
1819

.github/workflows/build-and-test.yml

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: [ "3.12" ]
16-
poetry-version: [ "1.7.1" ]
15+
python-version: [ "3.13" ]
1716

1817
env:
1918
PYTHONDONTWRITEBYTECODE: 1
@@ -43,17 +42,12 @@ jobs:
4342
- 27017:27017
4443

4544
steps:
46-
- uses: actions/checkout@v3
47-
- name: Set up Python
48-
uses: actions/setup-python@v4
45+
- uses: actions/checkout@v4
46+
47+
- name: Install the latest version of uv and set the python version
48+
uses: astral-sh/setup-uv@v5
4949
with:
5050
python-version: ${{ matrix.python-version }}
51-
- name: Install Poetry
52-
uses: abatilo/actions-poetry@v2
53-
with:
54-
poetry-version: ${{ matrix.poetry-version }}
55-
- name: Install dependencies
56-
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
57-
run: poetry install --no-interaction --no-root
58-
- name: Test Code
59-
run: poetry run pytest
51+
52+
- name: Test with python ${{ matrix.python-version }}
53+
run: uv run --frozen pytest

Dockerfile

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,58 @@
1-
FROM python:3.12-slim-bookworm AS base
2-
RUN apt-get update \
3-
&& apt-get upgrade -y \
4-
&& apt-get install -y --no-install-recommends curl git build-essential \
5-
&& apt-get autoremove -y
6-
ENV POETRY_HOME="/opt/poetry"
7-
RUN curl -sSL https://install.python-poetry.org | python3 -
8-
9-
FROM base AS install
10-
WORKDIR /home/code
11-
12-
# allow controlling the poetry installation of dependencies via external args
13-
ARG INSTALL_ARGS="--no-root --only main"
14-
ENV POETRY_HOME="/opt/poetry"
15-
ENV PATH="$POETRY_HOME/bin:$PATH"
16-
COPY pyproject.toml poetry.lock ./
17-
18-
# install without virtualenv, since we are inside a container
19-
RUN poetry config virtualenvs.create false \
20-
&& poetry install $INSTALL_ARGS
21-
22-
# cleanup
23-
RUN curl -sSL https://install.python-poetry.org | python3 - --uninstall
24-
RUN apt-get purge -y curl git build-essential \
25-
&& apt-get clean -y \
26-
&& rm -rf /root/.cache \
27-
&& rm -rf /var/apt/lists/* \
28-
&& rm -rf /var/cache/apt/*
29-
30-
FROM install as app-image
31-
32-
ENV PYTHONPATH=/home/code/ PYTHONHASHSEED=0
33-
34-
COPY greens/ greens/
35-
COPY tests/ tests/
36-
COPY .env ./
37-
38-
# create a non-root user and switch to it, for security.
39-
RUN addgroup --system --gid 1001 "farmer-eleven"
40-
RUN adduser --system --uid 1001 "farmer-eleven"
41-
USER "farmer-eleven"
42-
1+
FROM ubuntu:oracular AS build
2+
3+
RUN apt-get update -qy && apt-get install -qyy \
4+
-o APT::Install-Recommends=false \
5+
-o APT::Install-Suggests=false \
6+
build-essential \
7+
ca-certificates \
8+
python3-setuptools \
9+
python3.13-dev
10+
11+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
12+
13+
ENV UV_LINK_MODE=copy \
14+
UV_COMPILE_BYTECODE=1 \
15+
UV_PYTHON_DOWNLOADS=never \
16+
UV_PYTHON=python3.13 \
17+
UV_PROJECT_ENVIRONMENT=/app
18+
19+
COPY pyproject.toml /_lock/
20+
COPY uv.lock /_lock/
21+
22+
RUN --mount=type=cache,target=/root/.cache
23+
RUN cd /_lock && uv sync \
24+
--locked \
25+
--no-dev \
26+
--no-install-project
27+
##########################################################################
28+
FROM ubuntu:oracular
29+
30+
ENV PATH=/app/bin:$PATH
31+
32+
RUN groupadd -r app
33+
RUN useradd -r -d /app -g app -N app
34+
35+
STOPSIGNAL SIGINT
36+
37+
RUN apt-get update -qy && apt-get install -qyy \
38+
-o APT::Install-Recommends=false \
39+
-o APT::Install-Suggests=false \
40+
python3.13 \
41+
libpython3.13 \
42+
libpcre3 \
43+
libxml2
44+
45+
RUN apt-get clean
46+
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
47+
48+
COPY --from=build --chown=app:app /app /app
49+
50+
USER app
51+
WORKDIR /app
52+
COPY /greens/ greens/
53+
COPY /tests/ tests/
54+
COPY .env greens/
55+
56+
RUN python -V
57+
RUN python -Im site
58+
RUN python -Ic 'import uvicorn'

Dockerfile.old

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM python:3.12-slim-bookworm AS base
2+
RUN apt-get update \
3+
&& apt-get upgrade -y \
4+
&& apt-get install -y --no-install-recommends curl git build-essential \
5+
&& apt-get autoremove -y
6+
ENV POETRY_HOME="/opt/poetry"
7+
RUN curl -sSL https://install.python-poetry.org | python3 -
8+
9+
FROM base AS install
10+
WORKDIR /home/code
11+
12+
# allow controlling the poetry installation of dependencies via external args
13+
ARG INSTALL_ARGS="--no-root --only main"
14+
ENV POETRY_HOME="/opt/poetry"
15+
ENV PATH="$POETRY_HOME/bin:$PATH"
16+
COPY pyproject.tbd poetry.lock ./
17+
18+
# install without virtualenv, since we are inside a container
19+
RUN poetry config virtualenvs.create false \
20+
&& poetry install $INSTALL_ARGS
21+
22+
# cleanup
23+
RUN curl -sSL https://install.python-poetry.org | python3 - --uninstall
24+
RUN apt-get purge -y curl git build-essential \
25+
&& apt-get clean -y \
26+
&& rm -rf /root/.cache \
27+
&& rm -rf /var/apt/lists/* \
28+
&& rm -rf /var/cache/apt/*
29+
30+
FROM install as app-image
31+
32+
ENV PYTHONPATH=/home/code/ PYTHONHASHSEED=0
33+
34+
COPY greens/ greens/
35+
COPY tests/ tests/
36+
COPY .env ./
37+
38+
# create a non-root user and switch to it, for security.
39+
RUN addgroup --system --gid 1001 "farmer-eleven"
40+
RUN adduser --system --uid 1001 "farmer-eleven"
41+
USER "farmer-eleven"
42+

Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ help: ## Show this help
44

55
.PHONY: build
66
build: ## Build project with compose
7-
docker-compose build
7+
docker compose build
88

99
.PHONY: up
1010
up: ## Run project with compose
11-
docker-compose up
11+
docker compose up
1212

1313
.PHONY: down
1414
down: ## Reset project containers with compose
15-
docker-compose down -v --remove-orphans
15+
docker compose down -v --remove-orphans
1616

1717
.PHONY: test
1818
test: ## Run project tests
19-
docker-compose run --rm web pytest -vv
19+
docker compose -f compose.yml run --rm web pytest -vv tests
2020

2121
.PHONY: test-snapshot
2222
test-snapshot: ## Run project tests
23-
docker-compose run --rm web pytest -vv --inline-snapshot=create
23+
docker compose -f compose.yml run web pytest --inline-snapshot=create tests
2424

2525
.PHONY: mypy
2626
mypy: ## mypy check.
@@ -41,5 +41,5 @@ format: ## format project code.
4141

4242
.PHONY: clean
4343
clean: ## Clean Reset project containers and volumes with compose
44-
docker-compose down -v --remove-orphans | true
45-
docker-compose rm -f
44+
docker compose down -v --remove-orphans | true
45+
docker compose rm -f

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@
1313
### How to Setup
1414

1515
### About logging
16+
17+
### UV knowledge and inspirations
18+
- https://hynek.me/articles/docker-uv/
19+
- https://thedataquarry.com/posts/towards-a-unified-python-toolchain/
20+
-

docker-compose.yml renamed to compose.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
web:
53
build: .
@@ -12,7 +10,8 @@ services:
1210
--reload
1311
"
1412
volumes:
15-
- .:/home/code
13+
- ./greens:/app/greens
14+
- ./tests:/app/tests
1615
ports:
1716
- "8989:8989"
1817
depends_on:

greens/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ async def health_check():
4242
# except Exception:
4343
# app.state.logger.exception("My way or highway...")
4444
return await get_mongo_meta()
45+

pyproject.tbd

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
[tool.poetry]
2+
name = "fastapi-mongodb"
3+
version = "0.6.0"
4+
description = ""
5+
authors = ["Jakub Miazek <[email protected]>"]
6+
readme = "README.md"
7+
packages = [{ include = "fastapi_mongodb" }]
8+
9+
[tool.poetry.dependencies]
10+
python = "^3.12"
11+
fastapi = "^0.111.0"
12+
pydantic = { version = "^2.7.0", extras = ["email"] }
13+
pydantic-settings = "^2.2.1"
14+
motor = "^3.4.0"
15+
uvicorn = { version = "^0uv.29.0", extras = ["standard"] }
16+
pytest = "^8.1.1"
17+
pytest-cov = "^5.0.0"
18+
httpx = "^0.27.0"
19+
rich = "^13.7.1"
20+
uvloop = "^0.19.0"
21+
httptools = "^0.6.1"
22+
ruff = "^0.4.4"
23+
inline-snapshot = "^0.9.0"
24+
25+
[build-system]
26+
requires = ["poetry-core>=1.0.0"]
27+
build-backend = "poetry.core.masonry.api"
28+
29+
[tool.ruff]
30+
line-length = 120
31+
indent-width = 4
32+
33+
lint.select = ["E", "F", "UP", "N", "C", "B"]
34+
lint.ignore = ["E501"]
35+
36+
# Assume Python 3.12
37+
target-version = "py312"
38+
39+
[tool.ruff.lint.flake8-quotes]
40+
docstring-quotes = "double"
41+
42+
[tool.ruff.lint.flake8-bugbear]
43+
extend-immutable-calls = ["fastapi.Depends",]
44+
45+
[tool.pytest.ini_options]
46+
addopts = "-v --doctest-modules --doctest-glob=*.md --cov=. --cov-report html:htmlcov --cov-report=term-missing"
47+
asyncio_mode = "strict"
48+
env_files = [".env"]
49+
50+
[tool.ruff.format]
51+
# Like Black, use double quotes for strings.
52+
quote-style = "double"
53+
54+
# Like Black, indent with spaces, rather than tabs.
55+
indent-style = "space"
56+
57+
# Like Black, respect magic trailing commas.
58+
skip-magic-trailing-comma = false
59+
60+
# Like Black, automatically detect the appropriate line ending.
61+
line-ending = "auto"

pyproject.toml

Lines changed: 19 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,21 @@
1-
[tool.poetry]
1+
[project]
22
name = "fastapi-mongodb"
3-
version = "0.6.0"
4-
description = ""
5-
authors = ["Jakub Miazek <[email protected]>"]
3+
version = "0.1.0"
4+
description = "Add your description here"
65
readme = "README.md"
7-
packages = [{ include = "fastapi_mongodb" }]
8-
9-
[tool.poetry.dependencies]
10-
python = "^3.12"
11-
fastapi = "^0.111.0"
12-
pydantic = { version = "^2.7.0", extras = ["email"] }
13-
pydantic-settings = "^2.2.1"
14-
motor = "^3.4.0"
15-
uvicorn = { version = "^0.29.0", extras = ["standard"] }
16-
pytest = "^8.1.1"
17-
pytest-cov = "^5.0.0"
18-
httpx = "^0.27.0"
19-
rich = "^13.7.1"
20-
uvloop = "^0.19.0"
21-
httptools = "^0.6.1"
22-
ruff = "^0.4.4"
23-
inline-snapshot = "^0.9.0"
24-
25-
[build-system]
26-
requires = ["poetry-core>=1.0.0"]
27-
build-backend = "poetry.core.masonry.api"
28-
29-
[tool.ruff]
30-
line-length = 120
31-
indent-width = 4
32-
33-
lint.select = ["E", "F", "UP", "N", "C", "B"]
34-
lint.ignore = ["E501"]
35-
36-
# Assume Python 3.12
37-
target-version = "py312"
38-
39-
[tool.ruff.lint.flake8-quotes]
40-
docstring-quotes = "double"
41-
42-
[tool.ruff.lint.flake8-bugbear]
43-
extend-immutable-calls = ["fastapi.Depends",]
44-
45-
[tool.pytest.ini_options]
46-
addopts = "-v --doctest-modules --doctest-glob=*.md --cov=. --cov-report html:htmlcov --cov-report=term-missing"
47-
asyncio_mode = "strict"
48-
env_files = [".env"]
49-
50-
[tool.ruff.format]
51-
# Like Black, use double quotes for strings.
52-
quote-style = "double"
53-
54-
# Like Black, indent with spaces, rather than tabs.
55-
indent-style = "space"
56-
57-
# Like Black, respect magic trailing commas.
58-
skip-magic-trailing-comma = false
59-
60-
# Like Black, automatically detect the appropriate line ending.
61-
line-ending = "auto"
6+
requires-python = ">=3.13"
7+
dependencies = [
8+
"fastapi[standard]>=0.115.8",
9+
"httptools>=0.6.4",
10+
"httpx>=0.28.1",
11+
"inline-snapshot>=0.18.2",
12+
"motor>=3.6.0",
13+
"pydantic>=2.11.0a1",
14+
"pydantic-settings>=2.7.1",
15+
"pytest>=8.3.4",
16+
"pytest-cov>=6.0.0",
17+
"rich>=13.9.4",
18+
"ruff>=0.9.4",
19+
"uvicorn>=0.34.0",
20+
"uvloop>=0.21.0",
21+
]

0 commit comments

Comments
 (0)