Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ jobs:
#----------------------------------------------
# Build & Cache environment
#----------------------------------------------
- name: "Build & Cache with Poetry"
uses: devbruce/poetry-build-action@1.0.0
- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
python-version: "3.13"
enable-cache: true

- name: "Build project with uv"
run: uv sync --locked --all-extras --dev
#----------------------------------------------
# Check Lint & Format
#----------------------------------------------
- name: "Lint & Format Check"
run: |
poetry run mypy --config-file=pyproject.toml .
poetry run black --config=pyproject.toml --check .
poetry run isort --sp=pyproject.toml --check .
poetry run flake8 --toml-config=pyproject.toml .
make check

test:
name: "Test"
Expand All @@ -44,13 +44,16 @@ jobs:
#----------------------------------------------
# Build & Cache environment
#----------------------------------------------
- name: "Build & Cache with Poetry"
uses: devbruce/poetry-build-action@1.0.0
- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
python-version: "3.13"
enable-cache: true

- name: "Build project with uv"
run: uv sync --locked --all-extras --dev
#----------------------------------------------
# Run tests
#----------------------------------------------
- name: "Run tests"
run: |
poetry run pytest -c pyproject.toml
make test
28 changes: 5 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,25 @@ repos:
- repo: local
hooks:
- id: mypy
name: "[mypy] Type Checker"
name: "[Type Checker] mypy"
language: system
entry: mypy --config-file=pyproject.toml
types: [file, python]
stages: [pre-commit]

- repo: local
hooks:
- id: black
name: "[black] Formatter"
- id: ruff
name: "[Lint & Format Checker] ruff"
language: system
entry: black --config=pyproject.toml
types: [file, python]
stages: [pre-commit]

- repo: local
hooks:
- id: isort
name: "[isort] Sort imports"
language: system
entry: isort --sp=pyproject.toml
types: [file, python]
stages: [pre-commit]

- repo: local
hooks:
- id: flake8
name: "[flake8] Linter"
language: system
entry: flake8 --toml-config=pyproject.toml
entry: ruff check --config=pyproject.toml
types: [file, python]
stages: [pre-commit]

- repo: local
hooks:
- id: pytest
name: "[pytest] Test"
name: "[Test] pytest"
language: system
entry: pytest -c pyproject.toml
pass_filenames: false
Expand Down
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"module": "uvicorn",
"args": [
"src.main:create_app",
"--port=55000",
"--port=55001",
"--factory",
"--reload",
],
Expand Down
16 changes: 8 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
FROM python:3.13.2-slim-bookworm
FROM python:3.13-slim-bookworm

LABEL appname "fastapi-di-tpl"
LABEL appname="fastapi-di-tpl"

ARG DEBCONF_NOWARNINGS="yes"
ARG DEBIAN_FRONTEND="noninteractive"

ENV PIP_NO_CACHE_DIR "1"
ENV PATH "/usr/local/bin:${PATH}"
ENV PIP_NO_CACHE_DIR="1"
ENV PATH="/root/.local/bin:${PATH}"

USER root

RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/usr/local python -
RUN curl -LsSf https://astral.sh/uv/install.sh | sh

WORKDIR /app
COPY ./pyproject.toml .
COPY ./poetry.lock .
COPY ./uv.lock .
COPY ./src .

RUN poetry config virtualenvs.create false && poetry install --only main
RUN uv sync --locked

ENTRYPOINT ["poetry", "run"]
ENTRYPOINT ["uv", "run"]
CMD ["uvicorn", "main:create_app", "--host=0.0.0.0", "--port=8000", "--factory"]

EXPOSE 8000
15 changes: 6 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,20 @@ export PYTHONPATH = ./src:$PYTHONPATH
#----------------------------------------------
# Variables
#----------------------------------------------
PORT := 32000
PORT := 55000

#----------------------------------------------
# Commands
#----------------------------------------------
run:
poetry run uvicorn src.main:create_app --port $(PORT) --factory --reload
uv run uvicorn src.main:create_app --port $(PORT) --factory --reload

test:
poetry run pytest -c pyproject.toml
uv run pytest -c pyproject.toml

format:
poetry run black --config=pyproject.toml .
poetry run isort --sp=pyproject.toml .
uv run ruff format --config=pyproject.toml .

check:
poetry run mypy --config-file=pyproject.toml .
poetry run black --config=pyproject.toml --check .
poetry run isort --sp=pyproject.toml --check .
poetry run flake8 --toml-config=pyproject.toml .
uv run ruff check --config=pyproject.toml .
uv run mypy --config-file=pyproject.toml .
37 changes: 5 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<img src="https://img.shields.io/github/release/devbruce/fastapi-di-tpl.svg" alt="release" />
<br>
<img src="https://img.shields.io/badge/Python-3.13-blue?style=flat&logo=python" alt="python" />
<img src="https://img.shields.io/badge/FastAPI-0.115-brightgreen?style=flat&logo=fastapi" alt="fastapi" />
<img src="https://img.shields.io/badge/Dependency Injector-4.46-skyblue?style=flat" alt="dependency-injector" />
<img src="https://img.shields.io/badge/FastAPI-0.116-brightgreen?style=flat&logo=fastapi" alt="fastapi" />
<img src="https://img.shields.io/badge/Dependency Injector-4.48-skyblue?style=flat" alt="dependency-injector" />
<br>
<img src="https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json" alt="poetry" />
</p>
Expand All @@ -20,8 +20,7 @@

### 🛠️ Prerequisites

- [pyenv](https://github.com/pyenv/pyenv)
- [Poetry](https://python-poetry.org/)
- [uv](https://github.com/astral-sh/uv)
- [direnv](https://direnv.net/)

<br>
Expand All @@ -45,39 +44,13 @@ direnv allow
- Install python with [pyenv](https://github.com/pyenv/pyenv)

```bash
pyenv install ${PYTHON_VERSION}
```

- Set poetry config

```bash
poetry config virtualenvs.in-project true
```

- Create virtualenv(`.venv`) with poetry

```bash
poetry env use $(pyenv root)/versions/${PYTHON_VERSION}/bin/python
```

- Install python dependencies with poetry([`poetry.lock`](./poetry.lock))

```bash
poetry install
uv sync
```

- Activate virtualenv(`.venv`)

> Ref: [managing-environments#activating-the-environment](https://python-poetry.org/docs/managing-environments#activating-the-environment)

```bash
eval $(poetry env activate)
```

- Activate virtualenv(`.venv`) with plugin([python-poetry/poetry-plugin-shell](https://github.com/python-poetry/poetry-plugin-shell))

```bash
poetry shell
source .venv/bin/activate
```

<br>
Expand Down
101 changes: 47 additions & 54 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
[tool.poetry]
[project]
name = "fastapi-di-tpl"
version = "0.1.0"
description = "FastAPI with Dependency Injector Template"
authors = ["devbruce <bruce93k@gmail.com>"]
readme = "README.md"
package-mode = false

[tool.poetry.dependencies]
python = "~3.13"
fastapi = {extras = ["standard"], version = "~0.115.12"}
pydantic-settings = "~2.9.1"
dependency-injector = "~4.46.0"
loguru = "~0.7.3"

[tool.poetry.group.dev.dependencies]
pytest = "~8.3.5"
pytest-asyncio = "~0.26.0"
pytest-cov = "~6.1.1"
pytest-env = "~1.1.5"
pytest-mock = "~3.14.0"
pytest-xdist = {extras = ["psutil"], version = "~3.6.1"}
flake8-pyproject = "~1.2.3"
black = "~25.1.0"
isort = "~6.0.1"
mypy = "~1.15.0"
types-pyyaml = "~6.0.12.20240917"
pre-commit = "~4.2.0"
ipykernel = "~6.29.5"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
requires-python = ">=3.13, <3.14"
dependencies = [
"dependency-injector>=4.48.1, <4.49",
"fastapi[standard]>=0.116.1, <0.117",
"loguru>=0.7.3, <0.8",
"pydantic-settings>=2.10.1, <2.11",
]

[dependency-groups]
dev = [
"ipykernel>=6.29.5, <6.30",
"mypy>=1.16.1, <1.17",
"pre-commit>=4.2.0, <4.3",
"pytest>=8.4.1, <8.5",
"pytest-asyncio>=1.0.0, <1.1",
"pytest-cov>=6.2.1, <6.3",
"pytest-env>=1.1.5, <1.2",
"pytest-mock>=3.14.1, <3.15",
"pytest-xdist>=3.8.0, <3.9",
"ruff>=0.12.3, <0.13",
"types-pyyaml>=6.0.12.20250516, <6.1",
]

# ---------------------------------
# Type Checker
# ---------------------------------
[tool.mypy]
python_version = "3.13"
ignore_missing_imports = true
Expand All @@ -42,36 +37,34 @@ exclude = [
".venv",
]

[tool.black]
# ---------------------------------
# Formatter / Linter
# ---------------------------------
[tool.ruff]
line-length = 120
target-version = ["py313"]
exclude = '''
(
/(
| \.venv
)/
)
'''
target-version = "py313"
exclude = [".venv"]

[tool.isort]
profile = "black"
line_length = 120
force_single_line = true
skip_glob = [
".venv/**",
[tool.ruff.lint]
select = [
"F", # flake
"I", # isort
]

[tool.flake8]
ignore = ["C901", "E501"]
max-line-length = 120
per-file-ignores = [
"__init__.py:F401",
]
exclude = [
".venv",
]

[tool.ruff.lint.isort]
force-single-line = true

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E401"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

# ---------------------------------
# Test
# ---------------------------------
[tool.pytest.ini_options]
markers = [
"e2e: End-to-end test",
Expand Down
Loading