|
10 | 10 | # Python 2.x |
11 | 11 | from urllib import urlencode |
12 | 12 |
|
13 | | -from requests_oauthlib import OAuth1, OAuth1Session, OAuth2, OAuth2Session |
| 13 | +from requests_oauthlib import OAuth2, OAuth2Session |
14 | 14 | from oauthlib.oauth2 import TokenExpiredError |
15 | 15 | from fitbit.exceptions import (BadResponse, DeleteError, HTTPBadRequest, |
16 | 16 | HTTPUnauthorized, HTTPForbidden, |
|
19 | 19 | from fitbit.utils import curry |
20 | 20 |
|
21 | 21 |
|
22 | | -class FitbitOauthClient(object): |
23 | | - API_ENDPOINT = "https://api.fitbit.com" |
24 | | - AUTHORIZE_ENDPOINT = "https://www.fitbit.com" |
25 | | - API_VERSION = 1 |
26 | | - |
27 | | - request_token_url = "%s/oauth/request_token" % API_ENDPOINT |
28 | | - access_token_url = "%s/oauth/access_token" % API_ENDPOINT |
29 | | - authorization_url = "%s/oauth/authorize" % AUTHORIZE_ENDPOINT |
30 | | - |
31 | | - def __init__(self, client_key, client_secret, resource_owner_key=None, |
32 | | - resource_owner_secret=None, user_id=None, callback_uri=None, |
33 | | - *args, **kwargs): |
34 | | - """ |
35 | | - Create a FitbitOauthClient object. Specify the first 5 parameters if |
36 | | - you have them to access user data. Specify just the first 2 parameters |
37 | | - to access anonymous data and start the set up for user authorization. |
38 | | -
|
39 | | - Set callback_uri to a URL and when the user has granted us access at |
40 | | - the fitbit site, fitbit will redirect them to the URL you passed. This |
41 | | - is how we get back the magic verifier string from fitbit if we're a web |
42 | | - app. If we don't pass it, then fitbit will just display the verifier |
43 | | - string for the user to copy and we'll have to ask them to paste it for |
44 | | - us and read it that way. |
45 | | - """ |
46 | | - |
47 | | - self.session = requests.Session() |
48 | | - self.client_key = client_key |
49 | | - self.client_secret = client_secret |
50 | | - self.resource_owner_key = resource_owner_key |
51 | | - self.resource_owner_secret = resource_owner_secret |
52 | | - if user_id: |
53 | | - self.user_id = user_id |
54 | | - params = {'client_secret': client_secret} |
55 | | - if callback_uri: |
56 | | - params['callback_uri'] = callback_uri |
57 | | - if self.resource_owner_key and self.resource_owner_secret: |
58 | | - params['resource_owner_key'] = self.resource_owner_key |
59 | | - params['resource_owner_secret'] = self.resource_owner_secret |
60 | | - self.oauth = OAuth1Session(client_key, **params) |
61 | | - |
62 | | - def _request(self, method, url, **kwargs): |
63 | | - """ |
64 | | - A simple wrapper around requests. |
65 | | - """ |
66 | | - return self.session.request(method, url, **kwargs) |
67 | | - |
68 | | - def make_request(self, url, data={}, method=None, **kwargs): |
69 | | - """ |
70 | | - Builds and makes the OAuth Request, catches errors |
71 | | -
|
72 | | - https://wiki.fitbit.com/display/API/API+Response+Format+And+Errors |
73 | | - """ |
74 | | - if not method: |
75 | | - method = 'POST' if data else 'GET' |
76 | | - auth = OAuth1( |
77 | | - self.client_key, self.client_secret, self.resource_owner_key, |
78 | | - self.resource_owner_secret, signature_type='auth_header') |
79 | | - response = self._request(method, url, data=data, auth=auth, **kwargs) |
80 | | - |
81 | | - if response.status_code == 401: |
82 | | - raise HTTPUnauthorized(response) |
83 | | - elif response.status_code == 403: |
84 | | - raise HTTPForbidden(response) |
85 | | - elif response.status_code == 404: |
86 | | - raise HTTPNotFound(response) |
87 | | - elif response.status_code == 409: |
88 | | - raise HTTPConflict(response) |
89 | | - elif response.status_code == 429: |
90 | | - exc = HTTPTooManyRequests(response) |
91 | | - exc.retry_after_secs = int(response.headers['Retry-After']) |
92 | | - raise exc |
93 | | - |
94 | | - elif response.status_code >= 500: |
95 | | - raise HTTPServerError(response) |
96 | | - elif response.status_code >= 400: |
97 | | - raise HTTPBadRequest(response) |
98 | | - return response |
99 | | - |
100 | | - def fetch_request_token(self): |
101 | | - """ |
102 | | - Step 1 of getting authorized to access a user's data at fitbit: this |
103 | | - makes a signed request to fitbit to get a token to use in step 3. |
104 | | - Returns that token.} |
105 | | - """ |
106 | | - |
107 | | - token = self.oauth.fetch_request_token(self.request_token_url) |
108 | | - self.resource_owner_key = token.get('oauth_token') |
109 | | - self.resource_owner_secret = token.get('oauth_token_secret') |
110 | | - return token |
111 | | - |
112 | | - def authorize_token_url(self, **kwargs): |
113 | | - """Step 2: Return the URL the user needs to go to in order to grant us |
114 | | - authorization to look at their data. Then redirect the user to that |
115 | | - URL, open their browser to it, or tell them to copy the URL into their |
116 | | - browser. Allow the client to request the mobile display by passing |
117 | | - the display='touch' argument. |
118 | | - """ |
119 | | - |
120 | | - return self.oauth.authorization_url(self.authorization_url, **kwargs) |
121 | | - |
122 | | - def fetch_access_token(self, verifier, token=None): |
123 | | - """Step 3: Given the verifier from fitbit, and optionally a token from |
124 | | - step 1 (not necessary if using the same FitbitOAuthClient object) calls |
125 | | - fitbit again and returns an access token object. Extract the needed |
126 | | - information from that and save it to use in future API calls. |
127 | | - """ |
128 | | - if token: |
129 | | - self.resource_owner_key = token.get('oauth_token') |
130 | | - self.resource_owner_secret = token.get('oauth_token_secret') |
131 | | - |
132 | | - self.oauth = OAuth1Session( |
133 | | - self.client_key, |
134 | | - client_secret=self.client_secret, |
135 | | - resource_owner_key=self.resource_owner_key, |
136 | | - resource_owner_secret=self.resource_owner_secret, |
137 | | - verifier=verifier) |
138 | | - response = self.oauth.fetch_access_token(self.access_token_url) |
139 | | - |
140 | | - self.user_id = response.get('encoded_user_id') |
141 | | - self.resource_owner_key = response.get('oauth_token') |
142 | | - self.resource_owner_secret = response.get('oauth_token_secret') |
143 | | - return response |
144 | | - |
145 | | - |
146 | 22 | class FitbitOauth2Client(object): |
147 | 23 | API_ENDPOINT = "https://api.fitbit.com" |
148 | 24 | AUTHORIZE_ENDPOINT = "https://www.fitbit.com" |
@@ -205,7 +81,7 @@ def make_request(self, url, data={}, method=None, **kwargs): |
205 | 81 | try: |
206 | 82 | if(d['errors'][0]['errorType'] == 'oauth' and |
207 | 83 | d['errors'][0]['fieldName'] == 'access_token' and |
208 | | - d['errors'][0]['message'].find('Access token invalid or expired:')==0): |
| 84 | + d['errors'][0]['message'].find('Access token invalid or expired:') == 0): |
209 | 85 | self.refresh_token() |
210 | 86 | auth = OAuth2(client_id=self.client_id, token=self.token) |
211 | 87 | response = self._request(method, url, data=data, auth=auth, **kwargs) |
@@ -322,17 +198,12 @@ class Fitbit(object): |
322 | 198 | 'frequent', |
323 | 199 | ] |
324 | 200 |
|
325 | | - def __init__(self, client_key, client_secret, oauth2=False, system=US, **kwargs): |
| 201 | + def __init__(self, client_id, client_secret, system=US, **kwargs): |
326 | 202 | """ |
327 | | - oauth1: Fitbit(<key>, <secret>, resource_owner_key=<key>, resource_owner_secret=<key>) |
328 | | - oauth2: Fitbit(<id>, <secret>, oauth2=True, access_token=<token>, refresh_token=<token>) |
| 203 | + Fitbit(<id>, <secret>, access_token=<token>, refresh_token=<token>) |
329 | 204 | """ |
330 | 205 | self.system = system |
331 | | - |
332 | | - if oauth2: |
333 | | - self.client = FitbitOauth2Client(client_key, client_secret, **kwargs) |
334 | | - else: |
335 | | - self.client = FitbitOauthClient(client_key, client_secret, **kwargs) |
| 206 | + self.client = FitbitOauth2Client(client_id, client_secret, **kwargs) |
336 | 207 |
|
337 | 208 | # All of these use the same patterns, define the method for accessing |
338 | 209 | # creating and deleting records once, and use curry to make individual |
@@ -1114,10 +985,3 @@ def list_subscriptions(self, collection=''): |
1114 | 985 | collection='/{0}'.format(collection) if collection else '' |
1115 | 986 | ) |
1116 | 987 | return self.make_request(url) |
1117 | | - |
1118 | | - @classmethod |
1119 | | - def from_oauth_keys(self, client_key, client_secret, user_key=None, |
1120 | | - user_secret=None, user_id=None, system=US): |
1121 | | - client = FitbitOauthClient(client_key, client_secret, user_key, |
1122 | | - user_secret, user_id) |
1123 | | - return self(client, system) |
0 commit comments