milvus-haystack 0.0.4__tar.gz → 0.0.6__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.
@@ -6,6 +6,7 @@ on:
6
6
  - "src/**"
7
7
  - "tests/**"
8
8
  - pyproject.toml
9
+ - .github/workflows/test.yml
9
10
 
10
11
  concurrency:
11
12
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -17,7 +18,7 @@ jobs:
17
18
  runs-on: ubuntu-latest
18
19
  strategy:
19
20
  matrix:
20
- python-version: ['3.9']
21
+ python-version: [ '3.9' ]
21
22
 
22
23
  steps:
23
24
  - name: Checkout code
@@ -34,5 +35,17 @@ jobs:
34
35
  - name: Lint
35
36
  run: hatch run lint:all
36
37
 
37
- - name: Run tests
38
+ - name: Run Milvus
39
+ run: |
40
+ wget https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh
41
+ bash standalone_embed.sh start
42
+ sleep 5
43
+ echo "\nMilvus server started!"
44
+
45
+ - name: Run tests
38
46
  run: hatch run cov
47
+
48
+ - name: Stop and Remove Milvus
49
+ run: |
50
+ bash standalone_embed.sh stop
51
+ echo "\nMilvus server stopped and removed!"
@@ -0,0 +1,172 @@
1
+ Metadata-Version: 2.3
2
+ Name: milvus-haystack
3
+ Version: 0.0.6
4
+ Project-URL: Documentation, https://github.com/milvus-io/milvus-haystack#readme
5
+ Project-URL: Issues, https://github.com/milvus-io/milvus-haystack/issues
6
+ Project-URL: Source, https://github.com/milvus-io/milvus-haystack
7
+ Author-email: Zilliz <support@zilliz.com>
8
+ License-Expression: Apache-2.0
9
+ License-File: LICENSE.txt
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: Implementation :: CPython
18
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
19
+ Requires-Python: >=3.7
20
+ Requires-Dist: haystack-ai
21
+ Requires-Dist: pymilvus
22
+ Requires-Dist: typing-extensions
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Milvus Document Store for Haystack
26
+
27
+ [![PyPI - Version](https://img.shields.io/pypi/v/milvus-haystack.svg)](https://pypi.org/project/milvus-haystack)
28
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/milvus-haystack.svg)](https://pypi.org/project/milvus-haystack)
29
+
30
+ ## Installation
31
+
32
+ ```shell
33
+ pip install --upgrade pymilvus milvus-haystack
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ By default, if you install the latest version of pymilvus, you don't need to start the milvus service manually.
39
+ Optionally, you
40
+ can [start the Milvus service by docker](https://milvus.io/docs/install_standalone-docker.md#Start-Milvus).
41
+
42
+ Use the `MilvusDocumentStore` in a Haystack pipeline as a quick start.
43
+
44
+ ```python
45
+ from haystack import Document
46
+ from milvus_haystack import MilvusDocumentStore
47
+
48
+ document_store = MilvusDocumentStore(
49
+ # If you have installed the latest version of pymilvus with milvus lite, you can use a local path as the uri without starting the milvus service.
50
+ connection_args={"uri": "./milvus.db"},
51
+ # Or, if you have started the milvus standalone service by docker, you can use the specified uri to connect to the service.
52
+ # connection_args={"uri": "http://localhost:19530"},
53
+ drop_old=True,
54
+ )
55
+ documents = [Document(
56
+ content="A Foo Document",
57
+ meta={"page": "100", "chapter": "intro"},
58
+ embedding=[-10.0] * 128,
59
+ )]
60
+ document_store.write_documents(documents)
61
+ print(document_store.count_documents()) # 1
62
+ ```
63
+
64
+ ## Dive deep usage
65
+
66
+ Prepare an OpenAI API key and set it as an environment variable:
67
+
68
+ ```shell
69
+ export OPENAI_API_KEY=<your_api_key>
70
+ ```
71
+
72
+ Here are the ways to
73
+
74
+ - Create the indexing Pipeline
75
+ - Create the retrieval pipeline
76
+ - Create the RAG pipeline
77
+
78
+ ### Create the indexing Pipeline and index some documents
79
+
80
+ ```python
81
+ import glob
82
+ import os
83
+
84
+ from haystack import Pipeline
85
+ from haystack.components.converters import MarkdownToDocument
86
+ from haystack.components.embedders import OpenAIDocumentEmbedder, OpenAITextEmbedder
87
+ from haystack.components.preprocessors import DocumentSplitter
88
+ from haystack.components.writers import DocumentWriter
89
+
90
+ from milvus_haystack import MilvusDocumentStore
91
+ from milvus_haystack.milvus_embedding_retriever import MilvusEmbeddingRetriever
92
+
93
+ current_file_path = os.path.abspath(__file__)
94
+ file_paths = [current_file_path] # You can replace it with your own file paths.
95
+
96
+ document_store = MilvusDocumentStore(
97
+ # If you have installed the latest version of pymilvus with milvus lite, you can use a local path as the uri without starting the milvus service.
98
+ connection_args={"uri": "./milvus.db"},
99
+ # Or, if you have started the milvus standalone service by docker, you can use the specified uri to connect to the service.
100
+ # connection_args={"uri": "http://localhost:19530"},
101
+ drop_old=True,
102
+ )
103
+ indexing_pipeline = Pipeline()
104
+ indexing_pipeline.add_component("converter", MarkdownToDocument())
105
+ indexing_pipeline.add_component("splitter", DocumentSplitter(split_by="sentence", split_length=2))
106
+ indexing_pipeline.add_component("embedder", OpenAIDocumentEmbedder())
107
+ indexing_pipeline.add_component("writer", DocumentWriter(document_store))
108
+ indexing_pipeline.connect("converter", "splitter")
109
+ indexing_pipeline.connect("splitter", "embedder")
110
+ indexing_pipeline.connect("embedder", "writer")
111
+ indexing_pipeline.run({"converter": {"sources": file_paths}})
112
+
113
+ print("Number of documents:", document_store.count_documents())
114
+ ```
115
+
116
+ ### Create the retrieval pipeline and try a query
117
+
118
+ ```python
119
+ question = "How to set the service uri with milvus lite?" # You can replace it with your own question.
120
+
121
+ retrieval_pipeline = Pipeline()
122
+ retrieval_pipeline.add_component("embedder", OpenAITextEmbedder())
123
+ retrieval_pipeline.add_component("retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3))
124
+ retrieval_pipeline.connect("embedder", "retriever")
125
+
126
+ retrieval_results = retrieval_pipeline.run({"embedder": {"text": question}})
127
+
128
+ for doc in retrieval_results["retriever"]["documents"]:
129
+ print(doc.content)
130
+ print("-" * 10)
131
+ ```
132
+
133
+ ### Create the RAG pipeline and try a query
134
+
135
+ ```python
136
+ from haystack.utils import Secret
137
+ from haystack.components.builders import PromptBuilder
138
+ from haystack.components.generators import OpenAIGenerator
139
+
140
+ prompt_template = """Answer the following query based on the provided context. If the context does
141
+ not include an answer, reply with 'I don't know'.\n
142
+ Query: {{query}}
143
+ Documents:
144
+ {% for doc in documents %}
145
+ {{ doc.content }}
146
+ {% endfor %}
147
+ Answer:
148
+ """
149
+
150
+ rag_pipeline = Pipeline()
151
+ rag_pipeline.add_component("text_embedder", OpenAITextEmbedder())
152
+ rag_pipeline.add_component("retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3))
153
+ rag_pipeline.add_component("prompt_builder", PromptBuilder(template=prompt_template))
154
+ rag_pipeline.add_component("generator", OpenAIGenerator(api_key=Secret.from_token(os.getenv("OPENAI_API_KEY")),
155
+ generation_kwargs={"temperature": 0}))
156
+ rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
157
+ rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
158
+ rag_pipeline.connect("prompt_builder", "generator")
159
+
160
+ results = rag_pipeline.run(
161
+ {
162
+ "text_embedder": {"text": question},
163
+ "prompt_builder": {"query": question},
164
+ }
165
+ )
166
+ print('RAG answer:', results["generator"]["replies"][0])
167
+
168
+ ```
169
+
170
+ ## License
171
+
172
+ `milvus-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -0,0 +1,148 @@
1
+ # Milvus Document Store for Haystack
2
+
3
+ [![PyPI - Version](https://img.shields.io/pypi/v/milvus-haystack.svg)](https://pypi.org/project/milvus-haystack)
4
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/milvus-haystack.svg)](https://pypi.org/project/milvus-haystack)
5
+
6
+ ## Installation
7
+
8
+ ```shell
9
+ pip install --upgrade pymilvus milvus-haystack
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ By default, if you install the latest version of pymilvus, you don't need to start the milvus service manually.
15
+ Optionally, you
16
+ can [start the Milvus service by docker](https://milvus.io/docs/install_standalone-docker.md#Start-Milvus).
17
+
18
+ Use the `MilvusDocumentStore` in a Haystack pipeline as a quick start.
19
+
20
+ ```python
21
+ from haystack import Document
22
+ from milvus_haystack import MilvusDocumentStore
23
+
24
+ document_store = MilvusDocumentStore(
25
+ # If you have installed the latest version of pymilvus with milvus lite, you can use a local path as the uri without starting the milvus service.
26
+ connection_args={"uri": "./milvus.db"},
27
+ # Or, if you have started the milvus standalone service by docker, you can use the specified uri to connect to the service.
28
+ # connection_args={"uri": "http://localhost:19530"},
29
+ drop_old=True,
30
+ )
31
+ documents = [Document(
32
+ content="A Foo Document",
33
+ meta={"page": "100", "chapter": "intro"},
34
+ embedding=[-10.0] * 128,
35
+ )]
36
+ document_store.write_documents(documents)
37
+ print(document_store.count_documents()) # 1
38
+ ```
39
+
40
+ ## Dive deep usage
41
+
42
+ Prepare an OpenAI API key and set it as an environment variable:
43
+
44
+ ```shell
45
+ export OPENAI_API_KEY=<your_api_key>
46
+ ```
47
+
48
+ Here are the ways to
49
+
50
+ - Create the indexing Pipeline
51
+ - Create the retrieval pipeline
52
+ - Create the RAG pipeline
53
+
54
+ ### Create the indexing Pipeline and index some documents
55
+
56
+ ```python
57
+ import glob
58
+ import os
59
+
60
+ from haystack import Pipeline
61
+ from haystack.components.converters import MarkdownToDocument
62
+ from haystack.components.embedders import OpenAIDocumentEmbedder, OpenAITextEmbedder
63
+ from haystack.components.preprocessors import DocumentSplitter
64
+ from haystack.components.writers import DocumentWriter
65
+
66
+ from milvus_haystack import MilvusDocumentStore
67
+ from milvus_haystack.milvus_embedding_retriever import MilvusEmbeddingRetriever
68
+
69
+ current_file_path = os.path.abspath(__file__)
70
+ file_paths = [current_file_path] # You can replace it with your own file paths.
71
+
72
+ document_store = MilvusDocumentStore(
73
+ # If you have installed the latest version of pymilvus with milvus lite, you can use a local path as the uri without starting the milvus service.
74
+ connection_args={"uri": "./milvus.db"},
75
+ # Or, if you have started the milvus standalone service by docker, you can use the specified uri to connect to the service.
76
+ # connection_args={"uri": "http://localhost:19530"},
77
+ drop_old=True,
78
+ )
79
+ indexing_pipeline = Pipeline()
80
+ indexing_pipeline.add_component("converter", MarkdownToDocument())
81
+ indexing_pipeline.add_component("splitter", DocumentSplitter(split_by="sentence", split_length=2))
82
+ indexing_pipeline.add_component("embedder", OpenAIDocumentEmbedder())
83
+ indexing_pipeline.add_component("writer", DocumentWriter(document_store))
84
+ indexing_pipeline.connect("converter", "splitter")
85
+ indexing_pipeline.connect("splitter", "embedder")
86
+ indexing_pipeline.connect("embedder", "writer")
87
+ indexing_pipeline.run({"converter": {"sources": file_paths}})
88
+
89
+ print("Number of documents:", document_store.count_documents())
90
+ ```
91
+
92
+ ### Create the retrieval pipeline and try a query
93
+
94
+ ```python
95
+ question = "How to set the service uri with milvus lite?" # You can replace it with your own question.
96
+
97
+ retrieval_pipeline = Pipeline()
98
+ retrieval_pipeline.add_component("embedder", OpenAITextEmbedder())
99
+ retrieval_pipeline.add_component("retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3))
100
+ retrieval_pipeline.connect("embedder", "retriever")
101
+
102
+ retrieval_results = retrieval_pipeline.run({"embedder": {"text": question}})
103
+
104
+ for doc in retrieval_results["retriever"]["documents"]:
105
+ print(doc.content)
106
+ print("-" * 10)
107
+ ```
108
+
109
+ ### Create the RAG pipeline and try a query
110
+
111
+ ```python
112
+ from haystack.utils import Secret
113
+ from haystack.components.builders import PromptBuilder
114
+ from haystack.components.generators import OpenAIGenerator
115
+
116
+ prompt_template = """Answer the following query based on the provided context. If the context does
117
+ not include an answer, reply with 'I don't know'.\n
118
+ Query: {{query}}
119
+ Documents:
120
+ {% for doc in documents %}
121
+ {{ doc.content }}
122
+ {% endfor %}
123
+ Answer:
124
+ """
125
+
126
+ rag_pipeline = Pipeline()
127
+ rag_pipeline.add_component("text_embedder", OpenAITextEmbedder())
128
+ rag_pipeline.add_component("retriever", MilvusEmbeddingRetriever(document_store=document_store, top_k=3))
129
+ rag_pipeline.add_component("prompt_builder", PromptBuilder(template=prompt_template))
130
+ rag_pipeline.add_component("generator", OpenAIGenerator(api_key=Secret.from_token(os.getenv("OPENAI_API_KEY")),
131
+ generation_kwargs={"temperature": 0}))
132
+ rag_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
133
+ rag_pipeline.connect("retriever.documents", "prompt_builder.documents")
134
+ rag_pipeline.connect("prompt_builder", "generator")
135
+
136
+ results = rag_pipeline.run(
137
+ {
138
+ "text_embedder": {"text": question},
139
+ "prompt_builder": {"query": question},
140
+ }
141
+ )
142
+ print('RAG answer:', results["generator"]["replies"][0])
143
+
144
+ ```
145
+
146
+ ## License
147
+
148
+ `milvus-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -28,7 +28,6 @@ dependencies = [
28
28
  "haystack-ai",
29
29
  "typing_extensions",
30
30
  "pymilvus",
31
- "milvus",
32
31
  ]
33
32
 
34
33
  [project.urls]
@@ -177,7 +176,6 @@ module = [
177
176
  "milvus_haystack.*",
178
177
  "pymilvus.*",
179
178
  "numpy",
180
- "milvus",
181
179
  "pytest.*"
182
180
  ]
183
181
  ignore_missing_imports = true
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2023-present Tuana Celik <tuana.celik@deepset.ai>
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
- __version__ = "0.0.4"
4
+ __version__ = "0.0.6"
@@ -409,9 +409,7 @@ class MilvusDocumentStore:
409
409
  elif uri.startswith("http://"):
410
410
  given_address = uri.split("http://")[1]
411
411
  else:
412
- err_msg = "Invalid Milvus URI: %s", uri
413
- logger.error(err_msg)
414
- raise ValueError(err_msg)
412
+ given_address = uri # Milvus lite
415
413
  elif address is not None:
416
414
  given_address = address
417
415
  else:
@@ -60,7 +60,7 @@ def _assert_comparison_filter(filters: Dict[str, Any]):
60
60
  assert "field" in filters, "field must be specified in filters" # noqa: S101
61
61
  assert "value" in filters, "value must be specified in filters" # noqa: S101
62
62
  assert filters["operator"] in COMPARISON_OPERATORS, FilterError( # noqa: S101
63
- "operator must be one of: %s" % LOGIC_OPERATORS
63
+ f"operator must be one of: {LOGIC_OPERATORS}"
64
64
  )
65
65
 
66
66
 
@@ -85,5 +85,5 @@ def _parse_logic(filters: Dict[str, Any]) -> str:
85
85
  def _assert_logic_filter(filters: Dict[str, Any]):
86
86
  assert "operator" in filters, "operator must be specified in filters" # noqa: S101
87
87
  assert "conditions" in filters, "conditions must be specified in filters" # noqa: S101
88
- assert filters["operator"] in LOGIC_OPERATORS, "operator must be one of: %s" % LOGIC_OPERATORS # noqa: S101
88
+ assert filters["operator"] in LOGIC_OPERATORS, f"operator must be one of: {LOGIC_OPERATORS}" # noqa: S101
89
89
  assert isinstance(filters["conditions"], list), "conditions must be a list" # noqa: S101
@@ -12,24 +12,6 @@ logger = logging.getLogger(__name__)
12
12
 
13
13
 
14
14
  class TestDocumentStore(CountDocumentsTest, WriteDocumentsTest, DeleteDocumentsTest):
15
- from milvus import MilvusServer
16
-
17
- milvus_server = MilvusServer()
18
- milvus_server.set_base_dir("test_milvus_base")
19
- milvus_server.listen_port = 19530
20
- try:
21
- milvus_server.stop()
22
- except Exception as err:
23
- logger.debug("Can not stop Milvus server. %s", err)
24
- try:
25
- milvus_server.cleanup()
26
- except Exception as err:
27
- logger.debug("Can not cleanup Milvus. %s", err)
28
- try:
29
- milvus_server.start()
30
- except Exception as err:
31
- logger.debug("Can not start Milvus server. %s", err)
32
-
33
15
  @pytest.fixture
34
16
  def document_store(self) -> MilvusDocumentStore:
35
17
  return MilvusDocumentStore(
@@ -10,24 +10,6 @@ logger = logging.getLogger(__name__)
10
10
 
11
11
 
12
12
  class TestMilvusEmbeddingTests:
13
- from milvus import MilvusServer
14
-
15
- milvus_server = MilvusServer()
16
- milvus_server.set_base_dir("test_milvus_base")
17
- milvus_server.listen_port = 19530
18
- try:
19
- milvus_server.stop()
20
- except Exception as err:
21
- logger.debug("Can not stop Milvus server. %s", err)
22
- try:
23
- milvus_server.cleanup()
24
- except Exception as err:
25
- logger.debug("Can not cleanup Milvus. %s", err)
26
- try:
27
- milvus_server.start()
28
- except Exception as err:
29
- logger.debug("Can not start Milvus server. %s", err)
30
-
31
13
  @pytest.fixture
32
14
  def document_store(self) -> MilvusDocumentStore:
33
15
  return MilvusDocumentStore(
@@ -12,24 +12,6 @@ logger = logging.getLogger(__name__)
12
12
 
13
13
 
14
14
  class TestMilvusFilters(FilterDocumentsTest):
15
- from milvus import MilvusServer
16
-
17
- milvus_server = MilvusServer()
18
- milvus_server.set_base_dir("test_milvus_base")
19
- milvus_server.listen_port = 19530
20
- try:
21
- milvus_server.stop()
22
- except Exception as err:
23
- logger.debug("Can not stop Milvus server. %s", err)
24
- try:
25
- milvus_server.cleanup()
26
- except Exception as err:
27
- logger.debug("Can not cleanup Milvus. %s", err)
28
- try:
29
- milvus_server.start()
30
- except Exception as err:
31
- logger.debug("Can not start Milvus server. %s", err)
32
-
33
15
  @pytest.fixture
34
16
  def filterable_docs(self) -> List[Document]:
35
17
  documents = []
@@ -1,56 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: milvus-haystack
3
- Version: 0.0.4
4
- Project-URL: Documentation, https://github.com/milvus-io/milvus-haystack#readme
5
- Project-URL: Issues, https://github.com/milvus-io/milvus-haystack/issues
6
- Project-URL: Source, https://github.com/milvus-io/milvus-haystack
7
- Author-email: Zilliz <support@zilliz.com>
8
- License-Expression: Apache-2.0
9
- License-File: LICENSE.txt
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Programming Language :: Python
12
- Classifier: Programming Language :: Python :: 3.7
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
- Classifier: Programming Language :: Python :: 3.10
16
- Classifier: Programming Language :: Python :: 3.11
17
- Classifier: Programming Language :: Python :: Implementation :: CPython
18
- Classifier: Programming Language :: Python :: Implementation :: PyPy
19
- Requires-Python: >=3.7
20
- Requires-Dist: haystack-ai
21
- Requires-Dist: milvus
22
- Requires-Dist: pymilvus
23
- Requires-Dist: typing-extensions
24
- Description-Content-Type: text/markdown
25
-
26
- # Milvus Document Store for Haystack
27
-
28
-
29
- ## Installation
30
-
31
- ```console
32
- pip install -e milvus-haystack
33
- ```
34
-
35
- ## Usage
36
- First, to start up a Milvus service, follow the ['Start Milvus'](https://milvus.io/docs/install_standalone-docker.md#Start-Milvus) instructions in the documentation.
37
-
38
- Then, to use the `MilvusDocumentStore` in a Haystack pipeline"
39
-
40
- ```py
41
- from haystack import Document
42
- from milvus_haystack import MilvusDocumentStore
43
-
44
- document_store = MilvusDocumentStore()
45
- documents = [Document(
46
- content="A Foo Document",
47
- meta={"page": "100", "chapter": "intro"},
48
- embedding=[-10.0] * 128,
49
- )]
50
- document_store.write_documents(documents)
51
- document_store.count_documents() # 1
52
- ```
53
-
54
- ## License
55
-
56
- `milvus-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -1,31 +0,0 @@
1
- # Milvus Document Store for Haystack
2
-
3
-
4
- ## Installation
5
-
6
- ```console
7
- pip install -e milvus-haystack
8
- ```
9
-
10
- ## Usage
11
- First, to start up a Milvus service, follow the ['Start Milvus'](https://milvus.io/docs/install_standalone-docker.md#Start-Milvus) instructions in the documentation.
12
-
13
- Then, to use the `MilvusDocumentStore` in a Haystack pipeline"
14
-
15
- ```py
16
- from haystack import Document
17
- from milvus_haystack import MilvusDocumentStore
18
-
19
- document_store = MilvusDocumentStore()
20
- documents = [Document(
21
- content="A Foo Document",
22
- meta={"page": "100", "chapter": "intro"},
23
- embedding=[-10.0] * 128,
24
- )]
25
- document_store.write_documents(documents)
26
- document_store.count_documents() # 1
27
- ```
28
-
29
- ## License
30
-
31
- `milvus-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
File without changes