cocoindex 0.1.73__tar.gz → 0.1.75__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/workflows/_doc_release.yml +0 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/workflows/_test.yml +1 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/workflows/docs.yml +0 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/Cargo.lock +1 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/Cargo.toml +1 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/PKG-INFO +5 -3
- {cocoindex-0.1.73 → cocoindex-0.1.75}/README.md +1 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/data_types.mdx +1 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/flow_def.mdx +4 -4
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/flow_methods.mdx +2 -2
- cocoindex-0.1.73/docs/docs/core/custom_function.mdx → cocoindex-0.1.75/docs/docs/custom_ops/custom_functions.mdx +1 -1
- cocoindex-0.1.75/docs/docs/custom_ops/custom_targets.mdx +178 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docusaurus.config.ts +4 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/sidebars.ts +9 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/src/css/custom.css +17 -5
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/yarn.lock +190 -190
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/amazon_s3_embedding/pyproject.toml +5 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/azure_blob_embedding/pyproject.toml +5 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/code_embedding/pyproject.toml +6 -1
- cocoindex-0.1.75/examples/custom_output_files/.gitignore +1 -0
- cocoindex-0.1.75/examples/custom_output_files/README.md +53 -0
- cocoindex-0.1.75/examples/custom_output_files/main.py +123 -0
- cocoindex-0.1.75/examples/custom_output_files/pyproject.toml +9 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/gdrive_text_embedding/pyproject.toml +5 -1
- cocoindex-0.1.75/examples/live_updates/data/bizarre_animals.md +21 -0
- cocoindex-0.1.75/examples/live_updates/data/chunk_norris.md +19 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/pdf_embedding/main.py +0 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/pdf_embedding/pyproject.toml +2 -0
- cocoindex-0.1.75/examples/text_embedding_qdrant/.env +2 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/pyproject.toml +6 -2
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/__init__.py +5 -3
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/convert.py +188 -167
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/flow.py +29 -12
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/op.py +264 -6
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/tests/test_convert.py +184 -151
- cocoindex-0.1.75/python/cocoindex/tests/test_transform_flow.py +103 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/tests/test_typing.py +5 -12
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/typing.py +8 -8
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/spec.rs +0 -10
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/builder/analyzed_flow.rs +4 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/builder/analyzer.rs +11 -19
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/builder/flow_builder.rs +61 -54
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/lib_context.rs +1 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/factory_bases.rs +6 -6
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/interface.rs +2 -2
- cocoindex-0.1.75/src/ops/py_factory.rs +501 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/kuzu.rs +3 -3
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/neo4j.rs +8 -6
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/postgres.rs +3 -3
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/qdrant.rs +4 -4
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/py/convert.rs +1 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/py/mod.rs +10 -1
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/setup/driver.rs +22 -15
- cocoindex-0.1.73/src/ops/py_factory.rs +0 -225
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.cargo/config.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.env.lib_debug +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/ISSUE_TEMPLATE//360/237/220/233-bug-report.md" +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/ISSUE_TEMPLATE//360/237/222/241-feature-request.md" +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/scripts/update_version.sh +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/workflows/CI.yml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/workflows/format.yml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.github/workflows/release.yml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/.pre-commit-config.yaml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/CODE_OF_CONDUCT.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/CONTRIBUTING.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/LICENSE +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/dev/neo4j.yaml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/dev/postgres.yaml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/about/community.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/about/contributing.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/ai/llm.mdx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/basics.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/cli.mdx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/data_example.svg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/flow_example.svg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/core/settings.mdx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/getting_started/installation.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/getting_started/markdown_files.zip +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/getting_started/overview.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/getting_started/quickstart.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/ops/functions.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/ops/sources.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/ops/targets.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/query.mdx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/docs/tutorials/live_updates.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/package.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/src/components/HomepageFeatures/index.tsx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/src/components/HomepageFeatures/styles.module.css +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/src/theme/Root.js +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/static/.nojekyll +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/static/img/docusaurus.png +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/static/img/favicon.ico +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/static/img/icon.svg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/static/img/incremental-etl.gif +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/static/robots.txt +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/docs/tsconfig.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/amazon_s3_embedding/.env.example +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/amazon_s3_embedding/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/amazon_s3_embedding/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/amazon_s3_embedding/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/azure_blob_embedding/.env.example +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/azure_blob_embedding/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/azure_blob_embedding/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/azure_blob_embedding/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/code_embedding/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/code_embedding/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/code_embedding/main.py +0 -0
- {cocoindex-0.1.73/examples/docs_to_knowledge_graph → cocoindex-0.1.75/examples/custom_output_files}/.env +0 -0
- {cocoindex-0.1.73/examples/live_updates → cocoindex-0.1.75/examples/custom_output_files}/data/bizarre_animals.md +0 -0
- {cocoindex-0.1.73/examples/live_updates → cocoindex-0.1.75/examples/custom_output_files}/data/chunk_norris.md +0 -0
- {cocoindex-0.1.73/examples/face_recognition → cocoindex-0.1.75/examples/docs_to_knowledge_graph}/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/docs_to_knowledge_graph/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/docs_to_knowledge_graph/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/docs_to_knowledge_graph/pyproject.toml +0 -0
- {cocoindex-0.1.73/examples/manuals_llm_extraction → cocoindex-0.1.75/examples/face_recognition}/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/images/Carter_welcomes_Reagan.jpg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/images/Solvay_conference_1927.jpg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/images/Steve_Jobs_and_Bill_Gates_(522695099).jpg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/images/einplanck3.jpg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/face_recognition/pyproject.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/.dockerignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/compose.yaml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/dockerfile +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/files/1810.04805v2.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/fastapi_server_docker/requirements.txt +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/gdrive_text_embedding/.env.example +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/gdrive_text_embedding/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/gdrive_text_embedding/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/gdrive_text_embedding/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/index.html +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/package-lock.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/package.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/src/App.jsx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/src/main.jsx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/src/style.css +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/frontend/vite.config.js +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/img/cat1.jpeg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/img/dog1.jpeg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/img/elephant1.jpg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/img/giraffe.jpg +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/image_search/pyproject.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/live_updates/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/live_updates/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/live_updates/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/live_updates/pyproject.toml +0 -0
- {cocoindex-0.1.73/examples/pdf_embedding → cocoindex-0.1.75/examples/manuals_llm_extraction}/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/manuals/array.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/manuals/base64.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/manuals/copy.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/manuals/glob.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/manuals_llm_extraction/pyproject.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/.env.example +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/.gitignore +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/papers/1706.03762v7.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/papers/1810.04805v2.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/papers/2502.06786v3.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/papers/2502.20346v1.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/paper_metadata/pyproject.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/.env.example +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/data/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_Form_David_Artificial.docx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_Form_Emily_Artificial.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_Form_Joe_Artificial.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_From_Jane_Artificial.docx +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/patient_intake_extraction/pyproject.toml +0 -0
- {cocoindex-0.1.73/examples/product_recommendation → cocoindex-0.1.75/examples/pdf_embedding}/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/pdf_embedding/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/pdf_embedding/pdf_files/1706.03762v7.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/pdf_embedding/pdf_files/1810.04805v2.pdf +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/pdf_embedding/pdf_files/rfc8259.pdf +0 -0
- {cocoindex-0.1.73/examples/text_embedding → cocoindex-0.1.75/examples/product_recommendation}/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/img/cocoinsight.png +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/img/neo4j.png +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p1.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p2.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p3.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p4.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p5.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p6.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p7.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p8.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/products/p9.json +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/product_recommendation/pyproject.toml +0 -0
- {cocoindex-0.1.73/examples/text_embedding_qdrant → cocoindex-0.1.75/examples/text_embedding}/.env +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/Text_Embedding.ipynb +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/markdown_files/1706.03762v7.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/markdown_files/1810.04805v2.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/markdown_files/rfc8259.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding/pyproject.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding_qdrant/README.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding_qdrant/main.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding_qdrant/markdown_files/rfc8259.md +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/examples/text_embedding_qdrant/pyproject.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/auth_registry.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/cli.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/functions.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/index.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/lib.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/llm.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/py.typed +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/runtime.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/setting.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/setup.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/sources.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/targets.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/tests/__init__.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/tests/test_optional_database.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/tests/test_validation.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/utils.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/python/cocoindex/validation.py +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/ruff.toml +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/duration.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/field_attrs.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/json_schema.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/schema.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/base/value.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/builder/exec_ctx.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/builder/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/builder/plan.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/db_tracking.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/db_tracking_setup.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/dumper.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/evaluator.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/indexing_status.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/live_updater.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/memoization.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/row_indexer.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/source_indexer.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/execution/stats.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/lib.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/anthropic.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/gemini.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/litellm.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/ollama.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/openai.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/openrouter.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/vllm.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/llm/voyage.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/functions/embed_text.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/functions/extract_by_llm.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/functions/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/functions/parse_json.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/functions/split_recursively.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/functions/test_utils.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/registration.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/registry.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/sdk.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/sources/amazon_s3.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/sources/azure_blob.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/sources/google_drive.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/sources/local_file.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/sources/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/shared/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/shared/property_graph.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/ops/targets/shared/table_columns.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/prelude.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/server.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/service/error.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/service/flows.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/service/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/settings.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/setup/auth_registry.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/setup/components.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/setup/db_metadata.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/setup/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/setup/states.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/concur_control.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/db.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/fingerprint.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/immutable.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/mod.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/retryable.rs +0 -0
- {cocoindex-0.1.73 → cocoindex-0.1.75}/src/utils/yaml_ser.rs +0 -0
@@ -1,24 +1,25 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cocoindex
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.75
|
4
4
|
Requires-Dist: click>=8.1.8
|
5
5
|
Requires-Dist: rich>=14.0.0
|
6
6
|
Requires-Dist: python-dotenv>=1.1.0
|
7
7
|
Requires-Dist: watchfiles>=1.1.0
|
8
8
|
Requires-Dist: numpy>=1.23.2
|
9
9
|
Requires-Dist: pytest ; extra == 'dev'
|
10
|
+
Requires-Dist: pytest-asyncio ; extra == 'dev'
|
10
11
|
Requires-Dist: ruff ; extra == 'dev'
|
11
12
|
Requires-Dist: mypy ; extra == 'dev'
|
12
13
|
Requires-Dist: pre-commit ; extra == 'dev'
|
13
14
|
Requires-Dist: sentence-transformers>=3.3.1 ; extra == 'embeddings'
|
14
|
-
Requires-Dist:
|
15
|
+
Requires-Dist: sentence-transformers>=3.3.1 ; extra == 'all'
|
15
16
|
Provides-Extra: dev
|
16
17
|
Provides-Extra: embeddings
|
17
18
|
Provides-Extra: all
|
18
19
|
License-File: LICENSE
|
19
20
|
Summary: 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.
|
20
21
|
Author-email: CocoIndex <cocoindex.io@gmail.com>
|
21
|
-
License: Apache-2.0
|
22
|
+
License-Expression: Apache-2.0
|
22
23
|
Requires-Python: >=3.11
|
23
24
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
24
25
|
Project-URL: Homepage, https://cocoindex.io/
|
@@ -210,6 +211,7 @@ It defines an index flow like this:
|
|
210
211
|
| [Image Search with Vision API](examples/image_search) | Generates detailed captions for images using a vision model, embeds them, enables live-updating semantic search via FastAPI and served on a React frontend|
|
211
212
|
| [Face Recognition](examples/face_recognition) | Recognize faces in images and build embedding index |
|
212
213
|
| [Paper Metadata](examples/paper_metadata) | Index papers in PDF files, and build metadata tables for each paper |
|
214
|
+
| [Custom Output Files](examples/custom_output_files) | Convert markdown files to HTML files and save them to a local directory, using *CocoIndex Custom Targets* |
|
213
215
|
|
214
216
|
More coming and stay tuned 👀!
|
215
217
|
|
@@ -185,6 +185,7 @@ It defines an index flow like this:
|
|
185
185
|
| [Image Search with Vision API](examples/image_search) | Generates detailed captions for images using a vision model, embeds them, enables live-updating semantic search via FastAPI and served on a React frontend|
|
186
186
|
| [Face Recognition](examples/face_recognition) | Recognize faces in images and build embedding index |
|
187
187
|
| [Paper Metadata](examples/paper_metadata) | Index papers in PDF files, and build metadata tables for each paper |
|
188
|
+
| [Custom Output Files](examples/custom_output_files) | Convert markdown files to HTML files and save them to a local directory, using *CocoIndex Custom Targets* |
|
188
189
|
|
189
190
|
More coming and stay tuned 👀!
|
190
191
|
|
@@ -19,7 +19,7 @@ You don't need to spell out any data type explicitly when you define the flow.
|
|
19
19
|
All you need to do is to make sure the data passed to functions and targets are compatible with them.
|
20
20
|
|
21
21
|
Each type in CocoIndex type system is mapped to one or multiple types in Python.
|
22
|
-
When you define a [custom function](/docs/
|
22
|
+
When you define a [custom function](/docs/custom_ops/custom_functions), you need to annotate the data types of arguments and return values.
|
23
23
|
|
24
24
|
* When you pass a Python value to the engine (e.g. return values of a custom function), a specific type annotation is required.
|
25
25
|
The type annotation needs to be specific in describing the target data type, as it provides the ground truth of the data type in the flow.
|
@@ -33,23 +33,23 @@ It takes two arguments:
|
|
33
33
|
* `flow_builder`: a `FlowBuilder` object to help build the flow.
|
34
34
|
* `data_scope`: a `DataScope` object, representing the top-level data scope. Any data created by the flow should be added to it.
|
35
35
|
|
36
|
-
Alternatively, for more flexibility (e.g. you want to do this conditionally or generate dynamic name), you can explicitly call the `cocoindex.
|
36
|
+
Alternatively, for more flexibility (e.g. you want to do this conditionally or generate dynamic name), you can explicitly call the `cocoindex.open_flow()` method:
|
37
37
|
|
38
38
|
```python
|
39
39
|
def demo_flow_def(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope):
|
40
40
|
...
|
41
41
|
|
42
42
|
# Add the flow definition to the flow registry.
|
43
|
-
demo_flow = cocoindex.
|
43
|
+
demo_flow = cocoindex.open_flow("DemoFlow", demo_flow_def)
|
44
44
|
```
|
45
45
|
|
46
46
|
In both cases, `demo_flow` will be an object with `cocoindex.Flow` class type.
|
47
47
|
See [Flow Running](/docs/core/flow_methods) for more details on it.
|
48
48
|
|
49
|
-
Sometimes you no longer want to keep states of the flow in memory. We provide a `
|
49
|
+
Sometimes you no longer want to keep states of the flow in memory. We provide a `close()` method for this purpose:
|
50
50
|
|
51
51
|
```python
|
52
|
-
|
52
|
+
demo_flow.close()
|
53
53
|
```
|
54
54
|
|
55
55
|
After it's called, `demo_flow` becomes an invalid object, and you should not call any methods of it.
|
@@ -39,7 +39,7 @@ It creates a `demo_flow` object in `cocoindex.Flow` type.
|
|
39
39
|
For a flow, its persistent backends need to be ready before it can run, including:
|
40
40
|
|
41
41
|
* [Internal storage](/docs/core/basics#internal-storage) for CocoIndex.
|
42
|
-
* Backend
|
42
|
+
* Backend resources for targets exported by the flow, e.g. a table (in relational databases), a collection (in some vector databases), etc.
|
43
43
|
|
44
44
|
The desired state of the backends for a flow is derived based on the flow definition itself.
|
45
45
|
CocoIndex supports two types of actions to manage the persistent backends automatically:
|
@@ -104,7 +104,7 @@ cocoindex.drop_all_flows(report_to_stdout=True)
|
|
104
104
|
|
105
105
|
After dropping the flow, the in-memory `cocoindex.Flow` instance is still valid, and you can call setup methods on it again.
|
106
106
|
|
107
|
-
If you want to remove the flow from the current process, you can call `
|
107
|
+
If you want to remove the flow from the current process, you can call `demo_flow.close()` to do so (see [related doc](/docs/core/flow_def#entry-point)).
|
108
108
|
|
109
109
|
:::
|
110
110
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
---
|
2
2
|
title: Custom Functions
|
3
|
-
description: Build
|
3
|
+
description: Build powerful custom functions in CocoIndex for data transformation and processing. Create standalone functions or advanced function specs with executors, including caching, GPU support, and configurable behavior for scalable data operations.
|
4
4
|
---
|
5
5
|
|
6
6
|
import Tabs from '@theme/Tabs';
|
@@ -0,0 +1,178 @@
|
|
1
|
+
---
|
2
|
+
title: Custom Targets
|
3
|
+
description: Learn how to create custom targets in CocoIndex to export data to any destination including databases, cloud storage, file systems, and APIs. Build target specs and connectors with setup and data methods for flexible data export operations.
|
4
|
+
toc_max_heading_level: 4
|
5
|
+
---
|
6
|
+
|
7
|
+
import Tabs from '@theme/Tabs';
|
8
|
+
import TabItem from '@theme/TabItem';
|
9
|
+
|
10
|
+
A custom target allows you to export data to any destination you want, such as databases, cloud storage, file systems, APIs, or other external systems.
|
11
|
+
|
12
|
+
Custom targets are defined by two components:
|
13
|
+
|
14
|
+
* A **target spec** that configures the behavior and connection parameters for the target.
|
15
|
+
* A **target connector** that handles the actual data export operations.
|
16
|
+
|
17
|
+
## Target Spec
|
18
|
+
|
19
|
+
The target spec defines the configuration parameters for your custom target. When you use this target in a flow (typically by calling [`export()`](/docs/core/flow_def#export)), you instantiate this target spec with specific parameter values.
|
20
|
+
|
21
|
+
<Tabs>
|
22
|
+
<TabItem value="python" label="Python" default>
|
23
|
+
|
24
|
+
A target spec is defined as a class that inherits from `cocoindex.op.TargetSpec`.
|
25
|
+
|
26
|
+
```python
|
27
|
+
class CustomTarget(cocoindex.op.TargetSpec):
|
28
|
+
"""
|
29
|
+
Documentation for the target.
|
30
|
+
"""
|
31
|
+
param1: str
|
32
|
+
param2: int | None = None
|
33
|
+
...
|
34
|
+
```
|
35
|
+
|
36
|
+
Notes:
|
37
|
+
* All fields of the spec must have a type serializable / deserializable by the `json` module.
|
38
|
+
* All subclasses of `TargetSpec` can be instantiated similar to a dataclass, i.e. `ClassName(param1=value1, param2=value2, ...)`.
|
39
|
+
|
40
|
+
</TabItem>
|
41
|
+
</Tabs>
|
42
|
+
|
43
|
+
## Target Connector
|
44
|
+
|
45
|
+
A target connector handles the actual data export operations for your custom target. It defines how data should be written to your target destination.
|
46
|
+
|
47
|
+
Target connectors implement two categories of methods: **setup methods** for managing target infrastructure (similar to DDL operations in databases), and **data methods** for handling specific data operations (similar to DML operations).
|
48
|
+
|
49
|
+
<Tabs>
|
50
|
+
<TabItem value="python" label="Python" default>
|
51
|
+
|
52
|
+
A target connector is defined as a class decorated by `@cocoindex.op.target_connector(spec_cls=CustomTarget)`.
|
53
|
+
|
54
|
+
```python
|
55
|
+
@cocoindex.op.target_connector(spec_cls=CustomTarget)
|
56
|
+
class CustomTargetConnector:
|
57
|
+
# Setup methods
|
58
|
+
@staticmethod
|
59
|
+
def get_persistent_key(spec: CustomTarget, target_name: str) -> PersistentKey:
|
60
|
+
"""Required. Return a persistent key that uniquely identifies this target instance."""
|
61
|
+
...
|
62
|
+
|
63
|
+
@staticmethod
|
64
|
+
def apply_setup_change(
|
65
|
+
key: PersistentKey, previous: CustomTarget | None, current: CustomTarget | None
|
66
|
+
) -> None:
|
67
|
+
"""Required. Apply setup changes to the target."""
|
68
|
+
...
|
69
|
+
|
70
|
+
@staticmethod
|
71
|
+
def describe(key: PersistentKey) -> str:
|
72
|
+
"""Optional. Return a human-readable description of the target."""
|
73
|
+
...
|
74
|
+
|
75
|
+
# Data methods
|
76
|
+
@staticmethod
|
77
|
+
def prepare(spec: CustomTarget) -> PreparedCustomTarget:
|
78
|
+
"""Optional. Prepare for execution before applying mutations."""
|
79
|
+
...
|
80
|
+
|
81
|
+
@staticmethod
|
82
|
+
def mutate(
|
83
|
+
*all_mutations: tuple[PreparedCustomTarget, dict[DataKeyType, DataValueType | None]],
|
84
|
+
) -> None:
|
85
|
+
"""Required. Apply data mutations to the target."""
|
86
|
+
...
|
87
|
+
```
|
88
|
+
|
89
|
+
</TabItem>
|
90
|
+
</Tabs>
|
91
|
+
|
92
|
+
The following data types are involved in the method definitions above: `CustomTarget`, `PersistentKey`, `PreparedCustomTarget`, `DataKeyType`, `DataValueType`. They should be replaced with the actual types in your implementation. We will explain each of them below.
|
93
|
+
|
94
|
+
### Setup Methods
|
95
|
+
Setup methods manage the target infrastructure - creating, configuring, and cleaning up target resources.
|
96
|
+
|
97
|
+
#### `get_persistent_key(spec, target_name) -> PersistentKey` (Required)
|
98
|
+
|
99
|
+
This method returns a unique identifier for the target instance. This key is used by CocoIndex to keep track of target state and drive target spec changes.
|
100
|
+
|
101
|
+
The key should be stable across different runs. If a previously existing key no longer exists, CocoIndex will assume the target is gone, and will drop it by calling `apply_setup_change` with `current` set to `None`.
|
102
|
+
|
103
|
+
The return type of this method should be serializable by the `json` module. It will be passed to other setup methods.
|
104
|
+
|
105
|
+
#### `apply_setup_change(key, previous, current) -> None` (Required)
|
106
|
+
|
107
|
+
This method is called when the target configuration changes. It receives:
|
108
|
+
- `key`: The persistent key for this target
|
109
|
+
- `previous`: The previous target spec (or `None` if this is a new target)
|
110
|
+
- `current`: The current target spec (or `None` if the target is being removed)
|
111
|
+
|
112
|
+
This method should be implemented to:
|
113
|
+
- Create resources when a target is first added (`previous` is `None`)
|
114
|
+
- Update configuration when a target spec changes
|
115
|
+
- Clean up resources when a target is removed (`current` is `None`)
|
116
|
+
|
117
|
+
#### `describe(key) -> str` (Optional)
|
118
|
+
|
119
|
+
Returns a human-readable description of the target for logging and debugging purposes.
|
120
|
+
|
121
|
+
|
122
|
+
### Data Methods
|
123
|
+
|
124
|
+
Data methods handle the actual data operations - inserting, updating, and deleting records in the target.
|
125
|
+
|
126
|
+
#### `mutate(*all_mutations) -> None` (Required)
|
127
|
+
|
128
|
+
This method applies data changes to the target. It receives multiple mutation batches, where each batch is a tuple containing:
|
129
|
+
|
130
|
+
- The target spec (`PreparedCustomTarget`, or `CustomTarget` if `prepare` is not provided).
|
131
|
+
|
132
|
+
- A dictionary of mutations (`dict[DataKeyType, DataValueType | None]`).
|
133
|
+
Each entry represents a mutation for a single row. When the value is `None`, it represents a deletion for the row, otherwise it's an upsert.
|
134
|
+
|
135
|
+
It represented in the same way as [*KTable*](/docs/core/data_types#ktable), except the value can be `None`.
|
136
|
+
In particular:
|
137
|
+
|
138
|
+
- Since both `DataKeyType` and `DataValueType` can have multiple columns, they're [*Struct*](/docs/core/data_types#struct-types).
|
139
|
+
- `DataKeyType` can be represented by a frozen dataclass (i.e. `@dataclass(frozen=True)`) or a `NamedTuple`, as it needs to be immutable.
|
140
|
+
- `DataValueType` can be represented by a `dataclass`, a `NamedTuple` or a `dict[str, Any]`.
|
141
|
+
|
142
|
+
- For simplicity, when there're a single primary key column with basic type, we allow using type of this column (e.g. `str`, `int` etc.) as the key type, and a wrapper *Struct* type can be omitted.
|
143
|
+
You can still use a `@dataclass(frozen=True)` or a `NamedTuple` to represent the key for this case though, if you want to handle both cases consistently.
|
144
|
+
|
145
|
+
#### `prepare(spec) -> PreparedCustomTarget` (Optional)
|
146
|
+
|
147
|
+
Prepares for execution by performing common operations before applying mutations. The returned value will be passed as the first element of tuples in the `mutate` method instead of the original spec.
|
148
|
+
|
149
|
+
```python
|
150
|
+
@staticmethod
|
151
|
+
def prepare(spec: CustomTarget) -> PreparedCustomTarget:
|
152
|
+
"""
|
153
|
+
Prepare for execution. Called once before mutations.
|
154
|
+
"""
|
155
|
+
# Initialize connections, validate configuration, etc.
|
156
|
+
return PreparedCustomTarget(...)
|
157
|
+
```
|
158
|
+
|
159
|
+
If not provided, the original spec will be passed directly to `mutate`.
|
160
|
+
|
161
|
+
## Best Practices
|
162
|
+
|
163
|
+
### Idempotency of Methods with Side Effects
|
164
|
+
|
165
|
+
`apply_setup_change()` and `mutate()` are the two methods that are expected to produce side effects.
|
166
|
+
We expect them to be idempotent, i.e. when calling them with the same arguments multiple times, the effect should remain the same.
|
167
|
+
|
168
|
+
For example,
|
169
|
+
- For `apply_setup_change()`, if the target is a directory, it should be a no-op if we try to create it (`previous` is `None`) when the directory already exists, and also a no-op if we try to delete it (`current` is `None`) when the directory does not exist.
|
170
|
+
- For `mutate()`, if a mutation is a deletion, it should be a no-op if the row does not exist.
|
171
|
+
|
172
|
+
This is to make sure when the system if left in an intermediate state, e.g. interrupted in the middle between a change is made and CocoIndex notes down the change is completed, the targets can still be gracefully rolled forward to the desired states after the system is resumed.
|
173
|
+
|
174
|
+
## Examples
|
175
|
+
|
176
|
+
The cocoindex repository contains the following examples of custom targets:
|
177
|
+
|
178
|
+
* In the [custom_output_files](https://github.com/cocoindex-io/cocoindex/blob/main/examples/custom_output_files/main.py) example, `LocalFileTarget` exports data to local HTML files.
|
@@ -31,7 +31,6 @@ const sidebars: SidebarsConfig = {
|
|
31
31
|
'core/settings',
|
32
32
|
'core/flow_methods',
|
33
33
|
'core/cli',
|
34
|
-
'core/custom_function',
|
35
34
|
],
|
36
35
|
},
|
37
36
|
{
|
@@ -44,6 +43,15 @@ const sidebars: SidebarsConfig = {
|
|
44
43
|
'ops/targets',
|
45
44
|
],
|
46
45
|
},
|
46
|
+
{
|
47
|
+
type: 'category',
|
48
|
+
label: 'Custom Operations',
|
49
|
+
collapsed: false,
|
50
|
+
items: [
|
51
|
+
'custom_ops/custom_functions',
|
52
|
+
'custom_ops/custom_targets',
|
53
|
+
],
|
54
|
+
},
|
47
55
|
{
|
48
56
|
type: 'category',
|
49
57
|
label: 'AI Support',
|
@@ -61,6 +61,13 @@
|
|
61
61
|
--theme-color-keyline: #374151;
|
62
62
|
}
|
63
63
|
|
64
|
+
|
65
|
+
.table-of-contents {
|
66
|
+
code {
|
67
|
+
border: none;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
64
71
|
.markdown {
|
65
72
|
line-height: 150%;
|
66
73
|
|
@@ -92,13 +99,15 @@
|
|
92
99
|
|
93
100
|
.navbar__title {
|
94
101
|
font-family: 'Questrial', sans-serif;
|
95
|
-
font-size: 1.125rem;
|
102
|
+
font-size: 1.125rem;
|
103
|
+
/* 18px */
|
96
104
|
color: var(--my-color-text-black);
|
97
105
|
}
|
98
106
|
|
99
107
|
.navbar {
|
100
108
|
box-shadow: none;
|
101
|
-
font-size: 0.875rem;
|
109
|
+
font-size: 0.875rem;
|
110
|
+
/* 14px */
|
102
111
|
border-bottom: 1px solid var(--ifm-color-emphasis-200);
|
103
112
|
}
|
104
113
|
|
@@ -145,11 +154,13 @@
|
|
145
154
|
}
|
146
155
|
|
147
156
|
.theme-doc-sidebar-menu {
|
148
|
-
font-size: 0.875rem;
|
157
|
+
font-size: 0.875rem;
|
158
|
+
/* 14px */
|
149
159
|
}
|
150
160
|
|
151
161
|
.table-of-contents {
|
152
|
-
font-size: 0.8125rem;
|
162
|
+
font-size: 0.8125rem;
|
163
|
+
/* 13px */
|
153
164
|
}
|
154
165
|
|
155
166
|
.breadcrumbs {
|
@@ -161,6 +172,7 @@
|
|
161
172
|
.breadcrumbs__item:first-child {
|
162
173
|
display: none;
|
163
174
|
}
|
175
|
+
|
164
176
|
.breadcrumbs__link {
|
165
177
|
padding: 0;
|
166
178
|
background: none;
|
@@ -173,7 +185,7 @@
|
|
173
185
|
background: var(--ifm-menu-link-sublist-icon) 50% / 1rem 1rem;
|
174
186
|
}
|
175
187
|
|
176
|
-
.navbar__item.navbar-github-link{
|
188
|
+
.navbar__item.navbar-github-link {
|
177
189
|
display: block;
|
178
190
|
width: 120px;
|
179
191
|
}
|