Merge pull request #3 from flowroute/e911_integration

SDK Demo Complete
e911_addr
Chris Lacina 7 years ago committed by GitHub
commit b4c89a76bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 115
      demo.py
  2. 192
      flowroutenumbersandmessaging/controllers/messages_controller.py
  3. 169
      flowroutenumbersandmessaging/controllers/numbers_controller.py
  4. 155
      flowroutenumbersandmessaging/controllers/porting_controller.py
  5. 5
      flowroutenumbersandmessaging/flowroutenumbersandmessaging_client.py

@ -1,10 +1,12 @@
#!/usr/bin/env python
import datetime
import pprint
import random
import string
from flowroutenumbersandmessaging.configuration import Configuration
from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import \
FlowroutenumbersandmessagingClient
from dateutil.relativedelta import relativedelta
print("Number/Route Management v2 & Messaging v2.1 Demo")
@ -21,8 +23,11 @@ client = FlowroutenumbersandmessagingClient(Configuration.basic_auth_user_name,
numbers_controller = client.numbers
routes_controller = client.routes
messages_controller = client.messages
porting_controller = client.porting
print("--List Available Area Codes")
# --------------------- Numbering -----------------------------------------
print("--List Available Area Codes, specifying a maximum setup cost.")
max_setup_cost = 3.25
limit = 3
offset = None
@ -43,9 +48,9 @@ result = numbers_controller.list_available_exchange_codes(limit,
pprint.pprint(result)
print("--Search for Purchasable Phone Numbers")
starts_with = 646
starts_with = 206
contains = 3
ends_with = 7
ends_with = None
limit = 3
offset = None
rate_center = None
@ -59,10 +64,13 @@ result = numbers_controller.search_for_purchasable_phone_numbers(starts_with,
state)
pprint.pprint(result)
purchasable_number = None
if len(result['data']):
print("--Purchase a Phone Number")
purchasable_number = result['data'][0]['id']
print("NOTE: This demo has been disabled as it pulls credit from your account")
# purchasable_number = result['data'][0]['id']
# result = numbers_controller.purchase_a_phone_number(purchasable_number)
# pprint.pprint(result)
print("--List Account Phone Numbers")
starts_with = None
@ -74,17 +82,32 @@ result = numbers_controller.list_account_phone_numbers(starts_with, ends_with,
contains, limit, offset)
pprint.pprint(result)
print("--List Phone Number Details")
number_id = result['data'][0]['id']
result = numbers_controller.list_phone_number_details(number_id)
pprint.pprint(result)
print("---Create an Inbound Route")
if purchasable_number is not None:
print("--Release a DID")
result = numbers_controller.release_a_did(purchasable_number)
pprint.pprint(result)
print("--Update an Alias for a DID")
result = numbers_controller.set_did_alias(number_id, "New Test")
pprint.pprint(result)
result = numbers_controller.list_phone_number_details(number_id)
pprint.pprint(result)
print("---First list all available edge strategies")
# result = routes_controller.list_edge_strategies()
# pprint.pprint(result)
print("--Set a callback for a DID")
result = numbers_controller.set_did_callback(number_id,
'http://www.example.com/test')
pprint.pprint(result)
# --------------------- Routes -----------------------------------------
print("---List all available edge strategies")
result = routes_controller.list_edge_strategies()
pprint.pprint(result)
# Function to generate six-charac random string
@ -92,6 +115,7 @@ def id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
print("---Create an Inbound Route")
new_route = '{}.sonsofodin.com'.format(id_generator())
alias = id_generator()
for i in range(10):
@ -111,17 +135,17 @@ result = routes_controller.create_an_inbound_route(request_body)
pprint.pprint(result)
print ("---List Inbound Routes")
limit = 3
limit = 10
result = routes_controller.list_inbound_routes(limit)
pprint.pprint(result)
primary_routeid = result['data'][1]['id']
secondary_routeid = result['data'][2]['id']
prirouteid = result['data'][1]['id']
secrouteid = result['data'][2]['id']
request_body = '{ \
"data": { \
"type": "route", \
"id": "' + str(prirouteid) + '" \
"id": "' + str(primary_routeid) + '" \
} \
}'
@ -135,7 +159,7 @@ else:
request_body = '{ \
"data": { \
"type": "route", \
"id": "' + str(secrouteid) + '" \
"id": "' + str(secondary_routeid) + '" \
} \
}'
@ -146,7 +170,9 @@ if result is None:
else:
print (result)
body_with_space = "hello there{}how are you?".format(chr(160))
# --------------------- Messaging -----------------------------------------
body = "Hello there how are you?"
request_body = '{ \
"data": { \
@ -154,7 +180,7 @@ request_body = '{ \
"attributes": { \
"to": "' + str(mobile_number) + '", \
"from": "' + str(number_id) + '", \
"body": "' + unicode(body_with_space, "utf-8") + '", \
"body": "' + unicode(body, "utf-8") + '", \
"is_mms": "false" \
} \
} \
@ -173,20 +199,65 @@ request_body_mms = '{ \
} \
}'
request_body_with_dlr = '{ \
"data": { \
"type": "message", \
"attributes": { \
"to": "' + str(mobile_number) + '", \
"from": "' + str(number_id) + '", \
"body": "' + unicode(body, "utf-8") + '", \
"is_mms": "false", \
"dlr_callback": "http://httpbin.org/status/:code" \
} \
} \
}'
print("---Send A Message")
result = messages_controller.send_a_message(request_body)
pprint.pprint(result)
print("---Send A Message with a DLR")
sms_url = 'http://example.com/sms/special'
result = messages_controller.send_a_message(request_body_with_dlr)
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,
start_date = datetime.datetime.now() - relativedelta(days=30)
end_date = datetime.datetime.now()
start_date_string = start_date.strftime("%Y-%m-%d")
end_date_string = end_date.strftime("%Y-%m-%d")
limit = 10
result = messages_controller.look_up_a_set_of_messages(start_date_string,
end_date_string,
limit)
pprint.pprint(result)
print ("---Look Up A Message Detail Record")
print ("\n---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)
print("\n---Set an Account Level SMS Callback URL")
sms_url = 'http://example.com/sms'
result = messages_controller.set_account_level_sms_callback(sms_url)
pprint.pprint(result)
print("\n---Set an Account Level MMS Callback URL")
mms_url = 'http://example.com/mms'
result = messages_controller.set_account_level_mms_callback(mms_url)
pprint.pprint(result)
print("\n---Set an Account Level DLR Callback URL")
dlr_url = 'http://example.com/dlr'
result = messages_controller.set_account_level_dlr_callback(dlr_url)
pprint.pprint(result)
# --------------------- Porting -----------------------------------------
print("\n---Check Number Portability")
numbers = ['14254664444', '18827833439']
result = porting_controller.checkPortability(numbers)
pprint.pprint(result)

@ -14,11 +14,11 @@ from ..models.mdr_2 import MDR2
from ..exceptions.error_exception import ErrorException
import json
class MessagesController(BaseController):
"""A Controller to access Endpoints in the flowroutenumbersandmessaging API."""
def look_up_a_set_of_messages(self,
start_date,
end_date=None,
@ -192,3 +192,193 @@ class MessagesController(BaseController):
# Return appropriate type
return APIHelper.json_deserialize(_context.response.raw_body)
def set_account_level_sms_callback(self, url):
"""Does a PUT request to /v2.1/messages/sms_callback.
Sets the callback url for all sms messages.
Args:
url (string): The callback url to be hit.
Returns:
mixed: Response from the API. ACCEPTED
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.1/messages/sms_callback'
_query_url = APIHelper.clean_url(_query_builder)
# Prepare headers
_headers = {
'accept': 'application/vnd.api+json',
'content-type': 'application/vnd.api+json; charset=utf-8'
}
body = {
'data': {
'attributes': {
'callback_url': url
}
}
}
# Prepare and execute request
_request = self.http_client.put(_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 == 403:
raise ErrorException('Forbidden – You don\'t have permission to access this resource.', _context)
elif _context.response.status_code == 404:
raise ErrorException('The specified resource was not found', _context)
elif _context.response.status_code == 422:
raise ErrorException('Unprocessable Entity - You tried to enter an incorrect value.', _context)
self.validate_response(_context)
# Return appropriate type
return APIHelper.json_deserialize(_context.response.raw_body)
def set_account_level_mms_callback(self, url):
"""Does a PUT request to /v2.1/messages/mms_callback.
Sets the callback url for all mms messages.
Args:
url (string): The callback url to be hit.
Returns:
mixed: Response from the API. ACCEPTED
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.1/messages/mms_callback'
_query_url = APIHelper.clean_url(_query_builder)
# Prepare headers
_headers = {
'accept': 'application/vnd.api+json',
'content-type': 'application/vnd.api+json; charset=utf-8'
}
body = {
'data': {
'attributes': {
'callback_url': url
}
}
}
# Prepare and execute request
_request = self.http_client.put(_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 == 403:
raise ErrorException(
'Forbidden – You don\'t have permission to access this resource.',
_context)
elif _context.response.status_code == 404:
raise ErrorException('The specified resource was not found',
_context)
elif _context.response.status_code == 422:
raise ErrorException(
'Unprocessable Entity - You tried to enter an incorrect value.',
_context)
self.validate_response(_context)
# Return appropriate type
return APIHelper.json_deserialize(_context.response.raw_body)
def set_account_level_dlr_callback(self, url):
"""Does a PUT request to /v2.1/messages/dlr_callback.
Sets the callback url for all delivery receipts (dlrs)
Args:
url (string): The callback url to be hit.
Returns:
mixed: Response from the API. ACCEPTED
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.1/messages/dlr_callback'
_query_url = APIHelper.clean_url(_query_builder)
# Prepare headers
_headers = {
'accept': 'application/vnd.api+json',
'content-type': 'application/vnd.api+json; charset=utf-8'
}
body = {
'data': {
'attributes': {
'callback_url': url
}
}
}
# Prepare and execute request
_request = self.http_client.put(_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 == 403:
raise ErrorException(
'Forbidden – You don\'t have permission to access this resource.',
_context)
elif _context.response.status_code == 404:
raise ErrorException('The specified resource was not found',
_context)
elif _context.response.status_code == 422:
raise ErrorException(
'Unprocessable Entity - You tried to enter an incorrect value.',
_context)
self.validate_response(_context)
# Return appropriate type
return APIHelper.json_deserialize(_context.response.raw_body)

@ -14,11 +14,11 @@ from ..models.number_26 import Number26
from ..exceptions.error_exception import ErrorException
from ..exceptions.api_exception import APIException
class NumbersController(BaseController):
"""A Controller to access Endpoints in the flowroutenumbersandmessaging API."""
def list_available_exchange_codes(self,
limit=None,
offset=None,
@ -392,3 +392,170 @@ class NumbersController(BaseController):
# Return appropriate type
return APIHelper.json_deserialize(_context.response.raw_body)
def release_a_did(self, id):
"""Does a DELETE request to /v2/numbers/{id}.
Lets you release a phone number back to available Flowroute inventory.
Args:
id (int): Phone number to purchase. Must be in 11-digit E.164
format; e.g. 12061231234.
Returns:
Number26: Response from the API. CREATED
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/{id}'
_query_builder = APIHelper.append_url_with_template_parameters(_query_builder, {
'id': 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 set_did_alias(self, id, alias):
"""Does a PATCH request to /v2/numbers/{id}.
Lets you set an alias on one of your DIDs.
Args:
id (int): Phone number to purchase. Must be in 11-digit E.164
format; e.g. 12061231234.
alias (string): String to use as alias for this DID
Returns:
Number26: Response from the API. CREATED
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/{id}'
_query_builder = APIHelper.append_url_with_template_parameters(_query_builder, {
'id': id
})
# Return appropriate type
_query_url = APIHelper.clean_url(_query_builder)
# Prepare headers
_headers = {
'accept': 'application/json'
}
body = {
'type': 'number',
'alias': alias
}
# Prepare and execute request
_request = self.http_client.patch(_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 set_did_callback(self, id, url):
"""Does a POST request to /v2/numbers/{id}/relationships/dlr_callback.
Lets you set a dlr callback for a specific DID.
Args:
id (int): Phone number to purchase. Must be in 11-digit E.164
format; e.g. 12061231234.
url (string): String / URL to notify
Returns:
204 No Content
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/{id}/relationships/dlr_callback'
_query_builder = APIHelper.append_url_with_template_parameters(_query_builder, {
'id': id
})
# Return appropriate type
_query_url = APIHelper.clean_url(_query_builder)
# Prepare headers
_headers = {
'accept': 'application/json'
}
body = {
'data': {
'attributes': {
'callback_url': url
}
}
}
# 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)

@ -0,0 +1,155 @@
# -*- coding: utf-8 -*-
"""
flowroutenumbersandmessaging.controllers.porting_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 PortingController(BaseController):
"""A Controller to access Endpoints in the
flowroutenumbersandmessaging API."""
def checkPortability(self, numbers):
"""Does a POST request to /v2/portorders/portability.
Args:
numbers (list: comma delimited list of strings, required):
Phone numbers to check
Returns:
mixed: Response from the API. A JSON object of the status of each
number specified
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 = {
"numbers": numbers
}
# Prepare query URL
_query_builder = Configuration.base_uri
_query_builder += '/v2/portorders/portability'
_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)

@ -12,6 +12,7 @@ from .controllers.routes_controller import RoutesController
from .controllers.messages_controller import MessagesController
from .controllers.e911s_controller import E911sController
from .controllers.cnams_controller import CNAMsController
from .controllers.porting_controller import PortingController
class FlowroutenumbersandmessagingClient(object):
@ -38,6 +39,10 @@ class FlowroutenumbersandmessagingClient(object):
def cnams(self):
return CNAMsController()
@lazy_property
def porting(self):
return PortingController()
def __init__(self,
basic_auth_user_name = None,
basic_auth_password = None):

Loading…
Cancel
Save