Skip to content

Commit bce5b7f

Browse files
authored
chore: add pre-commit hooks and lint code (#2)
1 parent 0194a28 commit bce5b7f

21 files changed

+444
-217
lines changed

.github/workflows/lint.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Linting
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
15+
- name: Install uv
16+
uses: astral-sh/setup-uv@v6
17+
18+
- name: Run linter
19+
shell: bash
20+
run: uv run -- pre-commit run -a

.github/workflows/publish_release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- uses: actions/checkout@v4
1919

2020
- name: Install uv
21-
uses: astral-sh/setup-uv@v5
21+
uses: astral-sh/setup-uv@v6
2222

2323
- name: Build and publish
2424
env:

.pre-commit-config.yaml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
default_language_version:
3+
python: python3
4+
5+
repos:
6+
- repo: https://github.com/pre-commit/pre-commit-hooks
7+
rev: v5.0.0
8+
hooks:
9+
- id: check-byte-order-marker
10+
- id: check-merge-conflict
11+
- id: check-toml
12+
- id: check-yaml
13+
args: [--allow-multiple-documents]
14+
- id: detect-private-key
15+
- id: end-of-file-fixer
16+
- id: mixed-line-ending
17+
- id: trailing-whitespace
18+
19+
- repo: https://github.com/charliermarsh/ruff-pre-commit
20+
rev: v0.11.13
21+
hooks:
22+
- id: ruff-format
23+
- id: ruff-check
24+
args: [--fix, --exit-non-zero-on-fix]
25+
26+
- repo: https://github.com/pre-commit/mirrors-mypy
27+
rev: v1.15.0
28+
hooks:
29+
- id: mypy
30+
additional_dependencies:
31+
[
32+
"types-Deprecated",
33+
"types-PyYAML",
34+
"types-botocore",
35+
"types-aiobotocore",
36+
"types-protobuf==4.24.0.4",
37+
"types-redis",
38+
"types-requests",
39+
"types-setuptools",
40+
"types-click",
41+
]
42+
args:
43+
[
44+
--disallow-untyped-defs,
45+
--ignore-missing-imports,
46+
--python-version=3.11,
47+
]
48+
# exclude: ^(examples/|e2e_tests/|tests/message_queues/test_aws.py)
49+
50+
- repo: https://github.com/codespell-project/codespell
51+
rev: v2.3.0
52+
hooks:
53+
- id: codespell
54+
additional_dependencies: [tomli]
55+
56+
- repo: https://github.com/pappasam/toml-sort
57+
rev: v0.23.1
58+
hooks:
59+
- id: toml-sort-fix

pyproject.toml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,24 @@
22
requires = ["hatchling"]
33
build-backend = "hatchling.build"
44

5+
[dependency-groups]
6+
dev = [
7+
"pre-commit>=4.2.0",
8+
"pytest>=8.4.0",
9+
"pytest-asyncio>=1.0.0",
10+
"pytest-cov>=6.1.1"
11+
]
12+
513
[project]
614
name = "llama-index-workflows"
715
version = "0.1.0"
816
description = "Add your description here"
917
readme = "README.md"
1018
requires-python = ">=3.9"
1119
dependencies = [
12-
"llama-index-instrumentation>=0.1.0",
13-
"pydantic>=2.11.5",
20+
"llama-index-instrumentation>=0.1.0",
21+
"pydantic>=2.11.5"
1422
]
1523

16-
[dependency-groups]
17-
dev = ["pytest>=8.4.0", "pytest-asyncio>=1.0.0", "pytest-cov>=6.1.1"]
18-
1924
[tool.hatch.build.targets.wheel]
2025
packages = ["src/workflows"]

src/workflows/service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def __init__(self) -> None:
2323
def get(self, name: str, default: Optional["Workflow"] = None) -> "Workflow":
2424
try:
2525
return self._services[name]
26-
except KeyError as e:
26+
except KeyError:
2727
if default:
2828
return default
2929

src/workflows/utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def get_steps_from_class(_class: object) -> Dict[str, Callable]:
171171
Dict[str, Callable]: A dictionary mapping step names to their corresponding methods.
172172
173173
"""
174-
step_methods = {}
174+
step_methods: dict[str, Callable] = {}
175175
all_methods = inspect.getmembers(_class, predicate=inspect.isfunction)
176176

177177
for name, method in all_methods:
@@ -192,7 +192,7 @@ def get_steps_from_instance(workflow: object) -> Dict[str, Callable]:
192192
Dict[str, Callable]: A dictionary mapping step names to their corresponding methods.
193193
194194
"""
195-
step_methods = {}
195+
step_methods: dict[str, Callable] = {}
196196
all_methods = inspect.getmembers(workflow, predicate=inspect.ismethod)
197197

198198
for name, method in all_methods:
@@ -315,8 +315,8 @@ def import_module_from_qualified_name(qualified_name: str) -> Any:
315315
if not qualified_name or "." not in qualified_name:
316316
raise ValueError("Qualified name must be in format 'module.attribute'")
317317

318+
module_path = qualified_name.rsplit(".", 1)
318319
try:
319-
module_path = qualified_name.rsplit(".", 1)
320320
module = import_module(module_path[0])
321321
return getattr(module, module_path[1])
322322
except ImportError as e:

tests/conftest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ async def end_step(self, ev: LastEvent) -> StopEvent:
3434

3535

3636
@pytest.fixture()
37-
def workflow():
37+
def workflow() -> Workflow:
3838
return DummyWorkflow()
3939

4040

4141
@pytest.fixture()
42-
def events():
42+
def events() -> list:
4343
return [OneTestEvent, AnotherTestEvent]
4444

4545

4646
@pytest.fixture()
47-
def ctx():
47+
def ctx() -> Context:
4848
return Context(workflow=DummyWorkflow())

tests/test_checkpointer.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717

1818
@pytest.fixture()
19-
def workflow_checkpointer(workflow: DummyWorkflow):
19+
def workflow_checkpointer(workflow: DummyWorkflow) -> WorkflowCheckpointer:
2020
return WorkflowCheckpointer(workflow=workflow)
2121

2222

2323
@pytest.mark.asyncio
24-
async def test_create_checkpoint(workflow_checkpointer: WorkflowCheckpointer):
24+
async def test_create_checkpoint(workflow_checkpointer: WorkflowCheckpointer) -> None:
2525
incoming_ev = StartEvent()
2626
output_ev = OneTestEvent()
2727
ctx = Context(workflow=workflow_checkpointer.workflow)
@@ -48,7 +48,7 @@ async def test_create_checkpoint(workflow_checkpointer: WorkflowCheckpointer):
4848
@pytest.mark.asyncio
4949
async def test_checkpoints_after_successive_runs(
5050
workflow_checkpointer: WorkflowCheckpointer,
51-
):
51+
) -> None:
5252
num_steps = len(workflow_checkpointer.workflow._get_steps())
5353
num_runs = 2
5454

@@ -67,7 +67,7 @@ async def test_checkpoints_after_successive_runs(
6767

6868

6969
@pytest.mark.asyncio
70-
async def test_filter_checkpoints(workflow_checkpointer: WorkflowCheckpointer):
70+
async def test_filter_checkpoints(workflow_checkpointer: WorkflowCheckpointer) -> None:
7171
num_runs = 2
7272
for _ in range(num_runs):
7373
handler: WorkflowHandler = workflow_checkpointer.run()
@@ -106,11 +106,11 @@ async def test_filter_checkpoints(workflow_checkpointer: WorkflowCheckpointer):
106106
@pytest.mark.asyncio
107107
async def test_checkpoints_works_with_new_instances_concurrently(
108108
workflow_checkpointer: WorkflowCheckpointer,
109-
):
109+
) -> None:
110110
num_instances = 3
111111
tasks = []
112112

113-
async def add_random_startup(coro: WorkflowHandler):
113+
async def add_random_startup(coro: WorkflowHandler) -> None:
114114
"""To randomly mix up the processing of the 3 runs."""
115115
startup = random.random()
116116
await asyncio.sleep(startup)
@@ -134,7 +134,7 @@ async def add_random_startup(coro: WorkflowHandler):
134134

135135

136136
@pytest.mark.asyncio
137-
async def test_run_from_checkpoint(workflow_checkpointer: WorkflowCheckpointer):
137+
async def test_run_from_checkpoint(workflow_checkpointer: WorkflowCheckpointer) -> None:
138138
num_steps = len(workflow_checkpointer.workflow._get_steps())
139139
num_ckpts_in_single_run = num_steps - 1
140140
handler: WorkflowHandler = workflow_checkpointer.run()
@@ -146,7 +146,7 @@ async def test_run_from_checkpoint(workflow_checkpointer: WorkflowCheckpointer):
146146
ckpt = workflow_checkpointer.filter_checkpoints(last_completed_step="middle_step")[
147147
0
148148
]
149-
handler: WorkflowHandler = workflow_checkpointer.run_from(checkpoint=ckpt)
149+
handler = workflow_checkpointer.run_from(checkpoint=ckpt)
150150
await handler
151151

152152
assert len(workflow_checkpointer.checkpoints) == 2
@@ -164,7 +164,7 @@ async def test_run_from_checkpoint(workflow_checkpointer: WorkflowCheckpointer):
164164
async def test_checkpointer_with_stepwise(
165165
mock_uuid: MagicMock,
166166
workflow_checkpointer: WorkflowCheckpointer,
167-
):
167+
) -> None:
168168
# -------------------------------
169169
# Stepwise run with checkpointing
170170
stepwise_run_id = "stepwise_run"
@@ -219,7 +219,7 @@ async def test_checkpointer_with_stepwise(
219219
async def test_disable_and_enable_checkpoints(
220220
mock_uuid: MagicMock,
221221
workflow_checkpointer: WorkflowCheckpointer,
222-
):
222+
) -> None:
223223
run_ids = ["42", "84"]
224224
mock_uuid.uuid4.side_effect = run_ids
225225

0 commit comments

Comments
 (0)