forked from softprops/muxup
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmeetup.py
151 lines (130 loc) · 5.34 KB
/
meetup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from os import getenv
from urllib2 import quote, URLError, HTTPError
from datetime import datetime
import requests
MU_HOST = getenv('MU_HOST', 'https://secure.meetup.com')
AUTHENTICATION_URI = '%s/oauth2/authorize' % MU_HOST
TOKEN_URI = '%s/oauth2/access' % MU_HOST
API_HOST = getenv('API_HOST', 'https://api.meetup.com')
CLIENT_ID = getenv('CLIENT_ID')
CLIENT_SECRET = getenv('CLIENT_SECRET')
VERSION = '0.1.0'
USER_AGENT = 'MeetupFlask/%s' % VERSION
if not CLIENT_ID or not CLIENT_SECRET: raise Exception(
'CLIENT_ID and CLIENT_SECRET must be set as env vars'
)
def url_for_authentication(
redirect_uri,
response_type='code',
state=str(datetime.now()),
scopes=[]):
''' return the configured uri for
acquiring user authorization for oauth2
'''
uri = "%s?client_id=%s&response_type=%s&state=%s&redirect_uri=%s" % (
AUTHENTICATION_URI,
CLIENT_ID,
response_type,
quote(state),
quote(redirect_uri))
return scopes and "%s&scope=%s" % (uri, '+'.join(scopes)) or uri
def request_access_token(code, redirect_uri):
''' make a request for an access token given
an access grant
'''
resp = requests.post(TOKEN_URI,
data = { 'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': redirect_uri },
headers = { 'User-Agent' : USER_AGENT }).json()
return resp
def refresh_access_token(refresh_token):
''' request a new set of oauth2 credentials given
a previously acquired refresh_token
'''
resp = requests.post(TOKEN_URI,
data = { 'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token },
headers = { 'User-Agent': USER_AGENT })
if 400 == resp.status_code:
raise MeetupNotAuthorized(resp.json())
return resp.json()
def client(access_token):
''' returns a new configured meetup api client
'''
return Client(API_HOST, access_token)
class MeetupNotAuthorized(Exception):
''' Represents an exception thrown when an api request
is rejected due to invalid authorization HTTP 401 Unauthorized
'''
pass
class MeetupBadRequest(Exception):
''' Represents an exception throw when an api request
is rejected for being malformed HTTP 400 Bad Request
'''
pass
class MeetupInternalServerError(Exception):
''' Represents an exception throw when Meetups server messed up.
HTTP 500 Internal Server Error
'''
pass
class Client():
''' rest client for api.meetup.com
'''
def __init__(self, host, access_token):
self.host = host
self.access_token = access_token
def url(self, path):
return "%s%s" % (self.host, path)
def client_headers(self):
return { 'User-Agent': USER_AGENT, 'Authorization': 'Bearer %s' % self.access_token }
def get(self, path, params = {}):
try:
resp = requests.get(self.url(path), params = params, headers = self.client_headers())
if 401 == resp.status_code:
raise MeetupNotAuthorized(resp.json())
if 400 == resp.status_code:
raise MeetupBadRequest(resp.json())
if 500 == resp.status_code:
raise MeetupInternalServerError(resp.json())
return resp.json()
except HTTPError, e:
if 401 == e.code: raise MeetupNotAuthorized(e.read())
if 400 == e.code: raise MeetupBadRequest(e.read())
if 500 == e.code: raise MeetupInternalServerError(e.read())
except URLError, e:
raise MeetupBadRequest("malformed url %s" % e.reason)
except Exception, e:
raise MeetupNotAuthorized('not authorized to request %s: %s' % (path, e))
def post(self, path, params = {}):
try:
resp = requests.post(self.url(path), data = params, headers = self.client_headers())
if 401 == resp.status_code:
raise MeetupNotAuthorized(resp.json())
if 400 == resp.status_code:
raise MeetupBadRequest(resp.json())
if 500 == resp.status_code:
raise MeetupInternalServerError(resp.json())
return resp.json()
except HTTPError, e:
if 401 == e.code: raise MeetupNotAuthorized(e.read())
if 400 == e.code: raise MeetupBadRequest(e.read())
if 500 == e.code: raise MeetupInternalServerError(e.read())
raise e
except URLError, e:
raise MeetupBadRequest("malformed url %s" % e.reason)
except Exception, e:
raise MeetupNotAuthorized('not authorized to request %s: %s' % (path, e))
def current_user(self):
''' return the user that authorized this client
'''
return self.get('/2/member/self')
def open_events(self, params):
''' return events that are in public in groups
and public to rsvp to
'''
return self.get('/2/open_events', params)