Skip to content

Commit 0ac59b1

Browse files
authored
Merge pull request #60 from dynata/feature-targeting-template
added targeting template APIs
2 parents f1d7ea2 + f0420cf commit 0ac59b1

13 files changed

+624
-0
lines changed

dynatademand/api.py

+52
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,23 @@ def _api_get(self, uri, query_params=None):
7272
return response.content
7373
return response.json()
7474

75+
def _api_delete(self, uri):
76+
# Send an authenticated DELETE request to an API endpoint.
77+
self._check_authentication()
78+
url = '{}{}'.format(self.base_url, uri)
79+
request_headers = {
80+
'Authorization': 'Bearer {}'.format(self._access_token),
81+
'Content-Type': "application/json",
82+
}
83+
response = requests.delete(url=url, headers=request_headers)
84+
if response.status_code > 399:
85+
raise DemandAPIError('Demand API request to {} failed with status {}. Response: {}'.format(
86+
url, response.status_code, response.content
87+
))
88+
if response.headers['content-type'] == 'application/pdf':
89+
return response.content
90+
return response.json()
91+
7592
def authenticate(self):
7693
# Sends the authentication data to the access token endpoint.
7794
url = '{}/token/password'.format(self.auth_base_url)
@@ -485,3 +502,38 @@ def reconcile_project(self, project_id, file, message):
485502
url, response.status_code, response.content
486503
))
487504
return response.json()
505+
506+
def create_template(self, template):
507+
# TODO: Waiting on a valid path and request body schema.
508+
# self.validator.validate_request(
509+
# 'create_template',
510+
# request_body=template,
511+
# )
512+
return self._api_post('/templates/quotaplan', template)
513+
514+
def update_template(self, id, template):
515+
# TODO: Waiting on a valid path and request body schema.
516+
# self.validator.validate_request(
517+
# 'update_template',
518+
# path_data={'id': '{}'.format(id)},
519+
# request_body=template,
520+
# )
521+
return self._api_post('/templates/quotaplan/{}'.format(id), template)
522+
523+
def delete_template(self, id):
524+
self.validator.validate_request(
525+
'delete_template',
526+
path_data={'id': '{}'.format(id)},
527+
)
528+
return self._api_delete('/templates/quotaplan/{}'.format(id))
529+
530+
def get_templates(self, country, lang, **kwargs):
531+
self.validator.validate_request(
532+
'get_templates',
533+
path_data={
534+
'countryCode': '{}'.format(country),
535+
'languageCode': '{}'.format(lang)
536+
},
537+
query_params=kwargs,
538+
)
539+
return self._api_get('/templates/quotaplan/{}/{}'.format(country, lang), kwargs)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
{
2+
"type": "object",
3+
"title": "New Template",
4+
"properties": {
5+
"name": {
6+
"type": "string",
7+
"description": "Name of the template"
8+
},
9+
"description": {
10+
"type": "string",
11+
"description": "template description"
12+
},
13+
"countryISOCode": {
14+
"type": "string",
15+
"description": "2 letter ISO Country Code",
16+
"minLength": 2,
17+
"maxLength": 2
18+
},
19+
"languageISOCode": {
20+
"type": "string",
21+
"description": "2 letter ISO Language Code",
22+
"minLength": 2,
23+
"maxLength": 2
24+
},
25+
"tags": {
26+
"type": "array",
27+
"description": "keyword tags"
28+
},
29+
"quotaPlan": {
30+
"type": "object",
31+
"title": "Quota Plan",
32+
"description": "Defines the type of respondents you want to invite for the survey",
33+
"properties": {
34+
"filters": {
35+
"type": "array",
36+
"description": "Filters are minimum set of targeting that every respondent must have in order to qualify for the study. Only attributes that have `isAllowedInFilters = true` is allowed to be used in `filters`",
37+
"items": {
38+
"type": "object",
39+
"properties": {
40+
"attributeId": {
41+
"type": "string",
42+
"description": "The attribute you want to target respondents on"
43+
},
44+
"options": {
45+
"type": "array",
46+
"description": "The options of the attribute you want to target respondents on",
47+
"uniqueItems": true,
48+
"items": {
49+
"type": "string"
50+
}
51+
},
52+
"operator": {
53+
"type": "string",
54+
"enum": [
55+
"exclude",
56+
"include"
57+
],
58+
"default": "include",
59+
"description": "The operator to use for the attribute options."
60+
}
61+
}
62+
}
63+
},
64+
"quotaGroups": {
65+
"type": "array",
66+
"description": "Quota groups define the allocated targeting attributes for panelists within this line item. Only attributes that have `isAllowedInQuotas = true` is allowed in `quotaGroups`.",
67+
"items": {
68+
"type": "object",
69+
"properties": {
70+
"name": {
71+
"type": "string",
72+
"description": "A quota group name of your choosing"
73+
},
74+
"quotaCells": {
75+
"type": "array",
76+
"description": "Quota Cells define the percentage allocation for the required targeting. A quota cell is made up of a collection of quota Nodes",
77+
"items": {
78+
"type": "object",
79+
"properties": {
80+
"quotaNodes": {
81+
"type": "array",
82+
"description": "Quota Nodes define the collection of attributes and options being targeted.",
83+
"items": {
84+
"type": "object",
85+
"properties": {
86+
"attributeId": {
87+
"type": "string",
88+
"description": "The attribute you want to target respondents on"
89+
},
90+
"options": {
91+
"type": "array",
92+
"description": "The options of the attribute you want to target respondents on",
93+
"uniqueItems": true,
94+
"items": {
95+
"type": "string"
96+
}
97+
},
98+
"operator": {
99+
"type": "string",
100+
"enum": [
101+
"exclude",
102+
"include"
103+
],
104+
"default": "include",
105+
"description": "**Deprecated field** The operator to use for the attribute options."
106+
}
107+
}
108+
}
109+
},
110+
"count": {
111+
"type": "integer",
112+
"description": "The count of respondents you want to qualify for the defined quota cell"
113+
}
114+
}
115+
}
116+
}
117+
}
118+
}
119+
}
120+
}
121+
}
122+
},
123+
"required": [
124+
"name",
125+
"countryISOCode",
126+
"languageISOCode",
127+
"description",
128+
"quotaPlan"
129+
]
130+
}
131+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
{
2+
"type": "object",
3+
"title": "New Template",
4+
"properties": {
5+
"name": {
6+
"type": "string",
7+
"description": "Name of the template"
8+
},
9+
"description": {
10+
"type": "string",
11+
"description": "template description"
12+
},
13+
"countryISOCode": {
14+
"type": "string",
15+
"description": "2 letter ISO Country Code",
16+
"minLength": 2,
17+
"maxLength": 2
18+
},
19+
"languageISOCode": {
20+
"type": "string",
21+
"description": "2 letter ISO Language Code",
22+
"minLength": 2,
23+
"maxLength": 2
24+
},
25+
"tags": {
26+
"type": "array",
27+
"description": "keyword tags"
28+
},
29+
"quotaPlan": {
30+
"type": "object",
31+
"title": "Quota Plan",
32+
"description": "Defines the type of respondents you want to invite for the survey",
33+
"properties": {
34+
"filters": {
35+
"type": "array",
36+
"description": "Filters are minimum set of targeting that every respondent must have in order to qualify for the study. Only attributes that have `isAllowedInFilters = true` is allowed to be used in `filters`",
37+
"items": {
38+
"type": "object",
39+
"properties": {
40+
"attributeId": {
41+
"type": "string",
42+
"description": "The attribute you want to target respondents on"
43+
},
44+
"options": {
45+
"type": "array",
46+
"description": "The options of the attribute you want to target respondents on",
47+
"uniqueItems": true,
48+
"items": {
49+
"type": "string"
50+
}
51+
},
52+
"operator": {
53+
"type": "string",
54+
"enum": [
55+
"exclude",
56+
"include"
57+
],
58+
"default": "include",
59+
"description": "The operator to use for the attribute options."
60+
}
61+
}
62+
}
63+
},
64+
"quotaGroups": {
65+
"type": "array",
66+
"description": "Quota groups define the allocated targeting attributes for panelists within this line item. Only attributes that have `isAllowedInQuotas = true` is allowed in `quotaGroups`.",
67+
"items": {
68+
"type": "object",
69+
"properties": {
70+
"name": {
71+
"type": "string",
72+
"description": "A quota group name of your choosing"
73+
},
74+
"quotaCells": {
75+
"type": "array",
76+
"description": "Quota Cells define the percentage allocation for the required targeting. A quota cell is made up of a collection of quota Nodes",
77+
"items": {
78+
"type": "object",
79+
"properties": {
80+
"quotaNodes": {
81+
"type": "array",
82+
"description": "Quota Nodes define the collection of attributes and options being targeted.",
83+
"items": {
84+
"type": "object",
85+
"properties": {
86+
"attributeId": {
87+
"type": "string",
88+
"description": "The attribute you want to target respondents on"
89+
},
90+
"options": {
91+
"type": "array",
92+
"description": "The options of the attribute you want to target respondents on",
93+
"uniqueItems": true,
94+
"items": {
95+
"type": "string"
96+
}
97+
},
98+
"operator": {
99+
"type": "string",
100+
"enum": [
101+
"exclude",
102+
"include"
103+
],
104+
"default": "include",
105+
"description": "**Deprecated field** The operator to use for the attribute options."
106+
}
107+
}
108+
}
109+
},
110+
"count": {
111+
"type": "integer",
112+
"description": "The count of respondents you want to qualify for the defined quota cell"
113+
}
114+
}
115+
}
116+
}
117+
}
118+
}
119+
}
120+
}
121+
}
122+
},
123+
"required": [
124+
"name",
125+
"countryISOCode",
126+
"languageISOCode",
127+
"description",
128+
"quotaPlan"
129+
]
130+
}
131+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"name": {
5+
"type": "string",
6+
"required": true
7+
}
8+
},
9+
"required": [
10+
"name"
11+
]
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"id": {
5+
"type": "integer",
6+
"required": true
7+
}
8+
},
9+
"required": [
10+
"id"
11+
]
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"countryCode": {
5+
"type": "string",
6+
"required": true
7+
},
8+
"languageCode": {
9+
"type": "string",
10+
"required": true
11+
}
12+
},
13+
"required": [
14+
"countryCode",
15+
"languageCode"
16+
]
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"name": {
5+
"type": "string",
6+
"required": true
7+
}
8+
},
9+
"required": [
10+
"name"
11+
]
12+
}

0 commit comments

Comments
 (0)