Skip to content
Open
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
11 changes: 11 additions & 0 deletions .github/workflows/mkdocs-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: MkDocs Build (RationAI Standard)
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
workflow_dispatch:

jobs:
run:
uses: RationAI/.github/.github/workflows/mkdocs-build.yml@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow lines =="
for f in .github/workflows/mkdocs-build.yml .github/workflows/python-lint.yml; do
  if [ -f "$f" ]; then
    echo "-- $f --"
    nl -ba "$f" | sed -n '1,25p'
  else
    echo "MISSING $f"
  fi
done

echo
echo "== all reusable workflow refs to RationAI/.github in workflows =="
rg -n "uses:\s*RationAI/\.github/\.github/workflows/.*@" .github/workflows || true

Repository: RationAI/quality-control

Length of output: 264


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repository files =="
git ls-files '.github/workflows/*' || true

echo
echo "== workflow lines =="
for f in .github/workflows/mkdocs-build.yml .github/workflows/python-lint.yml; do
  if [ -f "$f" ]; then
    echo "-- $f --"
    awk '{printf "%4d:\t%s\n", NR, $0}' "$f" | sed -n '1,40p'
  else
    echo "MISSING $f"
  fi
done

echo
echo "== all reusable workflow refs to RationAI/.github in workflows =="
grep -RInE "uses:\s*RationAI/\.github/\.github/workflows/.*@" .github/workflows || true

Repository: RationAI/quality-control

Length of output: 1200


Pin the reusable workflows to full commit SHAs.

Both workflows call RationAI/.github with the mutable @main ref, so an upstream workflow change runs in this repository without a local review. Use an approved full commit SHA at .github/workflows/mkdocs-build.yml:11 and .github/workflows/python-lint.yml:11.

📍 Affects 2 files
  • .github/workflows/mkdocs-build.yml#L11-L11 (this comment)
  • .github/workflows/python-lint.yml#L11-L11
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/mkdocs-build.yml at line 11, Pin the reusable workflow
references in .github/workflows/mkdocs-build.yml:11 and
.github/workflows/python-lint.yml:11 to approved full commit SHAs instead of the
mutable `@main` ref, preserving the existing RationAI/.github workflow targets.

11 changes: 11 additions & 0 deletions .github/workflows/python-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Python Lint (RationAI Standard)
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
workflow_dispatch:

jobs:
run:
uses: RationAI/.github/.github/workflows/python-lint.yml@main
9 changes: 0 additions & 9 deletions .gitlab-ci.yml

This file was deleted.

6 changes: 6 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MD013: false # Line length
MD023: false # Heading start left
MD024: false # Duplicate headings
MD033: false # Inline HTML
MD041: false # First line in file should be a top level heading
MD046: false # Fenced code blocks
6 changes: 5 additions & 1 deletion .mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@ strict = True
ignore_missing_imports = True
disallow_untyped_calls = False
disable_error_code = no-any-return
explicit_package_bases = True
explicit_package_bases = True

# Ignore type errors in the external piqe.py file
[mypy-rationai.qc.blur.piqe]
ignore_errors = True
9 changes: 4 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ repos:
args: [--unsafe]

- repo: https://github.com/commitizen-tools/commitizen
rev: v4.8.3
rev: v4.10.0
hooks:
- id: commitizen

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.10
rev: v0.14.10
hooks:
# Run the linter.
- id: ruff
entry: pdm lint --force-exclude
- id: ruff-check
args: [--fix]
# Run the formatter.
- id: ruff-format
entry: pdm format --force-exclude
8 changes: 5 additions & 3 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ fix = true
line-length = 88
target-version = "py311"

extend-exclude = ["rationai/qc/blur/piqe.py"]

Comment on lines +5 to +6

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(\.ruff\.toml|\.pre-commit-config\.yaml)$' || true

echo
echo "== .ruff.toml =="
if [ -f .ruff.toml ]; then cat -n .ruff.toml; fi

echo
echo "== .pre-commit-config.yaml relevant hooks =="
if [ -f .pre-commit-config.yaml ]; then
  rg -n "ruff-check|ruff-format|files:|force-exclude|extend-exclude" .pre-commit-config.yaml -C 2 || true
  sed -n '1,70p' .pre-commit-config.yaml | cat -n
fi

echo
echo "== references to piqe.py =="
rg -n "piqe\.py|rationai/qc/blur/piqe|ruff" . -g '*.py' -g '*.toml' -g '*.yaml' -g '*.yml' || true

Repository: RationAI/quality-control

Length of output: 3464


🌐 Web query:

Ruff force-exclude explicit filenames documentation

💡 Result:

By default, Ruff analyzes all files passed directly to the command-line, even if they match patterns defined in your exclude or extend-exclude settings [1][2]. To force Ruff to respect your exclusion rules even when files are passed explicitly, you must enable the force-exclude option [1][2]. You can enable this setting in two ways: 1. Configuration File: Add force-exclude = true to your configuration file (e.g., pyproject.toml or ruff.toml) under the [tool.ruff] section [2]. [tool.ruff] force-exclude = true 2. Command-Line Interface: Pass the --force-exclude flag when running the ruff command [1][3]. This feature is particularly useful for tools like pre-commit, which often pass specific, modified files to Ruff regardless of its internal configuration [2][4]. Enabling force-exclude ensures these files remain subject to your project's defined exclusion patterns [2].

Citations:


Make the exclusion apply to pre-commit hooks.

The Ruff pre-commit hooks pass changed filenames, and extend-exclude does not exclude explicit filenames unless force-exclude is enabled. Add force-exclude = true to the top-level Ruff settings, or pass --force-exclude to both ruff-check and ruff-format.

Proposed fix
 extend-exclude = ["rationai/qc/blur/piqe.py"]
+force-exclude = true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
extend-exclude = ["rationai/qc/blur/piqe.py"]
extend-exclude = ["rationai/qc/blur/piqe.py"]
force-exclude = true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.ruff.toml around lines 5 - 6, Add the top-level Ruff setting force-exclude
= true alongside extend-exclude in .ruff.toml so pre-commit hooks honor the
exclusion for explicitly passed filenames.

[format]
# Enable reformatting of code snippets in docstrings.
docstring-code-format = true
Expand All @@ -20,10 +22,10 @@ extend-select = [
"PGH", # pygrep
"RUF", # ruff checks
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"TC", # flake8-type-checking
"TID", # flake8-tidy-imports
"UP", # pyupgrade
"D", # pydocstyle
"D", # pydocstyle
]
extend-ignore = [
"ERA001", # commented out code
Expand All @@ -36,7 +38,7 @@ extend-ignore = [
"D106", # missing docstring in public nested class
"D107", # missing docstring in __init__
"N812", # lowercase imported as non lowercase
"TCH002", # move third-party into a type-checking block
"TC002", # move third-party into a type-checking block
"F722", # jaxtyping
]

Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,21 @@ for QC methods** developed at RationAI. These functions are meant to be run on s
regions and they **offer a straightforward and well-documented access** to the key parts
of the complete QC methods to allow for easier debugging and experimenting.

TODO: Add link to mkdocs documentation
## Documentation

**[`RationAI Quality Control`](https://rationai.github.io/quality-control/)**

## Setting up a Development Environment

1. Create the development environment (including all optional and development dependencies):

```bash
uv sync --all-groups
```

2. Install pre-commit hooks:

```bash
uv run pre-commit install
uv run pre-commit install --hook-type commit-msg
```
32 changes: 6 additions & 26 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
1. ### Install **pyvips** for Efficient Image Processing
1. ### Install **pyvips** for Efficient Image Processing

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Expect: no numbered-list markers before Markdown headings.
! rg -n '^[0-9]+\. ### ' docs/getting-started/installation.md

Repository: RationAI/quality-control

Length of output: 272


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Markdown availability:"
command -v markdown || true
command -v pandoc || true
command -v node || true

echo
echo "Target lines:"
sed -n '1,30p' docs/getting-started/installation.md | cat -n

echo
echo "Parse probe with markdown-it (if available):"
python3 - <<'PY'
try:
    import markdown_it
except Exception as e:
    print(f"markdown_it unavailable: {type(e).__name__}: {e}")
    raise SystemExit(0)

source = open("docs/getting-started/installation.md").read()
tokens = markdown_it.MarkdownIt().parse(source)
for token in tokens:
    print(f"{token.type}\ttag={token.tag}\tmap={token.map}\theading= h{token.attrs[0]['level']} if token.type=='heading' else None\tcontent={token.content[:80]}")
PY

echo
echo "Parse probe with commonmark if installed:"
python3 - <<'PY'
try:
    import commonmark
except Exception as e:
    print(f"commonmark unavailable: {type(e).__name__}: {e}")
    raise SystemExit(0)

source = open("docs/getting-started/installation.md").read()
reader = commonmark.BlockReader(source)
parser = commonmark.Parser()
doc = parser.parse(reader)
def dump(node, indent=0):
    if node.type == "heading":
        print("\t"*indent + f"heading level {node.level} text {next(node.blocks, type('', (), {'info': None})()).literal if hasattr(next(node.blocks, None), 'literal') else '(nested)'}")
    elif node.type == "list":
        print("\t"*indent + f"list tight={node.tight} delim={node.delim} start={node.start}")
    sub = node.first_child
    while sub:
        dump(sub, indent+1)
        sub = sub.next
dump(doc)
PY

Repository: RationAI/quality-control

Length of output: 1593


🌐 Web query:

CommonMark numbered list marker before heading syntax

💡 Result:

In CommonMark, a numbered list marker followed by a heading syntax—such as "1. Heading" followed by a setext underline ("---")—is interpreted as a list item containing a paragraph, rather than a heading [1]. According to the CommonMark specification, a line starting with a numbered list marker (e.g., "1.") is parsed as a list item [2][3]. Because the specification prioritizes list item interpretation in this context, the subsequent text and the underline are treated as the content of that list item [1]. Consequently, the "1. Heading" and the following "---" line will be rendered as a list containing a paragraph, not as a level 1 heading [1]. To avoid this interpretation and force the text to be treated as a heading, you must escape the period in the numbered list marker (e.g., "1. Heading") [1]. This prevents the parser from identifying the line as a list item, allowing the subsequent text and underline to be parsed as a setext heading [1]. For ATX headings (using "#"), placing a "#" after a list marker (e.g., "1. # Heading") generally parses the "# Heading" as the content of the list item, not as a heading block, because headings cannot typically interrupt a list item in that manner within the CommonMark specification [2][3].

Citations:


Move the section numbers inside the H3 headings.

1. ### and 2. ### are parsed as ordered-list items containing heading-like text, so the numbered sections become list content instead of document-level H3 headings. Use ### 1. Install ... and ### 2. Install ..., or plain H3 headings.

Proposed fix
-1. ### Install **pyvips** for Efficient Image Processing
+### 1. Install **pyvips** for Efficient Image Processing

-2. ### Install the Core Quality Control Library
+### 2. Install the Core Quality Control Library

Also applies to: 21-21

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/getting-started/installation.md` at line 1, Update the numbered H3
headings in the installation documentation, including the pyvips section and the
section at the corresponding later occurrence, by moving each numeric prefix
after the H3 marker (for example, “### 1. …”). Preserve the existing section
titles and numbering.


[Pyvips](https://pypi.org/project/pyvips/2.0.2/) is a powerful and fast image processing library, particularly suited for working with large images like WSIs. To install `pyvips`, ensure that the `libvips` system dependencies are installed first:

Expand All @@ -18,41 +18,21 @@

Follow the instructions on the official [libvips installation page](https://www.libvips.org/install.html).


2. ### Install the Core Quality Control Library
2. ### Install the Core Quality Control Library

You can install the core library using one of the following methods, depending on your package manager:

=== "pdm"

```bash
pdm add git+https://gitlab.ics.muni.cz/rationai/digital-pathology/quality-control/quality-control.git
```

=== "pip"

```bash
pip install git+https://gitlab.ics.muni.cz/rationai/digital-pathology/quality-control/quality-control.git
```

#### Installing a Specific Version

To install a specific version of the **Quality Control** library, use the following command, replacing `v1.0.0` with your desired version.

=== "pdm"
=== "uv"
(*Note that this command assumes an existing uv project.*)

```bash
pdm add git+https://gitlab.ics.muni.cz/rationai/digital-pathology/quality-control/quality-control.git@v1.0.0
uv add git+https://github.com/RationAI/quality-control.git
```

=== "pip"

```bash
pip install git+https://gitlab.ics.muni.cz/rationai/digital-pathology/quality-control/quality-control.git@v1.0.0
pip install git+https://github.com/RationAI/quality-control.git
```

!!! info

Replace `v1.0.0` with the specific version you want to install.

Once **pyvips**, and the core library are installed, you're ready to start using QC functions.
Loading
Loading