From ef593009fee3ba66e66f1371af116037b624ee1b Mon Sep 17 00:00:00 2001 From: vitor-aignosi Date: Wed, 26 Aug 2026 16:15:14 -0300 Subject: [PATCH] Add pyproject.toml --- pyproject.toml | 189 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2f2ef0d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,189 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "laborious" +version = "0.0.0" +description = "Sientia DataOps Laborious - ML Model Orchestration System" +readme = "README.md" +requires-python = ">=3.11" +authors = [ + {name = "Aignosi", email = "dev@aignosi.com"} +] + +[tool.ruff] +line-length = 100 +target-version = "py311" +exclude = [ + ".git", + ".venv", + "venv", + "__pycache__", + "*.pyc", + ".pytest_cache", + "htmlcov", + "tests/laborious/workflows/subworkflows/test_prediction_process.py", +] + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "UP", # pyupgrade + "N", # pep8-naming + "YTT", # flake8-2020 + "S", # flake8-bandit + "BLE", # flake8-blind-except + "A", # flake8-builtins + "C90", # mccabe complexity +] + +ignore = [ + "BLE001", # ignore blind except, we need to send notifications with any error + "E501", # line too long (handled by formatter) + "S101", # use of assert (needed for tests) + "S105", # possible hardcoded password (false positives) + "S106", # possible hardcoded password (false positives) + "S608", # potential sql injection (false positives) + "N802", # function name should be lowercase (temporal decorators) + "N806", # variable in function should be lowercase +] + +[tool.ruff.lint.per-file-ignores] +"tests/**/*.py" = [ + "S101", # assert allowed in tests + "S105", # hardcoded passwords ok in tests + "S106", # hardcoded passwords ok in tests +] +"e2e/conftest.py" = [ + # Imports below the sientia/ModelAnalysis stub are load-order critical: the stub + # must be in sys.modules before Activities is imported, so they cannot move up. + "E402", +] +"scripts/**/*.py" = [ + # Notebook-style scripts split into `# %%` cells: each cell imports what it needs + # where it needs it, so imports legitimately appear below other statements. + "E402", +] + +[tool.ruff.lint.mccabe] +max-complexity = 15 + +[tool.ruff.format] +quote-style = "single" +indent-style = "space" +line-ending = "auto" + +[tool.mypy] +python_version = "3.11" +warn_return_any = false +warn_unused_configs = true +disallow_untyped_defs = false +disallow_incomplete_defs = false +check_untyped_defs = true +no_implicit_optional = true +warn_redundant_casts = true +warn_unused_ignores = false +warn_no_return = true +strict_equality = true +ignore_missing_imports = true + +# Ignore missing imports for external packages +[[tool.mypy.overrides]] +module = "temporalio.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "sientia_do.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "mlflow.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "prometheus_client.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "sientia.*" +ignore_missing_imports = true + +[[tool.mypy.overrides]] +module = "pandas.*" +ignore_missing_imports = true + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = ["test_*.py"] +python_classes = ["Test*"] +python_functions = ["test_*"] +addopts = [ + "-v", + "--strict-markers", + # pytest>=9.1 has a known bug where its unraisableexception plugin crashes + # (tracemalloc partially-initialized AttributeError) when 2+ unraisable + # exceptions land close together — e.g. "coroutine was never awaited" from + # AsyncMock-mocked sync methods (metrics_controller, minio_repository) being + # GC'd. Harmless mock artifacts turned into a hard ERROR by the plugin itself. + "-p", "no:unraisableexception", +] +filterwarnings = [ + # `kafka-python`, pulled in transitively by `sientia_do`, reads its protocol schemas through the + # legacy `importlib.resources` API that Python 3.11 deprecated. It emits ~109 warnings per run, + # twice each (once at the call site, once inside `importlib`), which is enough noise to bury a + # warning worth reading. Nothing here can fix it — the change belongs in `kafka-python`. + # + # Matched on the message rather than by module so the filter cannot quietly swallow an unrelated + # deprecation: any *other* DeprecationWarning, including one from our own code, still shows up. + "ignore:read_text is deprecated:DeprecationWarning", + "ignore:open_text is deprecated:DeprecationWarning", +] +markers = [ + "asyncio: marks tests as async", + "integration: marks tests as integration tests", + "unit: marks tests as unit tests", + "opc: marks tests that use the in-process OPC UA server (OpcRepository E2E)", + # The .sientia import e2e suite. Outside `testpaths`, so `validate --only-tests` and the + # coverage gate never collect it; run it on request with `pytest e2e -m import_e2e`. + "import_e2e: marks the model-import end-to-end tests (needs Docker and an MLflow server)", + "slow: marks tests that run on a real clock and take tens of seconds", +] + +[tool.coverage.run] +source = ["laborious"] +omit = [ + "*/tests/*", + "*/venv/*", + "*/__pycache__/*", + "*/site-packages/*", +] +branch = true + +[tool.coverage.report] +precision = 2 +show_missing = true +skip_covered = false +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "def __str__", + "raise AssertionError", + "raise NotImplementedError", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", + "class .*\\bProtocol\\):", + "@(abc\\.)?abstractmethod", +] + +[tool.coverage.html] +directory = "htmlcov" + +[tool.bandit] +exclude_dirs = ["tests", "venv", ".venv"] +skips = ["B101", "B601", "B608"] # Skip assert, shell injection, and SQL injection (false positives) \ No newline at end of file