[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] template_dir = "templates" exclude_commit_patterns = [ "^chore\\(release\\):", "^Merge", "^Bump version", ] [tool.semantic_release.changelog.default_templates] changelog_file = "CHANGELOG.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 = true [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", ]