pinecone-haystack 6.2.0__py3-none-any.whl
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.
- haystack_integrations/components/retrievers/pinecone/__init__.py +3 -0
- haystack_integrations/components/retrievers/pinecone/embedding_retriever.py +173 -0
- haystack_integrations/components/retrievers/py.typed +0 -0
- haystack_integrations/document_stores/pinecone/__init__.py +6 -0
- haystack_integrations/document_stores/pinecone/document_store.py +1102 -0
- haystack_integrations/document_stores/pinecone/filters.py +191 -0
- haystack_integrations/document_stores/py.typed +0 -0
- pinecone_haystack-6.2.0.dist-info/METADATA +38 -0
- pinecone_haystack-6.2.0.dist-info/RECORD +10 -0
- pinecone_haystack-6.2.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2023-present deepset GmbH <info@deepset.ai>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from haystack.errors import FilterError
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _normalize_filters(filters: dict[str, Any]) -> dict[str, Any]:
|
|
10
|
+
"""
|
|
11
|
+
Converts Haystack filters in Pinecone compatible filters.
|
|
12
|
+
|
|
13
|
+
Reference: https://docs.pinecone.io/docs/metadata-filtering
|
|
14
|
+
"""
|
|
15
|
+
if not isinstance(filters, dict):
|
|
16
|
+
msg = "Filters must be a dictionary"
|
|
17
|
+
raise FilterError(msg)
|
|
18
|
+
|
|
19
|
+
if "field" in filters:
|
|
20
|
+
return _parse_comparison_condition(filters)
|
|
21
|
+
return _parse_logical_condition(filters)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _parse_logical_condition(condition: dict[str, Any]) -> dict[str, Any]:
|
|
25
|
+
if "operator" not in condition:
|
|
26
|
+
msg = f"'operator' key missing in {condition}"
|
|
27
|
+
raise FilterError(msg)
|
|
28
|
+
if "conditions" not in condition:
|
|
29
|
+
msg = f"'conditions' key missing in {condition}"
|
|
30
|
+
raise FilterError(msg)
|
|
31
|
+
|
|
32
|
+
operator = condition["operator"]
|
|
33
|
+
conditions = [_parse_comparison_condition(c) for c in condition["conditions"]]
|
|
34
|
+
|
|
35
|
+
if operator in LOGICAL_OPERATORS:
|
|
36
|
+
return {LOGICAL_OPERATORS[operator]: conditions}
|
|
37
|
+
|
|
38
|
+
msg = f"Unknown logical operator '{operator}'"
|
|
39
|
+
raise FilterError(msg)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _parse_comparison_condition(condition: dict[str, Any]) -> dict[str, Any]:
|
|
43
|
+
if "field" not in condition:
|
|
44
|
+
# 'field' key is only found in comparison dictionaries.
|
|
45
|
+
# We assume this is a logic dictionary since it's not present.
|
|
46
|
+
return _parse_logical_condition(condition)
|
|
47
|
+
|
|
48
|
+
field: str = condition["field"]
|
|
49
|
+
if "operator" not in condition:
|
|
50
|
+
msg = f"'operator' key missing in {condition}"
|
|
51
|
+
raise FilterError(msg)
|
|
52
|
+
if "value" not in condition:
|
|
53
|
+
msg = f"'value' key missing in {condition}"
|
|
54
|
+
raise FilterError(msg)
|
|
55
|
+
operator: str = condition["operator"]
|
|
56
|
+
if field.startswith("meta."):
|
|
57
|
+
# Remove the "meta." prefix if present.
|
|
58
|
+
# Documents are flattened when using the PineconeDocumentStore
|
|
59
|
+
# so we don't need to specify the "meta." prefix.
|
|
60
|
+
# Instead of raising an error we handle it gracefully.
|
|
61
|
+
field = field[5:]
|
|
62
|
+
|
|
63
|
+
value: Any = condition["value"]
|
|
64
|
+
|
|
65
|
+
return COMPARISON_OPERATORS[operator](field, value)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _equal(field: str, value: Any) -> dict[str, Any]:
|
|
69
|
+
supported_types = (str, int, float, bool)
|
|
70
|
+
if not isinstance(value, supported_types):
|
|
71
|
+
msg = (
|
|
72
|
+
f"Unsupported type for 'equal' comparison: {type(value)}. "
|
|
73
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
74
|
+
)
|
|
75
|
+
raise FilterError(msg)
|
|
76
|
+
|
|
77
|
+
return {field: {"$eq": value}}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _not_equal(field: str, value: Any) -> dict[str, Any]:
|
|
81
|
+
supported_types = (str, int, float, bool)
|
|
82
|
+
if not isinstance(value, supported_types):
|
|
83
|
+
msg = (
|
|
84
|
+
f"Unsupported type for 'not equal' comparison: {type(value)}. "
|
|
85
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
86
|
+
)
|
|
87
|
+
raise FilterError(msg)
|
|
88
|
+
|
|
89
|
+
return {field: {"$ne": value}}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _greater_than(field: str, value: Any) -> dict[str, Any]:
|
|
93
|
+
supported_types = (int, float)
|
|
94
|
+
if not isinstance(value, supported_types):
|
|
95
|
+
msg = (
|
|
96
|
+
f"Unsupported type for 'greater than' comparison: {type(value)}. "
|
|
97
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
98
|
+
)
|
|
99
|
+
raise FilterError(msg)
|
|
100
|
+
|
|
101
|
+
return {field: {"$gt": value}}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _greater_than_equal(field: str, value: Any) -> dict[str, Any]:
|
|
105
|
+
supported_types = (int, float)
|
|
106
|
+
if not isinstance(value, supported_types):
|
|
107
|
+
msg = (
|
|
108
|
+
f"Unsupported type for 'greater than equal' comparison: {type(value)}. "
|
|
109
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
110
|
+
)
|
|
111
|
+
raise FilterError(msg)
|
|
112
|
+
|
|
113
|
+
return {field: {"$gte": value}}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _less_than(field: str, value: Any) -> dict[str, Any]:
|
|
117
|
+
supported_types = (int, float)
|
|
118
|
+
if not isinstance(value, supported_types):
|
|
119
|
+
msg = (
|
|
120
|
+
f"Unsupported type for 'less than' comparison: {type(value)}. "
|
|
121
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
122
|
+
)
|
|
123
|
+
raise FilterError(msg)
|
|
124
|
+
|
|
125
|
+
return {field: {"$lt": value}}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _less_than_equal(field: str, value: Any) -> dict[str, Any]:
|
|
129
|
+
supported_types = (int, float)
|
|
130
|
+
if not isinstance(value, supported_types):
|
|
131
|
+
msg = (
|
|
132
|
+
f"Unsupported type for 'less than equal' comparison: {type(value)}. "
|
|
133
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
134
|
+
)
|
|
135
|
+
raise FilterError(msg)
|
|
136
|
+
|
|
137
|
+
return {field: {"$lte": value}}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _not_in(field: str, value: Any) -> dict[str, Any]:
|
|
141
|
+
if not isinstance(value, list):
|
|
142
|
+
msg = f"{field}'s value must be a list when using 'not in' comparator in Pinecone"
|
|
143
|
+
raise FilterError(msg)
|
|
144
|
+
|
|
145
|
+
supported_types = (int, float, str)
|
|
146
|
+
for v in value:
|
|
147
|
+
if not isinstance(v, supported_types):
|
|
148
|
+
msg = (
|
|
149
|
+
f"Unsupported type for 'not in' comparison: {type(v)}. "
|
|
150
|
+
f"Types supported by Pinecone are: {supported_types}"
|
|
151
|
+
)
|
|
152
|
+
raise FilterError(msg)
|
|
153
|
+
|
|
154
|
+
return {field: {"$nin": value}}
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _in(field: str, value: Any) -> dict[str, Any]:
|
|
158
|
+
if not isinstance(value, list):
|
|
159
|
+
msg = f"{field}'s value must be a list when using 'in' comparator in Pinecone"
|
|
160
|
+
raise FilterError(msg)
|
|
161
|
+
|
|
162
|
+
supported_types = (int, float, str)
|
|
163
|
+
for v in value:
|
|
164
|
+
if not isinstance(v, supported_types):
|
|
165
|
+
msg = f"Unsupported type for 'in' comparison: {type(v)}. Types supported by Pinecone are: {supported_types}"
|
|
166
|
+
raise FilterError(msg)
|
|
167
|
+
|
|
168
|
+
return {field: {"$in": value}}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
COMPARISON_OPERATORS = {
|
|
172
|
+
"==": _equal,
|
|
173
|
+
"!=": _not_equal,
|
|
174
|
+
">": _greater_than,
|
|
175
|
+
">=": _greater_than_equal,
|
|
176
|
+
"<": _less_than,
|
|
177
|
+
"<=": _less_than_equal,
|
|
178
|
+
"in": _in,
|
|
179
|
+
"not in": _not_in,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
LOGICAL_OPERATORS = {"AND": "$and", "OR": "$or"}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _validate_filters(filters: dict[str, Any] | None) -> None:
|
|
186
|
+
"""
|
|
187
|
+
Helper method to validate filter syntax.
|
|
188
|
+
"""
|
|
189
|
+
if filters and "operator" not in filters and "conditions" not in filters:
|
|
190
|
+
msg = "Invalid filter syntax. See https://docs.haystack.deepset.ai/docs/metadata-filtering for details."
|
|
191
|
+
raise ValueError(msg)
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pinecone_haystack
|
|
3
|
+
Version: 6.2.0
|
|
4
|
+
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/pinecone#readme
|
|
5
|
+
Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
|
|
6
|
+
Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/pinecone
|
|
7
|
+
Author-email: deepset GmbH <info@deepset.ai>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
18
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: haystack-ai>=2.28.0
|
|
21
|
+
Requires-Dist: pinecone[asyncio]>=7.0.0
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# pinecone-haystack
|
|
25
|
+
|
|
26
|
+
[](https://pypi.org/project/pinecone-haystack)
|
|
27
|
+
[](https://pypi.org/project/pinecone-haystack)
|
|
28
|
+
|
|
29
|
+
- [Integration page](https://haystack.deepset.ai/integrations/pinecone-document-store)
|
|
30
|
+
- [Changelog](https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/pinecone/CHANGELOG.md)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Contributing
|
|
35
|
+
|
|
36
|
+
Refer to the general [Contribution Guidelines](https://github.com/deepset-ai/haystack-core-integrations/blob/main/CONTRIBUTING.md).
|
|
37
|
+
|
|
38
|
+
To run integration tests locally, you need to export the `PINECONE_API_KEY` environment variable.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
haystack_integrations/components/retrievers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
haystack_integrations/components/retrievers/pinecone/__init__.py,sha256=45Ny1bezIdZ_nBB6PJce-ekkeSAP_8eYZb7mUS8KtS4,102
|
|
3
|
+
haystack_integrations/components/retrievers/pinecone/embedding_retriever.py,sha256=UvSfOHyXxdmlLPmttuy8cU_Mw9w3xUU3-TyyuDI_Dx0,6983
|
|
4
|
+
haystack_integrations/document_stores/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
haystack_integrations/document_stores/pinecone/__init__.py,sha256=Fj-FzfUJFIlH6eOsB4XYVmw26U-Qg1gfONvsCFoKMRU,197
|
|
6
|
+
haystack_integrations/document_stores/pinecone/document_store.py,sha256=WEuEItbAF2SRfkL0BVmqNJZNoIt_hiKzz6OBGEkJmzQ,46917
|
|
7
|
+
haystack_integrations/document_stores/pinecone/filters.py,sha256=kBaWgFWeo6E819XJLzDj0bCIEpEbRO-jUAQue7-zkvo,6257
|
|
8
|
+
pinecone_haystack-6.2.0.dist-info/METADATA,sha256=bvtSrZjOz-t1U178vfw5UkGLLjtCfFLvZC6mx9HBzR0,1870
|
|
9
|
+
pinecone_haystack-6.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
10
|
+
pinecone_haystack-6.2.0.dist-info/RECORD,,
|