cocoindex 0.1.32__tar.gz → 0.1.33__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 (216) hide show
  1. {cocoindex-0.1.32 → cocoindex-0.1.33}/Cargo.lock +1 -1
  2. {cocoindex-0.1.32 → cocoindex-0.1.33}/Cargo.toml +5 -2
  3. {cocoindex-0.1.32 → cocoindex-0.1.33}/PKG-INFO +2 -1
  4. {cocoindex-0.1.32 → cocoindex-0.1.33}/README.md +1 -0
  5. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/code_embedding/pyproject.toml +1 -1
  6. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/pyproject.toml +1 -1
  7. cocoindex-0.1.33/examples/fastapi_server_docker/.dockerignore +2 -0
  8. cocoindex-0.1.33/examples/fastapi_server_docker/.env +1 -0
  9. cocoindex-0.1.33/examples/fastapi_server_docker/README.md +10 -0
  10. cocoindex-0.1.33/examples/fastapi_server_docker/compose.yaml +18 -0
  11. cocoindex-0.1.33/examples/fastapi_server_docker/dockerfile +13 -0
  12. cocoindex-0.1.33/examples/fastapi_server_docker/main.py +30 -0
  13. cocoindex-0.1.33/examples/fastapi_server_docker/requirements.txt +5 -0
  14. cocoindex-0.1.33/examples/fastapi_server_docker/sample_code/main.py +113 -0
  15. cocoindex-0.1.33/examples/fastapi_server_docker/src/cocoindex_funs.py +45 -0
  16. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/pyproject.toml +1 -1
  17. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/pyproject.toml +1 -1
  18. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/pyproject.toml +1 -1
  19. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/.env +3 -0
  20. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/README.md +66 -0
  21. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/img/cocoinsight.png +0 -0
  22. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/img/neo4j.png +0 -0
  23. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/main.py +185 -0
  24. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p1.json +22 -0
  25. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p2.json +22 -0
  26. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p3.json +22 -0
  27. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p4.json +22 -0
  28. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p5.json +22 -0
  29. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p6.json +22 -0
  30. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p7.json +26 -0
  31. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p8.json +21 -0
  32. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/products/p9.json +21 -0
  33. cocoindex-0.1.33/examples/product_taxonomy_knowledge_graph/pyproject.toml +6 -0
  34. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/pyproject.toml +1 -1
  35. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding_qdrant/pyproject.toml +1 -1
  36. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/__init__.py +1 -0
  37. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/storages/qdrant.rs +5 -3
  38. cocoindex-0.1.33/src/utils/yaml_ser.rs +731 -0
  39. cocoindex-0.1.32/src/utils/yaml_ser.rs +0 -349
  40. {cocoindex-0.1.32 → cocoindex-0.1.33}/.cargo/config.toml +0 -0
  41. {cocoindex-0.1.32 → cocoindex-0.1.33}/.env.lib_debug +0 -0
  42. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/ISSUE_TEMPLATE//360/237/220/233-bug-report.md" +0 -0
  43. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/ISSUE_TEMPLATE//360/237/222/241-feature-request.md" +0 -0
  44. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/scripts/update_version.sh +0 -0
  45. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/workflows/CI.yml +0 -0
  46. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/workflows/_test.yml +0 -0
  47. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/workflows/docs.yml +0 -0
  48. {cocoindex-0.1.32 → cocoindex-0.1.33}/.github/workflows/release.yml +0 -0
  49. {cocoindex-0.1.32 → cocoindex-0.1.33}/.gitignore +0 -0
  50. {cocoindex-0.1.32 → cocoindex-0.1.33}/.vscode/settings.json +0 -0
  51. {cocoindex-0.1.32 → cocoindex-0.1.33}/CODE_OF_CONDUCT.md +0 -0
  52. {cocoindex-0.1.32 → cocoindex-0.1.33}/CONTRIBUTING.md +0 -0
  53. {cocoindex-0.1.32 → cocoindex-0.1.33}/LICENSE +0 -0
  54. {cocoindex-0.1.32 → cocoindex-0.1.33}/dev/neo4j.yaml +0 -0
  55. {cocoindex-0.1.32 → cocoindex-0.1.33}/dev/postgres.yaml +0 -0
  56. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/.gitignore +0 -0
  57. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/README.md +0 -0
  58. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/about/community.md +0 -0
  59. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/about/contributing.md +0 -0
  60. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/ai/llm.mdx +0 -0
  61. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/basics.md +0 -0
  62. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/cli.mdx +0 -0
  63. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/custom_function.mdx +0 -0
  64. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/data_example.svg +0 -0
  65. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/data_types.mdx +0 -0
  66. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/flow_def.mdx +0 -0
  67. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/flow_example.svg +0 -0
  68. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/flow_methods.mdx +0 -0
  69. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/core/initialization.mdx +0 -0
  70. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/getting_started/installation.md +0 -0
  71. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/getting_started/markdown_files.zip +0 -0
  72. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/getting_started/overview.md +0 -0
  73. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/getting_started/quickstart.md +0 -0
  74. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/ops/functions.md +0 -0
  75. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/ops/sources.md +0 -0
  76. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docs/ops/storages.md +0 -0
  77. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/docusaurus.config.ts +0 -0
  78. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/package.json +0 -0
  79. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/sidebars.ts +0 -0
  80. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/src/components/HomepageFeatures/index.tsx +0 -0
  81. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/src/components/HomepageFeatures/styles.module.css +0 -0
  82. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/src/css/custom.css +0 -0
  83. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/src/theme/Root.js +0 -0
  84. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/static/.nojekyll +0 -0
  85. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/static/img/docusaurus.png +0 -0
  86. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/static/img/favicon.ico +0 -0
  87. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/static/img/icon.svg +0 -0
  88. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/static/robots.txt +0 -0
  89. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/tsconfig.json +0 -0
  90. {cocoindex-0.1.32 → cocoindex-0.1.33}/docs/yarn.lock +0 -0
  91. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/code_embedding/.env +0 -0
  92. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/code_embedding/README.md +0 -0
  93. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/code_embedding/main.py +0 -0
  94. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/.env +0 -0
  95. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/README.md +0 -0
  96. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/main.py +0 -0
  97. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/markdown_files/1706.03762v7.md +0 -0
  98. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/markdown_files/1810.04805v2.md +0 -0
  99. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/docs_to_knowledge_graph/markdown_files/rfc8259.md +0 -0
  100. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/.env.example +0 -0
  101. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/.gitignore +0 -0
  102. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/README.md +0 -0
  103. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/data/1706.03762v7.docx +0 -0
  104. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/data/1810.04805v2.docx +0 -0
  105. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/gdrive_text_embedding/main.py +0 -0
  106. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/.env +0 -0
  107. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/README.md +0 -0
  108. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/main.py +0 -0
  109. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/manuals/array.pdf +0 -0
  110. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/manuals/base64.pdf +0 -0
  111. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/manuals/copy.pdf +0 -0
  112. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/manuals_llm_extraction/manuals/glob.pdf +0 -0
  113. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/.env +0 -0
  114. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/README.md +0 -0
  115. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/main.py +0 -0
  116. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/pdf_files/1706.03762v7.pdf +0 -0
  117. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/pdf_files/1810.04805v2.pdf +0 -0
  118. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/pdf_embedding/pdf_files/rfc8259.pdf +0 -0
  119. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/.env +0 -0
  120. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/README.md +0 -0
  121. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/Text_Embedding.ipynb +0 -0
  122. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/main.py +0 -0
  123. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/markdown_files/1706.03762v7.md +0 -0
  124. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/markdown_files/1810.04805v2.md +0 -0
  125. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding/markdown_files/rfc8259.md +0 -0
  126. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding_qdrant/.env +0 -0
  127. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding_qdrant/README.md +0 -0
  128. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding_qdrant/main.py +0 -0
  129. {cocoindex-0.1.32 → cocoindex-0.1.33}/examples/text_embedding_qdrant/markdown_files/rfc8259.md +0 -0
  130. {cocoindex-0.1.32 → cocoindex-0.1.33}/pyproject.toml +0 -0
  131. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/auth_registry.py +0 -0
  132. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/cli.py +0 -0
  133. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/convert.py +0 -0
  134. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/flow.py +0 -0
  135. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/functions.py +0 -0
  136. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/index.py +0 -0
  137. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/lib.py +0 -0
  138. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/llm.py +0 -0
  139. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/op.py +0 -0
  140. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/py.typed +0 -0
  141. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/query.py +0 -0
  142. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/runtime.py +0 -0
  143. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/setting.py +0 -0
  144. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/setup.py +0 -0
  145. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/sources.py +0 -0
  146. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/storages.py +0 -0
  147. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/tests/__init__.py +0 -0
  148. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/tests/test_convert.py +0 -0
  149. {cocoindex-0.1.32 → cocoindex-0.1.33}/python/cocoindex/typing.py +0 -0
  150. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/base/field_attrs.rs +0 -0
  151. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/base/json_schema.rs +0 -0
  152. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/base/mod.rs +0 -0
  153. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/base/schema.rs +0 -0
  154. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/base/spec.rs +0 -0
  155. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/base/value.rs +0 -0
  156. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/builder/analyzed_flow.rs +0 -0
  157. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/builder/analyzer.rs +0 -0
  158. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/builder/flow_builder.rs +0 -0
  159. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/builder/mod.rs +0 -0
  160. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/builder/plan.rs +0 -0
  161. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/db_tracking.rs +0 -0
  162. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/db_tracking_setup.rs +0 -0
  163. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/dumper.rs +0 -0
  164. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/evaluator.rs +0 -0
  165. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/live_updater.rs +0 -0
  166. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/memoization.rs +0 -0
  167. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/mod.rs +0 -0
  168. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/query.rs +0 -0
  169. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/row_indexer.rs +0 -0
  170. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/source_indexer.rs +0 -0
  171. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/execution/stats.rs +0 -0
  172. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/lib.rs +0 -0
  173. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/lib_context.rs +0 -0
  174. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/llm/anthropic.rs +0 -0
  175. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/llm/gemini.rs +0 -0
  176. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/llm/mod.rs +0 -0
  177. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/llm/ollama.rs +0 -0
  178. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/llm/openai.rs +0 -0
  179. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/factory_bases.rs +0 -0
  180. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/functions/extract_by_llm.rs +0 -0
  181. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/functions/mod.rs +0 -0
  182. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/functions/parse_json.rs +0 -0
  183. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/functions/split_recursively.rs +0 -0
  184. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/interface.rs +0 -0
  185. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/mod.rs +0 -0
  186. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/py_factory.rs +0 -0
  187. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/registration.rs +0 -0
  188. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/registry.rs +0 -0
  189. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/sdk.rs +0 -0
  190. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/sources/google_drive.rs +0 -0
  191. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/sources/local_file.rs +0 -0
  192. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/sources/mod.rs +0 -0
  193. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/storages/mod.rs +0 -0
  194. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/storages/neo4j.rs +0 -0
  195. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/storages/postgres.rs +0 -0
  196. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/ops/storages/spec.rs +0 -0
  197. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/prelude.rs +0 -0
  198. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/py/convert.rs +0 -0
  199. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/py/mod.rs +0 -0
  200. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/server.rs +0 -0
  201. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/service/error.rs +0 -0
  202. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/service/flows.rs +0 -0
  203. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/service/mod.rs +0 -0
  204. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/service/search.rs +0 -0
  205. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/settings.rs +0 -0
  206. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/setup/auth_registry.rs +0 -0
  207. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/setup/components.rs +0 -0
  208. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/setup/db_metadata.rs +0 -0
  209. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/setup/driver.rs +0 -0
  210. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/setup/mod.rs +0 -0
  211. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/setup/states.rs +0 -0
  212. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/utils/db.rs +0 -0
  213. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/utils/fingerprint.rs +0 -0
  214. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/utils/immutable.rs +0 -0
  215. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/utils/mod.rs +0 -0
  216. {cocoindex-0.1.32 → cocoindex-0.1.33}/src/utils/retriable.rs +0 -0
@@ -533,7 +533,7 @@ dependencies = [
533
533
 
534
534
  [[package]]
535
535
  name = "cocoindex"
536
- version = "0.1.32"
536
+ version = "0.1.33"
537
537
  dependencies = [
538
538
  "anyhow",
539
539
  "async-openai",
@@ -2,10 +2,13 @@
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.32"
5
+ version = "0.1.33"
6
6
  edition = "2021"
7
7
 
8
- # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8
+ [profile.release]
9
+ codegen-units = 1
10
+ lto = true
11
+
9
12
  [lib]
10
13
  name = "cocoindex_engine"
11
14
  crate-type = ["cdylib"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cocoindex
3
- Version: 0.1.32
3
+ Version: 0.1.33
4
4
  Requires-Dist: sentence-transformers>=3.3.1
5
5
  Requires-Dist: click>=8.1.8
6
6
  Requires-Dist: rich>=14.0.0
@@ -120,6 +120,7 @@ Go to the [examples directory](examples) to try out with any of the examples, fo
120
120
  | [Google Drive Text Embedding](examples/gdrive_text_embedding) | Index text documents from Google Drive |
121
121
  | [Docs to Knowledge Graph](examples/docs_to_knowledge_graph) | Extract relationships from Markdown documents and build a knowledge graph |
122
122
  | [Embeddings to Qdrant](examples/text_embedding_qdrant) | Index documents in a Qdrant collection for semantic search |
123
+ | [FastAPI Server with Docker](examples/fastapi_server_docker) | Run the semantic search server in a Dockerized FastAPI setup |
123
124
 
124
125
  More coming and stay tuned! If there's any specific examples you would like to see, please let us know in our [Discord community](https://discord.com/invite/zpA9S2DR7s) 🌱.
125
126
 
@@ -104,6 +104,7 @@ Go to the [examples directory](examples) to try out with any of the examples, fo
104
104
  | [Google Drive Text Embedding](examples/gdrive_text_embedding) | Index text documents from Google Drive |
105
105
  | [Docs to Knowledge Graph](examples/docs_to_knowledge_graph) | Extract relationships from Markdown documents and build a knowledge graph |
106
106
  | [Embeddings to Qdrant](examples/text_embedding_qdrant) | Index documents in a Qdrant collection for semantic search |
107
+ | [FastAPI Server with Docker](examples/fastapi_server_docker) | Run the semantic search server in a Dockerized FastAPI setup |
107
108
 
108
109
  More coming and stay tuned! If there's any specific examples you would like to see, please let us know in our [Discord community](https://discord.com/invite/zpA9S2DR7s) 🌱.
109
110
 
@@ -3,4 +3,4 @@ name = "code-embedding"
3
3
  version = "0.1.0"
4
4
  description = "Simple example for cocoindex: build embedding index based on source code."
5
5
  requires-python = ">=3.10"
6
- dependencies = ["cocoindex>=0.1.30", "python-dotenv>=1.0.1"]
6
+ dependencies = ["cocoindex>=0.1.32", "python-dotenv>=1.0.1"]
@@ -3,4 +3,4 @@ name = "manuals-to-kg"
3
3
  version = "0.1.0"
4
4
  description = "Simple example for cocoindex: extract triples from files and build knowledge graph."
5
5
  requires-python = ">=3.10"
6
- dependencies = ["cocoindex>=0.1.30", "python-dotenv>=1.0.1"]
6
+ dependencies = ["cocoindex>=0.1.32", "python-dotenv>=1.0.1"]
@@ -0,0 +1,2 @@
1
+ .venv
2
+ __pycache__
@@ -0,0 +1 @@
1
+ COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@coco_db:5432/cocoindex
@@ -0,0 +1,10 @@
1
+ ## Run cocoindex docker container with a simple query endpoint via fastapi
2
+ In this example, we provide a simple docker container using docker compose to build pgvector17 along with a simple python fastapi script than runs a simple query endpoint. This example uses the code from the code embedding example.
3
+
4
+ ## How to run
5
+ Edit the sample code directory to include the code you want to query over in
6
+ ```sample_code/```
7
+
8
+ Edit the configuration code from the file ```src/cocoindex_funs.py``` line 23 to 25.
9
+
10
+ Finally build the docker container via: ```docker compose up``` while inside the directory of the example.
@@ -0,0 +1,18 @@
1
+ services:
2
+ coco_db:
3
+ image: pgvector/pgvector:pg17
4
+ restart: always
5
+ environment:
6
+ POSTGRES_USER: cocoindex
7
+ POSTGRES_PASSWORD: cocoindex
8
+ POSTGRES_DB: cocoindex
9
+ ports:
10
+ - "5432:5432"
11
+
12
+ coco_api:
13
+ build:
14
+ context: .
15
+ ports:
16
+ - 8080:8080
17
+ depends_on:
18
+ - coco_db
@@ -0,0 +1,13 @@
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+
7
+ RUN pip install -r requirements.txt
8
+
9
+ COPY . .
10
+
11
+ RUN cat .env
12
+
13
+ CMD ["sh", "-c", "echo yes | python main.py cocoindex setup && python main.py cocoindex update && python main.py"]
@@ -0,0 +1,30 @@
1
+ import cocoindex
2
+ import uvicorn
3
+
4
+ from fastapi import FastAPI
5
+ from dotenv import load_dotenv
6
+
7
+ from src.cocoindex_funs import code_embedding_flow, code_to_embedding
8
+
9
+ fastapi_app = FastAPI()
10
+
11
+ query_handler = cocoindex.query.SimpleSemanticsQueryHandler(
12
+ name="SemanticsSearch",
13
+ flow=code_embedding_flow,
14
+ target_name="code_embeddings",
15
+ query_transform_flow=code_to_embedding,
16
+ default_similarity_metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY
17
+ )
18
+
19
+ @fastapi_app.get("/query")
20
+ def query_endpoint(string: str):
21
+ results, _ = query_handler.search(string, 10)
22
+ return results
23
+
24
+ @cocoindex.main_fn()
25
+ def _run():
26
+ uvicorn.run(fastapi_app, host="0.0.0.0", port=8080)
27
+
28
+ if __name__ == "__main__":
29
+ load_dotenv(override=True)
30
+ _run()
@@ -0,0 +1,5 @@
1
+ cocoindex>=0.1.26
2
+ python-dotenv>=1.0.1
3
+ fastapi==0.115.12
4
+ fastapi-cli==0.0.7
5
+ uvicorn==0.34.2
@@ -0,0 +1,113 @@
1
+ class Button:
2
+ def __init__(self, label, on_click):
3
+ self.label = label
4
+ self.on_click = on_click
5
+
6
+ def click(self):
7
+ print(f"Button '{self.label}' clicked.")
8
+ if callable(self.on_click):
9
+ self.on_click()
10
+
11
+
12
+ class ProgressBar:
13
+ def __init__(self, max_value):
14
+ self.max_value = max_value
15
+ self.current_value = 0
16
+
17
+ def update(self, value):
18
+ self.current_value = min(value, self.max_value)
19
+ self.display()
20
+
21
+ def display(self):
22
+ percent = (self.current_value / self.max_value) * 100
23
+ print(f"Progress: {percent:.2f}%")
24
+
25
+
26
+ class Slider:
27
+ def __init__(self, min_value, max_value, initial_value=None):
28
+ self.min_value = min_value
29
+ self.max_value = max_value
30
+ self.value = initial_value if initial_value is not None else min_value
31
+
32
+ def set_value(self, new_value):
33
+ if self.min_value <= new_value <= self.max_value:
34
+ self.value = new_value
35
+ print(f"Slider set to {self.value}")
36
+ else:
37
+ print("Value out of range.")
38
+
39
+
40
+ class Dropdown:
41
+ def __init__(self, options):
42
+ self.options = options
43
+ self.selected = None
44
+
45
+ def select(self, option):
46
+ if option in self.options:
47
+ self.selected = option
48
+ print(f"Dropdown selected: {option}")
49
+ else:
50
+ print("Option not available.")
51
+
52
+
53
+ class TextField:
54
+ def __init__(self, placeholder=''):
55
+ self.placeholder = placeholder
56
+ self.text = ''
57
+
58
+ def input(self, new_text):
59
+ self.text = new_text
60
+ print(f"Text field updated: {self.text}")
61
+
62
+
63
+ class Checkbox:
64
+ def __init__(self, label):
65
+ self.label = label
66
+ self.checked = False
67
+
68
+ def toggle(self):
69
+ self.checked = not self.checked
70
+ print(f"{self.label}: {'Checked' if self.checked else 'Unchecked'}")
71
+
72
+
73
+ class RadioButton:
74
+ def __init__(self, group, label):
75
+ self.group = group
76
+ self.label = label
77
+ self.selected = False
78
+
79
+ def select(self):
80
+ self.selected = True
81
+ print(f"Radio button '{self.label}' selected in group '{self.group}'.")
82
+
83
+
84
+ class ToggleSwitch:
85
+ def __init__(self, state=False):
86
+ self.state = state
87
+
88
+ def toggle(self):
89
+ self.state = not self.state
90
+ print(f"ToggleSwitch is now {'On' if self.state else 'Off'}")
91
+
92
+
93
+ class Tooltip:
94
+ def __init__(self, text):
95
+ self.text = text
96
+
97
+ def show(self):
98
+ print(f"Tooltip: {self.text}")
99
+
100
+
101
+ class Modal:
102
+ def __init__(self, content):
103
+ self.content = content
104
+ self.visible = False
105
+
106
+ def open(self):
107
+ self.visible = True
108
+ print("Modal opened.")
109
+ print(f"Content: {self.content}")
110
+
111
+ def close(self):
112
+ self.visible = False
113
+ print("Modal closed.")
@@ -0,0 +1,45 @@
1
+ import cocoindex
2
+ import os
3
+
4
+ @cocoindex.op.function()
5
+ def extract_extension(filename: str) -> str:
6
+ """Extract the extension of a filename."""
7
+ return os.path.splitext(filename)[1]
8
+
9
+ def code_to_embedding(text: cocoindex.DataSlice) -> cocoindex.DataSlice:
10
+ """
11
+ Embed the text using a SentenceTransformer model.
12
+ """
13
+ return text.transform(
14
+ cocoindex.functions.SentenceTransformerEmbed(
15
+ model="sentence-transformers/all-MiniLM-L6-v2"))
16
+
17
+ @cocoindex.flow_def(name="CodeEmbedding")
18
+ def code_embedding_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope):
19
+ """
20
+ Define an example flow that embeds files into a vector database.
21
+ """
22
+ data_scope["files"] = flow_builder.add_source(
23
+ cocoindex.sources.LocalFile(path="sample_code",
24
+ included_patterns=["*.py", "*.rs", "*.toml", "*.md", "*.mdx", "*.ts", "*.tsx"],
25
+ excluded_patterns=[".*", "target", "**/node_modules"]))
26
+ code_embeddings = data_scope.add_collector()
27
+
28
+ with data_scope["files"].row() as file:
29
+ file["extension"] = file["filename"].transform(extract_extension)
30
+ file["chunks"] = file["content"].transform(
31
+ cocoindex.functions.SplitRecursively(),
32
+ language=file["extension"], chunk_size=1000, chunk_overlap=300)
33
+ with file["chunks"].row() as chunk:
34
+ chunk["embedding"] = chunk["text"].call(code_to_embedding)
35
+ code_embeddings.collect(filename=file["filename"], location=chunk["location"],
36
+ code=chunk["text"], embedding=chunk["embedding"])
37
+
38
+ code_embeddings.export(
39
+ "code_embeddings",
40
+ cocoindex.storages.Postgres(),
41
+ primary_key_fields=["filename", "location"],
42
+ vector_indexes=[
43
+ cocoindex.VectorIndexDef(
44
+ field_name="embedding",
45
+ metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY)])
@@ -3,4 +3,4 @@ name = "gdrive-text-embedding"
3
3
  version = "0.1.0"
4
4
  description = "Simple example for cocoindex: build embedding index based on Google Drive files."
5
5
  requires-python = ">=3.11"
6
- dependencies = ["cocoindex>=0.1.30", "python-dotenv>=1.0.1"]
6
+ dependencies = ["cocoindex>=0.1.32", "python-dotenv>=1.0.1"]
@@ -4,7 +4,7 @@ version = "0.1.0"
4
4
  description = "Simple example for cocoindex: extract structured information from a Markdown file using LLM."
5
5
  requires-python = ">=3.10"
6
6
  dependencies = [
7
- "cocoindex>=0.1.30",
7
+ "cocoindex>=0.1.32",
8
8
  "python-dotenv>=1.0.1",
9
9
  "marker-pdf>=1.5.2",
10
10
  ]
@@ -4,7 +4,7 @@ version = "0.1.0"
4
4
  description = "Simple example for cocoindex: build embedding index based on local PDF files."
5
5
  requires-python = ">=3.10"
6
6
  dependencies = [
7
- "cocoindex>=0.1.30",
7
+ "cocoindex>=0.1.32",
8
8
  "python-dotenv>=1.0.1",
9
9
  "marker-pdf>=1.5.2",
10
10
  ]
@@ -0,0 +1,3 @@
1
+ # Postgres database address for cocoindex
2
+ COCOINDEX_DATABASE_URL=postgres://cocoindex:cocoindex@localhost/cocoindex
3
+
@@ -0,0 +1,66 @@
1
+ # Build Real-Time Product Recommendation based on LLM Taxonomy Extraction and Knowledge Graph
2
+
3
+ We will process a list of products and use LLM to extract the taxonomy and complimentary taxonomy for each product.
4
+
5
+ Please drop [CocoIndex on Github](https://github.com/cocoindex-io/cocoindex) a star to support us and stay tuned for more updates. Thank you so much 🥥🤗. [![GitHub](https://img.shields.io/github/stars/cocoindex-io/cocoindex?color=5B5BD6)](https://github.com/cocoindex-io/cocoindex)
6
+
7
+
8
+ ## Prerequisite
9
+ * [Install Postgres](https://cocoindex.io/docs/getting_started/installation#-install-postgres) if you don't have one.
10
+ * [Install Neo4j](https://cocoindex.io/docs/ops/storages#neo4j) if you don't have one.
11
+ * [Configure your OpenAI API key](https://cocoindex.io/docs/ai/llm#openai).
12
+
13
+ ## Documentation
14
+ You can read the official CocoIndex Documentation for Property Graph Targets [here](https://cocoindex.io/docs/ops/storages#property-graph-targets).
15
+
16
+ ## Run
17
+
18
+ ### Build the index
19
+
20
+ Install dependencies:
21
+
22
+ ```bash
23
+ pip install -e .
24
+ ```
25
+
26
+ Setup:
27
+
28
+ ```bash
29
+ python main.py cocoindex setup
30
+ ```
31
+
32
+ Update index:
33
+
34
+ ```bash
35
+ python main.py cocoindex update
36
+ ```
37
+
38
+ ### Browse the knowledge graph
39
+
40
+ After the knowledge graph is built, you can explore the knowledge graph you built in Neo4j Browser.
41
+
42
+ For the dev enviroment, you can connect neo4j browser using credentials:
43
+ - username: `neo4j`
44
+ - password: `cocoindex`
45
+ which is pre-configured in the our docker compose [config.yaml](https://raw.githubusercontent.com/cocoindex-io/cocoindex/refs/heads/main/dev/neo4j.yaml).
46
+
47
+ You can open it at [http://localhost:7474](http://localhost:7474), and run the following Cypher query to get all relationships:
48
+
49
+ ```cypher
50
+ MATCH p=()-->() RETURN p
51
+ ```
52
+ ![Neo4j Browser Screenshot](img/neo4j.png)
53
+
54
+ ## CocoInsight
55
+ I used CocoInsight (Free beta now) to troubleshoot the index generation and understand the data lineage of the pipeline.
56
+ It just connects to your local CocoIndex server, with Zero pipeline data retention. Run following command to start CocoInsight:
57
+
58
+ ```bash
59
+ python main.py cocoindex server -ci
60
+ ```
61
+
62
+ And then open the url https://cocoindex.io/cocoinsight.
63
+
64
+ ![CocoInsight Screenshot](img/cocoinsight.png)
65
+
66
+
@@ -0,0 +1,185 @@
1
+ """
2
+ This example shows how to extract relationships from Markdown documents and build a knowledge graph.
3
+ """
4
+ import dataclasses
5
+ import datetime
6
+ from dotenv import load_dotenv
7
+ import cocoindex
8
+ from jinja2 import Template
9
+
10
+ # Template for rendering product information as markdown to provide information to LLMs
11
+ PRODUCT_TEMPLATE = """
12
+ # {{ title }}
13
+
14
+ ## Highlights
15
+ {% for highlight in highlights %}
16
+ - {{ highlight }}
17
+ {% endfor %}
18
+
19
+ ## Description
20
+ {{ description.header | default('') }}
21
+ {{ description.paragraph | default('') }}
22
+ {% for bullet in description.bullets %}
23
+
24
+ - {{ bullet }}
25
+ {% endfor %}
26
+
27
+ """
28
+
29
+ @dataclasses.dataclass
30
+ class ProductInfo:
31
+ id: str
32
+ title: str
33
+ price: float
34
+ detail: str
35
+
36
+ @dataclasses.dataclass
37
+ class ProductTaxonomy:
38
+ """
39
+ Taxonomy for the product.
40
+
41
+ A taxonomy is a concise noun (or short noun phrase), based on its core functionality, without specific details such as branding, style, etc.
42
+
43
+ Always use the most common words in US English.
44
+
45
+ Use lowercase without punctuation, unless it's a proper noun or acronym.
46
+
47
+ A product may have multiple taxonomies. Avoid large categories like "office supplies" or "electronics". Use specific ones, like "pen" or "printer".
48
+ """
49
+ name: str
50
+
51
+ @dataclasses.dataclass
52
+ class ProductTaxonomyInfo:
53
+ """
54
+ Taxonomy information for the product.
55
+
56
+ Fields:
57
+ - taxonomies: Taxonomies for the current product.
58
+ - complementary_taxonomies: Think about when customers buy this product, what else they might need as complementary products. Put labels for these complentary products.
59
+ """
60
+ taxonomies: list[ProductTaxonomy]
61
+ complementary_taxonomies: list[ProductTaxonomy]
62
+
63
+ @cocoindex.op.function(behavior_version=2)
64
+ def extract_product_info(product: cocoindex.typing.Json, filename: str) -> ProductInfo:
65
+ # Print markdown for LLM to extract the taxonomy and complimentary taxonomy
66
+ return ProductInfo(
67
+ id=f"{filename.removesuffix('.json')}",
68
+ title=product["title"],
69
+ price=float(product["price"].lstrip("$").replace(",", "")),
70
+ detail=Template(PRODUCT_TEMPLATE).render(**product),
71
+ )
72
+
73
+
74
+ @cocoindex.flow_def(name="StoreProduct")
75
+ def store_product_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope):
76
+ """
77
+ Define an example flow that extracts triples from files and build knowledge graph.
78
+ """
79
+ data_scope["products"] = flow_builder.add_source(
80
+ cocoindex.sources.LocalFile(path="products",
81
+ included_patterns=["*.json"]),
82
+ refresh_interval=datetime.timedelta(seconds=5))
83
+
84
+ product_node = data_scope.add_collector()
85
+ product_taxonomy = data_scope.add_collector()
86
+ product_complementary_taxonomy = data_scope.add_collector()
87
+
88
+
89
+ with data_scope["products"].row() as product:
90
+ data = (product["content"].transform(cocoindex.functions.ParseJson(), language="json")
91
+ .transform(extract_product_info, filename=product["filename"]))
92
+ taxonomy = data["detail"].transform(cocoindex.functions.ExtractByLlm(
93
+ llm_spec=cocoindex.LlmSpec(
94
+ api_type=cocoindex.LlmApiType.OPENAI, model="gpt-4.1"),
95
+ output_type=ProductTaxonomyInfo))
96
+
97
+ product_node.collect(id=data["id"], title=data["title"], price=data["price"])
98
+ with taxonomy['taxonomies'].row() as t:
99
+ product_taxonomy.collect(id=cocoindex.GeneratedField.UUID, product_id=data["id"], taxonomy=t["name"])
100
+ with taxonomy['complementary_taxonomies'].row() as t:
101
+ product_complementary_taxonomy.collect(id=cocoindex.GeneratedField.UUID, product_id=data["id"], taxonomy=t["name"])
102
+
103
+
104
+
105
+ conn_spec = cocoindex.add_auth_entry(
106
+ "Neo4jConnection",
107
+ cocoindex.storages.Neo4jConnection(
108
+ uri="bolt://localhost:7687",
109
+ user="neo4j",
110
+ password="cocoindex",
111
+ ))
112
+
113
+ product_node.export(
114
+ "product_node",
115
+ cocoindex.storages.Neo4j(
116
+ connection=conn_spec,
117
+ mapping=cocoindex.storages.Nodes(label="Product")
118
+ ),
119
+ primary_key_fields=["id"],
120
+ )
121
+
122
+ flow_builder.declare(
123
+ cocoindex.storages.Neo4jDeclaration(
124
+ connection=conn_spec,
125
+ nodes_label="Taxonomy",
126
+ primary_key_fields=["value"],
127
+ )
128
+ )
129
+
130
+ product_taxonomy.export(
131
+ "product_taxonomy",
132
+ cocoindex.storages.Neo4j(
133
+ connection=conn_spec,
134
+ mapping=cocoindex.storages.Relationships(
135
+ rel_type="PRODUCT_TAXONOMY",
136
+ source=cocoindex.storages.NodeFromFields(
137
+ label="Product",
138
+ fields=[
139
+ cocoindex.storages.TargetFieldMapping(
140
+ source="product_id", target="id"),
141
+ ]
142
+ ),
143
+ target=cocoindex.storages.NodeFromFields(
144
+ label="Taxonomy",
145
+ fields=[
146
+ cocoindex.storages.TargetFieldMapping(
147
+ source="taxonomy", target="value"),
148
+ ]
149
+ ),
150
+ ),
151
+ ),
152
+ primary_key_fields=["id"],
153
+ )
154
+ product_complementary_taxonomy.export(
155
+ "product_complementary_taxonomy",
156
+ cocoindex.storages.Neo4j(
157
+ connection=conn_spec,
158
+ mapping=cocoindex.storages.Relationships(
159
+ rel_type="PRODUCT_COMPLEMENTARY_TAXONOMY",
160
+ source=cocoindex.storages.NodeFromFields(
161
+ label="Product",
162
+ fields=[
163
+ cocoindex.storages.TargetFieldMapping(
164
+ source="product_id", target="id"),
165
+ ]
166
+ ),
167
+ target=cocoindex.storages.NodeFromFields(
168
+ label="Taxonomy",
169
+ fields=[
170
+ cocoindex.storages.TargetFieldMapping(
171
+ source="taxonomy", target="value"),
172
+ ]
173
+ ),
174
+ ),
175
+ ),
176
+ primary_key_fields=["id"],
177
+ )
178
+
179
+ @cocoindex.main_fn()
180
+ def _run():
181
+ pass
182
+
183
+ if __name__ == "__main__":
184
+ load_dotenv(override=True)
185
+ _run()
@@ -0,0 +1,22 @@
1
+ {
2
+ "title": "Pilot G2 Premium Gel Roller Pens, Fine Point, 0.7mm, Black Ink, 2/Pack",
3
+ "price": "$4.99",
4
+ "highlights": [
5
+ "Smooth-writing gel ink for effortless note-taking.",
6
+ "Comfortable rubber grip for long study sessions.",
7
+ "Refillable design reduces waste and saves money."
8
+ ],
9
+ "description": {
10
+ "header": "Take your writing to the next level with this 2-pack of Pilot G2 Premium Gel Roller Pens.",
11
+ "paragraph": "Engineered for precision and comfort, these pens are ideal for students who need reliability during long lectures and study marathons. The gel ink delivers bold, smooth lines while the ergonomic grip reduces writing fatigue.",
12
+ "bullets": [
13
+ "Smooth-writing gel ink for effortless note-taking.",
14
+ "Fine 0.7mm tip for precise lines and detailed writing.",
15
+ "Comfortable contoured rubber grip for extended use.",
16
+ "Refillable design for long-term value.",
17
+ "Sleek black barrel with visible ink supply.",
18
+ "Includes 2 black ink pens.",
19
+ "Ideal for students, professionals, and everyday writing tasks."
20
+ ]
21
+ }
22
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "title": "Multi-Purpose Paper, 8.5\" x 11\", 20 lbs., 92 Bright, 500 Sheets/Ream, White (SPLMPP500)",
3
+ "price": "$6.99",
4
+ "highlights": [
5
+ "Ideal for everyday printing and writing needs.",
6
+ "Compatible with laser printers, inkjet printers, and copiers.",
7
+ "Smooth surface ensures sharp text and vibrant images."
8
+ ],
9
+ "description": {
10
+ "header": "Print crisp documents with this 500-sheet ream of Staples multi-purpose paper.",
11
+ "paragraph": "This versatile white paper delivers reliable performance for a wide variety of printing and writing tasks. Whether you're preparing professional reports or everyday notes, the 92 brightness rating ensures high contrast and readability.",
12
+ "bullets": [
13
+ "20 lb. weight for standard document printing and copying.",
14
+ "8.5\" x 11\" letter size for everyday use.",
15
+ "92 brightness rating offers crisp, clear print results.",
16
+ "Compatible with laser printers, inkjet printers, and copiers.",
17
+ "Acid-free paper prevents yellowing over time.",
18
+ "Ideal for memos, reports, drafts, and more.",
19
+ "500 sheets per ream for bulk efficiency."
20
+ ]
21
+ }
22
+ }