[python-experimental] Enhance octet-stream deserialize (#13402)

* [python-experimental] Enhance octet-stream deserialization

When the headers didn't provide the filename, use the url of response to
extract filename.

* [python-experimental] Remove todo comment.

* [python-experimental] Fix test code.

* Update samples

* [python-experimental] Refined the method and the test

+ Early return when the url is empty or `None`.
+ Removed unused f-string prefix.

* [python-experimental] Comapre url is None explicitly.

* Update samples.
This commit is contained in:
Elton H.Y. Chou 2022-09-13 03:04:14 +08:00 committed by GitHub
parent 194d421d83
commit 8e66294bfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 151 additions and 67 deletions

View File

@ -15,7 +15,7 @@ import tempfile
import typing
import urllib3
from urllib3._collections import HTTPHeaderDict
from urllib.parse import quote
from urllib.parse import urlparse, quote
from urllib3.fields import RequestField as RequestFieldBase
{{#if tornado}}
@ -832,6 +832,19 @@ class OpenApiResponse(JSONDetector):
# python must be >= 3.9 so we can pass in bytes into json.loads
return json.loads(response.data)
@staticmethod
def __file_name_from_response_url(response_url: typing.Optional[str]) -> typing.Optional[str]:
if response_url is None:
return None
url_path = urlparse(response_url).path
if url_path:
path_basename = os.path.basename(url_path)
if path_basename:
_filename, ext = os.path.splitext(path_basename)
if ext:
return path_basename
return None
@classmethod
def __file_name_from_content_disposition(cls, content_disposition: typing.Optional[str]) -> typing.Optional[str]:
if content_disposition is None:
@ -851,13 +864,16 @@ class OpenApiResponse(JSONDetector):
a file will be written and returned
"""
if response.supports_chunked_reads():
file_name = self.__file_name_from_content_disposition(response.headers.get('content-disposition'))
file_name = (
self.__file_name_from_content_disposition(response.headers.get('content-disposition'))
or self.__file_name_from_response_url(response.geturl())
)
if file_name is None:
_fd, path = tempfile.mkstemp()
else:
path = os.path.join(tempfile.gettempdir(), file_name)
# TODO get file_name from the filename at the end of the url if it exists
with open(path, 'wb') as new_file:
chunk_size = 1024
while True:

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.AnotherFake do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.Default do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.Fake do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.FakeClassnameTags123 do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.Pet do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.Store do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Api.User do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Connection do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Deserializer do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.FooGetDefaultResponse do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.SpecialModelName do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.AdditionalPropertiesClass do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.AllOfWithSingleRef do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Animal do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ApiResponse do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ArrayOfArrayOfNumberOnly do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ArrayOfNumberOnly do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ArrayTest do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Capitalization do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Cat do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.CatAllOf do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Category do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ClassModel do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Client do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.DeprecatedObject do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Dog do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.DogAllOf do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.EnumArrays do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.EnumClass do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.EnumTest do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.File do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.FileSchemaTestClass do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Foo do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.FormatTest do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.HasOnlyReadOnly do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.HealthCheckResult do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.List do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.MapTest do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.MixedPropertiesAndAdditionalPropertiesClass do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Model200Response do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Name do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.NullableClass do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.NumberOnly do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ObjectWithDeprecatedFields do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Order do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.OuterComposite do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.OuterEnum do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.OuterEnumDefaultValue do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.OuterEnumInteger do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.OuterEnumIntegerDefaultValue do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.OuterObjectWithEnumProperty do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Pet do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.ReadOnlyFirst do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Return do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.SingleRefType do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.Tag do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.Model.User do

View File

@ -1,4 +1,4 @@
# NOTE: This file is auto generated by OpenAPI Generator 6.1.0-SNAPSHOT (https://openapi-generator.tech).
# NOTE: This file is auto generated by OpenAPI Generator 6.1.1-SNAPSHOT (https://openapi-generator.tech).
# Do not edit this file manually.
defmodule OpenapiPetstore.RequestBuilder do

View File

@ -22,7 +22,7 @@ import tempfile
import typing
import urllib3
from urllib3._collections import HTTPHeaderDict
from urllib.parse import quote
from urllib.parse import urlparse, quote
from urllib3.fields import RequestField as RequestFieldBase
import frozendict
@ -836,6 +836,19 @@ class OpenApiResponse(JSONDetector):
# python must be >= 3.9 so we can pass in bytes into json.loads
return json.loads(response.data)
@staticmethod
def __file_name_from_response_url(response_url: typing.Optional[str]) -> typing.Optional[str]:
if response_url is None:
return None
url_path = urlparse(response_url).path
if url_path:
path_basename = os.path.basename(url_path)
if path_basename:
_filename, ext = os.path.splitext(path_basename)
if ext:
return path_basename
return None
@classmethod
def __file_name_from_content_disposition(cls, content_disposition: typing.Optional[str]) -> typing.Optional[str]:
if content_disposition is None:
@ -855,13 +868,16 @@ class OpenApiResponse(JSONDetector):
a file will be written and returned
"""
if response.supports_chunked_reads():
file_name = self.__file_name_from_content_disposition(response.headers.get('content-disposition'))
file_name = (
self.__file_name_from_content_disposition(response.headers.get('content-disposition'))
or self.__file_name_from_response_url(response.geturl())
)
if file_name is None:
_fd, path = tempfile.mkstemp()
else:
path = os.path.join(tempfile.gettempdir(), file_name)
# TODO get file_name from the filename at the end of the url if it exists
with open(path, 'wb') as new_file:
chunk_size = 1024
while True:

View File

@ -22,7 +22,7 @@ import tempfile
import typing
import urllib3
from urllib3._collections import HTTPHeaderDict
from urllib.parse import quote
from urllib.parse import urlparse, quote
from urllib3.fields import RequestField as RequestFieldBase
import frozendict
@ -836,6 +836,19 @@ class OpenApiResponse(JSONDetector):
# python must be >= 3.9 so we can pass in bytes into json.loads
return json.loads(response.data)
@staticmethod
def __file_name_from_response_url(response_url: typing.Optional[str]) -> typing.Optional[str]:
if response_url is None:
return None
url_path = urlparse(response_url).path
if url_path:
path_basename = os.path.basename(url_path)
if path_basename:
_filename, ext = os.path.splitext(path_basename)
if ext:
return path_basename
return None
@classmethod
def __file_name_from_content_disposition(cls, content_disposition: typing.Optional[str]) -> typing.Optional[str]:
if content_disposition is None:
@ -855,13 +868,16 @@ class OpenApiResponse(JSONDetector):
a file will be written and returned
"""
if response.supports_chunked_reads():
file_name = self.__file_name_from_content_disposition(response.headers.get('content-disposition'))
file_name = (
self.__file_name_from_content_disposition(response.headers.get('content-disposition'))
or self.__file_name_from_response_url(response.geturl())
)
if file_name is None:
_fd, path = tempfile.mkstemp()
else:
path = os.path.join(tempfile.gettempdir(), file_name)
# TODO get file_name from the filename at the end of the url if it exists
with open(path, 'wb') as new_file:
chunk_size = 1024
while True:

View File

@ -400,6 +400,42 @@ class TestFakeApi(ApiTestMixin):
api_response.body.close()
os.unlink(api_response.body.name)
"""
when streaming is used and the response contains the content disposition header without a filename
the url of response is used to extract the filename.
"""
file1 = open(file_path1, "rb")
streamable_body = StreamableBody(file1)
expected_filename = "the_file.ext"
no_filename_mock_response = self.response(
streamable_body,
content_type='application/octet-stream',
headers={'content-disposition': 'attachment'},
preload_content=False
)
with patch.object(RESTClientObject, 'request') as mock_request:
no_filename_mock_response.geturl = lambda: f'http://foo.bar/{expected_filename}'
mock_request.return_value = no_filename_mock_response
api_response = self.api.upload_download_file(body=file_bytes, stream=True)
self.assert_request_called_with(
mock_request,
'http://petstore.swagger.io:80/v2/fake/uploadDownloadFile',
body=file_bytes,
content_type='application/octet-stream',
accept_content_type='application/octet-stream',
stream=True
)
self.assertTrue(file1.closed)
self.assertTrue(isinstance(api_response.body, schemas.BinarySchema))
self.assertTrue(isinstance(api_response.body, schemas.FileSchema))
self.assertTrue(isinstance(api_response.body, schemas.FileIO))
self.assertTrue(api_response.body.name.endswith(expected_filename))
self.assertEqual(api_response.body.read(), file_bytes)
api_response.body.close()
os.unlink(api_response.body.name)
def test_upload_file(self):
"""Test case for upload_file
uploads a file using multipart/form-data # noqa: E501