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
14 changes: 7 additions & 7 deletions .github/workflows/backend-QA.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ jobs:
working-directory: backend
run: |
pip install -U pip
pip install -e .[lint,scripts,test,check,maint-scripts]
pip install -e .[qa,scripts,test,maint-scripts]

- name: Check black formatting
- name: Check Linting
working-directory: backend
run: inv lint-black
run: inv check-lint

- name: Check ruff
- name: Check Formatting
working-directory: backend
run: inv lint-ruff
run: inv check-format

- name: Check pyright
- name: Check Type
working-directory: backend
run: inv check-pyright
run: inv check-type
14 changes: 7 additions & 7 deletions .github/workflows/healthcheck-QA.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ jobs:
working-directory: healthcheck
run: |
pip install -U pip
pip install -e .[lint,scripts,test,check]
pip install -e .[qa,scripts,test]

- name: Check black formatting
- name: Check Linting
working-directory: healthcheck
run: inv lint-black
run: inv check-lint

- name: Check ruff
- name: Check Formatting
working-directory: healthcheck
run: inv lint-ruff
run: inv check-format

- name: Check pyright
- name: Check Type
working-directory: healthcheck
run: inv check-pyright
run: inv check-type
44 changes: 21 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,13 @@ repos:
- id: mixed-line-ending

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.10
rev: v0.15.12
hooks:
- id: ruff-check
- id: ruff-format

- repo: https://github.com/psf/black
rev: "25.1.0"
hooks:
- id: black

- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.400
rev: v1.1.409
hooks:
- id: pyright
name: pyright (system)
Expand All @@ -30,22 +25,25 @@ repos:
require_serial: true
minimum_pre_commit_version: "2.9.2"

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
- repo: local
hooks:
- id: prettier
files: frontend\/.*$ # files in javascript folder
name: prettier (system)
entry: prettier --write --ignore-unknown
language: node
files: frontend\/.*$ # files in frontend folder
minimum_pre_commit_version: "2.9.2"

# - repo: https://github.com/pre-commit/mirrors-eslint
# rev: v9.35.0
# hooks:
# - id: eslint
# additional_dependencies:
# - eslint@9.29.0
# - eslint-plugin-vue@10.2.0
# - jiti@2.4.2
# types: [file]
# files: frontend\/src\/.*(?:\.[jt]sx?|\.vue)$ # *.js, *.jsx, *.ts, *.tsx, *.vue in frontend-ui/src folder
# args:
# - --config
# - frontend/eslint.config.ts
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.35.0
hooks:
- id: eslint
additional_dependencies:
- eslint@9.29.0
- eslint-plugin-vue@10.2.0
- jiti@2.4.2
types: [file]
files: frontend\/src\/.*(?:\.[jt]sx?|\.vue)$ # *.js, *.jsx, *.ts, *.tsx, *.vue in frontend/src folder
args:
- --config
- frontend/eslint.config.ts
49 changes: 17 additions & 32 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ classifiers = [
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
]
dependencies = [
"alembic == 1.15.2",
"alembic == 1.18.4",
"pydantic == 2.11.4", # this is also a sub-dep of fastapi but we rely a lot on it
"SQLAlchemy == 2.0.41",
"pymongo == 4.13.0",
Expand All @@ -38,12 +38,9 @@ api = [
scripts = [
"invoke == 2.2.0",
]
lint = [
"black == 25.1.0",
"ruff == 0.11.10",
]
check = [
"pyright == 1.1.400",
qa = [
"ruff==0.15.12",
"pyright==1.1.409",
"types-humanfriendly == 10.0.0"
]
test = [
Expand All @@ -61,12 +58,10 @@ maint-scripts = [
]
dev = [
"pre-commit == 4.2.0",
"ipykernel == 6.29.5",
"cms_backend[api]",
"cms_backend[scripts]",
"cms_backend[lint]",
"cms_backend[test]",
"cms_backend[check]",
"cms_backend[qa]",
"cms_backend[maint-scripts]",
]

Expand Down Expand Up @@ -105,29 +100,19 @@ report-cov = "inv report-cov"
coverage = "inv coverage --args '{args}'"
html = "inv coverage --html --args '{args}'"

[tool.hatch.envs.lint]
template = "lint"
[tool.hatch.envs.qa]
template = "qa"
skip-install = false
features = ["scripts", "lint"]

[tool.hatch.envs.lint.scripts]
black = "inv lint-black --args '{args}'"
ruff = "inv lint-ruff --args '{args}'"
all = "inv lintall --args '{args}'"
fix-black = "inv fix-black --args '{args}'"
fix-ruff = "inv fix-ruff --args '{args}'"
fixall = "inv fixall --args '{args}'"

[tool.hatch.envs.check]
features = ["scripts", "test", "check"]

[tool.hatch.envs.check.scripts]
pyright = "inv check-pyright --args '{args}'"
all = "inv checkall --args '{args}'"

[tool.black]
line-length = 88
target-version = ['py313']
features = ["scripts", "qa", "test"]

[tool.hatch.envs.qa.scripts]
check-lint = "inv check-lint --args '{args}'"
check-format = "inv check-format --args '{args}'"
check-type = "inv check-type --args '{args}'"
check-all = "inv check-all --args '{args}'"
fix-format = "inv fix-format --args '{args}'"
fix-lint = "inv fix-lint --args '{args}'"
fix-all = "inv fix-all --args '{args}'"

[tool.ruff]
line-length = 88
Expand Down
4 changes: 2 additions & 2 deletions backend/src/cms_backend/api/routes/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import math
from typing import Generic, TypeVar
from typing import TypeVar

from pydantic import Field

Expand All @@ -16,7 +16,7 @@ class Paginator(BaseModel):
page: int


class ListResponse(BaseModel, Generic[T]):
class ListResponse[T](BaseModel):
meta: Paginator
items: list[T]

Expand Down
7 changes: 3 additions & 4 deletions backend/src/cms_backend/api/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,9 @@ def can_decode(self, token: str) -> bool:
except Exception:
return False

if payload.get(
"iss"
) != Context.oauth_issuer or Context.oauth_session_audience_id not in payload.get(
"aud", []
if (
payload.get("iss") != Context.oauth_issuer
or Context.oauth_session_audience_id not in payload.get("aud", [])
):
return False
return True
Expand Down
5 changes: 2 additions & 3 deletions backend/src/cms_backend/db/book.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,8 @@ def determine_current_location_kind(
):
return "quarantine"

if (
loc.warehouse_id == Context.staging_warehouse_id
and loc.path.is_relative_to(Context.staging_base_path)
if loc.warehouse_id == Context.staging_warehouse_id and loc.path.is_relative_to(
Context.staging_base_path
):
return "staging"

Expand Down
4 changes: 2 additions & 2 deletions backend/src/cms_backend/schemas/orms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import datetime
from pathlib import Path
from typing import Any, Generic, TypeVar
from typing import Any, TypeVar
from uuid import UUID

from cms_backend.api.routes.fields import NotEmptyString
Expand All @@ -9,7 +9,7 @@
T = TypeVar("T")


class ListResult(BaseModel, Generic[T]):
class ListResult[T](BaseModel):
nb_records: int
records: list[T]

Expand Down
74 changes: 35 additions & 39 deletions backend/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,69 +42,65 @@ def coverage(ctx: Context, args: str = "", *, html: bool = False):
report_cov(ctx, html=html)


@task(optional=["args"], help={"args": "black additional arguments"})
def lint_black(ctx: Context, args: str = "."):
def _lint(ctx: Context, args: str = "."):
args = args or "." # needed for hatch script
ctx.run("black --version", pty=use_pty)
ctx.run(f"black --check --diff {args}", pty=use_pty)
ctx.run("ruff --version", pty=use_pty)
ctx.run(f"ruff check {args}", pty=use_pty)


@task(optional=["args"], help={"args": "ruff additional arguments"})
def lint_ruff(ctx: Context, args: str = "."):
def check_lint(ctx: Context, args: str = "."):
"""check linting with ruff"""
args = args or "." # needed for hatch script
ctx.run("ruff --version", pty=use_pty)
ctx.run(f"ruff check {args}", pty=use_pty)
_lint(ctx, args)


@task(
optional=["args"],
help={
"args": "linting tools (black, ruff) additional arguments, typically a path",
},
)
def lintall(ctx: Context, args: str = "."):
"""Check linting"""
@task(optional=["args"], help={"args": "ruff additional arguments"})
def fix_lint(ctx: Context, args: str = "."):
"""fix linting issues with ruff"""
args = args or "." # needed for hatch script
lint_black(ctx, args)
lint_ruff(ctx, args)
_lint(ctx, f"--fix {args}")


@task(optional=["args"], help={"args": "check tools (pyright) additional arguments"})
def check_pyright(ctx: Context, args: str = ""):
def check_type(ctx: Context, args: str = ""):
"""check static types with pyright"""
ctx.run("pyright --version")
ctx.run(f"pyright {args}", pty=use_pty)


@task(optional=["args"], help={"args": "check tools (pyright) additional arguments"})
def checkall(ctx: Context, args: str = ""):
"""check static types"""
check_pyright(ctx, args)
def _format(ctx: Context, args: str = "."):
args = args or "." # needed for hatch script
ctx.run("ruff --version", pty=use_pty)
ctx.run(f"ruff format {args}", pty=use_pty)


@task(optional=["args"], help={"args": "black additional arguments"})
def fix_black(ctx: Context, args: str = "."):
"""fix black formatting"""
@task(optional=["args"], help={"args": "ruff additional arguments"})
def check_format(ctx: Context, args: str = "."):
"""check formatting with ruff"""
args = args or "." # needed for hatch script
ctx.run(f"black {args}", pty=use_pty)
_format(ctx, f"--check {args}")


@task(optional=["args"], help={"args": "ruff additional arguments"})
def fix_ruff(ctx: Context, args: str = "."):
"""fix all ruff rules"""
def fix_format(ctx: Context, args: str = "."):
"""fix formatting with ruff"""
args = args or "." # needed for hatch script
ctx.run(f"ruff check --fix {args}", pty=use_pty)
_format(ctx, args)


@task(
optional=["args"],
help={
"args": "linting tools (black, ruff) additional arguments, typically a path",
},
)
def fixall(ctx: Context, args: str = "."):
@task(optional=["args"], help={"args": "additional arguments"})
def check_all(ctx: Context, args: str = ""):
"""check linting, formatting and static types"""
args = args or "." # needed for hatch script
check_lint(ctx, args)
check_format(ctx, args)
check_type(ctx, args)


@task(optional=["args"], help={"args": "additional arguments"})
def fix_all(ctx: Context, args: str = ""):
"""Fix everything automatically"""
args = args or "." # needed for hatch script
fix_black(ctx, args)
fix_ruff(ctx, args)
lintall(ctx, args)
fix_lint(ctx, args)
fix_format(ctx, args)
4 changes: 2 additions & 2 deletions backend/tests/api/routes/test_books.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime
from collections.abc import Callable
from http import HTTPStatus
from uuid import UUID, uuid4

import pytest
from fastapi.testclient import TestClient
Expand Down Expand Up @@ -183,6 +184,7 @@ def test_get_books_combined_filters(
],
)
def test_get_books_filter_by_needs_attention(
*,
client: TestClient,
create_book: Callable[..., Book],
create_title: Callable[..., Title],
Expand Down Expand Up @@ -243,7 +245,6 @@ def test_get_books_filter_by_id(
create_book: Callable[..., Book],
):
"""Test get books endpoint passes id filter to database layer"""
from uuid import UUID

# Create books with specific UUIDs for partial matching
book1 = create_book(
Expand Down Expand Up @@ -326,7 +327,6 @@ def test_get_book_by_id_not_found(
book: Book, # noqa: ARG001 - needed for conftest
):
"""Test get book by ID endpoint when book doesn't exist"""
from uuid import uuid4

non_existent_id = uuid4()
response = client.get(f"/v1/books/{non_existent_id}")
Expand Down
Loading
Loading