pinecone.openapi_support.api_client_utils

  1import json
  2import mimetypes
  3import io
  4import os
  5from urllib3.fields import RequestField
  6from urllib.parse import quote
  7
  8from typing import Optional, List, Tuple, Dict, Any, Union
  9from .serializer import Serializer
 10from .exceptions import PineconeApiValueError
 11
 12
 13class HeaderUtil:
 14    @staticmethod
 15    def select_header_content_type(content_types: List[str]) -> str:
 16        """Returns `Content-Type` based on an array of content_types provided.
 17
 18        :param content_types: List of content-types.
 19        :return: Content-Type (e.g. application/json).
 20        """
 21        if not content_types:
 22            return "application/json"
 23
 24        content_types = [x.lower() for x in content_types]
 25
 26        if "application/json" in content_types or "*/*" in content_types:
 27            return "application/json"
 28        else:
 29            return content_types[0]
 30
 31    @staticmethod
 32    def select_header_accept(accepts: List[str]) -> str:
 33        """Returns `Accept` based on an array of accepts provided.
 34
 35        :param accepts: List of headers.
 36        :return: Accept (e.g. application/json).
 37        """
 38        if not accepts:
 39            return ""
 40
 41        accepts = [x.lower() for x in accepts]
 42
 43        if "application/json" in accepts:
 44            return "application/json"
 45        else:
 46            return ", ".join(accepts)
 47
 48    @staticmethod
 49    def process_header_params(
 50        default_headers: Dict[str, str], header_params: Dict[str, str], collection_formats
 51    ) -> Dict[str, Any]:
 52        header_params.update(default_headers)
 53        if header_params:
 54            sanitized_header_params: Dict[str, Any] = Serializer.sanitize_for_serialization(
 55                header_params
 56            )
 57            processed_header_params: Dict[str, Any] = dict(
 58                parameters_to_tuples(sanitized_header_params, collection_formats)
 59            )
 60        return processed_header_params
 61
 62    @staticmethod
 63    def prepare_headers(headers_map: Dict[str, List[str]], params) -> None:
 64        """Mutates the params to set Accept and Content-Type headers."""
 65        accept_headers_list = headers_map["accept"]
 66        if accept_headers_list:
 67            params["header"]["Accept"] = HeaderUtil.select_header_accept(accept_headers_list)
 68
 69        content_type_headers_list = headers_map["content_type"]
 70        if content_type_headers_list:
 71            header_list = HeaderUtil.select_header_content_type(content_type_headers_list)
 72            params["header"]["Content-Type"] = header_list
 73
 74
 75def process_query_params(query_params, collection_formats):
 76    if query_params:
 77        sanitized_query_params = Serializer.sanitize_for_serialization(query_params)
 78        processed_query_params = parameters_to_tuples(sanitized_query_params, collection_formats)
 79    else:
 80        processed_query_params = []
 81
 82    return processed_query_params
 83
 84
 85def process_params(
 86    default_headers: Dict[str, str],
 87    header_params: Dict[str, Any],
 88    path_params: Dict[str, Any],
 89    collection_formats: Dict[str, str],
 90):
 91    # header parameters
 92    headers_tuple = HeaderUtil.process_header_params(
 93        default_headers, header_params, collection_formats
 94    )
 95
 96    # path parameters
 97    sanitized_path_params: Dict[str, Any] = Serializer.sanitize_for_serialization(path_params or {})
 98    path_parm: List[Tuple[str, Any]] = parameters_to_tuples(
 99        sanitized_path_params, collection_formats
100    )
101
102    return headers_tuple, path_parm, sanitized_path_params
103
104
105def parameters_to_multipart(params, collection_types):
106    """Get parameters as list of tuples, formatting as json if value is collection_types
107
108    :param params: Parameters as list of two-tuples
109    :param dict collection_types: Parameter collection types
110    :return: Parameters as list of tuple or urllib3.fields.RequestField
111    """
112    new_params = []
113    if collection_types is None:
114        collection_types = dict
115    for k, v in params.items() if isinstance(params, dict) else params:  # noqa: E501
116        if isinstance(
117            v, collection_types
118        ):  # v is instance of collection_type, formatting as application/json
119            v = json.dumps(v, ensure_ascii=False).encode("utf-8")
120            field = RequestField(k, v)
121            field.make_multipart(content_type="application/json; charset=utf-8")
122            new_params.append(field)
123        else:
124            new_params.append((k, v))
125    return new_params
126
127
128def files_parameters(files: Optional[Dict[str, List[io.IOBase]]] = None):
129    """Builds form parameters.
130
131    :param files: None or a dict with key=param_name and
132        value is a list of open file objects
133    :return: List of tuples of form parameters with file data
134    """
135    if files is None:
136        return []
137
138    params = []
139    for param_name, file_instances in files.items():
140        if file_instances is None:
141            # if the file field is nullable, skip None values
142            continue
143        for file_instance in file_instances:
144            if file_instance is None:
145                # if the file field is nullable, skip None values
146                continue
147            if file_instance.closed is True:
148                raise PineconeApiValueError(
149                    "Cannot read a closed file. The passed in file_type "
150                    "for %s must be open." % param_name
151                )
152            filename = os.path.basename(file_instance.name)  # type: ignore
153            filedata = Serializer.get_file_data_and_close_file(file_instance)
154            mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream"
155            params.append(tuple([param_name, tuple([filename, filedata, mimetype])]))
156
157    return params
158
159
160def parameters_to_tuples(
161    params: Union[Dict[str, Any], List[Tuple[str, Any]]],
162    collection_formats: Optional[Dict[str, str]],
163) -> List[Tuple[str, str]]:
164    """Get parameters as list of tuples, formatting collections.
165
166    :param params: Parameters as dict or list of two-tuples
167    :param dict collection_formats: Parameter collection formats
168    :return: Parameters as list of tuples, collections formatted
169    """
170    new_params: List[Tuple[str, Any]] = []
171    if collection_formats is None:
172        collection_formats = {}
173    for k, v in params.items() if isinstance(params, dict) else params:  # noqa: E501
174        if k in collection_formats:
175            collection_format = collection_formats[k]
176            if collection_format == "multi":
177                new_params.extend((k, value) for value in v)
178            else:
179                if collection_format == "ssv":
180                    delimiter = " "
181                elif collection_format == "tsv":
182                    delimiter = "\t"
183                elif collection_format == "pipes":
184                    delimiter = "|"
185                else:  # csv is the default
186                    delimiter = ","
187                new_params.append((k, delimiter.join(str(value) for value in v)))
188        else:
189            new_params.append((k, v))
190    return new_params
191
192
193def build_request_url(config, processed_path_params, resource_path, _host):
194    for k, v in processed_path_params:
195        # specified safe chars, encode everything
196        resource_path = resource_path.replace(
197            "{%s}" % k, quote(str(v), safe=config.safe_chars_for_path_param)
198        )
199
200    # _host is a host override passed for an individual operation
201    host = _host if _host is not None else config.host
202
203    return host + resource_path
class HeaderUtil:
14class HeaderUtil:
15    @staticmethod
16    def select_header_content_type(content_types: List[str]) -> str:
17        """Returns `Content-Type` based on an array of content_types provided.
18
19        :param content_types: List of content-types.
20        :return: Content-Type (e.g. application/json).
21        """
22        if not content_types:
23            return "application/json"
24
25        content_types = [x.lower() for x in content_types]
26
27        if "application/json" in content_types or "*/*" in content_types:
28            return "application/json"
29        else:
30            return content_types[0]
31
32    @staticmethod
33    def select_header_accept(accepts: List[str]) -> str:
34        """Returns `Accept` based on an array of accepts provided.
35
36        :param accepts: List of headers.
37        :return: Accept (e.g. application/json).
38        """
39        if not accepts:
40            return ""
41
42        accepts = [x.lower() for x in accepts]
43
44        if "application/json" in accepts:
45            return "application/json"
46        else:
47            return ", ".join(accepts)
48
49    @staticmethod
50    def process_header_params(
51        default_headers: Dict[str, str], header_params: Dict[str, str], collection_formats
52    ) -> Dict[str, Any]:
53        header_params.update(default_headers)
54        if header_params:
55            sanitized_header_params: Dict[str, Any] = Serializer.sanitize_for_serialization(
56                header_params
57            )
58            processed_header_params: Dict[str, Any] = dict(
59                parameters_to_tuples(sanitized_header_params, collection_formats)
60            )
61        return processed_header_params
62
63    @staticmethod
64    def prepare_headers(headers_map: Dict[str, List[str]], params) -> None:
65        """Mutates the params to set Accept and Content-Type headers."""
66        accept_headers_list = headers_map["accept"]
67        if accept_headers_list:
68            params["header"]["Accept"] = HeaderUtil.select_header_accept(accept_headers_list)
69
70        content_type_headers_list = headers_map["content_type"]
71        if content_type_headers_list:
72            header_list = HeaderUtil.select_header_content_type(content_type_headers_list)
73            params["header"]["Content-Type"] = header_list
@staticmethod
def select_header_content_type(content_types: List[str]) -> str:
15    @staticmethod
16    def select_header_content_type(content_types: List[str]) -> str:
17        """Returns `Content-Type` based on an array of content_types provided.
18
19        :param content_types: List of content-types.
20        :return: Content-Type (e.g. application/json).
21        """
22        if not content_types:
23            return "application/json"
24
25        content_types = [x.lower() for x in content_types]
26
27        if "application/json" in content_types or "*/*" in content_types:
28            return "application/json"
29        else:
30            return content_types[0]

Returns Content-Type based on an array of content_types provided.

Parameters
  • content_types: List of content-types.
Returns

Content-Type (e.g. application/json).

@staticmethod
def select_header_accept(accepts: List[str]) -> str:
32    @staticmethod
33    def select_header_accept(accepts: List[str]) -> str:
34        """Returns `Accept` based on an array of accepts provided.
35
36        :param accepts: List of headers.
37        :return: Accept (e.g. application/json).
38        """
39        if not accepts:
40            return ""
41
42        accepts = [x.lower() for x in accepts]
43
44        if "application/json" in accepts:
45            return "application/json"
46        else:
47            return ", ".join(accepts)

Returns Accept based on an array of accepts provided.

Parameters
  • accepts: List of headers.
Returns

Accept (e.g. application/json).

@staticmethod
def process_header_params( default_headers: Dict[str, str], header_params: Dict[str, str], collection_formats) -> Dict[str, Any]:
49    @staticmethod
50    def process_header_params(
51        default_headers: Dict[str, str], header_params: Dict[str, str], collection_formats
52    ) -> Dict[str, Any]:
53        header_params.update(default_headers)
54        if header_params:
55            sanitized_header_params: Dict[str, Any] = Serializer.sanitize_for_serialization(
56                header_params
57            )
58            processed_header_params: Dict[str, Any] = dict(
59                parameters_to_tuples(sanitized_header_params, collection_formats)
60            )
61        return processed_header_params
@staticmethod
def prepare_headers(headers_map: Dict[str, List[str]], params) -> None:
63    @staticmethod
64    def prepare_headers(headers_map: Dict[str, List[str]], params) -> None:
65        """Mutates the params to set Accept and Content-Type headers."""
66        accept_headers_list = headers_map["accept"]
67        if accept_headers_list:
68            params["header"]["Accept"] = HeaderUtil.select_header_accept(accept_headers_list)
69
70        content_type_headers_list = headers_map["content_type"]
71        if content_type_headers_list:
72            header_list = HeaderUtil.select_header_content_type(content_type_headers_list)
73            params["header"]["Content-Type"] = header_list

Mutates the params to set Accept and Content-Type headers.

def process_query_params(query_params, collection_formats):
76def process_query_params(query_params, collection_formats):
77    if query_params:
78        sanitized_query_params = Serializer.sanitize_for_serialization(query_params)
79        processed_query_params = parameters_to_tuples(sanitized_query_params, collection_formats)
80    else:
81        processed_query_params = []
82
83    return processed_query_params
def process_params( default_headers: Dict[str, str], header_params: Dict[str, Any], path_params: Dict[str, Any], collection_formats: Dict[str, str]):
 86def process_params(
 87    default_headers: Dict[str, str],
 88    header_params: Dict[str, Any],
 89    path_params: Dict[str, Any],
 90    collection_formats: Dict[str, str],
 91):
 92    # header parameters
 93    headers_tuple = HeaderUtil.process_header_params(
 94        default_headers, header_params, collection_formats
 95    )
 96
 97    # path parameters
 98    sanitized_path_params: Dict[str, Any] = Serializer.sanitize_for_serialization(path_params or {})
 99    path_parm: List[Tuple[str, Any]] = parameters_to_tuples(
100        sanitized_path_params, collection_formats
101    )
102
103    return headers_tuple, path_parm, sanitized_path_params
def parameters_to_multipart(params, collection_types):
106def parameters_to_multipart(params, collection_types):
107    """Get parameters as list of tuples, formatting as json if value is collection_types
108
109    :param params: Parameters as list of two-tuples
110    :param dict collection_types: Parameter collection types
111    :return: Parameters as list of tuple or urllib3.fields.RequestField
112    """
113    new_params = []
114    if collection_types is None:
115        collection_types = dict
116    for k, v in params.items() if isinstance(params, dict) else params:  # noqa: E501
117        if isinstance(
118            v, collection_types
119        ):  # v is instance of collection_type, formatting as application/json
120            v = json.dumps(v, ensure_ascii=False).encode("utf-8")
121            field = RequestField(k, v)
122            field.make_multipart(content_type="application/json; charset=utf-8")
123            new_params.append(field)
124        else:
125            new_params.append((k, v))
126    return new_params

Get parameters as list of tuples, formatting as json if value is collection_types

Parameters
  • params: Parameters as list of two-tuples
  • dict collection_types: Parameter collection types
Returns

Parameters as list of tuple or urllib3.fields.RequestField

def files_parameters(files: Optional[Dict[str, List[io.IOBase]]] = None):
129def files_parameters(files: Optional[Dict[str, List[io.IOBase]]] = None):
130    """Builds form parameters.
131
132    :param files: None or a dict with key=param_name and
133        value is a list of open file objects
134    :return: List of tuples of form parameters with file data
135    """
136    if files is None:
137        return []
138
139    params = []
140    for param_name, file_instances in files.items():
141        if file_instances is None:
142            # if the file field is nullable, skip None values
143            continue
144        for file_instance in file_instances:
145            if file_instance is None:
146                # if the file field is nullable, skip None values
147                continue
148            if file_instance.closed is True:
149                raise PineconeApiValueError(
150                    "Cannot read a closed file. The passed in file_type "
151                    "for %s must be open." % param_name
152                )
153            filename = os.path.basename(file_instance.name)  # type: ignore
154            filedata = Serializer.get_file_data_and_close_file(file_instance)
155            mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream"
156            params.append(tuple([param_name, tuple([filename, filedata, mimetype])]))
157
158    return params

Builds form parameters.

Parameters
  • files: None or a dict with key=param_name and value is a list of open file objects
Returns

List of tuples of form parameters with file data

def parameters_to_tuples( params: Union[Dict[str, Any], List[Tuple[str, Any]]], collection_formats: Optional[Dict[str, str]]) -> List[Tuple[str, str]]:
161def parameters_to_tuples(
162    params: Union[Dict[str, Any], List[Tuple[str, Any]]],
163    collection_formats: Optional[Dict[str, str]],
164) -> List[Tuple[str, str]]:
165    """Get parameters as list of tuples, formatting collections.
166
167    :param params: Parameters as dict or list of two-tuples
168    :param dict collection_formats: Parameter collection formats
169    :return: Parameters as list of tuples, collections formatted
170    """
171    new_params: List[Tuple[str, Any]] = []
172    if collection_formats is None:
173        collection_formats = {}
174    for k, v in params.items() if isinstance(params, dict) else params:  # noqa: E501
175        if k in collection_formats:
176            collection_format = collection_formats[k]
177            if collection_format == "multi":
178                new_params.extend((k, value) for value in v)
179            else:
180                if collection_format == "ssv":
181                    delimiter = " "
182                elif collection_format == "tsv":
183                    delimiter = "\t"
184                elif collection_format == "pipes":
185                    delimiter = "|"
186                else:  # csv is the default
187                    delimiter = ","
188                new_params.append((k, delimiter.join(str(value) for value in v)))
189        else:
190            new_params.append((k, v))
191    return new_params

Get parameters as list of tuples, formatting collections.

Parameters
  • params: Parameters as dict or list of two-tuples
  • dict collection_formats: Parameter collection formats
Returns

Parameters as list of tuples, collections formatted

def build_request_url(config, processed_path_params, resource_path, _host):
194def build_request_url(config, processed_path_params, resource_path, _host):
195    for k, v in processed_path_params:
196        # specified safe chars, encode everything
197        resource_path = resource_path.replace(
198            "{%s}" % k, quote(str(v), safe=config.safe_chars_for_path_param)
199        )
200
201    # _host is a host override passed for an individual operation
202    host = _host if _host is not None else config.host
203
204    return host + resource_path