You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafficcontrol.apache.org by GitBox <gi...@apache.org> on 2018/12/18 02:19:10 UTC

[GitHub] mitchell852 closed pull request #3130: Python client Package restructure

mitchell852 closed pull request #3130: Python client Package restructure
URL: https://github.com/apache/trafficcontrol/pull/3130
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/docs/source/api/api_capabilities.rst b/docs/source/api/api_capabilities.rst
index 9d7bdf44e..bb8aa31e8 100644
--- a/docs/source/api/api_capabilities.rst
+++ b/docs/source/api/api_capabilities.rst
@@ -13,7 +13,7 @@
 .. limitations under the License.
 ..
 
-.. _to-api-api_capability:
+.. _to-api-api_capabilities:
 
 ********************
 ``api_capabilities``
diff --git a/docs/source/api/api_capabilities_id.rst b/docs/source/api/api_capabilities_id.rst
index f72216c6b..10f511147 100644
--- a/docs/source/api/api_capabilities_id.rst
+++ b/docs/source/api/api_capabilities_id.rst
@@ -13,7 +13,7 @@
 .. limitations under the License.
 ..
 
-.. _to-api-api_capabilities_id:
+.. _to-api-api_capabilities-id:
 
 ***************************
 ``api_capabilities/{{ID}}``
diff --git a/docs/source/api/cachegroups_id_parameters.rst b/docs/source/api/cachegroups_id_parameters.rst
index 899f1a9de..0f5378c18 100644
--- a/docs/source/api/cachegroups_id_parameters.rst
+++ b/docs/source/api/cachegroups_id_parameters.rst
@@ -13,7 +13,7 @@
 .. limitations under the License.
 ..
 
-.. _to-api-cachegroup_id_parameters:
+.. _to-api-cachegroups-id-parameters:
 
 *********************************
 ``cachegroups/{{ID}}/parameters``
diff --git a/docs/source/api/cachegroups_id_queue_updates.rst b/docs/source/api/cachegroups_id_queue_update.rst
similarity index 100%
rename from docs/source/api/cachegroups_id_queue_updates.rst
rename to docs/source/api/cachegroups_id_queue_update.rst
diff --git a/docs/source/api/cachegroups_id_unassigned_parameters.rst b/docs/source/api/cachegroups_id_unassigned_parameters.rst
index 45347699d..42fd37596 100644
--- a/docs/source/api/cachegroups_id_unassigned_parameters.rst
+++ b/docs/source/api/cachegroups_id_unassigned_parameters.rst
@@ -13,7 +13,7 @@
 .. limitations under the License.
 ..
 
-.. _to-api-cachegroup_id_unassigned_parameters:
+.. _to-api-cachegroups-id-unassigned_parameters:
 
 ********************************************
 ``cachegroups/{{id}}/unassigned_parameters``
diff --git a/docs/source/api/cachegroups_trimmed.rst b/docs/source/api/cachegroups_trimmed.rst
index ae46e3018..dd462c3c7 100644
--- a/docs/source/api/cachegroups_trimmed.rst
+++ b/docs/source/api/cachegroups_trimmed.rst
@@ -13,7 +13,7 @@
 .. limitations under the License.
 ..
 
-.. _to-api-cachegroups_trimmed:
+.. _to-api-cachegroups-trimmed:
 
 ***********************
 ``cachegroups/trimmed``
diff --git a/docs/source/api/cdns_name_snapshot.rst b/docs/source/api/cdns_name_snapshot.rst
index 91d976c02..facc93bc2 100644
--- a/docs/source/api/cdns_name_snapshot.rst
+++ b/docs/source/api/cdns_name_snapshot.rst
@@ -13,7 +13,7 @@
 .. limitations under the License.
 ..
 
-.. _to-api-cdns-snapshot-name:
+.. _to-api-cdns-name-snapshot:
 
 **************************
 ``cdns/{{name}}/snapshot``
diff --git a/docs/source/api/deliveryservices_regex.rst b/docs/source/api/deliveryservices_regexes.rst
similarity index 100%
rename from docs/source/api/deliveryservices_regex.rst
rename to docs/source/api/deliveryservices_regexes.rst
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 71cdc4742..d36508ba2 100755
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -29,8 +29,11 @@
 import sys
 here = os.path.dirname(__file__)
 ortPath = os.path.join(here, '..', '..', 'infrastructure', 'cdn-in-a-box', 'ort')
+clientPath = os.path.join(here, '..', '..', 'traffic_control', 'clients', 'python')
 ortPath = os.path.abspath(ortPath)
+clientPath = os.path.abspath(clientPath)
 sys.path.insert(0, ortPath)
+sys.path.insert(0, clientPath)
 
 # -- Custom Lexical Analyzer for DNS -----------------------------------------
 
diff --git a/docs/source/tools/index.rst b/docs/source/tools/index.rst
index 6ef79a819..c834ab7cf 100644
--- a/docs/source/tools/index.rst
+++ b/docs/source/tools/index.rst
@@ -24,5 +24,5 @@ This is a living list of tools used to interact with, test, and develop for the
 	:maxdepth: 2
 
 	compare
+	python_client
 	traffic_vault_util
-	
diff --git a/docs/source/tools/python_client.rst b/docs/source/tools/python_client.rst
new file mode 100644
index 000000000..2135ad22c
--- /dev/null
+++ b/docs/source/tools/python_client.rst
@@ -0,0 +1,46 @@
+..
+..
+.. Licensed under the Apache License, Version 2.0 (the "License");
+.. you may not use this file except in compliance with the License.
+.. You may obtain a copy of the License at
+..
+..     http://www.apache.org/licenses/LICENSE-2.0
+..
+.. Unless required by applicable law or agreed to in writing, software
+.. distributed under the License is distributed on an "AS IS" BASIS,
+.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+.. See the License for the specific language governing permissions and
+.. limitations under the License.
+..
+
+*****************************
+Apache-TrafficControl Package
+*****************************
+
+Package Contents
+================
+.. automodule:: trafficops
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+TOSession
+---------
+.. automodule:: trafficops.tosession
+	:members:
+	:undoc-members:
+	:show-inheritance:
+
+RestAPI
+-------
+.. automodule:: trafficops.restapi
+	:members:
+	:undoc-members:
+	:show-inheritance:
+
+Utils
+-----
+.. automodule:: trafficops.utils
+	:members:
+	:undoc-members:
+	:show-inheritance:
diff --git a/traffic_control/clients/python/.gitignore b/traffic_control/clients/python/.gitignore
new file mode 100644
index 000000000..130f75bfd
--- /dev/null
+++ b/traffic_control/clients/python/.gitignore
@@ -0,0 +1,3 @@
+*.egg-info
+build/
+dist/
diff --git a/traffic_control/clients/python/README.rst b/traffic_control/clients/python/README.rst
new file mode 100644
index 000000000..e51d10451
--- /dev/null
+++ b/traffic_control/clients/python/README.rst
@@ -0,0 +1,69 @@
+************
+Introduction
+************
+This is the Traffic Ops Python Client for Python 2.x and Python 3.x.
+
+.. attention:: Traffic Control version 3.0.0 officially deprecates Python 2.x support. Starting with Traffic Control version 4.0.0, Python 2.x support will be dropped, and only Python 3.x will be supported. Users and developers are encouraged to switch to Python 3 as soon as possible.
+
+.. note:: This client has only been tested against Python 2.7 and Python 3.6. Other versions may or may not work.
+
+Installation
+============
+The official installation method is to use ``pip`` to install directly from from GitHub.
+
+.. code-block:: shell
+	:caption: Install Using 'pip' From GitHub
+
+	pip install git+https://github.com/apache/trafficcontrol.git#"egg=trafficops&subdirectory=traffic_control/clients/python/trafficops"
+
+	# or
+	# pip install git+ssh://git@github.com/apache/trafficcontrol.git#"egg=trafficops&subdirectory=traffic_control/clients/python/trafficops"
+
+Local Installation
+------------------
+The preferred method is to use ``pip`` to install locally. Starting from the repository's root directory, the following script should do the job:
+
+.. code-block:: shell
+	:linenos:
+	:caption: Local Installation of Python Client
+
+	cd traffic_control/clients/python
+	pip install .
+
+	# The above will install using the system's default Python interpreter - to use a specific
+	# version it will be necessary to specify the interpreter and pass the 'pip' module to it.
+	# e.g. for the system's default Python 2 interpreter, typically one would do:
+	# sudo -H /usr/bin/env python2 -m pip install .
+
+	# Developers may wish to use the '-e' flag. This will install the package 'edit-ably',
+	# meaning that changes made to the package within the repository structure will be effected on
+	# the system-wide installation.
+	# sudo -H pip install -e .
+
+	# If your system does not have 'pip', but does (somehow) have 'setuptools' as well
+	# as the package's dependencies, you can call 'setup.py' directly to install the
+	# package for the system's default Python 3 interpreter
+	# sudo -H ./setup.py install
+
+The local installation method requires ``pip`` and ``setuptools``. ``setuptools`` should be installed if your system has ``pip``, but if you are missing either of them they can both be relatively easily installed with Python standard libraries.
+
+.. code-block:: shell
+	:caption: Setuptools Package Installation
+
+	# Here I'm using 'python' because that points to a Python 3 interpreter on my system. You may
+	# wish to use 'python3' or 'python2' (please not that one) instead.
+	sudo -H python -m ensure_pip
+	sudo -H python -m pip install -U pip
+
+	# If your system's 'python' already has 'pip', then you may skip to this step to
+	# install only 'setuptools'
+	sudo -H python -m pip install setuptools
+
+Development Dependencies
+------------------------
+To install the development dependencies, first ensure that your system has ``pip`` and ``setuptools`` then use ``pip`` to install the development environment.
+
+.. code-block:: shell
+	:caption: Development Dependencies Installation
+
+	pip install -e .[dev]
diff --git a/traffic_control/clients/python/common/__init__.py b/traffic_control/clients/python/common/__init__.py
deleted file mode 100644
index 7ada6c313..000000000
--- a/traffic_control/clients/python/common/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
\ No newline at end of file
diff --git a/traffic_control/clients/python/common/restapi.py b/traffic_control/clients/python/common/restapi.py
deleted file mode 100644
index 4fe55184b..000000000
--- a/traffic_control/clients/python/common/restapi.py
+++ /dev/null
@@ -1,551 +0,0 @@
-# -*- coding: utf-8 -*-
-
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Module to help retrieve/create/update/delete data from/to any RESTful API (Base Class).
-
-Requires Python Version >= 2.7 or >= 3.6
-"""
-
-# Core Modules
-import json
-import logging
-import functools
-
-# Third-party Modules
-import munch
-import requests
-import requests.adapters as ra
-
-# Local Modules
-import common.utils as utils
-
-# Python 2 to Python 3 Compatibility
-import requests.compat as compat
-from builtins import str
-
-try:
-	from future.utils import iteritems
-except ImportError:
-	iteritems = lambda x: x.items()
-
-
-logger = logging.getLogger(__name__)
-
-__all__ = [u'LoginError', u'OperationError', u'InvalidJSONError', u'api_request', u'RestApiSession',
-		   u'default_headers']
-
-
-# Exception Classes
-class LoginError(BaseException):
-	def __init__(self, *args):
-		BaseException.__init__(self, *args)
-
-
-class OperationError(BaseException):
-	def __init__(self, *args):
-		BaseException.__init__(self, *args)
-
-
-class InvalidJSONError(BaseException):
-	def __init__(self, *args):
-		BaseException.__init__(self, *args)
-
-# Miscellaneous Constants and/or Variables
-default_headers = {u'Content-Type': u'application/json; charset=UTF-8'}
-
-
-# Helper Functions/Decorators
-def api_request(method_name, api_path, supported_versions):
-	"""
-	This wrapper returns a decorator that routes the calls to the appropriate utility function that generates the
-	RESTful API endpoint, performs the appropriate call to the endpoint and returns the data to the user.
-
-	:param method_name: A method name defined on the Class, this decorator is decorating, that will be called
-						to perform the operation. E.g. 'get', 'post', 'put', 'delete', etc.
-						The method_name chosen must have the signature of
-						<method>(self, api_path, **kwargs).
-							E.g. def get(self, api_path, **kwargs): ...
-	:type method_name: Text
-	:param api_path: type str: The path to the API end-point that you want to call which does not include the
-					 base url.  e.g. 'user/login', 'servers', etc.  This string can contain
-					 substitution parameters as denoted by a valid field_name replacement field
-					 specification as per str.format().
-						 E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-	:type api_path: Text
-	:param supported_versions: a tuple of API versions that this route supports
-	:type supported_versions: Tuple[Text]
-	:return: rtype int: A new function that replaces the original function with a boilerplate execution process.
-	:rtype: Callable[Text, Dict[Text, Any]]
-	"""
-	def outer(func):
-		@functools.wraps(func)
-		def method_wrapper(self, *args, **kwargs):
-			# Positional arguments, e.g. *args, are not being used. Keyword arguments are the
-			# preferred way to pass the parameters needed by the helper functions
-			if (self.api_version is None) or (self.api_version in supported_versions):
-				msg = (u'Calling method [{0}] with keyword arguments [{1}] '
-					   u'via API endpoint method [{2}]')  # type: Text
-				utils.log_with_debug_info(logging.DEBUG, msg.format(method_name, kwargs, func.__name__))
-
-				return getattr(self, method_name)(api_path, **kwargs)
-			else:
-				# Client API version is not supported by the method being called
-				msg = (u"Method [{0}] is not supported by this client's API version [{1}]; "
-					   u'Supported versions: {2}')  # type: Text
-				msg = msg.format(func.__name__, self.api_version, supported_versions)
-				utils.log_with_debug_info(logging.DEBUG, msg)
-				raise OperationError(msg)
-
-		return method_wrapper
-	return outer
-
-
-class RestApiSession(object):
-	def __init__(self, host_ip, api_version=None, api_base_path=u'api/',
-				 host_port=443, ssl=True, headers=default_headers, verify_cert=True,
-				 create_session=False, max_retries=5):
-		"""
-		The class initializer.
-		:param host_ip: The dns name or ip address of the RESTful API host to use to talk to the API
-		:type host_ip: Text
-		:param host_port: The port to use when contacting the RESTful API
-		:type host_port: int
-		:param api_version: The version of the API to make calls against.  If supplied,
-							end-point version validation will be performed.  If supplied as
-							None, no version validation will be performed.  None is allowed
-							so that non-versioned REST APIs can be implemented.
-							   E.g. '1.2', None, etc.
-		:type api_version: Union[Text, None]
-		:param api_base_path: The part of the url that is the base path, from the web server root
-							  (which may include a api version), for all api end-points without
-							  the server url portion.
-								  E.g. 'api/', 'api/1.2/', etc.
-
-							  NOTE: To specify the base path with the passed 'api_version' you can
-									specify api_base_path as 'api/{api_version}/' and the API
-									version will be substituted.  If api_version is None and
-									'{api_version}' is specified in the api_base_path string
-									then an exception will be thrown.
-									e.g. api_version=u'1.2' -> 'api/{api_version}/' -> 'api/1.2/'
-										 api_version=None   -> 'api/{api_version}/' -> Throws Exception
-		:type api_base_path: Text
-		:param ssl: Should ssl be used? http vs. https
-		:type ssl: bool
-		:param headers:  The http headers to use when contacting the RESTful API
-		:type headers: Dict[Text, Text]
-		:param verify_cert: Should the ssl certificates be verified when contacting the RESTful API.
-							You may want to set this to False for systems with self-signed certificates.
-		:type verify_cert: bool
-		:param create_session: Should a session be created automatically?
-		:type create_session: bool
-		"""
-
-		self._session = None
-		self._host_ip = host_ip
-		self._host_port = host_port
-		self._api_version = api_version
-		self._api_base_path = api_base_path
-		self._ssl = ssl
-		self._headers = headers
-		self._verify_cert = verify_cert
-		self._create_session = create_session
-		self._max_retries = max_retries
-
-		# Setup API End-point Version validation, if enabled
-		self.__api_version_format_name = u'api_version'
-		self.__api_version_format_value = u'{{{0}}}'.format(self.__api_version_format_name)
-
-		if self._api_version:
-			# if api_base_path is supplied as 'api/{api_version}/' or some string
-			# containing '{api_version}' then try to substitute the api_version supplied
-			# by the user.
-
-			version_params = {
-				self.__api_version_format_name: self._api_version
-			}
-			self._api_base_path = self._api_base_path.format(**version_params)
-
-		if not self._api_version and self.__api_version_format_value in self._api_base_path:
-			msg = (u'{0} was specified in the API Base Path [{1}] '
-				   u'but the replacement did not occur because the API Version '
-				   u'was not supplied.')  # type: Text
-			msg = msg.format(self.__api_version_format_value, self._api_base_path)
-			utils.log_with_debug_info(logging.ERROR, msg)
-			raise OperationError(msg)
-
-		# Setup some common URLs
-		self._server_url = u'{0}://{1}{2}/'.format(u'https' if ssl else u'http',
-												   host_ip,
-												   u':{0}'.format(host_port) if host_port else u'')
-		self._api_base_url = compat.urljoin(self._server_url, self._api_base_path)
-		self._api_base_url = self._api_base_url.rstrip(u'/') + u'/'
-
-		utils.log_with_debug_info(logging.DEBUG, u'Server URL: {0}'.format(self._server_url))
-		utils.log_with_debug_info(logging.DEBUG, u'API Base Path: {0}'.format(self._api_base_path))
-		utils.log_with_debug_info(logging.DEBUG, u'API Version: {0}'.format(self._api_version))
-		utils.log_with_debug_info(logging.DEBUG, u'API Base URL: {0}'.format(self._api_base_url))
-
-		if not self._verify_cert:
-			# Not verifying certs so let's disable the warning
-			import requests.packages.urllib3 as u3l
-			import requests.packages.urllib3.exceptions as u3e
-			u3l.disable_warnings(u3e.InsecureRequestWarning)
-			utils.log_with_debug_info(logging.WARNING, u'Certificate verification warnings are disabled.')
-
-		msg = u'RestApiSession instance {0:#0x} initialized: Details: {1}'
-		utils.log_with_debug_info(logging.DEBUG, msg.format(id(self), self.__dict__))
-
-		if self._create_session:
-			self.create()
-
-	@property
-	def is_open(self):
-		"""
-		Is the session open to the RESTful API? (Read-only Property)
-		:return: True if yes, otherwise, False
-		:rtype: bool
-		"""
-		return self._session is not None
-
-	@property
-	def session(self):
-		"""
-		The RESTful API session (Read-only Property)
-		:return: The requests session
-		:rtype: requests.Session
-		"""
-		return self._session
-
-	def create(self):
-		"""
-		Create the requests.Session to communicate with the RESTful API.
-		:return: None
-		:rtype: None
-		"""
-		if self._session:
-			self.close()
-
-		if not self._session:
-			self._session = requests.Session()
-			self._session.mount('http://', ra.HTTPAdapter(max_retries=self._max_retries))
-			self._session.mount('https://', ra.HTTPAdapter(max_retries=self._max_retries))
-
-			msg = u'Created internal requests Session instance {0:#0x}'
-			utils.log_with_debug_info(logging.DEBUG, msg.format(id(self._session)))
-
-	def close(self):
-		"""
-		Close and cleanup the requests Session object.
-		:return: None
-		:rtype: None
-		"""
-
-		if self._session:
-			sid = id(self._session)
-			self._session.close()
-			del self._session
-			self._session = None
-
-			if logging:
-				msg = u'Internal requests Session instance 0x{0:x} closed and cleaned up'
-				utils.log_with_debug_info(logging.DEBUG, msg.format(sid))
-
-	@property
-	def server_url(self):
-		"""
-		The URL without the api portion. (read-only)
-		:return: The url should be in the format of
-				 '<protocol>://<hostname>[:<port>]'; [] = optional
-					 E.g. 'https://to.somedomain.net' or 'https://to.somedomain.net:443'
-		:rtype: Text
-		"""
-
-		return self._server_url
-
-	@property
-	def api_version(self):
-		"""
-		Returns the api version. (read-only)
-		:return: The api version this instance will request end-points from.
-		:rtype: Text
-		"""
-
-		return self._api_version
-
-	@property
-	def api_base_url(self):
-		"""
-		Returns the base url. (read-only)
-		:return: The base url should be in the format of
-				 '<protocol>://<hostname>[:<port>]/<api base url>'; [] = optional
-					 E.g. 'https://to.somedomain.net/api/0.1/'
-		:rtype: Text
-		"""
-
-		return self._api_base_url
-
-	def _build_endpoint(self, api_path, params=None, query_params=None):
-		"""
-		Helper function to form API URL.
-		The base url is '<protocol>://<hostname>[:<port>]/<api base url>'
-			E.g. 'https://to.somedomain.net/api/0.1/'
-		:param api_path: The path to the API end-point that you want to call which does not include the
-						 base url.  e.g. 'user/login', 'servers', etc.  This string can contain
-						 substitution parameters as denoted by a valid field_name
-						 replacement field specification as per str.format().
-						   E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-		:type api_path: Text
-		:param params: If str.format() field_name replacement field specifications exists in the
-					   api_path use this dictionary to perform replacements of the specifications
-					   with the value(s) in the dictionary that match the parameter name(s).
-					   E.g. '{param_id}' or '{param_id:d}' in api_string is replaced by value in
-							params['param_id'].
-		:type params: Union[Dict[Text, Any], None]
-		:param: query_params: URL query params to provide to the end-point.
-							 E.g. { 'sort': 'asc', 'maxresults': 200 }  which
-							 translates to something like '?sort=asc&maxresults=200' which
-							 is appended to the request URL
-		:type query_params: Union[Dict[Text, Any], None]
-		:return: The base url plus the passed and possibly substituted api_path to form a
-				 complete URL to the API resource to request
-		:rtype: Text
-		:raises: ValueError
-		"""
-
-		new_api_path = api_path
-
-		# Replace all parameters in the new_api_path path, if required
-		try:
-			# Make the parameters values safe for adding to URLs
-			url_params = {k: compat.quote(str(v)) if isinstance(v, str) else v for k, v in iteritems(params)}
-
-			utils.log_with_debug_info(logging.DEBUG, u'URL parameters are: [{0}]'.format(url_params))
-
-			qparams = u''
-			if query_params:
-				# Process the URL query parameters
-				qparams = u'?{0}'.format(compat.urlencode(query_params))
-				utils.log_with_debug_info(logging.DEBUG, u'URL query parameters are: [{0}]'.format(qparams))
-
-			new_api_path = api_path.format(**url_params) + qparams
-		except KeyError as e:
-			msg = (u'Expecting a value for keyword argument [{0}] for format field '
-				   u'specification [{1!r}]')
-			msg = msg.format(e, api_path)
-			utils.log_with_debug_info(logging.ERROR, msg)
-			raise ValueError(msg)
-		except ValueError as e:
-			msg = (u'One or more values do not match the format field specification '
-				   u'[{0!r}]; Supplied values: {1!r} ')
-			msg = msg.format(api_path, params)
-			utils.log_with_debug_info(logging.ERROR, msg)
-			raise ValueError(msg)
-
-		retval = compat.urljoin(self.api_base_url, new_api_path)
-
-		utils.log_with_debug_info(logging.DEBUG, u'Built end-point to return: {0}'.format(retval))
-
-		return retval
-
-	def _do_operation(self, operation, api_path, query_params=None, munchify=True, debug_response=False,
-					  expected_status_codes=(200, 204,), *args, **kwargs):
-		"""
-		Helper method to perform http operation requests - This is a boilerplate process for http operations
-		:param operation: Name of method to call on the self._session object to perform the http request
-		:type operation: Text
-		:param api_path: The path to the API end-point that you want to call which does not include the
-						 base url.  e.g. 'user/login', 'servers', etc.  This string can contain substitution
-						 parameters as denoted by a valid field_name replacement field specification as per
-						 str.format().
-							 E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-		:type api_path: Text
-		:param: query_params: URL query params to provide to the end-point.
-							  E.g. { 'sort': 'asc', 'maxresults': 200 }  which
-							  translates to something like '?sort=asc&maxresults=200' which
-							  is appended to the request URL
-		:type query_params: Union[Dict[Text, Any], None]
-		:param: munchify: If True encapsulate data to be returned in a munch.Munch object which allows
-						  keys in a Python dictionary to additionally have attribute access.
-							  E.g. a_dict['a_key'] with munch becomes a_dict['a_key'] or a_dict.a_key
-		:type munchify: bool
-		:param kwargs: Passed Keyword Parameters.  If you need to send JSON data to the endpoint pass the
-					   keyword parameter 'data' with the python data structure e.g. a dict.  This method
-					   will convert it to JSON before sending it to the API endpoint.
-		:type kwargs: Dict[Text, Any]
-		:param debug_response: If True, the actual response data text will be added to the log if a JSON decoding
-							   exception is encountered.
-		:type debug_response: bool
-		:type expected_status_codes: Tuple[int]
-		:param: expected_status_codes: expected success http status codes.  If the user needs to override
-									   the defaults this parameter can be passed.
-									   E.g. (200, 204,)
-		:type munchify: bool
-
-		:return: Python data structure distilled from JSON from the API request.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]], munch.Munch, List[munch.Munch]],
-					  requests.Response]
-		:raises: miscellaneous.exceptions.OperationError
-		"""
-
-		if not self._session:
-			msg = u'No session has been created for the API.  Have you called create() yet?'
-			utils.log_with_debug_info(logging.ERROR, msg)
-			raise OperationError(msg)
-
-		response = None
-		retdata = None
-
-		endpoint = self._build_endpoint(api_path, params=kwargs, query_params=query_params)
-
-		params = {
-			u'headers': self._headers,
-			u'verify': self._verify_cert,
-		}
-
-		if u'data' in kwargs:
-			params[u'data'] = json.dumps(kwargs[u'data'])
-
-		utils.log_with_debug_info(logging.DEBUG, u'Call parameters: {0}'.format(params))
-
-		# Call the API endpoint
-		response = getattr(self._session, operation)(endpoint, **params)
-
-		utils.log_with_debug_info(logging.DEBUG, u'Response status: {0} {1}'.format(response.status_code,
-								  response.reason))
-
-		if response.status_code not in expected_status_codes:
-			try:
-				retdata = response.json()
-			except Exception as e:
-				# Invalid JSON payload.
-				msg = (u'HTTP Status Code: [{0}]; API response data for end-point [{1}] does not '
-					   u'appear to be valid JSON. Cause: {2}.')
-				msg = msg.format(response.status_code, endpoint, e)
-				if debug_response:
-					utils.log_with_debug_info(logging.ERROR, msg + u' Data: [' + str(response.text) + u']')
-				raise InvalidJSONError(msg)
-			msg = u'{0} request to RESTful API at [{1}] expected status(s) {2}; failed: {3} {4}; Response: {5}'
-			msg = msg.format(operation.upper(), endpoint, expected_status_codes,
-							 response.status_code, response.reason, retdata)
-			utils.log_with_debug_info(logging.ERROR, msg)
-			raise OperationError(msg)
-
-		try:
-			if response.status_code in ('204',):
-				# "204 No Content"
-				retdata = {}
-			else:
-				# Decode the expected JSON
-				retdata = response.json()
-		except Exception as e:
-			# Invalid JSON payload.
-			msg = (u'HTTP Status Code: [{0}]; API response data for end-point [{1}] does not '
-				   u'appear to be valid JSON. Cause: {2}.')
-			msg = msg.format(response.status_code, endpoint, e)
-			if debug_response:
-				utils.log_with_debug_info(logging.ERROR, msg + u' Data: [' + str(response.text) + u']')
-			raise InvalidJSONError(msg)
-		retdata = munch.munchify(retdata) if munchify else retdata
-		return (retdata[u'response'] if u'response' in retdata else retdata), response
-
-	def get(self, api_path, *args, **kwargs):
-		"""
-		Perform http get requests
-		:param api_path: The path to the API end-point that you want to call which does not include the
-						 base url.  e.g. 'user/login', 'servers', etc.  This string can contain
-						 substitution parameters as denoted by a valid field_name replacement field
-						 specification as per str.format().
-						   E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-		:type api_path: Text
-		:param kwargs: Passed Keyword Parameters.  If you need to send JSON data to the endpoint pass the
-					   keyword parameter 'data' with the python data structure.  This method will convert it
-					   to JSON before sending it to the API endpoint. Use 'query_params' to pass a
-					   dictionary of query parameters
-		:type kwargs: Dict[Text, Any]
-		:return: Python data structure distilled from JSON from the API request.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]], munch.Munch,
-					  List[munch.Munch]], requests.Response]
-		:raises: Union[miscellaneous.exceptions.LoginError, miscellaneous.exceptions.OperationError]
-		"""
-
-		return self._do_operation(u'get', api_path, *args, **kwargs)
-
-	def post(self, api_path, *args, **kwargs):
-		"""
-		Perform http post requests
-		:param api_path: The path to the API end-point that you want to call which does not include the
-						 base url.  e.g. 'user/login', 'servers', etc.  This string can contain
-						 substitution parameters as denoted by a valid field_name replacement field
-						 specification as per str.format().
-						   E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-		:type api_path: Text
-		:param kwargs: Passed Keyword Parameters.  If you need to send JSON data to the endpoint pass the
-					   keyword parameter 'data' with the python data structure.  This method will convert it
-					   to JSON before sending it to the API endpoint. Use 'query_params' to pass a
-					   dictionary of query parameters
-		:type kwargs: Dict[Text, Any]
-		:return: Python data structure distilled from JSON from the API request.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]], munch.Munch,
-					  List[munch.Munch]], requests.Response]
-		:raises: Union[miscellaneous.exceptions.LoginError, miscellaneous.exceptions.OperationError]
-		"""
-
-		return self._do_operation(u'post', api_path, *args, **kwargs)
-
-	def put(self, api_path, *args, **kwargs):
-		"""
-		Perform http put requests
-		:param api_path: The path to the API end-point that you want to call which does not include the
-						 base url.  e.g. 'user/login', 'servers', etc.  This string can contain
-						 substitution parameters as denoted by a valid field_name replacement field
-						 specification as per str.format().
-						   E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-		:type api_path: Text
-		:param kwargs: Passed Keyword Parameters.  If you need to send JSON data to the endpoint pass the
-					   keyword parameter 'data' with the python data structure.  This method will convert it
-					   to JSON before sending it to the API endpoint. Use 'query_params' to pass a
-					   dictionary of query parameters
-		:type kwargs: Dict[Text, Any]
-		:return: Python data structure distilled from JSON from the API request.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]], munch.Munch,
-					  List[munch.Munch]], requests.Response]
-		:raises: Union[miscellaneous.exceptions.LoginError, miscellaneous.exceptions.OperationError]
-		"""
-
-		return self._do_operation(u'put', api_path, *args, **kwargs)
-
-	def delete(self, api_path, *args, **kwargs):
-		"""
-		Perform http delete requests
-		:param api_path: The path to the API end-point that you want to call which does not include the
-						 base url.  e.g. 'user/login', 'servers', etc.  This string can contain
-						 substitution parameters as denoted by a valid field_name replacement field
-						 specification as per str.format().
-		:type api_path: Text
-						   E.g. 'cachegroups/{id}' or 'cachegroups/{id:d}'
-		:param kwargs: Passed Keyword Parameters.  If you need to send JSON data to the endpoint pass the
-					   keyword parameter 'data' with the python data structure.  This method will convert it
-					   to JSON before sending it to the API endpoint. Use 'query_params' to pass a
-					   dictionary of query parameters
-		:type kwargs: Dict[Text, Any]
-		:return: Python data structure distilled from JSON from the API request.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]], munch.Munch,
-					  List[munch.Munch]], requests.Response]
-		:raises: Union[miscellaneous.exceptions.LoginError, miscellaneous.exceptions.OperationError]
-		"""
-
-		return self._do_operation(u'delete', api_path, *args, **kwargs)
diff --git a/traffic_control/clients/python/pylint.rc b/traffic_control/clients/python/pylint.rc
new file mode 100644
index 000000000..1ef22468c
--- /dev/null
+++ b/traffic_control/clients/python/pylint.rc
@@ -0,0 +1,485 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+[MASTER]
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code.
+extension-pkg-whitelist=
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Add files or directories matching the regex patterns to the blacklist. The
+# regex matches against base names, not paths.
+ignore-patterns=
+
+# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
+# number of processors available to use.
+jobs=0
+
+# Control the amount of potential inferred values when inferring a single
+# object. This can help the performance when dealing with large functions or
+# complex, nested conditions.
+limit-inference-results=100
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# When enabled, pylint would attempt to guess common misconfiguration and emit
+# user-friendly hints instead of false-positive error messages.
+suggestion-mode=yes
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once). You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use "--disable=all --enable=classes
+# --disable=W".
+disable=R0205,C0330,W0612
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+enable=c-extension-no-member
+
+
+[REPORTS]
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details.
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, json
+# and msvs (visual studio). You can also give a reporter class, e.g.
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Tells whether to display a full report or only the messages.
+reports=no
+
+# Activate the evaluation score.
+score=yes
+
+
+[REFACTORING]
+
+# Maximum number of nested blocks for function / method body
+max-nested-blocks=5
+
+# Complete name of functions that never returns. When checking for
+# inconsistent-return-statements if a never returning function is called then
+# it will be considered as an explicit return statement and no message will be
+# printed.
+never-returning-functions=sys.exit,exit
+
+
+[BASIC]
+
+# Naming style matching correct argument names.
+argument-naming-style=any
+
+# Regular expression matching correct argument names. Overrides argument-
+# naming-style.
+#argument-rgx=
+
+# Naming style matching correct attribute names.
+attr-naming-style=any
+
+# Regular expression matching correct attribute names. Overrides attr-naming-
+# style.
+#attr-rgx=
+
+# Bad variable names which should always be refused, separated by a comma.
+bad-names=foo,
+          bar,
+          baz,
+          toto,
+          tutu,
+          tata
+
+# Naming style matching correct class attribute names.
+class-attribute-naming-style=any
+
+# Regular expression matching correct class attribute names. Overrides class-
+# attribute-naming-style.
+#class-attribute-rgx=
+
+# Naming style matching correct class names.
+class-naming-style=PascalCase
+
+# Regular expression matching correct class names. Overrides class-naming-
+# style.
+#class-rgx=
+
+# Naming style matching correct constant names.
+const-naming-style=UPPER_CASE
+
+# Regular expression matching correct constant names. Overrides const-naming-
+# style.
+#const-rgx=
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=1
+
+# Naming style matching correct function names.
+function-naming-style=any
+
+# Regular expression matching correct function names. Overrides function-
+# naming-style.
+#function-rgx=
+
+# Good variable names which should always be accepted, separated by a comma.
+good-names=i,
+           j,
+           k,
+           ex,
+           _
+
+# Include a hint for the correct naming format with invalid-name.
+include-naming-hint=yes
+
+# Naming style matching correct inline iteration names.
+inlinevar-naming-style=any
+
+# Regular expression matching correct inline iteration names. Overrides
+# inlinevar-naming-style.
+#inlinevar-rgx=
+
+# Naming style matching correct method names.
+method-naming-style=any
+
+# Regular expression matching correct method names. Overrides method-naming-
+# style.
+#method-rgx=
+
+# Naming style matching correct module names.
+module-naming-style=snake_case
+
+# Regular expression matching correct module names. Overrides module-naming-
+# style.
+#module-rgx=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=^_
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+# These decorators are taken in consideration only for invalid-name.
+property-classes=abc.abstractproperty,property
+
+# Naming style matching correct variable names.
+variable-naming-style=any
+
+# Regular expression matching correct variable names. Overrides variable-
+# naming-style.
+#variable-rgx=
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid defining new builtins when possible.
+additional-builtins=
+
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables=no
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,_cb
+
+# A regular expression matching the name of dummy variables (i.e. expected to
+# not be used).
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore.
+ignored-argument-names=_.*|^ignored_|^unused_
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
+
+
+[LOGGING]
+
+# Format style used to check logging format string. `old` means using %
+# formatting, while `new` is for `{}` formatting.
+logging-format-style=new
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format.
+logging-modules=logging
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# Tells whether to warn about missing members when the owner of the attribute
+# is inferred to be None.
+ignore-none=yes
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference
+# can return multiple potential results while evaluating a Python object, but
+# some branches might not be evaluated, which results in partial inference. In
+# that case, it might be useful to still emit no-member and other checks for
+# the rest of the inferred objects.
+ignore-on-opaque-inference=yes
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis. It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# Show a hint with possible names when a member name was not found. The aspect
+# of finding the hint is based on edit distance.
+missing-member-hint=yes
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance=1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices=1
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,
+      TODO
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[FORMAT]
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=LF
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$|^\s*:\w+: .+$
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren=-1
+
+# String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1
+# tab).
+indent-string='\t'
+
+# Maximum number of characters on a single line.
+max-line-length=100
+
+# Maximum number of lines in a module.
+max-module-lines=1000
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=trailing-comma,
+			   dict-separator
+
+# Allow the body of a class to be on the same line as the declaration if body
+# contains single statement.
+single-line-class-stmt=no
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+
+[SPELLING]
+
+# Limits count of emitted suggestions for spelling mistakes.
+max-spelling-suggestions=4
+
+# Spelling dictionary name. Available dictionaries: none. To make it working
+# install python-enchant package..
+spelling-dict=
+
+# List of comma separated words that should not be checked.
+spelling-ignore-words=
+
+# A path to a file that contains private dictionary; one word per line.
+spelling-private-dict-file=
+
+# Tells whether to store unknown words to indicated private dictionary in
+# --spelling-private-dict-file option instead of raising a message.
+spelling-store-unknown-words=no
+
+
+[IMPORTS]
+
+# Allow wildcard imports from modules that define __all__.
+allow-wildcard-with-all=no
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+# Deprecated modules which should not be used, separated by a comma.
+deprecated-modules=optparse,tkinter.tix
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled).
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled).
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled).
+int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method.
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of boolean expressions in an if statement.
+max-bool-expr=5
+
+# Maximum number of branch for function / method body.
+max-branches=15
+
+# Maximum number of locals for function / method body.
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body.
+max-returns=6
+
+# Maximum number of statements in function / method body.
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,login,create
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,
+                  _fields,
+                  _replace,
+                  _source,
+                  _make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=cls
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception".
+overgeneral-exceptions=Exception,BaseException
diff --git a/traffic_control/clients/python/setup.py b/traffic_control/clients/python/setup.py
new file mode 100755
index 000000000..cec24977e
--- /dev/null
+++ b/traffic_control/clients/python/setup.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+Setuptools build/install script for the Python Traffic Control client
+"""
+
+import sys
+import os
+from setuptools import setup, find_packages
+from trafficops import __version__ as version
+
+HERE = os.path.abspath(os.path.dirname(__file__))
+
+with open(os.path.join(HERE, "README.rst")) as fd:
+	setup(
+	       name="Apache-TrafficControl",
+	       version=version,
+	       author="Apache Software Foundation",
+	       author_email="dev@trafficcontrol.apache.org",
+	       description="Python API Client for Traffic Control",
+	       long_description=fd.read(),
+	       url="http://trafficcontrol.apache.org/",
+	       license="http://www.apache.org/licenses/LICENSE-2.0",
+	       classifiers=[
+	           'Development Status :: 4 - Beta',
+	           'Intended Audience :: Developers',
+	           'Intended Audience :: Information Technology',
+	           'License :: OSI Approved :: Apache Software License',
+	           'Operating System :: OS Independent',
+	           'Programming Language :: Python :: 2.7',
+	           'Programming Language :: Python :: 3',
+	           'Programming Language :: Python :: 3.6',
+	           'Programming Language :: Python :: 3.7',
+	           'Programming Language :: Python :: 3.8',
+	           'Topic :: Database :: Front-Ends',
+	           'Topic :: Internet :: WWW/HTTP',
+	           'Topic :: Software Development :: Libraries :: Python Modules'
+	       ],
+	       keywords="Apache TrafficControl Traffic Control Client TrafficOps Ops",
+	       packages=find_packages(exclude=["contrib", "docs", "tests"]),
+	       install_requires=[
+	           "future>=0.16.0",
+	           "requests>=2.13.0",
+	           "munch>=2.1.1",
+	       ],
+	       extras_require={
+	           "dev": [
+	               "pylint"
+	           ]
+	       }
+	)
+
+if ((sys.version_info[0] == 2 and sys.version_info < (2, 7))
+   or (sys.version_info[0] == 3 and sys.version_info < (3, 6))):
+	MSG = ('WARNING: This library may not work properly with Python {0}, '
+		   'as it is untested for this version.')
+	print(MSG.format(sys.version.split(' ', 1)[0]))
diff --git a/traffic_control/clients/python/trafficops/README.txt b/traffic_control/clients/python/trafficops/README.txt
deleted file mode 100644
index f8843c943..000000000
--- a/traffic_control/clients/python/trafficops/README.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-- Introduction
-
-This directory contains the Traffic Ops Python Client for Python 2.x and Python 3.x.
-
-NOTE: This client has only been tested against Python 2.7 and Python 3.6.  Other versions
-      may work, so, you mileage may vary.
-
-- Installation
-
-NOTE: Assuming in a already newly created and activated virtualenv
-
-From github.com via pip:
-
-# pip install git+https://github.com/apache/trafficcontrol.git#"egg=trafficops&subdirectory=traffic_control/clients/python/trafficops"
-
-or
-
-# pip install git+ssh://git@github.com/apache/trafficcontrol.git#"egg=trafficops&subdirectory=traffic_control/clients/python/trafficops"
-
-Local Installation from cloned 'trafficcontrol' repository:
-
-NOTE: 'trafficcontrol' => https://www.github.com/apache/trafficcontrol
-
-NOTE: Assuming cd'd to the root of a forked/cloned 'trafficcontrol' repository
-
-    1. Activate your virtualenv environment (Python Virtual Environment)
-        E.g.
-            NOTE: Where <virtual environment directory> is, for example, '~/VENV/my_venv'.
-            $ source ~/VENV/my_venv/bin/activate
-            (my_venv) $
-    2. Install the software for the correct environment in the activated virtualenv
-        (my_venv) $ cd <root of 'trafficcontrol' repository>/traffic_control/clients/python/trafficops
-        (my_venv) $ python setup.py install
-        ...
-        (my_venv) $ cd <root of 'trafficcontrol' repository>
-    3. Test Package is installed correctly
-        (my_venv) $ python
-        (my_venv) $ Python 3.6.1 (default, Apr  4 2017, 09:40:21)
-                    [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)] on darwin
-                    Type "help", "copyright", "credits" or "license" for more information.
-                    >>> import trafficops
-                    >>> dir(trafficops)
-                    ['LoginError', 'OperationError', 'RestApiSession', 'TOSession', '__builtins__', '__cached__',
-                     '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__',
-                      '__version__', 'api_request', 'default_headers', 'restapi', 'tosession']
-                    >>> tos = trafficops.TOSession(host_ip=u'to.somedomain.net', verify_cert=True)
-                    >>> tos.login(u'someuser', u'someuser123')
-                    >>> cdns, response = tos.get_cdns()
-                    >>> exit()
-        (my_venv) $
-
-        NOTE: No errors/exceptions (warnings are okay) means you should be good to go.
diff --git a/traffic_control/clients/python/trafficops/trafficops/__init__.py b/traffic_control/clients/python/trafficops/__init__.py
similarity index 67%
rename from traffic_control/clients/python/trafficops/trafficops/__init__.py
rename to traffic_control/clients/python/trafficops/__init__.py
index 82a4c01f0..0131aa39b 100644
--- a/traffic_control/clients/python/trafficops/trafficops/__init__.py
+++ b/traffic_control/clients/python/trafficops/__init__.py
@@ -14,14 +14,16 @@
 # limitations under the License.
 #
 
-# Core Modules
-import logging
-
-logger = logging.getLogger(__name__)
-
 # Import Local Modules into the 'trafficops' package namespace for convenience.
-from common.restapi import *
-from trafficops.tosession import *
+from .tosession import TOSession
+from .restapi import InvalidJSONError, LoginError, OperationError, api_request, RestApiSession
+
+__all__ = [u'TOSession',
+           u'InvalidJSONError',
+           u'LoginError',
+           u'OperationError',
+           u'api_request',
+           u'RestApiSession']
 
 # The Module Version
-__version__ = '0.1.1'
+__version__ = '1.0.0'
diff --git a/traffic_control/clients/python/trafficops/common b/traffic_control/clients/python/trafficops/common
deleted file mode 120000
index 83323993b..000000000
--- a/traffic_control/clients/python/trafficops/common
+++ /dev/null
@@ -1 +0,0 @@
-../common/
\ No newline at end of file
diff --git a/traffic_control/clients/python/trafficops/restapi.py b/traffic_control/clients/python/trafficops/restapi.py
new file mode 100644
index 000000000..9320f399b
--- /dev/null
+++ b/traffic_control/clients/python/trafficops/restapi.py
@@ -0,0 +1,580 @@
+# -*- coding: utf-8 -*-
+
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+Module to help retrieve/create/update/delete data from/to any RESTful API (Base Class).
+
+Requires Python Version >= 2.7 or >= 3.6
+"""
+
+# Core Modules
+import json
+import logging
+import functools
+from builtins import str
+
+# Third-party Modules
+import munch
+import requests
+import requests.adapters as ra
+
+# Python 2 to Python 3 Compatibility
+import requests.compat as compat
+# Local Modules
+from .utils import log_with_debug_info
+
+
+try:
+	from future.utils import iteritems
+except ImportError:
+	iteritems = lambda x: x.items()
+
+__all__ = ['LoginError', 'OperationError', 'InvalidJSONError', 'api_request', 'RestApiSession',
+           'DEFAULT_HEADERS']
+
+LOGGER = logging.getLogger(__name__)
+
+# Exception Classes
+class LoginError(OSError):
+	"""
+	This represents an error that occurred during server login.
+	"""
+	def __init__(self, *args):
+		OSError.__init__(self, *args)
+
+
+class OperationError(IOError):
+	"""
+	This class represents a generic error, indicating something went wrong with the request or on
+	the server.
+	"""
+	def __init__(self, *args):
+		IOError.__init__(self, *args)
+
+
+class InvalidJSONError(ValueError):
+	"""
+	An error that occurs when an invalid JSON payload is passed to an endpoint.
+	"""
+	def __init__(self, *args):
+		ValueError.__init__(self, *args)
+
+# Miscellaneous Constants and/or Variables
+DEFAULT_HEADERS = {u'Content-Type': u'application/json; charset=UTF-8'}
+
+
+# Helper Functions/Decorators
+def api_request(method_name, api_path, supported_versions):
+	"""
+	This wrapper returns a decorator that routes the calls to the appropriate utility function that
+	generates the RESTful API endpoint, performs the appropriate call to the endpoint and returns
+	the data to the user.
+
+	:param method_name: A method name defined on the Class, this decorator is decorating, that will
+	                    be called to perform the operation. E.g. 'GET', 'POST', 'PUT', 'DELETE',
+	                    etc. The method_name chosen must have the signature of
+	                    ``<method>(self, api_path, **kwargs)`` e.g.
+	                    ``def get(self, api_path, **kwargs): ...``
+
+	:type method_name: str
+	:param api_path: The path to the API end-point that you want to call which does not
+	                 include the base url e.g. ``user/login``, ``servers``, etc. This string can
+	                 contain substitution parameters as denoted by a valid field_name replacement
+	                 field specification as per :meth:`str.format` e.g. ``cachegroups/{id}`` or
+	                 ``cachegroups/{id:d}``
+	:type api_path: str
+	:param supported_versions: A tuple of API versions that this route supports
+	:type supported_versions: Tuple[str]
+	:return: rtype int: A new function that replaces the original function with a boilerplate
+	                    execution process.
+	:rtype: Callable[str, Dict[str, Any]]
+	"""
+
+	def outer(func):
+		@functools.wraps(func)
+		def method_wrapper(self, *args, **kwargs):
+			# Positional arguments, e.g. *args, are not being used. Keyword arguments are the
+			# preferred way to pass the parameters needed by the helper functions
+			if (self.api_version is None) or (self.api_version in supported_versions):
+				msg = (u'Calling method [{0}] with keyword arguments [{1}] '
+				       u'via API endpoint method [{2}]')
+				log_with_debug_info(logging.DEBUG, msg.format(method_name, kwargs, func.__name__))
+
+				return getattr(self, method_name)(api_path, **kwargs)
+
+			# Client API version is not supported by the method being called
+			msg = (u"Method [{0}] is not supported by this client's API version [{1}]; "
+			       u'Supported versions: {2}')  # type: Text
+			msg = msg.format(func.__name__, self.api_version, supported_versions)
+			log_with_debug_info(logging.DEBUG, msg)
+			raise OperationError(msg)
+
+		return method_wrapper
+	return outer
+
+
+class RestApiSession(object):
+	"""
+	This class represents a login session with a generic REST API server. It provides base
+	functionality inherited by :class:`TOSession`.
+	"""
+	def __init__(self, host_ip, api_version=None, api_base_path=u'api/', host_port=443, ssl=True,
+	             headers=None, verify_cert=True, create_session=False, max_retries=5):
+		"""
+		The class initializer.
+		:param host_ip: The dns name or ip address of the RESTful API host to use to talk to the API
+		:type host_ip: str
+		:param host_port: The port to use when contacting the RESTful API
+		:type host_port: int
+		:param api_version: The version of the API to make calls against. If supplied, endpoint
+			version validation will be performed. If supplied as None, no version validation will be
+			performed. :const:`None` is allowed so that non-versioned REST APIs can be implemented.
+
+		:type api_version: Union[str, None]
+		:param api_base_path: The part of the url that is the base path, from the web server root
+			(which may include an API version), for all API endpoints without the server url portion
+			e.g. 'api/', 'api/1.2/'
+
+			.. note:: To specify the base path with the passed ``api_version`` you can specify
+				``api_base_path`` as ``api/{api_version}/`` and the API version will be substituted.
+				If ``api_version`` is :const:`None` and '{api_version}' is specified in the
+				``api_base_path`` string then an exception will be thrown.
+				e.g. api_version=u'1.2' -> 'api/{api_version}/' -> 'api/1.2/'
+				api_version=None   -> 'api/{api_version}/' -> Throws Exception
+
+		:type api_base_path: str
+		:param ssl: Should SSL be used? (http vs. https)
+		:type ssl: bool
+		:param headers: The HTTP headers to use when contacting the RESTful API
+		:type headers: Dict[str, str]
+		:param verify_cert: Should the SSL certificates be verified when contacting the RESTful API.
+			You may want to set this to :const:`False` for systems with self-signed certificates.
+
+		:type verify_cert: bool
+		:param create_session: Should a session be created automatically?
+		:type create_session: bool
+		"""
+		if headers is None:
+			headers = DEFAULT_HEADERS
+
+		self._session = None
+		self._host_ip = host_ip
+		self._host_port = host_port
+		self._api_version = api_version
+		self._api_base_path = api_base_path
+		self._ssl = ssl
+		self._headers = headers
+		self._verify_cert = verify_cert
+		self._create_session = create_session
+		self._max_retries = max_retries
+
+		# Setup API End-point Version validation, if enabled
+		self.__api_version_format_name = u'api_version'
+		self.__api_version_format_value = u'{{{0}}}'.format(self.__api_version_format_name)
+
+		if self._api_version:
+			# if api_base_path is supplied as 'api/{api_version}/' or some string
+			# containing '{api_version}' then try to substitute the api_version supplied
+			# by the user.
+
+			version_params = {
+				self.__api_version_format_name: self._api_version
+			}
+			self._api_base_path = self._api_base_path.format(**version_params)
+
+		if not self._api_version and self.__api_version_format_value in self._api_base_path:
+			msg = (u'{0} was specified in the API Base Path [{1}] '
+			       u'but the replacement did not occur because the API Version '
+			       u'was not supplied.')
+			msg = msg.format(self.__api_version_format_value, self._api_base_path)
+			log_with_debug_info(logging.ERROR, msg)
+			raise OperationError(msg)
+
+		# Setup some common URLs
+		self._server_url = u'{0}://{1}{2}/'.format(u'https' if ssl else u'http',
+		                                           host_ip,
+		                                           u':{0}'.format(host_port) if host_port else u'')
+		self._api_base_url = compat.urljoin(self._server_url, self._api_base_path)
+		self._api_base_url = self._api_base_url.rstrip(u'/') + u'/'
+
+
+		if not self._verify_cert:
+			# Not verifying certs so let's disable the warning
+			#pylint: disable=E1101
+			requests.packages.urllib3.disable_warnings(\
+			                            requests.packages.urllib3.exceptions.InsecureRequestWarning)
+			#pylint: enable=E1101
+			log_with_debug_info(logging.WARNING, u'Certificate verification warnings are disabled.')
+
+		msg = u'RestApiSession instance {0:#0x} initialized: Details: {1}'
+		log_with_debug_info(logging.DEBUG, msg.format(id(self), self.__dict__))
+
+		if self._create_session:
+			self.create()
+
+	@property
+	def is_open(self):
+		"""
+		Is the session open to the RESTful API? (Read-only Property)
+		:return: :const:`True` if yes, otherwise, :const:`False`
+		:rtype: bool
+		"""
+		return self._session is not None
+
+	@property
+	def session(self):
+		"""
+		The RESTful API session (Read-only Property)
+		:return: The requests session
+		:rtype: :class:`requests.Session`
+		"""
+		return self._session
+
+	def create(self):
+		"""
+		Create the requests.Session to communicate with the RESTful API.
+		:return: :const:`None`
+		:rtype: NoneType
+		"""
+		if self._session:
+			self.close()
+
+		if not self._session:
+			self._session = requests.Session()
+			self._session.mount('http://', ra.HTTPAdapter(max_retries=self._max_retries))
+			self._session.mount('https://', ra.HTTPAdapter(max_retries=self._max_retries))
+
+			msg = u'Created internal requests Session instance {0:#0x}'
+			log_with_debug_info(logging.DEBUG, msg.format(id(self._session)))
+
+	def close(self):
+		"""
+		Close and cleanup the requests Session object.
+		:return: :const:`None`
+		:rtype: NoneType
+		"""
+
+		if self._session:
+			sid = id(self._session)
+			self._session.close()
+			del self._session
+			self._session = None
+
+			msg = u'Internal requests Session instance 0x{0:x} closed and cleaned up'
+			log_with_debug_info(logging.DEBUG, msg.format(sid))
+
+	@property
+	def server_url(self):
+		"""
+		The URL without the api portion. (read-only)
+		:return: The URL should match '[\\w\\+\\-\\.]+://[\\w\\+\\-\\.]+(:\\d+)?'
+			e.g. 'https://to.somedomain.net' or 'https://to.somedomain.net:443'
+
+		:rtype: str
+		"""
+
+		return self._server_url
+
+	@property
+	def api_version(self):
+		"""
+		Returns the api version. (read-only)
+		:return: The api version from which this instance will request endpoints.
+		:rtype: str
+		"""
+
+		return self._api_version
+
+	@property
+	def api_base_url(self):
+		"""
+		Returns the base URL. (read-only)
+		:return: The base URL should match '[\\w\\+\\-\\.]+://[\\w\\+\\-\\.]+(:\\d+)?'
+			e.g. 'https://to.somedomain.net/api/0.1/'
+		:rtype: str
+		"""
+
+		return self._api_base_url
+
+	def _build_endpoint(self, api_path, params=None, query_params=None):
+		"""
+		Helper function to form API URL.
+		The base URL is '<protocol>://<hostname>[:<port>]/<api base url>'
+		e.g. 'https://to.somedomain.net/api/0.1/'
+		:param api_path: The path to the API end-point that you want to call which does not include
+			the base URL e.g. ``user/login``, ``servers``, etc. This string can contain substitution
+			parameters as denoted by a valid field_name replacement field specification as per
+			:meth:`str.format` e.g. ``cachegroups/{id}`` or ``cachegroups/{id:d}``
+
+		:type api_path: str
+		:param params: If :meth:`str.format` field_name replacement field specifications exists in
+			the ``api_path`` use this dictionary to perform replacements of the specifications with
+			the value(s) in the dictionary that match the parameter name(s) e.g. ``{param_id}`` or
+			``{param_id:d}`` in ``api_string`` is replaced by value in ``params['param_id']``.
+
+		:type params: Union[Dict[str, Any], None]
+		:param query_params: URL query params to provide to the end-point
+			e.g. ``{ 'sort': 'asc', 'maxresults': 200 }`` which translates to something like
+			``?sort=asc&maxresults=200`` which is appended to the request URL
+
+		:type query_params: Union[Dict[str, Any], None]
+		:return: The base url plus the passed and possibly substituted ``api_path`` to form a
+			complete URL to the API resource to request
+
+		:rtype: str
+		:raises: ValueError
+		"""
+
+		new_api_path = api_path
+
+		# Replace all parameters in the new_api_path path, if required
+		try:
+			# Make the parameters values safe for adding to URLs
+			url_params = {k: compat.quote(str(v)) if isinstance(v, str)\
+			                                      else v for k, v in iteritems(params)}
+
+			log_with_debug_info(logging.DEBUG, u'URL parameters are: [{0}]'.format(url_params))
+
+			qparams = u''
+			if query_params:
+				# Process the URL query parameters
+				qparams = u'?{0}'.format(compat.urlencode(query_params))
+				log_with_debug_info(logging.DEBUG,
+				                    u'URL query parameters are: [{0}]'.format(qparams))
+
+			new_api_path = api_path.format(**url_params) + qparams
+		except KeyError as e:
+			msg = (u'Expecting a value for keyword argument [{0}] for format field '
+			       u'specification [{1!r}]')
+			msg = msg.format(e, api_path)
+			log_with_debug_info(logging.ERROR, msg)
+			raise ValueError(msg)
+		except ValueError as e:
+			msg = (u'One or more values do not match the format field specification '
+			       u'[{0!r}]; Supplied values: {1!r} ')
+			msg = msg.format(api_path, params)
+			log_with_debug_info(logging.ERROR, msg)
+			raise ValueError(msg)
+
+		retval = compat.urljoin(self.api_base_url, new_api_path)
+
+		log_with_debug_info(logging.DEBUG, u'Built end-point to return: {0}'.format(retval))
+
+		return retval
+
+	def _do_operation(self,
+	                  operation, api_path, query_params=None, munchify=True, debug_response=False,
+	                  expected_status_codes=(200, 204,), *unused_args, **kwargs):
+		"""
+		Helper method to perform HTTP operation requests - This is a boilerplate process for HTTP
+		operations.
+
+		:param operation: Name of method to call on the :attr:`self._session` object to perform the
+			HTTP request
+
+		:type operation: str
+		:param api_path: The path to the API end-point that you want to call which does not include
+			the URL e.g. ``user/login``, ``servers``, etc. This string can contain substitution
+			parameters as denoted by a valid field_name replacement field specification as per
+			:meth:`str.format` e.g. ``cachegroups/{id}`` or ``cachegroups/{id:d}``
+
+		:type api_path: str
+		:param: query_params: URL query parameters to provide to the endpoint e.g.
+			``{ 'sort': 'asc', 'maxresults': 200 }`` which translates to something like
+			``?sort=asc&maxresults=200`` which is appended to the request URL
+
+		:type query_params: Union[Dict[str, Any], None]
+		:param: munchify: If :const:`True` encapsulate data to be returned in a :class:`munch.Munch`
+			object which allows keys in a Python dictionary to additionally have attribute access
+			e.g. ``a_dict['a_key']`` with :mod:`munch` becomes ``a_dict['a_key']`` or
+			``a_dict.a_key``
+
+		:type munchify: bool
+		:param kwargs: Passed Keyword Parameters. If you need to send JSON data to the endpoint pass
+			the keyword parameter ``data`` with the Python data structure e.g. a ``dict``. This
+			method will convert it to JSON before sending it to the API endpoint.
+
+		:type kwargs: Dict[str, Any]
+		:param debug_response: If :const:`True`, the actual response data text will be added to the
+			log if a JSON decoding exception is encountered.
+
+		:type debug_response: bool
+		:type expected_status_codes: Tuple[int]
+		:param: expected_status_codes: expected success HTTP status codes. If the user needs to
+			override the defaults this parameter can be passed e.g. ``(200, 204,)``
+
+		:type munchify: bool
+
+		:return: Python data structure distilled from JSON from the API request.
+		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]], munch.Munch, List[munch.Munch]],
+					  requests.Response]
+		:raises: miscellaneous.exceptions.OperationError
+		"""
+
+		if not self._session:
+			msg = u'No session has been created for the API.  Have you called create() yet?'
+			log_with_debug_info(logging.ERROR, msg)
+			raise OperationError(msg)
+
+		response = None
+		retdata = None
+
+		endpoint = self._build_endpoint(api_path, params=kwargs, query_params=query_params)
+
+		params = {u'headers': self._headers, u'verify': self._verify_cert}
+
+		if u'data' in kwargs:
+			params[u'data'] = json.dumps(kwargs[u'data'])
+
+		log_with_debug_info(logging.DEBUG, u'Call parameters: {0}'.format(params))
+
+		# Call the API endpoint
+		response = getattr(self._session, operation)(endpoint, **params)
+
+		log_with_debug_info(logging.DEBUG, u'Response status: {0} {1}'.format(response.status_code,
+		                    response.reason))
+
+		if response.status_code not in expected_status_codes:
+			try:
+				retdata = response.json()
+			except Exception as e:
+				# Invalid JSON payload.
+				msg = (u'HTTP Status Code: [{0}]; API response data for end-point [{1}] does not '
+				       u'appear to be valid JSON. Cause: {2}.')
+				msg = msg.format(response.status_code, endpoint, e)
+				if debug_response:
+					log_with_debug_info(logging.ERROR, msg + u' Data: [' + str(response.text) + u']')
+				raise InvalidJSONError(msg)
+			msg = u'{0} request to RESTful API at [{1}] expected status(s) {2}; failed: {3} {4};'\
+			      u' Response: {5}'
+			msg = msg.format(operation.upper(), endpoint, expected_status_codes,
+			                 response.status_code, response.reason, retdata)
+			log_with_debug_info(logging.ERROR, msg)
+			raise OperationError(msg)
+
+		try:
+			if response.status_code in ('204',):
+				# "204 No Content"
+				retdata = {}
+			else:
+				# Decode the expected JSON
+				retdata = response.json()
+		except Exception as e:
+			# Invalid JSON payload.
+			msg = (u'HTTP Status Code: [{0}]; API response data for end-point [{1}] does not '
+			       u'appear to be valid JSON. Cause: {2}.')
+			msg = msg.format(response.status_code, endpoint, e)
+			if debug_response:
+				log_with_debug_info(logging.ERROR, msg + u' Data: [' + str(response.text) + u']')
+			raise InvalidJSONError(msg)
+		retdata = munch.munchify(retdata) if munchify else retdata
+		return (retdata[u'response'] if u'response' in retdata else retdata), response
+
+	def get(self, api_path, *args, **kwargs):
+		"""
+		Perform http get requests
+		:param api_path: The path to the API end-point that you want to call which does not include
+			the base url e.g. ``user/login``, ``servers``, etc. This string can contain substitution
+			parameters as denoted by a valid field_name replacement field specification as per
+			:meth:`str.format` e.g. ``cachegroups/{id}`` or ``cachegroups/{id:d}``
+
+		:type api_path: str
+		:param kwargs: Passed Keyword Parameters. If you need to send JSON data to the endpoint pass
+			the keyword parameter ``data`` with the Python data structure. This method will convert
+			it to JSON before sending it to the API endpoint. Use ``query_params`` to pass a
+			dictionary of query parameters
+
+		:type kwargs: Dict[str, Any]
+		:return: Python data structure distilled from JSON from the API request.
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]], munch.Munch, List[munch.Munch]],
+			requests.Response]
+
+		:raises: Union[LoginError, OperationError]
+		"""
+
+		return self._do_operation(u'get', api_path, *args, **kwargs)
+
+	def post(self, api_path, *args, **kwargs):
+		"""
+		Perform http post requests
+		:param api_path: The path to the API end-point that you want to call which does not include
+			the base URL e.g. ``user/login``, ``servers``, etc. This string can contain substitution
+			parameters as denoted by a valid field_name replacement field specification as per
+			:meth:`str.format` e.g. ``cachegroups/{id}`` or ``cachegroups/{id:d}``
+
+		:type api_path: str
+		:param kwargs: Passed Keyword Parameters. If you need to send JSON data to the endpoint pass
+			the keyword parameter ``data`` with the Python data structure. This method will convert
+			it to JSON before sending it to the API endpoint. Use ``query_params`` to pass a
+			dictionary of query parameters
+
+		:type kwargs: Dict[str, Any]
+		:return: Python data structure distilled from JSON from the API request.
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]], munch.Munch, List[munch.Munch]],
+			requests.Response]
+
+		:raises: Union[LoginError, OperationError]
+		"""
+
+		return self._do_operation(u'post', api_path, *args, **kwargs)
+
+	def put(self, api_path, *args, **kwargs):
+		"""
+		Perform http put requests
+		:param api_path: The path to the API end-point that you want to call which does not include
+			the base URL e.g. ``user/login``, ``servers``, etc. This string can contain substitution
+			parameters as denoted by a valid field_name replacement field specification as per
+			:meth:`str.format` e.g. ``cachegroups/{id}`` or ``cachegroups/{id:d}``
+
+		:type api_path: str
+		:param kwargs: Passed Keyword Parameters. If you need to send JSON data to the endpoint pass
+			the keyword parameter ``data`` with the Python data structure. This method will convert
+			it to JSON before sending it to the API endpoint. Use ``query_params`` to pass a
+			dictionary of query parameters
+
+		:type kwargs: Dict[str, Any]
+		:return: Python data structure distilled from JSON from the API request.
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]], munch.Munch, List[munch.Munch]],
+			requests.Response]
+
+		:raises: Union[LoginError, OperationError]
+		"""
+
+		return self._do_operation(u'put', api_path, *args, **kwargs)
+
+	def delete(self, api_path, *args, **kwargs):
+		"""
+		Perform HTTP DELETE requests
+		:param api_path: The path to the API end-point that you want to call which does not include
+			the base URL e.g. ``user/login``, ``servers``, etc. This string can contain substitution
+			parameters as denoted by a valid field_name replacement field specification as per
+			:meth:`str.format` e.g. ``cachegroups/{id}`` or ``cachegroups/{id:d}``
+
+		:type api_path: str
+		:param kwargs: Passed Keyword Parameters. If you need to send JSON data to the endpoint pass
+			the keyword parameter ``data`` with the Python data structure. This method will convert
+			it to JSON before sending it to the API endpoint. Use ``query_params`` to pass a
+			dictionary of query parameters
+
+		:type kwargs: Dict[str, Any]
+		:return: Python data structure distilled from JSON from the API request.
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]], munch.Munch, List[munch.Munch]],
+			requests.Response]
+
+		:raises: Union[LoginError, OperationError]
+		"""
+
+		return self._do_operation(u'delete', api_path, *args, **kwargs)
diff --git a/traffic_control/clients/python/trafficops/setup.py b/traffic_control/clients/python/trafficops/setup.py
deleted file mode 100755
index e37a3bb21..000000000
--- a/traffic_control/clients/python/trafficops/setup.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-import sys
-
-from setuptools import setup
-
-version = ''
-for line in open('trafficops/__init__.py').readlines():
-    if '__version__' in line:
-        version = line.split('=')[-1].strip().strip("'")
-        break
-
-setup(
-    name='TrafficOps',
-    version=version,
-    author='Apache Software foundation',
-    author_email='dev@trafficcontrol.apache.org',
-    packages=['common', 'trafficops'],
-    url='http://trafficcontrol.apache.org/',
-    license='http://www.apache.org/licenses/LICENSE-2.0',
-    description='Python API Client for Traffic Ops',
-    long_description=open('README.txt').read(),
-    install_requires=[
-        "future>=0.16.0",
-        "requests>=2.13.0",
-        "munch>=2.1.1",
-    ],
-)
-
-if ((sys.version_info[0] == 2 and sys.version_info < (2, 7))
-   or (sys.version_info[0] == 3 and sys.version_info < (3, 6))):
-    msg = ('WARNING: This library may not work properly with Python {0}, '
-           'as it is untested for this version.')
-    print(msg.format(sys.version.split(' ', 1)[0]))
diff --git a/traffic_control/clients/python/trafficops/tosession.py b/traffic_control/clients/python/trafficops/tosession.py
new file mode 100644
index 000000000..c7db7fe6a
--- /dev/null
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -0,0 +1,2698 @@
+# -*- coding: utf-8 -*-
+
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+Module to help create/retrieve/update/delete data from/to the Traffic Ops API.
+
+Requires Python Version >= 2.7 or >= 3.6
+"""
+
+# Core Modules
+import logging
+import sys
+
+# Third-party Modules
+import munch
+from future.utils import raise_from
+import requests.exceptions as rex
+
+# Local Modules
+from .restapi import LoginError, OperationError, api_request, RestApiSession
+from .utils import log_with_debug_info
+
+__all__ = ['TOSession']
+
+LOGGER = logging.getLogger(__name__)
+
+class TOSession(RestApiSession):
+	"""
+	Traffic Ops Session Class
+	Once you login to the Traffic Ops API via :meth:`login`, you can call one or more of the methods
+	to retrieve, POST, PUT, DELETE, etc. data to the API.  If you are not logged in, an	exception
+	will be thrown if you try to call any of the endpoint methods. This API client is simplistic and
+	lightly structured on purpose but adding support for new endpoints routinely takes seconds.
+	Another nice bit of convenience that result data is, by default, wrapped in	:class:`munch.Munch`
+	objects, which provide attribute access to the returned dictionaries/hashes - e.g.
+	``a_dict['a_key']`` with :mod:`munch` becomes ``a_dict.a_key`` or ``a_dict['a_key']``. Also, the
+	lack of rigid structure (loose coupling) means many changes to the Traffic Ops API,	as it
+	evolves, will probably go un-noticed (usually additions), which means fewer	future problems to
+	potentially fix in user applications.
+
+	An area of improvement for later is defining classes to represent request data instead
+	of loading up dictionaries for request data.
+
+	Please see the :ref:`API documentation <to-api>` for the details of the API endpoints.
+
+	Adding end-point methods
+
+	.. code-block:: python3
+		:caption: Endpoint with no URL parameters and no query parameters
+
+		@api_request(u'get', u'cdns', (u'1.1', u'1.2',))
+		def get_cdns(self):
+			pass
+
+
+	.. caption:: python3
+		:caption: End-point with URL parameters and no query parameters
+
+		@api_request(u'get', u'cdns/{cdn_id:d}', (u'1.1', u'1.2',))
+		def get_cdn_by_id(self, cdn_id=None):
+			pass
+
+
+	.. caption:: python3
+		:caption: End-point with no URL parameters but with query parameters
+
+		@api_request(u'get', u'deliveryservices', (u'1.1', u'1.2',))
+		def get_deliveryservices(self, query_params=None):
+			pass
+
+	.. caption:: python3
+		:caption: End-point with URL parameters and query parameters
+
+		@api_request(u'get', u'deliveryservices/xmlId/{xml_id}/sslkeys', (u'1.1', u'1.2',))
+		def get_deliveryservice_ssl_keys_by_xml_id(self, xml_id=None, query_params=None):
+			pass
+
+	.. caption:: python3
+		:caption: End-point with request data
+
+		@api_request(u'post', u'cdns', (u'1.1', u'1.2',))
+		def create_cdn(self, data=None):
+			pass
+
+	.. caption:: python3
+		:caption: End-point with URL parameters and request data
+
+		@api_request(u'put', u'cdns', (u'1.1', u'1.2',))
+		def update_cdn_by_id(self, cdn_id=None, data=None):
+			pass
+
+	Calling end-point methods
+
+	:meth:`get_cdns` calls endpoint :ref:`to-api-cdns` e.g. ``t.get_cdns()``
+
+	:meth:`get_types` calls endpoint :ref:`to-api-types`, optionally with query parameters e.g.
+
+	``get_types(query_params={'useInTable': 'servers'})``
+	``get_foo_data(id=45, query_params={'sort': 'asc'})`` calls endpoint
+	``GET api/1.x/foo/45?sort=asc`` (presumably)
+
+	:meth:`cdns_queue_update` calls endpoint :ref:`to-api-cdns-name-queue_update`, with an ID path
+	parameter and a JSON payload e.g. ``cdns_queue_update(id=1, data={'action': 'queue'})``
+
+	.. note:: Only a small subset of the API endpoints are implemented. More can be implemented as
+		needed.
+	"""
+
+	def __init__(self, host_ip, host_port=443, api_version=u'1.3', ssl=True, headers=None,
+	             verify_cert=True):
+		"""
+		The class initializer.
+		:param host_ip: The dns name or ip address of the Traffic Ops host to use to talk to the API
+		:type host_ip: str
+		:param host_port: The port to use when contacting the Traffic Ops API
+		:type host_port: int
+		:param api_version: The version of the API to use when calling end-points on the Traffic Ops API
+		:type api_version: str
+		:param ssl: Should ssl be used? (http vs. https)
+		:type ssl: bool
+		:param headers:  The http headers to use when contacting the Traffic Ops API
+		:type headers: Dict[str, str]
+		:type verify_cert: bool
+		"""
+		super(TOSession, self).__init__(host_ip=host_ip, api_version=api_version,
+		                                api_base_path=u'api/{api_version}/',
+		                                host_port=host_port, ssl=ssl, headers=headers,
+		                                verify_cert=verify_cert)
+
+		self._logged_in = False
+
+		msg = u'TOSession instance {0:#0x} initialized: Details: {1}'
+		log_with_debug_info(logging.DEBUG, msg.format(id(self), self.__dict__))
+
+	def login(self, username, password):
+		"""
+		Login to the Traffic Ops API.
+		:param username: Traffic Ops User Name
+		:type username: str
+		:param password: Traffic Ops User Password
+		:type password: str
+		:return: None
+		:rtype: None
+		:raises: LoginError
+		"""
+		logging.info("Connecting to Traffic Ops at %s...", self.to_url)
+
+		if not self.is_open:
+			self.create()
+
+		logging.info("Connected. Authenticating...")
+
+		self._logged_in = False
+		try:
+			# Try to login to Traffic Ops
+			self.post(u'user/login', data={u'u': username, u'p': password})
+			self._logged_in = True
+		except rex.SSLError as e:
+			logging.debug("%s", e, stack_info=True, exc_info=True)
+			self.close()
+			msg = (u'{0}.  This system may have a self-signed certificate.  Try creating this'\
+			       u' TOSession object passing verify_cert=False. e.g. TOSession(..., '\
+			       u'verify_cert=False).')
+			msg = msg.format(e)
+			logging.error(msg)
+			logging.warning("disabling certificate verification is not recommended.")
+			raise_from(LoginError(msg), e)
+		except OperationError as e:
+			logging.debug("%s", e, exc_info=True, stack_info=True)
+			msg = u'Logging in to Traffic Ops has failed. Reason: {0}'.format(e)
+			self.close()
+			logging.error(msg)
+			raise_from(OperationError(msg), e)
+
+		logging.info("Authenticated.")
+
+	@property
+	def to_url(self):
+		"""
+		The URL without the api portion. (read-only)
+		:return: The URL should match '[\\w\\+\\-\\.]+://[\\w\\+\\-\\.]+(:\\d+)?' e.g
+			https://to.somedomain.net or https://to.somedomain.net:443
+
+		:rtype: str
+		"""
+
+		return self.server_url
+
+	@property
+	def base_url(self):
+		"""
+		Returns the base url. (read-only)
+		:return: The base url should match '[\\w\\+\\-\\.]+://[\\w\\+\\-\\.]+(:\\d+)?' e.g
+			https://to.somedomain.net/api/1.2/
+
+		:rtype: str
+		"""
+
+		return self._api_base_url
+
+	@property
+	def logged_in(self):
+		"""
+		Read-only property of to determine if user is logged in to Traffic Ops.
+		:return: :const:`True` if connected and logged in, :const:`False` otherwise
+		:rtype: bool
+		"""
+
+		return self.is_open and self._logged_in
+
+	# Programmatic Endpoint Methods - These can be created when you need to employ "creative
+	# methods" to form a correlated composite data set from one or more Traffic Ops API call(s) or
+	# employ composite operations against the API.
+	# Also, if the API requires you to retrieve the data via paging, these types of methods can be
+	# useful to perform that type of work too.
+	# These methods need to support similar method signatures as employed by the restapi.api_request
+	# decorator method_name argument.
+	def get_all_deliveryservice_servers(self, *args, **kwargs):
+		"""
+		Get all servers attached to all delivery services via the Traffic Ops API.
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+		result_set = []
+		resp = None
+		limit = 10000
+		page = 1
+
+		munchify = True  # Default to True
+		if u'munchify' in kwargs:
+			munchify = kwargs[u'munchify']
+
+		while True:
+			data, resp = self.get_deliveryserviceserver(query_params={u'limit':limit, u'page': page},
+			                                           *args, **kwargs)
+
+			if not data:
+				break
+
+			result_set.extend(munch.munchify(data) if munchify else data)
+			page += 1
+
+		return result_set, resp  # Note: Return last response object received
+
+#
+# PUT ALL API DEFINITIONS BELOW AND UNDER ITS RESPECTIVE PAGE (whether it is 1.2 or 1.3, etc, if its
+# a CDN put it under CDN header and corresponding calls)
+#
+
+	#
+	#	API Capabilities
+	#
+	@api_request(u'get', u'api_capabilities', (u'1.2', u'1.3',))
+	def get_api_capabilities(self, query_params=None):
+		"""
+		Get all API-capability mappings
+		:ref:`to-api-api_capabilities`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'api_capabilities/{id}', (u'1.2', u'1.3',))
+	def get_api_capabilities_by_id(self, id=None):
+		"""
+		Get an API-capability mapping by ID
+		:ref:`to-api-api_capabilities-id`
+		:param id: The api-capabilities Id
+		:type id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# ASN
+	#
+	@api_request(u'get', u'asns', (u'1.1', u'1.2', u'1.3',))
+	def get_asns(self, query_params=None):
+		"""
+		Get ASNs.
+		:ref:`to-api-asns`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'asns/{asn_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_asn_by_id(self, asn_id=None):
+		"""
+		Get ASN by ID
+		:ref:`to-api-asns-id`
+		:param asn_id: The ID of the ASN to retrieve
+		:type asn_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'asns/{asn_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_asn(self, asn_id=None, query_params=None):
+		"""
+		Update ASN
+		:ref:`to-api-asns-id`
+		:param asn_id: The ID of the ASN to update
+		:type asn_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'asns', (u'1.1', u'1.2', u'1.3',))
+	def create_asn(self, data=None):
+		"""
+		Create ASN
+		:ref:`to-api-asns`
+		:param data: The parameter data to use for cachegroup creation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'asns/{asn_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_asn(self, asn_id=None):
+		"""
+		Delete ASN
+		:to-api-asns-id:
+		:param asn_id: The ID of the ASN to delete
+		:type asn_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Cache Stats
+	#
+	@api_request(u'get', u'caches/stats', (u'1.1', u'1.2', u'1.3',))
+	def get_traffic_monitor_cache_stats(self):
+		"""
+		Retrieves cache stats from Traffic Monitor. Also includes rows for aggregates
+		:ref:`to-api-caches-stats`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Cache Group
+	#
+	@api_request(u'get', u'cachegroups', (u'1.1', u'1.2', u'1.3',))
+	def get_cachegroups(self, query_params=None):
+		"""
+		Get Cache Groups.
+		:ref:`to-api-cachegroups`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	# Example of URL parameter substitution via call parameter. You will need to pass the parameter
+	# value as a keyword parameter with the proper type to match the str.format specification,
+	# e.g. 'cachegroups/{cache_group_id:d}'.  In this case, ':d' specifies a decimal integer. A
+	# specification of 'cachegroups/{cache_group_id}' will try to convert any value passed to a
+	# string, which basically does no type checking, unless of course the value cannot be cast to a
+	# string e.g. get_cachegroups_by_id(cache_group_id=23) -> call end-point .../api/1.2/cachegroups/23
+	@api_request(u'get', u'cachegroups/{cache_group_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_cachegroup_by_id(self, cache_group_id=None):
+		"""
+		Get a Cache Group by Id.
+		:ref:`to-api-cachegroups-id`
+		:param cache_group_id: The cache group Id
+		:type cache_group_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cachegroups/{cache_group_id:d}/parameters', (u'1.1', u'1.2', u'1.3',))
+	def get_cachegroup_parameters(self, cache_group_id=None):
+		"""
+		Get a cache groups parameters
+		:ref:`to-api-cachegroups-id-parameters`
+		:param cache_group_id: The cache group Id
+		:type cache_group_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cachegroups/{cache_group_id:d}/unassigned_parameters',
+	             (u'1.1', u'1.2', u'1.3'))
+	def get_cachegroup_unassigned_parameters(self, cache_group_id=None):
+		"""
+		Get a cache groups unassigned parameters
+		:ref:`to-api-cachegroups-id-unassigned_parameters`
+		:param cache_group_id: The cache group Id
+		:type cache_group_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cachegroup/{parameter_id:d}/parameter', (u'1.1', u'1.2', u'1.3',))
+	def get_cachegroup_parameters_by_id(self, parameter_id=None):
+		"""
+		Get a cache groups parameter by its ID
+		:ref:`to-api-cachegroup-parameterID-parameter`
+		:param parameter_id: The parameter Id
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cachegroupparameters', (u'1.1', u'1.2', u'1.3',))
+	def get_all_cachegroup_parameters(self):
+		"""
+		A collection of all cache group parameters.
+		:ref:`to-api-cachegroupparameters`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'cachegroups', (u'1.1', u'1.2', u'1.3',))
+	def create_cachegroups(self, data=None):
+		"""
+		Create a Cache Group
+		:ref:`to-api-cachegroups`
+		:param data: The parameter data to use for cachegroup creation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'cachegroups/{cache_group_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_cachegroups(self, cache_group_id=None, data=None):
+		"""
+		Update a cache group
+		:ref:`to-api-cachegroups-id`
+		:param cache_group_id: The cache group id to update
+		:type cache_group_id: Integer
+		:param data: The parameter data to use for cachegroup creation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'cachegroups/{cache_group_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_cachegroups(self, cache_group_id=None):
+		"""
+		Delete a cache group
+		:ref:`to-api-cachegroups-id`
+		:param cache_group_id: The cache group id to update
+		:type cache_group_id: Integer
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'cachegroups/{cache_group_id:d}/queue_update', (u'1.1', u'1.2', u'1.3',))
+	def cachegroups_queue_update(self, cache_group_id=None, data=None):
+		"""
+		Queue Updates by Cache Group ID
+		:ref:`to-api-cachegroups-id-queue_update`
+		:param cache_group_id: The Cache Group Id
+		:type cache_group_id: int
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'cachegroupparameters/{cache_group_id:d}/{parameter_id:d}',
+	             (u'1.2', u'1.3'))
+	def delete_cache_group_parameters(self, cache_group_id=None, parameter_id=None):
+		"""
+		Delete a cache group parameter association
+		:ref:`to-api-cachegroupparameters-id-parameterID`
+		:param cache_group_id: The cache group id in which the parameter will be deleted
+		:type cache_group_id: int
+		:param parameter_id: The parameter id which will be disassociated
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Cache Group Fallback
+	#
+	@api_request(u'get', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
+	def get_cache_group_fallbacks(self, query_params=None):
+		"""
+		Retrieve fallback related configurations for a cache group
+		:ref:`to-api-cachegroup_fallbacks`
+		:param query_params: Either cacheGroupId or fallbackId must be used or can be used
+			simultaneously
+
+		:type query_params: Dict[str, int]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
+	def create_cache_group_fallbacks(self, data=None):
+		"""
+		Creates fallback configuration for the cache group. New fallbacks can be added only via POST.
+		:ref:`to-api-cachegroup_fallbacks`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
+	def update_cache_group_fallbacks(self, data=None):
+		"""
+		Updates an existing fallback configuration for the cache group.
+		:ref:`to-api-cachegroup_fallbacks`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
+	def delete_cache_group_fallbacks(self, query_params=None):
+		"""
+		Deletes an existing fallback related configurations for a cache group
+		:ref:`to-api-cachegroup_fallbacks`
+		:param query_params: Either cacheGroupId or fallbackId must be used or can be used
+			simultaneously
+
+		:type query_params: Dict[str, int]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Cache Statistics
+	#
+	@api_request(u'get', u'cache_stats', (u'1.2', u'1.3',))
+	def get_cache_stats(self, query_params=None):
+		"""
+		Retrieves statistics about the CDN.
+		:ref:`to-api-cache_stats`
+		:param query_params: See API page for more information on accepted params
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN
+	#
+	@api_request(u'get', u'cdns', (u'1.1', u'1.2', u'1.3',))
+	def get_cdns(self):
+		"""
+		Get all CDNs.
+		:ref:`to-api-cdns`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/{cdn_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_cdn_by_id(self, cdn_id=None):
+		"""
+		Get a CDN by Id.
+		:ref:`to-api-cdns-id`
+		:param cdn_id: The CDN id
+		:type cdn_id: str
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/name/{cdn_name}', (u'1.1', u'1.2', u'1.3',))
+	def get_cdn_by_name(self, cdn_name=None):
+		"""
+		Get a CDN by name.
+		:ref:`to-api-cdns-name-name`
+		:param cdn_name: The CDN name
+		:type cdn_name: str
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'cdns', (u'1.1', u'1.2', u'1.3',))
+	def create_cdn(self, data=None):
+		"""
+		Create a new CDN.
+		:ref:`to-api-cdns`
+		:param data: The parameter data to use for cdn creation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'cdns/{cdn_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_cdn_by_id(self, cdn_id=None, data=None):
+		"""
+		Update a CDN by Id.
+		:ref:`to-api-cdns-id`
+		:param cdn_id: The CDN id
+		:type cdn_id: int
+		:param data: The parameter data to use for cdn update.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'cdns/{cdn_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_cdn_by_id(self, cdn_id=None):
+		"""
+		Delete a CDN by Id.
+		:ref:`to-api-cdns-id`
+		:param cdn_id: The CDN id
+		:type cdn_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'cdns/{cdn_id:d}/queue_update', (u'1.1', u'1.2', u'1.3',))
+	def cdns_queue_update(self, cdn_id=None, data=None):
+		"""
+		Queue Updates by CDN Id.
+		:ref:`to-api-cdns-id-queue_update`
+		:param cdn_id: The CDN Id
+		:type cdn_id: int
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN Health
+	#
+	@api_request(u'get', u'cdns/health', (u'1.2', u'1.3',))
+	def get_cdns_health(self):
+		"""
+		Retrieves the health of all locations (cache groups) for all CDNs
+		:ref:`to-api-cdns-health`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'get', u'cdns/{cdn_name:s}/health', (u'1.2', u'1.3',))
+	def get_cdn_health_by_name(self, cdn_name=None):
+		"""
+		Retrieves the health of all locations (cache groups) for a given CDN
+		:ref:`to-api-cdns-name-health`
+		:param cdn_name: The CDN name to find health for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/usage', (u'1.2', u'1.3',))
+	def get_cdns_usage(self):
+		"""
+		Retrieves the high-level CDN usage metrics.
+		:ref:`to-api-cdns-usage`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/capacity', (u'1.2', u'1.3',))
+	def get_cdns_capacity(self):
+		"""
+		Retrieves the aggregate capacity percentages of all locations (cache groups) for a given CDN.
+		:ref:`to-api-cdns-capacity`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN Routing
+	#
+	@api_request(u'get', u'cdns/routing', (u'1.2', u'1.3',))
+	def get_cdns_routing(self):
+		"""
+		Retrieves the aggregate routing percentages of all locations (cache groups) for a given CDN.
+		:ref:`to-api-cdns-routing`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN Domains
+	#
+	@api_request(u'get', u'cdns/domains', (u'1.2', u'1.3',))
+	def get_cdns_domains(self):
+		"""
+		Retrieves the different CDN domains
+		:ref:`to-api-cdns-domains`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN Topology
+	#
+	@api_request(u'get', u'cdns/{cdn_name:s}/configs', (u'1.2', u'1.3',))
+	def get_cdn_config_info(self, cdn_name=None):
+		"""
+		Retrieves CDN config information
+		:ref:`to-api-cdns-name-configs`
+		:param cdn_name: The CDN name to find configs for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/{cdn_name:s}/configs/monitoring', (u'1.2', u'1.3',))
+	def get_cdn_monitoring_info(self, cdn_name=None):
+		"""
+		Retrieves CDN monitoring information
+		:ref:`to-api-cdns-name-configs-monitoring`
+		:param cdn_name: The CDN name to find configs for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/{cdn_name:s}/configs/routing', (u'1.2', u'1.3',))
+	def get_cdn_routing_info(self, cdn_name=None):
+		"""
+		Retrieves CDN routing information
+		:ref:`to-api-cdns-name-configs-routing`
+		:param cdn_name: The CDN name to find routing info for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN DNSSEC Keys
+	#
+	@api_request(u'get', u'cdns/name/{cdn_name:s}/dnsseckeys', (u'1.2', u'1.3',))
+	def get_cdn_dns_sec_keys(self, cdn_name=None):
+		"""
+		Gets a list of dnsseckeys for a CDN and all associated Delivery Services
+		:ref:`to-api-cdns-name--name-dnsseckeys`
+		:param cdn_name: The CDN name to find dnsseckeys info for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/name/{cdn_name:s}/dnsseckeys/delete', (u'1.2', u'1.3',))
+	def delete_cdn_dns_sec_keys(self, cdn_name=None):
+		"""
+		Delete dnssec keys for a cdn and all associated delivery services
+		:ref:`to-api-cdns-name-name-dnsseckeys-delete`
+		:param cdn_name: The CDN name to delete dnsseckeys info for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'deliveryservices/dnsseckeys/generate', (u'1.2', u'1.3',))
+	def create_cdn_dns_sec_keys(self, data=None):
+		"""
+		Generates ZSK and KSK keypairs for a CDN and all associated Delivery Services
+		:ref:`to-api-deliveryservices-dnsseckeys-generate`
+		:param data: The parameter data to use for cachegroup creation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# CDN SSL Keys
+	#
+	@api_request(u'get', u'cdns/name/{cdn_name:s}/sslkeys', (u'1.2', u'1.3',))
+	def get_cdn_ssl_keys(self, cdn_name=None):
+		"""
+		Returns ssl certificates for all Delivery Services that are a part of the CDN.
+		:ref:`to-api-cdns-name-name-sslkeys`
+		:param cdn_name: The CDN name to find ssl keys for
+		:type cdn_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Change Logs
+	# https://traffic-control-cdn.readthedocs.io/en/latest/api/changelog.html#change-logs
+	#
+
+	@api_request(u'get', u'logs', (u'1.2', u'1.3',))
+	def get_change_logs(self):
+		"""
+		Retrieve all change logs from traffic ops
+		:ref:`to-api-logs`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'logs/{days:d}/days', (u'1.2', u'1.3',))
+	def get_change_logs_for_days(self, days=None):
+		"""
+		Retrieve all change logs from Traffic Ops
+		:ref:`to-api-logs-days-days`
+		:param days: The number of days to retrieve change logs
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'logs/newcount', (u'1.2', u'1.3',))
+	def get_change_logs_newcount(self):
+		"""
+		Get amount of new logs from traffic ops
+		:ref:`to-api-logs-newcount`
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Config Files and Config File Metadata
+	#
+	@api_request(u'get', u'servers/{host_name:s}/configfiles/ats', (u'1.2', u'1.3',))
+	def get_server_config_files(self, host_name=None, query_params=None):
+		"""
+		Get the configuiration files for a given host name
+		:ref:`to-api-servers-server-configfiles-ats`
+		:param host_name: The host name to get config files for
+		:type host_name: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'servers/{host_name:s}/configfiles/ats/{config_file:s}', (u'1.2', u'1.3',))
+	def get_server_specific_config_file(self, host_name=None, config_file=None, query_params=None):
+		"""
+		Get the configuiration files for a given host name and config file
+		:ref:`to-api-servers-server-configfiles-ats-filename`
+		:param host_name: The host name to get config files for
+		:type host_name: String
+		:param config_file: The config file name to retrieve for host
+		:type config_file: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'profiles/{profile_name:s}/configfiles/ats/{config_file:s}',
+	             (u'1.2', u'1.3',))
+	def get_profile_specific_config_files(self, profile_name=None, config_file=None,
+	                                      query_params=None):
+		"""
+		Get the configuiration files for a given profile name and config file
+		:ref:`to-api-profiles-profile-configfiles-ats-filename`
+		:param profile_name: The profile name to get config files for
+		:type host_name: String
+		:param config_file: The config file name to retrieve for host
+		:type config_file: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/{cdn_name:s}/configfiles/ats/{config_file:s}', (u'1.2', u'1.3',))
+	def get_cdn_specific_config_file(self, cdn_name=None, config_file=None, query_params=None):
+		"""
+		Get the configuiration files for a given cdn name and config file
+		:ref:`to-api-cdns-cdn-configfiles-ats-filename`
+		:param cdn_name: The cdn name to get config files for
+		:type cdn_name: String
+		:param config_file: The config file name to retrieve for host
+		:type config_file: String
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	#
+	# Delivery Service
+	#
+	@api_request(u'get', u'deliveryservices', (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservices(self, query_params=None):
+		"""
+		Retrieves all delivery services (if admin or ops) or all delivery services assigned to user.
+		:ref:`to-api-deliveryservices`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_by_id(self, delivery_service_id=None):
+		"""
+		Retrieves a specific delivery service. If not admin / ops, delivery service must be assigned
+		to user.
+		:ref:`to-api-deliveryservices-id`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/servers',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_servers(self, delivery_service_id=None):
+		"""
+		Retrieves properties of CDN EDGE or ORG servers assigned to a delivery service.
+		:ref:`to-api-deliveryservices-id-servers`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/servers/unassigned',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_unassigned_servers(self, delivery_service_id=None):
+		"""
+		Retrieves properties of CDN EDGE or ORG servers not assigned to a delivery service.
+		(Currently call does not work)
+		:ref:`to-api-deliveryservices-id-servers-unassigned`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/servers/eligible',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_ineligible_servers(self, delivery_service_id=None):
+		"""
+		Retrieves properties of CDN EDGE or ORG servers not eligible for assignment to a delivery
+		service.
+		:ref:`to-api-deliveryservices-id-servers-eligible`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'deliveryservices', (u'1.1', u'1.2', u'1.3',))
+	def create_deliveryservice(self, data=None):
+		"""
+		Allows user to create a delivery service.
+		:ref:`to-api-deliveryservices`
+		:param data: The request data structure for the API request
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'deliveryservices/{delivery_service_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_deliveryservice_by_id(self, delivery_service_id=None, data=None):
+		"""
+		Update a Delivery Service by Id.
+		:ref:`to-api-deliveryservices-id`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:param data: The request data structure for the API request
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'deliveryservices/{delivery_service_id:d}/safe', (u'1.1', u'1.2', u'1.3',))
+	def update_deliveryservice_safe(self, delivery_service_id=None, data=None):
+		"""
+		Allows a user to edit limited fields of an assigned delivery service.
+		:ref:`to-api-deliveryservices-id-safe`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:param data: The request data structure for the API request
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'delete', u'deliveryservices/{delivery_service_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_deliveryservice_by_id(self, delivery_service_id=None):
+		"""
+		Allows user to delete a delivery service.
+		:ref:`to-api-deliveryservices-id`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Delivery Service Health
+	#
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/state', (u'1.1', u'1.2', u'1.3',))
+	def get_delivery_service_failover_state(self, delivery_service_id=None):
+		"""
+		Retrieves the failover state for a delivery service. Delivery service must be assigned to
+		user if user is not admin or operations.
+		:ref:`to-api-deliveryservices-id-state`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/health', (u'1.1', u'1.2', u'1.3',))
+	def get_delivery_service_health(self, delivery_service_id=None):
+		"""
+		Retrieves the health of all locations (cache groups) for a delivery service. Delivery
+		service must be assigned to user if user is not admin or operations.
+		:ref:`to-api-deliveryservices-id-health`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/capacity',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_delivery_service_capacity(self, delivery_service_id=None):
+		"""
+		Retrieves the capacity percentages of a delivery service. Delivery service must be assigned
+		to user if user is not admin or operations.
+		:ref:`to-api-deliveryservices-id-capacity`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/routing',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_delivery_service_routing(self, delivery_service_id=None):
+		"""
+		Retrieves the routing method percentages of a delivery service. Delivery service must be
+		assigned to user if user is not admin or operations.
+		:ref:`to-api-deliveryservices-id-routing`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Delivery Service Server
+	#
+	@api_request(u'get', u'deliveryserviceserver', (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryserviceserver(self, query_params=None):
+		"""
+		Retrieves delivery service / server assignments. (Allows pagination and limits)
+		:ref:`to-api-deliveryserviceserver`
+		:param query_params: The required url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'deliveryserviceserver', (u'1.1', u'1.2', u'1.3',))
+	def assign_deliveryservice_servers_by_ids(self, data=None):
+		"""
+		Assign servers by id to a Delivery Service. (New Method)
+		:ref:`to-api-deliveryserviceserver`
+		:param data: The required data to create server associations to a delivery service
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'deliveryservices/{xml_id}/servers', (u'1.1', u'1.2', u'1.3',))
+	def assign_deliveryservice_servers_by_names(self, xml_id=None, data=None):
+		"""
+		Assign servers by name to a Delivery Service by xmlId.
+		:ref:`to-api-deliveryservices-xmlid-servers`
+		:param xml_id: The XML Id of the delivery service
+		:type xml_id: str
+		:param data: The required data to assign servers to a delivery service
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'deliveryservice_server/{delivery_service_id:d}/{server_id:d}',
+	             (u'1.1', u'1.2', u'1.3',))
+	def delete_deliveryservice_servers_by_id(self, delivery_service_id=None, server_id=None):
+		"""
+		Removes a server (cache) from a delivery service.
+		:ref:`deliveryservice_server-dsid-serverid`
+		:param delivery_service_id: The delivery service id
+		:type delivery_service_id: int
+		:param server_id: The server id to remove from delivery service
+		:type server_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Delivery Service User
+	#
+	@api_request(u'post', u'deliveryservice_user', (u'1.2', u'1.3'))
+	def create_delivery_service_user_link(self, data=None):
+		"""
+		Create one or more user / delivery service assignments.
+		:ref:`to-api-deliveryservice_user`
+		:param data: The parameter data to use for Delivery Service SSL key generation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'deliveryservice_user/{delivery_service_id:d}/{user_id:d}',
+	             (u'1.2', u'1.3'))
+	def delete_delivery_service_user_link(self, delivery_service_id=None, user_id=None):
+		"""
+		Removes a delivery service from a user.
+		:ref:`to-api-deliveryservice_user-dsid-userid`
+		:param delivery_service_id: The delivery service id to dissasociate the user
+		:type delivery_service_id: int
+		:param user_id: The user id to dissassociate
+		:type user_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	#
+	# Delivery Service SSL Keys
+	#
+	@api_request(u'get', u'deliveryservices/xmlId/{xml_id}/sslkeys', (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_ssl_keys_by_xml_id(self, xml_id=None, query_params=None):
+		"""
+		Get SSL keys for a Delivery Service by xmlId.
+		:ref:`to-api-deliveryservices-xmlid-xmlid-sslkeys`
+		:param xml_id: The Delivery Service XML id
+		:type xml_id: str
+		:param query_params: The url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/xmlId/{xml_id}/sslkeys/delete', (u'1.1', u'1.2', u'1.3',))
+	def delete_deliveryservice_ssl_keys_by_xml_id(self, xml_id=None, query_params=None):
+		"""
+		Delete SSL keys for a Delivery Service by xmlId.
+		:ref:`to-api-deliveryservices-xmlid-xmlid-sslkeys-delete`
+		:param xml_id: The Delivery Service xmlId
+		:type xml_id: str
+		:param query_params: The url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'deliveryservices/sslkeys/generate', (u'1.1', u'1.2', u'1.3',))
+	def generate_deliveryservice_ssl_keys(self, data=None):
+		"""
+		Generate an SSL certificate. (self-signed)
+		:ref:`to-api-deliveryservices-sslkeys-generate`
+		:param data: The parameter data to use for Delivery Service SSL key generation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'deliveryservices/sslkeys/add', (u'1.1', u'1.2', u'1.3',))
+	def add_ssl_keys_to_deliveryservice(self, data=None):
+		"""
+		Add SSL keys to a Delivery Service.
+		:ref:`to-api-deliveryservices-sslkeys-add`
+		:param data: The parameter data to use for adding SSL keys to a Delivery Service.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Delivery Service URL Sig Keys
+	#
+	@api_request(u'post', u'deliveryservices/xmlId/{xml_id}/urlkeys/generate',
+	             (u'1.1', u'1.2', u'1.3',))
+	def generate_deliveryservice_url_signature_keys(self, xml_id=None):
+		"""
+		Generate URL Signature Keys for a Delivery Service by xmlId.
+		:ref:`to-api-deliveryservices-xmlid-xmlid-urlkeys-generate`
+		:param xml_id: The Delivery Service xmlId
+		:type xml_id: str
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Delivery Service Regexes
+	#
+	@api_request(u'get', u'deliveryservices_regexes', (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservices_regexes(self):
+		"""
+		Get RegExes for all Delivery Services.
+		:ref:`to-api-deliveryservices_regexes`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/regexes',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_regexes_by_id(self, delivery_service_id=None):
+		"""
+		Get RegExes for a Delivery Service by Id.
+		:ref:`to-api-deliveryservices-id-regexes`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'deliveryservices/{delivery_service_id:d}/regexes/{regex_id:d}',
+	             (u'1.1', u'1.2', u'1.3',))
+	def get_deliveryservice_regexes_by_regex_id(self, delivery_service_id=None, regex_id=None):
+		"""
+		Retrieves a regex for a specific delivery service.
+		:ref:`to-api-deliveryservices-id-regexes-rid`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:param regex_id: The delivery service regex id
+		:type regex_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'deliveryservices/{delivery_service_id:d}/regexes',
+	             (u'1.1', u'1.2', u'1.3',))
+	def create_deliveryservice_regexes(self, delivery_service_id=None, data=None):
+		"""
+		Create a regex for a delivery service
+		:ref:`to-api-deliveryservices-id-regexes`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:param data: The required data to create delivery service regexes
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'deliveryservices/{delivery_service_id:d}/regexes/{regex_id:d}',
+	             (u'1.1', u'1.2', u'1.3',))
+	def update_deliveryservice_regexes(self, delivery_service_id=None, regex_id=None,
+	                                   query_params=None):
+		"""
+		Update a regex for a delivery service
+		:ref:`to-api-deliveryservices-id-regexes-rid`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:param regex_id: The delivery service regex id
+		:type regex_id: int
+		:param query_params: The required data to update delivery service regexes
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'deliveryservices/{delivery_service_id:d}/regexes/'\
+	                        u'{delivery_service_regex_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_deliveryservice_regex_by_regex_id(self, delivery_service_id=None,
+	                                             delivery_service_regex_id=None):
+		"""
+		Delete a RegEx by Id for a Delivery Service by Id.
+		:ref:`to-api-deliveryservices-id-regexes-rid`
+		:param delivery_service_id: The delivery service Id
+		:type delivery_service_id: int
+		:param delivery_service_regex_id: The delivery service regex Id
+		:type delivery_service_regex_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Delivery Service Statistics
+	#
+	@api_request(u'get', u'deliveryservice_stats', (u'1.1', u'1.2', u'1.3',))
+	def get_delivery_service_stats(self, query_params=None):
+		"""
+		Retrieves statistics on the delivery services.
+		:ref:`to-api-deliveryservice_stats`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Divisions
+	#
+	@api_request(u'get', u'divisions', (u'1.1', u'1.2', u'1.3',))
+	def get_divisions(self):
+		"""
+		Get all divisions.
+		:ref:`to-api-divisions`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'divisions/{division_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_division_by_id(self, division_id=None):
+		"""
+		Get a division by division id
+		:ref:`to-api-divisions-id`
+		:param division_id: The division id to retrieve
+		:type division_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'divisions/{division_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_division(self, division_id=None, query_params=None):
+		"""
+		Update a division by division id
+		:ref:`to-api-divisions-id`
+		:param division_id: The division id to update
+		:type division_id: int
+		:param query_params: The required data to update delivery service regexes
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'divisions', (u'1.1', u'1.2', u'1.3',))
+	def create_division(self, data=None):
+		"""
+		Create a division
+		:ref:`to-api-divisions`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'divisions/{division_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_division(self, division_id=None, query_params=None):
+		"""
+		Delete a division by division id
+		:ref:`to-api-divisions-id`
+		:param division_id: The division id to delete
+		:type division_id: int
+		:param query_params: The required data to update delivery service regexes
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Federation
+	#
+	@api_request(u'get', u'federations', (u'1.2', u'1.3'))
+	def get_federations(self):
+		"""
+		Retrieves a list of federation mappings (aka federation resolvers) for a the current user
+		:ref:`to-api-federations`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'federations', (u'1.2', u'1.3'))
+	def create_federation(self, data=None):
+		"""
+		Allows a user to add federations for their delivery service(s).
+		:ref:`to-api-federations`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'get', u'cdns/{cdn_name:s}/federations', (u'1.2', u'1.3'))
+	def get_federations_for_cdn(self, cdn_name=None):
+		"""
+		Retrieves a list of federations for a cdn.
+		:ref:`to-api-cdns-name-federations`
+		:param cdn_name: The CDN name to find federation
+		:type cdn_name: String
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'get', u'cdns/{cdn_name:s}/federations/{federation_id:d}', (u'1.2', u'1.3'))
+	def get_federation_for_cdn_by_id(self, cdn_name=None, federation_id=None):
+		"""
+		Retrieves a federation for a cdn.
+		:ref:`to-api-cdns-name-federations-id`
+		:param cdn_name: The CDN name to find federation
+		:type cdn_name: String
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'cdns/{cdn_name:s}/federations', (u'1.2', u'1.3'))
+	def create_federation_in_cdn(self, cdn_name=None, data=None):
+		"""
+		Create a federation.
+		:ref:`to-api-cdns-name-federations`
+		:param cdn_name: The CDN name to find federation
+		:type cdn_name: String
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'cdns/{cdn_name:s}/federations/{federation_id:d}', (u'1.2', u'1.3'))
+	def update_federation_in_cdn(self, cdn_name=None, federation_id=None, query_params=None):
+		"""
+		Update a federation.
+		:ref:`to-api-cdns-name-federations-id`
+		:param cdn_name: The CDN name to find federation
+		:type cdn_name: String
+		:param federation_id: The federation id
+		:type federation_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'cdns/{cdn_name:s}/federations/{federation_id:d}', (u'1.2', u'1.3'))
+	def delete_federation_in_cdn(self, cdn_name=None, federation_id=None):
+		"""
+		Delete a federation.
+		:ref:`to-api-cdns-name-federations-id`
+		:param cdn_name: The CDN name to find federation
+		:type cdn_name: String
+		:param federation_id: The federation id
+		:type federation_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Federation Delivery Service
+	#
+	@api_request(u'get', u'federations/{federation_id:d}/deliveryservices', (u'1.2', u'1.3'))
+	def get_federation_delivery_services(self, federation_id=None):
+		"""
+		Retrieves delivery services assigned to a federation
+		:ref:`to-api-federations-id-deliveryservices`
+		:param federation_id: The federation id
+		:type federation_id: int
+		:param federation_id: The federation id
+		:type federation_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'federations/{federation_id:d}/deliveryservices', (u'1.2', u'1.3'))
+	def assign_delivery_services_to_federations(self, federation_id=None, data=None):
+		"""
+		Create one or more federation / delivery service assignments.
+		:ref:`to-api-federations-id-deliveryservices`
+		:param federation_id: The federation id
+		:type federation_id: int
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'federation_resolvers/{federation_id:d}/deliveryservices/'
+	                        u'{delivery_service_id:d}', (u'1.2', u'1.3'))
+	def remove_delivery_service_from_federation(self, federation_resolver_id=None,
+	                                            delivery_service_id=None):
+		"""
+		Removes a delivery service from a federation.
+		:ref:`to-api-federation_resolvers-id-deliveryservices-dsid`
+		:param federation_id: The federation id
+		:type federation_id: int
+		:param federation_id: The delivery service id
+		:type federation_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Federation Federation Resolver
+	#
+	@api_request(u'get', u'federations/{federation_id:d}/federation_resolvers', (u'1.2', u'1.3'))
+	def get_federation_resolvers_by_id(self, federation_id=None):
+		"""
+		:ref:`to-api-federations-id-federation_resolvers`
+		Retrieves federation resolvers assigned to a federation
+		:param federation_id: The federation id
+		:type federation_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'federations/{federation_id:d}/federation_resolvers', (u'1.2', u'1.3'))
+	def assign_federation_resolver_to_federations(self, federation_id=None, data=None):
+		"""
+		Create one or more federation / federation resolver assignments.
+		:ref:`to-api-federations-id-federation_resolvers`
+		:param federation_id: The federation id
+		:type federation_id: int
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Federation Resolver
+	#
+	@api_request(u'get', u'federation_resolvers', (u'1.2', u'1.3'))
+	def get_federation_resolvers(self, query_params=None):
+		"""
+		Get federation resolvers.
+		:ref:`to-api-federation_resolvers`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'federation_resolvers', (u'1.2', u'1.3'))
+	def create_federation_resolver(self, data=None):
+		"""
+		Create a federation resolver.
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'federation_resolvers/{federation_resolver_id:d}', (u'1.2', u'1.3'))
+	def delete_federation_resolver(self, federation_resolver_id=None):
+		"""
+		Delete a federation resolver.
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Federation User
+	#
+	@api_request(u'get', u'federations/{federation_id:d}/users', (u'1.2', u'1.3'))
+	def get_federation_users(self, federation_id=None):
+		"""
+		Retrieves users assigned to a federation.
+		:ref:`to-api-federations-id-users`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'federations/{federation_id:d}/users', (u'1.2', u'1.3'))
+	def create_federation_user(self, federation_id=None, data=None):
+		"""
+		Create one or more federation / user assignments.
+		:ref:`to-api-federations-id-users`
+		:param federation_id: Federation ID
+		:type federation_id: int
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'federations/{federation_id:d}/users/{user_id:d}', (u'1.2', u'1.3'))
+	def delete_federation_user(self, federation_id=None, user_id=None):
+		"""
+		Delete one or more federation / user assignments.
+		:ref:`to-api-federations-id-users-uid`
+		:param federation_id: Federation ID
+		:type federation_id: int
+		:param user_id: Federation User ID
+		:type user_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Hardware Info
+	#
+	@api_request(u'get', u'hwinfo', (u'1.2', u'1.3'))
+	def get_hwinfo(self):
+		"""
+		Get hwinfo for servers.
+		:ref:`to-api-hwinfo`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	#
+	# ISO
+	#
+	@api_request(u'get', u'osversions', (u'1.2', u'1.3'))
+	def get_osversions(self):
+		"""
+		Get all OS versions for ISO generation and the directory where the kickstarter files are
+		found. The values are retrieved from osversions.cfg found in either ``/var/www/files`` or in
+		the location defined by the kickstart.files.location parameter (if defined).
+		:ref:`to-api-osversions`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'isos', (u'1.2', u'1.3',))
+	def generate_iso(self, data=None):
+		"""
+		Generate an ISO
+		:ref:`to-api-isos`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Jobs
+	#
+	@api_request(u'get', u'jobs', (u'1.2', u'1.3'))
+	def get_jobs(self, query_params=None):
+		"""
+		Get all jobs (currently limited to invalidate content (PURGE) jobs) sorted by start time
+		(descending).
+		:ref:`to-api-jobs`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'jobs/{job_id:d}', (u'1.2', u'1.3'))
+	def get_job_by_id(self, job_id=None):
+		"""
+		Get a job by ID (currently limited to invalidate content (PURGE) jobs).
+		:ref:`to-api-jobs-id`
+		:param job_id: The job id to retrieve
+		:type job_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Parameter
+	#
+	@api_request(u'get', u'parameters', (u'1.2', u'1.3',))
+	def get_parameters(self):
+		"""
+		Get all Profile Parameters.
+		:ref:`to-api-parameters`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'parameters/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_parameter_by_id(self, parameter_id=None):
+		"""
+		Get a Parameter by Id.
+		:ref:`to-api-parameters-id`
+		:param parameter_id: The parameter Id
+		:type parameter_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'parameters/{parameter_id:d}/profiles', (u'1.1', u'1.2', u'1.3',))
+	def get_associated_profiles_by_parameter_id(self, parameter_id=None):
+		"""
+		Get all Profiles associated to a Parameter by Id.
+		:ref:`to-api-parameters-id-profiles`
+		:param parameter_id: The parameter id
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'parameters/{parameter_id:d}/unassigned_profiles', (u'1.1', u'1.2', u'1.3',))
+	def get_unassigned_profiles_by_parameter_id(self, parameter_id=None):
+		"""
+		Retrieves all profiles NOT assigned to the parameter.
+		:ref:`to-api-parameters-id-unassigned_profiles`
+		:param parameter_id: The parameter id
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'get', u'profiles/{id:d}/parameters', (u'1.1', u'1.2', u'1.3',))
+	def get_parameters_by_profile_id(self, profile_id=None):
+		"""
+		Get all Parameters associated with a Profile by Id.
+		:ref:`to-api-profiles-id-parameters`
+		:param profile_id: The profile Id
+		:type profile_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'profiles/{id:d}/unassigned_parameters', (u'1.1', u'1.2', u'1.3',))
+	def get_unnassigned_parameters_by_profile_id(self, profile_id=None):
+		"""
+		Get all Parameters associated with a Profile by Id.
+		:ref:`to-api-profiles-id-unassigned_parameters`
+		:param profile_id: The profile Id
+		:type profile_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'profiles/name/{profile_name}/parameters', (u'1.1', u'1.2', u'1.3',))
+	def get_parameters_by_profile_name(self, profile_name=None):
+		"""
+		Get all Parameters associated with a Profile by Name.
+		:ref:`to-api-profiles-name-name-parameters`
+		:param profile_name: The profile name
+		:type profile_name: str
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'parameters', (u'1.1', u'1.2', u'1.3',))
+	def create_parameter(self, data=None):
+		"""
+		Create Parameter
+		:ref:`to-api-parameters`
+		:param data: The parameter(s) data to use for parameter creation.
+		:type data: Union[Dict[str, Any], List[Dict[str, Any]]]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'parameters/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_parameter(self, parameter_id=None, query_params=None):
+		"""
+		Update Parameter
+		:ref:`to-api-parameters-id`
+		:param parameter_id: The parameter id to update
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'delete', u'parameters/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_parameter(self, parameter_id=None):
+		"""
+		Delete Parameter
+		:ref:`to-api-parameters-id`
+		:param parameter_id: The parameter id to delete
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'parameters/validate', (u'1.1', u'1.2', u'1.3',))
+	def validate_parameter_exists(self, data=None):
+		"""
+		Validate that a Parameter exists.
+		:ref:`to-api-parameters-validate`
+		:param data: The parameter data to use for parameter validation.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Physical Location
+	#
+	@api_request(u'get', u'phys_locations', (u'1.1', u'1.2', u'1.3',))
+	def get_physical_locations(self, query_params=None):
+		"""
+		Get Physical Locations.
+		:ref:`to-api-phys_locations`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'phys_locations/trimmed', (u'1.1', u'1.2', u'1.3',))
+	def get_trimmed_physical_locations(self):
+		"""
+		Get Physical Locations with name only
+		:ref:`to-api-phys_locations-trimmed`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'phys_locations/{physical_location_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_physical_location_by_id(self, physical_location_id=None):
+		"""
+		Get Physical Location by id
+		:ref:`to-api-phys_locations-id`
+		:param physical_location_id: The id to retrieve
+		:type physical_location_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'phys_locations/{physical_location_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_physical_location(self, physical_location_id=None, query_params=None):
+		"""
+		Update Physical Location by id
+		:ref:`to-api-phys_locations-id`
+		:param physical_location_id: The id to update
+		:type physical_location_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'regions/{region_name:s}/phys_locations', (u'1.1', u'1.2', u'1.3',))
+	def create_physical_location(self, region_name=None, query_params=None):
+		"""
+		Create physical location
+		:ref:`to-api-regions-name-phys_locations`
+		:param region_name: the name of the region to create physical location into
+		:type region_name: String
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'phys_locations/{physical_location_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_physical_location(self, physical_location_id=None, query_params=None):
+		"""
+		Delete Physical Location by id
+		:ref:`to-api-phys_locations-id`
+		:param physical_location_id: The id to delete
+		:type physical_location_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Profiles
+	#
+	@api_request(u'get', u'profiles', (u'1.1', u'1.2', u'1.3',))
+	def get_profiles(self, query_params=None):
+		"""
+		Get Profiles.
+		:ref:`to-api-profiles`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'profiles/trimmed', (u'1.1', u'1.2', u'1.3',))
+	def get_trimmed_profiles(self):
+		"""
+		Get Profiles with names only
+		:ref:`to-api-profiles-trimmed`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'profiles/{profile_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_profile_by_id(self, profile_id=None):
+		"""
+		Get Profile by Id.
+		:ref:`to-api-profiles-id`
+		:param profile_id: The profile Id
+		:type profile_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'profiles', (u'1.1', u'1.2', u'1.3',))
+	def create_profile(self, data=None):
+		"""
+		Create a profile
+		:ref:`to-api-profiles`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'profiles/name/{new_profile_name:s}/copy/{copy_profile_name:s}',
+	             (u'1.1', u'1.2', u'1.3',))
+	def copy_profile(self, new_profile_name=None, copy_profile_name=None, data=None):
+		"""
+		Copy profile to a new profile. The new profile name must not exist
+		:ref:`to-api-profiles-name-name-copy-copy`
+		:param new_profile_name: The name of profile to copy to
+		:type new_profile_name: String
+		:param copy_profile_name: The name of profile copy from
+		:type copy_profile_name: String
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'profiles/{profile_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_profile_by_id(self, profile_id=None, data=None):
+		"""
+		Update Profile by Id.
+		:ref:`to-api-profiles-id`
+		:param profile_id: The profile Id
+		:type profile_id: int
+		:param data: The parameter data to edit
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'profiles/{profile_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_profile_by_id(self, profile_id=None):
+		"""
+		Delete Profile by Id.
+		:ref:`to-api-profiles-id`
+		:param profile_id: The profile Id
+		:type profile_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Profile Parameters
+	#
+	@api_request(u'post', u'profileparameters', (u'1.1', u'1.2', u'1.3',))
+	def associate_paramater_to_profile(self, data=None):
+		"""
+		Associate parameter to profile.
+		:ref:`to-api-profileparameters`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'profiles/{profile_id:d}/parameters', (u'1.1', u'1.2', u'1.3',))
+	def associate_parameters_by_profile_id(self, profile_id=None, data=None):
+		"""
+		Associate Parameters to a Profile by Id.
+		:ref:`to-api-profiles-id-parameters`
+		:param profile_id: The profile id
+		:type profile_id: int
+		:param data: The parameter data to associate
+		:type data: Union[Dict[str, Any], List[Dict[str, Any]]]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'profileparameter', (u'1.1', u'1.2', u'1.3',))
+	def assign_profile_to_parameter_ids(self, data=None):
+		"""
+		Create one or more profile / parameter assignments.
+		:ref:`to-api-profileparameter`
+		:param data: The data to assign
+		:type data: Union[Dict[str, Any], List[Dict[str, Any]]]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'parameterprofile', (u'1.1', u'1.2', u'1.3',))
+	def assign_parameter_to_profile_ids(self, data=None):
+		"""
+		Create one or more parameter / profile assignments.
+		:ref:`to-api-profileparameter`
+		:param data: The data to assign
+		:type data: Union[Dict[str, Any], List[Dict[str, Any]]]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	@api_request(u'post', u'profiles/name/{profile_name}/parameters', (u'1.1', u'1.2', u'1.3',))
+	def associate_parameters_by_profile_name(self, profile_name=None, data=None):
+		"""
+		Associate Parameters to a Profile by Name.
+		:ref:`to-api-profiles-name-name-parameters`
+		:param profile_name: The profile name
+		:type profile_name: str
+		:param data: The parameter data to associate
+		:type data: Union[Dict[str, Any], List[Dict[str, Any]]]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'profileparameters/{profile_id:d}/{parameter_id:d}',
+	             (u'1.1', u'1.2', u'1.3',))
+	def delete_profile_parameter_association_by_id(self, profile_id=None, parameter_id=None):
+		"""
+		Delete Parameter association by Id for a Profile by Id.
+		:ref:`to-api-profileparameters-profileID-parameterID`
+		:param profile_id: The profile id
+		:type profile_id: int
+		:param parameter_id: The parameter id
+		:type parameter_id: int
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Regions
+	#
+	@api_request(u'get', u'regions', (u'1.1', u'1.2', u'1.3',))
+	def get_regions(self):
+		"""
+		Get Regions.
+		:ref:`to-api-regions`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'regions/{region_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_region_by_id(self, region_id=None):
+		"""
+		Get Region by ID
+		:ref:`to-api-regions-id`
+		:param region_id: The region id of the region to retrieve
+		:type region_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'regions/{region_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_region(self, region_id=None):
+		"""
+		Update a region
+		:ref:`to-api-regions-id`
+		:parma region_id: The region to update
+		:type region_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'divisions/{division_name:s}/regions', (u'1.1', u'1.2', u'1.3',))
+	def create_region(self, division_name=None, data=None):
+		"""
+		Create a region
+		:ref:`to-api-divisions-name-regions`
+		:param division_name: The Division name in which region will reside
+		:type division_name: String
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Roles
+	#
+	@api_request(u'get', u'roles', (u'1.1', u'1.2', u'1.3',))
+	def get_roles(self):
+		"""
+		Get Roles.
+		:ref:`to-api-roles`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Server
+	#
+	@api_request(u'get', u'servers', (u'1.1', u'1.2', u'1.3',))
+	def get_servers(self, query_params=None):
+		"""
+		Get Servers.
+		:ref:`to-api-servers`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'servers/{server_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_server_by_id(self, server_id=None):
+		"""
+		Get Server by Server ID
+		:ref:`to-api-servers-id`
+		:param server_id: The server id to retrieve
+		:type server_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'servers/{server_id:d}/deliveryservices', (u'1.1', u'1.2', u'1.3',))
+	def get_server_delivery_services(self, server_id=None):
+		"""
+		Retrieves all delivery services assigned to the server
+		:ref:`to-api-servers-id-deliveryservices`
+		:param server_id: The server id to retrieve
+		:type server_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'servers/total', (u'1.1', u'1.2', u'1.3',))
+	def get_server_type_count(self):
+		"""
+		Retrieves a count of CDN servers by type
+		:ref:`to-api-servers-total`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'servers/status', (u'1.1', u'1.2', u'1.3',))
+	def get_server_status_count(self):
+		"""
+		Retrieves a count of CDN servers by status
+		:ref:`to-api-servers-status`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'servers/hostname/{name}/details', (u'1.1', u'1.2', u'1.3',))
+	def get_server_details(self, name=None):
+		"""
+		Get server details from trafficOps
+		:ref:`to-api-servers-hostname-name-details`
+		:param hostname: Server hostname
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'servercheck', (u'1.1', u'1.2', u'1.3',))
+	def create_servercheck(self, data=None):
+		"""
+		Post a server check result to the serverchecks table.
+		:ref:`to-api-servercheck`
+		:param data: The parameter data to use for server creation
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'servers', (u'1.1', u'1.2', u'1.3',))
+	def create_server(self, data=None):
+		"""
+		Create a new Server.
+		:ref:`to-api-servers`
+		:param data: The parameter data to use for server creation
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'servers/{server_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_server_by_id(self, server_id=None, data=None):
+		"""
+		Update a Server by Id.
+		:ref:`to-api-servers-id`
+		:param server_id: The server Id
+		:type server_id: int
+		:param data: The parameter data to edit
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+	@api_request(u'put', u'servers/{server_id:d}/status', (u'1.1', u'1.2', u'1.3',))
+	def update_server_status_by_id(self, server_id=None, data=None):
+		"""
+		Update server_status by Id.
+		:ref:`to-api-servers-id-status`
+		:param server_id: The server Id
+		:type server_id: int
+		:status: https://traffic-control-cdn.readthedocs.io/en/latest/api/server.html
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'servers/{server_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def delete_server_by_id(self, server_id=None):
+		"""
+		Delete a Server by Id.
+		:ref:`to-api-servers-id`
+		:param server_id: The server Id
+		:type server_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'servers/{server_id:d}/queue_update', (u'1.1', u'1.2', u'1.3',))
+	def servers_queue_update(self, server_id=None, data=None):
+		"""
+		Queue Updates by Server Id.
+		:ref:`to-api-servers-id-queue_update`
+		:param server_id: The server Id
+		:type server_id: int
+		:param data: The update action.  QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Static DNS Entries
+	#
+	@api_request(u'get', u'staticdnsentries', (u'1.1', u'1.2', ))
+	def get_static_dns_entries(self):
+		"""
+		Get Static DNS Entries.
+		:ref:`to-api-staticdnsentries`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'staticdnsentries', (u'1.1', u'1.2', u'1.3',))
+	def get_staticdnsentries(self, query_params=None):
+		"""
+		Get static DNS entries associated with the delivery service
+		:ref:`to-api-staticdnsentries`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'staticdnsentries', (u'1.3',))
+	def create_staticdnsentries(self, data=None):
+		"""
+		Create static DNS entries associated with the delivery service
+		:ref:`to-api-staticdnsentries`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'staticdnsentries', (u'1.3',))
+	def update_staticdnsentries(self, data=None, query_params=None):
+		"""
+		Update static DNS entries associated with the delivery service
+		:ref:`to-api-staticdnsentries`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'staticdnsentries', (u'1.3',))
+	def delete_staticdnsentries(self, query_params=None):
+		"""
+		Delete static DNS entries associated with the delivery service
+		:ref:`to-api-staticdnsentries`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Status
+	#
+	@api_request(u'get', u'statuses', (u'1.1', u'1.2', u'1.3',))
+	def get_statuses(self):
+		"""
+		Retrieves a list of the server status codes available.
+		:ref:`to-api-statuses`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'statuses/{status_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_statuses_by_id(self, status_id=None):
+		"""
+		Retrieves a server status by ID.
+		:ref:`to-api-statuses-id`
+		:param status_id: The status id to retrieve
+		:type status_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# System
+	#
+	@api_request(u'get', u'system/info', (u'1.1', u'1.2', u'1.3',))
+	def get_system_info(self):
+		"""
+		Get information on the traffic ops system.
+		:ref:`to-api-system-info`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	#
+	# Tenants
+	#
+	@api_request(u'get', u'tenants', (u'1.1', u'1.2', u'1.3',))
+	def get_tenants(self):
+		"""
+		Get all tenants.
+		:ref:`to-api-tenants`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'tenants/{tenant_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_tenant_by_id(self, tenant_id=None):
+		"""
+		Get a tenant by ID.
+		:ref:`to-api-tenants-id`
+		:param tenant_id: The tenant to retrieve
+		:type tenant_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'tenants/{tenant_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def update_tenant(self, tenant_id=None):
+		"""
+		Update a tenant
+		:ref:`to-api-tenants-id`
+		:param tenant_id: The tenant to update
+		:type tenant_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'tenants', (u'1.1', u'1.2', u'1.3',))
+	def create_tenant(self, data=None):
+		"""
+		Create a tenant
+		:ref:`to-api-tenants`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+	#
+	# TO Extensions
+	#
+	@api_request(u'get', u'to_extensions', (u'1.1', u'1.2', u'1.3',))
+	def get_to_extensions(self):
+		"""
+		Retrieves the list of extensions.
+		:ref:`to-api-to_extensions`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'to_extensions', (u'1.1', u'1.2', u'1.3',))
+	def create_to_extension(self, data=None):
+		"""
+		Creates a Traffic Ops extension.
+		:ref:`to-api-to_extensions`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'to_extensions/{extension_id:d}/delete', (u'1.1', u'1.2', u'1.3',))
+	def delete_to_extension(self, extension_id=None):
+		"""
+		Deletes a Traffic Ops extension.
+		:ref:`to-api-to_extensions-id-delete`
+		:param extension_id: The extension id to delete
+		:type extension_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Types
+	#
+	@api_request(u'get', u'types', (u'1.1', u'1.2', u'1.3',))
+	def get_types(self, query_params=None):
+		"""
+		Get Data Types.
+		:ref:`to-api-types`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'types/trimmed', (u'1.1', u'1.2', u'1.3',))
+	def get_types_only_names(self):
+		"""
+		Get Data Types with only the Names
+		:ref:`to-api-types-trimmed`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'types/{type_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_type_by_id(self, type_id=None):
+		"""
+		Get Data Type with the given type id
+		:ref:`to-api-types-id`
+		:param type_id: The ID of the type to retrieve
+		:type type_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Users
+	#
+	@api_request(u'get', u'users', (u'1.1', u'1.2', u'1.3',))
+	def get_users(self):
+		"""
+		Retrieves all users.
+		:ref:`to-api-users`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'users/{user_id:d}', (u'1.1', u'1.2', u'1.3',))
+	def get_user_by_id(self, user_id=None):
+		"""
+		Retrieves user by ID.
+		:ref:`to-api-users-id`
+		:param user_id: The user to retrieve
+		:type user_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'users', (u'1.1', u'1.2', u'1.3',))
+	def create_user(self, data=None):
+		"""
+		Create a user.
+		:ref:`to-api-users`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'users/register', (u'1.1', u'1.2', u'1.3',))
+	def create_user_with_registration(self, data=None):
+		"""
+		Register a user and send registration email
+		:ref:`to-api-users-register`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'users/{user_id:d}/deliveryservices', (u'1.1', u'1.2', u'1.3',))
+	def get_user_delivery_services(self, user_id=None):
+		"""
+		Retrieves all delivery services assigned to the user.
+		:ref:`to-api-users-id-deliveryservices`
+		:param user_id: The user to retrieve
+		:type user_id: int
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'user/current', (u'1.1', u'1.2', u'1.3',))
+	def get_authenticated_user(self):
+		"""
+		Retrieves the profile for the authenticated user.
+		:ref:`to-api-user-current`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'user/current/jobs', (u'1.1', u'1.2', u'1.3',))
+	def get_authenticated_user_jobs(self):
+		"""
+		Retrieves the user's list of jobs.
+		:ref:`to-api-user-current-jobs`
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'user/current/jobs', (u'1.1', u'1.2', u'1.3',))
+	def create_invalidation_job(self, data=None):
+		"""
+		Invalidating content on the CDN is sometimes necessary when the origin was mis-configured
+		and something is cached in the CDN that needs to be removed. Given the size of a typical
+		Traffic Control CDN and the amount of content that can be cached in it, removing the content
+		from all the caches may take a long time. To speed up content invalidation, Traffic Ops will
+		not try to remove the content from the caches, but it makes the content inaccessible using
+		the `regex_revalidate ATS plugin <https://docs.trafficserver.apache.org/en/latest/admin-guide/plugins/regex_revalidate.en.html>`_
+		This forces a revalidation of the content, rather than a new get.
+		:ref:`to-api-user-current-jobs`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Snapshot CRConfig
+	#
+	@api_request(u'get', u'cdns/{cdn_name}/snapshot', (u'1.2', u'1.3',))
+	def get_current_snapshot_crconfig(self, cdn_name=None):
+		"""
+		Retrieves the CURRENT snapshot for a CDN which doesn't necessarily represent the current
+		state of the CDN. The contents of this snapshot are currently used by Traffic Monitor and
+		Traffic Router.
+		:ref:`to-api-cdns-name-snapshot`
+		:param cdn_name: The CDN name
+		:type cdn_name: str
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'get', u'cdns/{cdn_name}/snapshot/new', (u'1.2', u'1.3',))
+	def get_pending_snapshot_crconfig(self, cdn_name=None):
+		"""
+		Retrieves a PENDING snapshot for a CDN which represents the current state of the CDN. The
+		contents of this snapshot are NOT currently used by Traffic Monitor and Traffic Router. Once
+		a snapshot is performed, this snapshot will become the CURRENT snapshot and will be used by
+		Traffic Monitor and Traffic Router.
+		:ref:`to-api-cdns-name-snapshot-new`
+		:param cdn_name: The CDN name
+		:type cdn_name: str
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'snapshot/{cdn_name}', (u'1.2', u'1.3',))
+	def snapshot_crconfig(self, cdn_name=None):
+		"""
+		Snapshot CRConfig by CDN Name.
+		:ref:`to-api-snapshot-name`
+		:param cdn_name: The CDN name
+		:type cdn_name: str
+		:rtype: Tuple[Dict[str, Any], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+
+
+	#
+	# Coordinate
+	#
+	@api_request(u'get', u'coordinates', (u'1.3',))
+	def get_coordinates(self, query_params=None):
+		"""
+		Get all coordinates associated with the cdn
+		:ref:`to-api-coordinates`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'coordinates', (u'1.3'))
+	def create_coordinates(self, data=None):
+		"""
+		Create coordinates
+		:ref:`to-api-coordinates`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'coordinates', (u'1.3'))
+	def update_coordinates(self, query_params=None, data=None):
+		"""
+		Update coordinates
+		:ref:`to-api-coordinates`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'coordinates', (u'1.3'))
+	def delete_coordinates(self, query_params=None):
+		"""
+		Delete coordinates
+		:ref:`to-api-coordinates`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	#
+	# Origin
+	#
+	@api_request(u'get', u'origins', (u'1.3',))
+	def get_origins(self, query_params=None):
+		"""
+		Get origins associated with the delivery service
+		:ref:`to-api-origins`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'post', u'origins', (u'1.3',))
+	def create_origins(self, data=None):
+		"""
+		Creates origins associated with a delivery service
+		:ref:`to-api-origins`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'put', u'origins', (u'1.3',))
+	def update_origins(self, query_params=None):
+		"""
+		Updates origins associated with a delivery service
+		:ref:`to-api-origins`
+		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
+		:type data: Dict[str, Any]
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	@api_request(u'delete', u'origins', (u'1.3',))
+	def delete_origins(self, query_params=None):
+		"""
+		Updates origins associated with a delivery service
+		:ref:`to-api-origins`
+		:param query_params: The optional url query parameters for the call
+		:type query_params: Dict[str, Any]
+		:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], requests.Response]
+		:raises: Union[LoginError, OperationError]
+		"""
+
+	####################################################################################
+	####                                                                            ####
+	####                          Data Model Overrides                              ####
+	####                                                                            ####
+	####################################################################################
+
+	def __enter__(self):
+		"""
+		Implements context-management for ToSessions. This will open the session by sending a
+		connection request immediately, rather than waiting for login.
+
+		:returns: The constructed object (:meth:`__init__` is called implicitly prior to this method)
+		"""
+		self.create()
+		return self
+
+	def __exit__(self, exc_type, exc_value, traceback):
+		"""
+		Implements context-management for TOSessions. This will close the underlying socket.
+		"""
+		self.close()
+
+		if exc_type:
+			logging.error("%s", exc_value)
+			logging.debug("%s", exc_type, stack_info=traceback)
+
+
+
+
+if __name__ == u'__main__':
+	# Sample usages
+	import operator
+
+	DEBUG = False
+
+	logging.basicConfig(stream=sys.stderr, level=logging.INFO if not DEBUG else logging.DEBUG)
+
+	# TOSession Class Examples
+	#     TOSession is a class that allows you to create a session to a Traffic Ops instance
+	#     and interact with the Traffic Ops API.
+
+	# Traffic Ops System - for self-signed cert -> turn off cert verification
+	TOS = TOSession(host_ip=u'to.somedomain.net', verify_cert=True)
+	TOS.login(u'someuser', u'someuser123')
+
+	# Objects get returned munch-ified by default which means you can access dictionary keys as
+	# attributes names but you can still access the entries with keys as well e.g.
+	# ``cdn.name`` is equivalent to ``cdn['name']``
+	CDNS = TOS.get_cdns()[0]
+	print(CDNS)
+	for cdn in CDNS:
+		print(u'CDN [{0}] has id [{1}]'.format(cdn.name, cdn.id))
+
+	ALL_TYPES = TOS.get_types()[0]
+	print(u'All Types are (sorted by useInTable, name):')
+	print(ALL_TYPES)
+	for atype in sorted(ALL_TYPES, key=operator.itemgetter(u'useInTable', u'name')):
+		print(u'Type [{0}] for table [{1}]'.format(atype.name, atype.useInTable))
+
+	print(u'Getting all cache groups (bulk)...')
+	CACHE_GROUPS = TOS.get_cachegroups()[0]
+	for cache_group in CACHE_GROUPS:
+		print(u'Bulk cache group [{0}] has id [{1}]'.format(cache_group.name, cache_group.id))
+
+		# Example with URL replacement parameters
+		# e.g. TOSession.get_cachegroups_by_id() == end-point 'api/1.2/cachegroups/{id}'
+		#      See TOSession object for details.
+		print(u'    Getting cachegroup by id [{0}]'.format(cache_group.id),
+			  u' to demonstrate getting by id...')
+		cg_id_list = TOS.get_cachegroup_by_id(cache_group_id=cache_group.id)[0]
+		print(u'    Cache group [{0}] by id [{1}]'.format(cg_id_list[0].name, cg_id_list[0].id))
+
+	# Example with URL query parameters
+	SERVER_TYPES = TOS.get_types(query_params={u'useInTable': u'server'})[0]
+	print(u'Server Types are:')
+	print(SERVER_TYPES)
+	for stype in SERVER_TYPES:
+		print(u'Type [{0}] for table [{1}]'.format(stype.name, stype.useInTable))
+	TOS.close()
+	print(u'Done!')
diff --git a/traffic_control/clients/python/trafficops/trafficops/tosession.py b/traffic_control/clients/python/trafficops/trafficops/tosession.py
deleted file mode 100644
index e52cd56ef..000000000
--- a/traffic_control/clients/python/trafficops/trafficops/tosession.py
+++ /dev/null
@@ -1,2741 +0,0 @@
-#! /usr/bin/env python
-
-# -*- coding: utf-8 -*-
-
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Module to help create/retrieve/update/delete data from/to the Traffic Ops API.
-
-Requires Python Version >= 2.7 or >= 3.6
-"""
-
-# Core Modules
-import logging
-import sys
-
-# Third-party Modules
-import munch
-from future.utils import raise_from
-import requests.exceptions as rex
-
-# Local Modules
-import common.restapi as restapi
-import common.utils as utils
-
-
-logger = logging.getLogger(__name__)
-
-__all__ = [u'default_headers', u'TOSession']
-
-# Miscellaneous Constants and/or Variables
-default_headers = {u'Content-Type': u'application/json; charset=UTF-8'}
-
-
-# TOSession Class
-class TOSession(restapi.RestApiSession):
-	"""
-	Traffic Ops Session Class
-	Once you login to the Traffic Ops API via the 'login' method, you can call one or more of the methods to retrieve,
-	post, put, delete, etc. data to the API.  If you are not logged in, an exception will be thrown if you try
-	to call any of the endpoint methods. e.g. get_servers, get_cachegroups, etc.
-
-	This API client is simplistic and lightly structured on purpose but adding support for new end-points
-	routinely takes seconds.  Another nice bit of convenience that result data is, by default, wrapped in
-	munch.Munch objects, which provide attribute access to the returned dictionaries/hashes.
-
-		e.g. "a_dict['a_key']" with munch becomes "a_dict.a_key" or "a_dict['a_key']"
-			 "a_dict['a_key']['b_key']" with munch becomes "a_dict.a_key.b_key" or "a_dict['a_key']['b_key']"
-
-	Also, the lack of rigid structure (loose coupling) means many changes to the Traffic Ops API,
-	as it evolves, will probably go un-noticed (usually additions), which means fewer
-	future problems to potentially fix in user applications.
-
-	An area of improvement for later is defining classes to represent request data instead
-	of loading up dictionaries for request data.
-
-	As of now you can see the following URL for API details:
-	   https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html #api for details
-
-	Adding end-point methods: (See "Implemented Direct API URL Endpoint Methods" for actual examples)
-		E.g. End-point with no URL parameters and no query parameters:
-			given end-point URL: GET api/1.2/cdns
-				@restapi.api_request(u'get', u'cdns', (u'1.1', u'1.2',))
-				def get_cdns(self):
-					pass
-
-		E.g. End-point with URL parameters and no query parameters:
-			given end-point URL: GET api/1.2/cdns/{cdn_id:d}
-				 @restapi.api_request(u'get', u'cdns/{cdn_id:d}', (u'1.1', u'1.2',))
-				 def get_cdn_by_id(self, cdn_id=None):
-					 pass
-
-		E.g. End-point with no URL parameters but with query parameters:
-			given end-point URL: GET api/1.2/deliveryservices
-				 @restapi.api_request(u'get', u'deliveryservices', (u'1.1', u'1.2',))
-				 def get_deliveryservices(self, query_params=None):
-					 pass
-
-		E.g. End-point with URL parameters and query parameters:
-			given end-point URL: GET api/1.2/deliveryservices/xmlId/{xml_id}/sslkeys
-				 @restapi.api_request(u'get', u'deliveryservices/xmlId/{xml_id}/sslkeys', (u'1.1', u'1.2',))
-				 def get_deliveryservice_ssl_keys_by_xml_id(self, xml_id=None, query_params=None):
-					 pass
-
-		E.g. End-point with request data:
-			given end-point URL: POST api/1.2/cdns
-				 @restapi.api_request(u'post', u'cdns', (u'1.1', u'1.2',))
-				 def create_cdn(self, data=None):
-					 pass
-
-		E.g. End-point with URL parameters and request data:
-			given end-point URL: PUT api/1.2/cdns/{cdn_id:d}
-				 @restapi.api_request(u'put', u'cdns', (u'1.1', u'1.2',))
-				 def update_cdn_by_id(self, cdn_id=None, data=None):
-					 pass
-
-	Calling end-point methods:
-
-		E.g. Using no URL parameters and no query parameters:
-			given end-point URL: GET api/1.2/cdns
-			get_cdns() -> calls end-point: GET api/1.2/cdns
-
-		E.g. Using no URL parameters but with query parameters:
-			given end-point URL: GET api/1.2/types
-			get_types(query_params={'useInTable': 'servers'}) -> calls end-point: GET api/1.2/types?useInTable=servers
-
-		E.g. Using URL parameters and query parameters:
-		   given end-point URL: GET api/1.2/foo/{id}
-		   get_foo_data(id=45, query_params={'sort': 'asc'}) -> calls end-point: GET api/1.2/foo/45?sort=asc
-
-		E.g. Using with required request data:
-			given end-point URL: POST api/1.2/cdns/{id:d}/queue_update
-			cdns_queue_update(...) -> calls end-point -> POST api/1.2/cdns/{id:d}/queue_update
-			cdns_queue_update(id=1, data={'action': 'queue'}) -> calls end-point: POST api/1.2/cdns/1/queue_update
-			   with json data '{"action": "queue"}'.
-
-		   So,
-
-		   dict_request = {'action': 'queue'}
-
-		   or
-
-		   Example with a namedtuple:
-			   import collections
-			   QueueUpdateRequest = collections.namedtuple('QueueUpdateRequest', ['action'])
-			   request = QueueUpdateRequest(action='update')
-
-		   Then:
-			   cdns_queue_update(id=1, data=vars(request))     # Python 2.x
-			   cdns_queue_update(id=1, data=request.asdict())  # Python 3.x
-			   cdns_queue_update(id=1, data=dict_request)      # Python 2.x/3.x
-
-		   NOTE: var(request)/request.asdict() transforms the namedtuple into a dictionary which is required
-				 by the 'data' argument.
-
-	NOTE: Only a small subset of the API endpoints are implemented.  More can be implemented as needed.
-		  See the Traffic Ops API documentation for more detail:
-					 https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html #api for details #api
-	"""
-
-	def __init__(self, host_ip, host_port=443, api_version=u'1.3', ssl=True, headers=default_headers,
-				 verify_cert=True):
-		"""
-		The class initializer.
-		:param host_ip: The dns name or ip address of the Traffic Ops host to use to talk to the API
-		:type host_ip: Text
-		:param host_port: The port to use when contacting the Traffic Ops API
-		:type host_port: int
-		:param api_version: The version of the API to use when calling end-points on the Traffic Ops API
-		:type api_version: Text
-		:param ssl: Should ssl be used? http vs. https
-		:type ssl: bool
-		:param headers:  The http headers to use when contacting the Traffic Ops API
-		:type headers: Dict[Text, Text]
-		:param verify_cert: Should the ssl certificates be verified when contacting the Traffic Ops API.
-							You may want to set this to False for systems with self-signed certificates.
-		:type verify_cert: bool
-		"""
-		super(TOSession, self).__init__(host_ip=host_ip, api_version=api_version,
-										api_base_path=u'api/{api_version}/',
-										host_port=host_port, ssl=ssl, headers=headers, verify_cert=verify_cert)
-
-		self._logged_in = False
-
-		msg = u'TOSession instance {0:#0x} initialized: Details: {1}'
-		utils.log_with_debug_info(logging.DEBUG, msg.format(id(self), self.__dict__))
-
-	def login(self, username, password):
-		"""
-		Login to the Traffic Ops API.
-		:param username: Traffic Ops User Name
-		:type username: Text
-		:param password: Traffic Ops User Password
-		:type password: Text
-		:return: None
-		:rtype: None
-		:raises: trafficops.restapi.LoginError
-		"""
-		logging.info("Connecting to Traffic Ops at %s...", self.to_url)
-
-		if not self.is_open:
-			self.create()
-
-		logging.info("Connected. Authenticating...")
-
-		self._logged_in = False
-		try:
-			# Try to login to Traffic Ops
-			self.post(u'user/login', data={u'u': username, u'p': password})
-			self._logged_in = True
-		except rex.SSLError as e:
-			logging.debug("%s", e, stack_info=True, exc_info=True)
-			self.close()
-			msg = (u'{0}.  This system may have a self-signed certificate.  Try creating this TOSession '
-				   u'object passing verify_cert=False. e.g. TOSession(..., verify_cert=False). ')
-			msg = msg.format(e)
-			logging.error(msg)
-			logging.warning("disabling certificate verification is not recommended.")
-			raise_from(restapi.LoginError(msg), e)
-		except restapi.OperationError as e:
-			logging.debug("%s", e, exc_info=True, stack_info=True)
-			msg = u'Logging in to Traffic Ops has failed. Reason: {0}'.format(e)
-			self.close()
-			logging.error(msg)
-			raise_from(restapi.OperationError(msg), e)
-
-		logging.info("Authenticated.")
-
-	@property
-	def to_url(self):
-		"""
-		The URL without the api portion. (read-only)
-		:return: The url should be in the format of
-				 '<protocol>://<hostname>[:<port>]'; [] = optional
-				 e.g https://to.somedomain.net or https://to.somedomain.net:443
-		:rtype: Text
-		"""
-
-		return self.server_url
-
-	@property
-	def base_url(self):
-		"""
-		Returns the base url. (read-only)
-		:return: The base url should be in the format of
-				 '<protocol>://<hostname>[:<port>]/api/<api version>/'; [] = optional
-				 e.g https://to.somedomain.net/api/1.2/
-		:rtype: Text
-		"""
-
-		return self._api_base_url
-
-	@property
-	def logged_in(self):
-		"""
-		Read-only property of boolean to determine if user is logged in to Traffic Ops. (read-only)
-		:return: boolean if logged in or not.
-		:rtype: bool
-		"""
-
-		return self.is_open and self._logged_in
-
-	# Programmatic Endpoint Methods - These can be created when you need to employ "creative
-	# methods" to form a correlated composite data set from one or more Traffic Ops API call(s) or
-	# employ composite operations against the API.
-	# Also, if the API requires you to retrieve the data via paging, these types of methods can be
-	# useful to perform that type of work too.
-	# These methods need to support similar method signatures as employed by the restapi.api_request decorator
-	# method_name argument.
-	def get_all_deliveryservice_servers(self, *args, **kwargs):
-		"""
-		Get all servers attached to all delivery services via the Traffic Ops API.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-		result_set = []
-		response = None
-		limit = 10000
-		page = 1
-
-		munchify = True  # Default to True
-		if u'munchify' in kwargs:
-			munchify = kwargs[u'munchify']
-
-		while True:
-			data, response = self.get_deliveryserviceserver(query_params={u'limit': limit, u'page': page},
-															munchify=munchify, *args, **kwargs)
-
-			if not data:
-				break
-
-			result_set.extend(munch.munchify(data) if munchify else data)
-			page += 1
-
-		return result_set, response  # Note: Return last response object received
-
-#
-# PUT ALL API DEFINITIONS BELOW AND UNDER ITS RESPECTIVE PAGE (whether it is 1.2 or 1.3, etc, if its a CDN put it under CDN header and corresponding calls)
-#
-
-	#
-	#	API Capabilities
-	#
-	@restapi.api_request(u'get', u'api_capabilities', (u'1.2', u'1.3',))
-	def get_api_capabilities(self, query_params=None):
-		"""
-		Get all API-capability mappings
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/api_capability.html#api-capabilities
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'api_capabilities/{id}', (u'1.2', u'1.3',))
-	def get_api_capabilities_by_id(self, id=None):
-		"""
-		Get an API-capability mapping by ID
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/api_capability.html#api-capabilities
-		:param id: The api-capabilities Id
-		:type id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# ASN
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/asn.html#api-1-2-asns
-	#
-
-	# Implemented Direct API URL Endpoint Methods
-	# See https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html #api for detail
-	@restapi.api_request(u'get', u'asns', (u'1.1', u'1.2', u'1.3',))
-	def get_asns(self, query_params=None):
-		"""
-		Get ASNs.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/asn.html#api-1-2-asns
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'asns/{asn_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_asn_by_id(self, asn_id=None):
-		"""
-		Get ASN by ID
-		:param asn_id: The ID of the ASN to retrieve
-		:type asn_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'asns/{asn_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_asn(self, asn_id=None, query_params=None):
-		"""
-		Update ASN
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/asn.html#api-1-2-asns
-		:param asn_id: The ID of the ASN to update
-		:type asn_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'asns', (u'1.1', u'1.2', u'1.3',))
-	def create_asn(self, data=None):
-		"""
-		Create ASN
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/asn.html#api-1-2-asns
-		:param data: The parameter data to use for cachegroup creation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'asns/{asn_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_asn(self, asn_id=None):
-		"""
-		Delete ASN
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/asn.html#api-1-2-asns
-		:param asn_id: The ID of the ASN to delete
-		:type asn_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Cache
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cache.html#api-1-2-caches-stats
-	#
-
-	@restapi.api_request(u'get', u'caches/stats', (u'1.1', u'1.2', u'1.3',))
-	def get_traffic_monitor_cache_stats(self):
-		"""
-		Retrieves cache stats from Traffic Monitor. Also includes rows for aggregates
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cache.html#cache
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Cache Group
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-	#
-
-	@restapi.api_request(u'get', u'cachegroups', (u'1.1', u'1.2', u'1.3',))
-	def get_cachegroups(self, query_params=None):
-		"""
-		Get Cache Groups.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	# Example of URL parameter substitution via call parameter. You will need to pass the parameter
-	# value as a keyword parameter with the proper type to match the str.format specification,
-	# e.g. 'cachegroups/{cache_group_id:d}'.  In this case, ':d' specifies a decimal integer.  A specification
-	# of 'cachegroups/{cache_group_id}' will try to convert any value passed to a string, which basically does
-	# no type checking, unless of course the value cannot be cast to a string.
-	# E.g. get_cachegroups_by_id(cache_group_id=23) -> call end-point .../api/1.2/cachegroups/23
-	@restapi.api_request(u'get', u'cachegroups/{cache_group_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_cachegroup_by_id(self, cache_group_id=None):
-		"""
-		Get a Cache Group by Id.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param cache_group_id: The cache group Id
-		:type cache_group_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cachegroups/{cache_group_id:d}/parameters', (u'1.1', u'1.2', u'1.3',))
-	def get_cachegroup_parameters(self, cache_group_id=None):
-		"""
-		Get a cache groups parameters
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param cache_group_id: The cache group Id
-		:type cache_group_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cachegroups/{cache_group_id:d}/unassigned_parameters', (u'1.1', u'1.2', u'1.3',))
-	def get_cachegroup_unassigned_parameters(self, cache_group_id=None):
-		"""
-		Get a cache groups unassigned parameters
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param cache_group_id: The cache group Id
-		:type cache_group_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cachegroup/{parameter_id:d}/parameter', (u'1.1', u'1.2', u'1.3',))
-	def get_cachegroup_parameters_by_id(self, parameter_id=None):
-		"""
-		Get a cache groups parameter by its ID
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param parameter_id: The parameter Id
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cachegroupparameters', (u'1.1', u'1.2', u'1.3',))
-	def get_all_cachegroup_parameters(self):
-		"""
-		A collection of all cache group parameters.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'cachegroups', (u'1.1', u'1.2', u'1.3',))
-	def create_cachegroups(self, data=None):
-		"""
-		Create a Cache Group
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param data: The parameter data to use for cachegroup creation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'cachegroups/{cache_group_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_cachegroups(self, cache_group_id=None, data=None):
-		"""
-		Update a cache group
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param cache_group_id: The cache group id to update
-		:type cache_group_id: Integer
-		:param data: The parameter data to use for cachegroup creation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'cachegroups/{cache_group_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_cachegroups(self, cache_group_id=None):
-		"""
-		Delete a cache group
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param cache_group_id: The cache group id to update
-		:type cache_group_id: Integer
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'cachegroups/{cache_group_id:d}/queue_update', (u'1.1', u'1.2', u'1.3',))
-	def cachegroups_queue_update(self, cache_group_id=None, data=None):
-		"""
-		Queue Updates by Cache Group ID
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup.html#cache-group
-		:param cache_group_id: The Cache Group Id
-		:type cache_group_id: int
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Cache Group Parameters
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_parameter.html#cache-group-parameters
-	#
-
-	@restapi.api_request(u'post', u'cachegroupparameters', (u'1.2', u'1.3'))
-	def assign_cache_group_parameters(self, data=None):
-		"""
-		Assign parameter(s) to cache group(s).
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_parameter.html#cache-group-parameters
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'cachegroupparameters/{cache_group_id:d}/{parameter_id:d}', (u'1.2', u'1.3'))
-	def delete_cache_group_parameters(self, cache_group_id=None, parameter_id=None):
-		"""
-		Delete a cache group parameter association
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_parameter.html#cache-group-parameters
-		:param cache_group_id: The cache group id in which the parameter will be deleted
-		:type cache_group_id: int
-		:param parameter_id: The parameter id which will be disassociated
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Cache Group Fallback
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_fallbacks.html#cache-group-fallback
-	#
-
-	@restapi.api_request(u'get', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
-	def get_cache_group_fallbacks(self, query_params=None):
-		"""
-		Retrieve fallback related configurations for a cache group
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_fallbacks.html#api-1-2-cachegroup-fallbacks
-		:param query_params: Either cacheGroupId or fallbackId must be used or can be used simultaneously
-		:type query_params: Dict[Text, int]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
-	def create_cache_group_fallbacks(self, data=None):
-		"""
-		Creates fallback configuration for the cache group. New fallbacks can be added only via POST.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_fallbacks.html#api-1-2-cachegroup-fallbacks
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
-	def update_cache_group_fallbacks(self, data=None):
-		"""
-		Updates an existing fallback configuration for the cache group.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_fallbacks.html#api-1-2-cachegroup-fallbacks
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'cachegroup_fallbacks', (u'1.2', u'1.3'))
-	def delete_cache_group_fallbacks(self, query_params=None):
-		"""
-		Deletes an existing fallback related configurations for a cache group
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cachegroup_fallbacks.html#api-1-2-cachegroup-fallbacks
-		:param query_params: Either cacheGroupId or fallbackId must be used or can be used simultaneously
-		:type query_params: Dict[Text, int]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Cache Statistics
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cache_stats.html#cache-statistics
-	#
-	@restapi.api_request(u'get', u'cache_stats', (u'1.2', u'1.3',))
-	def get_cache_stats(self, query_params=None):
-		"""
-		Retrieves statistics about the CDN.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cache_stats.html#cache-statistics
-		:param query_params: See API page for more information on accepted params
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Capabilities - Not adding for vagueness
-	#
-
-	#
-	# CDN
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#cdn
-	#
-
-	@restapi.api_request(u'get', u'cdns', (u'1.1', u'1.2', u'1.3',))
-	def get_cdns(self):
-		"""
-		Get all CDNs.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/{cdn_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_cdn_by_id(self, cdn_id=None):
-		"""
-		Get a CDN by Id.
-		:param cdn_id: The CDN id
-		:type cdn_id: Text
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/name/{cdn_name}', (u'1.1', u'1.2', u'1.3',))
-	def get_cdn_by_name(self, cdn_name=None):
-		"""
-		Get a CDN by name.
-		:param cdn_name: The CDN name
-		:type cdn_name: Text
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'cdns', (u'1.1', u'1.2', u'1.3',))
-	def create_cdn(self, data=None):
-		"""
-		Create a new CDN.
-		:param data: The parameter data to use for cdn creation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'cdns/{cdn_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_cdn_by_id(self, cdn_id=None, data=None):
-		"""
-		Update a CDN by Id.
-		:param cdn_id: The CDN id
-		:type cdn_id: int
-		:param data: The parameter data to use for cdn update.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'cdns/{cdn_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_cdn_by_id(self, cdn_id=None):
-		"""
-		Delete a CDN by Id.
-		:param cdn_id: The CDN id
-		:type cdn_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'cdns/{cdn_id:d}/queue_update', (u'1.1', u'1.2', u'1.3',))
-	def cdns_queue_update(self, cdn_id=None, data=None):
-		"""
-		Queue Updates by CDN Id.
-		:param cdn_id: The CDN Id
-		:type cdn_id: int
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# CDN Health
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#health
-	#
-
-	@restapi.api_request(u'get', u'cdns/health', (u'1.2', u'1.3',))
-	def get_cdns_health(self):
-		"""
-		Retrieves the health of all locations (cache groups) for all CDNs
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#health
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/health', (u'1.2', u'1.3',))
-	def get_cdn_health_by_name(self, cdn_name=None):
-		"""
-		Retrieves the health of all locations (cache groups) for a given CDN
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#health
-		:param cdn_name: The CDN name to find health for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/usage', (u'1.2', u'1.3',))
-	def get_cdns_usage(self):
-		"""
-		Retrieves the high-level CDN usage metrics.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#health
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/capacity', (u'1.2', u'1.3',))
-	def get_cdns_capacity(self):
-		"""
-		Retrieves the aggregate capacity percentages of all locations (cache groups) for a given CDN.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#health
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# CDN Routing
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#routing
-	#
-
-	@restapi.api_request(u'get', u'cdns/routing', (u'1.2', u'1.3',))
-	def get_cdns_routing(self):
-		"""
-		Retrieves the aggregate routing percentages of all locations (cache groups) for a given CDN.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#routing
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# CDN Metrics
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#metrics
-	# These routes are currently not implemented TODO when completed
-	#
-
-	#
-	# CDN Domains
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#domains
-	#
-
-	@restapi.api_request(u'get', u'cdns/domains', (u'1.2', u'1.3',))
-	def get_cdns_domains(self):
-		"""
-		Retrieves the different CDN domains
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#domains
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# CDN Topology
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#topology
-	#
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/configs', (u'1.2', u'1.3',))
-	def get_cdn_config_info(self, cdn_name=None):
-		"""
-		Retrieves CDN config information
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#topology
-		:param cdn_name: The CDN name to find configs for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/configs/monitoring', (u'1.2', u'1.3',))
-	def get_cdn_monitoring_info(self, cdn_name=None):
-		"""
-		Retrieves CDN monitoring information
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#topology
-		:param cdn_name: The CDN name to find configs for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/configs/routing', (u'1.2', u'1.3',))
-	def get_cdn_routing_info(self, cdn_name=None):
-		"""
-		Retrieves CDN routing information
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#topology
-		:param cdn_name: The CDN name to find routing info for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# CDN DNSSEC Keys
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#dnssec-keys
-	#
-
-	@restapi.api_request(u'get', u'cdns/name/{cdn_name:s}/dnsseckeys', (u'1.2', u'1.3',))
-	def get_cdn_dns_sec_keys(self, cdn_name=None):
-		"""
-		Gets a list of dnsseckeys for a CDN and all associated Delivery Services
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#dnssec-keys
-		:param cdn_name: The CDN name to find dnsseckeys info for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/name/{cdn_name:s}/dnsseckeys/delete', (u'1.2', u'1.3',))
-	def delete_cdn_dns_sec_keys(self, cdn_name=None):
-		"""
-		Delete dnssec keys for a cdn and all associated delivery services
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#dnssec-keys
-		:param cdn_name: The CDN name to delete dnsseckeys info for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'deliveryservices/dnsseckeys/generate', (u'1.2', u'1.3',))
-	def create_cdn_dns_sec_keys(self, data=None):
-		"""
-		Generates ZSK and KSK keypairs for a CDN and all associated Delivery Services
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#dnssec-keys
-		:param data: The parameter data to use for cachegroup creation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# CDN SSL Keys
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#ssl-keys
-	#
-
-	@restapi.api_request(u'get', u'cdns/name/{cdn_name:s}/sslkeys', (u'1.2', u'1.3',))
-	def get_cdn_ssl_keys(self, cdn_name=None):
-		"""
-		Returns ssl certificates for all Delivery Services that are a part of the CDN.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/cdn.html#ssl-keys
-		:param cdn_name: The CDN name to find ssl keys for
-		:type cdn_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Change Logs
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/changelog.html#change-logs
-	#
-
-	@restapi.api_request(u'get', u'logs', (u'1.2', u'1.3',))
-	def get_change_logs(self):
-		"""
-		Retrieve all change logs from traffic ops
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/changelog.html#change-logs
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'logs/{days:d}/days', (u'1.2', u'1.3',))
-	def get_change_logs_for_days(self, days=None):
-		"""
-		Retrieve all change logs from Traffic Ops
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/changelog.html#change-logs
-		:param days: The number of days to retrieve change logs
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'logs/newcount', (u'1.2', u'1.3',))
-	def get_change_logs_newcount(self):
-		"""
-		Get amount of new logs from traffic ops
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/changelog.html#change-logs
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Config Files and Config File Metadata
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/configfiles_ats.html#config-files-and-config-file-metadata
-	#
-
-	@restapi.api_request(u'get', u'servers/{host_name:s}/configfiles/ats', (u'1.2', u'1.3',))
-	def get_server_config_files(self, host_name=None, query_params=None):
-		"""
-		Get the configuiration files for a given host name
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/configfiles_ats.html#config-files-and-config
-		:param host_name: The host name to get config files for
-		:type host_name: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'servers/{host_name:s}/configfiles/ats/{config_file:s}', (u'1.2', u'1.3',))
-	def get_server_specific_config_file(self, host_name=None, config_file=None, query_params=None):
-		"""
-		Get the configuiration files for a given host name and config file
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/configfiles_ats.html#config-files-and-config
-		:param host_name: The host name to get config files for
-		:type host_name: String
-		:param config_file: The config file name to retrieve for host
-		:type config_file: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'profiles/{profile_name:s}/configfiles/ats/{config_file:s}', (u'1.2', u'1.3',))
-	def get_profile_specific_config_files(self, profile_name=None, config_file=None, query_params=None):
-		"""
-		Get the configuiration files for a given profile name and config file
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/configfiles_ats.html#config-files-and-config
-		:param profile_name: The profile name to get config files for
-		:type host_name: String
-		:param config_file: The config file name to retrieve for host
-		:type config_file: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/configfiles/ats/{config_file:s}', (u'1.2', u'1.3',))
-	def get_cdn_specific_config_file(self, cdn_name=None, config_file=None, query_params=None):
-		"""
-		Get the configuiration files for a given cdn name and config file
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/configfiles_ats.html#config-files-and-config
-		:param cdn_name: The cdn name to get config files for
-		:type cdn_name: String
-		:param config_file: The config file name to retrieve for host
-		:type config_file: String
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	#
-	# Delivery Service
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#delivery-service
-	#
-
-	@restapi.api_request(u'get', u'deliveryservices', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservices(self, query_params=None):
-		"""
-		Retrieves all delivery services (if admin or ops) or all delivery services assigned to user.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_by_id(self, delivery_service_id=None):
-		"""
-		Retrieves a specific delivery service. If not admin / ops, delivery service must be assigned to user.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/servers', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_servers(self, delivery_service_id=None):
-		"""
-		Retrieves properties of CDN EDGE or ORG servers assigned to a delivery service.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/servers/unassigned', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_unassigned_servers(self, delivery_service_id=None):
-		"""
-		Retrieves properties of CDN EDGE or ORG servers not assigned to a delivery service. (Currently call does not work)
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/servers/eligible', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_ineligible_servers(self, delivery_service_id=None):
-		"""
-		Retrieves properties of CDN EDGE or ORG servers not eligible for assignment to a delivery service.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'deliveryservices', (u'1.1', u'1.2', u'1.3',))
-	def create_deliveryservice(self, data=None):
-		"""
-		Allows user to create a delivery service.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param data: The request data structure for the API request
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'deliveryservices/{delivery_service_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_deliveryservice_by_id(self, delivery_service_id=None, data=None):
-		"""
-		Update a Delivery Service by Id.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:param data: The request data structure for the API request
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'deliveryservices/{delivery_service_id:d}/safe', (u'1.1', u'1.2', u'1.3',))
-	def update_deliveryservice_safe(self, delivery_service_id=None, data=None):
-		"""
-		Allows a user to edit limited fields of an assigned delivery service.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:param data: The request data structure for the API request
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'delete', u'deliveryservices/{delivery_service_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_deliveryservice_by_id(self, delivery_service_id=None):
-		"""
-		Allows user to delete a delivery service.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#api-1-2-deliveryservices
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Delivery Service Health
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#health
-	#
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/state', (u'1.1', u'1.2', u'1.3',))
-	def get_delivery_service_failover_state(self, delivery_service_id=None):
-		"""
-		Retrieves the failover state for a delivery service. Delivery service must be assigned to user if user is not admin or operations.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#health
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/health', (u'1.1', u'1.2', u'1.3',))
-	def get_delivery_service_health(self, delivery_service_id=None):
-		"""
-		Retrieves the health of all locations (cache groups) for a delivery service. Delivery service must be assigned to user if user is not admin or operations.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#health
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/capacity', (u'1.1', u'1.2', u'1.3',))
-	def get_delivery_service_capacity(self, delivery_service_id=None):
-		"""
-		Retrieves the capacity percentages of a delivery service. Delivery service must be assigned to user if user is not admin or operations.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#health
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/routing', (u'1.1', u'1.2', u'1.3',))
-	def get_delivery_service_routing(self, delivery_service_id=None):
-		"""
-		Retrieves the routing method percentages of a delivery service. Delivery service must be assigned to user if user is not admin or operations.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#health
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Delivery Service Server
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#delivery-service-server
-	#
-
-	@restapi.api_request(u'get', u'deliveryserviceserver', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryserviceserver(self, query_params=None):
-		"""
-		Retrieves delivery service / server assignments. (Allows pagination and limits)
-		:param query_params: The required url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'deliveryserviceserver', (u'1.1', u'1.2', u'1.3',))
-	def assign_deliveryservice_servers_by_ids(self, data=None):
-		"""
-		Assign servers by id to a Delivery Service. (New Method)
-		:param data: The required data to create server associations to a delivery service
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'deliveryservices/{xml_id}/servers', (u'1.1', u'1.2', u'1.3',))
-	def assign_deliveryservice_servers_by_names(self, xml_id=None, data=None):
-		"""
-		Assign servers by name to a Delivery Service by xmlId. (Old Method)
-		:param xml_id: The XML Id of the delivery service
-		:type xml_id: Text
-		:param data: The required data to assign servers to a delivery service
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'deliveryservice_server/{delivery_service_id:d}/{server_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_deliveryservice_servers_by_id(self, delivery_service_id=None, server_id=None):
-		"""
-		Removes a server (cache) from a delivery service.
-		:param delivery_service_id: The delivery service id
-		:type delivery_service_id: int
-		:param server_id: The server id to remove from delivery service
-		:type server_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Delivery Service User
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#delivery-service-user
-	#
-
-	@restapi.api_request(u'post', u'deliveryservice_user', (u'1.2', u'1.3'))
-	def create_delivery_service_user_link(self, data=None):
-		"""
-		Create one or more user / delivery service assignments.
-		:param data: The parameter data to use for Delivery Service SSL key generation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'deliveryservice_user/{delivery_service_id:d}/{user_id:d}', (u'1.2', u'1.3'))
-	def delete_delivery_service_user_link(self, delivery_service_id=None, user_id=None):
-		"""
-		Removes a delivery service from a user.
-		:param delivery_service_id: The delivery service id to dissasociate the user
-		:type delivery_service_id: int
-		:param user_id: The user id to dissassociate
-		:type user_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	#
-	# Delivery Service SSL Keys
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#ssl-keys
-	#
-
-	@restapi.api_request(u'get', u'deliveryservices/xmlId/{xml_id}/sslkeys', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_ssl_keys_by_xml_id(self, xml_id=None, query_params=None):
-		"""
-		Get SSL keys for a Delivery Service by xmlId.
-		:param xml_id: The Delivery Service XML id
-		:type xml_id: Text
-		:param query_params: The url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/xmlId/{xml_id}/sslkeys/delete', (u'1.1', u'1.2', u'1.3',))
-	def delete_deliveryservice_ssl_keys_by_xml_id(self, xml_id=None, query_params=None):
-		"""
-		Delete SSL keys for a Delivery Service by xmlId.
-		:param xml_id: The Delivery Service xmlId
-		:type xml_id: Text
-		:param query_params: The url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'deliveryservices/sslkeys/generate', (u'1.1', u'1.2', u'1.3',))
-	def generate_deliveryservice_ssl_keys(self, data=None):
-		"""
-		Generate an SSL certificate. (self-signed)
-		:param data: The parameter data to use for Delivery Service SSL key generation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'deliveryservices/sslkeys/add', (u'1.1', u'1.2', u'1.3',))
-	def add_ssl_keys_to_deliveryservice(self, data=None):
-		"""
-		Add SSL keys to a Delivery Service.
-		:param data: The parameter data to use for adding SSL keys to a Delivery Service.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Delivery Service URL Sig Keys
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice.html#url-sig-keys
-	#
-
-	@restapi.api_request(u'post', u'deliveryservices/xmlId/{xml_id}/urlkeys/generate', (u'1.1', u'1.2', u'1.3',))
-	def generate_deliveryservice_url_signature_keys(self, xml_id=None):
-		"""
-		Generate URL Signature Keys for a Delivery Service by xmlId.
-		:param xml_id: The Delivery Service xmlId
-		:type xml_id: Text
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Delivery Service Regexes
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice_regex.html#delivery-service-regexes
-	#
-
-	@restapi.api_request(u'get', u'deliveryservices_regexes', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservices_regexes(self):
-		"""
-		Get RegExes for all Delivery Services.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/regexes', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_regexes_by_id(self, delivery_service_id=None):
-		"""
-		Get RegExes for a Delivery Service by Id.
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'deliveryservices/{delivery_service_id:d}/regexes/{regex_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_deliveryservice_regexes_by_regex_id(self, delivery_service_id=None, regex_id=None):
-		"""
-		Retrieves a regex for a specific delivery service.
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:param regex_id: The delivery service regex id
-		:type regex_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'deliveryservices/{delivery_service_id:d}/regexes', (u'1.1', u'1.2', u'1.3',))
-	def create_deliveryservice_regexes(self, delivery_service_id=None, data=None):
-		"""
-		Create a regex for a delivery service
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:param data: The required data to create delivery service regexes
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'deliveryservices/{delivery_service_id:d}/regexes/{regex_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_deliveryservice_regexes(self, delivery_service_id=None, regex_id=None, query_params=None):
-		"""
-		Update a regex for a delivery service
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:param regex_id: The delivery service regex id
-		:type regex_id: int
-		:param query_params: The required data to update delivery service regexes
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'deliveryservices/{delivery_service_id:d}/regexes/{delivery_service_regex_id:d}',
-						 (u'1.1', u'1.2', u'1.3',))
-	def delete_deliveryservice_regex_by_regex_id(self, delivery_service_id=None, delivery_service_regex_id=None):
-		"""
-		Delete a RegEx by Id for a Delivery Service by Id.
-		:param delivery_service_id: The delivery service Id
-		:type delivery_service_id: int
-		:param delivery_service_regex_id: The delivery service regex Id
-		:type delivery_service_regex_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Delivery Service Statistics
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/deliveryservice_stats.html#delivery-service-statistics
-	#
-
-	@restapi.api_request(u'get', u'deliveryservice_stats.json', (u'1.1', u'1.2', u'1.3',))
-	def get_delivery_service_stats(self, query_params=None):
-		"""
-		Retrieves statistics on the delivery services.
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Divisions
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/division.html#divisions
-	#
-
-	@restapi.api_request(u'get', u'divisions', (u'1.1', u'1.2', u'1.3',))
-	def get_divisions(self):
-		"""
-		Get all divisions.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'divisions/{division_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_division_by_id(self, division_id=None):
-		"""
-		Get a division by division id
-		:param division_id: The division id to retrieve
-		:type division_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'divisions/{division_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_division(self, division_id=None, query_params=None):
-		"""
-		Update a division by division id
-		:param division_id: The division id to update
-		:type division_id: int
-		:param query_params: The required data to update delivery service regexes
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'divisions', (u'1.1', u'1.2', u'1.3',))
-	def create_division(self, data=None):
-		"""
-		Create a division
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'divisions/{division_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_division(self, division_id=None, query_params=None):
-		"""
-		Delete a division by division id
-		:param division_id: The division id to delete
-		:type division_id: int
-		:param query_params: The required data to update delivery service regexes
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Federation
-	#
-	#
-
-
-	@restapi.api_request(u'get', u'federations', (u'1.2', u'1.3'))
-	def get_federations(self):
-		"""
-		Retrieves a list of federation mappings (aka federation resolvers) for a the current user
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'federations', (u'1.2', u'1.3'))
-	def create_federation(self, data=None):
-		"""
-		Allows a user to add federations for their delivery service(s).
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/federations', (u'1.2', u'1.3'))
-	def get_federations_for_cdn(self, cdn_name=None):
-		"""
-		Retrieves a list of federations for a cdn.
-		:param cdn_name: The CDN name to find federation
-		:type cdn_name: String
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name:s}/federations/{federation_id:d}', (u'1.2', u'1.3'))
-	def get_federation_for_cdn_by_id(self, cdn_name=None, federation_id=None):
-		"""
-		Retrieves a federation for a cdn.
-		:param cdn_name: The CDN name to find federation
-		:type cdn_name: String
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'cdns/{cdn_name:s}/federations', (u'1.2', u'1.3'))
-	def create_federation_in_cdn(self, cdn_name=None, data=None):
-		"""
-		Create a federation.
-		:param cdn_name: The CDN name to find federation
-		:type cdn_name: String
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'cdns/{cdn_name:s}/federations/{federation_id:d}', (u'1.2', u'1.3'))
-	def update_federation_in_cdn(self, cdn_name=None, federation_id=None, query_params=None):
-		"""
-		Update a federation.
-		:param cdn_name: The CDN name to find federation
-		:type cdn_name: String
-		:param federation_id: The federation id
-		:type federation_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'cdns/{cdn_name:s}/federations/{federation_id:d}', (u'1.2', u'1.3'))
-	def delete_federation_in_cdn(self, cdn_name=None, federation_id=None):
-		"""
-		Delete a federation.
-		:param cdn_name: The CDN name to find federation
-		:type cdn_name: String
-		:param federation_id: The federation id
-		:type federation_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Federation Delivery Service
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/federation_deliveryservice.html
-	#
-
-	@restapi.api_request(u'get', u'federations/{federation_id:d}/deliveryservices', (u'1.2', u'1.3'))
-	def get_federation_delivery_services(self, federation_id=None):
-		"""
-		Retrieves delivery services assigned to a federation
-		:param federation_id: The federation id
-		:type federation_id: int
-		:param federation_id: The federation id
-		:type federation_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'federations/{federation_id:d}/deliveryservices', (u'1.2', u'1.3'))
-	def assign_delivery_services_to_federations(self, federation_id=None, data=None):
-		"""
-		Create one or more federation / delivery service assignments.
-		:param federation_id: The federation id
-		:type federation_id: int
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'federation_resolvers/{federation_id:d}/deliveryservices/{delivery_service_id:d}', (u'1.2', u'1.3'))
-	def delete_federation_resolver(self, federation_resolver_id=None, delivery_service_id=None):
-		"""
-		Removes a delivery service from a federation.
-		:param federation_id: The federation id
-		:type federation_id: int
-		:param federation_id: The delivery service id
-		:type federation_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Federation Federation Resolver
-	#
-	#
-
-	@restapi.api_request(u'get', u'federations/{federation_id:d}/federation_resolvers', (u'1.2', u'1.3'))
-	def get_federation_resolvers_by_id(self, federation_id=None):
-		"""
-		Retrieves federation resolvers assigned to a federation
-		:param federation_id: The federation id
-		:type federation_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'federations/{federation_id:d}/federation_resolvers', (u'1.2', u'1.3'))
-	def assign_federation_resolver_to_federations(self, federation_id=None, data=None):
-		"""
-		Create one or more federation / federation resolver assignments.
-		:param federation_id: The federation id
-		:type federation_id: int
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Federation Resolver
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/federation_resolver.html#federation-resolver
-	#
-
-	@restapi.api_request(u'get', u'federation_resolvers', (u'1.2', u'1.3'))
-	def get_federation_resolvers(self, query_params=None):
-		"""
-		Get federation resolvers.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'federation_resolvers', (u'1.2', u'1.3'))
-	def create_federation_resolver(self, data=None):
-		"""
-		Create a federation resolver.
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'federation_resolvers/{federation_resolver_id:d}', (u'1.2', u'1.3'))
-	def delete_federation_resolver(self, federation_resolver_id=None):
-		"""
-		Delete a federation resolver.
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	#
-	# Federation User
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/federation_user.html#federation-user
-	#
-
-	@restapi.api_request(u'get', u'federations/{federation_id:d}/users', (u'1.2', u'1.3'))
-	def get_federation_users(self, federation_id=None):
-		"""
-		Retrieves users assigned to a federation.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'federations/{federation_id:d}/users', (u'1.2', u'1.3'))
-	def create_federation_user(self, federation_id=None, data=None):
-		"""
-		Create one or more federation / user assignments.
-		:param federation_id: Federation ID
-		:type federation_id: int
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'federations/{federation_id:d}/users/{user_id:d}', (u'1.2', u'1.3'))
-	def delete_federation_user(self, federation_id=None, user_id=None):
-		"""
-		Delete one or more federation / user assignments.
-		:param federation_id: Federation ID
-		:type federation_id: int
-		:param user_id: Federation User ID
-		:type user_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Hardware Info
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/hwinfo.html#hardware-info
-	#
-
-	@restapi.api_request(u'get', u'hwinfo.json', (u'1.2', u'1.3'))
-	def get_hwinfo(self):
-		"""
-		Get hwinfo for servers.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	#
-	# ISO
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/iso.html#iso
-	#
-
-	@restapi.api_request(u'get', u'osversions', (u'1.2', u'1.3'))
-	def get_osversions(self):
-		"""
-		Get all OS versions for ISO generation and the directory where the kickstarter files are found.
-		The values are retrieved from osversions.cfg found in either /var/www/files or in the location defined by the kickstart.files.location parameter (if defined).
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'isos', (u'1.2', u'1.3',))
-	def generate_iso(self, data=None):
-		"""
-		Generate an ISO
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Jobs
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/job.html#jobs
-	#
-
-	@restapi.api_request(u'get', u'jobs', (u'1.2', u'1.3'))
-	def get_jobs(self, query_params=None):
-		"""
-		Get all jobs (currently limited to invalidate content (PURGE) jobs) sorted by start time (descending).
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'jobs/{job_id:d}', (u'1.2', u'1.3'))
-	def get_job_by_id(self, job_id=None):
-		"""
-		Get a job by ID (currently limited to invalidate content (PURGE) jobs).
-		:param job_id: The job id to retrieve
-		:type job_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Parameter
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/parameter.html#parameter
-	#
-
-	@restapi.api_request(u'get', u'parameters', (u'1.2', u'1.3',))
-	def get_parameters(self):
-		"""
-		Get all Profile Parameters.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'parameters/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_parameter_by_id(self, parameter_id=None):
-		"""
-		Get a Parameter by Id.
-		:param parameter_id: The parameter Id
-		:type parameter_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'parameters/{parameter_id:d}/profiles', (u'1.1', u'1.2', u'1.3',))
-	def get_associated_profiles_by_parameter_id(self, parameter_id=None):
-		"""
-		Get all Profiles associated to a Parameter by Id.
-		:param parameter_id: The parameter id
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'parameters/{parameter_id:d}/unassigned_profiles', (u'1.1', u'1.2', u'1.3',))
-	def get_unassigned_profiles_by_parameter_id(self, parameter_id=None):
-		"""
-		Retrieves all profiles NOT assigned to the parameter.
-		:param parameter_id: The parameter id
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'get', u'profiles/{id:d}/parameters', (u'1.1', u'1.2', u'1.3',))
-	def get_parameters_by_profile_id(self, profile_id=None):
-		"""
-		Get all Parameters associated with a Profile by Id.
-		:param profile_id: The profile Id
-		:type profile_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'profiles/{id:d}/unassigned_parameters', (u'1.1', u'1.2', u'1.3',))
-	def get_unnassigned_parameters_by_profile_id(self, profile_id=None):
-		"""
-		Get all Parameters associated with a Profile by Id.
-		:param profile_id: The profile Id
-		:type profile_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'profiles/name/{profile_name}/parameters', (u'1.1', u'1.2', u'1.3',))
-	def get_parameters_by_profile_name(self, profile_name=None):
-		"""
-		Get all Parameters associated with a Profile by Name.
-		:param profile_name: The profile name
-		:type profile_name: Text
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'parameters', (u'1.1', u'1.2', u'1.3',))
-	def create_parameter(self, data=None):
-		"""
-		Create Parameter
-		:param data: The parameter(s) data to use for parameter creation.
-		:type data: Union[Dict[Text, Any], List[Dict[Text, Any]]]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'parameters/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_parameter(self, parameter_id=None, query_params=None):
-		"""
-		Update Parameter
-		:param parameter_id: The parameter id to update
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'delete', u'parameters/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_parameter(self, parameter_id=None):
-		"""
-		Delete Parameter
-		:param parameter_id: The parameter id to delete
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'parameters/validate', (u'1.1', u'1.2', u'1.3',))
-	def validate_parameter_exists(self, data=None):
-		"""
-		Validate that a Parameter exists.
-		:param data: The parameter data to use for parameter validation.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Physical Location
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/phys_location.html#physical-location
-	#
-
-	@restapi.api_request(u'get', u'phys_locations', (u'1.1', u'1.2', u'1.3',))
-	def get_physical_locations(self, query_params=None):
-		"""
-		Get Physical Locations.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'phys_locations/trimmed.json', (u'1.1', u'1.2', u'1.3',))
-	def get_trimmed_physical_locations(self):
-		"""
-		Get Physical Locations with name only
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'phys_locations/{physical_location_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_physical_location_by_id(self, physical_location_id=None):
-		"""
-		Get Physical Location by id
-		:param physical_location_id: The id to retrieve
-		:type physical_location_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'phys_locations/{physical_location_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_physical_location(self, physical_location_id=None, query_params=None):
-		"""
-		Update Physical Location by id
-		:param physical_location_id: The id to update
-		:type physical_location_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'regions/{region_name:s}/phys_locations', (u'1.1', u'1.2', u'1.3',))
-	def create_physical_location(self, region_name=None, query_params=None):
-		"""
-		Create physical location
-		:param region_name: the name of the region to create physical location into
-		:type region_name: String
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'phys_locations/{physical_location_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_physical_location(self, physical_location_id=None, query_params=None):
-		"""
-		Delete Physical Location by id
-		:param physical_location_id: The id to delete
-		:type physical_location_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Profiles
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/profile.html#profiles
-	#
-
-	@restapi.api_request(u'get', u'profiles', (u'1.1', u'1.2', u'1.3',))
-	def get_profiles(self, query_params=None):
-		"""
-		Get Profiles.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'profiles/trimmed', (u'1.1', u'1.2', u'1.3',))
-	def get_trimmed_profiles(self):
-		"""
-		Get Profiles with names only
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'profiles/{profile_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_profile_by_id(self, profile_id=None):
-		"""
-		Get Profile by Id.
-		:param profile_id: The profile Id
-		:type profile_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'profiles', (u'1.1', u'1.2', u'1.3',))
-	def create_profile(self, data=None):
-		"""
-		Create a profile
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'profiles/name/{new_profile_name:s}/copy/{copy_profile_name:s}', (u'1.1', u'1.2', u'1.3',))
-	def copy_profile(self, new_profile_name=None, copy_profile_name=None, data=None):
-		"""
-		Copy profile to a new profile. The new profile name must not exist
-		:param new_profile_name: The name of profile to copy to
-		:type new_profile_name: String
-		:param copy_profile_name: The name of profile copy from
-		:type copy_profile_name: String
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'profiles/{profile_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_profile_by_id(self, profile_id=None, data=None):
-		"""
-		Update Profile by Id.
-		:param profile_id: The profile Id
-		:type profile_id: int
-		:param data: The parameter data to edit
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'profiles/{profile_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_profile_by_id(self, profile_id=None):
-		"""
-		Delete Profile by Id.
-		:param profile_id: The profile Id
-		:type profile_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Profile Parameters
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/profile_parameter.html#api-1-2-profileparameters
-	#
-
-	@restapi.api_request(u'post', u'profileparameters', (u'1.1', u'1.2', u'1.3',))
-	def associate_paramater_to_profile(self, data=None):
-		"""
-		Associate parameter to profile.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'profiles/id/{profile_id:d}/parameters', (u'1.1', u'1.2', u'1.3',))
-	def associate_parameters_by_profile_id(self, profile_id=None, data=None):
-		"""
-		Associate Parameters to a Profile by Id.
-		:param profile_id: The profile id
-		:type profile_id: int
-		:param data: The parameter data to associate
-		:type data: Union[Dict[Text, Any], List[Dict[Text, Any]]]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'profileparameter', (u'1.1', u'1.2', u'1.3',))
-	def assign_profile_to_parameter_ids(self, data=None):
-		"""
-		Create one or more profile / parameter assignments.
-		:param data: The data to assign
-		:type data: Union[Dict[Text, Any], List[Dict[Text, Any]]]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'parameterprofile', (u'1.1', u'1.2', u'1.3',))
-	def assign_parameter_to_profile_ids(self, data=None):
-		"""
-		Create one or more parameter / profile assignments.
-		:param data: The data to assign
-		:type data: Union[Dict[Text, Any], List[Dict[Text, Any]]]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	@restapi.api_request(u'post', u'profiles/name/{profile_name}/parameters', (u'1.1', u'1.2', u'1.3',))
-	def associate_parameters_by_profile_name(self, profile_name=None, data=None):
-		"""
-		Associate Parameters to a Profile by Name.
-		:param profile_name: The profile name
-		:type profile_name: Text
-		:param data: The parameter data to associate
-		:type data: Union[Dict[Text, Any], List[Dict[Text, Any]]]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'profileparameters/{profile_id:d}/{parameter_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_profile_parameter_association_by_id(self, profile_id=None, parameter_id=None):
-		"""
-		Delete Parameter association by Id for a Profile by Id.
-		:param profile_id: The profile id
-		:type profile_id: int
-		:param parameter_id: The parameter id
-		:type parameter_id: int
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-
-	#
-	# InfluxDB
-	# Documentation is unknown and call will not be documented
-	#
-
-	#
-	# Regions
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/region.html#regions
-	#
-
-	@restapi.api_request(u'get', u'regions', (u'1.1', u'1.2', u'1.3',))
-	def get_regions(self):
-		"""
-		Get Regions.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/region.html#regions
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'regions/{region_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_region_by_id(self, region_id=None):
-		"""
-		Get Region by ID
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/region.html#regions
-		:param region_id: The region id of the region to retrieve
-		:type region_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'regions/{region_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_region(self, region_id=None):
-		"""
-		Update a region
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-		:parma region_id: The region to update
-		:type region_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'divisions/{division_name:s}/regions', (u'1.1', u'1.2', u'1.3',))
-	def create_region(self, division_name=None, data=None):
-		"""
-		Create a region
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-		:param division_name: The Division name in which region will reside
-		:type division_name: String
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-
-
-	#
-	# Roles
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/role.html#roles
-	#
-
-	@restapi.api_request(u'get', u'roles', (u'1.1', u'1.2', u'1.3',))
-	def get_roles(self):
-		"""
-		Get Roles.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Server
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/server.html#server
-	#
-
-	@restapi.api_request(u'get', u'servers', (u'1.1', u'1.2',u'1.3',))
-	def get_servers(self, query_params=None):
-		"""
-		Get Servers.
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'servers/{server_id:d}', (u'1.1', u'1.2',u'1.3',))
-	def get_server_by_id(self, server_id=None):
-		"""
-		Get Server by Server ID
-		:param server_id: The server id to retrieve
-		:type server_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'servers/{server_id:d}/deliveryservices', (u'1.1', u'1.2',u'1.3',))
-	def get_server_delivery_services(self, server_id=None):
-		"""
-		Retrieves all delivery services assigned to the server
-		:param server_id: The server id to retrieve
-		:type server_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'servers/total', (u'1.1', u'1.2',u'1.3',))
-	def get_server_type_count(self):
-		"""
-		Retrieves a count of CDN servers by type
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'servers/status', (u'1.1', u'1.2',u'1.3',))
-	def get_server_status_count(self):
-		"""
-		Retrieves a count of CDN servers by status
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'servers/hostname/{name}/details', (u'1.1', u'1.2', u'1.3',))
-	def get_server_details(self, name=None):
-		"""
-		#GET /api/1.2/servers/hostname/:name/details
-		Get server details from trafficOps
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/server.html
-		:param hostname: Server hostname
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'servercheck', (u'1.1', u'1.2', u'1.3',))
-	def create_servercheck(self, data=None):
-		"""
-		Post a server check result to the serverchecks table.
-		:param data: The parameter data to use for server creation
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'servers', (u'1.1', u'1.2', u'1.3',))
-	def create_server(self, data=None):
-		"""
-		Create a new Server.
-		:param data: The parameter data to use for server creation
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'servers/{server_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_server_by_id(self, server_id=None, data=None):
-		"""
-		Update a Server by Id.
-		:param server_id: The server Id
-		:type server_id: int
-		:param data: The parameter data to edit
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-	@restapi.api_request(u'put', u'servers/{server_id:d}/status', (u'1.1', u'1.2', u'1.3',))
-	def update_server_status_by_id(self, server_id=None, data=None):
-		"""
-		Update server_status by Id.
-		:param server_id: The server Id
-		:type server_id: int
-		:status: https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/server.html
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'servers/{server_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def delete_server_by_id(self, server_id=None):
-		"""
-		Delete a Server by Id.
-		:param server_id: The server Id
-		:type server_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'servers/{server_id:d}/queue_update', (u'1.1', u'1.2', u'1.3',))
-	def servers_queue_update(self, server_id=None, data=None):
-		"""
-		Queue Updates by Server Id.
-		:param server_id: The server Id
-		:type server_id: int
-		:param data: The update action.  QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Static DNS Entries
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/static_dns.html#api-1-2-staticdnsentries
-	#
-
-	@restapi.api_request(u'get', u'staticdnsentries', (u'1.1', u'1.2', ))
-	def get_static_dns_entries(self):
-		"""
-		Get Static DNS Entries.
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'staticdnsentries', (u'1.1', u'1.2', u'1.3',))
-	def get_staticdnsentries(self, query_params=None):
-		"""
-		Get static DNS entries associated with the delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/staticdnsentry.html#api-1-3-staticdnsentries
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'staticdnsentries', (u'1.3',))
-	def create_staticdnsentries(self, data=None):
-		"""
-		Create static DNS entries associated with the delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/staticdnsentry.html#api-1-3-staticdnsentries
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'staticdnsentries', (u'1.3',))
-	def update_staticdnsentries(self, data=None, query_params=None):
-		"""
-		Update static DNS entries associated with the delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/staticdnsentry.html#api-1-3-staticdnsentries
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'staticdnsentries', (u'1.3',))
-	def delete_staticdnsentries(self, query_params=None):
-		"""
-		Delete static DNS entries associated with the delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/staticdnsentry.html#api-1-3-staticdnsentries
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Status
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/status.html#api-1-2-statuses
-	#
-
-	@restapi.api_request(u'get', u'statuses', (u'1.1', u'1.2', u'1.3',))
-	def get_statuses(self):
-		"""
-		Retrieves a list of the server status codes available.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/status.html#api-1-2-statuses
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'statuses/{status_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_statuses_by_id(self, status_id=None):
-		"""
-		Retrieves a server status by ID.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/status.html#api-1-2-statuses
-		:param status_id: The status id to retrieve
-		:type status_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Steering Targets
-	#
-	#
-
-	#
-	# System
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/system.html#api-1-1-system
-	#
-
-	@restapi.api_request(u'get', u'system/info.json', (u'1.1', u'1.2', u'1.3',))
-	def get_system_info(self):
-		"""
-		Get information on the traffic ops system.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/system.html#api-1-1-system
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	#
-	# Tenants
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-	#
-
-	@restapi.api_request(u'get', u'tenants', (u'1.1', u'1.2', u'1.3',))
-	def get_tenants(self):
-		"""
-		Get all tenants.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'tenants/{tenant_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_tenant_by_id(self, tenant_id=None):
-		"""
-		Get a tenant by ID.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-		:param tenant_id: The tenant to retrieve
-		:type tenant_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'tenants/{tenant_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def update_tenant(self, tenant_id=None):
-		"""
-		Update a tenant
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-		:param tenant_id: The tenant to update
-		:type tenant_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'tenants', (u'1.1', u'1.2', u'1.3',))
-	def create_tenant(self, data=None):
-		"""Create a tenant
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/tenant.html#tenants
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-	#
-	# TO Extensions
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/to_extension.html#to-extensions
-	#
-
-	@restapi.api_request(u'get', u'to_extensions.json', (u'1.1', u'1.2', u'1.3',))
-	def get_to_extensions(self):
-		"""
-		Retrieves the list of extensions.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/to_extension.html#to-extensions
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'to_extensions', (u'1.1', u'1.2', u'1.3',))
-	def create_to_extension(self, data=None):
-		"""
-		Creates a Traffic Ops extension.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/to_extension.html#to-extensions
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'to_extensions/{extension_id:d}/delete', (u'1.1', u'1.2', u'1.3',))
-	def delete_to_extension(self, extension_id=None):
-		"""
-		Deletes a Traffic Ops extension.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/to_extension.html#to-extensions
-		:param extension_id: The extension id to delete
-		:type extension_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Types
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/type.html#api-1-2-types
-	#
-
-	@restapi.api_request(u'get', u'types', (u'1.1', u'1.2', u'1.3',))
-	def get_types(self, query_params=None):
-		"""
-		Get Data Types.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/type.html#api-1-2-types
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'types/trimmed', (u'1.1', u'1.2', u'1.3',))
-	def get_types_only_names(self):
-		"""
-		Get Data Types with only the Names
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/type.html#api-1-2-types
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'types/{type_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_type_by_id(self, type_id=None):
-		"""
-		Get Data Type with the given type id
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/type.html#api-1-2-types
-		:param type_id: The ID of the type to retrieve
-		:type type_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Users
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-	#
-
-	@restapi.api_request(u'get', u'users', (u'1.1', u'1.2', u'1.3',))
-	def get_users(self):
-		"""
-		Retrieves all users.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'users/{user_id:d}', (u'1.1', u'1.2', u'1.3',))
-	def get_user_by_id(self, user_id=None):
-		"""
-		Retrieves user by ID.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:param user_id: The user to retrieve
-		:type user_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'users', (u'1.1', u'1.2', u'1.3',))
-	def create_user(self, data=None):
-		"""
-		Create a user.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'users/register', (u'1.1', u'1.2', u'1.3',))
-	def create_user_with_registration(self, data=None):
-		"""
-		Register a user and send registration email
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'users/{user_id:d}/deliveryservices', (u'1.1', u'1.2', u'1.3',))
-	def get_user_delivery_services(self, user_id=None):
-		"""
-		Retrieves all delivery services assigned to the user.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:param user_id: The user to retrieve
-		:type user_id: int
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'user/current', (u'1.1', u'1.2', u'1.3',))
-	def get_authenticated_user(self):
-		"""
-		Retrieves the profile for the authenticated user.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'user/current/jobs.json', (u'1.1', u'1.2', u'1.3',))
-	def get_authenticated_user_jobs(self):
-		"""
-		Retrieves the user's list of jobs.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/user_current_jobs.html
-
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'user/current/jobs', (u'1.1', u'1.2', u'1.3',))
-	def create_invalidation_job(self, data=None):
-		"""
-		Invalidating content on the CDN is sometimes necessary when the origin was mis-configured and something is cached in the CDN that needs to be removed.
-		Given the size of a typical Traffic Control CDN and the amount of content that can be cached in it, removing the content from all the caches may take a long time.
-		To speed up content invalidation, Traffic Ops will not try to remove the content from the caches, but it makes the content inaccessible using the regex_revalidate ATS plugin (https://docs.trafficserver.apache.org/en/latest/admin-guide/plugins/regex_revalidate.en.html).
-		This forces a revalidation of the content, rather than a new get..
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/user.html#api-1-2-users
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Snapshot CRConfig
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/topology.html#snapshot-crconfig
-	#
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name}/snapshot', (u'1.2', u'1.3',))
-	def get_current_snapshot_crconfig(self, cdn_name=None):
-		"""
-		Retrieves the CURRENT snapshot for a CDN which doesn't necessarily represent the current state of the CDN.
-		The contents of this snapshot are currently used by Traffic Monitor and Traffic Router.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/cdns_name_snapshot.html
-		:param cdn_name: The CDN name
-		:type cdn_name: Text
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'get', u'cdns/{cdn_name}/snapshot/new', (u'1.2', u'1.3',))
-	def get_pending_snapshot_crconfig(self, cdn_name=None):
-		"""
-		Retrieves a PENDING snapshot for a CDN which represents the current state of the CDN.
-		The contents of this snapshot are NOT currently used by Traffic Monitor and Traffic Router.
-		Once a snapshot is performed, this snapshot will become the CURRENT snapshot and will be used by Traffic Monitor and Traffic Router.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/topology.html#snapshot-crconfig
-		:param cdn_name: The CDN name
-		:type cdn_name: Text
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'snapshot/{cdn_name}', (u'1.2', u'1.3',))
-	def snapshot_crconfig(self, cdn_name=None):
-		"""
-		Snapshot CRConfig by CDN Name.
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v12/topology.html#snapshot-crconfig
-		:param cdn_name: The CDN name
-		:type cdn_name: Text
-		:rtype: Tuple[Dict[Text, Any], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-
-
-	#
-	# Coordinate
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/coordinate.html#coordinate
-	#
-
-	@restapi.api_request(u'get', u'coordinates', (u'1.3',))
-	def get_coordinates(self, query_params=None):
-		"""
-		Get all coordinates associated with the cdn
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/coordinate.html#coordinate
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'coordinates', (u'1.3'))
-	def create_coordinates(self, data=None):
-		"""
-		Create coordinates
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/coordinate.html#coordinate
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'coordinates', (u'1.3'))
-	def update_coordinates(self, query_params=None, data=None):
-		"""
-		Update coordinates
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/coordinate.html#coordinate
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'coordinates', (u'1.3'))
-	def delete_coordinates(self, query_params=None):
-		"""
-		Delete coordinates
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/coordinate.html#coordinate
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	#
-	# Origin
-	# https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/origin.html#api-1-3-origins
-	#
-
-	@restapi.api_request(u'get', u'origins', (u'1.3',))
-	def get_origins(self, query_params=None):
-		"""
-		Get origins associated with the delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/origin.html#api-1-3-origins
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'post', u'origins', (u'1.3',))
-	def create_origins(self, data=None):
-		"""
-		Creates origins associated with a delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/origin.html#api-1-3-origins
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'put', u'origins', (u'1.3',))
-	def update_origins(self, query_params=None):
-		"""
-		Updates origins associated with a delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/origin.html#api-1-3-origins
-		:param data: The update action. QueueUpdateRequest() can be used for this argument also.
-		:type data: Dict[Text, Any]
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	@restapi.api_request(u'delete', u'origins', (u'1.3',))
-	def delete_origins(self, query_params=None):
-		"""
-		Updates origins associated with a delivery service
-		https://traffic-control-cdn.readthedocs.io/en/latest/api/v13/origin.html#api-1-3-origins
-		:param query_params: The optional url query parameters for the call
-		:type query_params: Dict[Text, Any]
-		:rtype: Tuple[Union[Dict[Text, Any], List[Dict[Text, Any]]], requests.Response]
-		:raises: Union[trafficops.restapi.LoginError, trafficops.restapi.OperationError]
-		"""
-
-	# Extra things here
-
-	@restapi.api_request("get", "servers/{servername:s}/configfiles/ats", ("1.3",))
-	def getServerConfigFiles(self, servername=None):
-		"""
-		Fetches the configuration files for a server with the given short hostname
-		:param servername: The short hostname of the server
-		:returns: The response content and actual response object
-		"""
-
-	####################################################################################
-
-	####                          Data Model Overrides                              ####
-
-	####################################################################################
-
-	def __enter__(self):
-		"""
-		Implements context-management for ToSessions. This will open the session by sending a
-		connection request immediately, rather than waiting for login.
-
-		:returns: The constructed object (:meth:`__init__` is called implicitly prior to this method)
-		"""
-		self.create()
-		return self
-
-	def __exit__(self, exc_type, exc_value, traceback):
-		"""
-		Implements context-management for TOSessions. This will close the underlying socket.
-		"""
-		self.close()
-
-		if exc_type:
-			logging.error("%s", exc_value)
-			logging.debug("%s", exc_type, stack_info=traceback)
-
-
-
-
-if __name__ == u'__main__':
-	# Sample usages
-	import sys
-	import operator
-
-	DEBUG = False
-
-	logging.basicConfig(stream=sys.stderr, level=logging.INFO if not DEBUG else logging.DEBUG)
-
-	# TOSession Class Examples
-	#     TOSession is a class that allows you to create a session to a Traffic Ops instance
-	#     and interact with the Traffic Ops API.
-
-	# Traffic Ops System - for self-signed cert -> turn off cert verification
-	tos = TOSession(host_ip=u'to.somedomain.net', verify_cert=True)
-	tos.login(u'someuser', u'someuser123')
-
-	# Objects get returned munch-ified by default which means you can access dictionary keys as
-	# attributes names but you can still access the entries with keys as well.  E.g. cdn.name == cdn['name']
-	cdns, response = tos.get_cdns()
-	print(cdns)
-	for cdn in cdns:
-		print(u'CDN [{0}] has id [{1}]'.format(cdn.name, cdn.id))
-
-	all_types, response = tos.get_types()
-	print(u'All Types are (sorted by useInTable, name):')
-	print(all_types)
-	for atype in sorted(all_types, key=operator.itemgetter(u'useInTable', u'name')):
-		print(u'Type [{0}] for table [{1}]'.format(atype.name, atype.useInTable))
-
-	print(u'Getting all cache groups (bulk)...')
-	cache_groups, response = tos.get_cachegroups()
-	for cache_group in cache_groups:
-		print(u'Bulk cache group [{0}] has id [{1}]'.format(cache_group.name, cache_group.id))
-
-		# Example with URL replacement parameters
-		# e.g. TOSession.get_cachegroups_by_id() == end-point 'api/1.2/cachegroups/{id}'
-		#      See TOSession object for details.
-		print(u'    Getting cachegroup by id [{0}] to demonstrate getting by id...'.format(cache_group.id))
-		cg_id_list, response = tos.get_cachegroup_by_id(cache_group_id=cache_group.id)  # data returned is always a list
-		print(u'    Cache group [{0}] by id [{1}]'.format(cg_id_list[0].name, cg_id_list[0].id))
-
-	# Example with URL query parameters
-	server_types, response = tos.get_types(query_params={u'useInTable': u'server'})
-	print(u'Server Types are:')
-	print(server_types)
-	for stype in server_types:
-		print(u'Type [{0}] for table [{1}]'.format(stype.name, stype.useInTable))
-	tos.close()
-	print(u'Done!')
diff --git a/traffic_control/clients/python/common/utils.py b/traffic_control/clients/python/trafficops/utils.py
similarity index 87%
rename from traffic_control/clients/python/common/utils.py
rename to traffic_control/clients/python/trafficops/utils.py
index 604d927fc..dc81f6c2b 100644
--- a/traffic_control/clients/python/common/utils.py
+++ b/traffic_control/clients/python/trafficops/utils.py
@@ -26,9 +26,7 @@
 # Python 2 to Python 3 Compatibility
 from builtins import str
 
-
-logger = logging.getLogger(__name__)
-
+LOGGER = logging.getLogger(__name__)
 
 def log_with_debug_info(logging_level=logging.INFO, msg=u'', parent=False, separator=u':'):
 	"""
@@ -40,17 +38,22 @@ def log_with_debug_info(logging_level=logging.INFO, msg=u'', parent=False, separ
 	:type logging_level: int
 	:param msg: The message to log.
 	:type msg: Text
-	:param parent: If True, use the caller's parent information instead of the caller's information in the
-				   message.
+	:param parent: If True, use the caller's parent information instead of the caller's information
+		in the message.
 	:type parent: bool
 	:param separator: The string to use for the component separator
 	:type separator: Text
 	:return: '<file name>:<function name>:<line number>: <msg>'
-			 e.g. 'tosession.py:_build_endpoint:199: This is a message to log.'
+		e.g. 'tosession.py:_build_endpoint:199: This is a message to log.'
 	:rtype: Text
 	"""
 
-	frame, file_path, line_number, function_name, lines, index = inspect.stack()[1 if not parent else 2]
+	frame,\
+	file_path,\
+	line_number,\
+	function_name,\
+	_,\
+	_ = inspect.stack()[1 if not parent else 2]
 	file_name = os.path.split(file_path)[-1]
 	calling_module = inspect.getmodule(frame).__name__
 	debug_msg = separator.join(map(str, (file_name, function_name, line_number, u' '))) + str(msg)


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services