Skip to content

Commit 0141e6b

Browse files
author
Lelia
committed
changes support api
1 parent 4324036 commit 0141e6b

6 files changed

Lines changed: 188 additions & 56 deletions

File tree

pruebas.py

Whitespace-only changes.

pruebas2.py

Whitespace-only changes.

typeform/client.py

Lines changed: 125 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,79 @@
11
import requests
2+
from requests.auth import AuthBase
3+
from typeform import exception
4+
from typeform.enumerator import ErrorEnum
5+
from typeform.clientauth import ClientAuth
6+
import json
27

38
class Client(object):
4-
BASE_URL = 'https://api.typeform.com/'
5-
_VALID_VERSIONS = ['v1', ]
9+
_VALID_VERSIONS = ['v1']
610

7-
def __init__(self, api_key, version=None):
11+
def __init__(self, api_key=None, access_token=None, version=None):
12+
self.access_token = access_token
813
self.api_key = api_key
914
if version not in self._VALID_VERSIONS:
1015
self.version = self._VALID_VERSIONS[0]
16+
if api_key:
17+
self.auth = ClientAuth(api_key=api_key)
18+
self.base_url = 'https://api.typeform.com/'+self._VALID_VERSIONS[0]
19+
elif access_token:
20+
self.auth = ClientAuth(access_token=access_token)
21+
self.base_url = 'https://api.typeform.com'
22+
else:
23+
raise exception.CredentialRequired("You must provide either access_token or api_key")
1124

12-
def _get(self, endpoint, params=None):
13-
return self._request('GET', endpoint, params)
14-
15-
def _request(self, method, endpoint, params=None, data=None):
16-
url = '{0}{1}/{2}'.format(self.BASE_URL, self.version, endpoint)
17-
print(url)
18-
response = requests.request(method, url, params=params, json=data)
19-
r = response.json()
20-
if response.status_code in [403, 404]:
21-
if 'message' in r:
22-
raise Exception(r['message'])
25+
def _get(self, endpoint, data=None):
26+
return self._request('GET', endpoint, data=data)
27+
28+
def _put(self, endpoint, data=None):
29+
return self._request('PUT', endpoint, data=data)
30+
31+
def _delete(self, endpoint, data=None):
32+
return self._request('DELETE', endpoint, data=data)
33+
34+
def _request(self, method, endpoint, data=None):
35+
url = '{0}/{1}'.format(self.base_url, endpoint)
36+
response = requests.request(method, url, auth=self.auth, data=json.dumps(data))
37+
return self._parse(response)
38+
39+
def _parse(self, response):
40+
if not response.ok:
41+
try:
42+
data = response.json()
43+
if 'description' in data and 'code' in data:
44+
message = data['description']
45+
code = data['code']
46+
except:
47+
code = response.status_code
48+
message = ""
49+
try:
50+
error_enum = ErrorEnum(response.status_code)
51+
except Exception:
52+
raise exception.UnexpectedError('Error:{0}{1}.Message{2}'.format(code, response.status_code, message))
53+
if error_enum == ErrorEnum.Forbidden:
54+
raise exception.Forbidden(message)
55+
if error_enum == ErrorEnum.Not_Found:
56+
raise exception.Not_Found(message)
57+
if error_enum == ErrorEnum.Payment_Required:
58+
raise exception.Payment_Required(message)
59+
if error_enum == ErrorEnum.Internal_Server_Error:
60+
raise exception.Internal_Server_Error(message)
61+
if error_enum == ErrorEnum.Service_Unavailable:
62+
raise exception.Service_Unavailable(message)
63+
if error_enum == ErrorEnum.Bad_Request:
64+
raise exception.Bad_Request(message)
65+
if error_enum == ErrorEnum.Unauthorized:
66+
raise exception.Unauthorized(message)
2367
else:
24-
if 'code' in r:
25-
raise Exception(r['description'])
26-
raise Exception('Unexpected error.')
27-
return r
68+
raise exception.BaseError('Error: {0}{1}. Message {2}'.format(code, response.status_code, message))
69+
return data
70+
else:
71+
return response
2872

2973
def get_form_uid(self, url_form):
3074
"""Returns addresses registered by the user.
3175
Args:
32-
url_form:
76+
url_form: String, Url from the form (the method needs the uid or form)
3377
Returns:
3478
A string.
3579
"""
@@ -40,7 +84,7 @@ def get_form_uid(self, url_form):
4084
def get_form_information(self, uid=None, url=None):
4185
"""Returns addresses registered by the user.
4286
Args:
43-
typeform_uid:
87+
uid: Unique ID for the form
4488
Returns:
4589
A dict.
4690
"""
@@ -49,62 +93,87 @@ def get_form_information(self, uid=None, url=None):
4993
raise Exception('You must provide either an UID or Form URL.')
5094
else:
5195
uid = self.get_form_uid(url)
52-
params = {'key': self.api_key}
53-
return self._get('form/{}'.format(uid), params=params)
54-
55-
def get_form_stats(self, uid=None, url=None, form=None):
56-
"""Returns stats of form.
57-
Args:
58-
uid:
59-
url:
60-
Returns:
61-
A dict.
62-
"""
63-
if form is not None:
64-
return form['stats']
65-
return self.get_form_information(uid=uid, url=url)['stats']
96+
return self._get('forms/{}'.format(uid)).json()
6697

6798
def get_form_questions(self, uid=None, url=None, form=None):
6899
"""Returns questions of form.
69100
Args:
70-
uid:
71-
url:
101+
uid: Unique ID for the form
102+
url: String, Url from the form (the method needs the uid or form)
72103
Returns:
73104
A dict.
74105
"""
75106
if form is not None:
76-
return form['questions']
77-
return self.get_form_information(uid=uid, url=url)['questions']
107+
return form['fields']
108+
return self.get_form_information(uid=uid, url=url)['fields']
78109

79-
def get_form_metadata(self, uid=None, url=None, form=None):
80-
"""Returns metadata of form.
110+
def get_form_metadata(self, since, until, uid=None, url=None, form=None):
111+
"""Returns metadata of form (include answers).
81112
Args:
82-
uid:
83-
url:
113+
uid: String, ID from the form
114+
url: String, Url from the form (the method needs the uid or form)
115+
form: String, A form
116+
since: String, The since parameter is a string that uses ISO 8601 format,
117+
Coordinated Universal Time (UTC), with "T" as a delimiter between the date and time.
118+
July 10, 2017 at 12:00 a.m. UTC is expressed as 2017-07-10T00:00:00.
119+
If you want to retrieve responses for yesterday, 2017-07-09, the value for your since query parameter
120+
would be 2017-07-09T00:00:00
121+
until: String, The until parameter is a string that uses ISO 8601 format,
122+
Coordinated Universal Time (UTC), with "T" as a delimiter between the date and time.
123+
July 10, 2017 at 12:00 a.m. UTC is expressed as 2017-07-10T00:00:00.
124+
If you want to retrieve responses for yesterday, 2017-07-09, the value for your since query parameter
125+
would be 2017-07-09T00:00:00
84126
Returns:
85127
A dict.
86128
"""
87129
if form is not None:
88130
return form['responses']
89-
return self.get_form_information(uid=uid, url=url)['responses']
131+
data = {
132+
'since': since,
133+
'until': until,
134+
}
135+
return self._get(endpoint="forms/{0}/responses".format(uid), data=data).json()['items']
90136

91-
def get_form_answers(self, uid=None, url=None, form=None):
92-
"""Returns answers of form.
93-
Args:
94-
uid:
95-
url:
96-
Returns:
97-
A list.
98-
"""
99-
if form is None:
100-
form = self.get_form_information(uid=uid, url=url)
101-
return [answers['answers'] for answers in form['responses']]
102137

103138
def get_forms(self):
104139
"""Returns all forms
105140
Args:
106141
Returns:
107142
A dict.
108143
"""
109-
params = {'key': self.api_key}
110-
return self._get('forms?key={0}'.format(self.api_key), params=params)
144+
return self._get(endpoint='forms').json()
145+
146+
def create_webhook(self, url_webhook, tag_webhook, uid):
147+
"""
148+
:param url_webhook: String URL webhook request
149+
:param tag_webhook: String
150+
:param uid: String, Unique ID for the form
151+
:return: dict
152+
"""
153+
if self.access_token is not None:
154+
data = {'url':url_webhook, 'enabled':True}
155+
return self._put(endpoint='forms/{1}/webhooks/{0}'.format(tag_webhook, uid), data=data).json()
156+
else:
157+
raise exception.TokenRequired("You need an access token for this method")
158+
159+
def view_webhook(self, tag_webhook, uid):
160+
"""
161+
:param tag_webhook: String
162+
:param uid: String, Unique ID for the form
163+
:return:
164+
"""
165+
if self.access_token is not None:
166+
return self._get(endpoint='forms/{1}/webhooks/{0}'.format(tag_webhook, uid)).json()
167+
else:
168+
raise exception.TokenRequired("You need an access token for this method")
169+
170+
def delete_webhook(self, tag_webhook, uid):
171+
"""
172+
:param tag_webhook: String
173+
:param uid: String, Unique ID for the form
174+
:return:
175+
"""
176+
if self.access_token is not None:
177+
return self._delete(endpoint='forms/{1}/webhooks/{0}'.format(tag_webhook, uid)).ok
178+
else:
179+
raise exception.TokenRequired("You need an access token for this method")

typeform/clientauth.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import requests
2+
from typeform import exception
3+
4+
class ClientAuth(requests.auth.AuthBase):
5+
6+
def __init__(self, access_token=None, api_key=None):
7+
if access_token:
8+
self.access_token = access_token
9+
self.api_key = None
10+
elif api_key:
11+
self.api_key = api_key
12+
self.access_token = None
13+
else:
14+
raise exception.CredentialRequired("You must provide either access_token or api_key")
15+
16+
def __call__(self, r):
17+
if self.access_token is not None:
18+
r.headers['Authorization'] = 'bearer {0}'.format(self.access_token)
19+
elif self.api_key is not None:
20+
r.prepare_url(r.url, {'key': self.api_key})
21+
return r

typeform/enumerator.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from enum import Enum
2+
3+
class ErrorEnum(Enum):
4+
Forbidden = 403
5+
Not_Found = 404
6+
Payment_Required = 402
7+
Internal_Server_Error = 500
8+
Service_Unavailable = 503
9+
Bad_Request = 400
10+
Unauthorized = 401

typeform/exception.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class BaseError(Exception):
2+
pass
3+
4+
class CredentialRequired(BaseError):
5+
pass
6+
7+
class UnexpectedError(BaseError):
8+
pass
9+
10+
class Forbidden (BaseError):
11+
pass
12+
13+
class Not_Found (BaseError):
14+
pass
15+
16+
class Payment_Required (BaseError):
17+
pass
18+
19+
class Internal_Server_Error (BaseError):
20+
pass
21+
22+
class Service_Unavailable (BaseError):
23+
pass
24+
25+
class Bad_Request (BaseError):
26+
pass
27+
28+
class Unauthorized (BaseError):
29+
pass
30+
31+
class TokenRequired(BaseError):
32+
pass

0 commit comments

Comments
 (0)