Skip to content

Commit dbb4929

Browse files
author
Teun Zengerink
authored
Merge pull request #9 from usabilla/campaign-for-apps
Add support for Campaigns for Apps
2 parents 8701fdc + 8cb05b9 commit dbb4929

File tree

7 files changed

+80
-32
lines changed

7 files changed

+80
-32
lines changed

CHANGES.md

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ Changelog
33

44
Here you find a full list of changes.
55

6+
Version 1.3.0
7+
-------------
8+
9+
- Add support for Campaigns for Apps
10+
611
Version 1.2.3
712
-------------
813

LICENSE.MD

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2016 Usabilla
3+
Copyright (c) 2017 Usabilla
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.MD

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#Usabilla API - Python Client
1+
# Usabilla API - Python Client
22

33
[![Build Status](https://travis-ci.org/usabilla/api-python.svg?branch=master)](https://travis-ci.org/usabilla/api-python)
44
[![PyPI version](https://badge.fury.io/py/usabilla-api.svg)](https://badge.fury.io/py/usabilla-api)
@@ -7,7 +7,8 @@
77
The Usabilla Python client allows users to access data from their Usabilla accounts.
88
It makes use of the API to request the following products and resources:
99

10-
###Usabilla for Websites
10+
### Usabilla for Websites
11+
1112
- Buttons
1213
- Feedback items
1314
- Campaigns
@@ -16,13 +17,17 @@ It makes use of the API to request the following products and resources:
1617
- In-Page widgets
1718
- In-Page feedback
1819

19-
###Usabilla for Email
20-
- Buttons
21-
- Feedback items
20+
### Usabilla for Email
21+
22+
- Buttons
23+
- Feedback items
24+
25+
### Usabilla for Apps
2226

23-
###Usabilla for Apps
24-
- Apps
25-
- Feedback items
27+
- Apps
28+
- Feedback items
29+
- Campaigns
30+
- Campaign results
2631

2732
For more information on resources, authorization and available API calls, please visit out [documentation](https://usabilla.com/api).
2833

@@ -35,15 +40,15 @@ pip install usabilla-api
3540
```
3641

3742
## Examples
38-
The example folder contains an example of the client, which gives an idea how the client can be used and what is possible.
3943

44+
The example folder contains an example of the client, which gives an idea how the client can be used and what is possible.
4045

41-
###Iterators
46+
### Iterators
4247

4348
When working with the <code>limit</code> parameters (default value is **100**) you can request resources using the <code>item_iterator()</code> function.
4449
The API returns data in pages. This function returns a [Generator](https://wiki.python.org/moin/Generators) which
4550
traverses these pages for you and yields each result in the current page before retrieving the next page.
4651

47-
##Support
52+
## Support
4853

4954
The Usabilla Python Client API is maintained by Usabilla Development Team. Everyone is encouraged to file bug reports, feature requests, and pull requests through GitHub. This input is critical and will be carefully considered, but we can’t promise a specific resolution or time frame for any request. For more information please email our Support Team at [email protected]

example/examples_apps.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
# Set the limit of buttons to retrieve to 1
1212
if False:
13-
api.set_query_parameters({'limit': 1})
13+
api.set_query_parameters({'limit': 1})
1414

1515
# Set a limit for last 7 days
1616
if False:
@@ -25,5 +25,24 @@
2525
print first_form['name']
2626

2727
# Get the feedback of the first app form
28-
feedback = api.get_resource(api.SCOPE_LIVE, api.PRODUCT_APPS, api.RESOURCE_FEEDBACK, first_form['id'], iterate=True)
28+
feedback = api.get_resource(
29+
api.SCOPE_LIVE,
30+
api.PRODUCT_APPS,
31+
api.RESOURCE_FEEDBACK,
32+
first_form['id'],
33+
iterate=True)
2934
print len([item for item in feedback])
35+
36+
# Campaigns for apps
37+
app_campaigns = api.get_resource(
38+
api.SCOPE_LIVE,
39+
api.PRODUCT_APPS,
40+
api.RESOURCE_CAMPAIGN)
41+
first_campaign = app_campaigns['items'][0]
42+
responses = api.get_resource(
43+
api.SCOPE_LIVE,
44+
api.PRODUCT_APPS,
45+
api.RESOURCE_CAMPAIGN_RESULT,
46+
first_campaign['id'],
47+
iterate=True)
48+
print len([item for item in responses])

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
except ImportError:
44
from distutils.core import setup
55

6-
VERSION = '1.2.3'
6+
VERSION = '1.3.0'
77

88
setup(
99
name='usabilla-api',

tests.py

+26-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import sys
23
import unittest
34
import usabilla as ub
@@ -6,10 +7,9 @@
67
from unittest import TestCase, main as unittest_main
78

89

9-
import logging
10-
1110
logging.basicConfig(level=logging.DEBUG)
1211

12+
1313
class TestCredentials(TestCase):
1414

1515
def setUp(self):
@@ -66,18 +66,15 @@ def test_client_constants(self):
6666
self.assertEqual(self.client.host_protocol, 'https://')
6767
self.assertEqual('',self.client.query_parameters)
6868

69-
7069
def test_sign_key(self):
7170
signed_key = self.client.sign(self.secret_key.encode('utf-8'), 'usbl1_request'.encode('utf-8'))
7271
self.assertEqual(signed_key, b"&-\x88\x80Z9\xe8Pnvx\xe4S\xeeZ\x9fG\xc5\xf7g\x11|\xc1\xaa~q(\xef\xaf\x95\xc0\xac")
7372

74-
7573
def test_get_signature_key(self):
7674
datestamp = '20150115'
7775
signing_key = self.client.get_signature_key(self.secret_key, datestamp)
7876
self.assertEqual(signing_key, b"\x15\x8d\xd7U\xceG\xdeH\x8aHwU\xf5qg\xae\xd4Z\x19`\xedM\x80\x87\x97V\xbf\xe9pw\xaa\xae")
7977

80-
8178
def test_query_parameters(self):
8279
params = {'limit': 1}
8380
self.client.set_query_parameters(params)
@@ -88,12 +85,32 @@ def test_query_parameters(self):
8885

8986
def test_check_resource_validity(self):
9087
with self.assertRaises(ub.GeneralError):
91-
self.client.check_resource_validity('nonexisting', 'nonexisting', 'nonexisting')
88+
self.client.check_resource_validity(
89+
'nonexisting',
90+
'nonexisting',
91+
'nonexisting')
9292
with self.assertRaises(ub.GeneralError):
93-
self.client.check_resource_validity('live', 'nonexisting', 'nonexisting')
93+
self.client.check_resource_validity(
94+
'live',
95+
'nonexisting',
96+
'nonexisting')
9497
with self.assertRaises(ub.GeneralError):
95-
self.client.check_resource_validity('live', 'websites', 'nonexisting')
96-
self.assertEqual(self.client.check_resource_validity('live', 'websites', 'button'), '/live/websites/button')
98+
self.client.check_resource_validity(
99+
'live',
100+
'websites',
101+
'nonexisting')
102+
self.assertEqual(
103+
self.client.check_resource_validity('live', 'websites', 'button'),
104+
'/live/websites/button')
105+
self.assertEqual(
106+
self.client.check_resource_validity('live', 'apps', 'campaign'),
107+
'/live/apps/campaign')
108+
self.assertEqual(
109+
self.client.check_resource_validity(
110+
'live',
111+
'apps',
112+
'campaign_result'),
113+
'/live/apps/campaign/:id/results')
97114

98115
def test_handle_id(self):
99116
url = '/live/websites/button/:id/feedback'

usabilla.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2016 Usabilla.com
1+
# Copyright (c) 2017 Usabilla.com
22
#
33
# Permission is hereby granted, free of charge, to any person obtaining a
44
# copy of this software and associated documentation files (the
@@ -95,7 +95,9 @@ class APIClient(object):
9595
'apps': {
9696
'resources' : {
9797
'app': '',
98-
'feedback': '/:id/feedback'
98+
'feedback': '/:id/feedback',
99+
'campaign': '/campaign',
100+
'campaign_result': '/campaign/:id/results'
99101
}
100102
}
101103
}
@@ -237,7 +239,6 @@ def send_signed_request(self, scope):
237239
request_url = self.host + scope + '?' + canonical_querystring
238240
r = requests.get(self.host_protocol + request_url, headers=headers)
239241

240-
241242
if r.status_code != 200:
242243
return r
243244
else:
@@ -260,14 +261,15 @@ def check_resource_validity(self, scope, product, resource):
260261
"""
261262
if scope not in self.resources['scopes'].keys():
262263
raise GeneralError('invalid scope', 'Invalid scope name')
263-
if product not in self.resources['scopes'][scope]['products'].keys():
264+
found_scope = self.resources['scopes'][scope]
265+
if product not in found_scope['products'].keys():
264266
raise GeneralError('invalid product', 'Invalid product name')
265-
if resource not in self.resources['scopes'][scope]['products'][product]['resources'].keys():
267+
found_product = found_scope['products'][product]
268+
if resource not in found_product['resources'].keys():
266269
raise GeneralError('invalid resource', 'Invalid resource name')
270+
found_resource = found_product['resources'][resource]
267271

268-
url = '/' + scope + '/' + product + self.resources['scopes'][scope]['products'][product]['resources'][resource]
269-
270-
return url
272+
return '/%s/%s%s' % (scope, product, found_resource)
271273

272274
def handle_id(self, url, resource_id):
273275
"""Replaces the :id pattern in the url

0 commit comments

Comments
 (0)