Merge pull request #2 from flowroute/e911_integration

E911 integration
e911_addr
Chris Lacina 7 years ago committed by GitHub
commit 4f936f3afd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 53
      cnam_demo.py
  2. 90
      demo.py
  3. 91
      e911_demo.py
  4. 5
      flowroutenumbersandmessaging/configuration.py
  5. 305
      flowroutenumbersandmessaging/controllers/cnams_controller.py
  6. 539
      flowroutenumbersandmessaging/controllers/e911s_controller.py
  7. 42
      flowroutenumbersandmessaging/controllers/routes_controller.py
  8. 12
      flowroutenumbersandmessaging/flowroutenumbersandmessaging_client.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)

@ -1,21 +1,23 @@
#!/usr/bin/env python #!/usr/bin/env python
import pprint import pprint
import os
import json
import random import random
import string 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") print("Number/Route Management v2 & Messaging v2.1 Demo")
# Set up your api credentials and test mobile number for outbound SMS or MMS # 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_user_name = os.environ.get('FR_ACCESS_KEY')
basic_auth_password = os.environ.get('FR_SECRET_KEY') # basic_auth_password = os.environ.get('FR_SECRET_KEY')
mobile_number = "YOUR_MOBILE_NUMBER" mobile_number = "4254664078"
# Instantiate API client and create controllers for Numbers, Messages, and Routes # Instantiate API client and create controllers for Numbers,
client = FlowroutenumbersandmessagingClient(basic_auth_user_name, basic_auth_password) # Messages, and Routes
client = FlowroutenumbersandmessagingClient(Configuration.basic_auth_user_name,
Configuration.basic_auth_password)
numbers_controller = client.numbers numbers_controller = client.numbers
routes_controller = client.routes routes_controller = client.routes
messages_controller = client.messages messages_controller = client.messages
@ -24,7 +26,9 @@ print("--List Available Area Codes")
max_setup_cost = 3.25 max_setup_cost = 3.25
limit = 3 limit = 3
offset = None 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) pprint.pprint(result)
print("--List Available Exchange Codes") print("--List Available Exchange Codes")
@ -32,7 +36,10 @@ limit = 3
offset = None offset = None
max_setup_cost = None max_setup_cost = None
areacode = 347 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) pprint.pprint(result)
print("--Search for Purchasable Phone Numbers") print("--Search for Purchasable Phone Numbers")
@ -43,20 +50,28 @@ limit = 3
offset = None offset = None
rate_center = None rate_center = None
state = 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) pprint.pprint(result)
print("--Purchase a Phone Number") if len(result['data']):
purchasable_number = result['data'][0]['id'] print("--Purchase a Phone Number")
#result = numbers_controller.purchase_a_phone_number(purchasable_number) purchasable_number = result['data'][0]['id']
# result = numbers_controller.purchase_a_phone_number(purchasable_number)
print("--List Account Phone Numbers") print("--List Account Phone Numbers")
starts_with = 201 starts_with = None
ends_with = None ends_with = None
contains = None contains = None
limit = 3 limit = 3
offset = None 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) pprint.pprint(result)
@ -66,10 +81,18 @@ result = numbers_controller.list_phone_number_details(number_id)
pprint.pprint(result) pprint.pprint(result)
print("---Create an Inbound Route") 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 # Function to generate six-charac random string
def id_generator(size=6, chars=string.ascii_lowercase + string.digits): def id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size)) 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() alias = id_generator()
for i in range(10): for i in range(10):
alias += str(i) alias += str(i)
@ -78,8 +101,9 @@ request_body = '{ \
"type": "route", \ "type": "route", \
"attributes": { \ "attributes": { \
"route_type": "host", \ "route_type": "host", \
"value": "' + new_route +'", \ "value": "' + new_route + '", \
"alias": "' + alias + '" \ "alias": "' + alias + '", \
"edge_strategy": "1" \
} \ } \
} \ } \
}' }'
@ -97,7 +121,7 @@ secrouteid = result['data'][2]['id']
request_body = '{ \ request_body = '{ \
"data": { \ "data": { \
"type": "route", \ "type": "route", \
"id": "' + str(prirouteid) +'" \ "id": "' + str(prirouteid) + '" \
} \ } \
}' }'
@ -111,7 +135,7 @@ else:
request_body = '{ \ request_body = '{ \
"data": { \ "data": { \
"type": "route", \ "type": "route", \
"id": "' + str(secrouteid) +'" \ "id": "' + str(secrouteid) + '" \
} \ } \
}' }'
@ -122,7 +146,21 @@ if result is None:
else: else:
print (result) print (result)
body_with_space = "hello there{}how are you?".format(chr(160))
request_body = '{ \ 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": { \ "data": { \
"type": "message", \ "type": "message", \
"attributes": { \ "attributes": { \
@ -136,19 +174,19 @@ request_body = '{ \
}' }'
print("---Send A Message") print("---Send A Message")
#result = messages_controller.send_a_message(request_body) result = messages_controller.send_a_message(request_body)
#pprint.pprint(result) pprint.pprint(result)
print("---Look Up A Set Of Messages") print("---Look Up A Set Of Messages")
start_date = "2017-12-01" start_date = "2017-12-01"
end_date = "2018-01-08" end_date = "2018-01-08"
limit = 2 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) pprint.pprint(result)
print ("---Look Up A Message Detail Record") print ("---Look Up A Message Detail Record")
message_id = result['data'][0]['id'] message_id = result['data'][0]['id']
result = messages_controller.look_up_a_message_detail_record(message_id) result = messages_controller.look_up_a_message_detail_record(message_id)
pprint.pprint(result) pprint.pprint(result)

@ -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)

@ -7,6 +7,7 @@
""" """
from .api_helper import APIHelper from .api_helper import APIHelper
class Configuration(object): class Configuration(object):
"""A class used for configuring the SDK by a user. """A class used for configuring the SDK by a user.
@ -25,9 +26,9 @@ class Configuration(object):
# The username to use with basic authentication # The username to use with basic authentication
# TODO: Set an appropriate value # TODO: Set an appropriate value
basic_auth_user_name = "TODO: Replace" basic_auth_user_name = "22476860"
# The password to use with basic authentication # The password to use with basic authentication
# TODO: Set an appropriate value # TODO: Set an appropriate value
basic_auth_password = "TODO: Replace" basic_auth_password = "FYzckHAgBdHm1QpKbe6jdMivOWFlnApf"

@ -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/<cnam_id>.
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)

@ -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/<e911_id>.
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/<e911_id>.
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/<e911_id>.
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/<did>/relationships/e911s/<e911_id>.
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/<did>/relationships/e911s/<e911_id>.
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/<e911_id>/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)

@ -14,10 +14,11 @@ from ..exceptions.error_exception import ErrorException
from ..exceptions.api_exception import APIException from ..exceptions.api_exception import APIException
import json 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): def create_an_inbound_route(self, body):
"""Does a POST request to /v2/routes. """Does a POST request to /v2/routes.
@ -52,15 +53,19 @@ class RoutesController(BaseController):
} }
# Prepare and execute request # 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) BasicAuth.apply(_request)
_context = self.execute_request(_request) _context = self.execute_request(_request)
# Endpoint and global error handling using HTTP status codes. # Endpoint and global error handling using HTTP status codes.
if _context.response.status_code == 401: 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: 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: elif _context.response.status_code == 404:
raise ErrorException('404 The specified resource was not found', _context) raise ErrorException('404 The specified resource was not found', _context)
self.validate_response(_context) self.validate_response(_context)
@ -156,7 +161,8 @@ class RoutesController(BaseController):
_query_url = APIHelper.clean_url(_query_builder) _query_url = APIHelper.clean_url(_query_builder)
# Prepare and execute request # 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) BasicAuth.apply(_request)
_context = self.execute_request(_request) _context = self.execute_request(_request)
@ -168,8 +174,8 @@ class RoutesController(BaseController):
self.validate_response(_context) self.validate_response(_context)
def update_failover_voice_route(self, def update_failover_voice_route(self,
number_id, number_id,
body): body):
"""Does a PATCH request to /v2/numbers/{number_id}/relationships/failover_route. """Does a PATCH request to /v2/numbers/{number_id}/relationships/failover_route.
Use this endpoint to update the failover voice route for a phone 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: elif _context.response.status_code == 404:
raise ErrorException('The specified resource was not found', _context) raise ErrorException('The specified resource was not found', _context)
self.validate_response(_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)

@ -10,6 +10,9 @@ from .configuration import Configuration
from .controllers.numbers_controller import NumbersController from .controllers.numbers_controller import NumbersController
from .controllers.routes_controller import RoutesController from .controllers.routes_controller import RoutesController
from .controllers.messages_controller import MessagesController from .controllers.messages_controller import MessagesController
from .controllers.e911s_controller import E911sController
from .controllers.cnams_controller import CNAMsController
class FlowroutenumbersandmessagingClient(object): class FlowroutenumbersandmessagingClient(object):
@ -27,6 +30,13 @@ class FlowroutenumbersandmessagingClient(object):
def messages(self): def messages(self):
return MessagesController() 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_user_name = None,
@ -35,5 +45,3 @@ class FlowroutenumbersandmessagingClient(object):
Configuration.basic_auth_user_name = basic_auth_user_name Configuration.basic_auth_user_name = basic_auth_user_name
if basic_auth_password != None: if basic_auth_password != None:
Configuration.basic_auth_password = basic_auth_password Configuration.basic_auth_password = basic_auth_password

Loading…
Cancel
Save