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

Commit aeb1248

Browse files
committed
feat(Responses): add responses api, fixes #6
1 parent 35e514c commit aeb1248

12 files changed

Lines changed: 212 additions & 43 deletions

.travis.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
language: python
22
matrix:
33
include:
4-
- python: 3.3
5-
dist: trusty
6-
sudo: false
7-
- python: 3.4
8-
dist: trusty
9-
sudo: false
104
- python: 3.5
115
dist: trusty
126
sudo: false

README.md

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Python Client wrapper for [Typeform API](https://developer.typeform.com/)
1212
- [Reference](#reference)
1313
- [Create Client](#typeformapi_key)
1414
- [Forms](#forms)
15+
- [Responses](#responses)
1516

1617
## Installation
1718

@@ -56,67 +57,95 @@ pip install typeform
5657
Client returns the following properties:
5758

5859
- `forms`
60+
- `responses`
5961

6062
Each one of them encapsulates the operations related to it (like listing, updating, deleting the resource).
6163

6264
### Forms
6365

64-
#### `forms.create(data={})`
66+
#### `forms.create(data: dict = {})`
6567

6668
Creates a form. Returns `dict` of created form. [See docs](https://developer.typeform.com/create/reference/create-form/).
6769

6870
```python
6971
forms = Typeform('<api_key>').forms
70-
forms.create({ 'title': 'Hello World' })
72+
result: dict = forms.create({ 'title': 'Hello World' })
7173
```
7274

73-
#### `forms.delete('Form ID')`
75+
#### `forms.delete(uid: str)`
7476

75-
Deletes the form with the given form_id and all of the form's responses. Return a `str` based on success of deletion, `OK` on success, otherwise an error message. [See docs](https://developer.typeform.com/create/reference/delete-form/).
77+
Deletes the form with the given form_id and all of the form's responses. Returns a `str` based on success of deletion, `OK` on success, otherwise an error message. [See docs](https://developer.typeform.com/create/reference/delete-form/).
7678

7779
```python
7880
forms = Typeform('<api_key>').forms
79-
forms.delete('abc123') # OK
81+
result: str = forms.delete('abc123')
8082
```
8183

82-
#### `forms.get('Form ID')`
84+
#### `forms.get(uid: str)`
8385

8486
Retrieves a form by the given form_id. Includes any theme and images attached to the form as references. [See docs](https://developer.typeform.com/create/reference/retrieve-form/).
8587

8688
```python
8789
forms = Typeform('<api_key>').forms
88-
forms.get('abc123')
90+
result: dict = forms.get('abc123')
8991
```
9092

91-
#### `forms.list()`
93+
#### `forms.list(page: int = None, pageSize: int = None, search: str = None, workspaceId: str = None)`
9294

9395
Retrieves a list of JSON descriptions for all forms in your Typeform account (public and private). Forms are listed in reverse-chronological order based on the last date they were modified. [See docs](https://developer.typeform.com/create/reference/retrieve-form/).
9496

9597
```python
9698
forms = Typeform('<api_key>').forms
97-
forms.list()
99+
result: dict = forms.list()
98100
```
99101

100-
#### `forms.update('Form ID', data={}, patch=False)`
102+
#### `forms.update(uid: str, patch: bool = False, data: dict = {})`
101103

102-
Updates an existing form. Defaults to `put`. `put` will return the modified form as a `dict` object. `patch` will return a `str` based on success of change, `OK` on success, otherwise an error message. [See `put` docs](https://developer.typeform.com/create/reference/update-form/) or [`patch` docs](https://developer.typeform.com/create/reference/update-form-patch/).
104+
Updates an existing form. Defaults to `put`. `put` will return the modified form as a `dict` object. `patch` will Returns a `str` based on success of change, `OK` on success, otherwise an error message. [See `put` docs](https://developer.typeform.com/create/reference/update-form/) or [`patch` docs](https://developer.typeform.com/create/reference/update-form-patch/).
103105

104-
#### `forms.messages.get('Form ID')`
106+
```python
107+
forms = Typeform('<api_key>').forms
108+
result: dict = forms.update('abc123', { 'title': 'Hello World, Again' })
109+
result: str = forms.update('abc123', { 'title': 'Hello World, Again' }, patch=True)
110+
```
111+
112+
#### `forms.messages.get(uid: str)`
105113

106114
Retrieves the customizable messages for a form (specified by form_id) using the form's specified language. You can format messages with bold (*bold*) and italic (_italic_) text. HTML tags are forbidden. [See docs](https://developer.typeform.com/create/reference/retrieve-custom-form-messages/).
107115

108116
```python
109117
forms = Typeform('<api_key>').forms
110-
forms.messages.get('abc123')
118+
result: dict = forms.messages.get('abc123')
111119
```
112120

113-
#### `forms.messages.update('Form ID', data={})`
121+
#### `forms.messages.update(uid: str, data={})`
114122

115-
Specifies new values for the customizable messages in a form (specified by form_id). You can format messages with bold (*bold*) and italic (_italic_) text. HTML tags are forbidden. Return a `str` based on success of change, `OK` on success, otherwise an error message. [See docs](https://developer.typeform.com/create/reference/update-custom-messages/).
123+
Specifies new values for the customizable messages in a form (specified by form_id). You can format messages with bold (*bold*) and italic (_italic_) text. HTML tags are forbidden. Returns a `str` based on success of change, `OK` on success, otherwise an error message. [See docs](https://developer.typeform.com/create/reference/update-custom-messages/).
116124

117125
```python
118126
forms = Typeform('<api_key>').forms
119-
forms.messages.update('abc123', {
120-
'label.buttonHint.default': 'New Button Hint'
127+
result: str = forms.messages.update('abc123', {
128+
'label.buttonHint.default': 'New Button Hint'
121129
})
122130
```
131+
132+
### Responses
133+
134+
#### `responses.list(uid: str, pageSize: int = None, since: str = None, until: str = None, after: str = None, before: str = None, includedResponseIds: str = None, completed: bool = None, sort: str = None, query: str = None, fields: List[str] = None)`
135+
136+
Returns form responses and date and time of form landing and submission. [See docs](https://developer.typeform.com/responses/reference/retrieve-responses/).
137+
138+
```python
139+
responses = Typeform('<api_key>').responses
140+
result: dict = responses.list('abc123')
141+
```
142+
143+
#### `responses.delete(uid: str, includedTokens: Union[str, List[str]])`
144+
145+
Delete responses to a form. You must specify the `included_tokens` parameter. Returns a `str` based on success of deletion, `OK` on success, otherwise an error message. [See docs](https://developer.typeform.com/responses/reference/delete-responses/).
146+
147+
```python
148+
responses = Typeform('<api_key>').responses
149+
result: str = responses.delete('abc123' 'token1')
150+
result: str = responses.delete('abc123' ['token2', 'token3'])
151+
```

requirements-dev.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ coverage
22
coveralls
33
flake8
44
flake8-quotes
5-
requests-mock
6-
setuptools
5+
requests
6+
requests-mock

requirements.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

setup.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
'License :: OSI Approved :: MIT License',
3030
'Operating System :: OS Independent',
3131
'Programming Language :: Python :: 3',
32-
'Programming Language :: Python :: 3.3',
33-
'Programming Language :: Python :: 3.4',
3432
'Programming Language :: Python :: 3.5',
3533
'Programming Language :: Python :: 3.6',
3634
'Programming Language :: Python :: 3.7',

typeform/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .forms import Forms
2+
from .responses import Responses
23
from .client import Client
34

45
__all__ = ['Typeform']
@@ -7,11 +8,16 @@
78
class Typeform:
89
"""Typeform API client"""
910

10-
def __init__(self, token, headers: dict = {}):
11+
def __init__(self, token: str, headers: dict = {}):
1112
"""Constructor for Typeform API client"""
1213
client = Client(token, headers=headers)
1314
self.__forms = Forms(client)
15+
self.__responses = Responses(client)
1416

1517
@property
1618
def forms(self) -> Forms:
1719
return self.__forms
20+
21+
@property
22+
def responses(self) -> Responses:
23+
return self.__responses

typeform/client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class Client(object):
1010
"""TypeForm API HTTP client"""
1111

12-
def __init__(self, token, headers: dict = {}):
12+
def __init__(self, token: str, headers: dict = {}):
1313
"""Constructor for TypeForm API client"""
1414
self.__headers = mergeDict({
1515
'Content-Type': 'application/json',
@@ -21,7 +21,6 @@ def request(self, method: str, url: str, data: any = {}, params: dict = {}, head
2121
requestUrl = buildUrlWithParams((API_BASE_URL + url), params)
2222
requestHeaders = mergeDict(self.__headers, headers)
2323
requestData = ''
24-
2524
if type(data) is dict:
2625
requestData = json.dumps(data) if len(data.keys()) > 0 else ''
2726

typeform/forms.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def __init__(self, client: Client):
1313
def messages(self):
1414
return self.__messages
1515

16-
def create(self, data={}) -> dict:
16+
def create(self, data: dict = {}) -> dict:
1717
"""Creates a form"""
1818
return self.__client.request('post', '/forms', data=data)
1919

@@ -40,7 +40,7 @@ def list(self, page: int = None, pageSize: int = None, search: str = None, works
4040
'workspace_id': workspaceId
4141
})
4242

43-
def update(self, uid: str, patch=False, data: any = {}) -> typing.Union[str, dict]:
43+
def update(self, uid: str, data: dict = {}, patch: bool = False) -> typing.Union[str, dict]:
4444
"""
4545
Updates an existing form.
4646
Defaults to `put`.

typeform/responses.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import typing
2+
from .client import Client
3+
4+
5+
class Responses:
6+
"""Typeform Responses API client"""
7+
8+
def __init__(self, client: Client):
9+
"""Constructor for Typeform Responses class"""
10+
self.__client = client
11+
12+
def list(
13+
self, uid: str, pageSize: int = None, since: str = None, until: str = None,
14+
after: str = None, before: str = None, includedResponseIds: str = None,
15+
completed: bool = None, sort: str = None, query: str = None, fields: typing.List[str] = None
16+
) -> dict:
17+
"""
18+
Returns form responses and date and time of form landing and submission.
19+
"""
20+
return self.__client.request('get', '/forms/%s/responses' % uid, params={
21+
'page_size': pageSize or None,
22+
'since': since or None,
23+
'until': until,
24+
'after': after,
25+
'before': before,
26+
'included_response_ids': includedResponseIds,
27+
'completed': completed,
28+
'sort': sort,
29+
'query': query,
30+
'fields': fields
31+
})
32+
33+
def delete(self, uid: str, includedTokens: typing.Union[str, typing.List[str]]) -> str:
34+
"""
35+
Delete responses to a form. You must specify the `included_tokens`/`includedTokens` parameter.
36+
Return a `str` based on success of deletion, `OK` on success, otherwise an error message.
37+
"""
38+
return self.__client.request('delete', '/forms/%s/responses' % uid, params={
39+
'included_tokens': includedTokens
40+
})

typeform/test/test_client.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@ def test_client_pass_headers(self):
2222

2323
history = m.request_history
2424
self.assertEqual(history[0].url, API_BASE_URL+'/forms')
25-
self.assertEqual(history[0].headers, {
26-
'User-Agent': 'python-requests/2.21.0',
27-
'Accept-Encoding': 'gzip, deflate',
28-
'Accept': 'application/json',
29-
'Connection': 'keep-alive',
30-
'Content-Type': 'application/json',
31-
'Authorization': 'bearer %s' % TOKEN,
32-
'Accepts': 'application/json'
33-
})
25+
self.assertEqual(history[0].headers.pop('Content-Type'), 'application/json')
26+
self.assertEqual(history[0].headers.pop('Accepts'), 'application/json')
27+
self.assertEqual(history[0].headers.pop('Authorization'), 'bearer %s' % TOKEN)

0 commit comments

Comments
 (0)