You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2020/12/14 18:44:03 UTC

[ranger] branch ranger-2.1 updated (e1871ed -> a7d4179)

This is an automated email from the ASF dual-hosted git repository.

madhan pushed a change to branch ranger-2.1
in repository https://gitbox.apache.org/repos/asf/ranger.git.


    from e1871ed  RANGER-3012: Dockerfile - updated default to build from local repo (instead of from github)
     new f9f4221  RANGER-2927: updated README.md for Python client
     new f041a2c  RANGER-2927: updated description for apache-ranger PyPi project
     new a7d4179  RANGER-3114: updated Python client with more samples, and some refactoring

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                                         |   7 +
 intg/src/main/python/README.md                     | 102 ++++
 .../python/apache_ranger/client/ranger_client.py   | 618 ++++++++++-----------
 intg/src/main/python/apache_ranger/exceptions.py   |  45 ++
 .../model/grant_revoke_role_request.py             |  34 +-
 .../main/python/apache_ranger/model/ranger_base.py |  51 +-
 .../python/apache_ranger/model/ranger_policy.py    | 198 ++++---
 .../main/python/apache_ranger/model/ranger_role.py |  41 +-
 .../apache_ranger/model/ranger_security_zone.py    |  40 +-
 .../python/apache_ranger/model/ranger_service.py   |  36 +-
 .../apache_ranger/model/ranger_service_def.py      | 295 ++++++----
 intg/src/main/python/apache_ranger/utils.py        |  92 +++
 intg/src/main/python/setup.py                      |  26 +-
 .../sample-client/src/main/python/sample_client.py | 319 ++++++++---
 14 files changed, 1194 insertions(+), 710 deletions(-)
 create mode 100644 intg/src/main/python/apache_ranger/exceptions.py
 create mode 100644 intg/src/main/python/apache_ranger/utils.py


[ranger] 01/03: RANGER-2927: updated README.md for Python client

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch ranger-2.1
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit f9f42211562891e583309047de003823590f9b14
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Fri Dec 4 00:19:31 2020 -0800

    RANGER-2927: updated README.md for Python client
    
    (cherry picked from commit 789ce7dacb7c0d7899549dbd8082430f1d4bd4d8)
---
 intg/src/main/python/README.md | 47 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/intg/src/main/python/README.md b/intg/src/main/python/README.md
index 8cd7b03..305e7f5 100644
--- a/intg/src/main/python/README.md
+++ b/intg/src/main/python/README.md
@@ -19,3 +19,50 @@ under the License.
 
 # Apache Ranger - Python client
 
+This is a python library for Apache Ranger. Users can integrate with Apache Ranger using the python client.
+Currently, compatible with Python 3.5+
+
+## Installation
+
+Use the package manager [pip](https://pip.pypa.io/en/stable/) to install python client for Apache Ranger.
+
+```bash
+> pip install apache-ranger
+```
+
+Verify if apache-ranger client is installed:
+```bash
+> pip list
+
+Package      Version
+------------ ---------
+apache-ranger 0.0.1
+```
+
+## Usage
+
+```python init_dev_hive.py```
+```python
+# init_dev_hive.py
+
+from apache_ranger.model.ranger_service import RangerService
+from apache_ranger.client.ranger_client import RangerClient
+from apache_ranger.model.ranger_policy  import RangerPolicy, RangerPolicyResource, RangerPolicyItem, RangerPolicyItemAccess
+
+service_name = 'dev_hive'
+
+service = RangerService(name=service_name, type='hive')
+service.configs = {'username':'hive', 'password':'hive', 'jdbc.driverClassName': 'org.apache.hive.jdbc.HiveDriver', 'jdbc.url': 'jdfb:hive2://ranger-hadoop:10000', 'hadoop.security.authorization': 'true'}
+
+policy = RangerPolicy(service=service_name, name='test policy')
+policy.resources = {'database': RangerPolicyResource(['test_db']), 'table': RangerPolicyResource(['test_tbl']), 'column': RangerPolicyResource(['*'])}
+policy.policyItems.append(RangerPolicyItem(users=['admin'], accesses=[RangerPolicyItemAccess('create'), RangerPolicyItemAccess('alter'), RangerPolicyItemAccess('drop')], delegateAdmin=True))
+policy.denyPolicyItems.append(RangerPolicyItem(users=['admin'], accesses=[RangerPolicyItemAccess('select')]))
+
+
+ranger_client   = RangerClient('http://localhost:6080', 'admin', 'rangerR0cks!')
+created_service = ranger_client.create_service(service)
+created_policy  = ranger_client.create_policy(policy)
+
+```
+For more examples, checkout `sample-client` python  project in [ranger-examples](https://github.com/apache/ranger/blob/master/ranger-examples/sample-client/src/main/python/sample_client.py) module.


[ranger] 02/03: RANGER-2927: updated description for apache-ranger PyPi project

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch ranger-2.1
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit f041a2cf7c78108b61d7c3494f43c421f73fcd3d
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Fri Dec 4 00:52:09 2020 -0800

    RANGER-2927: updated description for apache-ranger PyPi project
    
    (cherry picked from commit 7b82a847134251dcdfdfbcafadd509ba9e926915)
---
 intg/src/main/python/README.md | 2 +-
 intg/src/main/python/setup.py  | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/intg/src/main/python/README.md b/intg/src/main/python/README.md
index 305e7f5..4426d10 100644
--- a/intg/src/main/python/README.md
+++ b/intg/src/main/python/README.md
@@ -36,7 +36,7 @@ Verify if apache-ranger client is installed:
 
 Package      Version
 ------------ ---------
-apache-ranger 0.0.1
+apache-ranger 0.0.2
 ```
 
 ## Usage
diff --git a/intg/src/main/python/setup.py b/intg/src/main/python/setup.py
index 89f2327..b073a80 100644
--- a/intg/src/main/python/setup.py
+++ b/intg/src/main/python/setup.py
@@ -18,13 +18,12 @@
 
 import setuptools
 
-# with open("README.md", "r") as fh:
-#     long_description = fh.read()
-long_description = "Apache Ranger Python client"
+with open("README.md", "r") as fh:
+    long_description = fh.read()
 
 setuptools.setup(
     name="apache-ranger",
-    version="0.0.1",
+    version="0.0.2",
     author="Apache Ranger",
     author_email="dev@ranger.apache.org",
     description="Apache Ranger Python client",
@@ -37,5 +36,6 @@ setuptools.setup(
         "License :: OSI Approved :: Apache Software License",
         "Operating System :: OS Independent",
     ],
+    keywords='ranger client, apache ranger',
     python_requires='>=3.6',
 )


[ranger] 03/03: RANGER-3114: updated Python client with more samples, and some refactoring

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch ranger-2.1
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit a7d41791c60b7fe8c2d4f49afab3e71ce6978e94
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Fri Dec 11 18:54:48 2020 -0800

    RANGER-3114: updated Python client with more samples, and some refactoring
    
    (cherry picked from commit fa3e3d6e1753eff062d73ba3eca57f71435e8bea)
---
 .gitignore                                         |   7 +
 intg/src/main/python/README.md                     |  91 ++-
 .../python/apache_ranger/client/ranger_client.py   | 618 ++++++++++-----------
 intg/src/main/python/apache_ranger/exceptions.py   |  45 ++
 .../model/grant_revoke_role_request.py             |  34 +-
 .../main/python/apache_ranger/model/ranger_base.py |  51 +-
 .../python/apache_ranger/model/ranger_policy.py    | 198 ++++---
 .../main/python/apache_ranger/model/ranger_role.py |  41 +-
 .../apache_ranger/model/ranger_security_zone.py    |  40 +-
 .../python/apache_ranger/model/ranger_service.py   |  36 +-
 .../apache_ranger/model/ranger_service_def.py      | 295 ++++++----
 intg/src/main/python/apache_ranger/utils.py        |  92 +++
 intg/src/main/python/setup.py                      |  20 +-
 .../sample-client/src/main/python/sample_client.py | 319 ++++++++---
 14 files changed, 1162 insertions(+), 725 deletions(-)

diff --git a/.gitignore b/.gitignore
index e351815..9768b79 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,10 @@
 winpkg/target
 .DS_Store
 .idea
+
+#Python
+*.pyc
+**/build
+**/dist
+**/apache_ranger.egg-info
+.python-version
diff --git a/intg/src/main/python/README.md b/intg/src/main/python/README.md
index 4426d10..a70fdac 100644
--- a/intg/src/main/python/README.md
+++ b/intg/src/main/python/README.md
@@ -19,8 +19,7 @@ under the License.
 
 # Apache Ranger - Python client
 
-This is a python library for Apache Ranger. Users can integrate with Apache Ranger using the python client.
-Currently, compatible with Python 3.5+
+Python library for Apache Ranger.
 
 ## Installation
 
@@ -36,33 +35,89 @@ Verify if apache-ranger client is installed:
 
 Package      Version
 ------------ ---------
-apache-ranger 0.0.2
+apache-ranger 0.0.3
 ```
 
 ## Usage
 
-```python init_dev_hive.py```
+```python test_ranger.py```
 ```python
-# init_dev_hive.py
+# test_ranger.py
 
-from apache_ranger.model.ranger_service import RangerService
-from apache_ranger.client.ranger_client import RangerClient
-from apache_ranger.model.ranger_policy  import RangerPolicy, RangerPolicyResource, RangerPolicyItem, RangerPolicyItemAccess
+from apache_ranger.model.ranger_service import *
+from apache_ranger.client.ranger_client import *
+from apache_ranger.model.ranger_policy  import *
 
-service_name = 'dev_hive'
 
-service = RangerService(name=service_name, type='hive')
-service.configs = {'username':'hive', 'password':'hive', 'jdbc.driverClassName': 'org.apache.hive.jdbc.HiveDriver', 'jdbc.url': 'jdfb:hive2://ranger-hadoop:10000', 'hadoop.security.authorization': 'true'}
+## Step 1: create a client to connect to Apache Ranger admin
+ranger_url  = 'http://localhost:6080'
+ranger_auth = ('admin', 'rangerR0cks!')
 
-policy = RangerPolicy(service=service_name, name='test policy')
-policy.resources = {'database': RangerPolicyResource(['test_db']), 'table': RangerPolicyResource(['test_tbl']), 'column': RangerPolicyResource(['*'])}
-policy.policyItems.append(RangerPolicyItem(users=['admin'], accesses=[RangerPolicyItemAccess('create'), RangerPolicyItemAccess('alter'), RangerPolicyItemAccess('drop')], delegateAdmin=True))
-policy.denyPolicyItems.append(RangerPolicyItem(users=['admin'], accesses=[RangerPolicyItemAccess('select')]))
+# For Kerberos authentication
+#
+# from requests_kerberos import HTTPKerberosAuth
+#
+# ranger_auth = HTTPKerberosAuth()
 
+ranger = RangerClient(ranger_url, ranger_auth)
 
-ranger_client   = RangerClient('http://localhost:6080', 'admin', 'rangerR0cks!')
-created_service = ranger_client.create_service(service)
-created_policy  = ranger_client.create_policy(policy)
+# to disable SSL certificate validation (not recommended for production use!)
+#
+# ranger.session.verify = False
+
+
+## Step 2: Let's create a service
+service         = RangerService()
+service.name    = 'test_hive'
+service.type    = 'hive'
+service.configs = {'username':'hive', 'password':'hive', 'jdbc.driverClassName': 'org.apache.hive.jdbc.HiveDriver', 'jdbc.url': 'jdbc:hive2://ranger-hadoop:10000', 'hadoop.security.authorization': 'true'}
+
+print('Creating service: name=' + service.name)
+
+created_service = ranger.create_service(service)
+
+print('    created service: name=' + created_service.name + ', id=' + str(created_service.id))
+
+
+## Step 3: Let's create a policy
+policy           = RangerPolicy()
+policy.service   = service.name
+policy.name      = 'test policy'
+policy.resources = { 'database': RangerPolicyResource({ 'values': ['test_db'] }),
+                     'table':    RangerPolicyResource({ 'values': ['test_tbl'] }),
+                     'column':   RangerPolicyResource({ 'values': ['*'] }) }
+
+allowItem1          = RangerPolicyItem()
+allowItem1.users    = [ 'admin' ]
+allowItem1.accesses = [ RangerPolicyItemAccess({ 'type': 'create' }),
+                        RangerPolicyItemAccess({ 'type': 'alter' }) ]
+
+denyItem1          = RangerPolicyItem()
+denyItem1.users    = [ 'admin' ]
+denyItem1.accesses = [ RangerPolicyItemAccess({ 'type': 'drop' }) ]
+
+policy.policyItems     = [ allowItem1 ]
+policy.denyPolicyItems = [ denyItem1 ]
+
+print('Creating policy: name=' + policy.name)
+
+created_policy = ranger.create_policy(policy)
+
+print('    created policy: name=' + created_policy.name + ', id=' + str(created_policy.id))
+
+
+## Step 4: Delete policy and service created above
+print('Deleting policy: id=' + str(created_policy.id))
+
+ranger.delete_policy_by_id(created_policy.id)
+
+print('    deleted policy: id=' + str(created_policy.id))
+
+print('Deleting service: id=' + str(created_service.id))
+
+ranger.delete_service_by_id(created_service.id)
+
+print('    deleted service: id=' + str(created_service.id))
 
 ```
 For more examples, checkout `sample-client` python  project in [ranger-examples](https://github.com/apache/ranger/blob/master/ranger-examples/sample-client/src/main/python/sample_client.py) module.
diff --git a/intg/src/main/python/apache_ranger/client/ranger_client.py b/intg/src/main/python/apache_ranger/client/ranger_client.py
index c95d0d9..67b21c2 100644
--- a/intg/src/main/python/apache_ranger/client/ranger_client.py
+++ b/intg/src/main/python/apache_ranger/client/ranger_client.py
@@ -17,475 +17,425 @@
 # limitations under the License.
 
 
-import enum
 import json
 import logging
-import requests
+import os
 
-from http     import HTTPStatus
 from requests import Session, Response
 
+from apache_ranger.exceptions                 import RangerServiceException
+from apache_ranger.model.ranger_base          import RangerBase
 from apache_ranger.model.ranger_role          import RangerRole
 from apache_ranger.model.ranger_policy        import RangerPolicy
 from apache_ranger.model.ranger_service       import RangerService
 from apache_ranger.model.ranger_service_def   import RangerServiceDef
 from apache_ranger.model.ranger_security_zone import RangerSecurityZone
+from apache_ranger.utils                      import *
 
 
-APPLICATION_JSON = 'application/json'
 
-requests.packages.urllib3.disable_warnings()
-
-log = logging.getLogger(__name__)
-
-class Message:
-    def __init__(self, name=None, rbKey=None, message=None, objectId=None, fieldName=None):
-        self.name      = name
-        self.rbKey     = rbKey
-        self.message   = message
-        self.objectId  = objectId
-        self.fieldName = fieldName
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
-
-class RESTResponse:
-    def __init__(self, httpStatusCode=None, statusCode=None, msgDesc=None, messageList=None):
-        self.httpStatusCode = httpStatusCode
-        self.statusCode     = statusCode
-        self.msgDesc        = msgDesc
-        self.messageList    = messageList if messageList is not None else []
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
-
-class HttpMethod(enum.Enum):
-    GET    = "GET"
-    PUT    = "PUT"
-    POST   = "POST"
-    DELETE = "DELETE"
-
-
-class API:
-    def __init__(self, path, method, expected_status, consumes=APPLICATION_JSON, produces=APPLICATION_JSON):
-        self.path            = path
-        self.method          = method
-        self.expected_status = expected_status
-        self.consumes        = consumes
-        self.produces        = produces
-
-    def call(self, session, baseUrl, params, request):
-        session.headers['Accept']       = self.consumes
-        session.headers['Content-type'] = self.produces
-
-        if log.isEnabledFor(logging.DEBUG):
-            log.debug('==> call({},{},{})'.format(self, params, request))
-            log.debug('------------------------------------------------------')
-            log.debug('Call         : {} {}'.format(self.method, self.path))
-            log.debug('Content-type : {}'.format(self.consumes))
-            log.debug('Accept       : {}'.format(self.produces))
-
-            if request is not None:
-                log.debug("Request      : {}".format(request))
-
-        path = baseUrl + self.path
-
-        if self.method == HttpMethod.GET:
-            client_response = session.get(path)
-        elif self.method == HttpMethod.POST:
-            client_response = session.post(path, data=request.__repr__())
-        elif self.method == HttpMethod.PUT:
-            client_response = session.put(path, data=request.__repr__())
-        elif self.method == HttpMethod.DELETE:
-            client_response = session.delete(path, params=params)
-        else:
-            raise Exception('Unsupported HTTP Method {}'.format(self.method))
-
-        if client_response.status_code == self.expected_status:
-            if client_response.content:
-                if log.isEnabledFor(logging.DEBUG):
-                    log.debug('Response: {}'.format(client_response.text))
-            else:
-                return None
-        elif client_response.status_code == HTTPStatus.SERVICE_UNAVAILABLE:
-            log.error('Ranger Admin unavailable. HTTP Status: {}'.format(HTTPStatus.SERVICE_UNAVAILABLE))
-            log.error("client_response=: {}" + str(client_response))
-            return None
-        else:
-            raise Exception(client_response.text)
-
-        __json = json.loads(str(json.dumps(client_response.json())))
-
-        if log.isEnabledFor(logging.DEBUG):
-            log.debug('<== call({},{},{}), result = {}'.format(self, params, request, client_response))
-
-        return __json
-
-    def apply_url_params(self, params):
-        try:
-            return API(self.path.format(**params), self.method, self.expected_status, self.consumes, self.produces)
-        except (KeyError, TypeError) as e:
-            log.error('Arguments not formatted properly' + str(e))
-            raise e
+LOG = logging.getLogger(__name__)
 
 
 class RangerClient:
-    # Query Params
-    PARAM_ID                            = "id"
-    PARAM_NAME                          = "name"
-    PARAM_DAYS                          = "days"
-    PARAM_EXEC_USER                     = "execUser"
-    PARAM_POLICY_NAME                   = "policyname"
-    PARAM_SERVICE_NAME                  = "serviceName"
-    PARAM_RELOAD_SERVICE_POLICIES_CACHE = "reloadServicePoliciesCache"
-
-    # URIs
-    URI_BASE = "/service/public/v2/api"
-
-    URI_SERVICEDEF         = URI_BASE + "/servicedef"
-    URI_SERVICEDEF_BY_ID   = URI_SERVICEDEF + "/{id}"
-    URI_SERVICEDEF_BY_NAME = URI_SERVICEDEF + "/name/{name}"
-
-    URI_SERVICE             = URI_BASE + "/service"
-    URI_SERVICE_BY_ID       = URI_SERVICE + "/{id}"
-    URI_SERVICE_BY_NAME     = URI_SERVICE + "/name/{name}"
-    URI_POLICIES_IN_SERVICE = URI_SERVICE + "/{serviceName}/policy"
-
-    URI_POLICY         = URI_BASE + "/policy"
-    URI_APPLY_POLICY   = URI_POLICY + "/apply"
-    URI_POLICY_BY_ID   = URI_POLICY + "/{id}"
-    URI_POLICY_BY_NAME = URI_SERVICE + "/{serviceName}/policy/{policyname}"
-
-    URI_ROLE         = URI_BASE + "/roles"
-    URI_ROLE_NAMES   = URI_ROLE + "/names"
-    URI_ROLE_BY_ID   = URI_ROLE + "/{id}"
-    URI_ROLE_BY_NAME = URI_ROLE + "/name/{name}"
-    URI_USER_ROLES   = URI_ROLE + "/user/{name}"
-    URI_GRANT_ROLE   = URI_ROLE + "/grant/{name}"
-    URI_REVOKE_ROLE  = URI_ROLE + "/revoke/{name}"
-
-    URI_ZONE         = URI_BASE + "/zones"
-    URI_ZONE_BY_ID   = URI_ZONE + "/{id}"
-    URI_ZONE_BY_NAME = URI_ZONE + "/name/{name}"
+    def __init__(self, url, auth):
+        self.url          = url
+        self.session      = Session()
+        self.session.auth = auth
 
-    URI_PLUGIN_INFO   = URI_BASE + "/plugins/info"
-    URI_POLICY_DELTAS = URI_BASE + "/server/policydeltas"
+        logging.getLogger("requests").setLevel(logging.WARNING)
 
-    # APIs
-    CREATE_SERVICEDEF         = API(URI_SERVICEDEF, HttpMethod.POST, HTTPStatus.OK)
-    UPDATE_SERVICEDEF_BY_ID   = API(URI_SERVICEDEF_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
-    UPDATE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
-    DELETE_SERVICEDEF_BY_ID   = API(URI_SERVICEDEF_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    DELETE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    GET_SERVICEDEF_BY_ID      = API(URI_SERVICEDEF_BY_ID, HttpMethod.GET, HTTPStatus.OK)
-    GET_SERVICEDEF_BY_NAME    = API(URI_SERVICEDEF_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
-    FIND_SERVICEDEFS          = API(URI_SERVICEDEF, HttpMethod.GET, HTTPStatus.OK)
-
-    CREATE_SERVICE         = API(URI_SERVICE, HttpMethod.POST, HTTPStatus.OK)
-    UPDATE_SERVICE_BY_ID   = API(URI_SERVICE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
-    UPDATE_SERVICE_BY_NAME = API(URI_SERVICE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
-    DELETE_SERVICE_BY_ID   = API(URI_SERVICE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    DELETE_SERVICE_BY_NAME = API(URI_SERVICE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    GET_SERVICE_BY_ID      = API(URI_SERVICE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
-    GET_SERVICE_BY_NAME    = API(URI_SERVICE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
-    FIND_SERVICES          = API(URI_SERVICE, HttpMethod.GET, HTTPStatus.OK)
-
-    CREATE_POLICY           = API(URI_POLICY, HttpMethod.POST, HTTPStatus.OK)
-    UPDATE_POLICY_BY_ID     = API(URI_POLICY_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
-    UPDATE_POLICY_BY_NAME   = API(URI_POLICY_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
-    APPLY_POLICY            = API(URI_APPLY_POLICY, HttpMethod.POST, HTTPStatus.OK)
-    DELETE_POLICY_BY_ID     = API(URI_POLICY_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    DELETE_POLICY_BY_NAME   = API(URI_POLICY, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    GET_POLICY_BY_ID        = API(URI_POLICY_BY_ID, HttpMethod.GET, HTTPStatus.OK)
-    GET_POLICY_BY_NAME      = API(URI_POLICY_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
-    GET_POLICIES_IN_SERVICE = API(URI_POLICIES_IN_SERVICE, HttpMethod.GET, HTTPStatus.OK)
-    FIND_POLICIES           = API(URI_POLICY, HttpMethod.GET, HTTPStatus.OK)
-
-    CREATE_ZONE         = API(URI_ZONE, HttpMethod.POST, HTTPStatus.OK)
-    UPDATE_ZONE_BY_ID   = API(URI_ZONE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
-    UPDATE_ZONE_BY_NAME = API(URI_ZONE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
-    DELETE_ZONE_BY_ID   = API(URI_ZONE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    DELETE_ZONE_BY_NAME = API(URI_ZONE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    GET_ZONE_BY_ID      = API(URI_ZONE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
-    GET_ZONE_BY_NAME    = API(URI_ZONE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
-    FIND_ZONES          = API(URI_ZONE, HttpMethod.GET, HTTPStatus.OK)
-
-    CREATE_ROLE         = API(URI_ROLE, HttpMethod.POST, HTTPStatus.OK)
-    UPDATE_ROLE_BY_ID   = API(URI_ROLE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
-    DELETE_ROLE_BY_ID   = API(URI_ROLE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    DELETE_ROLE_BY_NAME = API(URI_ROLE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-    GET_ROLE_BY_ID      = API(URI_ROLE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
-    GET_ROLE_BY_NAME    = API(URI_ROLE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
-    GET_ALL_ROLE_NAMES  = API(URI_ROLE_NAMES, HttpMethod.GET, HTTPStatus.OK)
-    GET_USER_ROLES      = API(URI_USER_ROLES, HttpMethod.GET, HTTPStatus.OK)
-    GRANT_ROLE          = API(URI_GRANT_ROLE, HttpMethod.PUT, HTTPStatus.OK)
-    REVOKE_ROLE         = API(URI_REVOKE_ROLE, HttpMethod.PUT, HTTPStatus.OK)
-    FIND_ROLES          = API(URI_ROLE, HttpMethod.GET, HTTPStatus.OK)
-
-    GET_PLUGIN_INFO      = API(URI_PLUGIN_INFO, HttpMethod.GET, HTTPStatus.OK)
-    DELETE_POLICY_DELTAS = API(URI_POLICY_DELTAS, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
-
-    def __init__(self, url, username, password):
-        self.__password     = password
-        self.url            = url
-        self.username       = username
-        self.session        = Session()
-        self.session.auth   = (username, password)
-        self.session.verify = False
-
-    def __call_api(self, api, params, request):
-        return api.call(self.session, self.url, params, request)
-
-    def __call_api_with_url_params(self, api, urlParams, params, request):
-        return api.apply_url_params(urlParams).call(self.session, self.url, params, request)
 
     # Service Definition APIs
     def create_service_def(self, serviceDef):
-        ret = self.__call_api(RangerClient.CREATE_SERVICEDEF, {}, serviceDef)
+        resp = self.__call_api(RangerClient.CREATE_SERVICEDEF, request_data=serviceDef)
 
-        return RangerServiceDef(**ret) if ret is not None else None
+        return type_coerce(resp, RangerServiceDef)
 
     def update_service_def_by_id(self, serviceDefId, serviceDef):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_SERVICEDEF_BY_ID, { RangerClient.PARAM_ID: serviceDefId }, {}, serviceDef)
+        resp = self.__call_api(RangerClient.UPDATE_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }), request_data=serviceDef)
 
-        return RangerServiceDef(**ret) if ret is not None else None
+        return type_coerce(resp, RangerServiceDef)
 
     def update_service_def(self, serviceDefName, serviceDef):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_SERVICEDEF_BY_NAME, { RangerClient.PARAM_NAME: serviceDefName }, {}, serviceDef)
+        resp = self.__call_api(RangerClient.UPDATE_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }), request_data=serviceDef)
 
-        return RangerServiceDef(**ret) if ret is not None else None
+        return type_coerce(resp, RangerServiceDef)
 
     def delete_service_def_by_id(self, serviceDefId):
-        self.__call_api_with_url_params(RangerClient.DELETE_SERVICEDEF_BY_ID, { RangerClient.PARAM_ID: serviceDefId }, {}, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }))
 
     def delete_service_def(self, serviceDefName):
-        self.__call_api_with_url_params(RangerClient.DELETE_SERVICEDEF_BY_NAME, { RangerClient.PARAM_NAME: serviceDefName }, {}, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }))
 
     def get_service_def_by_id(self, serviceDefId):
-        ret = self.__call_api_with_url_params(RangerClient.GET_SERVICEDEF_BY_ID, { RangerClient.PARAM_ID: serviceDefId }, {}, {})
+        resp = self.__call_api(RangerClient.GET_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }))
 
-        return RangerServiceDef(**ret) if ret is not None else None
+        return type_coerce(resp, RangerServiceDef)
 
     def get_service_def(self, serviceDefName):
-        ret = self.__call_api_with_url_params(RangerClient.GET_SERVICEDEF_BY_NAME, { RangerClient.PARAM_NAME: serviceDefName }, {}, {})
+        resp = self.__call_api(RangerClient.GET_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }))
 
-        return RangerServiceDef(**ret) if ret is not None else None
+        return type_coerce(resp, RangerServiceDef)
 
-    def find_service_defs(self, filter):
-        ret = self.__call_api(RangerClient.FIND_SERVICEDEFS, filter, {})
+    def find_service_defs(self, filter={}):
+        resp = self.__call_api(RangerClient.FIND_SERVICEDEFS, filter)
+
+        return type_coerce_list(resp, RangerServiceDef)
 
-        return list(ret) if ret is not None else None
 
     # Service APIs
     def create_service(self, service):
-        ret = self.__call_api(RangerClient.CREATE_SERVICE, {}, service)
+        resp = self.__call_api(RangerClient.CREATE_SERVICE, request_data=service)
+
+        return type_coerce(resp, RangerService)
+
+    def get_service_by_id(self, serviceId):
+        resp = self.__call_api(RangerClient.GET_SERVICE_BY_ID.format_path({ 'id': serviceId }))
+
+        return type_coerce(resp, RangerService)
+
+    def get_service(self, serviceName):
+        resp = self.__call_api(RangerClient.GET_SERVICE_BY_NAME.format_path({ 'name': serviceName }))
 
-        return RangerService(**ret) if ret is not None else None
+        return type_coerce(resp, RangerService)
 
     def update_service_by_id(self, serviceId, service):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_SERVICE_BY_ID, { RangerClient.PARAM_ID: serviceId }, {}, service)
+        resp = self.__call_api(RangerClient.UPDATE_SERVICE_BY_ID.format_path({ 'id': serviceId }), request_data=service)
 
-        return RangerService(**ret) if ret is not None else None
+        return type_coerce(resp, RangerService)
 
     def update_service(self, serviceName, service):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_SERVICE_BY_NAME, { RangerClient.PARAM_NAME: serviceName }, {}, service)
+        resp = self.__call_api(RangerClient.UPDATE_SERVICE_BY_NAME.format_path({ 'name': serviceName }), request_data=service)
 
-        return RangerService(**ret) if ret is not None else None
+        return type_coerce(resp, RangerService)
 
     def delete_service_by_id(self, serviceId):
-        self.__call_api_with_url_params(RangerClient.DELETE_SERVICE_BY_ID, { RangerClient.PARAM_ID: serviceId }, {}, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_SERVICE_BY_ID.format_path({ 'id': serviceId }))
 
     def delete_service(self, serviceName):
-        self.__call_api_with_url_params(RangerClient.DELETE_SERVICE_BY_NAME, { RangerClient.PARAM_NAME: serviceName }, {}, {})
+        self.__call_api(RangerClient.DELETE_SERVICE_BY_NAME.format_path({ 'name': serviceName }))
 
-        return None
+    def find_services(self, filter={}):
+        resp = self.__call_api(RangerClient.FIND_SERVICES, filter)
 
-    def get_service_by_id(self, serviceId):
-        ret = self.__call_api_with_url_params(RangerClient.GET_SERVICE_BY_ID, { RangerClient.PARAM_ID: serviceId }, {}, {})
+        return type_coerce_list(resp, RangerService)
 
-        return RangerService(**ret) if ret is not None else None
 
-    def get_service(self, serviceName):
-        ret = self.__call_api_with_url_params(RangerClient.GET_SERVICE_BY_NAME, { RangerClient.PARAM_NAME: serviceName }, {}, {})
+    # Policy APIs
+    def create_policy(self, policy):
+        resp = self.__call_api(RangerClient.CREATE_POLICY, request_data=policy)
 
-        return RangerService(**ret) if ret is not None else None
+        return type_coerce(resp, RangerPolicy)
 
-    def find_services(self, filter):
-        ret = self.__call_api(RangerClient.FIND_SERVICES, filter, {})
+    def get_policy_by_id(self, policyId):
+        resp = self.__call_api(RangerClient.GET_POLICY_BY_ID.format_path({ 'id': policyId }))
 
-        return list(ret) if ret is not None else None
+        return type_coerce(resp, RangerPolicy)
 
-    # Policy APIs
-    def create_policy(self, policy):
-        ret = self.__call_api(RangerClient.CREATE_POLICY, {}, policy)
+    def get_policy(self, serviceName, policyName):
+        resp = self.__call_api(RangerClient.GET_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}))
 
-        return RangerPolicy(**ret) if ret is not None else None
+        return type_coerce(resp, RangerPolicy)
+
+    def get_policies_in_service(self, serviceName):
+        resp = self.__call_api(RangerClient.GET_POLICIES_IN_SERVICE.format_path({ 'serviceName': serviceName }))
+
+        return type_coerce_list(resp, RangerPolicy)
 
     def update_policy_by_id(self, policyId, policy):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_POLICY_BY_ID, { RangerClient.PARAM_ID: policyId }, {}, policy)
+        resp = self.__call_api(RangerClient.UPDATE_POLICY_BY_ID.format_path({ 'id': policyId }), request_data=policy)
 
-        return RangerPolicy(**ret) if ret is not None else None
+        return type_coerce(resp, RangerPolicy)
 
     def update_policy(self, serviceName, policyName, policy):
-        path_params = { RangerClient.PARAM_SERVICE_NAME: serviceName, RangerClient.PARAM_POLICY_NAME: policyName }
-        ret         = self.__call_api_with_url_params(RangerClient.UPDATE_POLICY_BY_NAME, path_params, {}, policy)
+        resp = self.__call_api(RangerClient.UPDATE_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}), request_data=policy)
 
-        return RangerPolicy(**ret) if ret is not None else None
+        return type_coerce(resp, RangerPolicy)
 
     def apply_policy(self, policy):
-        ret = self.__call_api(RangerClient.APPLY_POLICY, {}, policy)
+        resp = self.__call_api(RangerClient.APPLY_POLICY, request_data=policy)
 
-        return RangerPolicy(**ret) if ret is not None else None
+        return type_coerce(resp, RangerPolicy)
 
     def delete_policy_by_id(self, policyId):
-        self.__call_api_with_url_params(RangerClient.DELETE_POLICY_BY_ID, { RangerClient.PARAM_ID: policyId }, {}, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_POLICY_BY_ID.format_path({ 'id': policyId }))
 
     def delete_policy(self, serviceName, policyName):
-        query_params = { RangerClient.PARAM_POLICY_NAME: policyName, 'servicename': serviceName }
-
-        self.__call_api(RangerClient.DELETE_POLICY_BY_NAME, query_params, {})
-
-        return None
-
-    def get_policy_by_id(self, policyId):
-        ret = self.__call_api_with_url_params(RangerClient.GET_POLICY_BY_ID, { RangerClient.PARAM_ID: policyId }, {}, {})
-
-        return RangerPolicy(**ret) if ret is not None else None
-
-    def get_policy(self, serviceName, policyName):
-        path_params = {RangerClient.PARAM_SERVICE_NAME: serviceName, RangerClient.PARAM_POLICY_NAME: policyName}
-        ret         = self.__call_api_with_url_params(RangerClient.GET_POLICY_BY_NAME, path_params, {}, {})
-
-        return RangerPolicy(**ret) if ret is not None else None
-
-    def get_policies_in_service(self, serviceName):
-        ret = self.__call_api_with_url_params(RangerClient.GET_POLICIES_IN_SERVICE, { RangerClient.PARAM_SERVICE_NAME: serviceName }, {}, {})
+        self.__call_api(RangerClient.DELETE_POLICY_BY_NAME, { 'servicename': serviceName, 'policyname': policyName })
 
-        return list(ret) if ret is not None else None
+    def find_policies(self, filter={}):
+        resp = self.__call_api(RangerClient.FIND_POLICIES, filter)
 
-    def find_policies(self, filter):
-        ret = self.__call_api(RangerClient.FIND_POLICIES, filter, {})
+        return type_coerce_list(resp, RangerPolicy)
 
-        return list(ret) if ret is not None else None
 
     # SecurityZone APIs
     def create_security_zone(self, securityZone):
-        ret = self.__call_api(RangerClient.CREATE_ZONE, {}, securityZone)
+        resp = self.__call_api(RangerClient.CREATE_ZONE, request_data=securityZone)
 
-        return RangerSecurityZone(**ret) if ret is not None else None
+        return type_coerce(resp, RangerSecurityZone)
 
     def update_security_zone_by_id(self, zoneId, securityZone):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_ZONE_BY_ID, { RangerClient.PARAM_ID: zoneId }, {}, securityZone)
+        resp = self.__call_api(RangerClient.UPDATE_ZONE_BY_ID.format_path({ 'id': zoneId }), request_data=securityZone)
 
-        return RangerSecurityZone(**ret) if ret is not None else None
+        return type_coerce(resp, RangerSecurityZone)
 
     def update_security_zone(self, zoneName, securityZone):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_ZONE_BY_NAME, { RangerClient.PARAM_NAME: zoneName }, {}, securityZone)
+        resp = self.__call_api(RangerClient.UPDATE_ZONE_BY_NAME.format_path({ 'name': zoneName }), request_data=securityZone)
 
-        return RangerSecurityZone(**ret) if ret is not None else None
+        return type_coerce(resp, RangerSecurityZone)
 
     def delete_security_zone_by_id(self, zoneId):
-        self.__call_api_with_url_params(RangerClient.DELETE_ZONE_BY_ID, { RangerClient.PARAM_ID: zoneId }, {}, {})
-        return None
+        self.__call_api(RangerClient.DELETE_ZONE_BY_ID.format_path({ 'id': zoneId }))
 
     def delete_security_zone(self, zoneName):
-        self.__call_api_with_url_params(RangerClient.DELETE_ZONE_BY_NAME, { RangerClient.PARAM_NAME: zoneName }, {}, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_ZONE_BY_NAME.format_path({ 'name': zoneName }))
 
     def get_security_zone_by_id(self, zoneId):
-        ret = self.__call_api_with_url_params(RangerClient.GET_ZONE_BY_ID, { RangerClient.PARAM_ID: zoneId }, {}, {})
+        resp = self.__call_api(RangerClient.GET_ZONE_BY_ID.format_path({ 'id': zoneId }))
 
-        return RangerSecurityZone(**ret) if ret is not None else None
+        return type_coerce(resp, RangerSecurityZone)
 
     def get_security_zone(self, zoneName):
-        ret = self.__call_api_with_url_params(RangerClient.GET_ZONE_BY_NAME, { RangerClient.PARAM_NAME: zoneName }, {}, {})
+        resp = self.__call_api(RangerClient.GET_ZONE_BY_NAME.format_path({ 'name': zoneName }))
 
-        return RangerSecurityZone(**ret) if ret is not None else None
+        return type_coerce(resp, RangerSecurityZone)
 
-    def find_security_zones(self, filter):
-        ret = self.__call_api(RangerClient.FIND_ZONES, filter, {})
+    def find_security_zones(self, filter={}):
+        resp = self.__call_api(RangerClient.FIND_ZONES, filter)
+
+        return type_coerce_list(resp, RangerSecurityZone)
 
-        return list(ret) if ret is not None else None
 
     # Role APIs
     def create_role(self, serviceName, role):
-        query_params = {RangerClient.PARAM_SERVICE_NAME, serviceName}
-        ret          = self.__call_api(RangerClient.CREATE_ROLE, query_params, role)
+        resp = self.__call_api(RangerClient.CREATE_ROLE, { 'serviceName': serviceName }, role)
 
-        return RangerRole(**ret) if ret is not None else None
+        return type_coerce(resp, RangerRole)
 
     def update_role(self, roleId, role):
-        ret = self.__call_api_with_url_params(RangerClient.UPDATE_ROLE_BY_ID, { RangerClient.PARAM_ID: roleId }, {}, role)
+        resp = self.__call_api(RangerClient.UPDATE_ROLE_BY_ID.format_path({ 'id': roleId }), request_data=role)
 
-        return RangerRole(**ret) if ret is not None else None
+        return type_coerce(resp, RangerRole)
 
     def delete_role_by_id(self, roleId):
-        self.__call_api_with_url_params(RangerClient.DELETE_ROLE_BY_ID, { RangerClient.PARAM_ID: roleId }, {}, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_ROLE_BY_ID.format_path({ 'id': roleId }))
 
     def delete_role(self, roleName, execUser, serviceName):
-        query_params = { RangerClient.PARAM_EXEC_USER: execUser, RangerClient.PARAM_SERVICE_NAME: serviceName }
-
-        self.__call_api_with_url_params(RangerClient.DELETE_ROLE_BY_NAME, { RangerClient.PARAM_NAME: roleName }, query_params, {})
-
-        return None
+        self.__call_api(RangerClient.DELETE_ROLE_BY_NAME.format_path({ 'name': roleName }), { 'execUser': execUser, 'serviceName': serviceName })
 
     def get_role_by_id(self, roleId):
-        ret = self.__call_api_with_url_params(RangerClient.GET_ROLE_BY_ID, { RangerClient.PARAM_ID: roleId }, {}, {})
+        resp = self.__call_api(RangerClient.GET_ROLE_BY_ID.format_path({ 'id': roleId }))
 
-        return RangerRole(**ret) if ret is not None else None
+        return type_coerce(resp, RangerRole)
 
     def get_role(self, roleName, execUser, serviceName):
-        query_params = { RangerClient.PARAM_EXEC_USER: execUser, RangerClient.PARAM_SERVICE_NAME: serviceName }
-        ret          = self.__call_api_with_url_params(RangerClient.GET_ROLE_BY_NAME, { RangerClient.PARAM_NAME: roleName }, query_params, {})
+        resp = self.__call_api(RangerClient.GET_ROLE_BY_NAME.format_path({ 'name': roleName }), { 'execUser': execUser, 'serviceName': serviceName })
 
-        return RangerRole(**ret) if ret is not None else None
+        return type_coerce(resp, RangerRole)
 
     def get_all_role_names(self, execUser, serviceName):
-        query_params = { RangerClient.PARAM_EXEC_USER: execUser, RangerClient.PARAM_SERVICE_NAME: serviceName }
-        ret          = self.__call_api_with_url_params(RangerClient.GET_ALL_ROLE_NAMES, { RangerClient.PARAM_NAME: serviceName }, query_params, {})
+        resp = self.__call_api(RangerClient.GET_ALL_ROLE_NAMES.format_path({ 'name': serviceName }), { 'execUser': execUser, 'serviceName': serviceName })
 
-        return list(ret) if ret is not None else None
+        return resp
 
     def get_user_roles(self, user):
-        ret = self.__call_api_with_url_params(RangerClient.GET_USER_ROLES, { RangerClient.PARAM_NAME: user }, {}, {})
+        ret = self.__call_api(RangerClient.GET_USER_ROLES.format_path({ 'name': user }))
 
         return list(ret) if ret is not None else None
 
-    def find_roles(self, filter):
-        ret = self.__call_api(RangerClient.FIND_ROLES, filter, {})
+    def find_roles(self, filter={}):
+        resp = self.__call_api(RangerClient.FIND_ROLES, filter)
 
-        return list(ret) if ret is not None else None
+        return type_coerce_list(resp, RangerRole)
 
     def grant_role(self, serviceName, request):
-        ret = self.__call_api_with_url_params(RangerClient.GRANT_ROLE, { RangerClient.PARAM_NAME: serviceName }, {}, request)
+        resp = self.__call_api(RangerClient.GRANT_ROLE.format_path({ 'name': serviceName }), request_data=request)
 
-        return RESTResponse(**ret) if ret is not None else None
+        return type_coerce(resp, RESTResponse)
 
     def revoke_role(self, serviceName, request):
-        ret = self.__call_api_with_url_params(RangerClient.REVOKE_ROLE, { RangerClient.PARAM_NAME: serviceName }, {}, request)
+        resp = self.__call_api(RangerClient.REVOKE_ROLE.format_path({ 'name': serviceName }), request_data=request)
+
+        return type_coerce(resp, RESTResponse)
 
-        return RESTResponse(**ret) if ret is not None else None
 
     # Admin APIs
     def delete_policy_deltas(self, days, reloadServicePoliciesCache):
-        query_params = {
-            RangerClient.PARAM_DAYS: days,
-            RangerClient.PARAM_RELOAD_SERVICE_POLICIES_CACHE: reloadServicePoliciesCache
-        }
+        self.__call_api(RangerClient.DELETE_POLICY_DELTAS, { 'days': days, 'reloadServicePoliciesCache': reloadServicePoliciesCache})
+
+
+
+    def __call_api(self, api, query_params=None, request_data=None):
+        ret    = None
+        params = { 'headers': { 'Accept': api.consumes, 'Content-type': api.produces } }
+
+        if query_params:
+            params['params'] = query_params
+
+        if request_data:
+            params['data'] = json.dumps(request_data)
+
+        path = os.path.join(self.url, api.path)
+
+        if LOG.isEnabledFor(logging.DEBUG):
+            LOG.debug("------------------------------------------------------")
+            LOG.debug("Call         : %s %s", api.method, path)
+            LOG.debug("Content-type : %s", api.consumes)
+            LOG.debug("Accept       : %s", api.produces)
+
+        response = None
+
+        if api.method == HttpMethod.GET:
+            response = self.session.get(path, **params)
+        elif api.method == HttpMethod.POST:
+            response = self.session.post(path, **params)
+        elif api.method == HttpMethod.PUT:
+            response = self.session.put(path, **params)
+        elif api.method == HttpMethod.DELETE:
+            response = self.session.delete(path, **params)
 
-        self.__call_api(RangerClient.DELETE_POLICY_DELTAS, query_params, {})
+        if LOG.isEnabledFor(logging.DEBUG):
+            LOG.debug("HTTP Status: %s", response.status_code if response else "None")
+
+        if response is None:
+            ret = None
+        elif response.status_code == api.expected_status:
+            try:
+                if response.content:
+                    if LOG.isEnabledFor(logging.DEBUG):
+                        LOG.debug("<== __call_api(%s, %s, %s), result=%s", vars(api), params, request_data, response)
+
+                        LOG.debug(response.json())
+
+                    ret = response.json()
+                else:
+                    ret = None
+            except Exception as e:
+                print(e)
+
+                LOG.exception("Exception occurred while parsing response with msg: %s", e)
+
+                raise RangerServiceException(api, response)
+        elif response.status_code == HTTPStatus.SERVICE_UNAVAILABLE:
+            LOG.error("Ranger admin unavailable. HTTP Status: %s", HTTPStatus.SERVICE_UNAVAILABLE)
+
+            ret = None
+        else:
+            raise RangerServiceException(api, response)
+
+        return ret
+
+
+    # URIs
+    URI_BASE                = "service/public/v2/api"
+
+    URI_SERVICEDEF          = URI_BASE + "/servicedef"
+    URI_SERVICEDEF_BY_ID    = URI_SERVICEDEF + "/{id}"
+    URI_SERVICEDEF_BY_NAME  = URI_SERVICEDEF + "/name/{name}"
+
+    URI_SERVICE             = URI_BASE + "/service"
+    URI_SERVICE_BY_ID       = URI_SERVICE + "/{id}"
+    URI_SERVICE_BY_NAME     = URI_SERVICE + "/name/{name}"
+    URI_POLICIES_IN_SERVICE = URI_SERVICE + "/{serviceName}/policy"
+
+    URI_POLICY              = URI_BASE + "/policy"
+    URI_APPLY_POLICY        = URI_POLICY + "/apply"
+    URI_POLICY_BY_ID        = URI_POLICY + "/{id}"
+    URI_POLICY_BY_NAME      = URI_SERVICE + "/{serviceName}/policy/{policyName}"
+
+    URI_ROLE                = URI_BASE + "/roles"
+    URI_ROLE_NAMES          = URI_ROLE + "/names"
+    URI_ROLE_BY_ID          = URI_ROLE + "/{id}"
+    URI_ROLE_BY_NAME        = URI_ROLE + "/name/{name}"
+    URI_USER_ROLES          = URI_ROLE + "/user/{name}"
+    URI_GRANT_ROLE          = URI_ROLE + "/grant/{name}"
+    URI_REVOKE_ROLE         = URI_ROLE + "/revoke/{name}"
+
+    URI_ZONE                = URI_BASE + "/zones"
+    URI_ZONE_BY_ID          = URI_ZONE + "/{id}"
+    URI_ZONE_BY_NAME        = URI_ZONE + "/name/{name}"
+
+    URI_PLUGIN_INFO         = URI_BASE + "/plugins/info"
+    URI_POLICY_DELTAS       = URI_BASE + "/server/policydeltas"
+
+    # APIs
+    CREATE_SERVICEDEF         = API(URI_SERVICEDEF, HttpMethod.POST, HTTPStatus.OK)
+    UPDATE_SERVICEDEF_BY_ID   = API(URI_SERVICEDEF_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
+    UPDATE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
+    DELETE_SERVICEDEF_BY_ID   = API(URI_SERVICEDEF_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    DELETE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    GET_SERVICEDEF_BY_ID      = API(URI_SERVICEDEF_BY_ID, HttpMethod.GET, HTTPStatus.OK)
+    GET_SERVICEDEF_BY_NAME    = API(URI_SERVICEDEF_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
+    FIND_SERVICEDEFS          = API(URI_SERVICEDEF, HttpMethod.GET, HTTPStatus.OK)
 
-        return None
+    CREATE_SERVICE            = API(URI_SERVICE, HttpMethod.POST, HTTPStatus.OK)
+    UPDATE_SERVICE_BY_ID      = API(URI_SERVICE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
+    UPDATE_SERVICE_BY_NAME    = API(URI_SERVICE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
+    DELETE_SERVICE_BY_ID      = API(URI_SERVICE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    DELETE_SERVICE_BY_NAME    = API(URI_SERVICE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    GET_SERVICE_BY_ID         = API(URI_SERVICE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
+    GET_SERVICE_BY_NAME       = API(URI_SERVICE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
+    FIND_SERVICES             = API(URI_SERVICE, HttpMethod.GET, HTTPStatus.OK)
+
+    CREATE_POLICY             = API(URI_POLICY, HttpMethod.POST, HTTPStatus.OK)
+    UPDATE_POLICY_BY_ID       = API(URI_POLICY_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
+    UPDATE_POLICY_BY_NAME     = API(URI_POLICY_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
+    APPLY_POLICY              = API(URI_APPLY_POLICY, HttpMethod.POST, HTTPStatus.OK)
+    DELETE_POLICY_BY_ID       = API(URI_POLICY_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    DELETE_POLICY_BY_NAME     = API(URI_POLICY, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    GET_POLICY_BY_ID          = API(URI_POLICY_BY_ID, HttpMethod.GET, HTTPStatus.OK)
+    GET_POLICY_BY_NAME        = API(URI_POLICY_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
+    GET_POLICIES_IN_SERVICE   = API(URI_POLICIES_IN_SERVICE, HttpMethod.GET, HTTPStatus.OK)
+    FIND_POLICIES             = API(URI_POLICY, HttpMethod.GET, HTTPStatus.OK)
+
+    CREATE_ZONE               = API(URI_ZONE, HttpMethod.POST, HTTPStatus.OK)
+    UPDATE_ZONE_BY_ID         = API(URI_ZONE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
+    UPDATE_ZONE_BY_NAME       = API(URI_ZONE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
+    DELETE_ZONE_BY_ID         = API(URI_ZONE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    DELETE_ZONE_BY_NAME       = API(URI_ZONE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    GET_ZONE_BY_ID            = API(URI_ZONE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
+    GET_ZONE_BY_NAME          = API(URI_ZONE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
+    FIND_ZONES                = API(URI_ZONE, HttpMethod.GET, HTTPStatus.OK)
+
+    CREATE_ROLE               = API(URI_ROLE, HttpMethod.POST, HTTPStatus.OK)
+    UPDATE_ROLE_BY_ID         = API(URI_ROLE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
+    DELETE_ROLE_BY_ID         = API(URI_ROLE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    DELETE_ROLE_BY_NAME       = API(URI_ROLE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+    GET_ROLE_BY_ID            = API(URI_ROLE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
+    GET_ROLE_BY_NAME          = API(URI_ROLE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
+    GET_ALL_ROLE_NAMES        = API(URI_ROLE_NAMES, HttpMethod.GET, HTTPStatus.OK)
+    GET_USER_ROLES            = API(URI_USER_ROLES, HttpMethod.GET, HTTPStatus.OK)
+    GRANT_ROLE                = API(URI_GRANT_ROLE, HttpMethod.PUT, HTTPStatus.OK)
+    REVOKE_ROLE               = API(URI_REVOKE_ROLE, HttpMethod.PUT, HTTPStatus.OK)
+    FIND_ROLES                = API(URI_ROLE, HttpMethod.GET, HTTPStatus.OK)
+
+    GET_PLUGIN_INFO           = API(URI_PLUGIN_INFO, HttpMethod.GET, HTTPStatus.OK)
+    DELETE_POLICY_DELTAS      = API(URI_POLICY_DELTAS, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
+
+
+class Message(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.name      = attrs.get('name')
+        self.rbKey     = attrs.get('rbKey')
+        self.message   = attrs.get('message')
+        self.objectId  = attrs.get('objectId')
+        self.fieldName = attrs.get('fieldName')
+
+
+class RESTResponse(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.httpStatusCode = attrs.get('httpStatusCode')
+        self.statusCode     = attrs.get('statusCode')
+        self.msgDesc        = attrs.get('msgDesc')
+        self.messageList    = non_null(attrs.get('messageList'), [])
+
+    def type_coerce_attrs(self):
+        super(RangerPolicy, self).type_coerce_attrs()
+
+        self.messageList = type_coerce_dict(self.messageList, Message)
diff --git a/intg/src/main/python/apache_ranger/exceptions.py b/intg/src/main/python/apache_ranger/exceptions.py
new file mode 100644
index 0000000..a229947
--- /dev/null
+++ b/intg/src/main/python/apache_ranger/exceptions.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+
+class RangerServiceException(Exception):
+    """Exception raised for errors in API calls.
+
+    Attributes:
+        api      -- api endpoint which caused the error
+        response -- response from the server
+    """
+
+    def __init__(self, api, response):
+        self.method          = api.method.name
+        self.path            = api.path
+        self.expected_status = api.expected_status
+        self.statusCode      = -1
+        self.msgDesc         = None
+        self.messageList     = None
+
+        print(response)
+
+        if api is not None and response is not None:
+            respJson = response.json()
+
+            self.statusCode  = response.status_code
+            self.msgDesc     = respJson['msgDesc']     if respJson is not None and 'msgDesc'     in respJson else None
+            self.messageList = respJson['messageList'] if respJson is not None and 'messageList' in respJson else None
+
+        Exception.__init__(self, "{} {} failed: expected_status={}, status={}, message={}".format(self.method, self.path, self.expected_status, self.statusCode, self.msgDesc))
diff --git a/intg/src/main/python/apache_ranger/model/grant_revoke_role_request.py b/intg/src/main/python/apache_ranger/model/grant_revoke_role_request.py
index fb0eab2..fcc9078 100644
--- a/intg/src/main/python/apache_ranger/model/grant_revoke_role_request.py
+++ b/intg/src/main/python/apache_ranger/model/grant_revoke_role_request.py
@@ -16,24 +16,24 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
+from apache_ranger.model.ranger_base import *
+from apache_ranger.utils             import *
 
 
-class GrantRevokeRoleRequest:
-    def __init__(self, grantor=None, grantorGroups=None, targetRoles=None, users=None, groups=None, roles=None, grantOption=None, clientIPAddress=None, clientType=None, requestData=None, sessionId=None, clusterName=None):
-        self.grantor         = grantor
-        self.grantorGroups   = grantorGroups if grantorGroups is not None else []
-        self.targetRoles     = targetRoles if targetRoles is not None else []
-        self.users           = users if users is not None else []
-        self.groups          = groups if groups is not None else []
-        self.roles           = roles if roles is not None else []
-        self.grantOption     = grantOption if grantOption is not None else False
-        self.clientIPAddress = clientIPAddress
-        self.clientType      = clientType
-        self.requestData     = requestData
-        self.sessionId       = sessionId
-        self.clusterName     = clusterName
+class GrantRevokeRoleRequest(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.grantor         = attrs.get('grantor')
+        self.grantorGroups   = attrs.get('grantorGroups')
+        self.targetRoles     = attrs.get('targetRoles')
+        self.users           = attrs.get('users')
+        self.groups          = attrs.get('groups')
+        self.roles           = attrs.get('roles')
+        self.grantOption     = non_null(attrs.get('grantOption'), False)
+        self.clientIPAddress = attrs.get('clientIPAddress')
+        self.clientType      = attrs.get('clientType')
+        self.requestData     = attrs.get('requestData')
+        self.sessionId       = attrs.get('sessionId')
+        self.clusterName     = attrs.get('clusterName')
 
diff --git a/intg/src/main/python/apache_ranger/model/ranger_base.py b/intg/src/main/python/apache_ranger/model/ranger_base.py
index ae8de74..edabe2c 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_base.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_base.py
@@ -18,17 +18,46 @@
 
 import json
 
+from apache_ranger.utils import *
 
-class RangerBase:
-    def __init__(self, id=None, guid=None, createdBy=None, updatedBy=None, createTime=None, updateTime=None, version=None, isEnabled=None):
-        self.id         = id
-        self.guid       = guid
-        self.isEnabled  = isEnabled if isEnabled is not None else True
-        self.createdBy  = createdBy
-        self.updatedBy  = updatedBy
-        self.createTime = createTime
-        self.updateTime = updateTime
-        self.version    = version
+
+class RangerBase(dict):
+    def __init__(self, attrs):
+        pass
+
+    def __getattr__(self, attr):
+        return self.get(attr)
+
+    def __setattr__(self, key, value):
+        self.__setitem__(key, value)
+
+    def __setitem__(self, key, value):
+        super(RangerBase, self).__setitem__(key, value)
+        self.__dict__.update({key: value})
+
+    def __delattr__(self, item):
+        self.__delitem__(item)
+
+    def __delitem__(self, key):
+        super(RangerBase, self).__delitem__(key)
+        del self.__dict__[key]
 
     def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        return json.dumps(self)
+
+    def type_coerce_attrs(self):
+        pass
+
+
+class RangerBaseModelObject(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.id         = attrs.get('id')
+        self.guid       = attrs.get('guid')
+        self.isEnabled  = non_null(attrs.get('isEnabled'), True)
+        self.createdBy  = attrs.get('createdBy')
+        self.updatedBy  = attrs.get('updatedBy')
+        self.createTime = attrs.get('createTime')
+        self.updateTime = attrs.get('updateTime')
+        self.version    = attrs.get('version')
diff --git a/intg/src/main/python/apache_ranger/model/ranger_policy.py b/intg/src/main/python/apache_ranger/model/ranger_policy.py
index 2136989..1531a84 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_policy.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_policy.py
@@ -16,112 +16,140 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
 
-from apache_ranger.model.ranger_base import RangerBase
+from apache_ranger.model.ranger_base import *
+from apache_ranger.utils             import *
 
 
-class RangerPolicyResource:
-    def __init__(self, values=None, isExcludes=None, isRecursive=None):
-        self.values      = values if values is not None else []
-        self.isExcludes  = isExcludes if isExcludes is not None else False
-        self.isRecursive = isRecursive if isRecursive is not None else False
+class RangerPolicy(RangerBaseModelObject):
+    POLICY_TYPE_ACCESS    = 0
+    POLICY_TYPE_DATAMASK  = 1
+    POLICY_TYPE_ROWFILTER = 2
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+    def __init__(self, attrs={}):
+        RangerBaseModelObject.__init__(self, attrs)
 
+        self.service              = attrs.get('service')
+        self.name                 = attrs.get('name')
+        self.policyType           = attrs.get('policyType')
+        self.policyPriority       = attrs.get('policyPriority')
+        self.description          = attrs.get('description')
+        self.resourceSignature    = attrs.get('resourceSignature')
+        self.isAuditEnabled       = attrs.get('isAuditEnabled')
+        self.resources            = attrs.get('resources')
+        self.policyItems          = attrs.get('policyItems')
+        self.denyPolicyItems      = attrs.get('denyPolicyItems')
+        self.allowExceptions      = attrs.get('allowExceptions')
+        self.denyExceptions       = attrs.get('denyExceptions')
+        self.dataMaskPolicyItems  = attrs.get('dataMaskPolicyItems')
+        self.rowFilterPolicyItems = attrs.get('rowFilterPolicyItems')
+        self.serviceType          = attrs.get('serviceType')
+        self.options              = attrs.get('options')
+        self.validitySchedules    = attrs.get('validitySchedules')
+        self.policyLabels         = attrs.get('policyLabels')
+        self.zoneName             = attrs.get('zoneName')
+        self.conditions           = attrs.get('conditions')
+        self.isDenyAllElse        = non_null(attrs.get('isDenyAllElse'), False)
 
-class RangerPolicyItemCondition:
-    def __init__(self, type=None, values=None):
-        self.type   = type
-        self.values = values if values is not None else []
+    def type_coerce_attrs(self):
+        super(RangerPolicy, self).type_coerce_attrs()
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.resources            = type_coerce_dict(self.resources, RangerPolicyResource)
+        self.policyItems          = type_coerce_list(self.policyItems, RangerPolicyItem)
+        self.denyPolicyItems      = type_coerce_list(self.denyPolicyItems, RangerPolicyItem)
+        self.allowExceptions      = type_coerce_list(self.allowExceptions, RangerPolicyItem)
+        self.denyExceptions       = type_coerce_list(self.denyExceptions, RangerPolicyItem)
+        self.dataMaskPolicyItems  = type_coerce_list(self.dataMaskPolicyItems, RangerDataMaskPolicyItem)
+        self.rowFilterPolicyItems = type_coerce_list(self.rowFilterPolicyItems, RangerRowFilterPolicyItem)
+        self.validitySchedules    = type_coerce_list(self.validitySchedules, RangerValiditySchedule)
 
 
-class RangerPolicyItem:
-    def __init__(self, accesses=None, users=None, groups=None, roles=None, conditions=None, delegateAdmin=None):
-        self.accesses      = accesses if accesses is not None else []
-        self.users         = users if users is not None else []
-        self.groups        = groups if groups is not None else []
-        self.roles         = roles if roles is not None else []
-        self.conditions    = conditions if conditions is not None else []
-        self.delegateAdmin = delegateAdmin if delegateAdmin is not None else False
+class RangerPolicyResource(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.values      = attrs.get('values')
+        self.isExcludes  = non_null(attrs.get('isExcludes'), False)
+        self.isRecursive = non_null(attrs.get('isRecursive'), False)
 
 
-class RangerPolicyItemAccess:
-    def __init__(self, type=None, isAllowed=None):
-        self.type      = type
-        self.isAllowed = isAllowed if isAllowed is not None else True
+class RangerPolicyItemCondition(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.type   = attrs.get('type')
+        self.values = attrs.get('values')
 
 
-class RangerPolicyItemDataMaskInfo:
-    def __init__(self, dataMaskType=None, conditionExpr=None, valueExpr=None):
-        self.dataMaskType  = dataMaskType
-        self.conditionExpr = conditionExpr
-        self.valueExpr     = valueExpr
+class RangerPolicyItem(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.accesses      = attrs.get('accesses')
+        self.users         = attrs.get('users')
+        self.groups        = attrs.get('groups')
+        self.roles         = attrs.get('roles')
+        self.conditions    = attrs.get('conditions')
+        self.delegateAdmin = non_null(attrs.get('delegateAdmin'), False)
+
+    def type_coerce_attrs(self):
+        super(RangerPolicyItem, self).type_coerce_attrs()
+
+        self.accesses = type_coerce_list(self.accesses, RangerPolicyItemAccess)
 
 
 class RangerDataMaskPolicyItem(RangerPolicyItem):
-    def __init__(self, dataMaskInfo=None, accesses=None, users=None, groups=None, roles=None, conditions=None, delegateAdmin=None):
-        super().__init__(accesses, users, groups, roles, conditions, delegateAdmin)
+    def __init__(self, attrs={}):
+        RangerPolicyItem.__init__(self, attrs)
+
+        self.dataMaskInfo = attrs.get('dataMaskInfo')
 
-        self.dataMaskInfo = dataMaskInfo if dataMaskInfo is not None else RangerPolicyItemDataMaskInfo()
+    def type_coerce_attrs(self):
+        super(RangerDataMaskPolicyItem, self).type_coerce_attrs()
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.dataMaskInfo = type_coerce(self.dataMaskInfo, RangerPolicyItemDataMaskInfo)
 
 
 class RangerRowFilterPolicyItem(RangerPolicyItem):
-    def __init__(self, rowFilterInfo=None, accesses=None, users=None, groups=None, roles=None, conditions=None, delegateAdmin=None):
-        super().__init__(accesses, users, groups, roles, conditions, delegateAdmin)
-
-        self.rowFilterInfo = rowFilterInfo
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
-
-class RangerPolicy(RangerBase):
-    def __init__(self, id=None, guid=None, createdBy=None, updatedBy=None, createTime=None, updateTime=None,
-                 service=None, name=None, description=None, isEnabled=True, isAuditEnabled=None, resources=None,
-                 policyItems=None, dataMaskPolicyItems=None, rowFilterPolicyItems=None, serviceType=None, options=None,
-                 policyLabels=None, zoneName=None, isDenyAllElse=None, validitySchedules=None, version=None,
-                 denyPolicyItems=None, denyExceptions=None, allowExceptions=None, resourceSignature=None,
-                 policyType=None, policyPriority=None, conditions=None):
-        super().__init__(id, guid, createdBy, updatedBy, createTime, updateTime, version, isEnabled)
-
-        self.service              = service
-        self.name                 = name
-        self.policyType           = policyType
-        self.policyPriority       = policyPriority if policyPriority is not None else 0
-        self.description          = description
-        self.resourceSignature    = resourceSignature
-        self.isAuditEnabled       = isAuditEnabled if isAuditEnabled is not None else True
-        self.resources            = resources if resources is not None else {}
-        self.policyItems          = policyItems if policyItems is not None else []
-        self.denyPolicyItems      = denyPolicyItems if denyPolicyItems is not None else []
-        self.allowExceptions      = allowExceptions if allowExceptions is not None else []
-        self.denyExceptions       = denyExceptions if denyExceptions is not None else []
-        self.dataMaskPolicyItems  = dataMaskPolicyItems if dataMaskPolicyItems is not None else []
-        self.rowFilterPolicyItems = rowFilterPolicyItems if rowFilterPolicyItems is not None else []
-        self.serviceType          = serviceType
-        self.options              = options if options is not None else {}
-        self.validitySchedules    = validitySchedules if validitySchedules is not None else []
-        self.policyLabels         = policyLabels if policyLabels is not None else []
-        self.zoneName             = zoneName
-        self.conditions           = conditions
-        self.isDenyAllElse        = isDenyAllElse if isDenyAllElse is not None else False
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+    def __init__(self, attrs={}):
+        RangerPolicyItem.__init__(self, attrs)
+
+        self.rowFilterInfo = attrs.get('rowFilterInfo')
+
+    def type_coerce_attrs(self):
+        super(RangerRowFilterPolicyItem, self).type_coerce_attrs()
+
+        self.rowFilterInfo = type_coerce(self.rowFilterInfo, RangerPolicyItemRowFilterInfo)
+
+
+class RangerValiditySchedule(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.startTime = attrs.get('startTime')
+        self.endTime   = attrs.get('endTime')
+        self.timeZone  = attrs.get('timeZone')
+
+
+class RangerPolicyItemAccess(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.type      = attrs.get('type')
+        self.isAllowed = non_null(attrs.get('isAllowed'), True)
+
+
+class RangerPolicyItemDataMaskInfo(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.dataMaskType  = attrs.get('dataMaskType')
+        self.conditionExpr = attrs.get('conditionExpr')
+        self.valueExpr     = attrs.get('valueExpr')
+
+
+class RangerPolicyItemRowFilterInfo(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.filterExpr = attrs.get('filterExpr')
diff --git a/intg/src/main/python/apache_ranger/model/ranger_role.py b/intg/src/main/python/apache_ranger/model/ranger_role.py
index 1c698ed..c789a76 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_role.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_role.py
@@ -16,33 +16,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
+from apache_ranger.model.ranger_base import RangerBase, RangerBaseModelObject
+from apache_ranger.utils             import *
 
-from apache_ranger.model.ranger_base import RangerBase
 
+class RoleMember(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-class RoleMember:
-    def __init__(self, name=None, isAdmin=None):
-        self.name    = name
-        self.isAdmin = isAdmin if isAdmin is not None else False
+        self.name    = attrs.get('name')
+        self.isAdmin = non_null(attrs.get('isAdmin'), False)
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
 
+class RangerRole(RangerBaseModelObject):
+    def __init__(self, attrs={}):
+        RangerBaseModelObject.__init__(self, attrs)
 
-class RangerRole(RangerBase):
-    def __init__(self, id=None, guid=None, createdBy=None, updatedBy=None, createTime=None, updateTime=None,
-                 version=None, isEnabled=None, name=None, description=None, options=None, users=None, groups=None,
-                 roles=None, createdByUser=None):
-        super().__init__(id, guid, createdBy, updatedBy, createTime, updateTime, version, isEnabled)
-
-        self.name          = name
-        self.description   = description
-        self.options       = options if options is not None else {}
-        self.users         = users if users is not None else []
-        self.groups        = groups if groups is not None else []
-        self.roles         = roles if roles is not None else []
-        self.createdByUser = createdByUser
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.name          = attrs.get('name')
+        self.description   = attrs.get('description')
+        self.options       = attrs.get('options')
+        self.users         = attrs.get('users')
+        self.groups        = attrs.get('groups')
+        self.roles         = attrs.get('roles')
+        self.createdByUser = attrs.get('createdByUser')
diff --git a/intg/src/main/python/apache_ranger/model/ranger_security_zone.py b/intg/src/main/python/apache_ranger/model/ranger_security_zone.py
index 9ed8208..2ba0915 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_security_zone.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_security_zone.py
@@ -16,33 +16,25 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
+from apache_ranger.model.ranger_base import RangerBase, RangerBaseModelObject
 
-from apache_ranger.model.ranger_base import RangerBase
 
+class RangerSecurityZoneService(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-class RangerSecurityZoneService:
-    def __init__(self, resources=None):
-        self.resources = resources if resources is not None else []
+        self.resources = attrs.get('resources')
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
 
+class RangerSecurityZone(RangerBaseModelObject):
+    def __init__(self, attrs={}):
+        RangerBaseModelObject.__init__(self, attrs)
 
-class RangerSecurityZone(RangerBase):
-    def __init__(self, id=None, guid=None, createdBy=None, updatedBy=None, createTime=None, updateTime=None,
-                 version=None, isEnabled=None, name=None, services=None, tagServices=None, adminUsers=None,
-                 adminUserGroups=None, auditUsers=None, auditUserGroups=None, description=None):
-        super().__init__(id, guid, createdBy, updatedBy, createTime, updateTime, version, isEnabled)
-        self.name = name
-        self.services = services if services is not None else {}
-        self.tagServices = tagServices if tagServices is not None else []
-        self.adminUsers = adminUsers if adminUsers is not None else []
-        self.adminUserGroups = adminUserGroups if adminUserGroups is not None else []
-        self.auditUsers = auditUsers if auditUsers is not None else []
-        self.auditUserGroups = auditUserGroups if auditUserGroups is not None else []
-        self.description = description
-        return
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.name            = attrs.get('name')
+        self.services        = attrs.get('services')
+        self.tagServices     = attrs.get('tagServices')
+        self.adminUsers      = attrs.get('adminUsers')
+        self.adminUserGroups = attrs.get('adminUserGroups')
+        self.auditUsers      = attrs.get('auditUsers')
+        self.auditUserGroups = attrs.get('auditUserGroups')
+        self.description     = attrs.get('description')
diff --git a/intg/src/main/python/apache_ranger/model/ranger_service.py b/intg/src/main/python/apache_ranger/model/ranger_service.py
index e07a706..d8ea93b 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_service.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_service.py
@@ -16,28 +16,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
+from apache_ranger.model.ranger_base import RangerBaseModelObject
 
-from apache_ranger.model.ranger_base import RangerBase
 
+class RangerService(RangerBaseModelObject):
+    def __init__(self, attrs={}):
+        RangerBaseModelObject.__init__(self, attrs)
 
-class RangerService(RangerBase):
-    def __init__(self, id=None, guid=None, createdBy=None, updatedBy=None, createTime=None, updateTime=None,
-                 version=None, isEnabled=None, type=None, name=None, displayName=None, description=None,
-                 tagService=None, configs=None, policyVersion=None, policyUpdateTime=None, tagVersion=None,
-                 tagUpdateTime=None):
-        super().__init__(id, guid, createdBy, updatedBy, createTime, updateTime, version, isEnabled)
-
-        self.type             = type
-        self.name             = name
-        self.displayName      = displayName
-        self.description      = description
-        self.tagService       = tagService
-        self.configs          = configs if configs is not None else {}
-        self.policyVersion    = policyVersion
-        self.policyUpdateTime = policyUpdateTime
-        self.tagVersion       = tagVersion
-        self.tagUpdateTime    = tagUpdateTime
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.type             = attrs.get('type')
+        self.name             = attrs.get('name')
+        self.displayName      = attrs.get('displayName')
+        self.description      = attrs.get('description')
+        self.tagService       = attrs.get('tagService')
+        self.configs          = attrs.get('configs')
+        self.policyVersion    = attrs.get('policyVersion')
+        self.policyUpdateTime = attrs.get('policyUpdateTime')
+        self.tagVersion       = attrs.get('tagVersion')
+        self.tagUpdateTime    = attrs.get('tagUpdateTime')
diff --git a/intg/src/main/python/apache_ranger/model/ranger_service_def.py b/intg/src/main/python/apache_ranger/model/ranger_service_def.py
index ec3845d..b35fe2a 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_service_def.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_service_def.py
@@ -16,121 +16,194 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import json
+from apache_ranger.model.ranger_base import RangerBase, RangerBaseModelObject
+from apache_ranger.utils             import *
+
+
+class RangerServiceDef(RangerBaseModelObject):
+    def __init__(self, attrs={}):
+        RangerBaseModelObject.__init__(self, attrs)
+
+        self.name             = attrs.get('name')
+        self.displayName      = attrs.get('displayName')
+        self.implClass        = attrs.get('implClass')
+        self.label            = attrs.get('label')
+        self.description      = attrs.get('description')
+        self.rbKeyLabel       = attrs.get('rbKeyLabel')
+        self.rbKeyDescription = attrs.get('rbKeyDescription')
+        self.options          = attrs.get('options')
+        self.configs          = attrs.get('configs')
+        self.resources        = attrs.get('resources')
+        self.accessTypes      = attrs.get('accessTypes')
+        self.policyConditions = attrs.get('policyConditions')
+        self.contextEnrichers = attrs.get('contextEnrichers')
+        self.enums            = attrs.get('enums')
+        self.dataMaskDef      = attrs.get('dataMaskDef')
+        self.rowFilterDef     = attrs.get('rowFilterDef')
+
+    def type_coerce_attrs(self):
+        super(RangerServiceDef, self).type_coerce_attrs()
+
+        self.configs          = type_coerce_list(self.configs, RangerResourceDef)
+        self.resources        = type_coerce_list(self.resources, RangerResourceDef)
+        self.accessTypes      = type_coerce_list(self.accessTypes, RangerAccessTypeDef)
+        self.policyConditions = type_coerce_list(self.policyConditions, RangerPolicyConditionDef)
+        self.contextEnrichers = type_coerce_list(self.contextEnrichers, RangerContextEnricherDef)
+        self.enums            = type_coerce_list(self.enums, RangerEnumDef)
+        self.dataMaskDef      = type_coerce(self.dataMaskDef, RangerDataMaskDef)
+        self.rowFilterDef     = type_coerce(self.rowFilterDef, RangerRowFilterDef)
 
-from apache_ranger.model.ranger_base import RangerBase
+
+class RangerServiceConfigDef:
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.itemId                 = attrs.get('itemId')
+        self.name                   = attrs.get('name')
+        self.type                   = attrs.get('type')
+        self.subType                = attrs.get('subType')
+        self.mandatory              = attrs.get('mandatory')
+        self.defaultValue           = attrs.get('defaultValue')
+        self.validationRegEx        = attrs.get('validationRegEx')
+        self.validationMessage      = attrs.get('validationMessage')
+        self.uiHint                 = attrs.get('uiHint')
+        self.label                  = attrs.get('label')
+        self.description            = attrs.get('description')
+        self.rbKeyLabel             = attrs.get('rbKeyLabel')
+        self.rbKeyDescription       = attrs.get('rbKeyDescription')
+        self.rbKeyValidationMessage = attrs.get('rbKeyValidationMessage')
+
+
+class RangerResourceDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.itemId                 = attrs.get('itemId')
+        self.name                   = attrs.get('name')
+        self.type                   = attrs.get('type')
+        self.level                  = non_null(attrs.get('level'), 1)
+        self.parent                 = attrs.get('parent')
+        self.mandatory              = attrs.get('mandatory')
+        self.lookupSupported        = attrs.get('lookupSupported')
+        self.recursiveSupported     = attrs.get('recursiveSupported')
+        self.excludesSupported      = attrs.get('excludesSupported')
+        self.matcher                = attrs.get('matcher')
+        self.matcherOptions         = attrs.get('matcherOptions')
+        self.validationRegEx        = attrs.get('validationRegEx')
+        self.validationMessage      = attrs.get('validationMessage')
+        self.uiHint                 = attrs.get('uiHint')
+        self.label                  = attrs.get('label')
+        self.description            = attrs.get('description')
+        self.rbKeyLabel             = attrs.get('rbKeyLabel')
+        self.rbKeyDescription       = attrs.get('rbKeyDescription')
+        self.rbKeyValidationMessage = attrs.get('rbKeyValidationMessage')
+        self.accessTypeRestrictions = attrs.get('accessTypeRestrictions')
+        self.isValidLeaf            = attrs.get('isValidLeaf')
+
+
+class RangerAccessTypeDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.itemId        = attrs.get('itemId')
+        self.name          = attrs.get('name')
+        self.label         = attrs.get('label')
+        self.rbKeyLabel    = attrs.get('rbKeyLabel')
+        self.impliedGrants = attrs.get('impliedGrants')
+
+
+class RangerPolicyConditionDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.itemId                 = attrs.get('itemId')
+        self.name                   = attrs.get('name')
+        self.evaluator              = attrs.get('evaluator')
+        self.evaluatorOptions       = attrs.get('evaluatorOptions')
+        self.validationRegEx        = attrs.get('validationRegEx')
+        self.validationMessage      = attrs.get('validationMessage')
+        self.uiHint                 = attrs.get('uiHint')
+        self.label                  = attrs.get('label')
+        self.description            = attrs.get('description')
+        self.rbKeyLabel             = attrs.get('rbKeyLabel')
+        self.rbKeyDescription       = attrs.get('rbKeyDescription')
+        self.rbKeyValidationMessage = attrs.get('rbKeyValidationMessage')
+
+
+class RangerContextEnricherDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.itemId         = attrs.get('itemId')
+        self.name           = attrs.get('name')
+        self.enricher       = attrs.get('enricher')
+        self.enricherOptions = attrs.get('enricherOptions')
+
+
+class RangerEnumDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.itemId       = attrs.get('itemId')
+        self.name         = attrs.get('name')
+        self.elements     = attrs.get('elements')
+        self.defaultIndex = attrs.get('defaultIndex')
+
+    def type_coerce_attrs(self):
+        super(RangerEnumDef, self).type_coerce_attrs()
+
+        self.elements = type_coerce_list(self.resources, RangerEnumElementDef)
+
+
+class RangerDataMaskDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.maskTypes   = attrs.get('maskTypes')
+        self.accessTypes = attrs.get('accessTypes')
+        self.resources   = attrs.get('resources')
+
+    def type_coerce_attrs(self):
+        super(RangerDataMaskDef, self).type_coerce_attrs()
+
+        self.maskTypes   = type_coerce_list(self.maskTypes, RangerDataMaskTypeDef)
+        self.accessTypes = type_coerce_list(self.accessTypes, RangerAccessTypeDef)
+        self.resources   = type_coerce_list(self.resources, RangerResourceDef)
+
+
+class RangerRowFilterDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
+
+        self.accessTypes = attrs.get('accessTypes')
+        self.resources   = attrs.get('resources')
+
+    def type_coerce_attrs(self):
+        super(RangerRowFilterDef, self).type_coerce_attrs()
+
+        self.accessTypes = type_coerce_list(self.accessTypes, RangerAccessTypeDef)
+        self.resources   = type_coerce_list(self.accessTypes, RangerResourceDef)
 
 
-class RangerDataMaskDef:
-    def __init__(self, maskTypes=None, accessTypes=None, resources=None):
-        self.maskTypes   = maskTypes if maskTypes is not None else []
-        self.accessTypes = accessTypes if accessTypes is not None else []
-        self.resources   = resources if resources is not None else []
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
+class RangerEnumElementDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-class RangerRowFilterDef:
-    def __init__(self, accessTypes=None, resources=None):
-        self.accessTypes = accessTypes if accessTypes is not None else []
-        self.resources   = resources if resources is not None else []
+        self.itemId     = attrs.get('itemId')
+        self.name       = attrs.get('name')
+        self.label      = attrs.get('label')
+        self.rbKeyLabel = attrs.get('rbKeyLabel')
 
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
 
+class RangerDataMaskTypeDef(RangerBase):
+    def __init__(self, attrs={}):
+        RangerBase.__init__(self, attrs)
 
-class RangerServiceConfigDef:
-    def __init__(self, itemId=None, name=None, type=None, subType=None, mandatory=None, defaultValue=None,
-                 validationRegEx=None, validationMessage=None, uiHint=None, label=None, description=None,
-                 rbKeyLabel=None, rbKeyDescription=None, rbKeyValidationMessage=None):
-        self.itemId                 = itemId
-        self.name                   = name
-        self.type                   = type
-        self.subType                = subType
-        self.mandatory              = mandatory if mandatory is not None else False
-        self.defaultValue           = defaultValue
-        self.validationRegEx        = validationRegEx
-        self.validationMessage      = validationMessage
-        self.uiHint                 = uiHint
-        self.label                  = label
-        self.description            = description
-        self.rbKeyLabel             = rbKeyLabel
-        self.rbKeyDescription       = rbKeyDescription
-        self.rbKeyValidationMessage = rbKeyValidationMessage
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
-
-class RangerAccessTypeDef:
-    def __init__(self, itemId=None, name=None, label=None, rbKeyLabel=None, impliedGrants=None):
-        self.itemId        = itemId
-        self.name          = name
-        self.label         = label
-        self.rbKeyLabel    = rbKeyLabel
-        self.impliedGrants = impliedGrants if impliedGrants is not None else []
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
-
-class RangerResourceDef:
-    def __init__(self, itemId=None, name=None, type=None, level=None, parent=None, mandatory=None, lookupSupported=None,
-                 recursiveSupported=None, excludesSupported=None, matcher=None, matcherOptions=None,
-                 validationRegEx=None, validationMessage=None, uiHint=None, label=None, description=None,
-                 rbKeyLabel=None, rbKeyDescription=None, rbKeyValidationMessage=None, accessTypeRestrictions=None,
-                 isValidLeaf=None):
-        self.itemId                 = itemId
-        self.name                   = name
-        self.type                   = type
-        self.level                  = level if level is not None else 1
-        self.parent                 = parent
-        self.mandatory              = mandatory if mandatory is not None else False
-        self.lookupSupported        = lookupSupported if lookupSupported is not None else False
-        self.recursiveSupported     = recursiveSupported if recursiveSupported is not None else False
-        self.excludesSupported      = excludesSupported if excludesSupported is not None else False
-        self.matcher                = matcher
-        self.matcherOptions         = matcherOptions if matcherOptions is not None else {}
-        self.validationRegEx        = validationRegEx
-        self.validationMessage      = validationMessage
-        self.uiHint                 = uiHint
-        self.label                  = label
-        self.description            = description
-        self.rbKeyLabel             = rbKeyLabel
-        self.rbKeyDescription       = rbKeyDescription
-        self.rbKeyValidationMessage = rbKeyValidationMessage
-        self.accessTypeRestrictions = accessTypeRestrictions if accessTypeRestrictions is not None else []
-        self.isValidLeaf            = isValidLeaf
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
-
-
-class RangerServiceDef(RangerBase):
-    def __init__(self, id=None, guid=None, createdBy=None, updatedBy=None, createTime=None, updateTime=None,
-                 version=None, isEnabled=None, name=None, displayName=None, implClass=None, label=None,
-                 description=None, rbKeyLabel=None, rbKeyDescription=None, options=None, configs=None, resources=None,
-                 accessTypes=None, policyConditions=None, contextEnrichers=None, enums=None, dataMaskDef=None,
-                 rowFilterDef=None):
-        super().__init__(id, guid, createdBy, updatedBy, createTime, updateTime, version, isEnabled)
-
-        self.name             = name
-        self.displayName      = displayName
-        self.implClass        = implClass
-        self.label            = label
-        self.description      = description
-        self.rbKeyLabel       = rbKeyLabel
-        self.rbKeyDescription = rbKeyDescription
-        self.options          = options if options is not None else {}
-        self.configs          = configs if configs is not None else []
-        self.resources        = resources if resources is not None else []
-        self.accessTypes      = accessTypes if accessTypes is not None else []
-        self.policyConditions = policyConditions if policyConditions is not None else []
-        self.contextEnrichers = contextEnrichers if contextEnrichers is not None else []
-        self.enums            = enums if enums is not None else []
-        self.dataMaskDef      = dataMaskDef if dataMaskDef is not None else RangerDataMaskDef()
-        self.rowFilterDef     = rowFilterDef if rowFilterDef is not None else RangerRowFilterDef()
-
-    def __repr__(self):
-        return json.dumps(self, default=lambda x: x.__dict__, sort_keys=True, indent=4)
+        self.itemId           = attrs.get('itemId')
+        self.name             = attrs.get('name')
+        self.label            = attrs.get('label')
+        self.description      = attrs.get('description')
+        self.transformer      = attrs.get('transformer')
+        self.dataMaskOptions  = attrs.get('dataMaskOptions')
+        self.rbKeyLabel       = attrs.get('rbKeyLabel')
+        self.rbKeyDescription = attrs.get('rbKeyDescription')
diff --git a/intg/src/main/python/apache_ranger/utils.py b/intg/src/main/python/apache_ranger/utils.py
new file mode 100644
index 0000000..4c7e77f
--- /dev/null
+++ b/intg/src/main/python/apache_ranger/utils.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 enum
+
+APPLICATION_JSON         = 'application/json'
+
+
+def non_null(obj, defValue):
+    return obj if obj is not None else defValue
+
+def type_coerce(obj, objType):
+    if isinstance(obj, objType):
+        ret = obj
+    elif isinstance(obj, dict):
+        ret = objType(obj)
+
+        ret.type_coerce_attrs()
+    else:
+        ret = None
+
+    return ret
+
+def type_coerce_list(obj, objType):
+    if isinstance(obj, list):
+        ret = []
+        for entry in obj:
+            ret.append(type_coerce(entry, objType))
+    else:
+        ret = None
+
+    return ret
+
+def type_coerce_dict(obj, objType):
+    if isinstance(obj, dict):
+        ret = {}
+        for k, v in obj.items():
+            ret[k] = type_coerce(v, objType)
+    else:
+        ret = None
+
+    return ret
+
+def type_coerce_dict_list(obj, objType):
+    if isinstance(obj, dict):
+        ret = {}
+        for k, v in obj.items():
+            ret[k] = type_coerce_list(v, objType)
+    else:
+        ret = None
+
+    return ret
+
+
+class API:
+    def __init__(self, path, method, expected_status, consumes=APPLICATION_JSON, produces=APPLICATION_JSON):
+        self.path            = path
+        self.method          = method
+        self.expected_status = expected_status
+        self.consumes        = consumes
+        self.produces        = produces
+
+    def format_path(self, params):
+        return API(self.path.format(**params), self.method, self.expected_status, self.consumes, self.produces)
+
+
+class HttpMethod(enum.Enum):
+    GET    = "GET"
+    PUT    = "PUT"
+    POST   = "POST"
+    DELETE = "DELETE"
+
+
+class HTTPStatus:
+    OK                  = 200
+    NO_CONTENT          = 204
+    SERVICE_UNAVAILABLE = 503
diff --git a/intg/src/main/python/setup.py b/intg/src/main/python/setup.py
index b073a80..5a97657 100644
--- a/intg/src/main/python/setup.py
+++ b/intg/src/main/python/setup.py
@@ -16,26 +16,34 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import setuptools
+from setuptools import setup, find_packages
 
+# External dependencies
+requirements = ['requests>=2.24']
+
+long_description = ''
 with open("README.md", "r") as fh:
     long_description = fh.read()
 
-setuptools.setup(
+setup(
     name="apache-ranger",
-    version="0.0.2",
+    version="0.0.3",
     author="Apache Ranger",
     author_email="dev@ranger.apache.org",
     description="Apache Ranger Python client",
     long_description=long_description,
     long_description_content_type="text/markdown",
     url="https://github.com/apache/ranger/tree/master/intg/src/main/python",
-    packages=setuptools.find_packages(),
+    license='Apache LICENSE 2.0',
     classifiers=[
-        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 2.7",
         "License :: OSI Approved :: Apache Software License",
         "Operating System :: OS Independent",
     ],
+    packages=find_packages(),
+    install_requires=requirements,
+    include_package_data=True,
+    zip_safe=False,
     keywords='ranger client, apache ranger',
-    python_requires='>=3.6',
+    python_requires='>=2.7',
 )
diff --git a/ranger-examples/sample-client/src/main/python/sample_client.py b/ranger-examples/sample-client/src/main/python/sample_client.py
index 1d1c331..9027349 100644
--- a/ranger-examples/sample-client/src/main/python/sample_client.py
+++ b/ranger-examples/sample-client/src/main/python/sample_client.py
@@ -16,131 +16,304 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import argparse
-import logging.config
+import time
 
-from os import path
+from apache_ranger.model.ranger_service import *
+from apache_ranger.client.ranger_client import *
+from apache_ranger.model.ranger_policy  import *
 
-from apache_ranger.model.ranger_service     import RangerService
-from apache_ranger.model.ranger_role        import RangerRole, RoleMember
-from apache_ranger.client.ranger_client     import RangerClient
-from apache_ranger.model.ranger_policy      import RangerPolicy, RangerPolicyResource
-from apache_ranger.model.ranger_service_def import RangerServiceConfigDef, RangerAccessTypeDef, RangerResourceDef, RangerServiceDef
 
-LOG_CONFIG = path.dirname(__file__) + '/../resources/logging.conf'
+## create a client to connect to Apache Ranger admin server
+ranger_url  = 'http://localhost:6080'
+ranger_auth = ('admin', 'rangerR0cks!')
 
-logging.config.fileConfig(LOG_CONFIG, disable_existing_loggers=False)
+# For Kerberos authentication
+#
+# from requests_kerberos import HTTPKerberosAuth
+#
+# ranger_auth = HTTPKerberosAuth()
+
+
+print('Using Ranger at ' + ranger_url);
+
+ranger = RangerClient(ranger_url, ranger_auth)
+
+# to disable SSL certificate validation (not recommended for production use!)
+#
+# ranger.session.verify = False
+
+
+print('Listing service-defs..')
+service_defs = ranger.find_service_defs()
+
+print('    ' + str(len(service_defs)) + ' service-defs found')
+for service_def in service_defs:
+    print('        ' + 'id: ' + str(service_def.id) + ', name: ' + service_def.name)
+
+
+service_name = 'dev_hive-' + str(int(time.time() * 1000))
+
+print('Creating service: name=' + service_name)
+
+service         = RangerService({'name': service_name, 'type': 'hive'})
+service.configs = {'username':'hive', 'password':'hive', 'jdbc.driverClassName': 'org.apache.hive.jdbc.HiveDriver', 'jdbc.url': 'jdbc:hive2://ranger-hadoop:10000', 'hadoop.security.authorization': 'true'}
+
+created_service = ranger.create_service(service)
+
+print('    created service: id: ' + str(created_service.id) + ', name: ' + created_service.name)
+
+service_id = created_service.id
+
+
+print('Retrieving service: id=' + str(service_id))
+
+retrieved_service = ranger.get_service_by_id(service_id)
+
+print('    retrieved service: id: ' + str(retrieved_service.id) + ', name: ' + retrieved_service.name)
+
+
+print('Retrieving service: name=' + service_name)
+
+retrieved_service = ranger.get_service(service_name)
+
+print('    retrieved service: id: ' + str(retrieved_service.id) + ', name: ' + retrieved_service.name)
+
+
+print('Updating service: id=' + str(service_id))
+
+saved_value                 = created_service.displayName
+created_service.displayName = service_name + '-UPDATE1'
+
+updated_service1 = ranger.update_service_by_id(service_id, created_service)
+
+print('    updated service: id: ' + str(updated_service1.id) + ', displayName: ' + saved_value + ', updatedDisplayName: ' + updated_service1.displayName)
+
+
+print('Updating service: name=' + service_name)
+
+saved_value                  = updated_service1.displayName
+updated_service1.displayName = service_name + '-UPDATE2'
+
+updated_service2 = ranger.update_service(service_name, updated_service1)
+
+print('    updated service: id: ' + str(updated_service2.id) + ', displayName: ' + saved_value + ', updatedDisplayName: ' + updated_service2.displayName)
+
+
+print('Listing services..')
+services = ranger.find_services()
+
+print('    ' + str(len(services)) + ' services found')
+for svc in services:
+    print('        ' + 'id: ' + str(svc.id) + ', type: ' + svc.type + ', name: ' + svc.name)
+
+
+print('Deleting service id=' + str(service_id))
+
+ranger.delete_service_by_id(service_id)
+
+print('    deleted service: id: ' + str(service_id) + ', name: ' + updated_service2.name)
+
+
+print('Deleting service: name=' + service.name)
+
+service_to_delete = ranger.create_service(service)
+
+print('    created service: id: ' + str(service_to_delete.id) + ', name: ' + service_to_delete.name)
+
+ranger.delete_service(service_to_delete.name)
+
+print('    deleted service: id: ' + str(service_to_delete.id) + ', name: ' + service_to_delete.name)
+
+
+print('Listing services..')
+services = ranger.find_services()
+
+print('    ' + str(len(services)) + ' services found')
+for svc in services:
+    print('        ' + 'id: ' + str(svc.id) + ', type: ' + svc.type + ', name: ' + svc.name)
+
+
+policy_name = 'test policy'
+
+print('Creating policy: name=' + policy_name)
+
+created_service = ranger.create_service(service)
+
+print('    created service: id: ' + str(created_service.id) + ', name: ' + created_service.name)
+
+service_id   = created_service.id
+service_name = created_service.name
+
+policy             = RangerPolicy()
+policy.service     = service_name
+policy.name        = policy_name
+policy.description = 'test description'
+policy.resources   = { 'database': RangerPolicyResource({ 'values': ['test_db'] }),
+                       'table':    RangerPolicyResource({ 'values': ['test_tbl'] }),
+					   'column':   RangerPolicyResource({ 'values': ['*'] }) }
+
+allowItem1          = RangerPolicyItem()
+allowItem1.users    = [ 'admin' ]
+allowItem1.accesses = [ RangerPolicyItemAccess({ 'type': 'create' }),
+                        RangerPolicyItemAccess({ 'type': 'alter' }),
+                        RangerPolicyItemAccess({ 'type': 'select' }) ]
+
+denyItem1          = RangerPolicyItem()
+denyItem1.users    = [ 'admin' ]
+denyItem1.accesses = [ RangerPolicyItemAccess({ 'type': 'drop' }) ]
+
+policy.policyItems     = [ allowItem1 ]
+policy.denyPolicyItems = [ denyItem1 ]
+
+created_policy = ranger.create_policy(policy)
+
+print('    created policy: id: ' + str(created_policy.id) + ', name: ' + created_policy.name)
+
+policy_id = created_policy.id
+
+
+data_mask_policy_name = 'test masking policy'
+
+print('Creating data-masking policy: name=' + data_mask_policy_name)
+
+data_mask_policy             = RangerPolicy()
+data_mask_policy.service     = service_name
+data_mask_policy.policyType  = RangerPolicy.POLICY_TYPE_DATAMASK
+data_mask_policy.name        = data_mask_policy_name
+data_mask_policy.description = 'test description'
+data_mask_policy.resources   = { 'database': RangerPolicyResource({ 'values': ['test_db'] }),
+                                 'table':    RangerPolicyResource({ 'values': ['test_tbl'] }),
+					             'column':   RangerPolicyResource({ 'values': ['test_col'] }) }
+
+policyItem1              = RangerDataMaskPolicyItem()
+policyItem1.users        = [ 'admin' ]
+policyItem1.accesses     = [ RangerPolicyItemAccess({ 'type': 'select' }) ]
+policyItem1.dataMaskInfo = RangerPolicyItemDataMaskInfo({ 'dataMaskType': 'MASK_SHOW_LAST_4' })
+
+data_mask_policy.dataMaskPolicyItems = [ policyItem1 ]
+
+created_data_mask_policy = ranger.create_policy(data_mask_policy)
+
+print('    created data-masking policy: id: ' + str(created_data_mask_policy.id) + ', name: ' + created_data_mask_policy.name)
+
+
+row_filter_policy_name = 'test row filter policy'
+
+print('Creating row-filtering policy: name=' + row_filter_policy_name)
+
+row_filter_policy             = RangerPolicy()
+row_filter_policy.service     = service_name
+row_filter_policy.policyType  = RangerPolicy.POLICY_TYPE_ROWFILTER
+row_filter_policy.name        = row_filter_policy_name
+row_filter_policy.description = 'test description'
+row_filter_policy.resources   = { 'database': RangerPolicyResource({ 'values': ['test_db'] }),
+                                  'table':    RangerPolicyResource({ 'values': ['test_tbl'] }) }
+
+policyItem1               = RangerRowFilterPolicyItem()
+policyItem1.users         = [ 'admin' ]
+policyItem1.accesses      = [ RangerPolicyItemAccess({ 'type': 'select' }) ]
+policyItem1.rowFilterInfo = RangerPolicyItemRowFilterInfo({ 'filterExpr': 'country_code = "US"' })
+
+row_filter_policy.rowFilterPolicyItems = [ policyItem1 ]
 
-log = logging.getLogger(__name__)
+create_row_filter_policy = ranger.create_policy(row_filter_policy)
 
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description='Parameters required for connection to Ranger Admin!')
+print('    created row-filtering policy: id: ' + str(create_row_filter_policy.id) + ', name: ' + create_row_filter_policy.name)
 
-    parser.add_argument('--url', default='http://localhost:6080')
-    parser.add_argument('--username')
-    parser.add_argument('--password')
 
-    args = parser.parse_args()
+print('Retrieving policy: id=' + str(policy_id))
 
-    service_def_name = "sampleServiceDef"
-    service_name     = "sampleService"
-    policy_name      = "samplePolicy"
-    role_name        = "sampleRole"
+retrieved_policy = ranger.get_policy_by_id(policy_id)
 
-    ranger_client = RangerClient(args.url, args.username, args.password)
+print('    retrieved policy: id: ' + str(retrieved_policy.id) + ', name: ' + retrieved_policy.name)
 
 
-    # create a new service definition
-    config       = RangerServiceConfigDef(itemId=1, name='sampleConfig', type='string')
-    access_type  = RangerAccessTypeDef(itemId=1, name='sampleAccess')
-    resource_def = RangerResourceDef(itemId=1, name='root', type='string')
-    service_def  = RangerServiceDef(name=service_def_name, configs=[config], accessTypes=[access_type],
-                                    resources=[resource_def])
+print('Retrieving policy: service_name=' + service_name + ', policy_name=' + data_mask_policy.name)
 
-    created_service_def = ranger_client.create_service_def(service_def)
+retrieved_policy = ranger.get_policy(service_name, data_mask_policy.name)
 
-    log.info('New Service Definition created successfully {}'.format(created_service_def))
+print('    retrieved policy: id: ' + str(retrieved_policy.id) + ', name: ' + retrieved_policy.name)
 
 
-    # create a new service
-    service = RangerService(name=service_name, type=service_def_name)
+print('Retrieving policy: service_name=' + service_name + ', policy_name=' + row_filter_policy.name)
 
-    created_service = ranger_client.create_service(service)
+retrieved_policy = ranger.get_policy(service_name, row_filter_policy.name)
 
-    log.info('New Service created successfully {}'.format(created_service))
+print('    retrieved policy: id: ' + str(retrieved_policy.id) + ', name: ' + retrieved_policy.name)
 
 
-    # create a new policy
-    resource = RangerPolicyResource(['/path/to/sample/resource'], False, False)
-    policy   = RangerPolicy(service=service_name, name=policy_name, resources={'root': resource})
+print('Retrieving policies in service ' + created_policy.service + '..')
 
-    created_policy = ranger_client.create_policy(policy)
+policies = ranger.get_policies_in_service(created_policy.service)
 
-    log.info('New Ranger Policy created successfully {}'.format(created_policy))
+print('    ' + str(len(policies)) + ' policies found')
+for plcy in policies:
+    print('        id: ' + str(plcy.id) + ', service: ' + plcy.service + ', name: ' + plcy.name)
 
 
-    # update an existing policy
-    policy = RangerPolicy(service=service_name, name=policy_name, description='Policy Updated!')
+print('Updating policy: id=' + str(policy_id))
 
-    updated_policy = ranger_client.update_policy(service_name, policy_name, policy)
+saved_value                = created_policy.description
+created_policy.description = 'updated description - #1'
 
-    log.info('Ranger Policy updated successfully {}'.format(updated_policy))
+updated_policy1 = ranger.update_policy_by_id(policy_id, created_policy)
 
+print('    updated policy: id: ' + str(updated_policy1.id) + ', description: ' + saved_value + ', updatedDescription: ' + updated_policy1.description)
 
-    # get a policy by name
-    fetched_policy = ranger_client.get_policy(service_name, policy_name)
 
-    log.info('Policy {} fetched {}'.format(policy_name, fetched_policy))
+print('Updating policy: service_name=' + service_name + ', policy_name=' + policy_name)
 
+saved_value                 = updated_policy1.description
+updated_policy1.description = 'updated description - #2'
 
-    # get all policies
-    all_policies = ranger_client.find_policies({})
+updated_policy2 = ranger.update_policy(service_name, policy_name, updated_policy1)
 
-    for id, policy in enumerate(all_policies):
-        log.info('Policy #{}: {}'.format(id, RangerPolicy(**policy)))
+print('    updated policy: id: ' + str(updated_policy2.id) + ', description: ' + saved_value + ', updatedDescription: ' + updated_policy2.description)
 
 
-    # delete a policy by name
-    ranger_client.delete_policy(service_name, policy_name)
+print('Deleting policy: id=' + str(policy_id))
 
-    log.info('Policy {} successfully deleted'.format(policy_name))
+ranger.delete_policy_by_id(policy_id)
 
+print('    deleted policy: id: ' + str(policy_id) + ', name: ' + updated_policy2.name)
 
-    # create a role in ranger
-    sample_role = RangerRole(name=role_name, description='Sample Role', users=[RoleMember(isAdmin=True)])
 
-    created_role = ranger_client.create_role(service_name, sample_role)
+print('Deleting policy: service_name=' + data_mask_policy.service + ', policy_name=' + data_mask_policy.name)
 
-    log.info('New Role successfully created {}'.format(created_role))
+ranger.delete_policy(data_mask_policy.service, data_mask_policy.name)
 
+print('    deleted policy: id: ' + str(data_mask_policy.id) + ', name: ' + data_mask_policy.name)
 
-    # update a role in ranger
-    sample_role = RangerRole(name=role_name, description='Updated Sample Role!')
 
-    updated_role = ranger_client.update_role(created_role.id, sample_role)
+print('Deleting policy: service_name=' + row_filter_policy.service + ', policy_name=' + row_filter_policy.name)
 
-    log.info('Role {} successfully updated {}'.format(role_name, updated_role))
+ranger.delete_policy(row_filter_policy.service, row_filter_policy.name)
 
+print('    deleted policy: id: ' + str(row_filter_policy.id) + ', name: ' + row_filter_policy.name)
 
-    # get all roles in ranger
-    all_roles = ranger_client.find_roles({})
+ranger.delete_service_by_id(service_id)
 
-    log.info('List of Roles {}'.format(all_roles)) if all_roles is not None else log.info('No roles found!')
 
+print('Listing policies..')
+policies = ranger.find_policies()
 
-    # delete a role in ranger
-    ranger_client.delete_role(role_name, ranger_client.username, service_name)
+print('    ' + str(len(policies)) + ' policies found')
+for policy in policies:
+    print('        id: ' + str(policy.id) + ', service: ' + policy.service + ', name: ' + policy.name)
 
-    log.info('Role {} successfully deleted'.format(role_name))
 
+print('Listing security zones..')
+security_zones = ranger.find_security_zones()
 
-    # delete a service
-    ranger_client.delete_service(service_name)
+print('    ' + str(len(security_zones)) + ' security zones found')
+for security_zone in security_zones:
+    print('        id: ' + str(security_zone.id) + ', name: ' + security_zone.name)
 
-    log.info('Service {} successfully deleted'.format(service_name))
 
+print('Listing roles..')
+roles = ranger.find_roles()
 
-    # delete a service definition
-    ranger_client.delete_service_def(service_def_name)
+print('    ' + str(len(roles)) + ' roles zones found')
+for role in roles:
+    print('        id: ' + str(role.id) + ', name: ' + role.name)
 
-    log.info('Service Definition {} successfully deleted'.format(service_def_name))