Skip to content

Commit 532bc6e

Browse files
Merge pull request #304 from plivo/feature/phone-number-compliance
Feature/phone number compliance
2 parents a0cd323 + 4a507c8 commit 532bc6e

7 files changed

Lines changed: 611 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
# Change Log
2+
## [4.60.0](https://github.com/plivo/plivo-python/tree/v4.60.0) (2026-04-08)
3+
**Feature - PhoneNumber Compliance API support**
4+
- Added `phone_number_compliance_requirements` resource for discovering compliance requirements by country, number type, and user type
5+
- Added `phone_number_compliance` resource with full CRUD support (create, get, list, update, delete) for compliance applications
6+
- Added `phone_number_compliance_link` resource for bulk linking phone numbers to accepted compliance applications
7+
- Create and update operations support multipart file uploads for compliance documents
8+
29
## [4.59.6](https://github.com/plivo/plivo-python/tree/v4.59.6) (2026-02-18)
310
**Feature - Campaign API optional fields support**
411
- Added `sample3`, `sample4`, `sample5` optional sample message fields to Campaign `create` and `update` methods

plivo/resources/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222
from .multipartycall import MultiPartyCalls, MultiPartyCall, MultiPartyCallParticipant
2323
from .verify import Sessions
2424
from .tollfree_verification import TollfreeVerifications
25+
from .phone_number_compliance import PhoneNumberComplianceRequirements, PhoneNumberComplianceApplications, PhoneNumberComplianceLink
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import json
2+
import os
3+
from plivo.base import PlivoResource, PlivoResourceInterface
4+
5+
6+
class PhoneNumberComplianceRequirement(PlivoResource):
7+
_name = 'PhoneNumberComplianceRequirement'
8+
_identifier_string = 'requirement_id'
9+
10+
11+
class PhoneNumberComplianceRequirements(PlivoResourceInterface):
12+
_resource_type = PhoneNumberComplianceRequirement
13+
14+
def get(self, country_iso=None, number_type=None, user_type=None):
15+
# GET /PhoneNumber/Compliance/Requirements
16+
return self.client.request(
17+
'GET',
18+
('PhoneNumber', 'Compliance', 'Requirements'),
19+
dict(country_iso=country_iso, number_type=number_type, user_type=user_type)
20+
)
21+
22+
23+
class PhoneNumberCompliance(PlivoResource):
24+
_name = 'PhoneNumberCompliance'
25+
_identifier_string = 'compliance_id'
26+
27+
28+
class PhoneNumberComplianceApplications(PlivoResourceInterface):
29+
_resource_type = PhoneNumberCompliance
30+
31+
def create(self, data=None, documents=None):
32+
"""
33+
data: dict with keys country_iso, number_type, alias, end_user, documents, callback_url, callback_method
34+
documents: list of local file paths for document uploads
35+
"""
36+
payload, files = _build_compliance_multipart(data, documents)
37+
return self.client.request(
38+
'POST',
39+
('PhoneNumber', 'Compliance'),
40+
payload,
41+
files=files
42+
)
43+
44+
def list(self, limit=None, offset=None, status=None, country_iso=None,
45+
number_type=None, user_type=None, alias=None, expand=None):
46+
params = {}
47+
if limit is not None:
48+
params['limit'] = limit
49+
if offset is not None:
50+
params['offset'] = offset
51+
if status:
52+
params['status'] = status
53+
if country_iso:
54+
params['country_iso'] = country_iso
55+
if number_type:
56+
params['number_type'] = number_type
57+
if user_type:
58+
params['user_type'] = user_type
59+
if alias:
60+
params['alias'] = alias
61+
if expand:
62+
params['expand'] = expand
63+
return self.client.request(
64+
'GET',
65+
('PhoneNumber', 'Compliance'),
66+
params
67+
)
68+
69+
def get(self, compliance_id, expand=None):
70+
params = {}
71+
if expand:
72+
params['expand'] = expand
73+
return self.client.request(
74+
'GET',
75+
('PhoneNumber', 'Compliance', compliance_id),
76+
params
77+
)
78+
79+
def update(self, compliance_id, data=None, documents=None):
80+
payload, files = _build_compliance_multipart(data, documents)
81+
return self.client.request(
82+
'PATCH',
83+
('PhoneNumber', 'Compliance', compliance_id),
84+
payload,
85+
files=files
86+
)
87+
88+
def delete(self, compliance_id):
89+
return self.client.request(
90+
'DELETE',
91+
('PhoneNumber', 'Compliance', compliance_id)
92+
)
93+
94+
95+
class PhoneNumberComplianceLink(PlivoResourceInterface):
96+
97+
def link(self, numbers=None):
98+
"""
99+
numbers: list of dicts, each with 'number' and 'compliance_application_id'
100+
"""
101+
return self.client.request(
102+
'POST',
103+
('PhoneNumber', 'Compliance', 'Link'),
104+
dict(numbers=numbers)
105+
)
106+
107+
108+
def _build_compliance_multipart(data, documents):
109+
payload = {}
110+
files = {}
111+
if data:
112+
payload['data'] = json.dumps(data)
113+
if documents:
114+
for idx, doc_path in enumerate(documents):
115+
field_name = 'documents[{}].file'.format(idx)
116+
files[field_name] = (os.path.basename(doc_path), open(doc_path, 'rb'))
117+
if not files:
118+
files = None
119+
return payload, files

plivo/rest/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from plivo.resources.queued_calls import QueuedCalls
2525
from plivo.resources.regulatory_compliance import EndUsers, ComplianceDocumentTypes, ComplianceDocuments, \
2626
ComplianceRequirements, ComplianceApplications
27+
from plivo.resources.phone_number_compliance import PhoneNumberComplianceRequirements, PhoneNumberComplianceApplications, PhoneNumberComplianceLink
2728
from plivo.utils import is_valid_mainaccount, is_valid_subaccount
2829
from plivo.version import __version__
2930
from requests import Request, Session
@@ -127,6 +128,9 @@ def __init__(self, auth_id=None, auth_token=None, proxies=None, timeout=5):
127128
self.verify_session = Sessions(self)
128129
self.verify_callerids = VerifyCallerids(self)
129130
self.transcriptions = Transcriptions(self)
131+
self.phone_number_compliance_requirements = PhoneNumberComplianceRequirements(self)
132+
self.phone_number_compliance = PhoneNumberComplianceApplications(self)
133+
self.phone_number_compliance_link = PhoneNumberComplianceLink(self)
130134

131135

132136
def __enter__(self):

plivo/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# -*- coding: utf-8 -*-
2-
__version__ = '4.59.5'
2+
__version__ = '4.60.0'

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
setup(
1212
name='plivo',
13-
version='4.59.6',
13+
version='4.60.0',
1414
description='A Python SDK to make voice calls & send SMS using Plivo and to generate Plivo XML',
1515
long_description=long_description,
1616
url='https://github.com/plivo/plivo-python',

0 commit comments

Comments
 (0)