diff --git a/.github/workflows/black.yaml b/.github/workflows/black.yaml index 8d823a98..054d0b4a 100644 --- a/.github/workflows/black.yaml +++ b/.github/workflows/black.yaml @@ -24,4 +24,4 @@ jobs: - name: Black version run: pdm run black --version - name: Black check - run: pdm run black . --check + run: make black diff --git a/.github/workflows/mypy.yaml b/.github/workflows/mypy.yaml index 13bb3db2..721bf1dc 100644 --- a/.github/workflows/mypy.yaml +++ b/.github/workflows/mypy.yaml @@ -17,7 +17,11 @@ jobs: python-version: '3.11' - name: Python version run: python --version - - name: Mypy installation - run: pip install --user mypy pydantic types-PyYAML - - name: Type checks - run: mypy --explicit-package-bases --disallow-untyped-calls --disallow-untyped-defs --disallow-incomplete-defs --ignore-missing-imports --disable-error-code attr-defined src/ + - name: PDM installation + run: pip install --user pdm + - name: Install dependencies + run: pdm install + - name: Install devel dependencies + run: pdm install --group default,dev + - name: Python linter + run: make check-types diff --git a/.github/workflows/pydocstyle.yaml b/.github/workflows/pydocstyle.yaml index 101fce9e..1b7fb472 100644 --- a/.github/workflows/pydocstyle.yaml +++ b/.github/workflows/pydocstyle.yaml @@ -17,7 +17,11 @@ jobs: python-version: '3.11' - name: Python version run: python --version - - name: Pydocstyle install - run: pip install --user pydocstyle - - name: Python docstring checks - run: pydocstyle -v . + - name: PDM installation + run: pip install --user pdm + - name: Install dependencies + run: pdm install + - name: Install devel dependencies + run: pdm install --group default,dev + - name: Python linter + run: make docstyle diff --git a/.github/workflows/pylint.yaml b/.github/workflows/pylint.yaml index 5ce45511..24d7b7d5 100644 --- a/.github/workflows/pylint.yaml +++ b/.github/workflows/pylint.yaml @@ -25,4 +25,4 @@ jobs: - name: Install devel dependencies run: pdm install --group default,dev - name: Python linter - run: pdm run pylint src + run: make pylint diff --git a/.github/workflows/pyright.yaml b/.github/workflows/pyright.yaml index 80c9ef2e..374ac170 100644 --- a/.github/workflows/pyright.yaml +++ b/.github/workflows/pyright.yaml @@ -25,4 +25,4 @@ jobs: - name: Install devel dependencies run: pdm install --group default,dev - name: Run Pyright tests - run: pdm run pyright src + run: make pyright diff --git a/.github/workflows/ruff.yaml b/.github/workflows/ruff.yaml index 735bfbe3..044b8214 100644 --- a/.github/workflows/ruff.yaml +++ b/.github/workflows/ruff.yaml @@ -12,7 +12,16 @@ jobs: pull-requests: read steps: - uses: actions/checkout@v4 - - uses: chartboost/ruff-action@v1 + - uses: actions/setup-python@v5 with: - args: 'check . --per-file-ignores=tests/*:S101 --per-file-ignores=scripts/*:S101' - + python-version: '3.11' + - name: Python version + run: python --version + - name: PDM installation + run: pip install --user pdm + - name: Install dependencies + run: pdm install + - name: Install devel dependencies + run: pdm install --group default,dev + - name: Python linter + run: make ruff diff --git a/Makefile b/Makefile index 84a7ebef..b2c3ce60 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ test-integration: ## Run integration tests tests COVERAGE_FILE="${ARTIFACT_DIR}/.coverage.integration" pdm run pytest tests/integration --cov=src --cov-report term-missing --cov-report "json:${ARTIFACT_DIR}/coverage_integration.json" --junit-xml="${ARTIFACT_DIR}/junit_integration.xml" --cov-fail-under=10 check-types: ## Checks type hints in sources - MYPYPATH=src pdm run mypy --namespace-packages --explicit-package-bases --strict --disallow-untyped-calls --disallow-untyped-defs --disallow-incomplete-defs src + pdm run mypy --explicit-package-bases --disallow-untyped-calls --disallow-untyped-defs --disallow-incomplete-defs --ignore-missing-imports --disable-error-code attr-defined src/ security-check: ## Check the project for security issues bandit -c pyproject.toml -r src tests @@ -43,3 +43,25 @@ shellcheck: ## Run shellcheck shellcheck --version shellcheck -- */*.sh +black: + pdm run black --check . + +pylint: + pdm run pylint src + +pyright: + pdm run pyright src + +docstyle: + pdm run pydocstyle -v . + +ruff: + pdm run ruff check . --per-file-ignores=tests/*:S101 --per-file-ignores=scripts/*:S101 + +verify: + $(MAKE) black + $(MAKE) pylint + $(MAKE) pyright + $(MAKE) ruff + $(MAKE) docstyle + $(MAKE) check-types diff --git a/pdm.lock b/pdm.lock index 57688a86..2b70c747 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:39ffd9411792359ce4c793606a92a8f2bcab6fe0781c4a843b789fca3b9de29c" +content_hash = "sha256:3dc065684ceb02081a1bd8843f12bd4a889883f71b3fac485eabaf0d3c890b6b" [[metadata.targets]] requires_python = ">=3.11.1,<=3.12.10" @@ -799,6 +799,35 @@ files = [ {file = "multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8"}, ] +[[package]] +name = "mypy" +version = "1.16.0" +requires_python = ">=3.9" +summary = "Optional static typing for Python" +groups = ["dev"] +dependencies = [ + "mypy-extensions>=1.0.0", + "pathspec>=0.9.0", + "tomli>=1.1.0; python_version < \"3.11\"", + "typing-extensions>=4.6.0", +] +files = [ + {file = "mypy-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab"}, + {file = "mypy-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2"}, + {file = "mypy-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff"}, + {file = "mypy-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666"}, + {file = "mypy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c"}, + {file = "mypy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b"}, + {file = "mypy-1.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13"}, + {file = "mypy-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090"}, + {file = "mypy-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1"}, + {file = "mypy-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8"}, + {file = "mypy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730"}, + {file = "mypy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec"}, + {file = "mypy-1.16.0-py3-none-any.whl", hash = "sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031"}, + {file = "mypy-1.16.0.tar.gz", hash = "sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab"}, +] + [[package]] name = "mypy-extensions" version = "1.1.0" @@ -1137,6 +1166,21 @@ files = [ {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, ] +[[package]] +name = "pydocstyle" +version = "6.3.0" +requires_python = ">=3.6" +summary = "Python docstring style checker" +groups = ["dev"] +dependencies = [ + "importlib-metadata<5.0.0,>=2.0.0; python_version < \"3.8\"", + "snowballstemmer>=2.2.0", +] +files = [ + {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, + {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, +] + [[package]] name = "pygments" version = "2.19.1" @@ -1481,6 +1525,33 @@ files = [ {file = "rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75"}, ] +[[package]] +name = "ruff" +version = "0.11.13" +requires_python = ">=3.7" +summary = "An extremely fast Python linter and code formatter, written in Rust." +groups = ["dev"] +files = [ + {file = "ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46"}, + {file = "ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48"}, + {file = "ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71"}, + {file = "ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432"}, + {file = "ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492"}, + {file = "ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250"}, + {file = "ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3"}, + {file = "ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b"}, + {file = "ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514"}, +] + [[package]] name = "setuptools" version = "80.8.0" @@ -1514,6 +1585,17 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] +[[package]] +name = "snowballstemmer" +version = "3.0.1" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*" +summary = "This package provides 32 stemmers for 30 languages generated from Snowball algorithms." +groups = ["dev"] +files = [ + {file = "snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064"}, + {file = "snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"}, +] + [[package]] name = "starlette" version = "0.46.2" @@ -1591,6 +1673,17 @@ files = [ {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, ] +[[package]] +name = "types-pyyaml" +version = "6.0.12.20250516" +requires_python = ">=3.9" +summary = "Typing stubs for PyYAML" +groups = ["dev"] +files = [ + {file = "types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530"}, + {file = "types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba"}, +] + [[package]] name = "typing-extensions" version = "4.13.2" diff --git a/pyproject.toml b/pyproject.toml index 5cfe1757..6d07377d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,10 @@ dev = [ "pytest-asyncio>=1.0.0", "pyright>=1.1.401", "pylint>=3.3.7", + "pydocstyle>=6.3.0", + "mypy>=1.16.0", + "types-PyYAML>=6.0.2", + "ruff>=0.11.13", ] [tool.pytest.ini_options] @@ -47,4 +51,5 @@ distribution = true start = "pdm run make run" test-unit = "pdm run make test-unit" test-integration = "pdm run make test-integration" +verify = "pdm run make verify" diff --git a/src/app/endpoints/query.py b/src/app/endpoints/query.py index 8f7ccd1a..bb713415 100644 --- a/src/app/endpoints/query.py +++ b/src/app/endpoints/query.py @@ -127,9 +127,7 @@ def retrieve_response( stream=False, ) - return str( - response.output_message.content # pyright: ignore[reportAttributeAccessIssue] - ) + return str(response.output_message.content) # type: ignore[union-attr] def validate_attachments_metadata(attachments: list[Attachment]) -> None: