Skip to content

Commit 8453a3c

Browse files
committed
initial commit
0 parents  commit 8453a3c

File tree

3 files changed

+278
-0
lines changed

3 files changed

+278
-0
lines changed

Api.py

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
"""
2+
UBER API Client Library
3+
4+
Usage:
5+
>>> from uber import Api
6+
>>> api = Api.Uber(**credentials)
7+
>>> api.get_profile()
8+
"""
9+
10+
__all__ = ['Api']
11+
12+
import json
13+
import config
14+
import urllib
15+
import requests
16+
from config import BASE_URL
17+
18+
19+
class UberApiError(Exception):
20+
'''Base class for Uber API errors'''
21+
22+
@property
23+
def message(self):
24+
'''Returns the first argument used to construct this error.'''
25+
return self.args[0]
26+
27+
28+
class Uber(object):
29+
"""
30+
"""
31+
def __init__(self, **credentials):
32+
self.url = BASE_URL
33+
self.server_token = credentials.get('SERVER_TOKEN')
34+
self.user_token = credentials.get('user_token')
35+
print self.url
36+
37+
38+
def authenticate(self, bearer=False, user_token=''):
39+
'''
40+
returns authentication header
41+
'''
42+
if bearer:
43+
request_headers = dict(Authorization='Bearer {}'.format(
44+
self.user_token))
45+
else:
46+
request_headers = dict(Authorization='Token {}'.format(
47+
self.server_token))
48+
return request_headers
49+
50+
51+
def validate_response(self, resp):
52+
'''
53+
validates response from Uber API.
54+
No action if status code is 200
55+
Else, raise custom exception
56+
'''
57+
msg = "Unexpected response - HTTP:{} - payload: {}".format(
58+
resp.status_code, resp.content)
59+
if resp.status_code not in (200, 202):
60+
# 202 for Request
61+
raise UberApiError(msg)
62+
63+
64+
def get_products(self, latitude, longitude):
65+
'''
66+
returns information about the Uber products offered at a
67+
given location
68+
'''
69+
url = self.url + '/products'
70+
params = dict(latitude=latitude,
71+
longitude=longitude)
72+
resp = requests.get(url, data=params, headers=self.authenticate())
73+
self.validate_response(resp)
74+
return json.loads(resp.content)
75+
76+
77+
def get_product(self, product_id):
78+
'''
79+
return individual product details
80+
'''
81+
url = self.url + '/products/{}'.format(str(product_id))
82+
params = dict(product_id=product_id)
83+
resp = requests.get(url, data=params, headers=self.authenticate())
84+
self.validate_response(resp)
85+
return json.loads(resp.content)
86+
87+
88+
def get_price_estimate(self, start, end):
89+
'''
90+
returns an estimated price range for each product
91+
offered at a given location
92+
93+
@param start <dict> contains keys: `latitude` and `longitude`
94+
@param end <dict> contains keys: `latitude` and `longitude`
95+
'''
96+
try:
97+
assert isinstance(start, dict)
98+
assert isinstance(end, dict)
99+
assert 'latitude' in start
100+
assert 'longitude' in start
101+
assert 'latitude' in end
102+
assert 'longitude' in end
103+
except AssertionError:
104+
raise UberApiError("Incorrect request parameters - "
105+
"start: {} - end: {}".format(start, end))
106+
url = self.url + '/estimates/price'
107+
params = dict(start_latitude=start.get('latitude'),
108+
start_longitude=start.get('longitude'),
109+
end_latitude=end.get('latitude'),
110+
end_longitude=end.get('longitude'))
111+
url = url + '?%s' % urllib.urlencode(params)
112+
resp = requests.get(url, headers=self.authenticate())
113+
self.validate_response(resp)
114+
return json.loads(resp.content)
115+
116+
117+
def get_time_estimate(self, start, customer_id=None, product_id=None):
118+
'''
119+
returns ETAs for all products offered at a given location
120+
121+
@param start <dict> contains keys: `latitude` and `longitude`
122+
@param customer_id <str> Optional
123+
@param product_id <str> Optional
124+
'''
125+
try:
126+
assert isinstance(start, dict)
127+
assert 'latitude' in start
128+
assert 'longitude' in start
129+
except AssertionError:
130+
raise UberApiError("Incorrect request parameters - "
131+
"start: {} - end: {}".format(start, end))
132+
url = self.url + '/estimates/time'
133+
params = dict(start_latitude=start.get('latitude'),
134+
start_longitude=start.get('longitude'))
135+
if customer_id:
136+
params['customer_uuid'] = str(customer_id)
137+
if product_id:
138+
params['product_id'] = str(product_id)
139+
url = url + '?%s' % urllib.urlencode(params)
140+
resp = requests.get(url, headers=self.authenticate())
141+
self.validate_response(resp)
142+
return json.loads(resp.content)
143+
144+
145+
def get_promotions(self, start={}, end={}):
146+
'''
147+
returns information about the promotion that will be
148+
available to a new user based on their activity's location
149+
150+
@param start <dict> contains keys: `latitude` and `longitude`
151+
@param end <dict> contains keys: `latitude` and `longitude`
152+
153+
At least one valid set of coordinates is required.
154+
'''
155+
try:
156+
assert (isinstance(start.get('latitude'), float) and\
157+
isinstance(start.get('longitude'), float)) or\
158+
(isinstance(end.get('latitude'), float) and\
159+
isinstance(end.get('longitude'), float))
160+
except AssertionError:
161+
raise UberApiError("Incorrect parameters - start: {} - end: {}".format(start, end))
162+
url = self.url + '/promotions'
163+
164+
params = dict(start_latitude=start.get('latitude'),
165+
start_longitude=start.get('longitude'),
166+
end_latitude=end.get('latitude'),
167+
end_longitude=end.get('longitude'))
168+
url = url + '?%s' % urllib.urlencode(params)
169+
resp = requests.get(url, headers=self.authenticate())
170+
self.validate_response(resp)
171+
return json.loads(resp.content)
172+
173+
174+
def get_profile(self,):
175+
try:
176+
url = self.url + '/me'
177+
resp = requests.get(url, headers=self.authenticate(bearer=True))
178+
self.validate_response(resp)
179+
return json.loads(resp.content)
180+
except Exception, err:
181+
error = 'cannot get profile - {}'.format(str(err))
182+
raise UberApiError(error)
183+
184+
185+
def request(self, product_id, start, end):
186+
'''
187+
allows a ride to be requested on behalf of an Uber user
188+
given their desired product, start, and end locations
189+
190+
@param product_id <str> product requested
191+
@param start <dict> contains keys: `latitude` and `longitude`
192+
@param end <dict> contains keys: `latitude` and `longitude`
193+
'''
194+
try:
195+
assert isinstance(start, dict)
196+
assert isinstance(end, dict)
197+
assert 'latitude' in start
198+
assert 'longitude' in start
199+
assert 'latitude' in end
200+
assert 'longitude' in end
201+
202+
url = self.url + '/requests'
203+
params = dict(product_id=str(product_id),
204+
start_latitude=start.get('latitude'),
205+
start_longitude=start.get('longitude'),
206+
end_latitude=end.get('latitude'),
207+
end_longitude=end.get('longitude'))
208+
request_headers = self.authenticate(bearer=True)
209+
request_headers['Content-Type'] = 'application/json'
210+
resp = requests.post(url, data=json.dumps(params),
211+
headers=request_headers)
212+
self.validate_response(resp)
213+
return json.loads(resp.content)
214+
215+
except AssertionError:
216+
raise UberApiError("Incorrect request parameters - "
217+
"start: {} - end: {}".format(start, end))
218+
219+
except Exception, err:
220+
error = 'Uber.request() fail - {}'.format(str(err))
221+
raise UberApiError(error)
222+
223+
224+
def request_details(self, request_id):
225+
'''
226+
Get the real time status of an ongoing trip that was
227+
created using the Ride Request endpoint
228+
'''
229+
try:
230+
url = self.url + '/requests/{}'.format(str(request_id).strip())
231+
resp = requests.get(url, headers=self.authenticate(bearer=True))
232+
self.validate_response(resp)
233+
return json.loads(resp.content)
234+
235+
except Exception, err:
236+
error = 'Uber.request_details() fail - {}'.format(str(err))
237+
raise UberApiError(error)
238+
239+
def sandbox_modify_request(self, request_id, new_status):
240+
'''
241+
modifies the status of an ongoing sandbox Request
242+
243+
@param request_id <str> id of the request to modify
244+
@param status <str> status to modify to
245+
( see config for all possible values for `status` )
246+
'''
247+
try:
248+
url = self.url + '/sandbox/requests/{}'.format(request_id)
249+
status_update = dict(status=new_status)
250+
params = json.dumps(status_update)
251+
request_headers = self.authenticate(bearer=True)
252+
request_headers['Content-Type'] = 'application/json'
253+
resp = requests.put(url, data=params, headers=request_headers)
254+
if resp.status_code == 204:
255+
return True
256+
else:
257+
return False
258+
except Exception, err:
259+
error = 'SANDBOX: could not update request status - {}'.format(str(err))
260+
raise UberApiError(error)

__init__.py

Whitespace-only changes.

config.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# `env` toggles settings for dev / prod environments
3+
#
4+
env = 'dev' #prod
5+
6+
URL = dict(prod='https://api.uber.com/v1',
7+
dev='https://sandbox-api.uber.com/v1')
8+
BASE_URL = URL[env]
9+
10+
STATUS = {}
11+
STATUS['0'] = 'processing'
12+
STATUS['1'] = 'accepted'
13+
STATUS['2'] = 'arriving'
14+
STATUS['3'] = 'in_progress'
15+
STATUS['4'] = 'completed'
16+
STATUS['5'] = 'rider_canceled'
17+
STATUS['6'] = 'driver_canceled'
18+
STATUS['7'] = 'no_driver_available'

0 commit comments

Comments
 (0)