Skip to content

Commit f139c09

Browse files
authored
[python-experimental] adds and uses regex patterns for json + filename detection (#13357)
* Unit test sample regenerated * Reverts version files
1 parent cb8d9d5 commit f139c09

6 files changed

Lines changed: 54 additions & 51 deletions

File tree

modules/openapi-generator/src/main/resources/python-experimental/README.handlebars

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Python {{generatorLanguageVersion}}
2121
v3.9 is needed so one can combine classmethod and property decorators to define
2222
object schema properties as classes
2323

24-
## Migration from other generators like python and python-experimental
24+
## Migration from other generators like python and python-legacy
2525

2626
### Changes
2727
1. This generator uses spec case for all (object) property names and parameter names.

modules/openapi-generator/src/main/resources/python-experimental/api_client.handlebars

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -796,24 +796,25 @@ class ApiResponseWithoutDeserialization(ApiResponse):
796796

797797

798798
class JSONDetector:
799-
@staticmethod
800-
def _content_type_is_json(content_type: str) -> bool:
801-
content_type_piece = content_type
802-
if ';' in content_type:
803-
# application/json; charset=UTF-8
804-
content_type_piece = content_type.split(';')[0]
805-
elif '-' in content_type:
806-
"""
807-
application/json-patch+json
808-
application/json-seq
809-
"""
810-
content_type_piece = content_type.split('-')[0]
811-
if content_type_piece == 'application/json':
799+
"""
800+
Works for:
801+
application/json
802+
application/json; charset=UTF-8
803+
application/json-patch+json
804+
application/geo+json
805+
"""
806+
__json_content_type_pattern = re.compile("application/[^+]*[+]?(json);?.*")
807+
808+
@classmethod
809+
def _content_type_is_json(cls, content_type: str) -> bool:
810+
if cls.__json_content_type_pattern.match(content_type):
812811
return True
813812
return False
814813

815814

816815
class OpenApiResponse(JSONDetector):
816+
__filename_content_disposition_pattern = re.compile('filename="(.+?)"')
817+
817818
def __init__(
818819
self,
819820
response_cls: typing.Type[ApiResponse] = ApiResponse,
@@ -831,11 +832,11 @@ class OpenApiResponse(JSONDetector):
831832
# python must be >= 3.9 so we can pass in bytes into json.loads
832833
return json.loads(response.data)
833834

834-
@staticmethod
835-
def __file_name_from_content_disposition(content_disposition: typing.Optional[str]) -> typing.Optional[str]:
835+
@classmethod
836+
def __file_name_from_content_disposition(cls, content_disposition: typing.Optional[str]) -> typing.Optional[str]:
836837
if content_disposition is None:
837838
return None
838-
match = re.search('filename="(.+?)"', content_disposition)
839+
match = cls.__filename_content_disposition_pattern.search(content_disposition)
839840
if not match:
840841
return None
841842
return match.group(1)

samples/openapi3/client/3_0_3_unit_test/python-experimental/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Python >=3.9
1313
v3.9 is needed so one can combine classmethod and property decorators to define
1414
object schema properties as classes
1515

16-
## Migration from other generators like python and python-experimental
16+
## Migration from other generators like python and python-legacy
1717

1818
### Changes
1919
1. This generator uses spec case for all (object) property names and parameter names.

samples/openapi3/client/3_0_3_unit_test/python-experimental/unit_test_api/api_client.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -800,24 +800,25 @@ class ApiResponseWithoutDeserialization(ApiResponse):
800800

801801

802802
class JSONDetector:
803-
@staticmethod
804-
def _content_type_is_json(content_type: str) -> bool:
805-
content_type_piece = content_type
806-
if ';' in content_type:
807-
# application/json; charset=UTF-8
808-
content_type_piece = content_type.split(';')[0]
809-
elif '-' in content_type:
810-
"""
811-
application/json-patch+json
812-
application/json-seq
813-
"""
814-
content_type_piece = content_type.split('-')[0]
815-
if content_type_piece == 'application/json':
803+
"""
804+
Works for:
805+
application/json
806+
application/json; charset=UTF-8
807+
application/json-patch+json
808+
application/geo+json
809+
"""
810+
__json_content_type_pattern = re.compile("application/[^+]*[+]?(json);?.*")
811+
812+
@classmethod
813+
def _content_type_is_json(cls, content_type: str) -> bool:
814+
if cls.__json_content_type_pattern.match(content_type):
816815
return True
817816
return False
818817

819818

820819
class OpenApiResponse(JSONDetector):
820+
__filename_content_disposition_pattern = re.compile('filename="(.+?)"')
821+
821822
def __init__(
822823
self,
823824
response_cls: typing.Type[ApiResponse] = ApiResponse,
@@ -835,11 +836,11 @@ def __deserialize_json(response: urllib3.HTTPResponse) -> typing.Any:
835836
# python must be >= 3.9 so we can pass in bytes into json.loads
836837
return json.loads(response.data)
837838

838-
@staticmethod
839-
def __file_name_from_content_disposition(content_disposition: typing.Optional[str]) -> typing.Optional[str]:
839+
@classmethod
840+
def __file_name_from_content_disposition(cls, content_disposition: typing.Optional[str]) -> typing.Optional[str]:
840841
if content_disposition is None:
841842
return None
842-
match = re.search('filename="(.+?)"', content_disposition)
843+
match = cls.__filename_content_disposition_pattern.search(content_disposition)
843844
if not match:
844845
return None
845846
return match.group(1)

samples/openapi3/client/petstore/python-experimental/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Python >=3.9
1313
v3.9 is needed so one can combine classmethod and property decorators to define
1414
object schema properties as classes
1515

16-
## Migration from other generators like python and python-experimental
16+
## Migration from other generators like python and python-legacy
1717

1818
### Changes
1919
1. This generator uses spec case for all (object) property names and parameter names.

samples/openapi3/client/petstore/python-experimental/petstore_api/api_client.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -800,24 +800,25 @@ class ApiResponseWithoutDeserialization(ApiResponse):
800800

801801

802802
class JSONDetector:
803-
@staticmethod
804-
def _content_type_is_json(content_type: str) -> bool:
805-
content_type_piece = content_type
806-
if ';' in content_type:
807-
# application/json; charset=UTF-8
808-
content_type_piece = content_type.split(';')[0]
809-
elif '-' in content_type:
810-
"""
811-
application/json-patch+json
812-
application/json-seq
813-
"""
814-
content_type_piece = content_type.split('-')[0]
815-
if content_type_piece == 'application/json':
803+
"""
804+
Works for:
805+
application/json
806+
application/json; charset=UTF-8
807+
application/json-patch+json
808+
application/geo+json
809+
"""
810+
__json_content_type_pattern = re.compile("application/[^+]*[+]?(json);?.*")
811+
812+
@classmethod
813+
def _content_type_is_json(cls, content_type: str) -> bool:
814+
if cls.__json_content_type_pattern.match(content_type):
816815
return True
817816
return False
818817

819818

820819
class OpenApiResponse(JSONDetector):
820+
__filename_content_disposition_pattern = re.compile('filename="(.+?)"')
821+
821822
def __init__(
822823
self,
823824
response_cls: typing.Type[ApiResponse] = ApiResponse,
@@ -835,11 +836,11 @@ def __deserialize_json(response: urllib3.HTTPResponse) -> typing.Any:
835836
# python must be >= 3.9 so we can pass in bytes into json.loads
836837
return json.loads(response.data)
837838

838-
@staticmethod
839-
def __file_name_from_content_disposition(content_disposition: typing.Optional[str]) -> typing.Optional[str]:
839+
@classmethod
840+
def __file_name_from_content_disposition(cls, content_disposition: typing.Optional[str]) -> typing.Optional[str]:
840841
if content_disposition is None:
841842
return None
842-
match = re.search('filename="(.+?)"', content_disposition)
843+
match = cls.__filename_content_disposition_pattern.search(content_disposition)
843844
if not match:
844845
return None
845846
return match.group(1)

0 commit comments

Comments
 (0)