Skip to content

Commit e26d47e

Browse files
authored
Merge pull request #3 from luiscastillocr/main
Calendly Oauth2 Client
2 parents dd5a4ce + 41f8fe6 commit e26d47e

8 files changed

Lines changed: 552 additions & 53 deletions

File tree

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ calendly = CalendlyAPI(api_key)
3434
- `get_event_details` - Get information about the event
3535
- `list_event_invitees` - Get all invitees for a event
3636

37+
### Oauth2
38+
Getting started with [Calendly Oauth2 API](https://developer.calendly.com/api-docs/YXBpOjU5MTQwNw-o-auth-2-0) .
39+
```
40+
from calendly import CalendlyOauth2
41+
42+
client_id = "<client_id>"
43+
client_secret = "<client_secret>"
44+
redirect_uri = "<redirect_uri>"
45+
46+
oauth2 = CalendlyOauth2(
47+
client_id,
48+
client_secret,
49+
redirect_uri
50+
)
51+
```
52+
53+
### Methods
54+
- `authorization_url` - Returns the formatted authorization URL
55+
- `get_access_token` - Send a request to obtain the given access token
56+
- `revoke_access_token` - Send a request to revoke the given access token
57+
- `refresh_access_token` - Send a request to refresh the given access token
58+
- `introspect_access_token` - Send a request to bring details about the given access token
3759

3860
## Issues
3961
Feel free to submit issues and enhancement requests.

calendly/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from .utils.oauth2 import CalendlyOauth2
12
from .calendly import CalendlyAPI
3+
from .exceptions import CalendlyException, CalendlyOauth2Exception
24

3-
__all__ = [CalendlyAPI]
5+
__all__ = [CalendlyAPI, CalendlyOauth2, CalendlyException, CalendlyOauth2Exception]

calendly/calendly.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
from calendly.utils.constants import WEBHOOK, EVENTS, ME, EVENT_TYPE
2-
from calendly.utils.requests import CalendlyReq, CalendlyException
1+
import json
32
from typing import List, MutableMapping
4-
import json
3+
4+
from calendly.utils.api import CalendlyReq
5+
from calendly.utils.constants import WEBHOOK, EVENTS, ME, EVENT_TYPE
6+
from calendly.exceptions import CalendlyException
7+
58

69
class CalendlyAPI(object):
710

@@ -21,14 +24,15 @@ def __init__(self, token: str):
2124
"""
2225
self.request = CalendlyReq(token)
2326

24-
def create_webhook(self, url: str, scope: str, organization: str, signing_key: str=None, user: str=None, event_types: List[str]=["canceled", "created"]) -> MutableMapping:
27+
def create_webhook(self, url: str, scope: str, organization: str, signing_key: str=None, user: str=None, event_types: List[str]=("canceled", "created")) -> MutableMapping:
2528
"""
2629
Create a Webhook Subscription
2730
2831
Args:
2932
url (str): Webhook URL
3033
scope (str): Either "organization" or "user"
3134
organization (str): Unique reference to the organization that the webhook will be tied to
35+
signing_key (str): A signing key
3236
user (str, optional): If scope is set to "user", then user reference is required.
3337
event_types (list, optional): List of user events to subscribe to. Defaults to ["canceled", "created"].
3438
@@ -44,8 +48,8 @@ def create_webhook(self, url: str, scope: str, organization: str, signing_key: s
4448
'scope': scope,
4549
'signing_key': signing_key}
4650

47-
if (scope == 'user'):
48-
if (user == None):
51+
if scope == 'user':
52+
if user is None:
4953
raise CalendlyException
5054
data['user'] = user
5155

@@ -131,7 +135,7 @@ def about(self) -> MutableMapping:
131135
response = self.request.get(ME)
132136
return response.json()
133137

134-
def list_event_types(self, count: int=20, organization: str=None, page_token: str=None, sort: str=None, user_uri: str=None) -> List[MutableMapping]:
138+
def list_event_types(self, count: int=20, organization: str=None, page_token: str=None, sort: str=None, user_uri: str=None) -> MutableMapping:
135139
"""
136140
Returns all Event Types associated with a specified user.
137141
@@ -146,13 +150,13 @@ def list_event_types(self, count: int=20, organization: str=None, page_token: st
146150
dict: json decoded response with list of event types
147151
"""
148152
data = {"count": count}
149-
if (organization):
153+
if organization:
150154
data['organization'] = organization
151-
if (page_token):
155+
if page_token:
152156
data['page_token'] = page_token
153-
if (sort):
157+
if sort:
154158
data['sort'] = sort
155-
if (user_uri):
159+
if user_uri:
156160
data['user'] = user_uri
157161
response = self.request.get(EVENT_TYPE, data)
158162
return response.json()
@@ -170,7 +174,7 @@ def get_event_type(self, uuid: str) -> MutableMapping:
170174
response = self.request.get(f'{EVENT_TYPE}/' + uuid, data)
171175
return response.json()
172176

173-
def list_events(self, count: int=20, organization: str=None, sort: str=None, user_uri: str=None, status: str=None) -> List[MutableMapping]:
177+
def list_events(self, count: int=20, organization: str=None, sort: str=None, user_uri: str=None, status: str=None) -> MutableMapping:
174178
"""
175179
Returns a List of Events
176180
@@ -185,13 +189,13 @@ def list_events(self, count: int=20, organization: str=None, sort: str=None, use
185189
dict: json decoded response of list of events.
186190
"""
187191
data = {'count': count}
188-
if (organization):
192+
if organization:
189193
data['organization'] = organization
190-
if (sort):
194+
if sort:
191195
data['sort'] = sort
192-
if (user_uri):
196+
if user_uri:
193197
data['user'] = user_uri
194-
if (status):
198+
if status:
195199
data['status'] = status
196200
response = self.request.get(EVENTS, data)
197201
return response.json()
@@ -239,7 +243,7 @@ def list_event_invitees(self, uuid: str) -> List[MutableMapping]:
239243
response = self.request.get(url)
240244
return response.json()
241245

242-
def get_all_event_types(self, user_uri: str) -> List[str]:
246+
def get_all_event_types(self, user_uri: str) -> List[MutableMapping]:
243247
"""
244248
Get all event types by recursively crawling on all result pages.
245249
@@ -254,14 +258,14 @@ def get_all_event_types(self, user_uri: str) -> List[str]:
254258

255259
data = first['collection']
256260

257-
while (next_page):
261+
while next_page:
258262
page = self.request.get(next_page).json()
259263
data += page['collection']
260264
next_page = page['pagination']['next_page']
261265

262266
return data
263267

264-
def get_all_scheduled_events(self, user_uri: str) -> List[str]:
268+
def get_all_scheduled_events(self, user_uri: str) -> List[MutableMapping]:
265269
"""
266270
Get all scheduled events by recursively crawling on all result pages.
267271
@@ -306,5 +310,4 @@ def convert_event_to_original_url(self, event_uri: str, user_uri: str) -> str:
306310
if not next_page:
307311
break
308312
page = self.request.get(next_page).json()
309-
return
310313

calendly/exceptions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class CalendlyException(Exception):
2+
"""Errors corresponding to a misuse of Calendly API"""
3+
4+
def __init__(self, message=None, details=None):
5+
self.message = message or ""
6+
self.details = details or []
7+
super(CalendlyException, self).__init__(f"{self.message} - {self.details}")
8+
9+
class CalendlyOauth2Exception(CalendlyException):
10+
"""Errors corresponding to a misuse of CalendlyOauth2 API"""

0 commit comments

Comments
 (0)