[project] name = "calibre-bookwarden" version = "1.3.2" description = "Local, supervised Calibre metadata auditing with read-only Certificate A verification and sealed evidence" readme = "README.md" requires-python = ">=3.12" license = { text = "GPL-3.0-or-later" } authors = [{ name = "Calibre Bookwarden Contributors" }] dependencies = [ "typer>=0.12.3", "pydantic>=2.7.1", "pydantic-settings>=2.2.1", "pyyaml>=6.0.1", "httpx>=0.27.0", "pymupdf>=1.27.0", "ocrmypdf>=16.3.0", "rich>=13.7.1", "python-dotenv>=1.0.1", "sqlmodel>=0.0.19", "pillow>=12.3.0", "fastapi>=0.111.0", "uvicorn>=0.30.0", "psycopg[binary]>=3.1.18", "redis>=5.0.0", "alembic>=1.13.1", "numpy>=1.26.0", "jinja2>=3.1.3", "python-multipart>=0.0.9", ] [project.optional-dependencies] legacy = [ "aiofiles>=23.0.0", "google-genai>=0.1.0", "imagehash>=4.3.1", "jinja2>=3.1.3", "openai>=1.0.0", "pymupdf4llm>=0.0.12", "python-multipart>=0.0.9", "qdrant-client>=1.9.0", ] mcp = [ "fastmcp>=0.1.0", ] ingest = [ "watchdog>=4.0.0", ] ocr = [ "paddleocr>=2.7.0", "paddlepaddle>=2.6.0", ] [dependency-groups] test = [ "pytest>=8.2.0", "pytest-asyncio>=1.3.0", ] dev = [ { include-group = "test" }, "aiofiles>=23.0.0", "fastmcp>=0.1.0", "google-genai>=0.1.0", "imagehash>=4.3.1", "jinja2>=3.1.3", "openai>=1.0.0", "pymupdf4llm>=0.0.12", "python-multipart>=0.0.9", "pytest-cov>=5.0.0", "pytest-benchmark>=4.0.0", "qdrant-client>=1.9.0", "ruff>=0.4.4", "mypy>=1.10.0", "watchdog>=4.0.0", ] [tool.uv] constraint-dependencies = [ "pi-heif>=1.3.0", "pikepdf>=10.10.0", ] [project.scripts] bookwarden = "calibre_ai_auditor.cli.main:app" calibre-bookwarden = "calibre_ai_auditor.cli.main:app" bookaudit = "calibre_ai_auditor.cli.main:app" bookwarden-certificate-a = "calibre_ai_auditor.production_cli:app" bookaudit-certificate-a = "calibre_ai_auditor.production_cli:app" [project.urls] Homepage = "https://github.com/felixapel/calibre-bookwarden" Documentation = "https://github.com/felixapel/calibre-bookwarden#readme" Repository = "https://github.com/felixapel/calibre-bookwarden.git" Issues = "https://github.com/felixapel/calibre-bookwarden/issues" Funding = "https://github.com/sponsors/felixapel" [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [tool.ruff] line-length = 120 target-version = "py312" [tool.ruff.lint] select = ["E", "F", "I", "N", "UP", "B", "C4", "SIM", "ARG", "PT"] ignore = ["B008", "ARG001", "ARG002"] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" markers = [ "benchmark: marks tests as performance benchmarks (deselect with -m 'not benchmark')", "ocr_live: marks tests that require real OCR dependencies installed locally", "network: marks tests that hit network services (deselect with -m 'not network')", "v2_live: required Manifestation V2 pilot integration with Calibre, OCR, PostgreSQL, and Valkey", ] addopts = "-ra --strict-markers" [tool.mypy] python_version = "3.12" strict = true warn_return_any = true warn_unused_configs = true show_error_codes = true [[tool.mypy.overrides]] # ocr/vision.py uses SQLModel Column queries that mypy can't infer through Pydantic v2 module = "calibre_ai_auditor.ocr.vision" ignore_errors = true # Per-file mypy overrides. Each lists the module path and the ignore flags. # Format: one `[[tool.mypy.overrides]]` block per module to avoid the # "Cannot overwrite a value" error that the new pydantic-settings emits. [[tool.mypy.overrides]] module = "calibre_ai_auditor.verification.ocr_router" ignore_missing_imports = true ignore_errors = true [[tool.mypy.overrides]] module = "calibre_ai_auditor.ingest.watcher" ignore_missing_imports = true [[tool.mypy.overrides]] module = "calibre_ai_auditor.queue.valkey" ignore_missing_imports = true [[tool.mypy.overrides]] module = "calibre_ai_auditor.llm.providers.google_provider" ignore_errors = true [[tool.mypy.overrides]] module = "yaml" ignore_missing_imports = true [[tool.mypy.overrides]] module = "fastmcp" ignore_missing_imports = true [[tool.mypy.overrides]] module = "calibre_ai_auditor.mcp_server" disallow_untyped_decorators = false