diff --git a/cnam_demo.py b/cnam_demo.py new file mode 100644 index 0000000..583a5f9 --- /dev/null +++ b/cnam_demo.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +import pprint +import os +from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import FlowroutenumbersandmessagingClient + +# Set up your api credentials and test mobile number for outbound SMS or MMS +basic_auth_user_name = os.environ.get('FR_ACCESS_KEY') +basic_auth_password = os.environ.get('FR_SECRET_KEY') + +# Instantiate API client and create controllers for Numbers and E911s +client = FlowroutenumbersandmessagingClient(basic_auth_user_name, basic_auth_password) +numbers_controller = client.numbers +cnams_controller = client.cnams + + + +print("--List CNAM Records") +limit = 10 +offset = None +result = cnams_controller.list_cnams(limit, offset) +pprint.pprint(result) + + +print("\n--List Approved CNAM Records") +result = cnams_controller.list_cnams(limit, offset, is_approved=True) +pprint.pprint(result) +cnam_id = result['data'][0]['id'] + +print("\n--List CNAM Detail") +cnam_id = result['data'][0]['id'] +result = cnams_controller.get_cnam(cnam_id) +pprint.pprint(result) + +print("\n--Search for CNAM Record") +result = cnams_controller.search_cnams(contains='CHRIS') +pprint.pprint(result) + +# print("\n--Create a CNAM Record") +# result = cnams_controller.create_cnam_record('CJL') +# pprint.pprint(result) +# cnam_id = result['data']['id'] + +print("\n--Associate a CNAM Record to a DID") +result = cnams_controller.associate_cnam(cnam_id, '12066417659') +pprint.pprint(result) + +print("\n--Unassociate a CNAM Record from a DID") +result = cnams_controller.unassociate_cnam('12066417659') +pprint.pprint(result) + +print("\n--Remove a CNAM Record from your account") +result = cnams_controller.remove_cnam(cnam_id) +pprint.pprint(result) diff --git a/demo.py b/demo.py index d1e0778..4cb36ec 100755 --- a/demo.py +++ b/demo.py @@ -1,21 +1,23 @@ #!/usr/bin/env python import pprint -import os -import json import random import string -from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import FlowroutenumbersandmessagingClient +from flowroutenumbersandmessaging.configuration import Configuration +from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import \ + FlowroutenumbersandmessagingClient print("Number/Route Management v2 & Messaging v2.1 Demo") # Set up your api credentials and test mobile number for outbound SMS or MMS -basic_auth_user_name = os.environ.get('FR_ACCESS_KEY') -basic_auth_password = os.environ.get('FR_SECRET_KEY') -mobile_number = "YOUR_MOBILE_NUMBER" +# basic_auth_user_name = os.environ.get('FR_ACCESS_KEY') +# basic_auth_password = os.environ.get('FR_SECRET_KEY') +mobile_number = "4254664078" -# Instantiate API client and create controllers for Numbers, Messages, and Routes -client = FlowroutenumbersandmessagingClient(basic_auth_user_name, basic_auth_password) +# Instantiate API client and create controllers for Numbers, +# Messages, and Routes +client = FlowroutenumbersandmessagingClient(Configuration.basic_auth_user_name, + Configuration.basic_auth_password) numbers_controller = client.numbers routes_controller = client.routes messages_controller = client.messages @@ -24,7 +26,9 @@ print("--List Available Area Codes") max_setup_cost = 3.25 limit = 3 offset = None -result = numbers_controller.list_available_area_codes(limit, offset, max_setup_cost) +result = numbers_controller.list_available_area_codes(limit, + offset, + max_setup_cost) pprint.pprint(result) print("--List Available Exchange Codes") @@ -32,7 +36,10 @@ limit = 3 offset = None max_setup_cost = None areacode = 347 -result = numbers_controller.list_available_exchange_codes(limit, offset, max_setup_cost, areacode) +result = numbers_controller.list_available_exchange_codes(limit, + offset, + max_setup_cost, + areacode) pprint.pprint(result) print("--Search for Purchasable Phone Numbers") @@ -43,20 +50,28 @@ limit = 3 offset = None rate_center = None state = None -result = numbers_controller.search_for_purchasable_phone_numbers(starts_with, contains, ends_with, limit, offset, rate_center, state) +result = numbers_controller.search_for_purchasable_phone_numbers(starts_with, + contains, + ends_with, + limit, + offset, + rate_center, + state) pprint.pprint(result) -print("--Purchase a Phone Number") -purchasable_number = result['data'][0]['id'] -#result = numbers_controller.purchase_a_phone_number(purchasable_number) +if len(result['data']): + print("--Purchase a Phone Number") + purchasable_number = result['data'][0]['id'] + # result = numbers_controller.purchase_a_phone_number(purchasable_number) print("--List Account Phone Numbers") -starts_with = 201 +starts_with = None ends_with = None contains = None limit = 3 offset = None -result = numbers_controller.list_account_phone_numbers(starts_with, ends_with, contains, limit, offset) +result = numbers_controller.list_account_phone_numbers(starts_with, ends_with, + contains, limit, offset) pprint.pprint(result) @@ -66,10 +81,18 @@ result = numbers_controller.list_phone_number_details(number_id) pprint.pprint(result) print("---Create an Inbound Route") + +print("---First list all available edge strategies") +# result = routes_controller.list_edge_strategies() +# pprint.pprint(result) + + # Function to generate six-charac random string def id_generator(size=6, chars=string.ascii_lowercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) -new_route = id_generator() + '.sonsofodin.com' + + +new_route = '{}.sonsofodin.com'.format(id_generator()) alias = id_generator() for i in range(10): alias += str(i) @@ -78,8 +101,9 @@ request_body = '{ \ "type": "route", \ "attributes": { \ "route_type": "host", \ - "value": "' + new_route +'", \ - "alias": "' + alias + '" \ + "value": "' + new_route + '", \ + "alias": "' + alias + '", \ + "edge_strategy": "1" \ } \ } \ }' @@ -97,7 +121,7 @@ secrouteid = result['data'][2]['id'] request_body = '{ \ "data": { \ "type": "route", \ - "id": "' + str(prirouteid) +'" \ + "id": "' + str(prirouteid) + '" \ } \ }' @@ -111,7 +135,7 @@ else: request_body = '{ \ "data": { \ "type": "route", \ - "id": "' + str(secrouteid) +'" \ + "id": "' + str(secrouteid) + '" \ } \ }' @@ -122,7 +146,21 @@ if result is None: else: print (result) +body_with_space = "hello there{}how are you?".format(chr(160)) + request_body = '{ \ + "data": { \ + "type": "message", \ + "attributes": { \ + "to": "' + str(mobile_number) + '", \ + "from": "' + str(number_id) + '", \ + "body": "' + unicode(body_with_space, "utf-8") + '", \ + "is_mms": "false" \ + } \ + } \ +}' + +request_body_mms = '{ \ "data": { \ "type": "message", \ "attributes": { \ @@ -136,19 +174,19 @@ request_body = '{ \ }' print("---Send A Message") -#result = messages_controller.send_a_message(request_body) -#pprint.pprint(result) +result = messages_controller.send_a_message(request_body) +pprint.pprint(result) print("---Look Up A Set Of Messages") start_date = "2017-12-01" end_date = "2018-01-08" limit = 2 -result = messages_controller.look_up_a_set_of_messages(start_date, end_date, limit) +result = messages_controller.look_up_a_set_of_messages(start_date, + end_date, + limit) pprint.pprint(result) print ("---Look Up A Message Detail Record") message_id = result['data'][0]['id'] result = messages_controller.look_up_a_message_detail_record(message_id) pprint.pprint(result) - - diff --git a/e911_demo.py b/e911_demo.py new file mode 100644 index 0000000..85a92ba --- /dev/null +++ b/e911_demo.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +import pprint +import os +from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import FlowroutenumbersandmessagingClient + +# Set up your api credentials and test mobile number for outbound SMS or MMS +basic_auth_user_name = os.environ.get('FR_ACCESS_KEY') +basic_auth_password = os.environ.get('FR_SECRET_KEY') + +# Instantiate API client and create controllers for Numbers and E911s +client = FlowroutenumbersandmessagingClient(basic_auth_user_name, basic_auth_password) +numbers_controller = client.numbers +e911s_controller = client.e911s + + +print("--List E911 Records") +limit = 10 +offset = None +result = e911s_controller.list_e911s(limit, offset) +pprint.pprint(result) + +print("--Validate an Address") +result = e911s_controller.validate_address( + label="Test Address", + first_name="Chris", + last_name="Smith", + street_name="3rd Ave", + street_number="1182", + city="Seattle", + state="WA", + country="USA", + zip="98101") +pprint.pprint(result) + +e911_id = None +# If the user has any E911 records, pull one up +for e in result['data']: + e911_id = e['id'] + break + +if e911_id: + print("--Get Details for a specific E911 Record") + result = e911s_controller.get_e911(e911_id) + pprint.pprint(result) + +print("--Create and Validate an Address") +result = e911s_controller.create_address( + label="E911 Test", + first_name="Chris", + last_name="Smith", + street_name="3rd Ave", + street_number="1218", + city="Seattle", + state="WA", + country="USA", + zip="98101") +pprint.pprint(result) + +# Pull the ID from the newly created record +record_id = result['data']['id'] + +print("--Update an E911 Address") +result = e911s_controller.update_address(record_id, last_name='Wiley') +pprint.pprint(result) + +# Get our DIDs +did_list = numbers_controller.list_account_phone_numbers() +did = did_list['data'][0]['attributes']['value'] + +# Get our E911s +e911_list = e911s_controller.list_e911s() +e911_id = e911_list['data'][0]['id'] + +# Associate them +print("--Associate an E911 Record and a DID") +result = e911s_controller.associate(e911_id, did) +pprint.pprint(result) + +print("--List all DIDs associated with an E911 Record") +result = e911s_controller.list_dids_for_e911(e911_id) +pprint.pprint(result) + +# Diss-Associate them +print("--Un-associate the address") +result = e911s_controller.disconnect(e911_id, did) +pprint.pprint(result) + +print("--Delete an E911 Address") +result = e911s_controller.delete_address(e911_id) +pprint.pprint(result) + diff --git a/flowroutenumbersandmessaging/configuration.py b/flowroutenumbersandmessaging/configuration.py index 407aa1e..0a02728 100644 --- a/flowroutenumbersandmessaging/configuration.py +++ b/flowroutenumbersandmessaging/configuration.py @@ -7,6 +7,7 @@ """ from .api_helper import APIHelper + class Configuration(object): """A class used for configuring the SDK by a user. @@ -25,9 +26,9 @@ class Configuration(object): # The username to use with basic authentication # TODO: Set an appropriate value - basic_auth_user_name = "TODO: Replace" + basic_auth_user_name = "22476860" # The password to use with basic authentication # TODO: Set an appropriate value - basic_auth_password = "TODO: Replace" + basic_auth_password = "FYzckHAgBdHm1QpKbe6jdMivOWFlnApf" diff --git a/flowroutenumbersandmessaging/controllers/cnams_controller.py b/flowroutenumbersandmessaging/controllers/cnams_controller.py new file mode 100644 index 0000000..4a5c88c --- /dev/null +++ b/flowroutenumbersandmessaging/controllers/cnams_controller.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +""" + flowroutenumbersandmessaging.controllers.cnams_controller + + This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). +""" + +from .base_controller import BaseController +from ..api_helper import APIHelper +from ..configuration import Configuration +from ..http.auth.basic_auth import BasicAuth +from ..exceptions.error_exception import ErrorException +from .numbers_controller import NumbersController + +class CNAMsController(BaseController): + + """A Controller to access Endpoints in the + flowroutenumbersandmessaging API.""" + + def list_cnams(self, + limit=None, + offset=None, + is_approved=None): + """Does a GET request to /v2/cnams. + + Returns a list of all cnams owned by the user. + + Args: + limit (int, optional): Limits the number of items to retrieve. A + maximum of 200 items can be retrieved. + offset (int, optional): Offsets the list of phone numbers by your + specified value. For example, if you have 4 phone numbers and + you entered 1 as your offset value, then only 3 of your phone + numbers will be displayed in the response. + is_approved if set to true or false, will only show matching records + + Returns: + mixed: Response from the API. A JSON object of E911 Records + that satisfy your search criteria. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/cnams' + _query_parameters = { + 'limit': limit, + 'offset': offset + } + if is_approved is not None: + _query_parameters['is_approved'] = is_approved + + _query_builder = APIHelper.append_url_with_query_parameters(_query_builder, + _query_parameters, Configuration.array_serialization) + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def get_cnam(self, cnam_id): + """Does a GET request to /v2/cnams/. + + Returns a record detail for the CNAM Record Id specified + + Args: + + Returns: + mixed: Response from the API. A JSON object of of an E911 record + that satisfy your search criteria. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/cnams/{}'.format(cnam_id) + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def search_cnams(self, limit=10, offset=0, starts_with=None, contains=None, ends_with=None): + """Does a GET request to /v2/cnams?. + + Searches for CNAM Records that match the criteria + + Args: + limit (int, optional): Limits the number of items to retrieve. A + maximum of 200 items can be retrieved. + offset (int, optional): Offsets the list of cnams by your + specified value. For example, if you have 4 cnam records and + you entered 1 as your offset value, then only 3 of your cnams + will be displayed in the response. + + Returns: + mixed: Response from the API. A JSON object of of an E911 record + that satisfy your search criteria. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/cnams' + _query_parameters = { + 'limit': limit, + 'offset': offset + } + if starts_with is not None: + _query_parameters['starts_with'] = starts_with + if contains is not None: + _query_parameters['contains'] = contains + if ends_with is not None: + _query_parameters['ends_with'] = ends_with + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def create_cnam_record(self, value): + """Does a POST request to /v2/cnams. + + Searches for CNAM Records that match the criteria + + Args: + value (string, required): The text string for the new CNAM record + + Returns: + mixed: Response from the API. A JSON object of of a CNAM record + with the new data + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + body = { + "value": value + } + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/cnams' + _query_url = APIHelper.clean_url(_query_builder) + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.post(_query_url, headers=_headers, + parameters=body) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def associate_cnam(self, cnam_id, phone_number): + # first, verify the number belongs to the user + did = NumbersController().list_account_phone_numbers(contains=phone_number) + + if did is None: + error_string = "Error, this phone number does not belong to you." + return error_string + + did = did['data'][0]['id'] + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/numbers/{}/relationships/cnam/{}'.format(did, cnam_id) + _query_url = APIHelper.clean_url(_query_builder) + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.patch(_query_url, headers=_headers) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def unassociate_cnam(self, phone_number): + # first, verify the number belongs to the user + did = NumbersController().list_account_phone_numbers(contains=phone_number) + + if did is None: + error_string = "Error, this phone number does not belong to you." + return error_string + + did = did['data'][0]['id'] + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/numbers/{}/relationships/cnam'.format(did) + _query_url = APIHelper.clean_url(_query_builder) + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.delete(_query_url, headers=_headers) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def remove_cnam(self, cnam_id): + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/cnams/{}'.format(cnam_id) + _query_url = APIHelper.clean_url(_query_builder) + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.delete(_query_url, headers=_headers) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) diff --git a/flowroutenumbersandmessaging/controllers/e911s_controller.py b/flowroutenumbersandmessaging/controllers/e911s_controller.py new file mode 100644 index 0000000..8106c63 --- /dev/null +++ b/flowroutenumbersandmessaging/controllers/e911s_controller.py @@ -0,0 +1,539 @@ +# -*- coding: utf-8 -*- + +""" + flowroutenumbersandmessaging.controllers.e911s_controller + + This file was automatically generated by APIMATIC v2.0 ( https://apimatic.io ). +""" + +from .base_controller import BaseController +from ..api_helper import APIHelper +from ..configuration import Configuration +from ..http.auth.basic_auth import BasicAuth +from ..exceptions.error_exception import ErrorException + + +class E911sController(BaseController): + + """A Controller to access Endpoints in the + flowroutenumbersandmessaging API.""" + + def list_e911s(self, + limit=None, + offset=None, + state=None): + """Does a GET request to /v2/e911s. + + Returns a list of all Central Office (exchange) codes containing + purchasable phone numbers. + + Args: + limit (int, optional): Limits the number of items to retrieve. A + maximum of 200 items can be retrieved. + offset (int, optional): Offsets the list of phone numbers by your + specified value. For example, if you have 4 phone numbers and + you entered 1 as your offset value, then only 3 of your phone + numbers will be displayed in the response. + state (2 char, optional): Restricts the results to the specified + state. + + Returns: + mixed: Response from the API. A JSON object of E911 Records + that satisfy your search criteria. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s' + _query_parameters = { + 'limit': limit, + 'offset': offset, + 'state': state + } + _query_builder = APIHelper.append_url_with_query_parameters(_query_builder, + _query_parameters, Configuration.array_serialization) + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def get_e911(self, e911_id): + """Does a GET request to /v2/e911s/. + + Returns a record detail for the E911 Record Id specified + + Args: + + Returns: + mixed: Response from the API. A JSON object of of an E911 record + that satisfy your search criteria. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s/{}'.format(e911_id) + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) + + def validate_address(self, + label, + first_name, + last_name, + street_name, + street_number, + city, + state, + country, + zip): + """Does a POST request to /v2/e911s/validate. + + Returns a 204 No Content on success, or a 404 with error data + + Args: + label (string): the alias or friendly name of your entry + first_name (string): + last_name (string): + street_name (string): + street_number (string): + city (string): + state (2 character string): + country (string USA or Canada): + zip (string postal code) + + Returns: + mixed: Response from the API. A 204 - No Content or a + JSON object ith error data + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + body = dict() + body['data'] = dict() + body['data']['type'] = 'e911' + body['data']['attributes'] = {} + body['data']['attributes']['label'] = label + body['data']['attributes']['first_name'] = first_name + body['data']['attributes']['last_name'] = last_name + body['data']['attributes']['street_name'] = street_name + body['data']['attributes']['street_number'] = street_number + body['data']['attributes']['city'] = city + body['data']['attributes']['state'] = state + body['data']['attributes']['country'] = country + body['data']['attributes']['zip'] = zip + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s/validate' + + # Return appropriate type + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.post(_query_url, headers=_headers, + parameters=APIHelper.json_serialize(body)) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + # Return appropriate type + return APIHelper.json_deserialize(_context.response.raw_body) + + def create_address(self, + label, + first_name, + last_name, + street_name, + street_number, + city, + state, + country, + zip): + """Does a POST request to /v2/e911s. + + Creates an address record that can then be associated with 1 or more DIDs + + Args: + label (string): the alias or friendly name of your entry + first_name (string): + last_name (string): + street_name (string): + street_number (string): + city (string): + state (2 character string): + country (string USA or Canada): + zip (string postal code) + + Returns: + mixed: Response from the API. A JSON object containing the new record information. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + body = dict() + body['data'] = dict() + body['data']['type'] = 'e911' + body['data']['attributes'] = {} + body['data']['attributes']['label'] = label + body['data']['attributes']['first_name'] = first_name + body['data']['attributes']['last_name'] = last_name + body['data']['attributes']['street_name'] = street_name + body['data']['attributes']['street_number'] = street_number + body['data']['attributes']['city'] = city + body['data']['attributes']['state'] = state + body['data']['attributes']['country'] = country + body['data']['attributes']['zip'] = zip + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s' + + # Return appropriate type + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.post(_query_url, headers=_headers, + parameters=APIHelper.json_serialize(body)) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + # Return appropriate type + return APIHelper.json_deserialize(_context.response.raw_body) + + def update_address(self, + e911_id, + label=None, + first_name=None, + last_name=None, + street_name=None, + street_number=None, + city=None, + state=None, + country=None, + zip=None): + + """Does a PATCH request to /v2/e911s/. + + Updates an existing address record and any associations it may have + + Args: + e911_id (integer, required): the id of the e911 record to update + label (string, optional): the alias or friendly name of your entry + first_name (string, optional): + last_name (string, optional): + street_name (string, optional): + street_number (string, optional): + city (string, optional): + state (2 character string, optional): + country (string USA or Canada, optional): + zip (string postal code, optional) + + Returns: + mixed: Response from the API. A JSON object containing the new record information. + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + cur_record = self.get_e911(e911_id) + record_data = cur_record + + record_data['data']['attributes']['zip_code'] = str(record_data['data']['attributes']['zip']) + record_data['data']['attributes']['house_number'] = str(record_data['data']['attributes']['street_number']) + + if label is not None: + record_data['data']['attributes']['label'] = label + if first_name is not None: + record_data['data']['attributes']['first_name'] = first_name + if last_name is not None: + record_data['data']['attributes']['last_name'] = last_name + if street_name is not None: + record_data['data']['attributes']['street_name'] = street_name + if street_number is not None: + record_data['data']['attributes']['street_number'] = str(street_number) + record_data['data']['attributes']['house_number'] = str(street_number) + if city is not None: + record_data['data']['attributes']['city'] = city + if state is not None: + record_data['data']['attributes']['state'] = state + if country is not None: + record_data['data']['attributes']['country'] = country + if zip is not None: + record_data['data']['attributes']['zip'] = str(zip) + record_data['data']['attributes']['zip_code'] = str(zip) + + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s/{}'.format(e911_id) + + # Return appropriate type + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.patch(_query_url, headers=_headers, + parameters=APIHelper.json_serialize(record_data)) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + # Return appropriate type + return APIHelper.json_deserialize(_context.response.raw_body) + + def delete_address(self, e911_id): + """Does a DELETE request to /v2/e911s/. + + Removes the existing address record and any associations it may have + + Args: + e911_id (integer, required): the id of the e911 record to update + + Returns: + mixed: Response from the API. A 204 - No Content or a + JSON object ith error data + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s/{}'.format(e911_id) + + # Return appropriate type + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.delete(_query_url, headers=_headers) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + # Return appropriate type + return APIHelper.json_deserialize(_context.response.raw_body) + + def associate(self, e911_id, did): + """Does a PATCH request to /v2/numbers//relationships/e911s/. + + Associates the specified e911 record with the specified did + + Args: + e911_id (integer, required): the id of the e911 record to update + did (string, required): the phone number to associate with + + Returns: + mixed: Response from the API. A 204 - No Content or a + JSON object ith error data + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/numbers/{}/relationships/e911s/{}'.format(did, e911_id) + + # Return appropriate type + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.patch(_query_url, headers=_headers) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + # Return appropriate type + return APIHelper.json_deserialize(_context.response.raw_body) + + def disconnect(self, e911_id, did): + """Does a DELETE request to /v2/numbers//relationships/e911s/. + + Un-Associates the specified e911 record with the specified did + + Args: + e911_id (integer, required): the id of the e911 record to update + did (string, required): the phone number to associate with + + Returns: + mixed: Response from the API. A 204 - No Content or a + JSON object ith error data + + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/numbers/{}/relationships/e911s/{}'.format(did, e911_id) + + # Return appropriate type + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare headers + _headers = { + 'accept': 'application/json' + } + + # Prepare and execute request + _request = self.http_client.delete(_query_url, headers=_headers) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + # Return appropriate type + return APIHelper.json_deserialize(_context.response.raw_body) + + def list_dids_for_e911(self, e911_id): + """Does a GET request to /v2/e911s//relationships/numbers + + Lists all Did records associated with the specified E911 record + + Args: + e911_id (integer, required): the id of the e911 record to query + + Returns: + mixed: Response from the API. A JSON Object list with the associated + DID records + Raises: + APIException: When an error occurs while fetching the data from + the remote API. This exception includes the HTTP Response + code, an error message, and the HTTP body that was received in + the request. + + """ + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/e911s/{}'.format(e911_id) + _query_url = APIHelper.clean_url(_query_builder) + + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise ErrorException('Unauthorized – There was an issue with your API credentials.', _context) + elif _context.response.status_code == 404: + raise ErrorException('The specified resource was not found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) diff --git a/flowroutenumbersandmessaging/controllers/routes_controller.py b/flowroutenumbersandmessaging/controllers/routes_controller.py index b43c61e..d275ea7 100644 --- a/flowroutenumbersandmessaging/controllers/routes_controller.py +++ b/flowroutenumbersandmessaging/controllers/routes_controller.py @@ -14,10 +14,11 @@ from ..exceptions.error_exception import ErrorException from ..exceptions.api_exception import APIException import json -class RoutesController(BaseController): - """A Controller to access Endpoints in the flowroutenumbersandmessaging API.""" +class RoutesController(BaseController): + """A Controller to access Endpoints in the + flowroutenumbersandmessaging API.""" def create_an_inbound_route(self, body): """Does a POST request to /v2/routes. @@ -52,15 +53,19 @@ class RoutesController(BaseController): } # Prepare and execute request - _request = self.http_client.post(_query_url, headers=_headers, parameters=APIHelper.json_serialize(json.loads(body))) + _request = self.http_client.post(_query_url, + headers=_headers, + parameters=APIHelper.json_serialize(json.loads(body))) BasicAuth.apply(_request) _context = self.execute_request(_request) # Endpoint and global error handling using HTTP status codes. if _context.response.status_code == 401: - raise ErrorException('401 Unauthorized – There was an issue with your API credentials.', _context) + raise ErrorException('401 Unauthorized – ' + 'There was an issue with your API credentials.', _context) elif _context.response.status_code == 403: - raise ErrorException('403 Forbidden – The server understood the request but refuses to authorize it.', _context) + raise ErrorException('403 Forbidden – ' + 'The server understood the request but refuses to authorize it.', _context) elif _context.response.status_code == 404: raise ErrorException('404 The specified resource was not found', _context) self.validate_response(_context) @@ -156,7 +161,8 @@ class RoutesController(BaseController): _query_url = APIHelper.clean_url(_query_builder) # Prepare and execute request - _request = self.http_client.patch(_query_url, parameters=APIHelper.json_serialize(json.loads(body))) + _request = self.http_client.patch(_query_url, + parameters=APIHelper.json_serialize(json.loads(body))) BasicAuth.apply(_request) _context = self.execute_request(_request) @@ -168,8 +174,8 @@ class RoutesController(BaseController): self.validate_response(_context) def update_failover_voice_route(self, - number_id, - body): + number_id, + body): """Does a PATCH request to /v2/numbers/{number_id}/relationships/failover_route. Use this endpoint to update the failover voice route for a phone @@ -213,3 +219,23 @@ class RoutesController(BaseController): elif _context.response.status_code == 404: raise ErrorException('The specified resource was not found', _context) self.validate_response(_context) + + def list_edge_strategies(self): + # Prepare query URL + _query_builder = Configuration.base_uri + _query_builder += '/v2/routes/edge_strategies' + _query_url = APIHelper.clean_url(_query_builder) + print("Query is : {}".format(_query_url)) + # Prepare and execute request + _request = self.http_client.get(_query_url) + BasicAuth.apply(_request) + _context = self.execute_request(_request) + + # Endpoint and global error handling using HTTP status codes. + if _context.response.status_code == 401: + raise APIException('Unauthorized', _context) + elif _context.response.status_code == 404: + raise APIException('Not Found', _context) + self.validate_response(_context) + + return APIHelper.json_deserialize(_context.response.raw_body) diff --git a/flowroutenumbersandmessaging/flowroutenumbersandmessaging_client.py b/flowroutenumbersandmessaging/flowroutenumbersandmessaging_client.py index d438623..dd619ab 100644 --- a/flowroutenumbersandmessaging/flowroutenumbersandmessaging_client.py +++ b/flowroutenumbersandmessaging/flowroutenumbersandmessaging_client.py @@ -10,6 +10,9 @@ from .configuration import Configuration from .controllers.numbers_controller import NumbersController from .controllers.routes_controller import RoutesController from .controllers.messages_controller import MessagesController +from .controllers.e911s_controller import E911sController +from .controllers.cnams_controller import CNAMsController + class FlowroutenumbersandmessagingClient(object): @@ -27,13 +30,18 @@ class FlowroutenumbersandmessagingClient(object): def messages(self): return MessagesController() + @lazy_property + def e911s(self): + return E911sController() + + @lazy_property + def cnams(self): + return CNAMsController() - def __init__(self, + def __init__(self, basic_auth_user_name = None, basic_auth_password = None): if basic_auth_user_name != None: Configuration.basic_auth_user_name = basic_auth_user_name if basic_auth_password != None: Configuration.basic_auth_password = basic_auth_password - -