Skip to content

Commit 08e00ab

Browse files
authored
Release/v0.3.1 (Pipelex#74)
### Added - New pytest marker `dry_runnable` for tests that can run without inference. - Enhanced `make` targets with dry-run capabilities for improved test coverage: - `make test-xdist` (or `make t`): Runs all non-inference tests **plus inference tests** that support dry-runs - fast and resource-efficient - `make test-inference` (or `make ti`): Runs tests requiring actual inference, with actual inference (slow and costly) - Parallel test execution using `pytest-xdist` (`-n auto`) enabled for: - GitHub Actions workflows - Codex test targets
1 parent d155426 commit 08e00ab

12 files changed

Lines changed: 48 additions & 28 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
# Changelog
22

3-
## [v0.3.0] - 2025-06-10
3+
## [v0.3.1] - 2025-06-10
4+
5+
### Added
6+
- New pytest marker `dry_runnable` for tests that can run without inference.
7+
- Enhanced `make` targets with dry-run capabilities for improved test coverage:
8+
- `make test-xdist` (or `make t`): Runs all non-inference tests **plus inference tests** that support dry-runs - fast and resource-efficient
9+
- `make test-inference` (or `make ti`): Runs tests requiring actual inference, with actual inference (slow and costly)
10+
- Parallel test execution using `pytest-xdist` (`-n auto`) enabled for:
11+
- GitHub Actions workflows
12+
- Codex test targets
13+
14+
### Changed
15+
- Domain validation is now less restrictive in pipeline TOML: the `definition` attribute is now `Optional`
16+
17+
## [v0.3.0] - 2025-06-09
418

519
### Highlights
620

Makefile

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ VENV_PIPELEX := $(VIRTUAL_ENV)/bin/pipelex
1616

1717
UV_MIN_VERSION = $(shell grep -m1 'required-version' pyproject.toml | sed -E 's/.*= *"([^<>=, ]+).*/\1/')
1818

19+
USUAL_PYTEST_MARKERS := "(dry_runnable or not (inference or llm or imgg or ocr)) and not (needs_output or pipelex_api)"
20+
1921
define PRINT_TITLE
2022
$(eval PROJECT_PART := [$(PROJECT_NAME)])
2123
$(eval TARGET_PART := ($@))
@@ -203,17 +205,17 @@ cleanall: cleanderived cleanenv cleanlibraries
203205
codex-tests: env
204206
$(call PRINT_TITLE,"Unit testing for Codex")
205207
@echo "• Running unit tests for Codex (excluding inference and codex_disabled)"
206-
$(VENV_PYTEST) --exitfirst --quiet -m "not (inference or codex_disabled or pipelex_api)" || [ $$? = 5 ]
208+
$(VENV_PYTEST) -n auto --exitfirst --quiet -m "(dry_runnable or not inference) and not (needs_output or pipelex_api)" || [ $$? = 5 ]
207209

208210
gha-tests: env
209211
$(call PRINT_TITLE,"Unit testing for github actions")
210212
@echo "• Running unit tests for github actions (excluding inference and gha_disabled)"
211-
$(VENV_PYTEST) --exitfirst --quiet -m "not (inference or gha_disabled or pipelex_api)" || [ $$? = 5 ]
213+
$(VENV_PYTEST) -n auto --exitfirst --quiet -m "(dry_runnable or not inference) and not (gha_disabled or pipelex_api)" || [ $$? = 5 ]
212214

213215
run-all-tests: env
214216
$(call PRINT_TITLE,"Running all unit tests")
215217
@echo "• Running all unit tests"
216-
$(VENV_PYTEST) --exitfirst --quiet
218+
$(VENV_PYTEST) -n auto --exitfirst --quiet
217219

218220
run-manual-trigger-gha-tests: env
219221
$(call PRINT_TITLE,"Running GHA tests")
@@ -229,18 +231,18 @@ test: env
229231
$(call PRINT_TITLE,"Unit testing without prints but displaying logs via pytest for WARNING level and above")
230232
@echo "• Running unit tests"
231233
@if [ -n "$(TEST)" ]; then \
232-
$(VENV_PYTEST) -s -o log_cli=true -o log_level=WARNING -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
234+
$(VENV_PYTEST) -s -m $(USUAL_PYTEST_MARKERS) -o log_cli=true -o log_level=WARNING -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
233235
else \
234-
$(VENV_PYTEST) -s -o log_cli=true -o log_level=WARNING $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
236+
$(VENV_PYTEST) -s -m $(USUAL_PYTEST_MARKERS) -o log_cli=true -o log_level=WARNING $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
235237
fi
236238

237239
test-xdist: env
238240
$(call PRINT_TITLE,"Unit testing without prints but displaying logs via pytest for WARNING level and above")
239241
@echo "• Running unit tests"
240242
@if [ -n "$(TEST)" ]; then \
241-
$(VENV_PYTEST) -n auto -o log_level=WARNING -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
243+
$(VENV_PYTEST) -n auto -m $(USUAL_PYTEST_MARKERS) -o log_level=WARNING -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
242244
else \
243-
$(VENV_PYTEST) -n auto -o log_level=WARNING $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
245+
$(VENV_PYTEST) -n auto -m $(USUAL_PYTEST_MARKERS) -o log_level=WARNING $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
244246
fi
245247

246248
t: test-xdist
@@ -250,9 +252,9 @@ test-quiet: env
250252
$(call PRINT_TITLE,"Unit testing without prints but displaying logs via pytest for WARNING level and above")
251253
@echo "• Running unit tests"
252254
@if [ -n "$(TEST)" ]; then \
253-
$(VENV_PYTEST) -o log_cli=true -o log_level=WARNING -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
255+
$(VENV_PYTEST) -m $(USUAL_PYTEST_MARKERS) -o log_cli=true -o log_level=WARNING -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
254256
else \
255-
$(VENV_PYTEST) -o log_cli=true -o log_level=WARNING $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
257+
$(VENV_PYTEST) -m $(USUAL_PYTEST_MARKERS) -o log_cli=true -o log_level=WARNING $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
256258
fi
257259

258260
tq: test-quiet
@@ -262,9 +264,9 @@ test-with-prints: env
262264
$(call PRINT_TITLE,"Unit testing with prints and our rich logs")
263265
@echo "• Running unit tests"
264266
@if [ -n "$(TEST)" ]; then \
265-
$(VENV_PYTEST) -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
267+
$(VENV_PYTEST) -s -m $(USUAL_PYTEST_MARKERS) -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
266268
else \
267-
$(VENV_PYTEST) -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
269+
$(VENV_PYTEST) -s -m $(USUAL_PYTEST_MARKERS) $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
268270
fi
269271

270272
tp: test-with-prints
@@ -273,9 +275,9 @@ tp: test-with-prints
273275
test-inference: env
274276
$(call PRINT_TITLE,"Unit testing")
275277
@if [ -n "$(TEST)" ]; then \
276-
$(VENV_PYTEST) --exitfirst -m "inference and not imgg" -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
278+
$(VENV_PYTEST) --pipe-run-mode live --exitfirst -m "inference and not imgg" -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
277279
else \
278-
$(VENV_PYTEST) --exitfirst -m "inference and not imgg" -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
280+
$(VENV_PYTEST) --pipe-run-mode live --exitfirst -m "inference and not imgg" -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
279281
fi
280282

281283
ti: test-inference
@@ -284,9 +286,9 @@ ti: test-inference
284286
test-ocr: env
285287
$(call PRINT_TITLE,"Unit testing ocr")
286288
@if [ -n "$(TEST)" ]; then \
287-
$(VENV_PYTEST) --exitfirst -m "ocr" -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
289+
$(VENV_PYTEST) --pipe-run-mode live --exitfirst -m "ocr" -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
288290
else \
289-
$(VENV_PYTEST) --exitfirst -m "ocr" -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
291+
$(VENV_PYTEST) --pipe-run-mode live --exitfirst -m "ocr" -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
290292
fi
291293

292294
to: test-ocr
@@ -295,9 +297,9 @@ to: test-ocr
295297
test-imgg: env
296298
$(call PRINT_TITLE,"Unit testing")
297299
@if [ -n "$(TEST)" ]; then \
298-
$(VENV_PYTEST) --exitfirst -m "imgg" -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
300+
$(VENV_PYTEST) --pipe-run-mode live --exitfirst -m "imgg" -s -k "$(TEST)" $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
299301
else \
300-
$(VENV_PYTEST) --exitfirst -m "imgg" -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
302+
$(VENV_PYTEST) --pipe-run-mode live --exitfirst -m "imgg" -s $(if $(filter 1,$(VERBOSE)),-v,$(if $(filter 2,$(VERBOSE)),-vv,$(if $(filter 3,$(VERBOSE)),-vvv,))); \
301303
fi
302304

303305
tg: test-imgg

pipelex/core/domain.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class SpecialDomain(StrEnum):
1313

1414
class Domain(BaseModel):
1515
code: str
16-
definition: str
16+
definition: Optional[str] = None
1717
system_prompt: Optional[str] = None
1818
system_prompt_to_structure: Optional[str] = None
1919
prompt_template_to_structure: Optional[str] = None
@@ -24,4 +24,4 @@ def __str__(self):
2424

2525
@classmethod
2626
def make_default(cls) -> Self:
27-
return cls(code=SpecialDomain.NATIVE, definition="")
27+
return cls(code=SpecialDomain.NATIVE)

pipelex/libraries/library_manager.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ def _load_combo_libraries(self, library_paths: List[str]):
128128
library_name = toml_path.stem
129129
domain_code = library_dict.get("domain")
130130
if domain_code is None:
131-
raise LibraryParsingError(f"Error loafing library '{library_name}' which has no domain set at '{toml_path}'")
131+
raise LibraryParsingError(
132+
f"Error loading library '{library_name}' which has no domain set at '{toml_path}'. "
133+
"Just write 'domain = \"my_domain\"' at the top of the file."
134+
)
132135
domain_definition = library_dict.get("definition")
133136
if domain_definition is None:
134137
# we skip the domain without definition, it must be defined one and only one time in the domain library
@@ -177,10 +180,6 @@ def _load_combo_libraries(self, library_paths: List[str]):
177180

178181
def _load_library_dict(self, library_name: str, library_dict: Dict[str, Any], component_type: LibraryComponent):
179182
if domain_code := library_dict.pop("domain", None):
180-
if not self.domain_library.get_domain(domain_code=domain_code):
181-
raise LibraryParsingError(
182-
f"Domain '{domain_code}' is has not been defined in the domain libraryn make sure it has exactlyone definition"
183-
)
184183
# domain is set at the root of the library
185184
self._load_library_components_from_recursive_dict(
186185
domain_code=domain_code,

pipelex/pipelex.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,4 @@ pipe_stack_limit = 20
244244

245245
[pipelex.dry_run_config]
246246
apply_to_jinja2_rendering = false
247-
text_gen_truncate_length = 256
247+
text_gen_truncate_length = 256

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "pipelex"
3-
version = "0.3.0"
3+
version = "0.3.1"
44
description = "Pipelex is an open-source dev tool based on a simple declarative language that lets you define replicable, structured, composable LLM pipelines."
55
authors = [{ name = "Evotis S.A.S.", email = "evotis@pipelex.com" }]
66
maintainers = [{ name = "Pipelex staff", email = "oss@pipelex.com" }]
@@ -208,6 +208,7 @@ markers = [
208208
"ocr: slow and costly due to ocr inference calls",
209209
"gha_disabled: tests that should not run in GitHub Actions",
210210
"codex_disabled: tests that should not run in Codex",
211+
"dry_runnable: tests that can be run in dry-run mode",
211212
]
212213
minversion = "8.0"
213214

tests/pipelex/pipelex_asynch/test_pipe_batch.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from pipelex.hub import get_pipe_router, get_pipeline_tracker, get_report_delegate
1111

1212

13+
@pytest.mark.dry_runnable
1314
@pytest.mark.llm
1415
@pytest.mark.inference
1516
@pytest.mark.asyncio(loop_scope="class")

tests/pipelex/pipelex_asynch/test_pipe_imgg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from tests.pipelex.test_data import IMGGTestCases
1212

1313

14+
@pytest.mark.dry_runnable
1415
@pytest.mark.imgg
1516
@pytest.mark.inference
1617
@pytest.mark.asyncio(loop_scope="class")

tests/pipelex/pipelex_asynch/test_pipe_llm.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from tests.pipelex.test_data import PipeTestCases
1717

1818

19+
@pytest.mark.dry_runnable
1920
@pytest.mark.llm
2021
@pytest.mark.inference
2122
@pytest.mark.asyncio(loop_scope="class")

tests/pipelex/pipelex_asynch/test_pipe_ocr.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from tests.pipelex.test_data import PipeOcrTestCases
1414

1515

16+
@pytest.mark.dry_runnable
1617
@pytest.mark.ocr
1718
@pytest.mark.inference
1819
@pytest.mark.asyncio(loop_scope="class")

0 commit comments

Comments
 (0)