[build-system] requires = ["setuptools>=68", "wheel"] build-backend = "setuptools.build_meta" [project] name = "fester" version = "0.3.0" description = "Distributed, DAG-driven build execution system with real-time scheduling, observability, and deterministic replay" readme = "README.md" license = { text = "AGPL-3.0-or-later", file = "LICENSE" } authors = [ { name = "Fester Contributors" }, ] requires-python = ">=3.12" keywords = ["build", "distributed", "scheduler", "dag", "compile", "distcc", "observability"] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "Environment :: Web Environment", "Framework :: FastAPI", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Build Tools", "Topic :: System :: Distributed Computing", ] # Core runtime dependencies dependencies = [ "fastapi>=0.128", "uvicorn[standard]>=0.30", "websockets>=12", "pydantic>=2", "aiohttp>=3.9", "minio>=7.2", "prometheus-client>=0.20", "PyYAML>=6", "requests>=2.31", "websocket-client>=1.7", ] [project.optional-dependencies] # Install with: pip install -e ".[dev]" dev = [ "ruff>=0.5", "mypy>=1.10", "pytest>=8", "pytest-asyncio>=0.23", "httpx>=0.27", # for FastAPI TestClient "respx>=0.21", # for mocking aiohttp in tests ] # Install with: pip install -e ".[docker]" docker = [ "gunicorn>=22", ] [project.scripts] # After `pip install -e .`, you can run `fester` from anywhere fester = "cli.fester:main" [project.urls] Homepage = "https://git.dcos.net/dcosnet/fester" Repository = "https://git.dcos.net/dcosnet/fester" Documentation = "https://git.dcos.net/dcosnet/fester/blob/main/README.md" Issues = "https://git.dcos.net/dcosnet/fester/issues" # ------------------------------------------------------------ # Setuptools package discovery # ------------------------------------------------------------ [tool.setuptools] # We're not a pure-Python package — just expose the CLI + backend modules py-modules = [] [tool.setuptools.packages.find] where = ["."] include = [ "backend*", "cli*", "cockpit*", ] exclude = [ "tests*", "docs*", "scripts*", ] [tool.setuptools.package-data] # Include non-Python files in the package "*" = ["*.html", "*.css", "*.js", "*.yaml", "*.json", "*.md"] # ------------------------------------------------------------ # Ruff (linter + formatter) # ------------------------------------------------------------ [tool.ruff] line-length = 100 target-version = "py312" extend-exclude = [ "docs", "scripts/mock_agent.py", ] [tool.ruff.lint] # Enable common rule sets select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade "RUF", # ruff-specific ] ignore = [ "E501", # line too long (we use 100 but don't want to fail on it) "B008", # do not perform function calls in argument defaults (FastAPI does this) "B904", # raise from (we have a lot of legacy code) "RUF001", # ambiguous unicode (we use emojis) "RUF002", # ambiguous unicode in docstring "RUF003", # ambiguous unicode in comment ] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] # re-exports "cli/fester.py" = ["E402"] # module-level imports after argparse helpers [tool.ruff.format] quote-style = "double" indent-style = "space" # ------------------------------------------------------------ # Mypy (type checking) # ------------------------------------------------------------ [tool.mypy] python_version = "3.12" warn_return_any = false # too noisy for this codebase warn_unused_configs = true disallow_untyped_defs = false # we have legacy untyped code disallow_incomplete_defs = false check_untyped_defs = true disallow_untyped_decorators = false no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true warn_unreachable = true strict_equality = true show_error_codes = true [[tool.mypy.overrides]] module = [ "minio.*", "aiohttp.*", "websocket.*", "prometheus_client.*", ] ignore_missing_imports = true # ------------------------------------------------------------ # Pytest # ------------------------------------------------------------ [tool.pytest.ini_options] minversion = "8.0" testpaths = ["tests"] asyncio_mode = "auto" filterwarnings = [ "ignore::DeprecationWarning", "ignore::PendingDeprecationWarning", ] markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", "integration: marks tests that require external services (minio, etc.)", ]