Ctrl K
ComunidadGuías…

pyproject.toml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
[project]
name = "jobd"
version = "0.5.57"
description = "Self-hostable GPU-aware job broker for your own machines, with native MCP/agent integration"
readme = "README.md"
license = { text = "MIT" }
authors = [{ name = "Jaret Arnold" }]
keywords = ["job-queue", "gpu", "scheduler", "mcp", "self-hosted", "homelab"]
requires-python = ">=3.11"
classifiers = [
    "Development Status :: 4 - Beta",
    "Environment :: Console",
    "Intended Audience :: Developers",
    "Intended Audience :: Science/Research",
    "License :: OSI Approved :: MIT License",
    "Operating System :: POSIX :: Linux",
    "Operating System :: MacOS",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Topic :: System :: Distributed Computing",
    "Topic :: Scientific/Engineering",
]
dependencies = [
    "fastapi>=0.110",
    "starlette>=1.0.1",
    "uvicorn[standard]>=0.27",
    "sqlalchemy>=2.0",
    "pydantic>=2.6",
    "pyyaml>=6.0",
    "typer>=0.9",
    "httpx>=0.26",
    "sse-starlette>=2.0",
    "prometheus-client>=0.20",
]

[project.urls]
Homepage = "https://github.com/musharna/jobd"
Repository = "https://github.com/musharna/jobd"
Issues = "https://github.com/musharna/jobd/issues"
Changelog = "https://github.com/musharna/jobd/blob/main/CHANGELOG.md"

[project.optional-dependencies]
worker = [
    "httpx>=0.26",
    "psutil>=5.9",
    "nvidia-ml-py>=12",
    "pyyaml>=6.0",
]
dev = [
    "pytest>=8.0",
    "pytest-asyncio>=0.23",
    "pytest-cov>=4.1",
    "pytest-timeout>=2.2",
    "respx>=0.20",
    "ruff>=0.3",
    "mypy>=1.8",
    "types-PyYAML",
    "hypothesis>=6.0",
]
mcp = ["mcp>=2,<3", "httpx>=0.27", "jsonschema>=4.18"]

[project.scripts]
jobd = "jobd.main:run"
job = "job_cli.cli:main"
jobd-mcp = "jobd.mcp.server:main"
jobd-worker = "jobd.worker.job_worker:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/jobd", "src/job_cli"]

# `job fleet add` pushes these over ssh at runtime; the canonical copies stay
# in scripts/ (where the deploy-lints and CD tests read them), the wheel gets
# copies. tests/test_fleet_cli.py builds a real wheel and asserts they landed.
[tool.hatch.build.targets.wheel.force-include]
"scripts/install-worker.sh" = "jobd/fleet_assets/install-worker.sh"
"scripts/update-worker.sh" = "jobd/fleet_assets/update-worker.sh"

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
# Bound any single hung test (a stuck subprocess/socket/watchdog) so CI fails
# in minutes instead of stalling to GitHub's 6h job kill. Generous vs the
# slowest real test (~50s: the meta-test that reruns the suite as a subprocess).
# Per-test override: @pytest.mark.timeout(N).
timeout = 300
markers = [
    "live: real-execution/live-broker suite behind an explicit opt-in env (RUN_LIVE_JOBD / JOBD_LIVE / JOBD_E2E); structurally deselected in CI via -m 'not live'",
]

[tool.mypy]
python_version = "3.11"
ignore_missing_imports = true
warn_unused_ignores = true
# Check the bodies of un-annotated functions too. Without this, mypy silently
# skips the bodies of every def lacking a full signature — which is most of the
# broker/worker hot path (app.py, job_worker.py) — making the "mypy green" gate
# vacuous there (audit Quality-4, 2026-07-01). The codebase already passes with
# it on; test_deploy_lint.py::test_mypy_checks_untyped_defs keeps it enabled.
check_untyped_defs = true

[tool.ruff]
line-length = 100
target-version = "py311"

[tool.ruff.lint]
# E/F (default) plus import-sorting, bugbear, pyupgrade, and simplify.
# E501 (line-too-long) is intentionally left to the formatter — `ruff format`
# wraps code; E501 would otherwise only nag about long strings/comments/URLs.
select = ["E", "F", "I", "B", "UP", "SIM"]
ignore = ["E501"]

[tool.ruff.lint.flake8-bugbear]
# Typer requires typer.Argument()/typer.Option() as argument defaults — these
# are not the mutable-default antipattern B008 targets.
extend-immutable-calls = ["typer.Argument", "typer.Option"]

[tool.ruff.lint.per-file-ignores]
# Nested `with patch.object(...)` is a readable, idiomatic test pattern.
"tests/**" = ["SIM117"]

[tool.coverage.report]
# Branch-coverage floor enforced by ci.yml's coverage leg (the workflow flag
# must agree; tests/test_deploy_lint.py checks). Measured 86.8% on 2026-09-02.
fail_under = 83