Skip to content

Commit

Permalink
PORTAL-869: Add phone numbers endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
kanemathers committed Mar 26, 2020
1 parent 8c02485 commit 14e747f
Show file tree
Hide file tree
Showing 5 changed files with 345 additions and 5 deletions.
8 changes: 8 additions & 0 deletions telnyx/api_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
from telnyx.api_resources.number_order import NumberOrder
from telnyx.api_resources.number_order_phone_number import NumberOrderPhoneNumber
from telnyx.api_resources.number_reservation import NumberReservation
from telnyx.api_resources.phone_number import (
PhoneNumber,
MessagingSettings,
VoiceSettings,
)
from telnyx.api_resources.phone_number_regulatory_requirement import (
PhoneNumberRegulatoryRequirement,
)
Expand All @@ -44,11 +49,14 @@
"Message",
"MessagingPhoneNumber",
"MessagingProfile",
"MessagingSettings",
"NumberOrder",
"NumberOrderPhoneNumber",
"NumberReservation",
"PhoneNumber",
"PhoneNumberRegulatoryRequirement",
"PublicKey",
"RegulatoryRequirement",
"ShortCode",
"VoiceSettings",
]
18 changes: 13 additions & 5 deletions telnyx/api_resources/abstract/nested_resource_class_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
from telnyx.six.moves.urllib.parse import quote_plus


def nested_resource_class_methods(resource, path=None, operations=None):
def nested_resource_class_methods(
resource, path=None, operations=None, pluralize_path=True
):
def make_path(v):
if pluralize_path:
return "%ss" % v
else:
return v

if path is None:
path = "%ss" % resource
path = make_path(resource)
if operations is None:
raise ValueError("operations list required")

Expand All @@ -20,15 +28,15 @@ def nested_resource_url(cls, id, nested_id=None):
parts.append(quote_plus(nested_id, safe=util.telnyx_valid_id_parts))
return "/".join(parts)

resource_url_method = "%ss_url" % resource
resource_url_method = "%s_url" % make_path(resource)
setattr(cls, resource_url_method, classmethod(nested_resource_url))

def nested_resource_request(cls, method, url, api_key=None, **params):
requestor = api_requestor.APIRequestor(api_key)
response, api_key = requestor.request(method, url, params)
return util.convert_to_telnyx_object(response, api_key)

resource_request_method = "%ss_request" % resource
resource_request_method = "%s_request" % make_path(resource)
setattr(cls, resource_request_method, classmethod(nested_resource_request))

for operation in operations:
Expand Down Expand Up @@ -76,7 +84,7 @@ def list_nested_resources(cls, id, **params):
url = getattr(cls, resource_url_method)(id)
return getattr(cls, resource_request_method)("get", url, **params)

list_method = "list_%ss" % resource
list_method = "list_%s" % make_path(resource)
setattr(cls, list_method, classmethod(list_nested_resources))

else:
Expand Down
128 changes: 128 additions & 0 deletions telnyx/api_resources/phone_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from __future__ import absolute_import, division, print_function

from telnyx import six, util
from telnyx.six.moves.urllib.parse import quote_plus

from telnyx.api_resources.abstract import (
CreateableAPIResource,
DeletableAPIResource,
ListableAPIResource,
UpdateableAPIResource,
nested_resource_class_methods,
)


@nested_resource_class_methods("voice", operations=["list"], pluralize_path=False)
@nested_resource_class_methods("voice", operations=["update"], pluralize_path=False)
@nested_resource_class_methods(
"enable_emergency", path="actions/enable_emergency", operations=["create"]
)
@nested_resource_class_methods(
"messaging", path="messaging", operations=["list"], pluralize_path=False
)
@nested_resource_class_methods(
"messaging", path="messaging", operations=["update"], pluralize_path=False
)
class PhoneNumber(DeletableAPIResource, ListableAPIResource, UpdateableAPIResource):
OBJECT_NAME = "phone_number"

@classmethod
def all_voice(cls, **params):
""" Returns the voice settings for /all/ numbers owned by the user.
This method breaks the naming convention of helper methods by adding
an `all_` prefix, which might be confusing at first. The reason for
this prefix is the `voice()` method name is already taken. The
Telnyx API supports these two endpoints:
- /v2/phone_numbers/{id}/voice
- /v2/phone_numbers/voice
The `/{id}/voice` endpoint is taken by the instance method `voice()`.
As we can't nicely re-use this method for two different endpoints,
we have this `all_voice()` endpoint to support the `/voice` endpoint.
"""

return PhoneNumber.list_voice(None, **params)

def voice(self, **params):
""" Returns the voice settings for the instantiated phone number. """

return PhoneNumber.list_voice(self.id, **params)

def enable_emergency(self, **params):
return PhoneNumber.create_enable_emergency(self.id, **params)

@classmethod
def all_messaging(cls, **params):
""" Returns the messaging settings for /all/ numbers owned by the
user.
See the documentation for `all_voice()` for an explanation on the
difference between `all_messaging()` and `messaging()`.
"""

return PhoneNumber.list_messaging(None, **params)

def messaging(self, **params):
""" Returns the messaging settings for the instantiated phone
number.
"""

return PhoneNumber.list_messaging(self.id, **params)


class VoiceSettings(ListableAPIResource, UpdateableAPIResource):
OBJECT_NAME = "voice_settings"

@classmethod
def class_url(cls):
return "/v2/phone_numbers/voice"

def instance_url(self):
id = self.get("id")

if not isinstance(id, six.string_types):
raise error.InvalidRequestError(
"Could not determine which URL to request: %s instance "
"has invalid ID: %r, %s. ID should be of type `str` (or"
" `unicode`)" % (type(self).__name__, id, type(id)),
"id",
)

id = util.utf8(id)
extn = quote_plus(id)
return "/v2/phone_numbers/%s/voice" % extn

@classmethod
def modify(cls, sid, **params):
url = "/v2/phone_numbers/%s/voice" % quote_plus(util.utf8(sid))
return cls._modify(url, **params)


class MessagingSettings(ListableAPIResource, UpdateableAPIResource):
OBJECT_NAME = "messaging_settings"

@classmethod
def class_url(cls):
return "/v2/phone_numbers/messaging"

def instance_url(self):
id = self.get("id")

if not isinstance(id, six.string_types):
raise error.InvalidRequestError(
"Could not determine which URL to request: %s instance "
"has invalid ID: %r, %s. ID should be of type `str` (or"
" `unicode`)" % (type(self).__name__, id, type(id)),
"id",
)

id = util.utf8(id)
extn = quote_plus(id)
return "/v2/phone_numbers/%s/messaging" % extn

@classmethod
def modify(cls, sid, **params):
url = "/v2/phone_numbers/%s/messaging" % quote_plus(util.utf8(sid))
return cls._modify(url, **params)
3 changes: 3 additions & 0 deletions telnyx/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,16 @@ def load_object_classes():
api_resources.Message.OBJECT_NAME: api_resources.Message,
api_resources.MessagingPhoneNumber.OBJECT_NAME: api_resources.MessagingPhoneNumber,
api_resources.MessagingProfile.OBJECT_NAME: api_resources.MessagingProfile,
api_resources.MessagingSettings.OBJECT_NAME: api_resources.MessagingSettings,
api_resources.NumberOrder.OBJECT_NAME: api_resources.NumberOrder,
api_resources.NumberOrderPhoneNumber.OBJECT_NAME: api_resources.NumberOrderPhoneNumber,
api_resources.NumberReservation.OBJECT_NAME: api_resources.NumberReservation,
api_resources.PhoneNumber.OBJECT_NAME: api_resources.PhoneNumber,
api_resources.PhoneNumberRegulatoryRequirement.OBJECT_NAME: api_resources.PhoneNumberRegulatoryRequirement,
api_resources.PublicKey.OBJECT_NAME: api_resources.PublicKey,
api_resources.RegulatoryRequirement.OBJECT_NAME: api_resources.RegulatoryRequirement,
api_resources.ShortCode.OBJECT_NAME: api_resources.ShortCode,
api_resources.VoiceSettings.OBJECT_NAME: api_resources.VoiceSettings,
}


Expand Down
Loading

0 comments on commit 14e747f

Please sign in to comment.