ffa0e1eb7b
- Rewrite tests/test_celery_worker.py to mock check_credentials.apply_async at import time, enabling all 35 statements to be covered without Redis - Add tests for conditional beat schedule entries (IMAP, Uptime Kuma) - Delete app/utils/config_validator.py — dead code shadowed by the config_validator/ package directory (Python gives packages precedence) - Remove both files from coverage omit in pyproject.toml - celery_worker.py now at 100% coverage (was 0%) Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
228 lines
6.9 KiB
TOML
228 lines
6.9 KiB
TOML
[build-system]
|
|
requires = ["setuptools>=45", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "docuelevate"
|
|
dynamic = ["version"]
|
|
description = "Intelligent document processing system with AI-powered metadata extraction"
|
|
readme = "README.md"
|
|
requires-python = ">=3.11"
|
|
license = {text = "Apache-2.0"}
|
|
authors = [
|
|
{name = "Christian Louis", email = "christianlouis@users.noreply.github.com"}
|
|
]
|
|
keywords = ["document", "processing", "ocr", "ai", "metadata", "extraction"]
|
|
classifiers = [
|
|
"Development Status :: 4 - Beta",
|
|
"Intended Audience :: Developers",
|
|
"License :: OSI Approved :: Apache Software License",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.11",
|
|
"Programming Language :: Python :: 3.12",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://github.com/christianlouis/DocuElevate"
|
|
Documentation = "https://github.com/christianlouis/DocuElevate/tree/main/docs"
|
|
Repository = "https://github.com/christianlouis/DocuElevate"
|
|
Issues = "https://github.com/christianlouis/DocuElevate/issues"
|
|
Changelog = "https://github.com/christianlouis/DocuElevate/blob/main/CHANGELOG.md"
|
|
|
|
[tool.setuptools.dynamic]
|
|
version = {file = "VERSION"}
|
|
|
|
[tool.semantic_release]
|
|
version_toml = []
|
|
version_source = "tag"
|
|
commit_version_number = true
|
|
tag_format = "v{version}"
|
|
major_on_zero = false
|
|
allow_zero_version = true
|
|
build_command = """
|
|
chmod +x scripts/generate_build_metadata.sh
|
|
./scripts/generate_build_metadata.sh
|
|
"""
|
|
|
|
[tool.semantic_release.branches.main]
|
|
match = "main"
|
|
prerelease = false
|
|
|
|
[tool.semantic_release.changelog]
|
|
mode = "update"
|
|
exclude_commit_patterns = [
|
|
"^chore\\(release\\):",
|
|
"^Merge",
|
|
"^Bump version",
|
|
]
|
|
|
|
[tool.semantic_release.changelog.default_templates]
|
|
changelog_file = "CHANGELOG.md"
|
|
output_format = "md"
|
|
|
|
[tool.semantic_release.changelog.environment]
|
|
block_start_string = "{%"
|
|
block_end_string = "%}"
|
|
variable_start_string = "{{"
|
|
variable_end_string = "}}"
|
|
comment_start_string = "{#"
|
|
comment_end_string = "#}"
|
|
trim_blocks = false
|
|
lstrip_blocks = false
|
|
newline_sequence = "\n"
|
|
keep_trailing_newline = false
|
|
extensions = []
|
|
autoescape = false
|
|
|
|
[tool.semantic_release.commit_parser_options]
|
|
allowed_tags = [
|
|
"feat",
|
|
"fix",
|
|
"docs",
|
|
"style",
|
|
"refactor",
|
|
"perf",
|
|
"test",
|
|
"build",
|
|
"ci",
|
|
"chore",
|
|
]
|
|
minor_tags = ["feat"]
|
|
patch_tags = ["fix", "perf"]
|
|
default_bump_level = 0
|
|
|
|
[tool.semantic_release.remote]
|
|
name = "origin"
|
|
type = "github"
|
|
ignore_token_for_push = false
|
|
|
|
[tool.semantic_release.remote.token]
|
|
env = "GH_TOKEN"
|
|
|
|
[tool.semantic_release.publish]
|
|
dist_glob_patterns = []
|
|
upload_to_vcs_release = true
|
|
upload_to_pypi = false
|
|
upload_to_repository = false
|
|
|
|
# Ruff configuration
|
|
[tool.ruff]
|
|
line-length = 120
|
|
target-version = "py311"
|
|
|
|
[tool.ruff.lint]
|
|
# Enable Pyflakes (`F`), pycodestyle (`E`, `W`), isort (`I`), bandit (`S`), flake8-bugbear (`B`), and pylint (`PL`)
|
|
select = ["E", "F", "W", "I", "S", "B", "PL"]
|
|
ignore = [
|
|
"E501", # Line too long (handled by formatter)
|
|
"S108", # Hardcoded temp file (common pattern)
|
|
"S105", # Hardcoded password string (false positives with 'password' variable names)
|
|
"S106", # Hardcoded password func arg (false positives)
|
|
"PLC0415", # Import outside top-level (common in FastAPI/Celery)
|
|
"PLR0913", # Too many arguments
|
|
"PLR0912", # Too many branches
|
|
"PLR0915", # Too many statements
|
|
"PLR0911", # Too many return statements
|
|
"PLR2004", # Magic value comparison
|
|
"PLW0603", # Global statement
|
|
"B008", # Function call in default argument (FastAPI Depends pattern)
|
|
"B904", # Raise without from (overly strict for error handlers)
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"tests/*" = ["S101", "S110", "B017", "F841", "B007", "E402"] # Allow assert, try-except-pass, assert-raises-exception, unused vars, unused loop vars, module imports not at top in tests
|
|
|
|
# pytest configuration
|
|
[tool.pytest.ini_options]
|
|
minversion = "7.0"
|
|
testpaths = ["tests"]
|
|
python_files = ["test_*.py"]
|
|
python_classes = ["Test*"]
|
|
python_functions = ["test_*"]
|
|
addopts = [
|
|
"-v",
|
|
"--strict-markers",
|
|
"--strict-config",
|
|
"--cov=app",
|
|
"--cov-report=term-missing",
|
|
"--cov-report=html",
|
|
"--cov-branch",
|
|
]
|
|
markers = [
|
|
"unit: Unit tests for individual functions/methods",
|
|
"integration: Integration tests for API endpoints and workflows",
|
|
"slow: Tests that take significant time to run",
|
|
"security: Security-related tests",
|
|
"requires_external: Tests requiring external services (OpenAI, Azure, etc.)",
|
|
"requires_db: Tests requiring database",
|
|
"requires_redis: Tests requiring Redis",
|
|
"e2e: End-to-end tests with full infrastructure (requires Docker)",
|
|
"requires_docker: Tests requiring Docker containers (testcontainers)",
|
|
]
|
|
|
|
# mypy configuration
|
|
[tool.mypy]
|
|
python_version = "3.11"
|
|
warn_return_any = true
|
|
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
|
|
warn_unreachable = false
|
|
strict_equality = true
|
|
ignore_missing_imports = true
|
|
# Disable error codes that produce widespread false positives with SQLAlchemy ORM,
|
|
# Pydantic, and other dynamic libraries used throughout the codebase.
|
|
# These would require major refactoring to resolve and are tracked for future work.
|
|
disable_error_code = [
|
|
"assignment", # SQLAlchemy Column[T] vs T assignments throughout ORM layer
|
|
"arg-type", # SQLAlchemy Column types passed where plain types expected
|
|
"union-attr", # Optional attribute access on ORM/Pydantic fields
|
|
"call-overload", # SQLAlchemy query builder overload resolution
|
|
"return-value", # Dynamic return types from ORM queries
|
|
"attr-defined", # Dynamic attributes on ORM models and API clients
|
|
"no-any-return", # Functions wrapping dynamic library calls
|
|
"var-annotated", # Complex inferred types from ORM queries
|
|
"index", # Indexing on dynamic ORM result types
|
|
"operator", # Operator usage on Optional/Column types
|
|
"dict-item", # Dict literal type inference with ORM fields
|
|
"type-var", # Type variable constraints with ORM generics
|
|
"method-assign", # Dynamic method assignment patterns
|
|
"call-arg", # Dynamic call signatures in framework code
|
|
]
|
|
|
|
# Stricter type-checking for utility modules
|
|
[[tool.mypy.overrides]]
|
|
module = "app.utils.*"
|
|
disallow_untyped_defs = true
|
|
disallow_incomplete_defs = true
|
|
|
|
# Coverage configuration
|
|
[tool.coverage.run]
|
|
source = ["app"]
|
|
omit = [
|
|
"*/tests/*",
|
|
"*/migrations/*",
|
|
"*/__pycache__/*",
|
|
"*/venv/*",
|
|
"*/env/*",
|
|
]
|
|
|
|
[tool.coverage.report]
|
|
precision = 2
|
|
show_missing = true
|
|
skip_covered = false
|
|
exclude_lines = [
|
|
"pragma: no cover",
|
|
"def __repr__",
|
|
"raise AssertionError",
|
|
"raise NotImplementedError",
|
|
"if __name__ == .__main__.:",
|
|
"if TYPE_CHECKING:",
|
|
"@abstractmethod",
|
|
]
|