Jonathan Ballet 22a0fc1727
python: adjust basic typing information (#17511)
* python: adjust basic typing information

This is an initial pass to fix and adjust the typing information for the
generated client. This is enough to have mypy runnning without complains
on all the (modern) generated clients (Pydantic v1 code is not checked
for instance)

mypy is also now run directly in the CI, so further changes will also be
checked and thus, will need to be compliant with good typing
information.

Note that this doesn't *fully* type all the code: mypy is not run in
"strict" mode and there are still many functions/methods/attributes
which are still not fully typed, but it's a first good step in that
direction.

* ApiResponse's raw_data can't be None

* Fix indentation

* Revert test changes

* run mypy on tests/ directory

* don't forcefully convert the client response headers to dict

* override petstore ApiResponse model

* adjust type of 'any/one_of_schemas' fields
2024-01-06 15:40:42 +08:00

201 lines
5.8 KiB
Python

# coding: utf-8
"""
Echo Server API
Echo Server API
The version of the OpenAPI document: 0.1.0
Contact: team@openapitools.org
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from typing import Any, Optional
from typing_extensions import Self
class OpenApiException(Exception):
"""The base exception class for all OpenAPIExceptions"""
class ApiTypeError(OpenApiException, TypeError):
def __init__(self, msg, path_to_item=None, valid_classes=None,
key_type=None) -> None:
""" Raises an exception for TypeErrors
Args:
msg (str): the exception message
Keyword Args:
path_to_item (list): a list of keys an indices to get to the
current_item
None if unset
valid_classes (tuple): the primitive classes that current item
should be an instance of
None if unset
key_type (bool): False if our value is a value in a dict
True if it is a key in a dict
False if our item is an item in a list
None if unset
"""
self.path_to_item = path_to_item
self.valid_classes = valid_classes
self.key_type = key_type
full_msg = msg
if path_to_item:
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
super(ApiTypeError, self).__init__(full_msg)
class ApiValueError(OpenApiException, ValueError):
def __init__(self, msg, path_to_item=None) -> None:
"""
Args:
msg (str): the exception message
Keyword Args:
path_to_item (list) the path to the exception in the
received_data dict. None if unset
"""
self.path_to_item = path_to_item
full_msg = msg
if path_to_item:
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
super(ApiValueError, self).__init__(full_msg)
class ApiAttributeError(OpenApiException, AttributeError):
def __init__(self, msg, path_to_item=None) -> None:
"""
Raised when an attribute reference or assignment fails.
Args:
msg (str): the exception message
Keyword Args:
path_to_item (None/list) the path to the exception in the
received_data dict
"""
self.path_to_item = path_to_item
full_msg = msg
if path_to_item:
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
super(ApiAttributeError, self).__init__(full_msg)
class ApiKeyError(OpenApiException, KeyError):
def __init__(self, msg, path_to_item=None) -> None:
"""
Args:
msg (str): the exception message
Keyword Args:
path_to_item (None/list) the path to the exception in the
received_data dict
"""
self.path_to_item = path_to_item
full_msg = msg
if path_to_item:
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
super(ApiKeyError, self).__init__(full_msg)
class ApiException(OpenApiException):
def __init__(
self,
status=None,
reason=None,
http_resp=None,
*,
body: Optional[str] = None,
data: Optional[Any] = None,
) -> None:
self.status = status
self.reason = reason
self.body = body
self.data = data
self.headers = None
if http_resp:
if self.status is None:
self.status = http_resp.status
if self.reason is None:
self.reason = http_resp.reason
if self.body is None:
try:
self.body = http_resp.data.decode('utf-8')
except Exception:
pass
self.headers = http_resp.getheaders()
@classmethod
def from_response(
cls,
*,
http_resp,
body: Optional[str],
data: Optional[Any],
) -> Self:
if http_resp.status == 400:
raise BadRequestException(http_resp=http_resp, body=body, data=data)
if http_resp.status == 401:
raise UnauthorizedException(http_resp=http_resp, body=body, data=data)
if http_resp.status == 403:
raise ForbiddenException(http_resp=http_resp, body=body, data=data)
if http_resp.status == 404:
raise NotFoundException(http_resp=http_resp, body=body, data=data)
if 500 <= http_resp.status <= 599:
raise ServiceException(http_resp=http_resp, body=body, data=data)
raise ApiException(http_resp=http_resp, body=body, data=data)
def __str__(self):
"""Custom error messages for exception"""
error_message = "({0})\n"\
"Reason: {1}\n".format(self.status, self.reason)
if self.headers:
error_message += "HTTP response headers: {0}\n".format(
self.headers)
if self.data or self.body:
error_message += "HTTP response body: {0}\n".format(self.data or self.body)
return error_message
class BadRequestException(ApiException):
pass
class NotFoundException(ApiException):
pass
class UnauthorizedException(ApiException):
pass
class ForbiddenException(ApiException):
pass
class ServiceException(ApiException):
pass
def render_path(path_to_item):
"""Returns a string representation of a path"""
result = ""
for pth in path_to_item:
if isinstance(pth, int):
result += "[{0}]".format(pth)
else:
result += "['{0}']".format(pth)
return result