My copy of flowroute sdk.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flowroute-sdk-v3-python/README.md

40 KiB

Flowroute Python Library v3

The Flowroute Python library v3 provides methods for interacting with Numbers v2 and Messages v2.1 of the Flowroute API.

Topics


Requirements


Installation

  1. First, start a shell session and clone the Python library:

    • via HTTPS: git clone https://github.com/flowroute/flowroute-sdk-v3-python.git

    • via SSH: git@github.com:flowroute/flowroute-sdk-v3-python.git

  2. Switch to the newly-created flowroute-sdk-v3-python directory. This version of the library comes with a requirements file listing the required Python libraries. See Installing Packages to learn more about different ways to install Python packages.

pip is already installed if you're using Python 2 >=2.7.9 or Python 3 >=3.4. This version of the library has been tested with both Python 2.7.9 and Python 3.6.4 for Mac OS X. To see which version of pip is installed on your machine, run the following:

pip --version

Depending on your pip permissions, you may be required to preface each pip command with sudo.

pip3 install -r requirements.txt


Usage

In Flowroute's approach to building the Python library v3, HTTP requests are handled by controllers named after the API resources they represent: Numbers, Routes, E911s, CNAMs, and Messages. These controllers contain the methods used to perform messaging, number management, route management, E911 address management, and CNAM record management within the Python library.

Controllers

NumbersController

Contains all of the methods necessary to search through Flowroute's phone number inventory, purchase a phone number, and review details of your account phone numbers.

RoutesController

Contains the methods required to create new inbound routes, view all of your account routes, and update primary and failover voice routes for your phone numbers.

MessagesController

Contains the methods required to send an MMS or SMS, and review a specific Message Detail Record (MDR) or a set of messages.

E911sController

Contains all of the methods necessary to create, update, and validate new and existing E911 addresses, retrieve all of the E911 records, activate and deactive E911 service for long code and toll-free numbers on your account, view all of the phone numbers associated with an E911 record, and remove an E911 address from your account once it is no longer associated with any of your Flowroute phone numbers.

  • list_e911s() - Returns a list of all E911 records on your account by default. All request parameters are optional. If you don't specify a limit, results are limited to the first 10 items.
  • get_e911(e911_id) - Returns details on a specified E911 record.
  • validate_address(e911_attributes) - Lets you validate new and existing E911 addresses on your account.
  • create_address(e911_attributes) - Lets you create and validate an E911 address within the US and Canada which can then be assigned to any of the long code or toll­free numbers on your account. To assign an E911 address to your number, see the associate method.
  • update_address(e911_id, e911_attributes) - Lets you update and validate an existing E911 address on your account. You must create the E911 address first by following the create_address method.
  • associate(e911_id, number_id) - Lets you update and validate an existing E911 address on your account. You must create the E911 address first by following the create_address method.
  • disconnect(number_id) - Lets you deactivate the current E911 service for your phone number.
  • delete_address(e911_id) - Lets you delete an E911 address associated with your account. You must remove all phone number associations first before you can successfully delete the specified E911 record.

CNAMsController

Contains all of the methods necessary to create and delete CNAM records, view all of the CNAM records associated with your account, filter for specific CNAM records by status, review CNAM record details, and assign and unassign CNAM records to your Flowroute long code phone numbers.

  • list_cnams() - Returns a list of all CNAM records on your account by default. You can apply search filters using any of the available query parameters.
  • get_cnam(cnam_id) - Returns details pertaining to a specific CNAM record on your account, including long code numbers that are associated with the record.
  • create_cnam_record(cnam_value) - Lets you create a Caller ID record for your account which can then be assigned to any of your long code numbers. To assign a CNAM record to your number, see the associate_cnam method.
  • associate_cnam(cnam_id, number_id) - Lets you associate a CNAM record with a specified long code number on your account. Note that a CNAM record takes 1-2 days to be approved.
  • unassociate(number_id) - Lets you unassign a CNAM record associated with a specified long code number on your account without deleting the CNAM record itself.
  • remove_cnam(cnam_id) - Lets you delete a CNAM record from your account. Note that this will automatically disassociate all numbers associated with the deleted CNAM record.

The following shows an example of a single Python file that imports the Flowroute API client and all the required modules. The Python library v3 comes with three example demo files — number_route_message_demo.py, e911_demo.py, cnam_demo.py — files that you can edit and run for demonstration and testing purposes.

import pprint
import os
import json
import random
import string
from flowroutenumbersandmessaging.flowroutenumbersandmessaging_client import FlowroutenumbersandmessagingClient

Credentials

Let's take number_route_message_demo.py as an example. In the file, replace basic_auth_user_name with your API Access Key and basic_auth_password with your API Secret Key from the Flowroute Manager. Note that in our example, we are accessing your Flowroute credentials as environment variables. To learn more about setting environment variables, see How To Read and Set Environmental and Shell Variables.

# 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"

Instantiate API Client and Controllers

Next, instantiate the API Client and its controllers. In the example below, we are only instantiating the necessary controllers for the Numbers,Messages, and Routes resources. The E911 and CNAM demo files come with their own set of required controllers to interact with the associated methods for E911 and CNAM record management.

# Instantiate API client and create controllers for Numbers, Messages, and Routes
client = FlowroutenumbersandmessagingClient(basic_auth_user_name, basic_auth_password)
numbers_controller = client.numbers
routes_controller = client.routes
messages_controller = client.messages

Methods

The following section will demonstrate the capabilities of Numbers v2, Messaging v2.1, E911 v2, and CNAM v2 that are wrapped in our Python library. Note that the example responses have been formatted using Mac's pbpaste and jq. To learn more, see Quickly Tidy Up JSON from the Command Line.

Number Management

The Flowroute Python library v3 allows you to make HTTP requests to the numbers resource of Flowroute API v2: https://api.flowroute.com/v2/numbers

list_available_area_codes()

The method accepts limit, offset, and max_setup_cost as parameters which you can learn more about in the API reference.

Example Request
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)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of area code objects in JSON format.

{
  "data": [
    {
      "type": "areacode",
      "id": "201",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/available/exchanges?areacode=201"
      }
    },
    {
      "type": "areacode",
      "id": "202",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/available/exchanges?areacode=202"
      }
    },
    {
      "type": "areacode",
      "id": "203",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/available/exchanges?areacode=203"
      }
    }
  ],
  "links": {
    "self": "https://api.flowroute.com/v2/numbers/available/areacodes?max_setup_cost=3&limit=3&offset=0",
    "next": "https://api.flowroute.com/v2/numbers/available/areacodes?max_setup_cost=3&limit=3&offset=3"
  }
}

list_available_exchange_codes()

The method accepts limit, offset, max_setup_cost, and areacode as parameters which you can learn more about in the API reference.

Example Request
print("--List Available Exchange Codes")
limit = 3
offset = None
max_setup_cost = None
areacode = 347
result = numbers_controller.list_available_exchange_codes(limit, offset, max_setup_cost, areacode)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of exchange objects in JSON format.

{
  "data": [
    {
      "type": "exchange",
      "id": "347215",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/available?starts_with=1347215"
      }
    },
    {
      "type": "exchange",
      "id": "347325",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/available?starts_with=1347325"
      }
    },
    {
      "type": "exchange",
      "id": "347331",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/available?starts_with=1347331"
      }
    }
  ],
  "links": {
    "self": "https://api.flowroute.com/v2/numbers/available/exchanges?areacode=347&limit=3&offset=0",
    "next": "https://api.flowroute.com/v2/numbers/available/exchanges?areacode=347&limit=3&offset=3"
  }
}

search_for_purchasable_phone_numbers()

The method accepts starts_with, contains, ends_with, limit, offset, rate_center, and state as parameters which you can learn more about in the API reference.

Example Request
print("--Search for Purchasable Phone Numbers")
starts_with = 646
contains = 3
ends_with = 7
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)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of phone number objects in JSON format.

{
  "data": [
    {
      "attributes": {
        "rate_center": "nwyrcyzn01",
        "value": "16463439507",
        "monthly_cost": 1.25,
        "state": "ny",
        "number_type": "standard",
        "setup_cost": 1
      },
      "type": "number",
      "id": "16463439507",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/16463439507"
      }
    },
    {
      "attributes": {
        "rate_center": "nwyrcyzn01",
        "value": "16463439617",
        "monthly_cost": 1.25,
        "state": "ny",
        "number_type": "standard",
        "setup_cost": 1
      },
      "type": "number",
      "id": "16463439617",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/16463439617"
      }
    },
    {
      "attributes": {
        "rate_center": "nwyrcyzn01",
        "value": "16463439667",
        "monthly_cost": 1.25,
        "state": "ny",
        "number_type": "standard",
        "setup_cost": 3.99
      },
      "type": "number",
      "id": "16463439667",
      "links": {
        "related": "https://api.flowroute.com/v2/numbers/16463439667"
      }
    }
  ],
  "links": {
    "self": "https://api.flowroute.com/v2/numbers/available?contains=3&ends_with=7&starts_with=1646&limit=3&offset=0",
    "next": "https://api.flowroute.com/v2/numbers/available?contains=3&ends_with=7&starts_with=1646&limit=3&offset=3"
  }
}

purchase_a_phone_number(purchasable_number)

The method is used to purchase a telephone number from Flowroute's inventory and accepts the phone number id as a parameter which you can learn more about in the API reference. In the following example, we assign the id of the first phone number in the resulting JSON array as the phone number to be purchased. Note that this function call is currently commented out. Uncomment to test the purchase_a_phone_number method.

Example Request
print("--Purchase a Phone Number")
purchasable_number = result['data'][0]['id'] 
result = numbers_controller.purchase_a_phone_number(purchasable_number)

Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains a phone number object in JSON format.

{
  "data": {
    "attributes": {
      "alias": null,
      "cnam_lookups_enabled": true,
      "number_type": "standard",
      "rate_center": "millbrae",
      "state": "ca",
      "value": "16502390214"
    },
    "id": "16502390214",
    "links": {
      "self": "https://api.flowroute.com/v2/numbers/16502390214"
    },
    "relationships": {
      "cnam_preset": {
        "data": null
      },
      "e911_address": {
        "data": null
      },
      "failover_route": {
        "data": null
      },
      "primary_route": {
        "data": {
          "id": "0",
          "type": "route"
        }
      }
    },
    "type": "number"
  },
  "included": [
    {
      "attributes": {
        "alias": "sip-reg",
        "route_type": "sip-reg",
        "value": null
      },
      "id": "0",
      "links": {
        "self": "https://api.flowroute.com/v2/routes/0"
      },
      "type": "route"
    }
  ],
  "links": {
    "self": "https://api.flowroute.com/v2/numbers/16502390214"
  }
}

list_account_phone_numbers()

The method accepts starts_with, ends_with, contains, limit, and offset as parameters which you can learn more about in the API reference.

Example Request
print("--List Account Phone Numbers")
starts_with = 201
ends_with = None
contains = None
limit = 3
offset = None
result = numbers_controller.list_account_phone_numbers(starts_with, ends_with, contains, limit, offset)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of phone number objects in JSON format.

{
  "data": [
    {
      "attributes": {
        "rate_center": "oradell",
        "value": "12012673227",
        "alias": null,
        "state": "nj",
        "number_type": "standard",
        "cnam_lookups_enabled": true
      },
      "type": "number",
      "id": "12012673227",
      "links": {
        "self": "https://api.flowroute.com/v2/numbers/12012673227"
      }
    },
    {
      "attributes": {
        "rate_center": "jerseycity",
        "value": "12014845220",
        "alias": null,
        "state": "nj",
        "number_type": "standard",
        "cnam_lookups_enabled": true
      },
      "type": "number",
      "id": "12014845220",
      "links": {
        "self": "https://api.flowroute.com/v2/numbers/12014845220"
      }
    }
  ],
  "links": {
    "self": "https://api.flowroute.com/v2/numbers?starts_with=1201&limit=3&offset=0"
  }
}

list_phone_number_details(number_id)

The method accepts the number_id as a parameter which you can learn more about in the API reference. In the following example, we request the details of the first phone number returned after calling the list_account_phone_numbers method.

Example Request
print("--List Phone Number Details")
number_id = result['data'][0]['id']
result = numbers_controller.list_phone_number_details(number_id)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains a phone number object in JSON format.

{
  "included": [
    {
      "attributes": {
        "route_type": "sip-reg",
        "alias": "sip-reg",
        "value": null
      },
      "type": "route",
      "id": "0",
      "links": {
        "self": "https://api.flowroute.com/v2/routes/0"
      }
    }
  ],
  "data": {
    "relationships": {
      "cnam_preset": {
        "data": null
      },
      "e911_address": {
        "data": null
      },
      "failover_route": {
        "data": null
      },
      "primary_route": {
        "data": {
          "type": "route",
          "id": "0"
        }
      }
    },
    "attributes": {
      "rate_center": "millbrae",
      "value": "16502390214",
      "alias": null,
      "state": "ca",
      "number_type": "standard",
      "cnam_lookups_enabled": true
    },
    "type": "number",
    "id": "16502390214",
    "links": {
      "self": "https://api.flowroute.com/v2/numbers/16502390214"
    }
  },
  "links": {
    "self": "https://api.flowroute.com/v2/numbers/16502390214"
  }
}

Route Management

The Flowroute Python library v3 allows you to make HTTP requests to the routes resource of Flowroute API v2: https://api.flowroute.com/v2/routes

create_an_inbound_route(route_body)

The method accepts the route object in JSON format as a parameter which you can learn more about in the API reference. In the following example, we define a function to generate a six-character random string for our subdomain which we later concatenate with our example domain and assign as our host value. We use the same function to generate a unique alias.

Example Request
print ("---Create an Inbound Route")
# 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'
alias = id_generator()
for i in range(6): alias += str(i)
print new_route
request_body = '{ \
  "data": { \
    "type": "route", \
    "attributes": { \
      "route_type": "host", \
      "value": "' + new_route +'", \
      "alias": "' + alias + '" \
    } \
  } \
}'
result = routes_controller.create_an_inbound_route(request_body)
print result
Example Response

On success, the HTTP status code in the response header is 201 Created and the response body contains a route object in JSON format.

{
  "data": {
    "attributes": {
      "alias": "new route",
      "route_type": "host",
      "value": "il775u.sonsofodin.com"
    },
    "id": "98396",
    "links": {
      "self": "https://api.flowroute.com/routes/98396"
    },
    "type": "route"
  },
  "links": {
    "self": "https://api.flowroute.com/routes/98396"
  }
}

list_inbound_routes()

The method accepts limit and offset as parameters which you can learn more about in the API reference.

Example Request
print ("---List Inbound Routes")
limit = 3
result = routes_controller.list_inbound_routes(limit)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of route objects in JSON format.

{
  "data": [
    {
      "attributes": {
        "route_type": "sip-reg",
        "alias": "sip-reg",
        "value": null
      },
      "type": "route",
      "id": "0",
      "links": {
        "self": "https://api.flowroute.com/v2/routes/0"
      }
    },
    {
      "attributes": {
        "route_type": "number",
        "alias": "PSTNroute1",
        "value": "12065551212"
      },
      "type": "route",
      "id": "83834",
      "links": {
        "self": "https://api.flowroute.com/v2/routes/83834"
      }
    }
  ],
  "links": {
    "self": "https://api.flowroute.com/v2/routes?limit=2&offset=0",
    "next": "https://api.flowroute.com/v2/routes?limit=2&offset=2"
  }
}

update_primary_voice_route(number_id, route_body)

The method accepts a phone number id and a route record object in JSON format as parameters which you can learn more about in the API reference. In the following example, we extract the second route in our list_inbound_routes search result and assign it as the primary voice route for our previously declared number_id.

Example Request
prirouteid = result['data'][1]['id']
request_body = '{ \
  "data": { \
    "type": "route", \
    "id": "' + str(prirouteid) +'" \
  } \
}'

print ("---Update Primary Voice Route")
result = routes_controller.update_primary_voice_route(number_id, request_body)
if result is None:
    print "204: No Content"
else:
    print result
Example Response

On success, the HTTP status code in the response header is 204 No Content which means that the server successfully processed the request and is not returning any content.

204: No Content

update_failover_voice_route(number_id, route_body)

The method accepts a phone number id and a route record object in JSON format as parameters which you can learn more about in the API reference. In the following example, we extract the third and last route in our list_inbound_routes search result and assign it as the failover voice route for our previously declared number_id.

Example Request
secrouteid = result['data'][2]['id']
request_body = '{ \
  "data": { \
    "type": "route", \
    "id": "' + str(secrouteid) +'" \
  } \
}'

print ("---Update Failover Voice Route")
result = routes_controller.update_failover_voice_route(number_id, request_body)
if result is None:
    print "204: No Content"
else:
    print result
Example Response

On success, the HTTP status code in the response header is 204 No Content which means that the server successfully processed the request and is not returning any content.

204: No Content

Messaging

The Flowroute Python library v3 allows you to make HTTP requests to the messages resource of Flowroute API v2.1: https://api.flowroute.com/v2.1/messages

send_a_message(message_body)

The method accepts a message object in JSON format as a parameter which you can learn more about in the API References for MMS and SMS. In the following example, we are sending an MMS with a gif attachment from the previously declared number_id to your mobile number.

Example Request
request_body = '{ \
  "data": { \
    "type": "message", \
    "attributes": { \
      "to": "' + str(mobile_number) + '", \
      "from": "' + str(number_id) + '", \
      "body": "hello there", \
      "is_mms": "true", \
      "media_urls": ["http://s3.amazonaws.com/barkpost-assets/50+GIFs/37.gif"] \
    } \
  } \
}'

print ("---Send A Message")
result = messages_controller.send_a_message(request_body)
pprint.pprint(result)

Note that this function call is currently commented out. Uncomment to test the send_a_message method.

Example Response

On success, the HTTP status code in the response header is 202 Accepted and the response body contains the message record ID with mdr2 prefix.

{
  "data": {
    "links": {
      "self": "https://api.flowroute.com/v2.1/messages/mdr2-39cadeace66e11e7aff806cd7f24ba2d"
    },
    "type": "message",
    "id": "mdr2-39cadeace66e11e7aff806cd7f24ba2d"
  }
}

look_up_a_set_of_messages(start_date)

The method accepts start_date, end_date, limit, and offset as parameters which you can learn more about in the API Reference.

Example Request
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)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of message objects in JSON format.

{
  "data": [
    {
      "attributes": {
        "body": "Hello are you there? ",
        "status": "delivered",
        "direction": "inbound",
        "amount_nanodollars": 4000000,
        "to": "12012673227",
        "message_encoding": 0,
        "timestamp": "2017-12-22T01:52:39.39Z",
        "delivery_receipts": [],
        "amount_display": "$0.0040",
        "from": "12061231234",
        "is_mms": false,
        "message_type": "longcode"
      },
      "type": "message",
      "id": "mdr2-ca82be46e6ba11e79d08862d092cf73d"
    },
    {
      "attributes": {
        "body": "test sms on v2",
        "status": "message buffered",
        "direction": "outbound",
        "amount_nanodollars": 4000000,
        "to": "12061232634",
        "message_encoding": 0,
        "timestamp": "2017-12-21T16:44:34.93Z",
        "delivery_receipts": [
          {
            "status": "message buffered",
            "status_code": 1003,
            "status_code_description": "Message accepted by Carrier",
            "timestamp": "2017-12-21T16:44:35.00Z",
            "level": 2
          },
          {
            "status": "smsc submit",
            "status_code": null,
            "status_code_description": "Message has been sent",
            "timestamp": "2017-12-21T16:44:35.00Z",
            "level": 1
          }
        ],
        "amount_display": "$0.0040",
        "from": "12012673227",
        "is_mms": false,
        "message_type": "longcode"
      },
      "type": "message",
      "id": "mdr2-39cadeace66e11e7aff806cd7f24ba2d"
    }
  ],
  "links": {
    "next": "https://api.flowroute.com/v2.1/messages?limit=2&start_date=2017-12-01T00%3A00%3A00%2B00%3A00&end_date=2018-01-08T00%3A00%3A00%2B00%3A00&offset=2"
  }
}

look_up_a_message_detail_record(message_id)

The method accepts a message id in MDR2 format as a parameter which you can learn more about in the API Reference. In the following example, we retrieve the details of the first message in our look_up_a_set_of_messages search result.

Example Request
message_id = result['data'][0]['id']
result = messages_controller.look_up_a_message_detail_record(message_id)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains the message object for our specified message id.

{
  "data": {
    "attributes": {
      "body": "Hello are you there? ",
      "status": "delivered",
      "direction": "inbound",
      "amount_nanodollars": 4000000,
      "to": "12012673227",
      "message_encoding": 0,
      "timestamp": "2017-12-22T01:52:39.39Z",
      "delivery_receipts": [],
      "amount_display": "$0.0040",
      "from": "12061232634",
      "is_mms": false,
      "message_type": "longcode"
    },
    "type": "message",
    "id": "mdr2-ca82be46e6ba11e79d08862d092cf73d"
  }
}

E911 Address Management

The Flowroute Python library v3 allows you to make HTTP requests to the e911s resource of Flowroute API v2: https://api.flowroute.com/v2/e911s

API Reference Pages
The E911 and CNAM API reference pages are currently restricted to our beta customers, which means that all API reference links below currently return a 404 Not Found. They will be publicly available during our E911 and CNAM APIs GA launch in a few weeks.

list_e911s()

The method accepts limit, offset, and state as parameters which you can learn more about in the API reference.

Example Request
print("--List E911 Records")
limit = 2
offset = None
result = e911s_controller.list_e911s(limit, offset)
pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains an array of e911 objects in JSON format.

--List E911 Records
{'data': [{'attributes': {'address_type': 'Lobby',
                          'address_type_number': '12',
                          'city': 'Seattle',
                          'country': 'USA',
                          'first_name': 'Maria',
                          'label': 'Example E911',
                          'last_name': 'Bermudez',
                          'state': 'WA',
                          'street_name': '20th Ave SW',
                          'street_number': '7742',
                          'zip': '98106'},
           'id': '20930',
           'links': {'self': 'https://api.flowroute.com/v2/e911s/20930'},
           'type': 'e911'},
          {'attributes': {'address_type': 'Apartment',
                          'address_type_number': '12',
                          'city': 'Seattle',
                          'country': 'US',
                          'first_name': 'Something',
                          'label': '5th E911',
                          'last_name': 'Someone',
                          'state': 'WA',
                          'street_name': 'Main St',
                          'street_number': '645',
                          'zip': '98104'},
           'id': '20707',
           'links': {'self': 'https://api.flowroute.com/v2/e911s/20707'},
           'type': 'e911'}],
 'links': {'next': 'https://api.flowroute.com/v2/e911s?limit=2&offset=2',
           'self': 'https://api.flowroute.com/v2/e911s?limit=2&offset=0'}}

get_e911(e911_id)

The method accepts an e911_id as a path parameter which you can learn more about in the API reference.

Example Request
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("\n--Get Details for a specific E911 Record")
    result = e911s_controller.get_e911(e911_id)
    pprint.pprint(result)
Example Response

On success, the HTTP status code in the response header is 200 OK and the response body contains a detailed e911 object in JSON format.

--Get Details for a specific E911 Record
{'data': {'attributes': {'address_type': 'L',
                         'address_type_number': '12',
                         'city': 'Seattle',
                         'country': 'USA',
                         'first_name': 'Maria',
                         'label': 'Example E911',
                         'last_name': 'Bermudez',
                         'state': 'WA',
                         'street_name': '20th Ave SW',
                         'street_number': '7742',
                         'zip': '98106'},
          'id': '20930',
          'links': {'self': 'https://api.flowroute.com/v2/e911s/20930'},
          'type': 'e911'}}

validate_address(label, first_name, last_name, street_name, street_number, city, state, country, zipcode)

The method accepts the different attributes of an E911 address as parameters: label, first_name, last_name, street_name, street_number, city, state, country, and zipcode. Learn more about the different E911 attributes in the API reference. Note that this method doesn't accept the address\_type and address\_type\_number which are acceptable but not required E911 address attributes by the API.

Example Request
print("\n--Validate an Address")
try:
    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="CA",
                                               zipcode="98101")
    pprint.pprint(result)
except Exception as e:
    print(str(e))
Example Response

On success, the HTTP status code in the response header is 204 No Content which means that the server successfully processed the request and is not returning any content. On error, a printable representation of the detailed API response is displayed.

--Validate an Address
HTTP response not OK.
{"errors":[{"detail":"Could not geocode this address. Please check the validity of your address.","id":"7fcfd1cd-486b-4159-8484-b710bd4bbab4","status":400,"title":"Client Error"}]}
#### Errors

In cases of method errors, the Python library raises an exception which includes the HTTP Response code, an error message, and the HTTP body that was received in the request. 

##### Example Error

raise ErrorException('403 Forbidden – The server understood the request but refuses to authorize it.', _context)

  
## Testing

Once you are done configuring your Flowroute API credentials and updating the function parameters, run the file to see the demo in action:

` python demo.py `