diff --git a/modules/openapi-generator/src/main/resources/python/api.mustache b/modules/openapi-generator/src/main/resources/python/api.mustache index 4319b31edfdc..c771516a8a49 100644 --- a/modules/openapi-generator/src/main/resources/python/api.mustache +++ b/modules/openapi-generator/src/main/resources/python/api.mustache @@ -308,7 +308,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -387,12 +387,12 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{#headerParams}} if {{paramName}} is not None: {{#vendorExtensions.x-python-json-header}} - _header_params['{{baseName}}'] = json.dumps( + self.api_client._set_header(_header_params, '{{baseName}}', json.dumps( self.api_client.sanitize_for_serialization({{paramName}}) - ) + )) {{/vendorExtensions.x-python-json-header}} {{^vendorExtensions.x-python-json-header}} - _header_params['{{baseName}}'] = {{paramName}} + self.api_client._set_header(_header_params, '{{baseName}}', {{paramName}}) {{/vendorExtensions.x-python-json-header}} {{/headerParams}} # process the form parameters @@ -431,13 +431,13 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{/isQueryParam}} {{#isHeaderParam}} # Set client side default value of Header Param "{{baseName}}". - _header_params['{{baseName}}'] = {{#_enum}}'{{{.}}}'{{/_enum}} + self.api_client._set_header(_header_params, '{{baseName}}', {{#_enum}}'{{{.}}}'{{/_enum}}) {{/isHeaderParam}} {{/constantParams}} {{#hasProduces}} # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [{{#produces}} '{{{mediaType}}}'{{^-last}}, {{/-last}}{{/produces}} @@ -448,7 +448,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{#hasConsumes}} # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -458,7 +458,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) {{/hasConsumes}} # authentication setting diff --git a/modules/openapi-generator/src/main/resources/python/api_client.mustache b/modules/openapi-generator/src/main/resources/python/api_client.mustache index 973a8de03b2b..9e16a465bd57 100644 --- a/modules/openapi-generator/src/main/resources/python/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/python/api_client.mustache @@ -20,7 +20,7 @@ from threading import Lock {{/compatibleWithPythonLegacyApi}} from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union{{#compatibleWithPythonLegacy}}, Any{{/compatibleWithPythonLegacy}} +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from {{packageName}}.configuration import Configuration @@ -231,16 +231,36 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None {{#useIndependentImplicitClients}} @@ -321,10 +341,9 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -856,7 +875,11 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -865,7 +888,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) {{#hasHttpSignatureMethods}} else: # The HTTP signature scheme requires multiple HTTP headers @@ -873,7 +896,8 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) {{/hasHttpSignatureMethods}} elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) diff --git a/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache b/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache index fefd5e2af81d..220c8335c36f 100644 --- a/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache +++ b/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache @@ -11,6 +11,7 @@ from typing import Any, Dict, Optional, Union import aiohttp import aiohttp_retry +from multidict import CIMultiDict from {{packageName}}.exceptions import ApiException, ApiValueError @@ -191,7 +192,7 @@ class RESTClientObject: ) post_params = post_params or {} - headers = headers or {} + headers = CIMultiDict(headers or {}) # url already contains the URL query string timeout = _request_timeout or 5 * 60 diff --git a/modules/openapi-generator/src/main/resources/python/common_README.mustache b/modules/openapi-generator/src/main/resources/python/common_README.mustache index 0001c1be1c03..6b3344bc648f 100644 --- a/modules/openapi-generator/src/main/resources/python/common_README.mustache +++ b/modules/openapi-generator/src/main/resources/python/common_README.mustache @@ -108,3 +108,33 @@ Class | Method | HTTP request | Description {{#apiInfo}}{{#apis}}{{#-last}}{{infoEmail}} {{/-last}}{{/apis}}{{/apiInfo}} + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/modules/openapi-generator/src/main/resources/python/httpx/rest.mustache b/modules/openapi-generator/src/main/resources/python/httpx/rest.mustache index 4cd2e513896a..749b7ffbadbf 100644 --- a/modules/openapi-generator/src/main/resources/python/httpx/rest.mustache +++ b/modules/openapi-generator/src/main/resources/python/httpx/rest.mustache @@ -110,7 +110,7 @@ class RESTClientObject: ) post_params = post_params or {} - headers = headers or {} + headers = {{httpxModule}}.Headers(headers or {}) timeout = _request_timeout or 5 * 60 if 'Content-Type' not in headers: diff --git a/modules/openapi-generator/src/main/resources/python/rest.mustache b/modules/openapi-generator/src/main/resources/python/rest.mustache index 5f56a2d60b32..efefcf117882 100644 --- a/modules/openapi-generator/src/main/resources/python/rest.mustache +++ b/modules/openapi-generator/src/main/resources/python/rest.mustache @@ -212,7 +212,7 @@ class RESTClientObject: ) post_params = post_params or {} - headers = headers or {} + headers = urllib3.HTTPHeaderDict(headers or {}) timeout = None if _request_timeout: diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java index 4c90e38d4ab7..3a92212c882e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java @@ -174,9 +174,9 @@ public void testJsonContentHeaderUsesJsonSerialization() throws IOException { TestUtils.assertFileContains( api, "import json", - "_header_params['X-Json-Arg'] = json.dumps(", + "self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps(", "self.api_client.sanitize_for_serialization(x_json_arg)", - "_header_params['X-Plain-Arg'] = x_plain_arg"); + "self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg)"); TestUtils.assertFileNotContains( api, @@ -806,7 +806,7 @@ public void testHandleConstantParams() throws IOException { File apiFile = files .get(Paths.get(output.getAbsolutePath(), "openapi_client", "api", "hello_example_api.py").toString()); assertNotNull(apiFile); - assertFileContains(apiFile.toPath(), "_header_params['X-CUSTOM_CONSTANT_HEADER'] = 'CONSTANT_VALUE'"); + assertFileContains(apiFile.toPath(), "self.api_client._set_header(_header_params, 'X-CUSTOM_CONSTANT_HEADER', 'CONSTANT_VALUE')"); assertFileContains(apiFile.toPath(), "_query_params.append(('CONSTANT_QUERY_STRING_KEY', 'CONSTANT_QUERY_STRING_VALUE'))"); } diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md index bbdaf5e1d957..91786c45dfc1 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/README.md @@ -165,3 +165,33 @@ Authentication schemes defined for the API: team@openapitools.org + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/auth_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/auth_api.py index 3ad40309ce6f..551e07af01bd 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/auth_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/auth_api.py @@ -236,7 +236,7 @@ def _test_auth_http_basic_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -251,7 +251,7 @@ def _test_auth_http_basic_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -482,7 +482,7 @@ def _test_auth_http_bearer_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -497,7 +497,7 @@ def _test_auth_http_bearer_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/body_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/body_api.py index c4b05d54f131..69360616c450 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/body_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/body_api.py @@ -241,7 +241,7 @@ def _test_binary_gif_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -256,7 +256,7 @@ def _test_binary_gif_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'image/gif' @@ -499,7 +499,7 @@ def _test_body_application_octetstream_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -524,7 +524,7 @@ def _test_body_application_octetstream_binary_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -533,7 +533,7 @@ def _test_body_application_octetstream_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -543,7 +543,7 @@ def _test_body_application_octetstream_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -781,7 +781,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -798,7 +798,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -807,7 +807,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -817,7 +817,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1054,7 +1054,7 @@ def _test_body_multipart_formdata_single_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1071,7 +1071,7 @@ def _test_body_multipart_formdata_single_binary_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1080,7 +1080,7 @@ def _test_body_multipart_formdata_single_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1090,7 +1090,7 @@ def _test_body_multipart_formdata_single_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1327,7 +1327,7 @@ def _test_echo_body_all_of_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1344,7 +1344,7 @@ def _test_echo_body_all_of_pet_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1353,7 +1353,7 @@ def _test_echo_body_all_of_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1363,7 +1363,7 @@ def _test_echo_body_all_of_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1600,7 +1600,7 @@ def _test_echo_body_free_form_object_response_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1617,7 +1617,7 @@ def _test_echo_body_free_form_object_response_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1626,7 +1626,7 @@ def _test_echo_body_free_form_object_response_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1636,7 +1636,7 @@ def _test_echo_body_free_form_object_response_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1873,7 +1873,7 @@ def _test_echo_body_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1890,7 +1890,7 @@ def _test_echo_body_pet_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1899,7 +1899,7 @@ def _test_echo_body_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1909,7 +1909,7 @@ def _test_echo_body_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2146,7 +2146,7 @@ def _test_echo_body_pet_response_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2163,7 +2163,7 @@ def _test_echo_body_pet_response_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2172,7 +2172,7 @@ def _test_echo_body_pet_response_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2182,7 +2182,7 @@ def _test_echo_body_pet_response_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2419,7 +2419,7 @@ def _test_echo_body_string_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2436,7 +2436,7 @@ def _test_echo_body_string_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2445,7 +2445,7 @@ def _test_echo_body_string_enum_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2455,7 +2455,7 @@ def _test_echo_body_string_enum_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2692,7 +2692,7 @@ def _test_echo_body_tag_response_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2709,7 +2709,7 @@ def _test_echo_body_tag_response_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2718,7 +2718,7 @@ def _test_echo_body_tag_response_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2728,7 +2728,7 @@ def _test_echo_body_tag_response_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/form_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/form_api.py index e4e3ddffa3ac..e9b0038cda16 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/form_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/form_api.py @@ -277,7 +277,7 @@ def _test_form_integer_boolean_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -298,7 +298,7 @@ def _test_form_integer_boolean_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -307,7 +307,7 @@ def _test_form_integer_boolean_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -317,7 +317,7 @@ def _test_form_integer_boolean_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -554,7 +554,7 @@ def _test_form_object_multipart_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -571,7 +571,7 @@ def _test_form_object_multipart_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -580,7 +580,7 @@ def _test_form_object_multipart_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -590,7 +590,7 @@ def _test_form_object_multipart_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -892,7 +892,7 @@ def _test_form_oneof_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -919,7 +919,7 @@ def _test_form_oneof_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -928,7 +928,7 @@ def _test_form_oneof_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -938,7 +938,7 @@ def _test_form_oneof_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/header_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/header_api.py index 9dbee4922feb..b7572b76afec 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/header_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/header_api.py @@ -303,7 +303,7 @@ def _test_header_integer_boolean_string_enums_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -314,21 +314,21 @@ def _test_header_integer_boolean_string_enums_serialize( # process the query parameters # process the header parameters if integer_header is not None: - _header_params['integer_header'] = integer_header + self.api_client._set_header(_header_params, 'integer_header', integer_header) if boolean_header is not None: - _header_params['boolean_header'] = boolean_header + self.api_client._set_header(_header_params, 'boolean_header', boolean_header) if string_header is not None: - _header_params['string_header'] = string_header + self.api_client._set_header(_header_params, 'string_header', string_header) if enum_nonref_string_header is not None: - _header_params['enum_nonref_string_header'] = enum_nonref_string_header + self.api_client._set_header(_header_params, 'enum_nonref_string_header', enum_nonref_string_header) if enum_ref_string_header is not None: - _header_params['enum_ref_string_header'] = enum_ref_string_header + self.api_client._set_header(_header_params, 'enum_ref_string_header', enum_ref_string_header) # process the form parameters # process the body parameter # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py index e4a07a198eb4..d3e2de0529f9 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py @@ -289,7 +289,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_ _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -312,7 +312,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_ # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py index 05837d93cbee..d8271833134e 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py @@ -267,7 +267,7 @@ def _test_enum_ref_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -290,7 +290,7 @@ def _test_enum_ref_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -559,7 +559,7 @@ def _test_query_datetime_date_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -604,7 +604,7 @@ def _test_query_datetime_date_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -873,7 +873,7 @@ def _test_query_integer_boolean_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -900,7 +900,7 @@ def _test_query_integer_boolean_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1143,7 +1143,7 @@ def _test_query_style_deep_object_explode_true_object_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1162,7 +1162,7 @@ def _test_query_style_deep_object_explode_true_object_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1405,7 +1405,7 @@ def _test_query_style_deep_object_explode_true_object_all_of_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1424,7 +1424,7 @@ def _test_query_style_deep_object_explode_true_object_all_of_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1668,7 +1668,7 @@ def _test_query_style_form_explode_false_array_integer_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1687,7 +1687,7 @@ def _test_query_style_form_explode_false_array_integer_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1931,7 +1931,7 @@ def _test_query_style_form_explode_false_array_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1950,7 +1950,7 @@ def _test_query_style_form_explode_false_array_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2193,7 +2193,7 @@ def _test_query_style_form_explode_true_array_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2212,7 +2212,7 @@ def _test_query_style_form_explode_true_array_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2455,7 +2455,7 @@ def _test_query_style_form_explode_true_object_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2474,7 +2474,7 @@ def _test_query_style_form_explode_true_object_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2717,7 +2717,7 @@ def _test_query_style_form_explode_true_object_all_of_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2736,7 +2736,7 @@ def _test_query_style_form_explode_true_object_all_of_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2993,7 +2993,7 @@ def _test_query_style_json_serialization_object_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3016,7 +3016,7 @@ def _test_query_style_json_serialization_object_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py index 77721a58cb85..516f7fb1a206 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py @@ -24,7 +24,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from openapi_client.configuration import Configuration @@ -104,16 +104,36 @@ def __exit__(self, exc_type, exc_value, traceback): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -180,10 +200,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -705,7 +724,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -714,7 +737,7 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py index 9a0c6d4de785..702a9b13b966 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py @@ -217,7 +217,7 @@ def request( ) post_params = post_params or {} - headers = headers or {} + headers = urllib3.HTTPHeaderDict(headers or {}) timeout = None if _request_timeout: diff --git a/samples/client/echo_api/python/README.md b/samples/client/echo_api/python/README.md index bbdaf5e1d957..91786c45dfc1 100644 --- a/samples/client/echo_api/python/README.md +++ b/samples/client/echo_api/python/README.md @@ -165,3 +165,33 @@ Authentication schemes defined for the API: team@openapitools.org + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/client/echo_api/python/openapi_client/api/auth_api.py b/samples/client/echo_api/python/openapi_client/api/auth_api.py index 3ad40309ce6f..551e07af01bd 100644 --- a/samples/client/echo_api/python/openapi_client/api/auth_api.py +++ b/samples/client/echo_api/python/openapi_client/api/auth_api.py @@ -236,7 +236,7 @@ def _test_auth_http_basic_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -251,7 +251,7 @@ def _test_auth_http_basic_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -482,7 +482,7 @@ def _test_auth_http_bearer_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -497,7 +497,7 @@ def _test_auth_http_bearer_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python/openapi_client/api/body_api.py b/samples/client/echo_api/python/openapi_client/api/body_api.py index c4b05d54f131..69360616c450 100644 --- a/samples/client/echo_api/python/openapi_client/api/body_api.py +++ b/samples/client/echo_api/python/openapi_client/api/body_api.py @@ -241,7 +241,7 @@ def _test_binary_gif_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -256,7 +256,7 @@ def _test_binary_gif_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'image/gif' @@ -499,7 +499,7 @@ def _test_body_application_octetstream_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -524,7 +524,7 @@ def _test_body_application_octetstream_binary_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -533,7 +533,7 @@ def _test_body_application_octetstream_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -543,7 +543,7 @@ def _test_body_application_octetstream_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -781,7 +781,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -798,7 +798,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -807,7 +807,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -817,7 +817,7 @@ def _test_body_multipart_formdata_array_of_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1054,7 +1054,7 @@ def _test_body_multipart_formdata_single_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1071,7 +1071,7 @@ def _test_body_multipart_formdata_single_binary_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1080,7 +1080,7 @@ def _test_body_multipart_formdata_single_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1090,7 +1090,7 @@ def _test_body_multipart_formdata_single_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1327,7 +1327,7 @@ def _test_echo_body_all_of_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1344,7 +1344,7 @@ def _test_echo_body_all_of_pet_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1353,7 +1353,7 @@ def _test_echo_body_all_of_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1363,7 +1363,7 @@ def _test_echo_body_all_of_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1600,7 +1600,7 @@ def _test_echo_body_free_form_object_response_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1617,7 +1617,7 @@ def _test_echo_body_free_form_object_response_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1626,7 +1626,7 @@ def _test_echo_body_free_form_object_response_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1636,7 +1636,7 @@ def _test_echo_body_free_form_object_response_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1873,7 +1873,7 @@ def _test_echo_body_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1890,7 +1890,7 @@ def _test_echo_body_pet_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1899,7 +1899,7 @@ def _test_echo_body_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1909,7 +1909,7 @@ def _test_echo_body_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2146,7 +2146,7 @@ def _test_echo_body_pet_response_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2163,7 +2163,7 @@ def _test_echo_body_pet_response_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2172,7 +2172,7 @@ def _test_echo_body_pet_response_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2182,7 +2182,7 @@ def _test_echo_body_pet_response_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2419,7 +2419,7 @@ def _test_echo_body_string_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2436,7 +2436,7 @@ def _test_echo_body_string_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2445,7 +2445,7 @@ def _test_echo_body_string_enum_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2455,7 +2455,7 @@ def _test_echo_body_string_enum_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2692,7 +2692,7 @@ def _test_echo_body_tag_response_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2709,7 +2709,7 @@ def _test_echo_body_tag_response_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2718,7 +2718,7 @@ def _test_echo_body_tag_response_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2728,7 +2728,7 @@ def _test_echo_body_tag_response_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/client/echo_api/python/openapi_client/api/form_api.py b/samples/client/echo_api/python/openapi_client/api/form_api.py index e4e3ddffa3ac..e9b0038cda16 100644 --- a/samples/client/echo_api/python/openapi_client/api/form_api.py +++ b/samples/client/echo_api/python/openapi_client/api/form_api.py @@ -277,7 +277,7 @@ def _test_form_integer_boolean_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -298,7 +298,7 @@ def _test_form_integer_boolean_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -307,7 +307,7 @@ def _test_form_integer_boolean_string_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -317,7 +317,7 @@ def _test_form_integer_boolean_string_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -554,7 +554,7 @@ def _test_form_object_multipart_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -571,7 +571,7 @@ def _test_form_object_multipart_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -580,7 +580,7 @@ def _test_form_object_multipart_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -590,7 +590,7 @@ def _test_form_object_multipart_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -892,7 +892,7 @@ def _test_form_oneof_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -919,7 +919,7 @@ def _test_form_oneof_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -928,7 +928,7 @@ def _test_form_oneof_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -938,7 +938,7 @@ def _test_form_oneof_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/client/echo_api/python/openapi_client/api/header_api.py b/samples/client/echo_api/python/openapi_client/api/header_api.py index 9dbee4922feb..b7572b76afec 100644 --- a/samples/client/echo_api/python/openapi_client/api/header_api.py +++ b/samples/client/echo_api/python/openapi_client/api/header_api.py @@ -303,7 +303,7 @@ def _test_header_integer_boolean_string_enums_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -314,21 +314,21 @@ def _test_header_integer_boolean_string_enums_serialize( # process the query parameters # process the header parameters if integer_header is not None: - _header_params['integer_header'] = integer_header + self.api_client._set_header(_header_params, 'integer_header', integer_header) if boolean_header is not None: - _header_params['boolean_header'] = boolean_header + self.api_client._set_header(_header_params, 'boolean_header', boolean_header) if string_header is not None: - _header_params['string_header'] = string_header + self.api_client._set_header(_header_params, 'string_header', string_header) if enum_nonref_string_header is not None: - _header_params['enum_nonref_string_header'] = enum_nonref_string_header + self.api_client._set_header(_header_params, 'enum_nonref_string_header', enum_nonref_string_header) if enum_ref_string_header is not None: - _header_params['enum_ref_string_header'] = enum_ref_string_header + self.api_client._set_header(_header_params, 'enum_ref_string_header', enum_ref_string_header) # process the form parameters # process the body parameter # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python/openapi_client/api/path_api.py b/samples/client/echo_api/python/openapi_client/api/path_api.py index e4a07a198eb4..d3e2de0529f9 100644 --- a/samples/client/echo_api/python/openapi_client/api/path_api.py +++ b/samples/client/echo_api/python/openapi_client/api/path_api.py @@ -289,7 +289,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_ _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -312,7 +312,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_ # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python/openapi_client/api/query_api.py b/samples/client/echo_api/python/openapi_client/api/query_api.py index 05837d93cbee..d8271833134e 100644 --- a/samples/client/echo_api/python/openapi_client/api/query_api.py +++ b/samples/client/echo_api/python/openapi_client/api/query_api.py @@ -267,7 +267,7 @@ def _test_enum_ref_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -290,7 +290,7 @@ def _test_enum_ref_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -559,7 +559,7 @@ def _test_query_datetime_date_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -604,7 +604,7 @@ def _test_query_datetime_date_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -873,7 +873,7 @@ def _test_query_integer_boolean_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -900,7 +900,7 @@ def _test_query_integer_boolean_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1143,7 +1143,7 @@ def _test_query_style_deep_object_explode_true_object_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1162,7 +1162,7 @@ def _test_query_style_deep_object_explode_true_object_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1405,7 +1405,7 @@ def _test_query_style_deep_object_explode_true_object_all_of_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1424,7 +1424,7 @@ def _test_query_style_deep_object_explode_true_object_all_of_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1668,7 +1668,7 @@ def _test_query_style_form_explode_false_array_integer_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1687,7 +1687,7 @@ def _test_query_style_form_explode_false_array_integer_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -1931,7 +1931,7 @@ def _test_query_style_form_explode_false_array_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1950,7 +1950,7 @@ def _test_query_style_form_explode_false_array_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2193,7 +2193,7 @@ def _test_query_style_form_explode_true_array_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2212,7 +2212,7 @@ def _test_query_style_form_explode_true_array_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2455,7 +2455,7 @@ def _test_query_style_form_explode_true_object_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2474,7 +2474,7 @@ def _test_query_style_form_explode_true_object_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2717,7 +2717,7 @@ def _test_query_style_form_explode_true_object_all_of_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2736,7 +2736,7 @@ def _test_query_style_form_explode_true_object_all_of_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -2993,7 +2993,7 @@ def _test_query_style_json_serialization_object_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3016,7 +3016,7 @@ def _test_query_style_json_serialization_object_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' diff --git a/samples/client/echo_api/python/openapi_client/api_client.py b/samples/client/echo_api/python/openapi_client/api_client.py index 77721a58cb85..516f7fb1a206 100644 --- a/samples/client/echo_api/python/openapi_client/api_client.py +++ b/samples/client/echo_api/python/openapi_client/api_client.py @@ -24,7 +24,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from openapi_client.configuration import Configuration @@ -104,16 +104,36 @@ def __exit__(self, exc_type, exc_value, traceback): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -180,10 +200,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -705,7 +724,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -714,7 +737,7 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/client/echo_api/python/openapi_client/rest.py b/samples/client/echo_api/python/openapi_client/rest.py index 77b4fe56053a..3c35dc796332 100644 --- a/samples/client/echo_api/python/openapi_client/rest.py +++ b/samples/client/echo_api/python/openapi_client/rest.py @@ -217,7 +217,7 @@ def request( ) post_params = post_params or {} - headers = headers or {} + headers = urllib3.HTTPHeaderDict(headers or {}) timeout = None if _request_timeout: diff --git a/samples/client/others/python-legacy-model-dictionaries/README.md b/samples/client/others/python-legacy-model-dictionaries/README.md index 0877f5284828..25df6323a088 100644 --- a/samples/client/others/python-legacy-model-dictionaries/README.md +++ b/samples/client/others/python-legacy-model-dictionaries/README.md @@ -112,3 +112,33 @@ Endpoints do not require authorization. + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api/default_api.py b/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api/default_api.py index 77aba80c25eb..2dff3238e7c7 100644 --- a/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api/default_api.py +++ b/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api/default_api.py @@ -197,7 +197,7 @@ def _list_legacy_models_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -212,7 +212,7 @@ def _list_legacy_models_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api_client.py b/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api_client.py index dffac725656d..25b5f869407f 100644 --- a/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api_client.py +++ b/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/api_client.py @@ -26,7 +26,7 @@ from threading import Lock from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union, Any +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from legacy_model_dict_client.configuration import Configuration @@ -208,16 +208,36 @@ def __exit__(self, exc_type, exc_value, traceback): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -284,10 +304,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -813,7 +832,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -822,7 +845,7 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/rest.py b/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/rest.py index c6da043e386b..705b48b5625c 100644 --- a/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/rest.py +++ b/samples/client/others/python-legacy-model-dictionaries/legacy_model_dict_client/rest.py @@ -216,7 +216,7 @@ def request( ) post_params = post_params or {} - headers = headers or {} + headers = urllib3.HTTPHeaderDict(headers or {}) timeout = None if _request_timeout: diff --git a/samples/openapi3/client/petstore/python-aiohttp/README.md b/samples/openapi3/client/petstore/python-aiohttp/README.md index 3f56c38a5e94..7e15564de3cc 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/README.md +++ b/samples/openapi3/client/petstore/python-aiohttp/README.md @@ -348,3 +348,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/another_fake_api.py index d840f94840b5..efe518659150 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/another_fake_api.py @@ -269,7 +269,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -286,7 +286,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -295,7 +295,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -305,7 +305,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/default_api.py index de0a0e9d83f5..9370d404e284 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/default_api.py @@ -251,7 +251,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -266,7 +266,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py index 37debd4fa721..99e4031552c1 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py @@ -284,7 +284,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -303,7 +303,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -313,7 +313,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -547,7 +547,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -786,7 +786,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -801,7 +801,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1067,7 +1067,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1082,7 +1082,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1092,7 +1092,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1103,7 +1103,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1341,7 +1341,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1358,7 +1358,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1367,7 +1367,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1377,7 +1377,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1614,7 +1614,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1631,7 +1631,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1640,7 +1640,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1650,7 +1650,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1887,7 +1887,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1904,7 +1904,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1913,7 +1913,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1923,7 +1923,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2160,7 +2160,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2177,7 +2177,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2186,7 +2186,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2196,7 +2196,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2447,7 +2447,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2468,7 +2468,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2477,7 +2477,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2487,7 +2487,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2708,7 +2708,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2723,7 +2723,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -2950,7 +2950,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2965,7 +2965,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3192,7 +3192,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3207,7 +3207,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3434,7 +3434,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3449,7 +3449,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3676,7 +3676,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3691,7 +3691,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3918,7 +3918,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3933,7 +3933,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4160,7 +4160,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4175,7 +4175,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4402,7 +4402,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4417,7 +4417,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4644,7 +4644,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4659,7 +4659,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4886,7 +4886,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4901,7 +4901,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5141,7 +5141,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5396,7 +5396,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5415,7 +5415,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5425,7 +5425,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5662,7 +5662,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5689,7 +5689,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5699,7 +5699,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5936,7 +5936,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5955,7 +5955,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5965,7 +5965,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6212,7 +6212,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6235,7 +6235,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6245,7 +6245,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6482,7 +6482,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6499,7 +6499,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6508,7 +6508,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6518,7 +6518,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6765,7 +6765,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7023,7 +7023,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7038,7 +7038,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -7466,7 +7466,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7513,7 +7513,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7523,7 +7523,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7751,7 +7751,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7766,7 +7766,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8074,7 +8074,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8101,9 +8101,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -8346,7 +8346,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8365,7 +8365,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8375,7 +8375,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8612,7 +8612,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8631,7 +8631,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8641,7 +8641,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8891,7 +8891,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8912,7 +8912,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8922,7 +8922,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9169,7 +9169,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9180,11 +9180,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -9423,7 +9423,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9442,7 +9442,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9452,7 +9452,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9772,7 +9772,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10051,7 +10051,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10070,7 +10070,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10080,7 +10080,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10343,7 +10343,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10364,7 +10364,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -10373,7 +10373,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10383,7 +10383,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_classname_tags123_api.py index 3bdf586ba12d..61dbccb2cc61 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_classname_tags123_api.py @@ -269,7 +269,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -286,7 +286,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -295,7 +295,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -305,7 +305,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/import_test_datetime_api.py index d2470196f063..3556c26f0a22 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/import_test_datetime_api.py @@ -251,7 +251,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -266,7 +266,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/pet_api.py index 8f290212ddbb..6aec11242f59 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/pet_api.py @@ -274,7 +274,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -293,7 +293,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -304,7 +304,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -559,7 +559,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -572,7 +572,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -819,7 +819,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -838,7 +838,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1091,7 +1091,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1110,7 +1110,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1362,7 +1362,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1379,7 +1379,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1633,7 +1633,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1652,7 +1652,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1663,7 +1663,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1931,7 +1931,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1954,7 +1954,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1964,7 +1964,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2228,7 +2228,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2249,7 +2249,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2258,7 +2258,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2268,7 +2268,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2532,7 +2532,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2553,7 +2553,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2562,7 +2562,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2572,7 +2572,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/store_api.py index e47aba3dc9f0..85a52d796667 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/store_api.py @@ -273,7 +273,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -513,7 +513,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -528,7 +528,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -778,7 +778,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -795,7 +795,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1042,7 +1042,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1059,7 +1059,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1069,7 +1069,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1079,7 +1079,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/user_api.py index 1246baedd369..a6ed97e521c4 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/user_api.py @@ -273,7 +273,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -292,7 +292,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -302,7 +302,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -537,7 +537,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -556,7 +556,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -566,7 +566,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -801,7 +801,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -820,7 +820,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -830,7 +830,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1070,7 +1070,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1329,7 +1329,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1346,7 +1346,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1606,7 +1606,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1629,7 +1629,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1857,7 +1857,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2124,7 +2124,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2145,7 +2145,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2155,7 +2155,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py index 50741490c29c..249166feb5ba 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -106,16 +106,36 @@ async def close(self): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -179,10 +199,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -704,7 +723,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -713,14 +736,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py index 374aeeb993fa..f9c8d3b2bab2 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py @@ -20,6 +20,7 @@ import aiohttp import aiohttp_retry +from multidict import CIMultiDict from petstore_api.exceptions import ApiException, ApiValueError @@ -193,7 +194,7 @@ async def request( ) post_params = post_params or {} - headers = headers or {} + headers = CIMultiDict(headers or {}) # url already contains the URL query string timeout = _request_timeout or 5 * 60 diff --git a/samples/openapi3/client/petstore/python-aiohttp/tests/test_request_headers.py b/samples/openapi3/client/petstore/python-aiohttp/tests/test_request_headers.py new file mode 100644 index 000000000000..f59bf5a64c49 --- /dev/null +++ b/samples/openapi3/client/petstore/python-aiohttp/tests/test_request_headers.py @@ -0,0 +1,228 @@ +"""Request-header behavior for the asyncio client.""" + +import asyncio +from concurrent.futures import ThreadPoolExecutor +import inspect +import unittest +from typing import Any +from unittest.mock import AsyncMock, Mock + +import petstore_api + +ASYNC = inspect.iscoroutinefunction(petstore_api.ApiClient.call_api) + + +class TestRequestHeaders(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.requests: list[dict[str, Any]] = [] + self.client = petstore_api.ApiClient(petstore_api.Configuration( + host='https://example.test', access_token='configured-token', + api_key={'api_key': 'configured-key'}, + )) + response = Mock(status=200, reason='OK', data=b'{}', headers={}) + response.read = AsyncMock(return_value=b'{}') + + def respond(*args, **kwargs): + self.requests.append({**kwargs, 'headers': kwargs['headers'].copy()}) + return response + + async def respond_async(*args, **kwargs): + await asyncio.sleep(0) + return respond(*args, **kwargs) + + self.pool: Any = AsyncMock() if ASYNC else Mock() + self.pool.request.side_effect = respond_async if ASYNC else respond + self.client.rest_client.pool_manager = self.pool + self.api = petstore_api.PetApi(self.client) + self.pet = petstore_api.Pet(name='test', photoUrls=[]) + + async def asyncTearDown(self): + if ASYNC: + await getattr(self.client, 'close')() + else: + self.pool.clear() + + async def call(self, **kwargs): + result = self.api.add_pet(self.pet, **kwargs) + if inspect.isawaitable(result): + await result + + def values(self, headers, name): + if isinstance(headers, dict): + return [value for key, value in headers.items() if key.lower() == name.lower()] + return headers.getall(name) if ASYNC else headers.getlist(name) + + def assert_header(self, name, value): + self.assertEqual(self.values(self.requests[-1]['headers'], name), [value]) + + async def test_generated_content_type_and_accept_are_case_insensitive(self): + for spelling in ('Content-Type', 'content-type', 'CONTENT-TYPE'): + for value in ('application/json', 'text/plain'): + with self.subTest(spelling=spelling, value=value): + headers = {spelling: value, 'accept': 'custom'} + await self.call(_headers=headers) + self.assert_header('content-type', 'application/json') + self.assert_header('accept', 'custom') + self.assertEqual(headers, {spelling: value, 'accept': 'custom'}) + + async def test_user_agent_matches_last_direct_default_header_write(self): + self.client.default_headers['user-agent'] = 'custom' + self.client.default_headers['USER-AGENT'] = 'latest' + defaults = self.client.default_headers.copy() + self.assertEqual(self.client.user_agent, 'latest') + await self.call() + self.assert_header('user-agent', 'latest') + self.assertEqual(self.client.default_headers, defaults) + + async def test_content_type_override_and_defaults_retain_precedence(self): + headers = {'content-type': 'text/plain'} + await self.call(_headers=headers, _content_type='application/custom+json') + self.assert_header('content-type', 'application/custom+json') + self.client.set_default_header('CONTENT-TYPE', 'application/default+json') + defaults = self.client.default_headers.copy() + await self.call(_headers=headers, _content_type='application/custom+json') + self.assert_header('content-type', 'application/default+json') + self.assertEqual(self.client.default_headers, defaults) + self.assertEqual(headers, {'content-type': 'text/plain'}) + + async def test_defaults_last_write_and_user_agent_property(self): + self.client.set_default_header('X-Default', 'old') + self.client.set_default_header('x-default', 'middle') + self.client.set_default_header('X-Default', 'new') + self.client.set_default_header('user-agent', 'custom') + self.assertEqual(self.client.user_agent, 'custom') + headers = {'x-default': 'call', 'X-List': 'first', 'x-list': 'a, b, a'} + await self.call(_headers=headers) + self.assert_header('x-default', 'new') + self.assert_header('user-agent', 'custom') + self.assert_header('x-list', 'a, b, a') + self.assertEqual(headers['X-List'], 'first') + self.client.user_agent = 'reset' + self.assertEqual(self.client.user_agent, 'reset') + self.assertEqual( + len([key for key in self.client.default_headers if key.lower() == 'user-agent']), 1 + ) + + async def test_serializers_preserve_inputs_and_explicit_header_wins(self): + headers = {'content-type': 'text/plain', 'API_KEY': 'call'} + original = headers.copy() + defaults = self.client.default_headers.copy() + params = self.api._delete_pet_serialize( + pet_id=1, api_key='explicit', _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(params[2]['api_key'], 'explicit') + self.api._add_pet_serialize( + pet=self.pet, _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.client.param_serialize('GET', '/pet', header_params=headers, query_params=[]) + self.assertEqual(headers, original) + self.assertEqual(self.client.default_headers, defaults) + + async def test_authentication_and_empty_override(self): + self.client.set_default_header('AUTHORIZATION', 'default') + headers = {'authorization': 'call'} + defaults = self.client.default_headers.copy() + await self.call(_headers=headers, _request_auth={}) + self.assert_header('authorization', 'Bearer configured-token') + auth = {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', 'value': 'Bearer call'} + await self.call(_headers=headers, _request_auth=auth) + self.assert_header('authorization', 'Bearer call') + self.assertEqual(headers, {'authorization': 'call'}) + self.assertEqual(auth['value'], 'Bearer call') + self.assertEqual(self.client.default_headers, defaults) + self.client.set_default_header('API_KEY', 'default') + key_headers = {'Api_Key': 'call'} + params = self.client.param_serialize( + 'GET', '/key', header_params=key_headers, auth_settings=['api_key'], query_params=[] + ) + result = self.client.call_api(*params) + if inspect.isawaitable(result): + await result + self.assert_header('api_key', 'configured-key') + self.assertEqual(key_headers, {'Api_Key': 'call'}) + + async def test_cookie_authentication_appends_without_empty_separator(self): + for value, expected in (('', 'session=two'), ('client=1', 'client=1; session=two')): + headers = {'cookie': value} + params = self.client.param_serialize( + 'GET', '/cookie', header_params=headers, query_params=[], + auth_settings=['cookie'], + _request_auth={ + 'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two', + }, + ) + result = self.client.call_api(*params) + if inspect.isawaitable(result): + await result + self.assert_header('cookie', expected) + self.assertEqual(headers, {'cookie': value}) + + async def test_concurrent_calls_keep_inputs_defaults_and_credentials_isolated(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + def auth(index): + return {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer request-{index}'} + + if ASYNC: + await asyncio.gather(*( + self.call(_headers=headers, _request_auth=auth(index)) for index in range(20) + )) + else: + def run_calls(): + with ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(lambda index: self.api.add_pet( + self.pet, _headers=headers, _request_auth=auth(index) + ), range(20))) + await asyncio.to_thread(run_calls) + self.assertCountEqual( + [request['headers']['authorization'] for request in self.requests], + [f'Bearer request-{index}' for index in range(20)], + ) + await self.call() + self.assert_header('authorization', 'Bearer configured-token') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_transport_reads_lowercase_content_type(self): + headers = {'content-type': 'application/x-www-form-urlencoded'} + result = self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + if inspect.isawaitable(result): + await result + self.assert_header('content-type', 'application/x-www-form-urlencoded') + import aiohttp + self.assertIsInstance(self.requests[-1]['data'], aiohttp.FormData) + self.assertEqual(headers, {'content-type': 'application/x-www-form-urlencoded'}) + + async def test_transport_reads_lowercase_content_type_and_preserves_repeated_fields(self): + from multidict import CIMultiDict + headers: Any = CIMultiDict([ + ('content-type', 'application/x-www-form-urlencoded'), + ('x-list', 'a'), ('x-list', 'b'), + ]) + result = self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + if inspect.isawaitable(result): + await result + self.assert_header('content-type', 'application/x-www-form-urlencoded') + self.assertEqual(self.values(self.requests[-1]['headers'], 'x-list'), ['a', 'b']) + self.assertEqual(self.values(headers, 'x-list'), ['a', 'b']) + import aiohttp + self.assertIsInstance(self.requests[-1]['data'], aiohttp.FormData) + + async def test_transport_multipart_removes_content_type_without_mutating_input(self): + headers = {'content-type': 'multipart/form-data'} + result = self.client.rest_client.request( + 'POST', 'https://example.test/upload', headers=headers, + post_params=[('file', ('name.txt', b'content', 'text/plain'))], + ) + if inspect.isawaitable(result): + await result + self.assertNotIn('content-type', self.requests[-1]['headers']) + self.assertEqual(headers, {'content-type': 'multipart/form-data'}) diff --git a/samples/openapi3/client/petstore/python-httpx-sync/README.md b/samples/openapi3/client/petstore/python-httpx-sync/README.md index b69b28fb19fc..d696bf8659b7 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/README.md +++ b/samples/openapi3/client/petstore/python-httpx-sync/README.md @@ -326,3 +326,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/another_fake_api.py index 3c8c561664d3..3e70d5e8c536 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/another_fake_api.py @@ -353,7 +353,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -370,7 +370,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -379,7 +379,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -389,7 +389,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/default_api.py index 227cb6c9bf89..0044d1e0287c 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/default_api.py @@ -329,7 +329,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -344,7 +344,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py index 05c6c53603af..4a6f7b7183da 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py @@ -368,7 +368,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -387,7 +387,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -397,7 +397,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -733,7 +733,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1068,7 +1068,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1083,7 +1083,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1463,7 +1463,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1478,7 +1478,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1488,7 +1488,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1499,7 +1499,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1839,7 +1839,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1856,7 +1856,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1865,7 +1865,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1875,7 +1875,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2214,7 +2214,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2231,7 +2231,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2240,7 +2240,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2250,7 +2250,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2589,7 +2589,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2606,7 +2606,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2615,7 +2615,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2625,7 +2625,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2964,7 +2964,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2981,7 +2981,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2990,7 +2990,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3000,7 +3000,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3359,7 +3359,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3380,7 +3380,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -3389,7 +3389,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3399,7 +3399,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3716,7 +3716,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3731,7 +3731,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4054,7 +4054,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4069,7 +4069,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4392,7 +4392,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4407,7 +4407,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4730,7 +4730,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4745,7 +4745,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5068,7 +5068,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5083,7 +5083,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -5406,7 +5406,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5421,7 +5421,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5744,7 +5744,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5759,7 +5759,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6082,7 +6082,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6097,7 +6097,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6420,7 +6420,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6435,7 +6435,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -6758,7 +6758,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6773,7 +6773,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -7115,7 +7115,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7472,7 +7472,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7491,7 +7491,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7501,7 +7501,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7840,7 +7840,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7867,7 +7867,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7877,7 +7877,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8216,7 +8216,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8235,7 +8235,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8245,7 +8245,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8600,7 +8600,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8623,7 +8623,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8633,7 +8633,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8972,7 +8972,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8989,7 +8989,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8998,7 +8998,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9008,7 +9008,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9363,7 +9363,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9717,7 +9717,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9732,7 +9732,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -10346,7 +10346,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10393,7 +10393,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10403,7 +10403,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10727,7 +10727,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10742,7 +10742,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -11182,7 +11182,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -11209,9 +11209,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -11556,7 +11556,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -11575,7 +11575,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -11585,7 +11585,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -11924,7 +11924,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -11943,7 +11943,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -11953,7 +11953,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -12311,7 +12311,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -12332,7 +12332,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -12342,7 +12342,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -12697,7 +12697,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -12708,11 +12708,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -13053,7 +13053,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -13072,7 +13072,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -13082,7 +13082,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -13540,7 +13540,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -13921,7 +13921,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -13940,7 +13940,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -13950,7 +13950,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -14327,7 +14327,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -14348,7 +14348,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -14357,7 +14357,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -14367,7 +14367,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_classname_tags123_api.py index 3ae5963332d5..da4d328c100f 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_classname_tags123_api.py @@ -353,7 +353,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -370,7 +370,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -379,7 +379,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -389,7 +389,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/import_test_datetime_api.py index cf3b1e092de7..fd933e5180e0 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/import_test_datetime_api.py @@ -329,7 +329,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -344,7 +344,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/pet_api.py index 4228f8f36727..d304e3fba145 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/pet_api.py @@ -358,7 +358,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -377,7 +377,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -388,7 +388,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -751,7 +751,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -764,7 +764,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -1113,7 +1113,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1132,7 +1132,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1487,7 +1487,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1506,7 +1506,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1860,7 +1860,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1877,7 +1877,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -2233,7 +2233,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2252,7 +2252,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2263,7 +2263,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2645,7 +2645,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2668,7 +2668,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2678,7 +2678,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3056,7 +3056,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3077,7 +3077,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3086,7 +3086,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3096,7 +3096,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3474,7 +3474,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3495,7 +3495,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3504,7 +3504,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3514,7 +3514,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/store_api.py index 3829184bb1fe..b6c56870658d 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/store_api.py @@ -357,7 +357,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -693,7 +693,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -708,7 +708,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1060,7 +1060,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1077,7 +1077,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1426,7 +1426,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1443,7 +1443,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1453,7 +1453,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1463,7 +1463,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/user_api.py index 85d34b6ebb62..d07e94b739fe 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/user_api.py @@ -357,7 +357,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -376,7 +376,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -386,7 +386,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -723,7 +723,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -742,7 +742,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -752,7 +752,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1089,7 +1089,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1108,7 +1108,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1118,7 +1118,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1460,7 +1460,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1821,7 +1821,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1838,7 +1838,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -2206,7 +2206,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2229,7 +2229,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -2553,7 +2553,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2928,7 +2928,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2949,7 +2949,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2959,7 +2959,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api_client.py index 44b7a286135f..43782b4ec85b 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -106,16 +106,36 @@ async def close(self): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -182,10 +202,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -707,7 +726,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -716,14 +739,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/rest.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/rest.py index e1d0094b6c56..f28745ec0fe7 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/rest.py @@ -119,7 +119,7 @@ async def request( ) post_params = post_params or {} - headers = headers or {} + headers = httpx.Headers(headers or {}) timeout = _request_timeout or 5 * 60 if 'Content-Type' not in headers: diff --git a/samples/openapi3/client/petstore/python-httpx-sync/tests/test_request_headers.py b/samples/openapi3/client/petstore/python-httpx-sync/tests/test_request_headers.py new file mode 100644 index 000000000000..addec9e857d8 --- /dev/null +++ b/samples/openapi3/client/petstore/python-httpx-sync/tests/test_request_headers.py @@ -0,0 +1,247 @@ +"""Regression tests for request-local, case-insensitive HTTPX headers.""" + +import asyncio +from concurrent.futures import ThreadPoolExecutor +import importlib +import unittest +from typing import Any + +import petstore_api +from petstore_api import rest + +httpx = importlib.import_module(rest.RESTResponseType.__module__.split('.')[0]) + + +class TestRequestHeaders(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.requests: list[Any] = [] + + async def respond(request): + self.requests.append(request) + await asyncio.sleep(0) + return httpx.Response(200, json={}) + + self.client = petstore_api.ApiClient(petstore_api.Configuration( + host='https://example.test', access_token='configured-token', + api_key={'api_key': 'configured-key'}, + )) + self.client.rest_client.pool_manager = httpx.AsyncClient( + transport=httpx.MockTransport(respond) + ) + self.api = petstore_api.PetApi(self.client) + self.pet = petstore_api.Pet(name='test', photoUrls=[]) + + async def asyncTearDown(self): + await self.client.close() + + def assert_single_header(self, request, name, value): + self.assertEqual(request.headers.get_list(name), [value]) + + async def test_serializers_copy_header_inputs_before_adding_defaults_and_auth(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + original = headers.copy() + defaults = self.client.default_headers.copy() + self.api._add_pet_serialize( + pet=self.pet, _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(headers, original) + self.client.param_serialize( + 'GET', '/pet', header_params=headers, query_params=[], auth_settings=['petstore_auth'] + ) + self.assertEqual(headers, original) + self.assertEqual(self.client.default_headers, defaults) + + async def test_user_agent_matches_last_direct_default_header_write(self): + self.client.default_headers['user-agent'] = 'custom' + self.client.default_headers['USER-AGENT'] = 'latest' + defaults = self.client.default_headers.copy() + self.assertEqual(self.client.user_agent, 'latest') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'latest') + self.assertEqual(self.client.default_headers, defaults) + + async def test_generated_content_type_replaces_case_variants(self): + for spelling in ('Content-Type', 'content-type', 'CONTENT-TYPE'): + for value in ('application/json', 'text/plain'): + with self.subTest(spelling=spelling, value=value): + headers = {spelling: value, 'accept': 'application/custom'} + original = headers.copy() + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/json' + ) + self.assert_single_header(self.requests[-1], 'accept', 'application/custom') + self.assertEqual(headers, original) + + async def test_content_type_override_and_client_default_precedence(self): + headers = {'content-type': 'text/plain'} + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/custom+json') + self.client.set_default_header('CONTENT-TYPE', 'application/default+json') + defaults = self.client.default_headers.copy() + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/default+json') + self.assertEqual(self.client.default_headers, defaults) + self.assertEqual(headers, {'content-type': 'text/plain'}) + + async def test_defaults_and_last_inserted_case_variant_win_without_splitting_values(self): + self.client.set_default_header('X-Default', 'earlier-default') + self.client.set_default_header('x-default', 'middle') + self.client.set_default_header('X-Default', 'default') + headers = {'x-default': 'call', 'X-List': 'first', 'x-list': 'a, b, a'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-default', 'default') + self.assert_single_header(self.requests[-1], 'x-list', 'a, b, a') + self.assertIn('x-list', self.requests[-1].headers) + self.assertEqual(headers['X-List'], 'first') + + async def test_user_agent_default_updates_case_insensitively(self): + self.client.set_default_header('user-agent', 'custom') + self.assertEqual(self.client.user_agent, 'custom') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'custom') + self.client.user_agent = 'reset' + self.assertEqual(self.client.user_agent, 'reset') + self.assertEqual( + len([key for key in self.client.default_headers if key.lower() == 'user-agent']), 1 + ) + + async def test_empty_request_auth_keeps_configured_authentication(self): + await self.api.add_pet(self.pet, _request_auth={}) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + + async def test_empty_cookie_does_not_add_leading_separator(self): + params = self.client.param_serialize( + 'GET', '/cookie', header_params={'cookie': ''}, query_params=[], + auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'session=two') + + async def test_explicit_header_parameter_overrides_call_headers(self): + headers = {'API_KEY': 'call'} + params = self.api._delete_pet_serialize( + pet_id=1, api_key='explicit', _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(params[2]['api_key'], 'explicit') + self.assertEqual(headers, {'API_KEY': 'call'}) + + async def test_authentication_overrides_case_variants_and_preserves_inputs(self): + self.client.set_default_header('AUTHORIZATION', 'default') + defaults = self.client.default_headers.copy() + headers = {'authorization': 'call'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + auth = {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', 'value': 'Bearer call'} + await self.api.add_pet(self.pet, _headers=headers, _request_auth=auth) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer call') + self.assertEqual(headers, {'authorization': 'call'}) + self.assertEqual(auth['value'], 'Bearer call') + self.assertEqual(self.client.default_headers, defaults) + + async def test_api_key_overrides_default_and_call_case_variants(self): + self.client.set_default_header('API_KEY', 'default') + headers = {'Api_Key': 'call'} + defaults = self.client.default_headers.copy() + params = self.client.param_serialize( + 'GET', '/key', header_params=headers, auth_settings=['api_key'], query_params=[] + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'api_key', 'configured-key') + self.assertEqual(headers, {'Api_Key': 'call'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_cookie_authentication_appends_to_selected_cookie(self): + self.client.cookie = 'client=1' + headers = {'cookie': 'call=1'} + params = self.client.param_serialize( + 'GET', '/cookie', header_params=headers, query_params=[], auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'client=1; session=two') + self.assertEqual(headers, {'cookie': 'call=1'}) + + async def test_concurrent_calls_do_not_share_headers_or_authentication(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + async def call(index): + await self.api.add_pet(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer request-{index}', + }) + + await asyncio.gather(*(call(index) for index in range(20))) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer request-{index}' for index in range(20)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_public_mapping_validation_retains_combined_values(self): + headers = httpx.Headers([('X-List', 'a'), ('x-list', 'b')]) + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-list', 'a, b') + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_reads_lowercase_content_type_and_preserves_repeated_fields(self): + headers = httpx.Headers([ + ('content-type', 'application/x-www-form-urlencoded'), + ('x-list', 'a'), ('x-list', 'b'), + ]) + await self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/x-www-form-urlencoded' + ) + self.assertEqual(self.requests[-1].content, b'field=value') + self.assertEqual(self.requests[-1].headers.get_list('x-list'), ['a', 'b']) + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_multipart_does_not_mutate_input(self): + headers = {'content-type': 'multipart/form-data'} + await self.client.rest_client.request( + 'POST', 'https://example.test/upload', headers=headers, + post_params=[('file', ('name.txt', b'content', 'text/plain'))], + ) + self.assertTrue( + self.requests[-1].headers['content-type'].startswith('multipart/form-data;') + ) + self.assertEqual(len(self.requests[-1].headers.get_list('content-type')), 1) + self.assertEqual(headers, {'content-type': 'multipart/form-data'}) + + async def test_sync_calls_use_request_local_headers(self): + if not hasattr(self.api, 'add_pet_sync'): + self.skipTest('Sample does not enable supportHttpxSync') + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + def call(index): + getattr(self.api, 'add_pet_sync')(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer sync-{index}', + }) + + def run_calls(): + with ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(call, range(8))) + + await asyncio.to_thread(run_calls) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer sync-{index}' for index in range(8)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) diff --git a/samples/openapi3/client/petstore/python-httpx/README.md b/samples/openapi3/client/petstore/python-httpx/README.md index b69b28fb19fc..d696bf8659b7 100644 --- a/samples/openapi3/client/petstore/python-httpx/README.md +++ b/samples/openapi3/client/petstore/python-httpx/README.md @@ -326,3 +326,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/another_fake_api.py index 9ceb307bbb24..968ac5d448d0 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/another_fake_api.py @@ -250,7 +250,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -276,7 +276,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -286,7 +286,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/default_api.py index dc264f69428e..5a766861f81f 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/default_api.py @@ -232,7 +232,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -247,7 +247,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py index 7fb0a185a264..8c7dc59ccaac 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py @@ -265,7 +265,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -284,7 +284,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -294,7 +294,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -528,7 +528,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -767,7 +767,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -782,7 +782,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1048,7 +1048,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1063,7 +1063,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1073,7 +1073,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1084,7 +1084,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1322,7 +1322,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1339,7 +1339,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1348,7 +1348,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1358,7 +1358,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1595,7 +1595,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1612,7 +1612,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1621,7 +1621,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1631,7 +1631,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1868,7 +1868,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1885,7 +1885,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1894,7 +1894,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1904,7 +1904,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2141,7 +2141,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2158,7 +2158,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2167,7 +2167,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2177,7 +2177,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2428,7 +2428,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2449,7 +2449,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2458,7 +2458,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2468,7 +2468,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2689,7 +2689,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2704,7 +2704,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -2931,7 +2931,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2946,7 +2946,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3173,7 +3173,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3188,7 +3188,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3415,7 +3415,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3430,7 +3430,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3657,7 +3657,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3672,7 +3672,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3899,7 +3899,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3914,7 +3914,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4141,7 +4141,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4156,7 +4156,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4383,7 +4383,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4398,7 +4398,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4625,7 +4625,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4640,7 +4640,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4867,7 +4867,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4882,7 +4882,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5122,7 +5122,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5377,7 +5377,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5396,7 +5396,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5406,7 +5406,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5643,7 +5643,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5670,7 +5670,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5680,7 +5680,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5917,7 +5917,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5936,7 +5936,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5946,7 +5946,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6193,7 +6193,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6216,7 +6216,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6226,7 +6226,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6463,7 +6463,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6480,7 +6480,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6489,7 +6489,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6499,7 +6499,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6746,7 +6746,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7004,7 +7004,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7019,7 +7019,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -7447,7 +7447,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7494,7 +7494,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7504,7 +7504,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7732,7 +7732,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7747,7 +7747,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8055,7 +8055,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8082,9 +8082,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -8327,7 +8327,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8346,7 +8346,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8356,7 +8356,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8593,7 +8593,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8612,7 +8612,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8622,7 +8622,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8872,7 +8872,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8893,7 +8893,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8903,7 +8903,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9150,7 +9150,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9161,11 +9161,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -9404,7 +9404,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9423,7 +9423,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9433,7 +9433,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9753,7 +9753,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10032,7 +10032,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10051,7 +10051,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10061,7 +10061,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10324,7 +10324,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10345,7 +10345,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -10354,7 +10354,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10364,7 +10364,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_classname_tags123_api.py index 08cf85d488bb..9e6aeb9ed9c9 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_classname_tags123_api.py @@ -250,7 +250,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -276,7 +276,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -286,7 +286,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/import_test_datetime_api.py index 47876e858687..9dbb9cd39e69 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/import_test_datetime_api.py @@ -232,7 +232,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -247,7 +247,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/pet_api.py index 5da83f4a686a..92b61d5dcbad 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/pet_api.py @@ -255,7 +255,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -274,7 +274,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -285,7 +285,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -540,7 +540,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -553,7 +553,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -800,7 +800,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -819,7 +819,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1072,7 +1072,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1091,7 +1091,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1343,7 +1343,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1360,7 +1360,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1614,7 +1614,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1633,7 +1633,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1644,7 +1644,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1912,7 +1912,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1935,7 +1935,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1945,7 +1945,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2209,7 +2209,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2230,7 +2230,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2239,7 +2239,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2249,7 +2249,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2513,7 +2513,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2534,7 +2534,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2543,7 +2543,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2553,7 +2553,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/store_api.py index 79116ca74ca8..5b7543c1b285 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/store_api.py @@ -254,7 +254,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -494,7 +494,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -509,7 +509,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -759,7 +759,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -776,7 +776,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1023,7 +1023,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1040,7 +1040,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1050,7 +1050,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1060,7 +1060,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/user_api.py index 9e4ff6771db8..387ff3f12e8d 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/user_api.py @@ -254,7 +254,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -273,7 +273,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -283,7 +283,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -518,7 +518,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -537,7 +537,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -547,7 +547,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -782,7 +782,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -801,7 +801,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -811,7 +811,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1051,7 +1051,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1310,7 +1310,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1327,7 +1327,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1587,7 +1587,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1610,7 +1610,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1838,7 +1838,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2105,7 +2105,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2126,7 +2126,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2136,7 +2136,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api_client.py index 44b7a286135f..43782b4ec85b 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -106,16 +106,36 @@ async def close(self): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -182,10 +202,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -707,7 +726,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -716,14 +739,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/rest.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/rest.py index e1d0094b6c56..f28745ec0fe7 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/rest.py @@ -119,7 +119,7 @@ async def request( ) post_params = post_params or {} - headers = headers or {} + headers = httpx.Headers(headers or {}) timeout = _request_timeout or 5 * 60 if 'Content-Type' not in headers: diff --git a/samples/openapi3/client/petstore/python-httpx/tests/test_request_headers.py b/samples/openapi3/client/petstore/python-httpx/tests/test_request_headers.py new file mode 100644 index 000000000000..addec9e857d8 --- /dev/null +++ b/samples/openapi3/client/petstore/python-httpx/tests/test_request_headers.py @@ -0,0 +1,247 @@ +"""Regression tests for request-local, case-insensitive HTTPX headers.""" + +import asyncio +from concurrent.futures import ThreadPoolExecutor +import importlib +import unittest +from typing import Any + +import petstore_api +from petstore_api import rest + +httpx = importlib.import_module(rest.RESTResponseType.__module__.split('.')[0]) + + +class TestRequestHeaders(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.requests: list[Any] = [] + + async def respond(request): + self.requests.append(request) + await asyncio.sleep(0) + return httpx.Response(200, json={}) + + self.client = petstore_api.ApiClient(petstore_api.Configuration( + host='https://example.test', access_token='configured-token', + api_key={'api_key': 'configured-key'}, + )) + self.client.rest_client.pool_manager = httpx.AsyncClient( + transport=httpx.MockTransport(respond) + ) + self.api = petstore_api.PetApi(self.client) + self.pet = petstore_api.Pet(name='test', photoUrls=[]) + + async def asyncTearDown(self): + await self.client.close() + + def assert_single_header(self, request, name, value): + self.assertEqual(request.headers.get_list(name), [value]) + + async def test_serializers_copy_header_inputs_before_adding_defaults_and_auth(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + original = headers.copy() + defaults = self.client.default_headers.copy() + self.api._add_pet_serialize( + pet=self.pet, _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(headers, original) + self.client.param_serialize( + 'GET', '/pet', header_params=headers, query_params=[], auth_settings=['petstore_auth'] + ) + self.assertEqual(headers, original) + self.assertEqual(self.client.default_headers, defaults) + + async def test_user_agent_matches_last_direct_default_header_write(self): + self.client.default_headers['user-agent'] = 'custom' + self.client.default_headers['USER-AGENT'] = 'latest' + defaults = self.client.default_headers.copy() + self.assertEqual(self.client.user_agent, 'latest') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'latest') + self.assertEqual(self.client.default_headers, defaults) + + async def test_generated_content_type_replaces_case_variants(self): + for spelling in ('Content-Type', 'content-type', 'CONTENT-TYPE'): + for value in ('application/json', 'text/plain'): + with self.subTest(spelling=spelling, value=value): + headers = {spelling: value, 'accept': 'application/custom'} + original = headers.copy() + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/json' + ) + self.assert_single_header(self.requests[-1], 'accept', 'application/custom') + self.assertEqual(headers, original) + + async def test_content_type_override_and_client_default_precedence(self): + headers = {'content-type': 'text/plain'} + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/custom+json') + self.client.set_default_header('CONTENT-TYPE', 'application/default+json') + defaults = self.client.default_headers.copy() + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/default+json') + self.assertEqual(self.client.default_headers, defaults) + self.assertEqual(headers, {'content-type': 'text/plain'}) + + async def test_defaults_and_last_inserted_case_variant_win_without_splitting_values(self): + self.client.set_default_header('X-Default', 'earlier-default') + self.client.set_default_header('x-default', 'middle') + self.client.set_default_header('X-Default', 'default') + headers = {'x-default': 'call', 'X-List': 'first', 'x-list': 'a, b, a'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-default', 'default') + self.assert_single_header(self.requests[-1], 'x-list', 'a, b, a') + self.assertIn('x-list', self.requests[-1].headers) + self.assertEqual(headers['X-List'], 'first') + + async def test_user_agent_default_updates_case_insensitively(self): + self.client.set_default_header('user-agent', 'custom') + self.assertEqual(self.client.user_agent, 'custom') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'custom') + self.client.user_agent = 'reset' + self.assertEqual(self.client.user_agent, 'reset') + self.assertEqual( + len([key for key in self.client.default_headers if key.lower() == 'user-agent']), 1 + ) + + async def test_empty_request_auth_keeps_configured_authentication(self): + await self.api.add_pet(self.pet, _request_auth={}) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + + async def test_empty_cookie_does_not_add_leading_separator(self): + params = self.client.param_serialize( + 'GET', '/cookie', header_params={'cookie': ''}, query_params=[], + auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'session=two') + + async def test_explicit_header_parameter_overrides_call_headers(self): + headers = {'API_KEY': 'call'} + params = self.api._delete_pet_serialize( + pet_id=1, api_key='explicit', _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(params[2]['api_key'], 'explicit') + self.assertEqual(headers, {'API_KEY': 'call'}) + + async def test_authentication_overrides_case_variants_and_preserves_inputs(self): + self.client.set_default_header('AUTHORIZATION', 'default') + defaults = self.client.default_headers.copy() + headers = {'authorization': 'call'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + auth = {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', 'value': 'Bearer call'} + await self.api.add_pet(self.pet, _headers=headers, _request_auth=auth) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer call') + self.assertEqual(headers, {'authorization': 'call'}) + self.assertEqual(auth['value'], 'Bearer call') + self.assertEqual(self.client.default_headers, defaults) + + async def test_api_key_overrides_default_and_call_case_variants(self): + self.client.set_default_header('API_KEY', 'default') + headers = {'Api_Key': 'call'} + defaults = self.client.default_headers.copy() + params = self.client.param_serialize( + 'GET', '/key', header_params=headers, auth_settings=['api_key'], query_params=[] + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'api_key', 'configured-key') + self.assertEqual(headers, {'Api_Key': 'call'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_cookie_authentication_appends_to_selected_cookie(self): + self.client.cookie = 'client=1' + headers = {'cookie': 'call=1'} + params = self.client.param_serialize( + 'GET', '/cookie', header_params=headers, query_params=[], auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'client=1; session=two') + self.assertEqual(headers, {'cookie': 'call=1'}) + + async def test_concurrent_calls_do_not_share_headers_or_authentication(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + async def call(index): + await self.api.add_pet(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer request-{index}', + }) + + await asyncio.gather(*(call(index) for index in range(20))) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer request-{index}' for index in range(20)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_public_mapping_validation_retains_combined_values(self): + headers = httpx.Headers([('X-List', 'a'), ('x-list', 'b')]) + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-list', 'a, b') + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_reads_lowercase_content_type_and_preserves_repeated_fields(self): + headers = httpx.Headers([ + ('content-type', 'application/x-www-form-urlencoded'), + ('x-list', 'a'), ('x-list', 'b'), + ]) + await self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/x-www-form-urlencoded' + ) + self.assertEqual(self.requests[-1].content, b'field=value') + self.assertEqual(self.requests[-1].headers.get_list('x-list'), ['a', 'b']) + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_multipart_does_not_mutate_input(self): + headers = {'content-type': 'multipart/form-data'} + await self.client.rest_client.request( + 'POST', 'https://example.test/upload', headers=headers, + post_params=[('file', ('name.txt', b'content', 'text/plain'))], + ) + self.assertTrue( + self.requests[-1].headers['content-type'].startswith('multipart/form-data;') + ) + self.assertEqual(len(self.requests[-1].headers.get_list('content-type')), 1) + self.assertEqual(headers, {'content-type': 'multipart/form-data'}) + + async def test_sync_calls_use_request_local_headers(self): + if not hasattr(self.api, 'add_pet_sync'): + self.skipTest('Sample does not enable supportHttpxSync') + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + def call(index): + getattr(self.api, 'add_pet_sync')(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer sync-{index}', + }) + + def run_calls(): + with ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(call, range(8))) + + await asyncio.to_thread(run_calls) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer sync-{index}' for index in range(8)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/README.md b/samples/openapi3/client/petstore/python-httpx2-sync/README.md index 8ed8c4e6a1a7..cf31ce123a3c 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/README.md +++ b/samples/openapi3/client/petstore/python-httpx2-sync/README.md @@ -329,3 +329,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/another_fake_api.py index 3c8c561664d3..3e70d5e8c536 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/another_fake_api.py @@ -353,7 +353,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -370,7 +370,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -379,7 +379,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -389,7 +389,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/default_api.py index 227cb6c9bf89..0044d1e0287c 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/default_api.py @@ -329,7 +329,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -344,7 +344,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py index 05c6c53603af..4a6f7b7183da 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py @@ -368,7 +368,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -387,7 +387,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -397,7 +397,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -733,7 +733,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1068,7 +1068,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1083,7 +1083,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1463,7 +1463,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1478,7 +1478,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1488,7 +1488,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1499,7 +1499,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1839,7 +1839,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1856,7 +1856,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1865,7 +1865,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1875,7 +1875,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2214,7 +2214,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2231,7 +2231,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2240,7 +2240,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2250,7 +2250,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2589,7 +2589,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2606,7 +2606,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2615,7 +2615,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2625,7 +2625,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2964,7 +2964,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2981,7 +2981,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2990,7 +2990,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3000,7 +3000,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3359,7 +3359,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3380,7 +3380,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -3389,7 +3389,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3399,7 +3399,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3716,7 +3716,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3731,7 +3731,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4054,7 +4054,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4069,7 +4069,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4392,7 +4392,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4407,7 +4407,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4730,7 +4730,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4745,7 +4745,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5068,7 +5068,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5083,7 +5083,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -5406,7 +5406,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5421,7 +5421,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5744,7 +5744,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5759,7 +5759,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6082,7 +6082,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6097,7 +6097,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6420,7 +6420,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6435,7 +6435,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -6758,7 +6758,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6773,7 +6773,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -7115,7 +7115,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7472,7 +7472,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7491,7 +7491,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7501,7 +7501,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7840,7 +7840,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7867,7 +7867,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7877,7 +7877,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8216,7 +8216,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8235,7 +8235,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8245,7 +8245,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8600,7 +8600,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8623,7 +8623,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8633,7 +8633,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8972,7 +8972,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8989,7 +8989,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8998,7 +8998,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9008,7 +9008,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9363,7 +9363,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9717,7 +9717,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9732,7 +9732,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -10346,7 +10346,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10393,7 +10393,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10403,7 +10403,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10727,7 +10727,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10742,7 +10742,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -11182,7 +11182,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -11209,9 +11209,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -11556,7 +11556,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -11575,7 +11575,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -11585,7 +11585,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -11924,7 +11924,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -11943,7 +11943,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -11953,7 +11953,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -12311,7 +12311,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -12332,7 +12332,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -12342,7 +12342,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -12697,7 +12697,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -12708,11 +12708,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -13053,7 +13053,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -13072,7 +13072,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -13082,7 +13082,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -13540,7 +13540,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -13921,7 +13921,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -13940,7 +13940,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -13950,7 +13950,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -14327,7 +14327,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -14348,7 +14348,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -14357,7 +14357,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -14367,7 +14367,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_classname_tags123_api.py index 3ae5963332d5..da4d328c100f 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_classname_tags123_api.py @@ -353,7 +353,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -370,7 +370,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -379,7 +379,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -389,7 +389,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/import_test_datetime_api.py index cf3b1e092de7..fd933e5180e0 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/import_test_datetime_api.py @@ -329,7 +329,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -344,7 +344,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/pet_api.py index 4228f8f36727..d304e3fba145 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/pet_api.py @@ -358,7 +358,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -377,7 +377,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -388,7 +388,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -751,7 +751,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -764,7 +764,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -1113,7 +1113,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1132,7 +1132,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1487,7 +1487,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1506,7 +1506,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1860,7 +1860,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1877,7 +1877,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -2233,7 +2233,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2252,7 +2252,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2263,7 +2263,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2645,7 +2645,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2668,7 +2668,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2678,7 +2678,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3056,7 +3056,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3077,7 +3077,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3086,7 +3086,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3096,7 +3096,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -3474,7 +3474,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3495,7 +3495,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3504,7 +3504,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -3514,7 +3514,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/store_api.py index 3829184bb1fe..b6c56870658d 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/store_api.py @@ -357,7 +357,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -693,7 +693,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -708,7 +708,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1060,7 +1060,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1077,7 +1077,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1426,7 +1426,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1443,7 +1443,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1453,7 +1453,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1463,7 +1463,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/user_api.py index 85d34b6ebb62..d07e94b739fe 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/user_api.py @@ -357,7 +357,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -376,7 +376,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -386,7 +386,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -723,7 +723,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -742,7 +742,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -752,7 +752,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1089,7 +1089,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1108,7 +1108,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1118,7 +1118,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1460,7 +1460,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1821,7 +1821,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1838,7 +1838,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -2206,7 +2206,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2229,7 +2229,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -2553,7 +2553,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2928,7 +2928,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2949,7 +2949,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2959,7 +2959,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api_client.py index 44b7a286135f..43782b4ec85b 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -106,16 +106,36 @@ async def close(self): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -182,10 +202,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -707,7 +726,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -716,14 +739,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/rest.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/rest.py index 649beee94d7b..22dc7db551e3 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/rest.py @@ -119,7 +119,7 @@ async def request( ) post_params = post_params or {} - headers = headers or {} + headers = httpx2.Headers(headers or {}) timeout = _request_timeout or 5 * 60 if 'Content-Type' not in headers: diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/tests/test_request_headers.py b/samples/openapi3/client/petstore/python-httpx2-sync/tests/test_request_headers.py new file mode 100644 index 000000000000..addec9e857d8 --- /dev/null +++ b/samples/openapi3/client/petstore/python-httpx2-sync/tests/test_request_headers.py @@ -0,0 +1,247 @@ +"""Regression tests for request-local, case-insensitive HTTPX headers.""" + +import asyncio +from concurrent.futures import ThreadPoolExecutor +import importlib +import unittest +from typing import Any + +import petstore_api +from petstore_api import rest + +httpx = importlib.import_module(rest.RESTResponseType.__module__.split('.')[0]) + + +class TestRequestHeaders(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.requests: list[Any] = [] + + async def respond(request): + self.requests.append(request) + await asyncio.sleep(0) + return httpx.Response(200, json={}) + + self.client = petstore_api.ApiClient(petstore_api.Configuration( + host='https://example.test', access_token='configured-token', + api_key={'api_key': 'configured-key'}, + )) + self.client.rest_client.pool_manager = httpx.AsyncClient( + transport=httpx.MockTransport(respond) + ) + self.api = petstore_api.PetApi(self.client) + self.pet = petstore_api.Pet(name='test', photoUrls=[]) + + async def asyncTearDown(self): + await self.client.close() + + def assert_single_header(self, request, name, value): + self.assertEqual(request.headers.get_list(name), [value]) + + async def test_serializers_copy_header_inputs_before_adding_defaults_and_auth(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + original = headers.copy() + defaults = self.client.default_headers.copy() + self.api._add_pet_serialize( + pet=self.pet, _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(headers, original) + self.client.param_serialize( + 'GET', '/pet', header_params=headers, query_params=[], auth_settings=['petstore_auth'] + ) + self.assertEqual(headers, original) + self.assertEqual(self.client.default_headers, defaults) + + async def test_user_agent_matches_last_direct_default_header_write(self): + self.client.default_headers['user-agent'] = 'custom' + self.client.default_headers['USER-AGENT'] = 'latest' + defaults = self.client.default_headers.copy() + self.assertEqual(self.client.user_agent, 'latest') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'latest') + self.assertEqual(self.client.default_headers, defaults) + + async def test_generated_content_type_replaces_case_variants(self): + for spelling in ('Content-Type', 'content-type', 'CONTENT-TYPE'): + for value in ('application/json', 'text/plain'): + with self.subTest(spelling=spelling, value=value): + headers = {spelling: value, 'accept': 'application/custom'} + original = headers.copy() + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/json' + ) + self.assert_single_header(self.requests[-1], 'accept', 'application/custom') + self.assertEqual(headers, original) + + async def test_content_type_override_and_client_default_precedence(self): + headers = {'content-type': 'text/plain'} + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/custom+json') + self.client.set_default_header('CONTENT-TYPE', 'application/default+json') + defaults = self.client.default_headers.copy() + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/default+json') + self.assertEqual(self.client.default_headers, defaults) + self.assertEqual(headers, {'content-type': 'text/plain'}) + + async def test_defaults_and_last_inserted_case_variant_win_without_splitting_values(self): + self.client.set_default_header('X-Default', 'earlier-default') + self.client.set_default_header('x-default', 'middle') + self.client.set_default_header('X-Default', 'default') + headers = {'x-default': 'call', 'X-List': 'first', 'x-list': 'a, b, a'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-default', 'default') + self.assert_single_header(self.requests[-1], 'x-list', 'a, b, a') + self.assertIn('x-list', self.requests[-1].headers) + self.assertEqual(headers['X-List'], 'first') + + async def test_user_agent_default_updates_case_insensitively(self): + self.client.set_default_header('user-agent', 'custom') + self.assertEqual(self.client.user_agent, 'custom') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'custom') + self.client.user_agent = 'reset' + self.assertEqual(self.client.user_agent, 'reset') + self.assertEqual( + len([key for key in self.client.default_headers if key.lower() == 'user-agent']), 1 + ) + + async def test_empty_request_auth_keeps_configured_authentication(self): + await self.api.add_pet(self.pet, _request_auth={}) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + + async def test_empty_cookie_does_not_add_leading_separator(self): + params = self.client.param_serialize( + 'GET', '/cookie', header_params={'cookie': ''}, query_params=[], + auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'session=two') + + async def test_explicit_header_parameter_overrides_call_headers(self): + headers = {'API_KEY': 'call'} + params = self.api._delete_pet_serialize( + pet_id=1, api_key='explicit', _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(params[2]['api_key'], 'explicit') + self.assertEqual(headers, {'API_KEY': 'call'}) + + async def test_authentication_overrides_case_variants_and_preserves_inputs(self): + self.client.set_default_header('AUTHORIZATION', 'default') + defaults = self.client.default_headers.copy() + headers = {'authorization': 'call'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + auth = {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', 'value': 'Bearer call'} + await self.api.add_pet(self.pet, _headers=headers, _request_auth=auth) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer call') + self.assertEqual(headers, {'authorization': 'call'}) + self.assertEqual(auth['value'], 'Bearer call') + self.assertEqual(self.client.default_headers, defaults) + + async def test_api_key_overrides_default_and_call_case_variants(self): + self.client.set_default_header('API_KEY', 'default') + headers = {'Api_Key': 'call'} + defaults = self.client.default_headers.copy() + params = self.client.param_serialize( + 'GET', '/key', header_params=headers, auth_settings=['api_key'], query_params=[] + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'api_key', 'configured-key') + self.assertEqual(headers, {'Api_Key': 'call'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_cookie_authentication_appends_to_selected_cookie(self): + self.client.cookie = 'client=1' + headers = {'cookie': 'call=1'} + params = self.client.param_serialize( + 'GET', '/cookie', header_params=headers, query_params=[], auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'client=1; session=two') + self.assertEqual(headers, {'cookie': 'call=1'}) + + async def test_concurrent_calls_do_not_share_headers_or_authentication(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + async def call(index): + await self.api.add_pet(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer request-{index}', + }) + + await asyncio.gather(*(call(index) for index in range(20))) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer request-{index}' for index in range(20)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_public_mapping_validation_retains_combined_values(self): + headers = httpx.Headers([('X-List', 'a'), ('x-list', 'b')]) + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-list', 'a, b') + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_reads_lowercase_content_type_and_preserves_repeated_fields(self): + headers = httpx.Headers([ + ('content-type', 'application/x-www-form-urlencoded'), + ('x-list', 'a'), ('x-list', 'b'), + ]) + await self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/x-www-form-urlencoded' + ) + self.assertEqual(self.requests[-1].content, b'field=value') + self.assertEqual(self.requests[-1].headers.get_list('x-list'), ['a', 'b']) + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_multipart_does_not_mutate_input(self): + headers = {'content-type': 'multipart/form-data'} + await self.client.rest_client.request( + 'POST', 'https://example.test/upload', headers=headers, + post_params=[('file', ('name.txt', b'content', 'text/plain'))], + ) + self.assertTrue( + self.requests[-1].headers['content-type'].startswith('multipart/form-data;') + ) + self.assertEqual(len(self.requests[-1].headers.get_list('content-type')), 1) + self.assertEqual(headers, {'content-type': 'multipart/form-data'}) + + async def test_sync_calls_use_request_local_headers(self): + if not hasattr(self.api, 'add_pet_sync'): + self.skipTest('Sample does not enable supportHttpxSync') + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + def call(index): + getattr(self.api, 'add_pet_sync')(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer sync-{index}', + }) + + def run_calls(): + with ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(call, range(8))) + + await asyncio.to_thread(run_calls) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer sync-{index}' for index in range(8)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) diff --git a/samples/openapi3/client/petstore/python-httpx2/README.md b/samples/openapi3/client/petstore/python-httpx2/README.md index 36ecb4c1a744..762afbfcdb00 100644 --- a/samples/openapi3/client/petstore/python-httpx2/README.md +++ b/samples/openapi3/client/petstore/python-httpx2/README.md @@ -328,3 +328,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/another_fake_api.py index 9ceb307bbb24..968ac5d448d0 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/another_fake_api.py @@ -250,7 +250,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -276,7 +276,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -286,7 +286,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/default_api.py index dc264f69428e..5a766861f81f 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/default_api.py @@ -232,7 +232,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -247,7 +247,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py index 7fb0a185a264..8c7dc59ccaac 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py @@ -265,7 +265,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -284,7 +284,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -294,7 +294,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -528,7 +528,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -767,7 +767,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -782,7 +782,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1048,7 +1048,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1063,7 +1063,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1073,7 +1073,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1084,7 +1084,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1322,7 +1322,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1339,7 +1339,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1348,7 +1348,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1358,7 +1358,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1595,7 +1595,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1612,7 +1612,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1621,7 +1621,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1631,7 +1631,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1868,7 +1868,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1885,7 +1885,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1894,7 +1894,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1904,7 +1904,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2141,7 +2141,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2158,7 +2158,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2167,7 +2167,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2177,7 +2177,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2428,7 +2428,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2449,7 +2449,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2458,7 +2458,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2468,7 +2468,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2689,7 +2689,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2704,7 +2704,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -2931,7 +2931,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2946,7 +2946,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3173,7 +3173,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3188,7 +3188,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3415,7 +3415,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3430,7 +3430,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3657,7 +3657,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3672,7 +3672,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3899,7 +3899,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3914,7 +3914,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4141,7 +4141,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4156,7 +4156,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4383,7 +4383,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4398,7 +4398,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4625,7 +4625,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4640,7 +4640,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4867,7 +4867,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4882,7 +4882,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5122,7 +5122,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5377,7 +5377,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5396,7 +5396,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5406,7 +5406,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5643,7 +5643,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5670,7 +5670,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5680,7 +5680,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5917,7 +5917,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5936,7 +5936,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5946,7 +5946,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6193,7 +6193,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6216,7 +6216,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6226,7 +6226,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6463,7 +6463,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6480,7 +6480,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6489,7 +6489,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6499,7 +6499,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6746,7 +6746,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7004,7 +7004,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7019,7 +7019,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -7447,7 +7447,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7494,7 +7494,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7504,7 +7504,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7732,7 +7732,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7747,7 +7747,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8055,7 +8055,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8082,9 +8082,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -8327,7 +8327,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8346,7 +8346,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8356,7 +8356,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8593,7 +8593,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8612,7 +8612,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8622,7 +8622,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8872,7 +8872,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8893,7 +8893,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8903,7 +8903,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9150,7 +9150,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9161,11 +9161,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -9404,7 +9404,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9423,7 +9423,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9433,7 +9433,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9753,7 +9753,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10032,7 +10032,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10051,7 +10051,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10061,7 +10061,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10324,7 +10324,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10345,7 +10345,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -10354,7 +10354,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10364,7 +10364,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_classname_tags123_api.py index 08cf85d488bb..9e6aeb9ed9c9 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_classname_tags123_api.py @@ -250,7 +250,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -276,7 +276,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -286,7 +286,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/import_test_datetime_api.py index 47876e858687..9dbb9cd39e69 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/import_test_datetime_api.py @@ -232,7 +232,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -247,7 +247,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/pet_api.py index 5da83f4a686a..92b61d5dcbad 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/pet_api.py @@ -255,7 +255,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -274,7 +274,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -285,7 +285,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -540,7 +540,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -553,7 +553,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -800,7 +800,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -819,7 +819,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1072,7 +1072,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1091,7 +1091,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1343,7 +1343,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1360,7 +1360,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1614,7 +1614,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1633,7 +1633,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1644,7 +1644,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1912,7 +1912,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1935,7 +1935,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1945,7 +1945,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2209,7 +2209,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2230,7 +2230,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2239,7 +2239,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2249,7 +2249,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2513,7 +2513,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2534,7 +2534,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2543,7 +2543,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2553,7 +2553,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/store_api.py index 79116ca74ca8..5b7543c1b285 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/store_api.py @@ -254,7 +254,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -494,7 +494,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -509,7 +509,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -759,7 +759,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -776,7 +776,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1023,7 +1023,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1040,7 +1040,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1050,7 +1050,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1060,7 +1060,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/user_api.py index 9e4ff6771db8..387ff3f12e8d 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/user_api.py @@ -254,7 +254,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -273,7 +273,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -283,7 +283,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -518,7 +518,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -537,7 +537,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -547,7 +547,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -782,7 +782,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -801,7 +801,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -811,7 +811,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1051,7 +1051,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1310,7 +1310,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1327,7 +1327,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1587,7 +1587,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1610,7 +1610,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1838,7 +1838,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2105,7 +2105,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2126,7 +2126,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2136,7 +2136,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api_client.py index 44b7a286135f..43782b4ec85b 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -106,16 +106,36 @@ async def close(self): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -182,10 +202,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -707,7 +726,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -716,14 +739,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/rest.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/rest.py index 649beee94d7b..22dc7db551e3 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/rest.py @@ -119,7 +119,7 @@ async def request( ) post_params = post_params or {} - headers = headers or {} + headers = httpx2.Headers(headers or {}) timeout = _request_timeout or 5 * 60 if 'Content-Type' not in headers: diff --git a/samples/openapi3/client/petstore/python-httpx2/tests/test_request_headers.py b/samples/openapi3/client/petstore/python-httpx2/tests/test_request_headers.py new file mode 100644 index 000000000000..addec9e857d8 --- /dev/null +++ b/samples/openapi3/client/petstore/python-httpx2/tests/test_request_headers.py @@ -0,0 +1,247 @@ +"""Regression tests for request-local, case-insensitive HTTPX headers.""" + +import asyncio +from concurrent.futures import ThreadPoolExecutor +import importlib +import unittest +from typing import Any + +import petstore_api +from petstore_api import rest + +httpx = importlib.import_module(rest.RESTResponseType.__module__.split('.')[0]) + + +class TestRequestHeaders(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.requests: list[Any] = [] + + async def respond(request): + self.requests.append(request) + await asyncio.sleep(0) + return httpx.Response(200, json={}) + + self.client = petstore_api.ApiClient(petstore_api.Configuration( + host='https://example.test', access_token='configured-token', + api_key={'api_key': 'configured-key'}, + )) + self.client.rest_client.pool_manager = httpx.AsyncClient( + transport=httpx.MockTransport(respond) + ) + self.api = petstore_api.PetApi(self.client) + self.pet = petstore_api.Pet(name='test', photoUrls=[]) + + async def asyncTearDown(self): + await self.client.close() + + def assert_single_header(self, request, name, value): + self.assertEqual(request.headers.get_list(name), [value]) + + async def test_serializers_copy_header_inputs_before_adding_defaults_and_auth(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + original = headers.copy() + defaults = self.client.default_headers.copy() + self.api._add_pet_serialize( + pet=self.pet, _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(headers, original) + self.client.param_serialize( + 'GET', '/pet', header_params=headers, query_params=[], auth_settings=['petstore_auth'] + ) + self.assertEqual(headers, original) + self.assertEqual(self.client.default_headers, defaults) + + async def test_user_agent_matches_last_direct_default_header_write(self): + self.client.default_headers['user-agent'] = 'custom' + self.client.default_headers['USER-AGENT'] = 'latest' + defaults = self.client.default_headers.copy() + self.assertEqual(self.client.user_agent, 'latest') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'latest') + self.assertEqual(self.client.default_headers, defaults) + + async def test_generated_content_type_replaces_case_variants(self): + for spelling in ('Content-Type', 'content-type', 'CONTENT-TYPE'): + for value in ('application/json', 'text/plain'): + with self.subTest(spelling=spelling, value=value): + headers = {spelling: value, 'accept': 'application/custom'} + original = headers.copy() + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/json' + ) + self.assert_single_header(self.requests[-1], 'accept', 'application/custom') + self.assertEqual(headers, original) + + async def test_content_type_override_and_client_default_precedence(self): + headers = {'content-type': 'text/plain'} + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/custom+json') + self.client.set_default_header('CONTENT-TYPE', 'application/default+json') + defaults = self.client.default_headers.copy() + await self.api.add_pet(self.pet, _headers=headers, _content_type='application/custom+json') + self.assert_single_header(self.requests[-1], 'content-type', 'application/default+json') + self.assertEqual(self.client.default_headers, defaults) + self.assertEqual(headers, {'content-type': 'text/plain'}) + + async def test_defaults_and_last_inserted_case_variant_win_without_splitting_values(self): + self.client.set_default_header('X-Default', 'earlier-default') + self.client.set_default_header('x-default', 'middle') + self.client.set_default_header('X-Default', 'default') + headers = {'x-default': 'call', 'X-List': 'first', 'x-list': 'a, b, a'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-default', 'default') + self.assert_single_header(self.requests[-1], 'x-list', 'a, b, a') + self.assertIn('x-list', self.requests[-1].headers) + self.assertEqual(headers['X-List'], 'first') + + async def test_user_agent_default_updates_case_insensitively(self): + self.client.set_default_header('user-agent', 'custom') + self.assertEqual(self.client.user_agent, 'custom') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'user-agent', 'custom') + self.client.user_agent = 'reset' + self.assertEqual(self.client.user_agent, 'reset') + self.assertEqual( + len([key for key in self.client.default_headers if key.lower() == 'user-agent']), 1 + ) + + async def test_empty_request_auth_keeps_configured_authentication(self): + await self.api.add_pet(self.pet, _request_auth={}) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + + async def test_empty_cookie_does_not_add_leading_separator(self): + params = self.client.param_serialize( + 'GET', '/cookie', header_params={'cookie': ''}, query_params=[], + auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'session=two') + + async def test_explicit_header_parameter_overrides_call_headers(self): + headers = {'API_KEY': 'call'} + params = self.api._delete_pet_serialize( + pet_id=1, api_key='explicit', _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(params[2]['api_key'], 'explicit') + self.assertEqual(headers, {'API_KEY': 'call'}) + + async def test_authentication_overrides_case_variants_and_preserves_inputs(self): + self.client.set_default_header('AUTHORIZATION', 'default') + defaults = self.client.default_headers.copy() + headers = {'authorization': 'call'} + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + auth = {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', 'value': 'Bearer call'} + await self.api.add_pet(self.pet, _headers=headers, _request_auth=auth) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer call') + self.assertEqual(headers, {'authorization': 'call'}) + self.assertEqual(auth['value'], 'Bearer call') + self.assertEqual(self.client.default_headers, defaults) + + async def test_api_key_overrides_default_and_call_case_variants(self): + self.client.set_default_header('API_KEY', 'default') + headers = {'Api_Key': 'call'} + defaults = self.client.default_headers.copy() + params = self.client.param_serialize( + 'GET', '/key', header_params=headers, auth_settings=['api_key'], query_params=[] + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'api_key', 'configured-key') + self.assertEqual(headers, {'Api_Key': 'call'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_cookie_authentication_appends_to_selected_cookie(self): + self.client.cookie = 'client=1' + headers = {'cookie': 'call=1'} + params = self.client.param_serialize( + 'GET', '/cookie', header_params=headers, query_params=[], auth_settings=['cookie'], + _request_auth={'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two'}, + ) + await self.client.call_api(*params) + self.assert_single_header(self.requests[-1], 'cookie', 'client=1; session=two') + self.assertEqual(headers, {'cookie': 'call=1'}) + + async def test_concurrent_calls_do_not_share_headers_or_authentication(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + async def call(index): + await self.api.add_pet(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer request-{index}', + }) + + await asyncio.gather(*(call(index) for index in range(20))) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer request-{index}' for index in range(20)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + await self.api.add_pet(self.pet) + self.assert_single_header(self.requests[-1], 'authorization', 'Bearer configured-token') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_public_mapping_validation_retains_combined_values(self): + headers = httpx.Headers([('X-List', 'a'), ('x-list', 'b')]) + await self.api.add_pet(self.pet, _headers=headers) + self.assert_single_header(self.requests[-1], 'x-list', 'a, b') + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_reads_lowercase_content_type_and_preserves_repeated_fields(self): + headers = httpx.Headers([ + ('content-type', 'application/x-www-form-urlencoded'), + ('x-list', 'a'), ('x-list', 'b'), + ]) + await self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + self.assert_single_header( + self.requests[-1], 'content-type', 'application/x-www-form-urlencoded' + ) + self.assertEqual(self.requests[-1].content, b'field=value') + self.assertEqual(self.requests[-1].headers.get_list('x-list'), ['a', 'b']) + self.assertEqual(headers.get_list('x-list'), ['a', 'b']) + + async def test_transport_multipart_does_not_mutate_input(self): + headers = {'content-type': 'multipart/form-data'} + await self.client.rest_client.request( + 'POST', 'https://example.test/upload', headers=headers, + post_params=[('file', ('name.txt', b'content', 'text/plain'))], + ) + self.assertTrue( + self.requests[-1].headers['content-type'].startswith('multipart/form-data;') + ) + self.assertEqual(len(self.requests[-1].headers.get_list('content-type')), 1) + self.assertEqual(headers, {'content-type': 'multipart/form-data'}) + + async def test_sync_calls_use_request_local_headers(self): + if not hasattr(self.api, 'add_pet_sync'): + self.skipTest('Sample does not enable supportHttpxSync') + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + def call(index): + getattr(self.api, 'add_pet_sync')(self.pet, _headers=headers, _request_auth={ + 'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer sync-{index}', + }) + + def run_calls(): + with ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(call, range(8))) + + await asyncio.to_thread(run_calls) + self.assertCountEqual( + [request.headers['authorization'] for request in self.requests], + [f'Bearer sync-{index}' for index in range(8)], + ) + for request in self.requests: + self.assert_single_header(request, 'content-type', 'application/json') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) diff --git a/samples/openapi3/client/petstore/python-lazyImports/README.md b/samples/openapi3/client/petstore/python-lazyImports/README.md index eff9ffcd975e..d907bad2411f 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/README.md +++ b/samples/openapi3/client/petstore/python-lazyImports/README.md @@ -349,3 +349,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/another_fake_api.py index 128465621cbc..cf0ad78f8b88 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/another_fake_api.py @@ -270,7 +270,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -287,7 +287,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -296,7 +296,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -306,7 +306,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/default_api.py index 25a038d2c23d..1d78bf1f8fe5 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/default_api.py @@ -252,7 +252,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py index b2e1cd1be926..b7d2c36217b7 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py @@ -285,7 +285,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -304,7 +304,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -314,7 +314,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -548,7 +548,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -787,7 +787,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -802,7 +802,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1068,7 +1068,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1083,7 +1083,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1093,7 +1093,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1104,7 +1104,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1342,7 +1342,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1359,7 +1359,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1368,7 +1368,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1378,7 +1378,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1615,7 +1615,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1632,7 +1632,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1641,7 +1641,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1651,7 +1651,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1888,7 +1888,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1905,7 +1905,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1914,7 +1914,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1924,7 +1924,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2161,7 +2161,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2178,7 +2178,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2187,7 +2187,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2197,7 +2197,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2448,7 +2448,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2469,7 +2469,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2478,7 +2478,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2488,7 +2488,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2709,7 +2709,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2724,7 +2724,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -2951,7 +2951,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2966,7 +2966,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3193,7 +3193,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3208,7 +3208,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3435,7 +3435,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3450,7 +3450,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3677,7 +3677,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3692,7 +3692,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3919,7 +3919,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3934,7 +3934,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4161,7 +4161,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4176,7 +4176,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4403,7 +4403,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4418,7 +4418,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4645,7 +4645,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4660,7 +4660,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4887,7 +4887,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4902,7 +4902,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5142,7 +5142,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5397,7 +5397,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5416,7 +5416,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5426,7 +5426,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5663,7 +5663,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5690,7 +5690,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5700,7 +5700,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5937,7 +5937,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5956,7 +5956,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5966,7 +5966,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6213,7 +6213,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6236,7 +6236,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6246,7 +6246,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6483,7 +6483,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6500,7 +6500,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6509,7 +6509,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6519,7 +6519,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6766,7 +6766,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7024,7 +7024,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7039,7 +7039,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -7467,7 +7467,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7514,7 +7514,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7524,7 +7524,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7752,7 +7752,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7767,7 +7767,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8075,7 +8075,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8102,9 +8102,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -8347,7 +8347,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8366,7 +8366,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8376,7 +8376,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8613,7 +8613,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8632,7 +8632,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8642,7 +8642,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8892,7 +8892,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8913,7 +8913,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8923,7 +8923,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9170,7 +9170,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9181,11 +9181,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -9424,7 +9424,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9443,7 +9443,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9453,7 +9453,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9773,7 +9773,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10052,7 +10052,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10071,7 +10071,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10081,7 +10081,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10344,7 +10344,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10365,7 +10365,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -10374,7 +10374,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10384,7 +10384,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_classname_tags123_api.py index d9f5f5a570be..8faa294b368f 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_classname_tags123_api.py @@ -270,7 +270,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -287,7 +287,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -296,7 +296,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -306,7 +306,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/import_test_datetime_api.py index 1045da8de511..1f7a61b06d09 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/import_test_datetime_api.py @@ -252,7 +252,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/pet_api.py index 2dfc90005d39..1ea2684a449d 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/pet_api.py @@ -275,7 +275,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -294,7 +294,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -305,7 +305,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -560,7 +560,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -573,7 +573,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -820,7 +820,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -839,7 +839,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1092,7 +1092,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1111,7 +1111,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1363,7 +1363,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1380,7 +1380,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1634,7 +1634,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1653,7 +1653,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1664,7 +1664,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1932,7 +1932,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1955,7 +1955,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1965,7 +1965,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2229,7 +2229,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2250,7 +2250,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2259,7 +2259,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2269,7 +2269,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2533,7 +2533,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2554,7 +2554,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2563,7 +2563,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2573,7 +2573,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/store_api.py index 6e3df4213355..c579ee54e748 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/store_api.py @@ -274,7 +274,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -514,7 +514,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -529,7 +529,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -779,7 +779,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -796,7 +796,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1043,7 +1043,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1060,7 +1060,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1070,7 +1070,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1080,7 +1080,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/user_api.py index 59ce49f2f797..321881637df4 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/user_api.py @@ -274,7 +274,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -293,7 +293,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -303,7 +303,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -538,7 +538,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -557,7 +557,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -567,7 +567,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -802,7 +802,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -821,7 +821,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -831,7 +831,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1071,7 +1071,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1330,7 +1330,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1347,7 +1347,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1607,7 +1607,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1630,7 +1630,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1858,7 +1858,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2125,7 +2125,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2146,7 +2146,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2156,7 +2156,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api_client.py index eeb694ac158b..e94f64789c50 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -106,16 +106,36 @@ def __exit__(self, exc_type, exc_value, traceback): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -179,10 +199,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -704,7 +723,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -713,14 +736,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/rest.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/rest.py index 8affe12ad0a2..abd28ce48ff1 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/rest.py @@ -219,7 +219,7 @@ def request( ) post_params = post_params or {} - headers = headers or {} + headers = urllib3.HTTPHeaderDict(headers or {}) timeout = None if _request_timeout: diff --git a/samples/openapi3/client/petstore/python/README.md b/samples/openapi3/client/petstore/python/README.md index a7585af3cc78..f50f803b5806 100755 --- a/samples/openapi3/client/petstore/python/README.md +++ b/samples/openapi3/client/petstore/python/README.md @@ -326,3 +326,33 @@ Authentication schemes defined for the API: + +## Request headers + +Header names are compared case-insensitively in all Python client libraries. +Request headers are copied; supplying `_headers` does not change the caller's dict +or the client's shared defaults. The public `_headers` argument retains its dict +validation and existing value serialization. Pydantic can coerce mappings such as HTTPX `Headers` to a dict, +combining repeated fields into a single value; `_headers` does not provide a +repeated-field or list-of-pairs API. + +Precedence, from lowest to highest: + +1. `_headers` (within one dict, the last inserted case variant wins). +2. Explicit OpenAPI header parameters and generated `Content-Type` (or `_content_type`). + Generated `Accept` is added only when neither `_headers` nor explicit header + parameters contain an `Accept` case variant. +3. `ApiClient.default_headers` (including headers set with `set_default_header`). +4. The client's `cookie` setting, for `Cookie`. +5. Authentication headers. A non-empty `_request_auth` replaces configured + authentication for that call; `{}` retains configured authentication. Cookie + authentication appends to the selected `Cookie` value. + +This retains the existing precedence for identically spelled names and extends it +to case variants. To override a generated content type, use `_content_type`; +client defaults still take precedence over it. The winning header's spelling and +value are retained for replacements. Cookie authentication uses the canonical +`Cookie` spelling and appends its value. Values containing legitimate +comma-separated lists are not split or deduplicated. This does not remove +duplicate values inside a header or change the handling of repeated fields +supplied directly to the transport. diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/another_fake_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/another_fake_api.py index 56f2ab2cd1cd..d75e24eca3a5 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/another_fake_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/another_fake_api.py @@ -250,7 +250,7 @@ def _call_123_test_special_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -276,7 +276,7 @@ def _call_123_test_special_tags_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -286,7 +286,7 @@ def _call_123_test_special_tags_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/default_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/default_api.py index ce4db6893d28..6abe92c60307 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/default_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/default_api.py @@ -232,7 +232,7 @@ def _foo_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -247,7 +247,7 @@ def _foo_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py index fca5d8161a3d..020ebbfa43ae 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py @@ -265,7 +265,7 @@ def _fake_any_type_request_body_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -284,7 +284,7 @@ def _fake_any_type_request_body_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -294,7 +294,7 @@ def _fake_any_type_request_body_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -528,7 +528,7 @@ def _fake_enum_ref_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -767,7 +767,7 @@ def _fake_health_get_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -782,7 +782,7 @@ def _fake_health_get_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -1048,7 +1048,7 @@ def _fake_http_signature_test_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1063,7 +1063,7 @@ def _fake_http_signature_test_serialize( # process the header parameters if header_1 is not None: - _header_params['header_1'] = header_1 + self.api_client._set_header(_header_params, 'header_1', header_1) # process the form parameters # process the body parameter if pet is not None: @@ -1073,7 +1073,7 @@ def _fake_http_signature_test_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1084,7 +1084,7 @@ def _fake_http_signature_test_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1322,7 +1322,7 @@ def _fake_outer_boolean_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1339,7 +1339,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1348,7 +1348,7 @@ def _fake_outer_boolean_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1358,7 +1358,7 @@ def _fake_outer_boolean_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1595,7 +1595,7 @@ def _fake_outer_composite_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1612,7 +1612,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1621,7 +1621,7 @@ def _fake_outer_composite_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1631,7 +1631,7 @@ def _fake_outer_composite_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1868,7 +1868,7 @@ def _fake_outer_number_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1885,7 +1885,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -1894,7 +1894,7 @@ def _fake_outer_number_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1904,7 +1904,7 @@ def _fake_outer_number_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2141,7 +2141,7 @@ def _fake_outer_string_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2158,7 +2158,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2167,7 +2167,7 @@ def _fake_outer_string_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2177,7 +2177,7 @@ def _fake_outer_string_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2428,7 +2428,7 @@ def _fake_property_enum_integer_serialize_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2449,7 +2449,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ '*/*' @@ -2458,7 +2458,7 @@ def _fake_property_enum_integer_serialize_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2468,7 +2468,7 @@ def _fake_property_enum_integer_serialize_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2689,7 +2689,7 @@ def _fake_ref_enum_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2704,7 +2704,7 @@ def _fake_ref_enum_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -2931,7 +2931,7 @@ def _fake_return_boolean_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2946,7 +2946,7 @@ def _fake_return_boolean_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3173,7 +3173,7 @@ def _fake_return_byte_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3188,7 +3188,7 @@ def _fake_return_byte_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3415,7 +3415,7 @@ def _fake_return_enum_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3430,7 +3430,7 @@ def _fake_return_enum_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -3657,7 +3657,7 @@ def _fake_return_enum_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3672,7 +3672,7 @@ def _fake_return_enum_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -3899,7 +3899,7 @@ def _fake_return_float_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -3914,7 +3914,7 @@ def _fake_return_float_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4141,7 +4141,7 @@ def _fake_return_int_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4156,7 +4156,7 @@ def _fake_return_int_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4383,7 +4383,7 @@ def _fake_return_list_of_objects_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4398,7 +4398,7 @@ def _fake_return_list_of_objects_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -4625,7 +4625,7 @@ def _fake_return_str_like_json_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4640,7 +4640,7 @@ def _fake_return_str_like_json_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'plain/text' @@ -4867,7 +4867,7 @@ def _fake_return_string_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -4882,7 +4882,7 @@ def _fake_return_string_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -5122,7 +5122,7 @@ def _fake_uuid_example_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5377,7 +5377,7 @@ def _test_additional_properties_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5396,7 +5396,7 @@ def _test_additional_properties_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5406,7 +5406,7 @@ def _test_additional_properties_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5643,7 +5643,7 @@ def _test_body_with_binary_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5670,7 +5670,7 @@ def _test_body_with_binary_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5680,7 +5680,7 @@ def _test_body_with_binary_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -5917,7 +5917,7 @@ def _test_body_with_file_schema_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -5936,7 +5936,7 @@ def _test_body_with_file_schema_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -5946,7 +5946,7 @@ def _test_body_with_file_schema_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6193,7 +6193,7 @@ def _test_body_with_query_params_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6216,7 +6216,7 @@ def _test_body_with_query_params_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6226,7 +6226,7 @@ def _test_body_with_query_params_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6463,7 +6463,7 @@ def _test_client_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -6480,7 +6480,7 @@ def _test_client_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -6489,7 +6489,7 @@ def _test_client_model_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -6499,7 +6499,7 @@ def _test_client_model_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -6746,7 +6746,7 @@ def _test_date_time_query_parameter_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7004,7 +7004,7 @@ def _test_empty_and_non_empty_responses_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7019,7 +7019,7 @@ def _test_empty_and_non_empty_responses_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'text/plain' @@ -7447,7 +7447,7 @@ def _test_endpoint_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7494,7 +7494,7 @@ def _test_endpoint_parameters_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -7504,7 +7504,7 @@ def _test_endpoint_parameters_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -7732,7 +7732,7 @@ def _test_error_responses_with_model_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -7747,7 +7747,7 @@ def _test_error_responses_with_model_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -8055,7 +8055,7 @@ def _test_group_parameters_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8082,9 +8082,9 @@ def _test_group_parameters_serialize( # process the header parameters if required_boolean_group is not None: - _header_params['required_boolean_group'] = required_boolean_group + self.api_client._set_header(_header_params, 'required_boolean_group', required_boolean_group) if boolean_group is not None: - _header_params['boolean_group'] = boolean_group + self.api_client._set_header(_header_params, 'boolean_group', boolean_group) # process the form parameters # process the body parameter @@ -8327,7 +8327,7 @@ def _test_inline_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8346,7 +8346,7 @@ def _test_inline_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8356,7 +8356,7 @@ def _test_inline_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8593,7 +8593,7 @@ def _test_inline_freeform_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8612,7 +8612,7 @@ def _test_inline_freeform_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8622,7 +8622,7 @@ def _test_inline_freeform_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -8872,7 +8872,7 @@ def _test_json_form_data_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -8893,7 +8893,7 @@ def _test_json_form_data_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -8903,7 +8903,7 @@ def _test_json_form_data_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9150,7 +9150,7 @@ def _test_json_header_content_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9161,11 +9161,11 @@ def _test_json_header_content_serialize( # process the query parameters # process the header parameters if x_json_arg is not None: - _header_params['X-Json-Arg'] = json.dumps( + self.api_client._set_header(_header_params, 'X-Json-Arg', json.dumps( self.api_client.sanitize_for_serialization(x_json_arg) - ) + )) if x_plain_arg is not None: - _header_params['X-Plain-Arg'] = x_plain_arg + self.api_client._set_header(_header_params, 'X-Plain-Arg', x_plain_arg) # process the form parameters # process the body parameter @@ -9404,7 +9404,7 @@ def _test_object_for_multipart_requests_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -9423,7 +9423,7 @@ def _test_object_for_multipart_requests_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -9433,7 +9433,7 @@ def _test_object_for_multipart_requests_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -9753,7 +9753,7 @@ def _test_query_parameter_collection_format_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10032,7 +10032,7 @@ def _test_string_map_reference_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10051,7 +10051,7 @@ def _test_string_map_reference_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10061,7 +10061,7 @@ def _test_string_map_reference_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -10324,7 +10324,7 @@ def _upload_file_with_additional_properties_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -10345,7 +10345,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -10354,7 +10354,7 @@ def _upload_file_with_additional_properties_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -10364,7 +10364,7 @@ def _upload_file_with_additional_properties_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/fake_classname_tags123_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/fake_classname_tags123_api.py index e373462e5f5b..bdcd298ac5db 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/api/fake_classname_tags123_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/fake_classname_tags123_api.py @@ -250,7 +250,7 @@ def _test_classname_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -267,7 +267,7 @@ def _test_classname_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -276,7 +276,7 @@ def _test_classname_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -286,7 +286,7 @@ def _test_classname_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/import_test_datetime_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/import_test_datetime_api.py index ae01fa137fa1..80426d1910ad 100644 --- a/samples/openapi3/client/petstore/python/petstore_api/api/import_test_datetime_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/import_test_datetime_api.py @@ -232,7 +232,7 @@ def _import_test_return_datetime_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -247,7 +247,7 @@ def _import_test_return_datetime_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/pet_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/pet_api.py index 7d4cf604eb15..d34bd5c3c4e7 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/pet_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/pet_api.py @@ -255,7 +255,7 @@ def _add_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -274,7 +274,7 @@ def _add_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -285,7 +285,7 @@ def _add_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -540,7 +540,7 @@ def _delete_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -553,7 +553,7 @@ def _delete_pet_serialize( # process the query parameters # process the header parameters if api_key is not None: - _header_params['api_key'] = api_key + self.api_client._set_header(_header_params, 'api_key', api_key) # process the form parameters # process the body parameter @@ -800,7 +800,7 @@ def _find_pets_by_status_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -819,7 +819,7 @@ def _find_pets_by_status_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1072,7 +1072,7 @@ def _find_pets_by_tags_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1091,7 +1091,7 @@ def _find_pets_by_tags_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1343,7 +1343,7 @@ def _get_pet_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1360,7 +1360,7 @@ def _get_pet_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1614,7 +1614,7 @@ def _update_pet_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1633,7 +1633,7 @@ def _update_pet_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1644,7 +1644,7 @@ def _update_pet_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1912,7 +1912,7 @@ def _update_pet_with_form_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1935,7 +1935,7 @@ def _update_pet_with_form_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1945,7 +1945,7 @@ def _update_pet_with_form_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2209,7 +2209,7 @@ def _upload_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2230,7 +2230,7 @@ def _upload_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2239,7 +2239,7 @@ def _upload_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2249,7 +2249,7 @@ def _upload_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -2513,7 +2513,7 @@ def _upload_file_with_required_file_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2534,7 +2534,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -2543,7 +2543,7 @@ def _upload_file_with_required_file_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2553,7 +2553,7 @@ def _upload_file_with_required_file_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/store_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/store_api.py index 73471217df00..f323e37fcdd5 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/store_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/store_api.py @@ -254,7 +254,7 @@ def _delete_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -494,7 +494,7 @@ def _get_inventory_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -509,7 +509,7 @@ def _get_inventory_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/json' @@ -759,7 +759,7 @@ def _get_order_by_id_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -776,7 +776,7 @@ def _get_order_by_id_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1023,7 +1023,7 @@ def _place_order_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1040,7 +1040,7 @@ def _place_order_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1050,7 +1050,7 @@ def _place_order_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -1060,7 +1060,7 @@ def _place_order_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/user_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/user_api.py index be61d536e31c..28e2ca3c42e1 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/user_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/user_api.py @@ -254,7 +254,7 @@ def _create_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -273,7 +273,7 @@ def _create_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -283,7 +283,7 @@ def _create_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -518,7 +518,7 @@ def _create_users_with_array_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -537,7 +537,7 @@ def _create_users_with_array_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -547,7 +547,7 @@ def _create_users_with_array_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -782,7 +782,7 @@ def _create_users_with_list_input_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -801,7 +801,7 @@ def _create_users_with_list_input_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -811,7 +811,7 @@ def _create_users_with_list_input_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ @@ -1051,7 +1051,7 @@ def _delete_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1310,7 +1310,7 @@ def _get_user_by_name_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1327,7 +1327,7 @@ def _get_user_by_name_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1587,7 +1587,7 @@ def _login_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -1610,7 +1610,7 @@ def _login_user_serialize( # set the HTTP header `Accept` - if 'Accept' not in _header_params: + if not any(key.lower() == 'accept' for key in _header_params): _header_params['Accept'] = self.api_client.select_header_accept( [ 'application/xml', @@ -1838,7 +1838,7 @@ def _logout_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2105,7 +2105,7 @@ def _update_user_serialize( _path_params: Dict[str, str] = {} _query_params: List[Tuple[str, str]] = [] - _header_params: Dict[str, Optional[str]] = _headers or {} + _header_params: Dict[str, Any] = self.api_client._merge_headers(_headers) _form_params: List[Tuple[str, str]] = [] _files: Dict[ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] @@ -2126,7 +2126,7 @@ def _update_user_serialize( # set the HTTP header `Content-Type` if _content_type: - _header_params['Content-Type'] = _content_type + self.api_client._set_header(_header_params, 'Content-Type', _content_type) else: _default_content_type = ( self.api_client.select_header_content_type( @@ -2136,7 +2136,7 @@ def _update_user_serialize( ) ) if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type + self.api_client._set_header(_header_params, 'Content-Type', _default_content_type) # authentication setting _auth_settings: List[str] = [ diff --git a/samples/openapi3/client/petstore/python/petstore_api/api_client.py b/samples/openapi3/client/petstore/python/petstore_api/api_client.py index c98eb486e651..5b6101731ba0 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api_client.py @@ -23,7 +23,7 @@ import uuid from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union +from typing import Any, Tuple, Optional, List, Dict, Union from pydantic import SecretStr from petstore_api.configuration import Configuration @@ -103,16 +103,36 @@ def __exit__(self, exc_type, exc_value, traceback): @property def user_agent(self): """User agent for this API client""" - return self.default_headers['User-Agent'] + for name, value in reversed(self.default_headers.items()): + if name.lower() == 'user-agent': + return value + raise KeyError('User-Agent') @user_agent.setter def user_agent(self, value): - self.default_headers['User-Agent'] = value + self._set_header(self.default_headers, 'User-Agent', value) def set_default_header(self, header_name, header_value): - self.default_headers[header_name] = header_value + self._set_header(self.default_headers, header_name, header_value) + @staticmethod + def _set_header(headers: Dict[str, Any], name: str, value: Any) -> None: + """Replace a header case-insensitively, retaining the winning spelling.""" + for key in list(headers): + if key.lower() == name.lower(): + del headers[key] + headers[name] = value + + @classmethod + def _merge_headers(cls, *sources: Optional[Dict[str, Any]]) -> Dict[str, Any]: + """Copy headers; later sources and later entries in each dict win.""" + headers: Dict[str, Any] = {} + for source in sources: + for name, value in (source or {}).items(): + cls._set_header(headers, name, value) + return headers + _default = None @classmethod @@ -179,10 +199,9 @@ def param_serialize( config = self.configuration # header parameters - header_params = header_params or {} - header_params.update(self.default_headers) + header_params = self._merge_headers(header_params, self.default_headers) if self.cookie: - header_params['Cookie'] = self.cookie + self._set_header(header_params, 'Cookie', self.cookie) if header_params: header_params = self.sanitize_for_serialization(header_params) header_params = dict( @@ -704,7 +723,11 @@ def _apply_auth_params( :param auth_setting: auth settings for the endpoint """ if auth_setting['in'] == 'cookie': - if not 'Cookie' in headers: + for key in list(headers): + if key.lower() == 'cookie': + self._set_header(headers, 'Cookie', headers[key]) + break + if not headers.get('Cookie'): headers['Cookie'] = "" else: headers['Cookie'] += "; " @@ -713,14 +736,15 @@ def _apply_auth_params( headers['Cookie'] += f"{auth_setting['key']}={cookie_value}" elif auth_setting['in'] == 'header': if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] + self._set_header(headers, auth_setting['key'], auth_setting['value']) else: # The HTTP signature scheme requires multiple HTTP headers # that are calculated dynamically. signing_info = self.configuration.signing_info auth_headers = signing_info.get_http_signature_headers( resource_path, method, headers, body, queries) - headers.update(auth_headers) + for name, value in auth_headers.items(): + self._set_header(headers, name, value) elif auth_setting['in'] == 'query': queries.append((auth_setting['key'], auth_setting['value'])) else: diff --git a/samples/openapi3/client/petstore/python/petstore_api/rest.py b/samples/openapi3/client/petstore/python/petstore_api/rest.py index a265bee3515c..b50e20bcbaae 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python/petstore_api/rest.py @@ -216,7 +216,7 @@ def request( ) post_params = post_params or {} - headers = headers or {} + headers = urllib3.HTTPHeaderDict(headers or {}) timeout = None if _request_timeout: diff --git a/samples/openapi3/client/petstore/python/tests/test_request_headers.py b/samples/openapi3/client/petstore/python/tests/test_request_headers.py new file mode 100644 index 000000000000..275c483d0e2b --- /dev/null +++ b/samples/openapi3/client/petstore/python/tests/test_request_headers.py @@ -0,0 +1,227 @@ +"""Request-header behavior for the urllib3 client.""" + +import asyncio +from concurrent.futures import ThreadPoolExecutor +import inspect +import unittest +from typing import Any +from unittest.mock import AsyncMock, Mock + +import petstore_api + +ASYNC = inspect.iscoroutinefunction(petstore_api.ApiClient.call_api) + + +class TestRequestHeaders(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + self.requests: list[dict[str, Any]] = [] + self.client = petstore_api.ApiClient(petstore_api.Configuration( + host='https://example.test', access_token='configured-token', + api_key={'api_key': 'configured-key'}, + )) + response = Mock(status=200, reason='OK', data=b'{}', headers={}) + response.read = AsyncMock(return_value=b'{}') + + def respond(*args, **kwargs): + self.requests.append({**kwargs, 'headers': kwargs['headers'].copy()}) + return response + + async def respond_async(*args, **kwargs): + await asyncio.sleep(0) + return respond(*args, **kwargs) + + self.pool: Any = AsyncMock() if ASYNC else Mock() + self.pool.request.side_effect = respond_async if ASYNC else respond + self.client.rest_client.pool_manager = self.pool + self.api = petstore_api.PetApi(self.client) + self.pet = petstore_api.Pet(name='test', photoUrls=[]) + + async def asyncTearDown(self): + if ASYNC: + await getattr(self.client, 'close')() + else: + self.pool.clear() + + async def call(self, **kwargs): + result = self.api.add_pet(self.pet, **kwargs) + if inspect.isawaitable(result): + await result + + def values(self, headers, name): + if isinstance(headers, dict): + return [value for key, value in headers.items() if key.lower() == name.lower()] + return headers.getall(name) if ASYNC else headers.getlist(name) + + def assert_header(self, name, value): + self.assertEqual(self.values(self.requests[-1]['headers'], name), [value]) + + async def test_generated_content_type_and_accept_are_case_insensitive(self): + for spelling in ('Content-Type', 'content-type', 'CONTENT-TYPE'): + for value in ('application/json', 'text/plain'): + with self.subTest(spelling=spelling, value=value): + headers = {spelling: value, 'accept': 'custom'} + await self.call(_headers=headers) + self.assert_header('content-type', 'application/json') + self.assert_header('accept', 'custom') + self.assertEqual(headers, {spelling: value, 'accept': 'custom'}) + + async def test_user_agent_matches_last_direct_default_header_write(self): + self.client.default_headers['user-agent'] = 'custom' + self.client.default_headers['USER-AGENT'] = 'latest' + defaults = self.client.default_headers.copy() + self.assertEqual(self.client.user_agent, 'latest') + await self.call() + self.assert_header('user-agent', 'latest') + self.assertEqual(self.client.default_headers, defaults) + + async def test_content_type_override_and_defaults_retain_precedence(self): + headers = {'content-type': 'text/plain'} + await self.call(_headers=headers, _content_type='application/custom+json') + self.assert_header('content-type', 'application/custom+json') + self.client.set_default_header('CONTENT-TYPE', 'application/default+json') + defaults = self.client.default_headers.copy() + await self.call(_headers=headers, _content_type='application/custom+json') + self.assert_header('content-type', 'application/default+json') + self.assertEqual(self.client.default_headers, defaults) + self.assertEqual(headers, {'content-type': 'text/plain'}) + + async def test_defaults_last_write_and_user_agent_property(self): + self.client.set_default_header('X-Default', 'old') + self.client.set_default_header('x-default', 'middle') + self.client.set_default_header('X-Default', 'new') + self.client.set_default_header('user-agent', 'custom') + self.assertEqual(self.client.user_agent, 'custom') + headers = {'x-default': 'call', 'X-List': 'first', 'x-list': 'a, b, a'} + await self.call(_headers=headers) + self.assert_header('x-default', 'new') + self.assert_header('user-agent', 'custom') + self.assert_header('x-list', 'a, b, a') + self.assertEqual(headers['X-List'], 'first') + self.client.user_agent = 'reset' + self.assertEqual(self.client.user_agent, 'reset') + self.assertEqual( + len([key for key in self.client.default_headers if key.lower() == 'user-agent']), 1 + ) + + async def test_serializers_preserve_inputs_and_explicit_header_wins(self): + headers = {'content-type': 'text/plain', 'API_KEY': 'call'} + original = headers.copy() + defaults = self.client.default_headers.copy() + params = self.api._delete_pet_serialize( + pet_id=1, api_key='explicit', _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.assertEqual(params[2]['api_key'], 'explicit') + self.api._add_pet_serialize( + pet=self.pet, _headers=headers, _request_auth=None, + _content_type=None, _host_index=0, + ) + self.client.param_serialize('GET', '/pet', header_params=headers, query_params=[]) + self.assertEqual(headers, original) + self.assertEqual(self.client.default_headers, defaults) + + async def test_authentication_and_empty_override(self): + self.client.set_default_header('AUTHORIZATION', 'default') + headers = {'authorization': 'call'} + defaults = self.client.default_headers.copy() + await self.call(_headers=headers, _request_auth={}) + self.assert_header('authorization', 'Bearer configured-token') + auth = {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', 'value': 'Bearer call'} + await self.call(_headers=headers, _request_auth=auth) + self.assert_header('authorization', 'Bearer call') + self.assertEqual(headers, {'authorization': 'call'}) + self.assertEqual(auth['value'], 'Bearer call') + self.assertEqual(self.client.default_headers, defaults) + self.client.set_default_header('API_KEY', 'default') + key_headers = {'Api_Key': 'call'} + params = self.client.param_serialize( + 'GET', '/key', header_params=key_headers, auth_settings=['api_key'], query_params=[] + ) + result = self.client.call_api(*params) + if inspect.isawaitable(result): + await result + self.assert_header('api_key', 'configured-key') + self.assertEqual(key_headers, {'Api_Key': 'call'}) + + async def test_cookie_authentication_appends_without_empty_separator(self): + for value, expected in (('', 'session=two'), ('client=1', 'client=1; session=two')): + headers = {'cookie': value} + params = self.client.param_serialize( + 'GET', '/cookie', header_params=headers, query_params=[], + auth_settings=['cookie'], + _request_auth={ + 'in': 'cookie', 'key': 'session', 'type': 'api_key', 'value': 'two', + }, + ) + result = self.client.call_api(*params) + if inspect.isawaitable(result): + await result + self.assert_header('cookie', expected) + self.assertEqual(headers, {'cookie': value}) + + async def test_concurrent_calls_keep_inputs_defaults_and_credentials_isolated(self): + headers = {'content-type': 'application/json', 'authorization': 'caller'} + defaults = self.client.default_headers.copy() + + def auth(index): + return {'in': 'header', 'key': 'Authorization', 'type': 'oauth2', + 'value': f'Bearer request-{index}'} + + if ASYNC: + await asyncio.gather(*( + self.call(_headers=headers, _request_auth=auth(index)) for index in range(20) + )) + else: + def run_calls(): + with ThreadPoolExecutor(max_workers=4) as executor: + list(executor.map(lambda index: self.api.add_pet( + self.pet, _headers=headers, _request_auth=auth(index) + ), range(20))) + await asyncio.to_thread(run_calls) + self.assertCountEqual( + [request['headers']['authorization'] for request in self.requests], + [f'Bearer request-{index}' for index in range(20)], + ) + await self.call() + self.assert_header('authorization', 'Bearer configured-token') + self.assertEqual(headers, {'content-type': 'application/json', 'authorization': 'caller'}) + self.assertEqual(self.client.default_headers, defaults) + + async def test_transport_reads_lowercase_content_type(self): + headers = {'content-type': 'application/x-www-form-urlencoded'} + result = self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + if inspect.isawaitable(result): + await result + self.assert_header('content-type', 'application/x-www-form-urlencoded') + self.assertFalse(self.requests[-1].get('encode_multipart', True)) + self.assertEqual(self.requests[-1]['fields'], [('field', 'value')]) + self.assertEqual(headers, {'content-type': 'application/x-www-form-urlencoded'}) + + async def test_transport_reads_lowercase_content_type_and_preserves_repeated_fields(self): + import urllib3 + headers = urllib3.HTTPHeaderDict({'content-type': 'application/x-www-form-urlencoded'}) + headers.add('x-list', 'a') + headers.add('x-list', 'b') + result = self.client.rest_client.request( + 'POST', 'https://example.test/form', headers=headers, post_params=[('field', 'value')] + ) + if inspect.isawaitable(result): + await result + self.assert_header('content-type', 'application/x-www-form-urlencoded') + self.assertEqual(self.values(self.requests[-1]['headers'], 'x-list'), ['a', 'b']) + self.assertEqual(self.values(headers, 'x-list'), ['a', 'b']) + self.assertFalse(self.requests[-1]['encode_multipart']) + self.assertEqual(self.requests[-1]['fields'], [('field', 'value')]) + + async def test_transport_multipart_removes_content_type_without_mutating_input(self): + headers = {'content-type': 'multipart/form-data'} + result = self.client.rest_client.request( + 'POST', 'https://example.test/upload', headers=headers, + post_params=[('file', ('name.txt', b'content', 'text/plain'))], + ) + if inspect.isawaitable(result): + await result + self.assertNotIn('content-type', self.requests[-1]['headers']) + self.assertEqual(headers, {'content-type': 'multipart/form-data'})