[build-system] requires = ["maturin>=1.10.0,<2.0"] build-backend = "maturin" [project] name = "cocoindex" dynamic = ["version"] 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", "msgspec>=0.19.0", ] 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"] qdrant = ["qdrant-client>=1.6.0"] sqlite = ["sqlite-vec>=0.1.6"] surrealdb = ["surrealdb>=1.0.0"] turbopuffer = ["turbopuffer>=0.5.0"] google_drive = [ "google-api-python-client>=2.0.0", "google-auth>=2.0.0", "google-auth-httplib2>=0.2.0", "httplib2>=0.22.0", ] amazon_s3 = ["aiobotocore>=2.0.0"] doris = ["aiohttp>=3.9.0", "pymysql>=1.1.0", "aiomysql>=0.2.0"] falkordb = ["falkordb>=1.1.0"] neo4j = ["neo4j>=5.18.0"] kafka = ["confluent_kafka>=2.6"] oci = ["oci>=2.0"] entity_resolution = ["faiss-cpu>=1.7"] entity_resolution_llm = [ "faiss-cpu>=1.7", "instructor>=1.0", "litellm>=1.81.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", "surrealdb>=1.0.0", "turbopuffer>=0.5.0", "google-api-python-client>=2.0.0", "google-auth>=2.0.0", "google-auth-httplib2>=0.2.0", "httplib2>=0.22.0", "aiobotocore>=2.0.0", "aiohttp>=3.9.0", "pymysql>=1.1.0", "aiomysql>=0.2.0", "falkordb>=1.1.0", "neo4j>=5.18.0", "confluent_kafka>=2.6", "oci>=2.0", "faiss-cpu>=1.7", "instructor>=1.0", ] [dependency-groups] build-test = [ "maturin>=1.10.0,<2.0", "pytest>=9.0.3", "pytest-asyncio", "pytest-timeout", "mypy", "moto[s3]>=5.0.0", "aiomoto[s3]>=0.3.0", "testcontainers[postgres,neo4j]>=4.0.0; sys_platform != 'win32'", ] format = ["ruff"] type-stubs = ["types-psutil", "asyncpg-stubs"] ci-enabled-optional-deps = ["pydantic>=2.11.9", "asyncpg>=0.31.0", "neo4j>=5.18.0"] 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 = [ "msgspec", "msgspec.*", "litellm", "litellm.*", "sentence_transformers", "sentence_transformers.*", "colpali_engine", "colpali_engine.*", "PIL", "PIL.*", "torch", "torch.*", "qdrant_client", "qdrant_client.*", "sqlite_vec", "sqlite_vec.*", "surrealdb", "surrealdb.*", "turbopuffer", "turbopuffer.*", "googleapiclient", "googleapiclient.*", "google.oauth2", "google.oauth2.*", "boto3", "boto3.*", "botocore", "botocore.*", "aiobotocore", "aiobotocore.*", "aiohttp", "aiohttp.*", "aiomysql", "aiomysql.*", "pymysql", "pymysql.*", "falkordb", "falkordb.*", "neo4j", "neo4j.*", "faiss", "faiss.*", "instructor", "instructor.*", "oci", "oci.*", "confluent_kafka", "confluent_kafka.*", "openai", "openai.*", "transformers", "transformers.*", "testcontainers", "testcontainers.*", ] 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"