Python client¶
apache-ranger is the official Python package for Apache Ranger. It wraps the Ranger Admin REST API (service
definitions, services, policies, roles, security zones, tags), user and group management, Ranger KMS,
Governed Data Sharing and the PDP authorization API in a handful of client classes built on
requests. Model classes are thin dict subclasses, so you can construct them from JSON, read attributes
as properties, and pass them straight back to the API.
Use it for automation scripts, tests and integrations in Python; the source lives in
intg/src/main/python and is published to PyPI.
Installation¶
pip install apache-ranger
pip install requests-kerberos # only for Kerberos/SPNEGO authentication
python -m pip show apache-ranger
- Package version on master:
0.0.13(intg/src/main/python/setup.py) - Python: 3.13 or later
- Dependencies:
requests,strenum; optionalrequests-kerberos
To use the sources from a checkout without installing: PYTHONPATH=intg/src/main/python python your_script.py.
Clients¶
| Class | Module | Talks to | Base path |
|---|---|---|---|
RangerClient |
apache_ranger.client.ranger_client |
Ranger Admin | service/public/v2/api |
RangerUserMgmtClient |
apache_ranger.client.ranger_user_mgmt_client |
Ranger Admin (wraps a RangerClient) |
service/xusers |
RangerGdsClient |
apache_ranger.client.ranger_gds_client |
Ranger Admin (wraps a RangerClient) |
service/gds |
RangerKMSClient |
apache_ranger.client.ranger_kms_client |
Ranger KMS | kms/v1 |
RangerPDPClient |
apache_ranger.client.ranger_pdp_client |
Ranger PDP | authz/v1 |
Authentication¶
RangerClient(url, auth, query_params=None, headers=None) creates a requests.Session and assigns auth
to it, so any requests authentication object works. headers and query_params are added to every call.
from apache_ranger.client.ranger_client import RangerClient, HadoopSimpleAuth
# basic authentication
ranger = RangerClient("http://localhost:6080", ("admin", "rangerR0cks!"))
# Kerberos / SPNEGO (pip install requests-kerberos; needs a ticket in the cache)
from requests_kerberos import HTTPKerberosAuth
ranger = RangerClient("https://ranger.example.com:6182", HTTPKerberosAuth())
# JWT bearer token or trusted header
ranger = RangerClient("https://ranger.example.com:6182", None, headers={"Authorization": "Bearer " + token})
# Hadoop "simple" auth for Ranger KMS (adds ?user.name=<user>)
from apache_ranger.client.ranger_kms_client import RangerKMSClient
kms = RangerKMSClient("http://localhost:9292", HadoopSimpleAuth("keyadmin"))
TLS verification is controlled through the underlying session:
ranger.session.verify = "/etc/ranger/ca-bundle.pem" # CA bundle; False disables verification (testing only)
Ranger Admin: RangerClient¶
from apache_ranger.client.ranger_client import RangerClient
from apache_ranger.model.ranger_service import RangerService
from apache_ranger.model.ranger_policy import RangerPolicy, RangerPolicyResource, RangerPolicyItem, RangerPolicyItemAccess
ranger = RangerClient("http://localhost:6080", ("admin", "rangerR0cks!"))
# service
service = RangerService({"name": "dev_hive", "type": "hive",
"configs": {"username": "hive", "password": "hive",
"jdbc.driverClassName": "org.apache.hive.jdbc.HiveDriver",
"jdbc.url": "jdbc:hive2://ranger-hadoop:10000"}})
created = ranger.create_service(service)
print("service id", created.id)
# access policy: analysts may select sales.orders
policy = RangerPolicy()
policy.service = "dev_hive"
policy.name = "sales-readers"
policy.resources = {"database": RangerPolicyResource({"values": ["sales"]}),
"table": RangerPolicyResource({"values": ["orders"]}),
"column": RangerPolicyResource({"values": ["*"]})}
policy.policyItems = [RangerPolicyItem({"groups": ["analysts"],
"accesses": [RangerPolicyItemAccess({"type": "select"})]})]
created_policy = ranger.create_policy(policy)
# read, search, delete
p = ranger.get_policy("dev_hive", "sales-readers")
for p in ranger.find_policies({"serviceName": "dev_hive"}).list:
print(p.id, p.name)
ranger.delete_policy("dev_hive", "sales-readers")
ranger.delete_service("dev_hive")
Masking and row-filter policies use policy.policyType = RangerPolicy.POLICY_TYPE_DATAMASK (1) with
dataMaskPolicyItems (RangerDataMaskPolicyItem, dataMaskInfo.dataMaskType, e.g. MASK_SHOW_LAST_4) or
RangerPolicy.POLICY_TYPE_ROWFILTER (2) with rowFilterPolicyItems (rowFilterInfo.filterExpr);
sample_client.py shows both.
Methods¶
- Service definitions
create_service_def,update_service_def_by_id,update_service_def,delete_service_def_by_id,delete_service_def,get_service_def_by_id,get_service_def,find_service_defs- Services
create_service,get_service_by_id,get_service,update_service_by_id,update_service,delete_service_by_id,delete_service,find_services- Policies
create_policy,apply_policy,get_policy_by_id,get_policy,get_policy_by_name_zone,get_policies_in_service,update_policy_by_id,update_policy,update_policy_by_name_zone,delete_policy_by_id,delete_policy,delete_policy_by_name_zone,find_policies- Security zones
create_security_zone,update_security_zone_by_id,delete_security_zone_by_id,delete_security_zone,get_security_zone_by_id,get_security_zone,get_security_zone_headers,get_security_zone_service_headers,get_zone_names_for_resource,find_security_zones- Security zones v2
create_security_zone_v2,update_security_zone_v2,partial_update_security_zone_v2(RangerSecurityZoneChangeRequest),get_security_zone_v2,get_security_zone_v2_by_id,zone_v2_get_resources,zone_v2_by_id_get_resources,find_security_zones_v2- Roles
create_role,update_role,delete_role_by_id,delete_role,get_role_by_id,get_role,get_all_role_names,get_user_roles,find_roles,grant_role,revoke_role- Tags, admin
import_service_tags,get_service_tags,delete_policy_deltas,purge_records,set_log_level
find_* methods take a filter dict of query parameters and return a PList with list, totalCount,
startIndex, pageSize and resultSize.
Users and groups: RangerUserMgmtClient¶
from apache_ranger.client.ranger_user_mgmt_client import RangerUserMgmtClient
from apache_ranger.model.ranger_user_mgmt import RangerUser, RangerGroup, RangerGroupUser
user_mgmt = RangerUserMgmtClient(ranger)
user = user_mgmt.create_user(RangerUser({"name": "alice", "password": "Alice123!", "firstName": "Alice",
"userRoleList": ["ROLE_USER"]}))
group = user_mgmt.create_group(RangerGroup({"name": "analysts"}))
user_mgmt.create_group_user(RangerGroupUser({"name": group.name, "parentGroupId": group.id, "userId": user.id}))
print([u.name for u in user_mgmt.find_users().list])
user_mgmt.delete_user_by_id(user.id, is_force_delete=True)
Methods: create_user, update_user_by_id, delete_user_by_id, get_user_by_id, get_user,
get_groups_for_user, find_users; create_group, update_group_by_id, delete_group_by_id,
get_group_by_id, get_group, get_users_in_group, find_groups; create_group_user,
update_group_user, delete_group_user_by_id, find_group_users, get_group_users_for_group.
Ranger KMS: RangerKMSClient¶
from apache_ranger.client.ranger_kms_client import RangerKMSClient
from apache_ranger.model.ranger_kms import RangerKey
kms = RangerKMSClient("http://localhost:9292", HadoopSimpleAuth("keyadmin"))
print(kms.kms_status())
key = kms.create_key(RangerKey({"name": "key1", "length": 128, "cipher": "AES/CTR/NoPadding"}))
eeks = kms.generate_encrypted_key("key1", 2)
Methods: create_key, rollover_key, invalidate_cache_for_key, delete_key, get_key, get_key_metadata,
get_keys_metadata, get_current_key, get_key_version, get_key_versions, get_key_names,
generate_encrypted_key, decrypt_encrypted_key, reencrypt_encrypted_key, batch_reencrypt_encrypted_keys,
kms_status. See Ranger KMS.
Governed Data Sharing: RangerGdsClient¶
from apache_ranger.client.ranger_gds_client import RangerGdsClient
gds = RangerGdsClient(ranger)
for ds in gds.find_datasets().list:
print(ds.id, ds.name)
Methods cover datasets (create_dataset, update_dataset, delete_dataset, get_dataset, find_datasets,
get_dataset_names, get_dataset_summary, dataset policies add_dataset_policy, update_dataset_policy,
delete_dataset_policy, get_dataset_policy, get_dataset_policies), projects (create_project, ...,
add_project_policy, ...), data shares (create_data_share, ..., find_data_shares), shared resources
(add_shared_resource, update_shared_resource, remove_shared_resource, get_shared_resource,
find_shared_resources), and the links add_data_share_in_dataset / add_dataset_in_project with their
update_*, remove_*, get_*, find_* variants. Concepts are explained in
Governed Data Sharing.
Authorization: RangerPDPClient¶
RangerPDPClient(url, auth, query_params=None, headers=None) calls the Ranger PDP server:
from apache_ranger.client.ranger_pdp_client import RangerPDPClient
from apache_ranger.model.ranger_authz import (RangerAccessContext, RangerAccessInfo, RangerAuthzRequest,
RangerResourceInfo, RangerUserInfo)
pdp = RangerPDPClient("http://localhost:6500", auth=None, headers={"X-Forwarded-User": "hive"})
request = RangerAuthzRequest({
"requestId": "req-1",
"user": RangerUserInfo({"name": "alice"}),
"access": RangerAccessInfo({"resource": RangerResourceInfo({"name": "table:sales/orders"}),
"action": "QUERY", "permissions": ["select"]}),
"context": RangerAccessContext({"serviceType": "hive", "serviceName": "dev_hive"}),
})
result = pdp.authorize(request)
print(result.decision) # ALLOW / DENY / NOT_DETERMINED
perm = result.permissions["select"]
if perm.get("rowFilter"):
print("row filter:", perm["rowFilter"]["filterExpr"])
| Method | Endpoint |
|---|---|
authorize(request) |
POST /authz/v1/authorize |
authorize_multi(request) |
POST /authz/v1/authorizeMulti |
get_resource_permissions(request) |
POST /authz/v1/permissions |
filter_resources(request) |
POST /authz/v1/filterResources |
Requests must include context.serviceType, context.serviceName and user.name. If the authenticated
caller differs from user.name, the caller must be allowed to delegate for that service, otherwise the PDP
returns 403 FORBIDDEN. Request and response fields are described in
Authorization API and PDP.
Errors and return values¶
- Unexpected HTTP status codes raise
apache_ranger.exceptions.RangerServiceException, whose message includes the API, status and response body. 404 Not Found,204 No Content,304 Not Modifiedand503 Service UnavailablereturnNone(404and503are logged as errors).- Models are dicts:
policy["name"]andpolicy.nameare equivalent, andjson.dumps(policy)works.
Samples and tests¶
Runnable samples live in ranger-examples/sample-client/src/main/python/ and are shipped in the
ranger-<version>-sample-client.tar.gz archive. Edit ranger_url / ranger_auth at the top of a script, then:
python ranger-examples/sample-client/src/main/python/sample_client.py
| Script | Demonstrates |
|---|---|
sample_client.py |
Service defs, services, access/mask/row-filter policies, roles, service tags |
user_mgmt.py |
Users, groups, group membership |
sample_kms_client.py |
Key lifecycle, EEK generate/decrypt/reencrypt |
sample_gds_client.py |
Datasets, projects, data shares, shared resources, GDS policies |
sample_pdp_client.py |
authorize, authorize_multi, get_resource_permissions |
security_zone_v2.py |
Zone v2 create, get, partial update, delete |
Unit tests for the client (mocked HTTP) run from intg/:
PYTHONPATH=src/main/python python -B src/test/python/test_ranger_client.py
Troubleshooting¶
| Symptom | Cause / fix |
|---|---|
ModuleNotFoundError: requests_kerberos |
pip install requests-kerberos. |
401 Unauthorized |
Wrong credentials, no Kerberos ticket, or missing auth header for the target service. |
403 Forbidden |
The user lacks the Ranger role/permission, or (PDP) delegation is not allowed for that service. |
| SSL certificate errors | Set ranger.session.verify to a CA bundle; never disable verification in production. |
| Connection timeouts | Check the URL and network path to Admin (6080/6182), KMS (9292) or PDP. |
Further reading¶
- Client libraries overview, Java client
- REST API
- Source and README:
intg/src/main/python