[project] name = "cerbero-bite" version = "0.0.1" description = "Rule-based deterministic engine for Cerberus Bite credit spread strategy on ETH options" readme = "README.md" requires-python = ">=3.12" authors = [{ name = "Adriano Dal Pastro", email = "adrianodalpastro@tielogic.com" }] license = { text = "Proprietary" } dependencies = [ "pydantic>=2.9", "pydantic-settings>=2.5", "click>=8.1", "rich>=13.9", "structlog>=24.4", "apscheduler>=3.10", "sqlalchemy>=2.0", "aiosqlite>=0.20", "pyyaml>=6.0", "httpx>=0.27", "mcp>=1.0", "tenacity>=9.0", "python-dateutil>=2.9", ] [project.optional-dependencies] gui = [ "streamlit>=1.40", "plotly>=5.24", "pandas>=2.2", "numpy>=2.0", ] backtest = [ "scipy>=1.14", "matplotlib>=3.9", "pandas>=2.2", "numpy>=2.0", ] [project.scripts] cerbero-bite = "cerbero_bite.cli:main" [dependency-groups] dev = [ "pytest>=8.3", "pytest-asyncio>=0.24", "pytest-cov>=5.0", "hypothesis>=6.115", "mypy>=1.13", "ruff>=0.7", "pre-commit>=4.0", "types-PyYAML>=6.0", "types-python-dateutil>=2.9", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/cerbero_bite"] [tool.ruff] line-length = 100 target-version = "py312" src = ["src", "tests"] [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 "SIM", # flake8-simplify "RET", # flake8-return "ARG", # flake8-unused-arguments "PTH", # flake8-use-pathlib "ERA", # eradicate "PL", # pylint "RUF", # ruff-specific ] ignore = [ "PLR0913", # too many arguments (we accept config-heavy functions) "PLR2004", # magic value (we have many domain constants in tests) "PLR0911", # too many return statements (rule engines have many early returns) "RUF001", # ambiguous unicode in strings (we use math symbols × ≤ ≥) "RUF002", # ambiguous unicode in docstrings "RUF003", # ambiguous unicode in comments ] [tool.ruff.lint.per-file-ignores] "tests/**" = ["PLR2004", "ARG", "S101", "ERA001", "B017"] [tool.ruff.format] quote-style = "double" indent-style = "space" [tool.mypy] python_version = "3.12" strict = true warn_unreachable = true warn_redundant_casts = true warn_unused_ignores = true disallow_any_generics = true disallow_untyped_defs = true no_implicit_reexport = true files = ["src/cerbero_bite"] [[tool.mypy.overrides]] module = ["apscheduler.*", "mcp.*"] ignore_missing_imports = true [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" addopts = [ "-ra", "--strict-markers", "--strict-config", ] markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", "integration: integration tests with fake MCP", "golden: golden scenario tests", ] [tool.coverage.run] source = ["src/cerbero_bite"] branch = true [tool.coverage.report] exclude_lines = [ "pragma: no cover", "raise NotImplementedError", "if TYPE_CHECKING:", "if __name__ == .__main__.:", ] show_missing = true skip_covered = false