Skip to content

Commit 61e8b4e

Browse files
authored
Merge pull request #47 from rootcodelabs/RAG-17
Added pyright CI checks for Python type checking
2 parents cd5b913 + 895a102 commit 61e8b4e

File tree

13 files changed

+486
-1
lines changed

13 files changed

+486
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Pyright Type Check
2+
3+
on:
4+
pull_request:
5+
branches: ["*"]
6+
push:
7+
branches: ["*"]
8+
9+
jobs:
10+
pyright:
11+
name: Pyright Type Check
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version-file: '.python-version'
22+
23+
- name: Set up uv
24+
uses: astral-sh/setup-uv@v6
25+
26+
- name: Install dependencies (locked)
27+
run: uv sync --frozen
28+
29+
- name: Run Pyright
30+
run: uv run pyright
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Pytest Testcases Check
2+
3+
on:
4+
pull_request:
5+
branches: ["*"] # run on PRs to any branch
6+
push:
7+
branches: [main, dev, testing, wip] # optional; expand to ["*"] if you want all pushes
8+
9+
jobs:
10+
pytest-testcases:
11+
name: Pytest Testcases Check
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version-file: '.python-version'
22+
23+
- name: Set up uv
24+
uses: astral-sh/setup-uv@v6
25+
26+
# Format check only — fails if files are not formatted
27+
- name: Run test cases using Pytest
28+
run: uv run pytest tests
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Ruff Format Check
2+
3+
on:
4+
pull_request:
5+
branches: ["*"] # run on PRs to any branch
6+
push:
7+
branches: ["*"] # optional; expand to ["*"] if you want all pushes
8+
9+
jobs:
10+
ruff-format:
11+
name: Ruff Format Check
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version-file: '.python-version'
22+
23+
- name: Set up uv
24+
uses: astral-sh/setup-uv@v6
25+
26+
# Format check only — fails if files are not formatted
27+
- name: Ruff format check
28+
run: uvx ruff format --check .
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Ruff Lint Check
2+
3+
on:
4+
pull_request:
5+
branches: ["*"] # run on PRs to any branch
6+
push:
7+
branches: ["*"] # optional; broaden to ["*"] if desired
8+
9+
jobs:
10+
ruff:
11+
name: Ruff Lint & Format Check
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Python
19+
uses: actions/setup-python@v5
20+
with:
21+
python-version-file: '.python-version'
22+
23+
- name: Set up uv
24+
uses: astral-sh/setup-uv@v6
25+
26+
# Lint: exits non-zero on violations -> job fails
27+
- name: Ruff lint
28+
run: uvx ruff check --output-format=github .

.github/workflows/uv-env-check.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: UV Environment Check
2+
3+
on:
4+
pull_request:
5+
branches: ["*"]
6+
push:
7+
branches: ["*"]
8+
9+
jobs:
10+
checks:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Setup uv (with cache)
18+
uses: astral-sh/setup-uv@v6
19+
with:
20+
version: "0.8.15"
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version-file: '.python-version'
26+
27+
# The authoritative guard: MUST match uv.lock and Python markers
28+
- name: Sync (frozen)
29+
run: uv sync --frozen

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12.10

CONTRIBUTING.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Contributor Guidelines
2+
3+
Welcome! This guide helps you set up the project locally for development and contributions. It also explains the coding standards used in the project along with the CI checks
4+
5+
## Local Setup
6+
7+
This project uses **uv** for Python packaging and virtual environments. Python is pinned to **3.12.10** in `pyproject.toml`.
8+
9+
10+
### Step 1: Clone the Repository
11+
Clone the repository and navigate to the project directory.
12+
13+
```bash
14+
cd RAG-Module
15+
```
16+
17+
### Step 2: Install uv
18+
If uv is not already installed, install it via the official installer.
19+
20+
```bash
21+
curl -LsSf https://astral.sh/uv/install.sh | sh
22+
# Restart your terminal or run: source ~/.zshrc
23+
```
24+
25+
### Step 3: Install the Required Python Version
26+
Use uv to install and manage Python 3.12.10.
27+
28+
```bash
29+
uv python install 3.12.10
30+
```
31+
32+
### Step 4: Recreate the Virtual Environment
33+
From the project root (where `pyproject.toml` and `uv.lock` are located), recreate the environment from the lockfile.
34+
35+
```bash
36+
# Create .venv and install dependencies strictly from uv.lock
37+
uv sync --frozen
38+
```
39+
40+
**Notes:**
41+
- `uv sync` creates a local `.venv/` directory by default and installs dependencies from `uv.lock`.
42+
- If `--frozen` fails due to a stale lockfile, run `uv sync -p 3.12.10` (without `--frozen`) to resolve and update.
43+
44+
### Step 5: Activate the Environment (Optional)
45+
Activate the virtual environment to use it directly.
46+
47+
```bash
48+
source .venv/bin/activate
49+
python -V # Should output: Python 3.12.10
50+
```
51+
52+
### Step 6: Run the Application
53+
54+
When running the FastAPI APIs locally always run with
55+
56+
```bash
57+
uv run python app.py
58+
```
59+
60+
instead of
61+
62+
```bash
63+
python3 app.py
64+
```
65+
66+
This will make sure that regardless of whether you have activated the .venv environment or not uv will use the right versions when setting up the
67+
68+
69+
For more help, check the [uv documentation](https://docs.astral.sh/uv/)
70+
71+
## CI Checks
72+
73+
### Environment Check
74+
75+
- Located in `.github/workflows/uv-env-check.yml`
76+
77+
- This GitHub actions check runs to check whether there are any conflicts between the lockfile and pyproject.toml. If it fails, then there has been some dependency update to the pyproject.toml without updating the lockfile
78+
79+
### Type check for Python
80+
81+
## Installing New Dependencies to the Project (Python)
82+
83+
If you need to add a new Python dependency, **do not run `pip install` directly**.
84+
85+
We use `uv` to manage environments and lockfiles so that installs are reproducible in local development, CI, and containers.
86+
87+
### Follow This Process:
88+
89+
#### 1. Add the Dependency
90+
Use `uv add` instead of `pip install`. This ensures both `pyproject.toml` and `uv.lock` are updated together.
91+
92+
```bash
93+
uv add "package-name>=x.y,<x.(y+1)"
94+
```
95+
96+
- Use a bounded version range (`>=` + `<`) to avoid uncontrolled upgrades.
97+
98+
99+
#### 2. Re-sync Your Environment
100+
After adding, re-sync to refresh your local `.venv`:
101+
102+
```bash
103+
uv sync --reinstall
104+
```
105+
106+
#### 3. Run Checks Locally
107+
Make sure type checks, linter, and tests pass:
108+
109+
```bash
110+
uv run pyright
111+
uv run ruff check .
112+
uv run pytest
113+
```
114+
115+
#### 4. Commit Both Files
116+
Always commit both `pyproject.toml` and `uv.lock`. If only one is updated, CI will fail (`uv sync --frozen` check).
117+
118+
```bash
119+
git add pyproject.toml uv.lock
120+
git commit -m "added package-name dependency"
121+
```
122+
123+
#### 5. Open a PR
124+
CI will validate that the lockfile and environment are consistent. If you forgot to update the lockfile, the PR will fail with a clear error.
125+
126+
---
127+
128+
### Important Notes
129+
130+
- **Never edit `uv.lock` manually.** It is controlled by `uv`.
131+
- **Never use `uv pip install` for permanent deps** — it only changes your local venv. Use `uv add` instead.
132+
- If you remove a dependency, run:
133+
134+
```bash
135+
uv remove package-name
136+
uv sync --reinstall
137+
git add pyproject.toml uv.lock
138+
git commit -m "removed package-name"
139+
```
140+
141+
## Coding Standards
142+
143+
## PR evaluation criteria

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,26 @@
1-
# RAG-Module
1+
# BYK-RAG (Retrieval-Augmented Generation Module)
2+
3+
The **BYK-RAG Module** is part of the Burokratt ecosystem, designed to provide **retrieval-augmented generation (RAG)** capabilities for Estonian government digital services. It ensures reliable, multilingual, and compliant AI-powered responses by integrating with multiple LLM providers, syncing with knowledge bases, and exposing flexible configuration and monitoring features for administrators.
4+
5+
---
6+
7+
## Features
8+
9+
- **Configurable LLM Providers**
10+
- Support for AWS Bedrock, Azure AI, Google Cloud, OpenAI, Anthropic, and self-hosted open-source LLMs.
11+
- Admins can create "connections" and switch providers/models without downtime.
12+
- Models searchable via dropdown with cache-enabled indicators.
13+
14+
- **Knowledge Base Integration**
15+
- Continuous sync with central knowledge base (CKB).
16+
- Last sync timestamp displayed in UI.
17+
- LLMs restricted to answering only from CKB content.
18+
- “I don’t know” payload returned when confidence is low.
19+
20+
- **Citations & Transparency**
21+
- All responses are accompanied with **clear citations**.
22+
23+
- **Analytics & Monitoring**
24+
- External **Langfuse dashboard** for API usage, inference trends, cost analysis, and performance logs.
25+
- Agencies can configure cost alerts and view alerts via LLM Alerts UI.
26+
- Logs integrated with **Grafana Loki**.

pyproject.toml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
[project]
2+
name = "rag-module"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = "==3.12.10"
7+
dependencies = [
8+
"pyright>=1.1.404",
9+
"pytest>=8.4.1",
10+
]
11+
12+
[tool.pyright]
13+
# --- Environment & discovery ---
14+
pythonVersion = "3.12.10" # Target Python semantics (pattern matching, typing features, stdlib types).
15+
venvPath = "." # Where virtual envs live relative to repo root.
16+
venv = ".venv" # The specific env name uv manages (uv sync creates .venv).
17+
18+
# --- What to analyze ---
19+
include = ["src", "tests"] # Top-level packages & tests to check.
20+
exclude = [
21+
"**/.venv", "**/__pycache__", "build", "dist", ".git",
22+
".ruff_cache", ".mypy_cache"
23+
]
24+
25+
# --- Global strictness ---
26+
typeCheckingMode = "strict" # Enforce full strict mode repo-wide (see notes below).
27+
useLibraryCodeForTypes = true # If a lib lacks stubs, inspect its code to infer types where possible.
28+
29+
# Make the most common "loose" mistakes fail fast in strict mode.
30+
# You can tune these individually if you need a temporary carve-out.
31+
reportMissingTypeStubs = "error" # Untyped third-party libs must have type info (stubs or inline).
32+
reportUnknownVariableType = "error" # Vars with unknown/implicit Any are not allowed.
33+
reportUnknownMemberType = "error" # Members on unknowns are not allowed.
34+
reportUnknownArgumentType = "error" # Call arguments can't be unknown.
35+
reportUnknownLambdaType = "error" # Lambda params must be typed in strict contexts.
36+
reportImplicitOptional = "error" # T | None must be explicit; no silent Optional.
37+
reportMissingTypeArgument = "error" # Generic types must specify their parameters.
38+
reportIncompatibleVariableOverride = "error" # Subclass fields must type-refine correctly.
39+
reportInvalidTypeVarUse = "error" # Catch misuse of TypeVar/variance.
40+
reportUntypedFunctionDecorator = "error" # Decorators must be typed (prevents Any leakage).
41+
reportUnusedVariable = "error" # Ditto; promote to "error" if you want hard hygiene.
42+
reportUnusedImport = "warning" # Hygiene: warn, but don’t fail builds.
43+
44+
45+
# Tests often deserialize lots of data and patch frameworks; keep them strict,
46+
# but relax "missing stubs" so untyped test-only libs don’t block you.
47+
[[tool.pyright.overrides]]
48+
module = "tests/**"
49+
reportMissingTypeStubs = "warning"

src/main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
def main():
2+
""
3+
print("Hello from rag-module!")
4+
5+
6+
if __name__ == "__main__":
7+
main()

0 commit comments

Comments
 (0)