Skip to content
This repository was archived by the owner on Jul 3, 2023. It is now read-only.

add Webhooks API support #18

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
11 changes: 7 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
language: python
matrix:
include:
- python: 3.5
dist: trusty
sudo: false
- python: 3.6
dist: trusty
sudo: false
- python: 3.7
dist: xenial
sudo: true
sudo: false
- python: 3.8
dist: xenial
sudo: false
- python: 3.9
dist: xenial
sudo: false

install:
- python setup.py develop
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python',
]
)
6 changes: 6 additions & 0 deletions typeform/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .forms import Forms
from .responses import Responses
from .webhooks import Webhooks
from .client import Client

__all__ = ['Typeform']
Expand All @@ -13,6 +14,7 @@ def __init__(self, token: str, headers: dict = {}):
client = Client(token, headers=headers)
self.__forms = Forms(client)
self.__responses = Responses(client)
self.__webhooks = Webhooks(client)

@property
def forms(self) -> Forms:
Expand All @@ -21,3 +23,7 @@ def forms(self) -> Forms:
@property
def responses(self) -> Responses:
return self.__responses

@property
def webhooks(self) -> Webhooks:
return self.__webhooks
2 changes: 1 addition & 1 deletion typeform/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __validator(self, result: requests.Response) -> typing.Union[str, dict]:
if type(body) is dict and body.get('code', None) is not None:
raise Exception(body.get('description'))
elif result.status_code >= 400:
raise Exception(' '.join([str(result.status_code),result.reason]))
raise Exception(' '.join([str(result.status_code), result.reason]))
elif len(result.text) == 0:
return 'OK'
else:
Expand Down
4 changes: 2 additions & 2 deletions typeform/test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
WORKSPACE = 'https://api.typeform.com/workspaces/hn3dNa'
WORKSPACE_ID = WORKSPACE.split('/')[-1]

if MOCK and (not TOKEN or '[YOUR WORKSPACE ID]' in WORKSPACE):
raise Exception("You need to setup TOKEN and WORKSPACE in fixtures.py")
if (not MOCK) and (not TOKEN or '[YOUR WORKSPACE ID]' in WORKSPACE):
raise Exception('You need to setup TOKEN and WORKSPACE in fixtures.py')
11 changes: 7 additions & 4 deletions typeform/test/test_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setUp(self):
form = self.forms.create(dict(title="Form's test form", workspace={'href': WORKSPACE}))
self.formID = form.get('id')
else:
self.formID = "MOCK-FORM-ID"
self.formID = 'MOCK-FORM-ID'

def tearDown(self):
if not MOCK:
Expand Down Expand Up @@ -93,7 +93,7 @@ def test_forms_update_as_patch_updates_a_form(self):
update as patch updates a form
"""
with requests_mock.mock(real_http=not MOCK) as m:
m.patch(API_BASE_URL+'/forms/'+self.formID, json="OK")
m.patch(API_BASE_URL+'/forms/'+self.formID, json='OK')
result = self.forms.update(self.formID, patch=True, data=[
dict(op='replace', path='/title', value='forms_update_as_patch_updates_a_form')])

Expand Down Expand Up @@ -125,7 +125,7 @@ def test_forms_delete_removes_the_correct_uid_form(self):
self.assertEqual(get_one_result.get('id'), self.formID)
self.forms.delete(self.formID)
m.get(API_BASE_URL + '/forms/{}'.format(self.formID),
json=dict(code="FORM_NOT_FOUND", description="Non existing form with uid {}".format(self.formID)))
json=dict(code='FORM_NOT_FOUND', description='Non existing form with uid {}'.format(self.formID)))
try:
self.forms.get(self.formID)
except Exception as err:
Expand Down Expand Up @@ -153,7 +153,10 @@ def test_forms_create_creates_a_new_form(self):
m.post(API_BASE_URL + '/forms', json=dict(id=str(self.formID)))
m.get(API_BASE_URL + '/forms/{}'.format(self.formID), json=dict(id=str(self.formID)))

create_result = self.forms.create(dict(title='forms_create_creates_a_new_form', workspace={'href': WORKSPACE}))
create_result = self.forms.create(dict(
title='forms_create_creates_a_new_form',
workspace={'href': WORKSPACE},
))

formID = create_result.get('id')

Expand Down
2 changes: 1 addition & 1 deletion typeform/test/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def setUp(self):
form = self.forms.create((dict(title="Responses's test form", workspace={'href': WORKSPACE})))
self.formID = form.get('id')
else:
self.formID = "MOCK-FORM-ID"
self.formID = 'MOCK-FORM-ID'

def tearDown(self):
if not MOCK:
Expand Down
42 changes: 42 additions & 0 deletions typeform/webhooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from .client import Client


class Webhooks:
"""Typeform Webhooks API client"""

def __init__(self, client: Client):
"""Constructor for Typeform Webhooks class"""
self.__client = client

def list(self, uid: str) -> dict:
"""
Returns form webhooks and date and time of form landing and submission.
"""
return self.__client.request('get', '/forms/%s/webhooks' % uid)

def get(self, uid: str, tag: str) -> dict:
"""
Returns form webhooks and date and time of form landing and submission.
"""
return self.__client.request('get', '/forms/%s/webhooks/%s' % (uid, tag))

def create_update(self, uid: str, tag: str, data={}) -> dict:
"""
Create or update a webhook.
{
'url': url, str
'enabled': enabled, bool
'secret': secret, str
'verify_ssl': verify_ssl bool
}
"""
return self.__client.request(
'put', '/forms/%s/webhooks/%s' % (uid, tag), data=data
)

def delete(self, uid: str, tag: str) -> str:
"""
Delete webhooks to a form.
Return a `str` based on success of deletion, `OK` on success, otherwise an error message.
"""
return self.__client.request('delete', '/forms/%s/webhooks/%s' % (uid, tag))