99
1010API_URL_V1 = "https://engage.newmode.net/api/"
1111API_URL_V2 = "https://base.newmode.net/api/"
12- API_AUTH_URL = 'https://base.newmode.net/oauth/token'
12+ API_AUTH_URL = "https://base.newmode.net/oauth/token"
13+
1314
1415class Newmode (object ):
1516 """
@@ -27,7 +28,14 @@ class Newmode(object):
2728 NewMode Class
2829 """
2930
30- def __init__ (self , api_user = None , api_password = None , client_id = None , client_secret = None , api_version = "v1.0" ):
31+ def __init__ (
32+ self ,
33+ api_user = None ,
34+ api_password = None ,
35+ client_id = None ,
36+ client_secret = None ,
37+ api_version = "v1.0" ,
38+ ):
3139 self .api_version = check_env .check ("NEWMODE_API_VERSION" , api_version )
3240
3341 if "v1" in self .api_version :
@@ -41,11 +49,14 @@ def __init__(self, api_user=None, api_password=None, client_id=None, client_secr
4149 self .client = APIConnector (
4250 self .base_url ,
4351 auth = (self .api_user , self .api_password ),
44- headers = self .headers ,)
52+ headers = self .headers ,
53+ )
4554 else :
4655 self .base_url = API_URL_V2
4756 self .client_id = check_env .check ("NEWMODE_API_CLIENT_ID" , client_id )
48- self .__client_secret = check_env .check ("NEWMODE_API_CLIENT_SECRET" , client_secret )
57+ self .__client_secret = check_env .check (
58+ "NEWMODE_API_CLIENT_SECRET" , client_secret
59+ )
4960 self .headers = {"content-type" : "application/x-www-form-urlencoded" }
5061 self .client = OAuth2APIConnector (
5162 uri = self .base_url ,
@@ -54,7 +65,8 @@ def __init__(self, api_user=None, api_password=None, client_id=None, client_secr
5465 client_secret = self .__client_secret ,
5566 headers = self .headers ,
5667 token_url = API_AUTH_URL ,
57- grant_type = "client_credentials" ,)
68+ grant_type = "client_credentials" ,
69+ )
5870
5971 def convert_to_table (self , data ):
6072 """Internal method to create a Parsons table from a data element."""
@@ -67,7 +79,9 @@ def convert_to_table(self, data):
6779
6880 return table
6981
70- def base_request (self , method , url , requires_csrf = True , params = {}):
82+ def base_request (
83+ self , method , url , requires_csrf = True , data = None , json = None , params = {}
84+ ):
7185
7286 if requires_csrf :
7387 csrf = self .get_csrf_token ()
@@ -76,11 +90,10 @@ def base_request(self, method, url, requires_csrf=True, params={}):
7690 response = None
7791 if method == "GET" :
7892 response = self .client .get_request (url = url , params = params )
79- # if "targets" in url:
80- # response = self.client.get_request(url=url, params=params)['_embedded']['hal:tool']
8193 elif method == "PATCH" :
8294 response = self .client .patch_request (url = url , params = params )
83- # response.get("_embedded", {}).get(f"osdi:{object_name}")
95+ elif method == "POST" :
96+ response = self .client .post_request (url = url , params = params , json = json )
8497 return response
8598
8699 def converted_request (
@@ -89,20 +102,27 @@ def converted_request(
89102 method ,
90103 requires_csrf = True ,
91104 supports_version = True ,
105+ data = None ,
106+ json = None ,
92107 params = {},
93108 convert_to_table = True ,
94109 ):
95110 url = f"{ self .api_version } /{ endpoint } " if supports_version else endpoint
96111 response = self .base_request (
97- method = method , url = url , requires_csrf = requires_csrf , params = params
112+ method = method ,
113+ url = url ,
114+ requires_csrf = requires_csrf ,
115+ json = json ,
116+ data = data ,
117+ params = params ,
98118 )
99119 if not response :
100120 logging .warning (f"Empty result returned from endpoint: { endpoint } " )
101121 if convert_to_table :
102122 return self .convert_to_table (response )
103123 else :
104124 return response
105-
125+
106126 def get_csrf_token (self , max_retries = 10 ):
107127 """
108128 Retrieve a CSRF token for making API requests
@@ -223,7 +243,7 @@ def run_action(self, tool_id, payload, params={}):
223243 endpoint = f"action/{ tool_id } " , method = "PATCH" , payload = payload , params = params
224244 )
225245 return response
226-
246+
227247 def get_campaigns (self , params = {}):
228248 """
229249 V1 & V2
@@ -237,11 +257,13 @@ def get_campaigns(self, params={}):
237257 """
238258 if "v1" in self .api_version :
239259 endpoint = "campaign"
260+ requires_csrf = True
240261 else :
241262 self .api_version = "jsonapi"
242263 endpoint = "action/action"
264+ requires_csrf = False
243265 response = self .converted_request (
244- endpoint = endpoint , method = "GET" , params = params
266+ endpoint = endpoint , method = "GET" , params = params , requires_csrf = requires_csrf
245267 )
246268 return response
247269
@@ -259,10 +281,14 @@ def get_campaign(self, campaign_id, params={}):
259281 `Returns:`
260282 Parsons Table containing campaign data.
261283 """
262- endpoint = f"campaign/{ campaign_id } " if "v1" in self .api_version else f"/campaign/{ campaign_id } /form"
263-
284+ if "v1" in self .api_version :
285+ endpoint = f"campaign/{ campaign_id } "
286+ requires_csrf = True
287+ else :
288+ endpoint = f"/campaign/{ campaign_id } /form"
289+ requires_csrf = False
264290 response = self .converted_request (
265- endpoint = endpoint , method = "GET" , params = params
291+ endpoint = endpoint , method = "GET" , params = params , requires_csrf = requires_csrf
266292 )
267293 return response
268294
@@ -395,29 +421,65 @@ def get_outreach(self, outreach_id, params={}):
395421 )
396422 return response
397423
398- def get_recipient (self , campaign_id , params = {}):
424+ def get_recipient (
425+ self ,
426+ campaign_id ,
427+ street_address = None ,
428+ city = None ,
429+ postal_code = None ,
430+ region = None ,
431+ params = {},
432+ ):
399433 """
400434 V2 only
401435 Retrieve a specific recipient by ID
402436 `Args:`
403437 campaign_id: str
404438 The ID of the campaign to retrieve.
439+ street_address: str
440+ Street address of recipient
441+ city: str
442+ City of recipient
443+ postal_code: str
444+ Postal code of recipient
445+ region: str
446+ Region (i.e. state/province abbreviation) of recipient
405447 params: dict
406448 Query parameters to include in the request.
407449 `Returns:`
408450 Parsons Table containing recipient data.
409451 """
452+ address_params = {
453+ "street_address" : street_address ,
454+ "city" : city ,
455+ "postal_code" : postal_code ,
456+ "region" : region ,
457+ }
458+ if all (x is None for x in address_params .values ()):
459+ logger .error (
460+ "Please specify a street address, city, postal code, and/or region."
461+ )
462+ raise Exception ("Incomplete Request" )
463+
464+ params = {
465+ f"address[value][{ key } ]" : value
466+ for key , value in address_params .items ()
467+ if value
468+ }
410469 response = self .converted_request (
411- endpoint = f"campaign/{ campaign_id } /target" , method = "GET" , params = params
470+ endpoint = f"campaign/{ campaign_id } /target" ,
471+ method = "GET" ,
472+ params = params ,
473+ requires_csrf = False ,
412474 )
413475 return response
414476
415- def run_submit (self , campaign_id , params = {}):
477+ def run_submit (self , campaign_id , json = None , data = None , params = {}):
416478 """
417479 V2 only
418480 Pass a submission from a supporter to a campaign
419- that ultimately fills in a petition,
420- sends an email or triggers a phone call
481+ that ultimately fills in a petition,
482+ sends an email or triggers a phone call
421483 depending on your campaign type
422484
423485 `Args:`
@@ -429,26 +491,30 @@ def run_submit(self, campaign_id, params={}):
429491 Parsons Table containing submit data.
430492 """
431493 response = self .converted_request (
432- endpoint = f"campaign/{ campaign_id } /submit " , method = "POST" , params = params
494+ endpoint = f"campaign/{ campaign_id } /submit" ,
495+ method = "POST" ,
496+ data = data ,
497+ json = json ,
498+ params = params ,
499+ requires_csrf = False ,
500+ convert_to_table = False ,
433501 )
434502 return response
435503
436504 def get_submissions (self , params = {}):
437505 """
438506 V2 only
439- Retrieve and sort submission and contact data
440- for your organization using a range of filters
507+ Retrieve and sort submission and contact data
508+ for your organization using a range of filters
441509 that include campaign id, data range and submission status
442510
443511 `Args:`
444- campaign_id: str
445- The ID of the campaign to retrieve.
446512 params: dict
447513 Query parameters to include in the request.
448514 `Returns:`
449515 Parsons Table containing submit data.
450516 """
451517 response = self .converted_request (
452- endpoint = "submission" , method = "POST " , params = params
518+ endpoint = "submission" , method = "GET " , params = params , requires_csrf = False
453519 )
454- return response
520+ return response
0 commit comments