Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python: Add back the HTTPValidationError #1699

Merged
merged 4 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions python/svix/api/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import httpx

from .client import AuthenticatedClient
from .http_error import HttpError

from .errors.http_error import HttpError
from .errors.http_validation_error import HTTPValidationError


def ensure_tz(x: t.Optional[datetime]) -> t.Optional[datetime]:
Expand Down Expand Up @@ -181,4 +183,9 @@ def _filter_response_for_errors_response(response: httpx.Response) -> httpx.Resp
if 200 <= response.status_code <= 299:
return response
else:
raise HttpError.init_exception(response.json(), response.status_code)
if response.status_code == 422:
raise HTTPValidationError.init_exception(
response.json(), response.status_code
)
else:
raise HttpError.init_exception(response.json(), response.status_code)
Empty file.
File renamed without changes.
79 changes: 79 additions & 0 deletions python/svix/api/errors/http_validation_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# TODO - remove this special case when we fix the generated code for empty openapi structs
from typing import Any, Dict, List, Type, TypeVar

import attr


from .validation_error import ValidationError


T = TypeVar("T", bound="HTTPValidationError")


@attr.s(auto_attribs=True)
class HTTPValidationError(Exception):
"""
Attributes:
detail (List['ValidationError']):
"""

detail: List[ValidationError]
additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

status_code: int = 0

@classmethod
def init_exception(cls: Type[T], response: Dict[str, str], status_code: int) -> T:
ret = cls.from_dict(response)
ret.status_code = status_code
return ret

def to_dict(self) -> Dict[str, Any]:
detail = []
for detail_item_data in self.detail:
detail_item = detail_item_data.to_dict()

detail.append(detail_item)

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update(
{
"detail": detail,
}
)

return field_dict

@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
d = src_dict.copy()
detail = []
_detail = d.pop("detail", "")
for detail_item_data in _detail:
detail_item = ValidationError.from_dict(detail_item_data)

detail.append(detail_item)

http_validation_error = cls(
detail=detail,
)

http_validation_error.additional_properties = d
return http_validation_error

@property
def additional_keys(self) -> List[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]

def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value

def __delitem__(self, key: str) -> None:
del self.additional_properties[key]

def __contains__(self, key: str) -> bool:
return key in self.additional_properties
85 changes: 85 additions & 0 deletions python/svix/api/errors/validation_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# TODO - remove this special case when we fix the generated code for empty openapi structs
from typing import Any, Dict, List, Type, TypeVar, cast

import attr

T = TypeVar("T", bound="ValidationError")


@attr.s(auto_attribs=True)
class ValidationError(Exception):
"""Validation errors have their own schema to provide context for invalid requests eg. mismatched types and out of
bounds values. There may be any number of these per 422 UNPROCESSABLE ENTITY error.

Attributes:
loc (List[str]): The location as a [`Vec`] of [`String`]s -- often in the form `["body", "field_name"]`,
`["query", "field_name"]`, etc. They may, however, be arbitrarily deep.
msg (str): The message accompanying the validation error item.
type (str): The type of error, often "type_error" or "value_error", but sometimes with more context like as
"value_error.number.not_ge"
"""

loc: List[str]
msg: str
type: str
additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)

status_code: int = 0

@classmethod
def init_exception(cls: Type[T], response: Dict[str, str], status_code: int) -> T:
ret = cls.from_dict(response)
ret.status_code = status_code
return ret

def to_dict(self) -> Dict[str, Any]:
loc = self.loc

msg = self.msg
type = self.type

field_dict: Dict[str, Any] = {}
field_dict.update(self.additional_properties)
field_dict.update(
{
"loc": loc,
"msg": msg,
"type": type,
}
)

return field_dict

@classmethod
def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
d = src_dict.copy()
loc = cast(List[str], d.pop("loc", []))

msg = d.pop("msg", "")

type = d.pop("type", "")

validation_error = cls(
loc=loc,
msg=msg,
type=type,
)

validation_error.additional_properties = d
return validation_error

@property
def additional_keys(self) -> List[str]:
return list(self.additional_properties.keys())

def __getitem__(self, key: str) -> Any:
return self.additional_properties[key]

def __setitem__(self, key: str, value: Any) -> None:
self.additional_properties[key] = value

def __delitem__(self, key: str) -> None:
del self.additional_properties[key]

def __contains__(self, key: str) -> bool:
return key in self.additional_properties
9 changes: 4 additions & 5 deletions python/svix/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from .api.http_error import HttpError
from .api.errors.http_error import HttpError
from .api.errors.http_validation_error import HTTPValidationError
from .webhooks import WebhookVerificationError

__all__ = [
"HttpError",
"WebhookVerificationError",
]

__all__ = ["HttpError", "WebhookVerificationError", "HTTPValidationError"]
1 change: 0 additions & 1 deletion python/tests/test_webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,4 @@ def test_sign_function():

wh = Webhook(key)
signature = wh.sign(msg_id=msg_id, timestamp=timestamp, data=payload)
print(signature)
assert signature == expected