pyproject.toml
Rama main · réplica de lectura del repositorio original.
[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",
"watchdog>=6.0.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 :: 5 - Production/Stable",
"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"]
# Both are written by the release workflow, not kept in git. The client file
# is git-ignored, which maturin honors unless a path is listed here.
include = [
"THIRD_PARTY_NOTICES.html",
"python/cocoindex/connectors/google_drive/_builtin_client.json",
]
# 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,!=1.107.0"]
sentence_transformers = ["sentence-transformers>=3.3.1"]
colpali = ["colpali-engine"]
lancedb = ["lancedb>=0.34.0", "pyarrow>=23.0.0"]
postgres = ["asyncpg>=0.31.0"]
qdrant = ["qdrant-client>=1.6.0"]
bigquery = ["google-cloud-bigquery>=3.0.0", "google-auth>=2.0.0"]
snowflake = ["snowflake-connector-python>=3.0.0"]
sqlite = ["sqlite-vec>=0.1.6"]
surrealdb = ["surrealdb>=1.0.0"]
zvec = ["zvec>=0.5.0"]
turbopuffer = ["turbopuffer>=0.5.0"]
valkey = ["valkey-glide>=2.5.2"]
google_drive = [
"google-api-python-client>=2.0.0",
"google-auth>=2.0.0",
"google-auth-httplib2>=0.2.0",
"httplib2>=0.22.0",
"httpx>=0.27.0",
]
amazon_s3 = ["aiobotocore>=2.0.0"]
azure_blob = ["azure-identity>=1.15.0", "azure-storage-blob>=12.19.0"]
doris = ["aiohttp>=3.9.0", "pymysql>=1.1.0", "aiomysql>=0.2.0"]
discord = ["httpx>=0.27.0"]
falkordb = ["falkordb>=1.6.0"]
neo4j = ["neo4j>=5.18.0"]
kafka = ["confluent_kafka>=2.6"]
iggy = ["apache-iggy>=0.8.0"]
oci = ["oci>=2.0"]
entity_resolution = ["faiss-cpu>=1.7"]
entity_resolution_llm = [
"faiss-cpu>=1.7",
"instructor>=1.0",
"litellm>=1.81.0,!=1.107.0",
]
all = [
"litellm>=1.81.0,!=1.107.0",
"sentence-transformers>=3.3.1",
"colpali-engine",
"lancedb>=0.34.0",
"pyarrow>=23.0.0",
"asyncpg>=0.31.0",
"pgvector>=0.4.2",
"qdrant-client>=1.6.0",
"google-cloud-bigquery>=3.0.0",
"snowflake-connector-python>=3.0.0",
"sqlite-vec>=0.1.6",
"surrealdb>=1.0.0",
"turbopuffer>=0.5.0",
"valkey-glide>=2.5.2",
"google-api-python-client>=2.0.0",
"google-auth>=2.0.0",
"google-auth-httplib2>=0.2.0",
"httplib2>=0.22.0",
"httpx>=0.27.0",
"aiobotocore>=2.0.0",
"azure-identity>=1.15.0",
"azure-storage-blob>=12.19.0",
"aiohttp>=3.9.0",
"pymysql>=1.1.0",
"aiomysql>=0.2.0",
"falkordb>=1.6.0",
"neo4j>=5.18.0",
"confluent_kafka>=2.6",
"apache-iggy>=0.8.0",
"oci>=2.0",
"faiss-cpu>=1.7",
"instructor>=1.0",
"zvec>=0.5.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'",
]
type-stubs = ["types-psutil", "asyncpg-stubs"]
ci-enabled-optional-deps = [
"pydantic>=2.11.9",
"asyncpg>=0.31.0",
"neo4j>=5.18.0",
"pymysql>=1.1.0",
"aiohttp>=3.9.0",
"valkey-glide>=2.5.2; sys_platform != 'win32'",
# The Google Drive connector's tests, including the OAuth sign-in, run offline.
"google-api-python-client>=2.0.0",
"google-auth>=2.0.0",
"google-auth-httplib2>=0.2.0",
"httplib2>=0.22.0",
"httpx>=0.27.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", "benchmarks"]
# 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.*",
"google.cloud",
"google.cloud.*",
"snowflake",
"snowflake.*",
"sqlite_vec",
"sqlite_vec.*",
"surrealdb",
"surrealdb.*",
"turbopuffer",
"turbopuffer.*",
"glide",
"glide.*",
"googleapiclient",
"googleapiclient.*",
"google.oauth2",
"google.oauth2.*",
"google.auth",
"google.auth.*",
"boto3",
"boto3.*",
"botocore",
"botocore.*",
"aiobotocore",
"aiobotocore.*",
"azure",
"azure.*",
"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.*",
"zvec",
"zvec.*",
]
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = ["examples.*", "benchmarks.*"]
# 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"