[build-system]
requires = ["maturin>=1.10.0,<2.0"]
build-backend = "maturin"

[project]
name = "cocoindex"
version = "1.0.0a16"
description = "With CocoIndex, users declare the transformation, CocoIndex creates & maintains an index, and keeps the derived index up to date based on source update, with minimal computation and changes."
authors = [{ name = "CocoIndex", email = "cocoindex.io@gmail.com" }]
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "typing-extensions>=4.12",
    "click>=8.1.8",
    "rich>=14.0.0",
    "python-dotenv>=1.1.0",
    "watchfiles>=1.1.0",
    "numpy>=1.23.2",
    "psutil>=7.2.1",
]
license = "Apache-2.0"
license-files = ["THIRD_PARTY_NOTICES.html"]
urls = { Homepage = "https://cocoindex.io/" }
classifiers = [
    "Development Status :: 3 - Alpha",
    "License :: OSI Approved :: Apache Software License",
    "Operating System :: OS Independent",
    "Programming Language :: Rust",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Programming Language :: Python :: Free Threading :: 2 - Beta",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Topic :: Text Processing :: Indexing",
    "Intended Audience :: Developers",
    "Natural Language :: English",
    "Typing :: Typed",
]
keywords = [
    "indexing",
    "real-time",
    "incremental",
    "pipeline",
    "search",
    "ai",
    "etl",
    "rag",
    "dataflow",
    "context-engineering",
]

[project.scripts]
cocoindex = "cocoindex.cli:cli"

[tool.maturin]
bindings = "pyo3"
python-source = "python"
module-name = "cocoindex._internal.core"
features = ["pyo3/extension-module"]
include = ["THIRD_PARTY_NOTICES.html"]
# Point to the crate within the workspace
manifest-path = "rust/py/Cargo.toml"

profile = "release"      # wheel / normal builds
editable-profile = "dev" # local editable builds

[project.optional-dependencies]
litellm = ["litellm>=1.81.0"]
sentence_transformers = ["sentence-transformers>=3.3.1"]
colpali = ["colpali-engine"]
lancedb = ["lancedb>=0.25.0", "pyarrow>=19.0.0"]
postgres = ["asyncpg>=0.31.0", "pgvector>=0.4.2"]
qdrant = ["qdrant-client>=1.6.0"]
sqlite = ["sqlite-vec>=0.1.6"]
google_drive = ["google-api-python-client>=2.0.0", "google-auth>=2.0.0"]

all = [
    "litellm>=1.81.0",
    "sentence-transformers>=3.3.1",
    "colpali-engine",
    "lancedb>=0.25.0",
    "pyarrow>=19.0.0",
    "asyncpg>=0.31.0",
    "pgvector>=0.4.2",
    "qdrant-client>=1.6.0",
    "sqlite-vec>=0.1.6",
    "google-api-python-client>=2.0.0",
    "google-auth>=2.0.0",
]

[dependency-groups]
build-test = [
    "maturin>=1.10.0,<2.0",
    "pytest",
    "pytest-asyncio",
    "pytest-timeout",
    "mypy",
]
format = ["ruff"]
type-stubs = ["types-psutil", "asyncpg-stubs"]
ci-enabled-optional-deps = ["pydantic>=2.11.9"]
examples = ["sentence-transformers>=3.0.0", "numpy"]

ci = [
    { include-group = "build-test" },
    { include-group = "type-stubs" },
    { include-group = "ci-enabled-optional-deps" },
]

dev-local = ["prek"]
dev = [{ include-group = "ci" }, { include-group = "dev-local" }]

[tool.uv]
package = false

[tool.mypy]
python_version = "3.11"
strict = true

files = ["python", "examples"]

# This allows 'import cocoindex' to work inside examples
mypy_path = "python"

# Prevent "Duplicate module named 'main'" errors
# This forces mypy to calculate module names based on file path
# relative to the root, rather than just the filename.
explicit_package_bases = true

# Enable namespace packages
# This allows 'examples/example1' to be seen as a module path
namespace_packages = true

exclude = [".venv", "site-packages", "baml_client"]
disable_error_code = ["unused-ignore"]

[[tool.mypy.overrides]]
# Ignore missing imports for optional dependencies from cocoindex library
# Use wildcards to cover all submodules (e.g., google.oauth2.service_account)
module = [
    "litellm",
    "litellm.*",
    "sentence_transformers",
    "sentence_transformers.*",
    "colpali_engine",
    "colpali_engine.*",
    "PIL",
    "PIL.*",
    "torch",
    "torch.*",
    "qdrant_client",
    "qdrant_client.*",
    "sqlite_vec",
    "sqlite_vec.*",
    "googleapiclient",
    "googleapiclient.*",
    "google.oauth2",
    "google.oauth2.*",
]
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = ["examples.*"]

# Silence missing import errors for optional dependencies
disable_error_code = ["import-not-found", "import-untyped", "untyped-decorator"]

# Prevent the "Any" contagion from triggering strict errors
# (These flags are normally True in strict mode)

warn_return_any = false
disallow_any_generics = false
disallow_subclassing_any = false
disallow_untyped_calls = false
disallow_any_decorated = false

[tool.pytest.ini_options]
pythonpath = ["python"]
timeout = 30
log_cli = true
log_cli_level = "INFO"
log_format = "%(asctime)s %(levelname)s %(message)s"
log_date_format = "%Y-%m-%d %H:%M:%S"
