Skip to content

Commit f1ebeb1

Browse files
authored
Merge branch 'main' into brtc-python-sdk
2 parents 4949e43 + 8e35fd3 commit f1ebeb1

26 files changed

+975
-128
lines changed

bandwidth.yml

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,13 @@ paths:
164164
/users/{accountId}/messages:
165165
get:
166166
summary: List Messages
167-
description: Returns a list of messages based on query parameters.
167+
description: >
168+
Returns a list of messages based on query parameters.
169+
170+
171+
**Rate Limit:** This endpoint is rate limited to 3500 requests per 5
172+
minutes per Source IP address. Exceeding the limit returns HTTP 429 with
173+
a `Retry-After` header.
168174
operationId: listMessages
169175
tags:
170176
- Messages
@@ -208,10 +214,12 @@ paths:
208214
$ref: '#/components/responses/messagingForbiddenError'
209215
'404':
210216
$ref: '#/components/responses/messagingNotFoundError'
217+
'405':
218+
$ref: '#/components/responses/messagingMethodNotAllowedError'
211219
'415':
212220
$ref: '#/components/responses/messagingInvalidMediaTypeError'
213221
'429':
214-
$ref: '#/components/responses/messagingTooManyRequestsError'
222+
$ref: '#/components/responses/listMessagesTooManyRequestsError'
215223
'500':
216224
$ref: '#/components/responses/messagingInternalServerError'
217225
post:
@@ -2417,7 +2425,9 @@ components:
24172425
type: object
24182426
properties:
24192427
media:
2420-
$ref: '#/components/schemas/rbmMessageContentFile'
2428+
type: array
2429+
items:
2430+
$ref: '#/components/schemas/rbmMessageContentFile'
24212431
suggestions:
24222432
$ref: '#/components/schemas/multiChannelFullActions'
24232433
required:
@@ -6035,15 +6045,13 @@ components:
60356045
type: object
60366046
internalTicketNumber:
60376047
type: string
6038-
format: uuid
60396048
description: >-
60406049
Unique identifier (UUID) generated by Bandwidth to assist in tracking
60416050
the verification status of a toll-free number - included in all webhook
60426051
payloads.
60436052
example: acde070d-8c4c-4f0d-9d8a-162843c10333
60446053
internalTicketNumberForWebhook:
60456054
type: string
6046-
format: uuid
60476055
description: >-
60486056
Unique identifier (UUID) generated by Bandwidth to assist in tracking
60496057
the verification status of a toll-free number.
@@ -7209,6 +7217,23 @@ components:
72097217
- type: internal-server-error
72107218
description: Internal server error. No further information available
72117219
source: {}
7220+
listMessagesTooManyRequestsError:
7221+
description: Too Many Requests
7222+
headers:
7223+
Retry-After:
7224+
description: The number of seconds to wait before retrying the request.
7225+
schema:
7226+
type: integer
7227+
example: 300
7228+
content:
7229+
application/json:
7230+
schema:
7231+
$ref: '#/components/schemas/messagingRequestError'
7232+
example:
7233+
type: rate_limit_exceeded
7234+
description: >-
7235+
Rate limit exceeded. Wait for Retry-After time before sending
7236+
another request.
72127237
createCallResponse:
72137238
description: Created
72147239
headers:

bandwidth/api/messages_api.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ def list_messages(
412412
) -> MessagesList:
413413
"""List Messages
414414
415-
Returns a list of messages based on query parameters.
415+
Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
416416
417417
:param account_id: Your Bandwidth Account ID. (required)
418418
:type account_id: str
@@ -533,6 +533,7 @@ def list_messages(
533533
'401': "MessagingRequestError",
534534
'403': "MessagingRequestError",
535535
'404': "MessagingRequestError",
536+
'405': "MessagingRequestError",
536537
'415': "MessagingRequestError",
537538
'429': "MessagingRequestError",
538539
'500': "MessagingRequestError",
@@ -594,7 +595,7 @@ def list_messages_with_http_info(
594595
) -> ApiResponse[MessagesList]:
595596
"""List Messages
596597
597-
Returns a list of messages based on query parameters.
598+
Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
598599
599600
:param account_id: Your Bandwidth Account ID. (required)
600601
:type account_id: str
@@ -715,6 +716,7 @@ def list_messages_with_http_info(
715716
'401': "MessagingRequestError",
716717
'403': "MessagingRequestError",
717718
'404': "MessagingRequestError",
719+
'405': "MessagingRequestError",
718720
'415': "MessagingRequestError",
719721
'429': "MessagingRequestError",
720722
'500': "MessagingRequestError",
@@ -776,7 +778,7 @@ def list_messages_without_preload_content(
776778
) -> RESTResponseType:
777779
"""List Messages
778780
779-
Returns a list of messages based on query parameters.
781+
Returns a list of messages based on query parameters. **Rate Limit:** This endpoint is rate limited to 3500 requests per 5 minutes per Source IP address. Exceeding the limit returns HTTP 429 with a `Retry-After` header.
780782
781783
:param account_id: Your Bandwidth Account ID. (required)
782784
:type account_id: str
@@ -897,6 +899,7 @@ def list_messages_without_preload_content(
897899
'401': "MessagingRequestError",
898900
'403': "MessagingRequestError",
899901
'404': "MessagingRequestError",
902+
'405': "MessagingRequestError",
900903
'415': "MessagingRequestError",
901904
'429': "MessagingRequestError",
902905
'500': "MessagingRequestError",

bandwidth/models/blocked_webhook.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator
2222
from typing import Any, ClassVar, Dict, List, Optional
2323
from typing_extensions import Annotated
24-
from uuid import UUID
2524
from bandwidth.models.tfv_callback_status_enum import TfvCallbackStatusEnum
2625
from typing import Optional, Set
2726
from typing_extensions import Self
@@ -33,7 +32,7 @@ class BlockedWebhook(BaseModel):
3332
account_id: Optional[StrictStr] = Field(default=None, description="User's account ID.", alias="accountId")
3433
phone_number: Optional[Annotated[str, Field(min_length=12, strict=True, max_length=12)]] = Field(default=None, description="Toll-free telephone number in E.164 format.", alias="phoneNumber")
3534
status: Optional[TfvCallbackStatusEnum] = None
36-
internal_ticket_number: Optional[UUID] = Field(default=None, description="Unique identifier (UUID) generated by Bandwidth to assist in tracking the verification status of a toll-free number.", alias="internalTicketNumber")
35+
internal_ticket_number: Optional[StrictStr] = Field(default=None, description="Unique identifier (UUID) generated by Bandwidth to assist in tracking the verification status of a toll-free number.", alias="internalTicketNumber")
3736
blocked: Optional[StrictBool] = Field(default=None, description="Whether a Toll-Free Verification is blocked. This attribute will only be defined when the number is blocked.")
3837
blocked_reason: Optional[StrictStr] = Field(default=None, description="The reason why the Toll-Free Verification is blocked. This attribute will only be defined when the number is blocked.", alias="blockedReason")
3938
additional_properties: Dict[str, Any] = {}

bandwidth/models/callback.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,18 @@ class Callback(BaseModel):
4242
protected_namespaces=(),
4343
)
4444

45-
46-
discriminator_value_class_map: Dict[str, str] = {
45+
# Discriminator's property name (OpenAPI v3)
46+
__openapi_discriminator_name__ = 'type'
47+
48+
# Discriminator's mapping (OpenAPI v3)
49+
__discriminator_value_class_map__ = {
50+
'message-delivered': 'StatusCallback',
51+
'message-failed': 'StatusCallback',
52+
'message-read': 'StatusCallback',
53+
'message-received': 'InboundCallback',
54+
'message-sent': 'StatusCallback',
55+
'request-location-response': 'InboundCallback',
56+
'suggestion-response': 'InboundCallback'
4757
}
4858

4959
def __init__(self, *args, **kwargs) -> None:
@@ -88,6 +98,20 @@ def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self:
8898
def from_json(cls, json_str: str) -> Self:
8999
"""Returns the object represented by the json string"""
90100
instance = cls.model_construct()
101+
102+
# Try to deserialize using the discriminator
103+
json_obj = json.loads(json_str)
104+
discriminator_value = json_obj.get(cls.__openapi_discriminator_name__)
105+
106+
if discriminator_value and discriminator_value in cls.__discriminator_value_class_map__:
107+
class_name = cls.__discriminator_value_class_map__[discriminator_value]
108+
target_class = globals()[class_name]
109+
try:
110+
instance.actual_instance = target_class.from_json(json_str)
111+
return instance
112+
except (ValidationError, ValueError) as e:
113+
raise ValueError(f"Failed to deserialize using discriminator '{discriminator_value}' -> {class_name}: {str(e)}")
114+
91115
error_messages = []
92116
match = 0
93117

bandwidth/models/failure_webhook.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator
2222
from typing import Any, ClassVar, Dict, List, Optional
2323
from typing_extensions import Annotated
24-
from uuid import UUID
2524
from typing import Optional, Set
2625
from typing_extensions import Self
2726

@@ -34,7 +33,7 @@ class FailureWebhook(BaseModel):
3433
error_code: Optional[StrictStr] = Field(default=None, description="An error code indicating what error was encountered. This code can be interpreted as an HTTP status code in regards to the error that was encountered.", alias="errorCode")
3534
error_message: Optional[StrictStr] = Field(default=None, description="A description of the error that was encountered.", alias="errorMessage")
3635
errors: Optional[List[StrictStr]] = Field(default=None, description="Details of the errors that were encountered when processing the request.")
37-
internal_ticket_number: Optional[UUID] = Field(default=None, description="Unique identifier (UUID) generated by Bandwidth to assist in tracking the verification status of a toll-free number.", alias="internalTicketNumber")
36+
internal_ticket_number: Optional[StrictStr] = Field(default=None, description="Unique identifier (UUID) generated by Bandwidth to assist in tracking the verification status of a toll-free number.", alias="internalTicketNumber")
3837
additional_properties: Dict[str, Any] = {}
3938
__properties: ClassVar[List[str]] = ["accountId", "phoneNumber", "errorCode", "errorMessage", "errors", "internalTicketNumber"]
4039

bandwidth/models/multi_channel_action.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,17 @@ class MultiChannelAction(BaseModel):
5757
"protected_namespaces": (),
5858
}
5959

60-
discriminator_value_class_map: Dict[str, str] = {
60+
# Discriminator's property name (OpenAPI v3)
61+
__openapi_discriminator_name__ = 'type'
62+
63+
# Discriminator's mapping (OpenAPI v3)
64+
__discriminator_value_class_map__ = {
65+
'CREATE_CALENDAR_EVENT': 'MultiChannelActionCalendarEvent',
66+
'DIAL_PHONE': 'RbmActionDial',
67+
'OPEN_URL': 'RbmActionOpenUrl',
68+
'REPLY': 'RbmActionBase',
69+
'REQUEST_LOCATION': 'RbmActionBase',
70+
'SHOW_LOCATION': 'RbmActionViewLocation'
6171
}
6272

6373
def __init__(self, *args, **kwargs) -> None:
@@ -118,6 +128,20 @@ def from_dict(cls, obj: Dict[str, Any]) -> Self:
118128
def from_json(cls, json_str: str) -> Self:
119129
"""Returns the object represented by the json string"""
120130
instance = cls.model_construct()
131+
132+
# Try to deserialize using the discriminator
133+
json_obj = json.loads(json_str)
134+
discriminator_value = json_obj.get(cls.__openapi_discriminator_name__)
135+
136+
if discriminator_value and discriminator_value in cls.__discriminator_value_class_map__:
137+
class_name = cls.__discriminator_value_class_map__[discriminator_value]
138+
target_class = globals()[class_name]
139+
try:
140+
instance.actual_instance = target_class.from_json(json_str)
141+
return instance
142+
except (ValidationError, ValueError) as e:
143+
raise ValueError(f"Failed to deserialize using discriminator '{discriminator_value}' -> {class_name}: {str(e)}")
144+
121145
error_messages = []
122146
# anyof_schema_1_validator: Optional[RbmActionBase] = None
123147
try:

bandwidth/models/multi_channel_channel_list_request_object.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ class MultiChannelChannelListRequestObject(BaseModel):
5151
"protected_namespaces": (),
5252
}
5353

54-
discriminator_value_class_map: Dict[str, str] = {
54+
# Discriminator's property name (OpenAPI v3)
55+
__openapi_discriminator_name__ = 'channel'
56+
57+
# Discriminator's mapping (OpenAPI v3)
58+
__discriminator_value_class_map__ = {
59+
'MMS': 'MultiChannelChannelListMMSObject',
60+
'RBM': 'MultiChannelChannelListRBMObject',
61+
'SMS': 'MultiChannelChannelListSMSObject'
5562
}
5663

5764
def __init__(self, *args, **kwargs) -> None:
@@ -100,6 +107,20 @@ def from_dict(cls, obj: Dict[str, Any]) -> Self:
100107
def from_json(cls, json_str: str) -> Self:
101108
"""Returns the object represented by the json string"""
102109
instance = cls.model_construct()
110+
111+
# Try to deserialize using the discriminator
112+
json_obj = json.loads(json_str)
113+
discriminator_value = json_obj.get(cls.__openapi_discriminator_name__)
114+
115+
if discriminator_value and discriminator_value in cls.__discriminator_value_class_map__:
116+
class_name = cls.__discriminator_value_class_map__[discriminator_value]
117+
target_class = globals()[class_name]
118+
try:
119+
instance.actual_instance = target_class.from_json(json_str)
120+
return instance
121+
except (ValidationError, ValueError) as e:
122+
raise ValueError(f"Failed to deserialize using discriminator '{discriminator_value}' -> {class_name}: {str(e)}")
123+
103124
error_messages = []
104125
# anyof_schema_1_validator: Optional[MultiChannelChannelListRBMObject] = None
105126
try:

bandwidth/models/multi_channel_channel_list_response_object.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ class MultiChannelChannelListResponseObject(BaseModel):
5151
"protected_namespaces": (),
5252
}
5353

54-
discriminator_value_class_map: Dict[str, str] = {
54+
# Discriminator's property name (OpenAPI v3)
55+
__openapi_discriminator_name__ = 'channel'
56+
57+
# Discriminator's mapping (OpenAPI v3)
58+
__discriminator_value_class_map__ = {
59+
'MMS': 'MultiChannelChannelListMMSResponseObject',
60+
'RBM': 'MultiChannelChannelListRBMResponseObject',
61+
'SMS': 'MultiChannelChannelListSMSResponseObject'
5562
}
5663

5764
def __init__(self, *args, **kwargs) -> None:
@@ -100,6 +107,20 @@ def from_dict(cls, obj: Dict[str, Any]) -> Self:
100107
def from_json(cls, json_str: str) -> Self:
101108
"""Returns the object represented by the json string"""
102109
instance = cls.model_construct()
110+
111+
# Try to deserialize using the discriminator
112+
json_obj = json.loads(json_str)
113+
discriminator_value = json_obj.get(cls.__openapi_discriminator_name__)
114+
115+
if discriminator_value and discriminator_value in cls.__discriminator_value_class_map__:
116+
class_name = cls.__discriminator_value_class_map__[discriminator_value]
117+
target_class = globals()[class_name]
118+
try:
119+
instance.actual_instance = target_class.from_json(json_str)
120+
return instance
121+
except (ValidationError, ValueError) as e:
122+
raise ValueError(f"Failed to deserialize using discriminator '{discriminator_value}' -> {class_name}: {str(e)}")
123+
103124
error_messages = []
104125
# anyof_schema_1_validator: Optional[MultiChannelChannelListRBMResponseObject] = None
105126
try:

bandwidth/models/rbm_message_media.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class RbmMessageMedia(BaseModel):
3030
"""
3131
RbmMessageMedia
3232
""" # noqa: E501
33-
media: RbmMessageContentFile
33+
media: List[RbmMessageContentFile]
3434
suggestions: Optional[Annotated[List[MultiChannelAction], Field(max_length=11)]] = Field(default=None, description="An array of suggested actions for the recipient.")
3535
additional_properties: Dict[str, Any] = {}
3636
__properties: ClassVar[List[str]] = ["media", "suggestions"]
@@ -76,9 +76,13 @@ def to_dict(self) -> Dict[str, Any]:
7676
exclude=excluded_fields,
7777
exclude_none=True,
7878
)
79-
# override the default output from pydantic by calling `to_dict()` of media
79+
# override the default output from pydantic by calling `to_dict()` of each item in media (list)
80+
_items = []
8081
if self.media:
81-
_dict['media'] = self.media.to_dict()
82+
for _item_media in self.media:
83+
if _item_media:
84+
_items.append(_item_media.to_dict())
85+
_dict['media'] = _items
8286
# override the default output from pydantic by calling `to_dict()` of each item in suggestions (list)
8387
_items = []
8488
if self.suggestions:
@@ -103,7 +107,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
103107
return cls.model_validate(obj)
104108

105109
_obj = cls.model_validate({
106-
"media": RbmMessageContentFile.from_dict(obj["media"]) if obj.get("media") is not None else None,
110+
"media": [RbmMessageContentFile.from_dict(_item) for _item in obj["media"]] if obj.get("media") is not None else None,
107111
"suggestions": [MultiChannelAction.from_dict(_item) for _item in obj["suggestions"]] if obj.get("suggestions") is not None else None
108112
})
109113
# store additional fields in additional_properties

bandwidth/models/tfv_status.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator
2323
from typing import Any, ClassVar, Dict, List, Optional
2424
from typing_extensions import Annotated
25-
from uuid import UUID
2625
from bandwidth.models.tfv_status_enum import TfvStatusEnum
2726
from bandwidth.models.tfv_submission_info import TfvSubmissionInfo
2827
from typing import Optional, Set
@@ -34,7 +33,7 @@ class TfvStatus(BaseModel):
3433
""" # noqa: E501
3534
phone_number: Optional[Annotated[str, Field(min_length=12, strict=True, max_length=12)]] = Field(default=None, description="Toll-free telephone number in E.164 format.", alias="phoneNumber")
3635
status: Optional[TfvStatusEnum] = None
37-
internal_ticket_number: Optional[UUID] = Field(default=None, description="Unique identifier (UUID) generated by Bandwidth to assist in tracking the verification status of a toll-free number - included in all webhook payloads.", alias="internalTicketNumber")
36+
internal_ticket_number: Optional[StrictStr] = Field(default=None, description="Unique identifier (UUID) generated by Bandwidth to assist in tracking the verification status of a toll-free number - included in all webhook payloads.", alias="internalTicketNumber")
3837
decline_reason_description: Optional[StrictStr] = Field(default=None, description="Explanation for why a verification request was declined.", alias="declineReasonDescription")
3938
resubmit_allowed: Optional[StrictBool] = Field(default=None, description="Whether a Toll-Free Verification request qualifies for resubmission via PUT.", alias="resubmitAllowed")
4039
created_date_time: Optional[datetime] = Field(default=None, description="Date and time the verification request was created.", alias="createdDateTime")

0 commit comments

Comments
 (0)