Skip to content

Commit a73a50e

Browse files
smoghe-bwclaude
andcommitted
Align link and error schemas with BRTC spec
Add method (enum: GET/POST/DELETE) to link schema and id, type, source fields to error schema per the authoritative BRTC spec. Extract LinkMethodEnum to its own file to match codebase conventions. Generated from Claude9 with Claude Code Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1d1dded commit a73a50e

8 files changed

Lines changed: 125 additions & 54 deletions

File tree

bandwidth.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,6 +2320,13 @@ components:
23202320
type: string
23212321
href:
23222322
type: string
2323+
method:
2324+
type: string
2325+
enum:
2326+
- GET
2327+
- POST
2328+
- DELETE
2329+
description: The HTTP method to use when making the request.
23232330
errorObject:
23242331
type: object
23252332
properties:
@@ -6672,6 +6679,13 @@ components:
66726679
error:
66736680
type: object
66746681
properties:
6682+
id:
6683+
type: string
6684+
format: uuid
6685+
description: A unique identifier for the error.
6686+
type:
6687+
type: string
6688+
description: The type of error.
66756689
code:
66766690
type: integer
66776691
description:
@@ -6680,6 +6694,21 @@ components:
66806694
type: array
66816695
items:
66826696
$ref: '#/components/schemas/telephoneNumber'
6697+
source:
6698+
type: object
6699+
properties:
6700+
parameter:
6701+
type: string
6702+
description: The URI parameter that caused the error.
6703+
field:
6704+
type: string
6705+
description: The request body field that caused the error.
6706+
header:
6707+
type: string
6708+
description: The header that caused the error.
6709+
reference:
6710+
type: string
6711+
description: A reference to the source of the error.
66836712
telephoneNumber:
66846713
type: object
66856714
properties:

bandwidth/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
from bandwidth.models.latest_message_delivery_status_enum import LatestMessageDeliveryStatusEnum
9595
from bandwidth.models.line_type_enum import LineTypeEnum
9696
from bandwidth.models.link import Link
97+
from bandwidth.models.link_method_enum import LinkMethodEnum
9798
from bandwidth.models.link_schema import LinkSchema
9899
from bandwidth.models.links_object import LinksObject
99100
from bandwidth.models.list_endpoints_response import ListEndpointsResponse

bandwidth/models/error.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
2222
from typing import Any, ClassVar, Dict, List, Optional
23+
from bandwidth.models.error_source import ErrorSource
2324
from bandwidth.models.telephone_number import TelephoneNumber
2425
from typing import Optional, Set
2526
from typing_extensions import Self
@@ -28,11 +29,14 @@ class Error(BaseModel):
2829
"""
2930
Error
3031
""" # noqa: E501
32+
id: Optional[StrictStr] = Field(default=None, description="A unique identifier for the error.")
33+
type: Optional[StrictStr] = Field(default=None, description="The type of error.")
3134
code: Optional[StrictInt] = None
3235
description: Optional[StrictStr] = None
3336
telephone_numbers: Optional[List[TelephoneNumber]] = Field(default=None, alias="telephoneNumbers")
37+
source: Optional[ErrorSource] = None
3438
additional_properties: Dict[str, Any] = {}
35-
__properties: ClassVar[List[str]] = ["code", "description", "telephoneNumbers"]
39+
__properties: ClassVar[List[str]] = ["id", "type", "code", "description", "telephoneNumbers", "source"]
3640

3741
model_config = ConfigDict(
3842
populate_by_name=True,
@@ -82,6 +86,9 @@ def to_dict(self) -> Dict[str, Any]:
8286
if _item_telephone_numbers:
8387
_items.append(_item_telephone_numbers.to_dict())
8488
_dict['telephoneNumbers'] = _items
89+
# override the default output from pydantic by calling `to_dict()` of source
90+
if self.source:
91+
_dict['source'] = self.source.to_dict()
8592
# puts key-value pairs in additional_properties in the top level
8693
if self.additional_properties is not None:
8794
for _key, _value in self.additional_properties.items():
@@ -99,9 +106,12 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
99106
return cls.model_validate(obj)
100107

101108
_obj = cls.model_validate({
109+
"id": obj.get("id"),
110+
"type": obj.get("type"),
102111
"code": obj.get("code"),
103112
"description": obj.get("description"),
104-
"telephoneNumbers": [TelephoneNumber.from_dict(_item) for _item in obj["telephoneNumbers"]] if obj.get("telephoneNumbers") is not None else None
113+
"telephoneNumbers": [TelephoneNumber.from_dict(_item) for _item in obj["telephoneNumbers"]] if obj.get("telephoneNumbers") is not None else None,
114+
"source": ErrorSource.from_dict(obj["source"]) if obj.get("source") is not None else None
105115
})
106116
# store additional fields in additional_properties
107117
for _key in obj.keys():

bandwidth/models/link.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
import re # noqa: F401
1919
import json
2020

21-
from pydantic import BaseModel, ConfigDict, StrictStr
21+
from pydantic import BaseModel, ConfigDict, Field, StrictStr
2222
from typing import Any, ClassVar, Dict, List, Optional
23+
from bandwidth.models.link_method_enum import LinkMethodEnum
2324
from typing import Optional, Set
2425
from typing_extensions import Self
2526

@@ -29,8 +30,9 @@ class Link(BaseModel):
2930
""" # noqa: E501
3031
rel: Optional[StrictStr] = None
3132
href: Optional[StrictStr] = None
33+
method: Optional[LinkMethodEnum] = Field(default=None, description="The HTTP method to use when making the request.")
3234
additional_properties: Dict[str, Any] = {}
33-
__properties: ClassVar[List[str]] = ["rel", "href"]
35+
__properties: ClassVar[List[str]] = ["rel", "href", "method"]
3436

3537
model_config = ConfigDict(
3638
populate_by_name=True,
@@ -91,7 +93,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
9193

9294
_obj = cls.model_validate({
9395
"rel": obj.get("rel"),
94-
"href": obj.get("href")
96+
"href": obj.get("href"),
97+
"method": obj.get("method")
9598
})
9699
# store additional fields in additional_properties
97100
for _key in obj.keys():
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# coding: utf-8
2+
3+
"""
4+
Bandwidth
5+
6+
Bandwidth's Communication APIs
7+
8+
The version of the OpenAPI document: 1.0.0
9+
Contact: letstalk@bandwidth.com
10+
Generated by OpenAPI Generator (https://openapi-generator.tech)
11+
12+
Do not edit the class manually.
13+
""" # noqa: E501
14+
15+
16+
from __future__ import annotations
17+
import json
18+
from enum import Enum
19+
from typing_extensions import Self
20+
21+
22+
class LinkMethodEnum(str, Enum):
23+
"""
24+
The HTTP method to use when making the request.
25+
"""
26+
27+
"""
28+
allowed enum values
29+
"""
30+
GET = 'GET'
31+
POST = 'POST'
32+
DELETE = 'DELETE'
33+
34+
@classmethod
35+
def from_json(cls, json_str: str) -> Self:
36+
"""Create an instance of LinkMethodEnum from a JSON string"""
37+
return cls(json.loads(json_str))
38+

test/unit/models/test_error.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import unittest
1717

1818
from bandwidth.models.error import Error
19+
from bandwidth.models.error_source import ErrorSource
1920
from bandwidth.models.telephone_number import TelephoneNumber
2021

2122
class TestError(unittest.TestCase):
@@ -27,35 +28,36 @@ def setUp(self):
2728
def tearDown(self):
2829
pass
2930

30-
def make_instance(self, include_optional) -> Error:
31-
"""Test Error
32-
include_optional is a boolean, when False only required
33-
params are included, when True both required and
34-
optional params are included """
35-
if include_optional:
36-
return Error(
37-
code = 56,
38-
description = '',
39-
telephone_numbers = [
40-
TelephoneNumber(
41-
telephone_number = '', )
42-
]
31+
def make_instance(self) -> Error:
32+
"""Test Error"""
33+
return Error(
34+
id = '59512d87-7a92-4040-8e4a-78fb772019b9',
35+
type = 'resource.not_found',
36+
code = 404,
37+
description = 'The requested resource was not found.',
38+
telephone_numbers = [
39+
TelephoneNumber(
40+
telephone_number = '+15551234567', )
41+
],
42+
source = ErrorSource(
43+
parameter = 'accountId',
4344
)
44-
else:
45-
return Error(
4645
)
4746

4847
def testError(self):
4948
"""Test Error"""
50-
instance = self.make_instance(True)
49+
instance = self.make_instance()
5150
assert instance is not None
5251
assert isinstance(instance, Error)
53-
assert instance.code == 56
54-
assert instance.description == ''
52+
assert instance.id == '59512d87-7a92-4040-8e4a-78fb772019b9'
53+
assert instance.type == 'resource.not_found'
54+
assert instance.code == 404
55+
assert instance.description == 'The requested resource was not found.'
5556
assert isinstance(instance.telephone_numbers, list)
5657
assert len(instance.telephone_numbers) == 1
5758
assert isinstance(instance.telephone_numbers[0], TelephoneNumber)
58-
assert instance.telephone_numbers[0].telephone_number == ''
59+
assert instance.source is not None
60+
assert instance.source.parameter == 'accountId'
5961

6062
if __name__ == '__main__':
6163
unittest.main()

test/unit/models/test_error_source.py

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,18 @@ def setUp(self):
2626
def tearDown(self):
2727
pass
2828

29-
def make_instance(self, include_optional) -> ErrorSource:
30-
"""Test ErrorSource
31-
include_optional is a boolean, when False only required
32-
params are included, when True both required and
33-
optional params are included """
34-
if include_optional:
35-
return ErrorSource(
36-
parameter = 'parameter',
37-
var_field = 'var_field',
38-
header = 'header',
39-
reference = 'reference'
40-
)
41-
else:
42-
return ErrorSource(
29+
def make_instance(self) -> ErrorSource:
30+
"""Test ErrorSource"""
31+
return ErrorSource(
32+
parameter = 'parameter',
33+
var_field = 'var_field',
34+
header = 'header',
35+
reference = 'reference'
4336
)
4437

4538
def testErrorSource(self):
4639
"""Test ErrorSource"""
47-
instance = self.make_instance(True)
40+
instance = self.make_instance()
4841
assert instance is not None
4942
assert isinstance(instance, ErrorSource)
5043
assert instance.parameter == 'parameter'

test/unit/models/test_link.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,22 @@ def setUp(self):
2626
def tearDown(self):
2727
pass
2828

29-
def make_instance(self, include_optional) -> Link:
30-
"""Test Link
31-
include_optional is a boolean, when False only required
32-
params are included, when True both required and
33-
optional params are included """
34-
if include_optional:
35-
return Link(
36-
rel = 'rel',
37-
href = 'href'
38-
)
39-
else:
40-
return Link(
29+
def make_instance(self) -> Link:
30+
"""Test Link"""
31+
return Link(
32+
rel = 'self',
33+
href = 'https://api.bandwidth.com/v2/accounts/123/endpoints',
34+
method = 'GET'
4135
)
4236

4337
def testLink(self):
4438
"""Test Link"""
45-
instance = self.make_instance(True)
39+
instance = self.make_instance()
4640
assert instance is not None
4741
assert isinstance(instance, Link)
48-
assert instance.rel == 'rel'
49-
assert instance.href == 'href'
42+
assert instance.rel == 'self'
43+
assert instance.href == 'https://api.bandwidth.com/v2/accounts/123/endpoints'
44+
assert instance.method == 'GET'
5045

5146
if __name__ == '__main__':
5247
unittest.main()

0 commit comments

Comments
 (0)