cocoindex 0.1.69__tar.gz → 0.1.70__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.
Files changed (275) hide show
  1. {cocoindex-0.1.69 → cocoindex-0.1.70}/Cargo.lock +1 -1
  2. {cocoindex-0.1.69 → cocoindex-0.1.70}/Cargo.toml +1 -1
  3. {cocoindex-0.1.69 → cocoindex-0.1.70}/PKG-INFO +1 -1
  4. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/flow_def.mdx +39 -8
  5. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/ops/sources.md +29 -16
  6. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/amazon_s3_embedding/main.py +0 -6
  7. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/__init__.py +2 -1
  8. cocoindex-0.1.70/python/cocoindex/auth_registry.py +51 -0
  9. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/sources.py +9 -0
  10. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/live_updater.rs +53 -29
  11. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/sources/azure_blob.rs +20 -8
  12. cocoindex-0.1.69/python/cocoindex/auth_registry.py +0 -29
  13. {cocoindex-0.1.69 → cocoindex-0.1.70}/.cargo/config.toml +0 -0
  14. {cocoindex-0.1.69 → cocoindex-0.1.70}/.env.lib_debug +0 -0
  15. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/ISSUE_TEMPLATE//360/237/220/233-bug-report.md" +0 -0
  16. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/ISSUE_TEMPLATE//360/237/222/241-feature-request.md" +0 -0
  17. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/scripts/update_version.sh +0 -0
  18. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/workflows/CI.yml +0 -0
  19. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/workflows/_doc_release.yml +0 -0
  20. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/workflows/_test.yml +0 -0
  21. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/workflows/docs.yml +0 -0
  22. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/workflows/format.yml +0 -0
  23. {cocoindex-0.1.69 → cocoindex-0.1.70}/.github/workflows/release.yml +0 -0
  24. {cocoindex-0.1.69 → cocoindex-0.1.70}/.gitignore +0 -0
  25. {cocoindex-0.1.69 → cocoindex-0.1.70}/.pre-commit-config.yaml +0 -0
  26. {cocoindex-0.1.69 → cocoindex-0.1.70}/CODE_OF_CONDUCT.md +0 -0
  27. {cocoindex-0.1.69 → cocoindex-0.1.70}/CONTRIBUTING.md +0 -0
  28. {cocoindex-0.1.69 → cocoindex-0.1.70}/LICENSE +0 -0
  29. {cocoindex-0.1.69 → cocoindex-0.1.70}/README.md +0 -0
  30. {cocoindex-0.1.69 → cocoindex-0.1.70}/dev/neo4j.yaml +0 -0
  31. {cocoindex-0.1.69 → cocoindex-0.1.70}/dev/postgres.yaml +0 -0
  32. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/.gitignore +0 -0
  33. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/README.md +0 -0
  34. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/about/community.md +0 -0
  35. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/about/contributing.md +0 -0
  36. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/ai/llm.mdx +0 -0
  37. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/basics.md +0 -0
  38. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/cli.mdx +0 -0
  39. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/custom_function.mdx +0 -0
  40. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/data_example.svg +0 -0
  41. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/data_types.mdx +0 -0
  42. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/flow_example.svg +0 -0
  43. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/flow_methods.mdx +0 -0
  44. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/core/settings.mdx +0 -0
  45. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/getting_started/installation.md +0 -0
  46. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/getting_started/markdown_files.zip +0 -0
  47. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/getting_started/overview.md +0 -0
  48. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/getting_started/quickstart.md +0 -0
  49. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/ops/functions.md +0 -0
  50. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/ops/targets.md +0 -0
  51. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docs/query.mdx +0 -0
  52. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/docusaurus.config.ts +0 -0
  53. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/package.json +0 -0
  54. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/sidebars.ts +0 -0
  55. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/src/components/HomepageFeatures/index.tsx +0 -0
  56. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/src/components/HomepageFeatures/styles.module.css +0 -0
  57. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/src/css/custom.css +0 -0
  58. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/src/theme/Root.js +0 -0
  59. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/static/.nojekyll +0 -0
  60. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/static/img/docusaurus.png +0 -0
  61. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/static/img/favicon.ico +0 -0
  62. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/static/img/icon.svg +0 -0
  63. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/static/img/incremental-etl.gif +0 -0
  64. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/static/robots.txt +0 -0
  65. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/tsconfig.json +0 -0
  66. {cocoindex-0.1.69 → cocoindex-0.1.70}/docs/yarn.lock +0 -0
  67. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/amazon_s3_embedding/.env.example +0 -0
  68. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/amazon_s3_embedding/.gitignore +0 -0
  69. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/amazon_s3_embedding/README.md +0 -0
  70. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/amazon_s3_embedding/pyproject.toml +0 -0
  71. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/azure_blob_embedding/.env.example +0 -0
  72. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/azure_blob_embedding/.gitignore +0 -0
  73. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/azure_blob_embedding/README.md +0 -0
  74. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/azure_blob_embedding/main.py +0 -0
  75. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/azure_blob_embedding/pyproject.toml +0 -0
  76. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/code_embedding/.env +0 -0
  77. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/code_embedding/README.md +0 -0
  78. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/code_embedding/main.py +0 -0
  79. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/code_embedding/pyproject.toml +0 -0
  80. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/docs_to_knowledge_graph/.env +0 -0
  81. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/docs_to_knowledge_graph/README.md +0 -0
  82. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/docs_to_knowledge_graph/main.py +0 -0
  83. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/docs_to_knowledge_graph/pyproject.toml +0 -0
  84. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/.dockerignore +0 -0
  85. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/.env +0 -0
  86. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/README.md +0 -0
  87. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/compose.yaml +0 -0
  88. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/dockerfile +0 -0
  89. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/files/1810.04805v2.md +0 -0
  90. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/main.py +0 -0
  91. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/fastapi_server_docker/requirements.txt +0 -0
  92. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/gdrive_text_embedding/.env.example +0 -0
  93. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/gdrive_text_embedding/.gitignore +0 -0
  94. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/gdrive_text_embedding/README.md +0 -0
  95. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/gdrive_text_embedding/main.py +0 -0
  96. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/gdrive_text_embedding/pyproject.toml +0 -0
  97. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/.env +0 -0
  98. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/README.md +0 -0
  99. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/.gitignore +0 -0
  100. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/index.html +0 -0
  101. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/package-lock.json +0 -0
  102. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/package.json +0 -0
  103. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/src/App.jsx +0 -0
  104. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/src/main.jsx +0 -0
  105. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/src/style.css +0 -0
  106. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/frontend/vite.config.js +0 -0
  107. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/img/cat1.jpeg +0 -0
  108. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/img/dog1.jpeg +0 -0
  109. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/img/elephant1.jpg +0 -0
  110. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/img/giraffe.jpg +0 -0
  111. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/main.py +0 -0
  112. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/image_search/pyproject.toml +0 -0
  113. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/.env +0 -0
  114. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/README.md +0 -0
  115. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/main.py +0 -0
  116. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/manuals/array.pdf +0 -0
  117. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/manuals/base64.pdf +0 -0
  118. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/manuals/copy.pdf +0 -0
  119. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/manuals/glob.pdf +0 -0
  120. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/manuals_llm_extraction/pyproject.toml +0 -0
  121. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/.env.example +0 -0
  122. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/.gitignore +0 -0
  123. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/README.md +0 -0
  124. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/main.py +0 -0
  125. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/papers/1706.03762v7.pdf +0 -0
  126. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/papers/1810.04805v2.pdf +0 -0
  127. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/papers/2502.06786v3.pdf +0 -0
  128. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/papers/2502.20346v1.pdf +0 -0
  129. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/paper_metadata/pyproject.toml +0 -0
  130. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/.env.example +0 -0
  131. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/README.md +0 -0
  132. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/data/README.md +0 -0
  133. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_Form_David_Artificial.docx +0 -0
  134. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_Form_Emily_Artificial.pdf +0 -0
  135. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_Form_Joe_Artificial.pdf +0 -0
  136. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/data/patient_forms/Patient_Intake_From_Jane_Artificial.docx +0 -0
  137. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/main.py +0 -0
  138. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/patient_intake_extraction/pyproject.toml +0 -0
  139. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/.env +0 -0
  140. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/README.md +0 -0
  141. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/main.py +0 -0
  142. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/pdf_files/1706.03762v7.pdf +0 -0
  143. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/pdf_files/1810.04805v2.pdf +0 -0
  144. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/pdf_files/rfc8259.pdf +0 -0
  145. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/pdf_embedding/pyproject.toml +0 -0
  146. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/.env +0 -0
  147. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/README.md +0 -0
  148. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/img/cocoinsight.png +0 -0
  149. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/img/neo4j.png +0 -0
  150. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/main.py +0 -0
  151. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p1.json +0 -0
  152. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p2.json +0 -0
  153. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p3.json +0 -0
  154. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p4.json +0 -0
  155. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p5.json +0 -0
  156. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p6.json +0 -0
  157. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p7.json +0 -0
  158. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p8.json +0 -0
  159. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/products/p9.json +0 -0
  160. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/product_recommendation/pyproject.toml +0 -0
  161. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/.env +0 -0
  162. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/README.md +0 -0
  163. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/Text_Embedding.ipynb +0 -0
  164. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/main.py +0 -0
  165. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/markdown_files/1706.03762v7.md +0 -0
  166. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/markdown_files/1810.04805v2.md +0 -0
  167. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/markdown_files/rfc8259.md +0 -0
  168. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding/pyproject.toml +0 -0
  169. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding_qdrant/.env +0 -0
  170. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding_qdrant/README.md +0 -0
  171. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding_qdrant/main.py +0 -0
  172. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding_qdrant/markdown_files/rfc8259.md +0 -0
  173. {cocoindex-0.1.69 → cocoindex-0.1.70}/examples/text_embedding_qdrant/pyproject.toml +0 -0
  174. {cocoindex-0.1.69 → cocoindex-0.1.70}/pyproject.toml +0 -0
  175. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/cli.py +0 -0
  176. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/convert.py +0 -0
  177. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/flow.py +0 -0
  178. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/functions.py +0 -0
  179. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/index.py +0 -0
  180. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/lib.py +0 -0
  181. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/llm.py +0 -0
  182. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/op.py +0 -0
  183. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/py.typed +0 -0
  184. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/runtime.py +0 -0
  185. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/setting.py +0 -0
  186. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/setup.py +0 -0
  187. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/targets.py +0 -0
  188. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/tests/__init__.py +0 -0
  189. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/tests/test_convert.py +0 -0
  190. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/tests/test_optional_database.py +0 -0
  191. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/tests/test_typing.py +0 -0
  192. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/typing.py +0 -0
  193. {cocoindex-0.1.69 → cocoindex-0.1.70}/python/cocoindex/utils.py +0 -0
  194. {cocoindex-0.1.69 → cocoindex-0.1.70}/ruff.toml +0 -0
  195. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/duration.rs +0 -0
  196. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/field_attrs.rs +0 -0
  197. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/json_schema.rs +0 -0
  198. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/mod.rs +0 -0
  199. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/schema.rs +0 -0
  200. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/spec.rs +0 -0
  201. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/base/value.rs +0 -0
  202. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/builder/analyzed_flow.rs +0 -0
  203. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/builder/analyzer.rs +0 -0
  204. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/builder/exec_ctx.rs +0 -0
  205. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/builder/flow_builder.rs +0 -0
  206. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/builder/mod.rs +0 -0
  207. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/builder/plan.rs +0 -0
  208. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/db_tracking.rs +0 -0
  209. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/db_tracking_setup.rs +0 -0
  210. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/dumper.rs +0 -0
  211. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/evaluator.rs +0 -0
  212. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/indexing_status.rs +0 -0
  213. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/memoization.rs +0 -0
  214. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/mod.rs +0 -0
  215. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/row_indexer.rs +0 -0
  216. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/source_indexer.rs +0 -0
  217. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/execution/stats.rs +0 -0
  218. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/lib.rs +0 -0
  219. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/lib_context.rs +0 -0
  220. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/anthropic.rs +0 -0
  221. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/gemini.rs +0 -0
  222. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/litellm.rs +0 -0
  223. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/mod.rs +0 -0
  224. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/ollama.rs +0 -0
  225. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/openai.rs +0 -0
  226. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/openrouter.rs +0 -0
  227. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/vertex_ai.rs +0 -0
  228. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/vllm.rs +0 -0
  229. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/llm/voyage.rs +0 -0
  230. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/factory_bases.rs +0 -0
  231. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/functions/embed_text.rs +0 -0
  232. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/functions/extract_by_llm.rs +0 -0
  233. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/functions/mod.rs +0 -0
  234. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/functions/parse_json.rs +0 -0
  235. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/functions/split_recursively.rs +0 -0
  236. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/functions/test_utils.rs +0 -0
  237. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/interface.rs +0 -0
  238. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/mod.rs +0 -0
  239. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/py_factory.rs +0 -0
  240. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/registration.rs +0 -0
  241. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/registry.rs +0 -0
  242. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/sdk.rs +0 -0
  243. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/sources/amazon_s3.rs +0 -0
  244. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/sources/google_drive.rs +0 -0
  245. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/sources/local_file.rs +0 -0
  246. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/sources/mod.rs +0 -0
  247. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/kuzu.rs +0 -0
  248. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/mod.rs +0 -0
  249. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/neo4j.rs +0 -0
  250. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/postgres.rs +0 -0
  251. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/qdrant.rs +0 -0
  252. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/shared/mod.rs +0 -0
  253. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/shared/property_graph.rs +0 -0
  254. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/ops/targets/shared/table_columns.rs +0 -0
  255. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/prelude.rs +0 -0
  256. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/py/convert.rs +0 -0
  257. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/py/mod.rs +0 -0
  258. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/server.rs +0 -0
  259. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/service/error.rs +0 -0
  260. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/service/flows.rs +0 -0
  261. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/service/mod.rs +0 -0
  262. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/settings.rs +0 -0
  263. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/setup/auth_registry.rs +0 -0
  264. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/setup/components.rs +0 -0
  265. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/setup/db_metadata.rs +0 -0
  266. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/setup/driver.rs +0 -0
  267. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/setup/mod.rs +0 -0
  268. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/setup/states.rs +0 -0
  269. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/concur_control.rs +0 -0
  270. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/db.rs +0 -0
  271. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/fingerprint.rs +0 -0
  272. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/immutable.rs +0 -0
  273. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/mod.rs +0 -0
  274. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/retryable.rs +0 -0
  275. {cocoindex-0.1.69 → cocoindex-0.1.70}/src/utils/yaml_ser.rs +0 -0
@@ -1297,7 +1297,7 @@ dependencies = [
1297
1297
 
1298
1298
  [[package]]
1299
1299
  name = "cocoindex"
1300
- version = "0.1.69"
1300
+ version = "0.1.70"
1301
1301
  dependencies = [
1302
1302
  "anyhow",
1303
1303
  "async-openai",
@@ -2,7 +2,7 @@
2
2
  name = "cocoindex"
3
3
  # Version used for local development is always higher than others to take precedence.
4
4
  # Will be overridden for specific release versions.
5
- version = "0.1.69"
5
+ version = "0.1.70"
6
6
  edition = "2024"
7
7
  rust-version = "1.88"
8
8
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cocoindex
3
- Version: 0.1.69
3
+ Version: 0.1.70
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
@@ -416,22 +416,28 @@ flow_builder.declare(
416
416
  ### Auth Registry
417
417
 
418
418
  CocoIndex manages an auth registry. It's an in-memory key-value store, mainly to store authentication information for a backend.
419
+ It's usually used for targets, where key stability is important for backend cleanup.
419
420
 
420
- Operation spec is the default way to configure a persistent backend. But it has the following limitations:
421
+ Operation spec is the default way to configure sources, functions and targets. But it has the following limitations:
421
422
 
422
423
  * The spec isn't supposed to contain secret information, and it's frequently shown in various places, e.g. `cocoindex show`.
423
- * Once an operation is removed after flow definition code change, the spec is also gone.
424
- But we still need to be able to drop the backend (e.g. a table) when [setup / drop flow](/docs/core/flow_methods#setup--drop-flow).
424
+ * For targets, once an operation is removed after flow definition code change, the spec is also gone.
425
+ But we still need to be able to drop the persistent backend (e.g. a table) when [setup / drop flow](/docs/core/flow_methods#setup--drop-flow).
425
426
 
426
- Auth registry is introduced to solve the problems above. It works as follows:
427
+ Auth registry is introduced to solve the problems above.
427
428
 
428
- * You can create new **auth entry** by a key and a value.
429
- * You can references the entry by the key, and pass it as part of spec for certain operations. e.g. `Neo4j` takes `connection` field in the form of auth entry reference.
429
+
430
+ #### Auth Entry
431
+
432
+ An auth entry is an entry in the auth registry with an explicit key.
433
+
434
+ * You can create new *auth entry* by a key and a value.
435
+ * You can reference the entry by the key, and pass it as part of spec for certain operations. e.g. `Neo4j` takes `connection` field in the form of auth entry reference.
430
436
 
431
437
  <Tabs>
432
438
  <TabItem value="python" label="Python" default>
433
439
 
434
- You can add an auth entry by `cocoindex.add_auth_entry()` function, which returns a `cocoindex.AuthEntryReference`:
440
+ You can add an auth entry by `cocoindex.add_auth_entry()` function, which returns a `cocoindex.AuthEntryReference[T]`:
435
441
 
436
442
  ```python
437
443
  my_graph_conn = cocoindex.add_auth_entry(
@@ -445,7 +451,7 @@ my_graph_conn = cocoindex.add_auth_entry(
445
451
 
446
452
  Then reference it when building a spec that takes an auth entry:
447
453
 
448
- * You can either reference by the `AuthEntryReference` object directly:
454
+ * You can either reference by the `AuthEntryReference[T]` object directly:
449
455
 
450
456
  ```python
451
457
  demo_collector.export(
@@ -472,3 +478,28 @@ Note that CocoIndex backends use the key of an auth entry to identify the backen
472
478
 
473
479
  * If a key is no longer referenced in any operation spec, keep it until the next flow setup / drop action,
474
480
  so that CocoIndex will be able to clean up the backends.
481
+
482
+ #### Transient Auth Entry
483
+
484
+ A transient auth entry is an entry in the auth registry with an automatically generated key.
485
+ It's usually used for sources and functions, where key stability is not important.
486
+
487
+ <Tabs>
488
+ <TabItem value="python" label="Python" default>
489
+
490
+ You can create a new *transient auth entry* by `cocoindex.add_transient_auth_entry()` function, which returns a `cocoindex.TransientAuthEntryReference[T]`, and pass it to a source or function spec that takes it, e.g.
491
+
492
+ ```python
493
+ flow_builder.add_source(
494
+ cocoindex.sources.AzureBlob(
495
+ ...
496
+ sas_token=cocoindex.add_transient_auth_entry("...")
497
+ )
498
+ )
499
+ ```
500
+
501
+
502
+ </TabItem>
503
+ </Tabs>
504
+
505
+ Whenever a `TransientAuthEntryReference[T]` is expected, you can also pass a `AuthEntryReference[T]` instead, as `AuthEntryReference[T]` is a subtype of `TransientAuthEntryReference[T]`.
@@ -170,22 +170,33 @@ These are actions you need to take:
170
170
 
171
171
  #### Authentication
172
172
 
173
- We use Azure’s **Default Credential** system (DefaultAzureCredential) for secure and flexible authentication.
174
- This allows you to connect to Azure services without putting any secrets in the code or flow spec.
175
- It automatically chooses the best authentication method based on your environment:
176
-
177
- * On your local machine: uses your Azure CLI login (`az login`) or environment variables.
178
-
179
- ```sh
180
- az login
181
- # Optional: Set a default subscription if you have more than one
182
- az account set --subscription "<YOUR_SUBSCRIPTION_NAME_OR_ID>"
183
- ```
184
- * In Azure (VM, App Service, AKS, etc.): uses the resource’s Managed Identity.
185
- * In automated environments: supports Service Principals via environment variables
186
- * `AZURE_CLIENT_ID`
187
- * `AZURE_TENANT_ID`
188
- * `AZURE_CLIENT_SECRET`
173
+ We support the following authentication methods:
174
+
175
+ * Shared access signature (SAS) tokens.
176
+ You can generate it from the Azure Portal in the settings for a specific container.
177
+ You need to provide at least *List* and *Read* permissions when generating the SAS token.
178
+ It's a query string in the form of
179
+ `sp=rl&st=2025-07-20T09:33:00Z&se=2025-07-19T09:48:53Z&sv=2024-11-04&sr=c&sig=i3FDjsadfklj3%23adsfkk`.
180
+
181
+ * Storage account access key. You can find it in the Azure Portal in the settings for a specific storage account.
182
+
183
+ * Default credential. When none of the above is provided, it will use the default credential.
184
+
185
+ This allows you to connect to Azure services without putting any secrets in the code or flow spec.
186
+ It automatically chooses the best authentication method based on your environment:
187
+
188
+ * On your local machine: uses your Azure CLI login (`az login`) or environment variables.
189
+
190
+ ```sh
191
+ az login
192
+ # Optional: Set a default subscription if you have more than one
193
+ az account set --subscription "<YOUR_SUBSCRIPTION_NAME_OR_ID>"
194
+ ```
195
+ * In Azure (VM, App Service, AKS, etc.): uses the resource’s Managed Identity.
196
+ * In automated environments: supports Service Principals via environment variables
197
+ * `AZURE_CLIENT_ID`
198
+ * `AZURE_TENANT_ID`
199
+ * `AZURE_CLIENT_SECRET`
189
200
 
190
201
  You can refer to [this doc](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication/overview) for more details.
191
202
 
@@ -202,6 +213,8 @@ The spec takes the following fields:
202
213
  * `excluded_patterns` (`list[str]`, optional): a list of glob patterns to exclude files, e.g. `["*.tmp", "**/*.log"]`.
203
214
  Any file or directory matching these patterns will be excluded even if they match `included_patterns`.
204
215
  If not specified, no files will be excluded.
216
+ * `sas_token` (`cocoindex.TransientAuthEntryReference[str]`, optional): a SAS token for authentication.
217
+ * `account_access_key` (`cocoindex.TransientAuthEntryReference[str]`, optional): an account access key for authentication.
205
218
 
206
219
  :::info
207
220
 
@@ -102,12 +102,6 @@ def _main() -> None:
102
102
 
103
103
  amazon_s3_text_embedding_flow.setup()
104
104
  with cocoindex.FlowLiveUpdater(amazon_s3_text_embedding_flow) as updater:
105
- while True:
106
- updates = updater.next_status_updates()
107
- print(f"Updates: {updates}")
108
- if not updates.active_sources:
109
- break
110
-
111
105
  # Run queries in a loop to demonstrate the query capabilities.
112
106
  while True:
113
107
  query = input("Enter search query (or Enter to quit): ")
@@ -6,7 +6,7 @@ from . import functions, sources, targets, cli, utils
6
6
 
7
7
  from . import targets as storages # Deprecated: Use targets instead
8
8
 
9
- from .auth_registry import AuthEntryReference, add_auth_entry, ref_auth_entry
9
+ from .auth_registry import AuthEntryReference, add_auth_entry, add_transient_auth_entry
10
10
  from .flow import FlowBuilder, DataScope, DataSlice, Flow, transform_flow
11
11
  from .flow import flow_def
12
12
  from .flow import EvaluateAndDumpOptions, GeneratedField
@@ -42,6 +42,7 @@ __all__ = [
42
42
  # Auth registry
43
43
  "AuthEntryReference",
44
44
  "add_auth_entry",
45
+ "add_transient_auth_entry",
45
46
  "ref_auth_entry",
46
47
  # Flow
47
48
  "FlowBuilder",
@@ -0,0 +1,51 @@
1
+ """
2
+ Auth registry is used to register and reference auth entries.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Generic, TypeVar
7
+ import threading
8
+
9
+ from . import _engine # type: ignore
10
+ from .convert import dump_engine_object
11
+
12
+ T = TypeVar("T")
13
+
14
+ # Global atomic counter for generating unique auth entry keys
15
+ _counter_lock = threading.Lock()
16
+ _auth_key_counter = 0
17
+
18
+
19
+ def _generate_auth_key() -> str:
20
+ """Generate a unique auth entry key using a global atomic counter."""
21
+ global _auth_key_counter # pylint: disable=global-statement
22
+ with _counter_lock:
23
+ _auth_key_counter += 1
24
+ return f"__auth_{_auth_key_counter}"
25
+
26
+
27
+ @dataclass
28
+ class TransientAuthEntryReference(Generic[T]):
29
+ """Reference an auth entry, may or may not have a stable key."""
30
+
31
+ key: str
32
+
33
+
34
+ class AuthEntryReference(TransientAuthEntryReference[T]):
35
+ """Reference an auth entry, with a key stable across ."""
36
+
37
+
38
+ def add_transient_auth_entry(value: T) -> TransientAuthEntryReference[T]:
39
+ """Add an auth entry to the registry. Returns its reference."""
40
+ return add_auth_entry(_generate_auth_key(), value)
41
+
42
+
43
+ def add_auth_entry(key: str, value: T) -> AuthEntryReference[T]:
44
+ """Add an auth entry to the registry. Returns its reference."""
45
+ _engine.add_auth_entry(key, dump_engine_object(value))
46
+ return AuthEntryReference(key)
47
+
48
+
49
+ def ref_auth_entry(key: str) -> AuthEntryReference[T]:
50
+ """Reference an auth entry by its key."""
51
+ return AuthEntryReference(key)
@@ -1,6 +1,7 @@
1
1
  """All builtin sources."""
2
2
 
3
3
  from . import op
4
+ from .auth_registry import TransientAuthEntryReference
4
5
  import datetime
5
6
 
6
7
 
@@ -48,6 +49,11 @@ class AmazonS3(op.SourceSpec):
48
49
  class AzureBlob(op.SourceSpec):
49
50
  """
50
51
  Import data from an Azure Blob Storage container. Supports optional prefix and file filtering by glob patterns.
52
+
53
+ Authentication mechanisms taken in the following order:
54
+ - SAS token (if provided)
55
+ - Account access key (if provided)
56
+ - Default Azure credential
51
57
  """
52
58
 
53
59
  _op_category = op.OpCategory.SOURCE
@@ -58,3 +64,6 @@ class AzureBlob(op.SourceSpec):
58
64
  binary: bool = False
59
65
  included_patterns: list[str] | None = None
60
66
  excluded_patterns: list[str] | None = None
67
+
68
+ sas_token: TransientAuthEntryReference[str] | None = None
69
+ account_access_key: TransientAuthEntryReference[str] | None = None
@@ -3,7 +3,7 @@ use crate::{execution::stats::UpdateStats, prelude::*};
3
3
  use super::stats;
4
4
  use futures::future::try_join_all;
5
5
  use sqlx::PgPool;
6
- use tokio::{sync::watch, time::MissedTickBehavior};
6
+ use tokio::{sync::watch, task::JoinSet, time::MissedTickBehavior};
7
7
 
8
8
  pub struct FlowLiveUpdaterUpdates {
9
9
  pub active_sources: Vec<String>,
@@ -22,7 +22,8 @@ struct UpdateReceiveState {
22
22
 
23
23
  pub struct FlowLiveUpdater {
24
24
  flow_ctx: Arc<FlowContext>,
25
- tasks: Vec<(tokio::task::JoinHandle<Result<()>>, Arc<stats::UpdateStats>)>,
25
+ join_set: Mutex<Option<JoinSet<Result<()>>>>,
26
+ stats_per_task: Vec<Arc<stats::UpdateStats>>,
26
27
  recv_state: tokio::sync::Mutex<UpdateReceiveState>,
27
28
  num_remaining_tasks_rx: watch::Receiver<usize>,
28
29
 
@@ -267,7 +268,11 @@ impl SourceUpdateTask {
267
268
  .boxed()
268
269
  });
269
270
 
270
- try_join_all(futs).await?;
271
+ let join_result = try_join_all(futs).await;
272
+ if let Err(err) = join_result {
273
+ error!("Error in source `{}`: {:?}", import_op.name, err);
274
+ return Err(err);
275
+ }
271
276
  Ok(())
272
277
  }
273
278
  }
@@ -288,27 +293,30 @@ impl FlowLiveUpdater {
288
293
 
289
294
  let (num_remaining_tasks_tx, num_remaining_tasks_rx) =
290
295
  watch::channel(plan.import_ops.len());
291
- let tasks = (0..plan.import_ops.len())
292
- .map(|source_idx| {
293
- let source_update_stats = Arc::new(stats::UpdateStats::default());
294
- let source_update_task = SourceUpdateTask {
295
- source_idx,
296
- flow: flow_ctx.flow.clone(),
297
- plan: plan.clone(),
298
- execution_ctx: execution_ctx.clone(),
299
- source_update_stats: source_update_stats.clone(),
300
- pool: pool.clone(),
301
- options: options.clone(),
302
- status_tx: status_tx.clone(),
303
- num_remaining_tasks_tx: num_remaining_tasks_tx.clone(),
304
- };
305
- let task = tokio::spawn(source_update_task.run());
306
- (task, source_update_stats)
307
- })
308
- .collect();
296
+
297
+ let mut join_set = JoinSet::new();
298
+ let mut stats_per_task = Vec::new();
299
+
300
+ for source_idx in 0..plan.import_ops.len() {
301
+ let source_update_stats = Arc::new(stats::UpdateStats::default());
302
+ let source_update_task = SourceUpdateTask {
303
+ source_idx,
304
+ flow: flow_ctx.flow.clone(),
305
+ plan: plan.clone(),
306
+ execution_ctx: execution_ctx.clone(),
307
+ source_update_stats: source_update_stats.clone(),
308
+ pool: pool.clone(),
309
+ options: options.clone(),
310
+ status_tx: status_tx.clone(),
311
+ num_remaining_tasks_tx: num_remaining_tasks_tx.clone(),
312
+ };
313
+ join_set.spawn(source_update_task.run());
314
+ stats_per_task.push(source_update_stats);
315
+ }
309
316
  Ok(Self {
310
317
  flow_ctx,
311
- tasks,
318
+ join_set: Mutex::new(Some(join_set)),
319
+ stats_per_task,
312
320
  recv_state: tokio::sync::Mutex::new(UpdateReceiveState {
313
321
  status_rx,
314
322
  last_num_source_updates: vec![0; plan.import_ops.len()],
@@ -322,17 +330,33 @@ impl FlowLiveUpdater {
322
330
  }
323
331
 
324
332
  pub async fn wait(&self) -> Result<()> {
325
- let mut rx = self.num_remaining_tasks_rx.clone();
326
- if *rx.borrow() == 0 {
333
+ {
334
+ let mut rx = self.num_remaining_tasks_rx.clone();
335
+ rx.wait_for(|v| *v == 0).await?;
336
+ }
337
+
338
+ let Some(mut join_set) = self.join_set.lock().unwrap().take() else {
327
339
  return Ok(());
340
+ };
341
+ while let Some(task_result) = join_set.join_next().await {
342
+ match task_result {
343
+ Ok(Ok(_)) => {}
344
+ Ok(Err(err)) => {
345
+ return Err(err);
346
+ }
347
+ Err(err) if err.is_cancelled() => {}
348
+ Err(err) => {
349
+ return Err(err.into());
350
+ }
351
+ }
328
352
  }
329
- rx.wait_for(|v| *v == 0).await?;
330
353
  Ok(())
331
354
  }
332
355
 
333
356
  pub fn abort(&self) {
334
- for (task, _) in &self.tasks {
335
- task.abort();
357
+ let mut join_set = self.join_set.lock().unwrap();
358
+ if let Some(join_set) = &mut *join_set {
359
+ join_set.abort_all();
336
360
  }
337
361
  }
338
362
 
@@ -340,9 +364,9 @@ impl FlowLiveUpdater {
340
364
  stats::IndexUpdateInfo {
341
365
  sources: std::iter::zip(
342
366
  self.flow_ctx.flow.flow_instance.import_ops.iter(),
343
- self.tasks.iter(),
367
+ self.stats_per_task.iter(),
344
368
  )
345
- .map(|(import_op, (_, stats))| stats::SourceUpdateInfo {
369
+ .map(|(import_op, stats)| stats::SourceUpdateInfo {
346
370
  source_name: import_op.name.clone(),
347
371
  stats: stats.as_ref().clone(),
348
372
  })
@@ -19,6 +19,11 @@ pub struct Spec {
19
19
  binary: bool,
20
20
  included_patterns: Option<Vec<String>>,
21
21
  excluded_patterns: Option<Vec<String>>,
22
+
23
+ /// SAS token for authentication. Takes precedence over account_access_key.
24
+ sas_token: Option<AuthEntryReference<String>>,
25
+ /// Account access key for authentication. If not provided, will use default Azure credential.
26
+ account_access_key: Option<AuthEntryReference<String>>,
22
27
  }
23
28
 
24
29
  struct Executor {
@@ -209,15 +214,22 @@ impl SourceFactoryBase for Factory {
209
214
  async fn build_executor(
210
215
  self: Arc<Self>,
211
216
  spec: Spec,
212
- _context: Arc<FlowInstanceContext>,
217
+ context: Arc<FlowInstanceContext>,
213
218
  ) -> Result<Box<dyn SourceExecutor>> {
214
- let default_credential = Arc::new(DefaultAzureCredential::create(
215
- TokenCredentialOptions::default(),
216
- )?);
217
- let client = BlobServiceClient::new(
218
- &spec.account_name,
219
- StorageCredentials::token_credential(default_credential),
220
- );
219
+ let credential = if let Some(sas_token) = spec.sas_token {
220
+ let sas_token = context.auth_registry.get(&sas_token)?;
221
+ StorageCredentials::sas_token(sas_token)?
222
+ } else if let Some(account_access_key) = spec.account_access_key {
223
+ let account_access_key = context.auth_registry.get(&account_access_key)?;
224
+ StorageCredentials::access_key(spec.account_name.clone(), account_access_key)
225
+ } else {
226
+ let default_credential = Arc::new(DefaultAzureCredential::create(
227
+ TokenCredentialOptions::default(),
228
+ )?);
229
+ StorageCredentials::token_credential(default_credential)
230
+ };
231
+
232
+ let client = BlobServiceClient::new(&spec.account_name, credential);
221
233
  Ok(Box::new(Executor {
222
234
  client,
223
235
  container_name: spec.container_name,
@@ -1,29 +0,0 @@
1
- """
2
- Auth registry is used to register and reference auth entries.
3
- """
4
-
5
- from dataclasses import dataclass
6
- from typing import Generic, TypeVar
7
-
8
- from . import _engine # type: ignore
9
- from .convert import dump_engine_object
10
-
11
- T = TypeVar("T")
12
-
13
-
14
- @dataclass
15
- class AuthEntryReference(Generic[T]):
16
- """Reference an auth entry by its key."""
17
-
18
- key: str
19
-
20
-
21
- def add_auth_entry(key: str, value: T) -> AuthEntryReference[T]:
22
- """Add an auth entry to the registry. Returns its reference."""
23
- _engine.add_auth_entry(key, dump_engine_object(value))
24
- return AuthEntryReference(key)
25
-
26
-
27
- def ref_auth_entry(key: str) -> AuthEntryReference[T]:
28
- """Reference an auth entry by its key."""
29
- return AuthEntryReference(key)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes