user1048839
user1048839

Reputation: 958

Retrieve data with Uber Rides Python SDK fails with 500 error

Having followed this tutorial https://developer.uber.com/docs/riders/ride-requests/tutorials/api/python , I'm getting errors when trying to fetch data such as user profile or activity.

Here is my sample(Flask) code:

import os
from datetime import datetime
from flask import Flask, request, flash, url_for, redirect, \
     render_template, abort, send_from_directory, redirect

from uber_rides.auth import AuthorizationCodeGrant
from uber_rides.session import Session
from uber_rides.client import UberRidesClient

app = Flask(__name__)
app.config.from_pyfile('flaskapp.cfg')

# Configure Uber Oauth2.0
auth_flow = AuthorizationCodeGrant(
    '<client_id>',
    ['profile', 'history'],
    '<client_secret>',
    'http://localhost:8080/callback'
    )

@app.route('/')
def index():
    auth_url = auth_flow.get_authorization_url()
    return redirect(auth_url, code=302)

@app.route('/callback')
def callback():
    session = auth_flow.get_session(request.url)
    client = UberRidesClient(session)
    credentials = session.oauth2credential

    # Fetch users profile
    response = client.get_user_profile()
    profile = response.json

    first_name = profile.get('first_name')
    last_name = profile.get('last_name')
    email = profile.get('email')

    # Fetch user activity
    response = client.get_user_activity()
    history = response.json

    return first_name, 200

if __name__ == '__main__':
    app.run(debug=True)

And trace of errors:

Starting WSGIServer type flask on 127.0.0.1:8080 ...
 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
127.0.0.1 - - [11/Jan/2017 21:11:53] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [11/Jan/2017 21:12:09] "GET /callback?state=VFI3w30Haz5MUb1jvaLxDsCdMduVedLv&code=NSol8RDwh5zbLYL4ef0U96ePjsZZ6l HTTP/1.1" 500 -
Error on request:
Traceback (most recent call last):
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/werkzeug/serving.py", line 205, in run_wsgi
    execute(self.server.app)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/werkzeug/serving.py", line 193, in execute
    application_iter = app(environ, start_response)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1994, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/crazywizard/Documents/uber/flaskapp.py", line 41, in callback
    response = client.get_user_activity()
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/uber_rides/client.py", line 260, in get_user_activity
    return self._api_call('GET', 'v1.2/history', args=args)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/uber_rides/client.py", line 104, in _api_call
    return request.execute()
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/uber_rides/request.py", line 152, in execute
    return self._send(prepared_request)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/uber_rides/request.py", line 136, in _send
    response = session.send(prepared_request)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/requests/sessions.py", line 615, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/Users/crazywizard/Documents/uber/venv/lib/python2.7/site-packages/uber_rides/utils/handlers.py", line 63, in error_handler
    raise ServerError(response, error_message)
ServerError: 500: We have experienced a problem.

Could this be a problem with Uber's service?

Update: Debug trace on requests.

Starting WSGIServer type flask on 127.0.0.1:8080 ...
INFO:werkzeug: * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
INFO:werkzeug:127.0.0.1 - - [15/Jan/2017 18:58:09] "GET / HTTP/1.1" 302 -
DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): login.uber.com
DEBUG:requests.packages.urllib3.connectionpool:https://login.uber.com:443 "POST /oauth/token HTTP/1.1" 200 None
INFO:werkzeug:127.0.0.1 - - [15/Jan/2017 18:58:19] "GET /callback?state=z9ga01Y6kgNFRbgDbeEA3IjCYLMTnI7M&code=wwTzfIbFivsCoGE4RIu0rDb2fO22NI HTTP/1.1" 200 -
DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sandbox-api.uber.com
DEBUG:requests.packages.urllib3.connectionpool:https://sandbox-api.uber.com:443 "GET /v1.2/me HTTP/1.1" 500 75
INFO:werkzeug:127.0.0.1 - - [15/Jan/2017 18:58:35] "GET /profile HTTP/1.1" 500 -
ERROR:werkzeug:Error on request:

UPDATE 2: Requests module logging

Starting WSGIServer type flask on 127.0.0.1:8080 ...
INFO:werkzeug: * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
^C(venv) Davids-MacBook-Pro:uber crazywizard$ clear
(venv) Davids-MacBook-Pro:uber crazywizard$ python app.py
Starting WSGIServer type flask on 127.0.0.1:8080 ...
INFO:werkzeug: * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
INFO:werkzeug:127.0.0.1 - - [17/Jan/2017 22:35:04] "GET / HTTP/1.1" 302 -
DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): login.uber.com
send: 'POST /oauth/token HTTP/1.1\r\nHost: login.uber.com\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.12.4\r\nContent-Length: 217\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\ncode=Mg1VBWKR0V0ioeLYTAv61pAbjy3WD4&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fcallback&client_id=xxx&client_secret=xxx&grant_type=authorization_code'
reply: 'HTTP/1.1 200 OK\r\n'
header: Server: nginx
header: Date: Tue, 17 Jan 2017 19:35:08 GMT
header: Content-Type: application/json
header: Transfer-Encoding: chunked
header: Connection: keep-alive
header: Pragma: no-cache
header: Cache-Control: no-store
header: Set-Cookie: session=ab5c70960ceb1415_587e71ec.pJiJyH80bf4wULzs_NpDCMc-Ymw; Domain=login.uber.com; Secure; HttpOnly; Path=/
header: X-Uber-App: login
header: Strict-Transport-Security: max-age=604800
header: X-Content-Type-Options: nosniff
header: X-XSS-Protection: 1; mode=block
header: Strict-Transport-Security: max-age=2592000
header: X-Frame-Options: SAMEORIGIN
header: Cache-Control: max-age=0
header: Content-Encoding: gzip
DEBUG:requests.packages.urllib3.connectionpool:https://login.uber.com:443 "POST /oauth/token HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): sandbox-api.uber.com
send: 'GET /v1/products?latitude=37.77&longitude=-122.41 HTTP/1.1\r\nHost: sandbox-api.uber.com\r\nAccept-Encoding: identity\r\nX-Uber-User-Agent: Python Rides SDK v0.2.7\r\nAuthorization: Bearer xxx\r\n\r\n'
reply: 'HTTP/1.1 500 Internal Server Error\r\n'
header: Server: nginx
header: Date: Tue, 17 Jan 2017 19:35:09 GMT
header: Content-Type: application/json
header: Content-Length: 75
header: Connection: keep-alive
header: X-Uber-App: uberex-sandbox
header: X-Uber-App: migrator-uberex-sandbox-optimus
header: Strict-Transport-Security: max-age=604800
header: X-Content-Type-Options: nosniff
header: X-XSS-Protection: 1; mode=block
DEBUG:requests.packages.urllib3.connectionpool:https://sandbox-api.uber.com:443 "GET /v1/products?latitude=37.77&longitude=-122.41 HTTP/1.1" 500 75
INFO:werkzeug:127.0.0.1 - - [17/Jan/2017 22:35:10] "GET /callback?state=dH1nnut35q9xcOdC3W9a1lFKNqGXn9h5&code=Mg1VBWKR0V0ioeLYTAv61pAbjy3WD4 HTTP/1.1" 500 -
ERROR:werkzeug:Error on request:

Update 3: I have dug into the rides_python_sdk and added extra headers as shown in the docs https://developer.uber.com/docs/riders/ride-requests/tutorials/api/curl#get-a-list-of-products-available

I also corrected the Accept-Encoding param to what is in the sdk ['gzip, deflate']

Still getting the 500 error

DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): api.uber.com
send: 'GET /v1.2/products?latitude=37.77&longitude=-122.41 HTTP/1.1\r\nHost: api.uber.com\r\nAccept-Language: en_EN\r\nX-Uber-User-Agent: Python Rides SDK v0.3.1\r\nContent-Type: application/json\r\nAccept-Encoding: gzip, deflate\r\nAuthorization: Bearer ppdHHakR8EQL09kpAIrPYkDCAWFHQT\r\n\r\n'
reply: 'HTTP/1.1 500 Internal Server Error\r\n'
header: Server: nginx
header: Date: Wed, 18 Jan 2017 09:46:04 GMT
header: Content-Type: application/json
header: Content-Length: 75
header: Connection: keep-alive
header: X-Uber-App: uberex-nonsandbox
header: X-Uber-App: migrator-uberex-optimus
header: Strict-Transport-Security: max-age=604800
header: X-Content-Type-Options: nosniff
header: X-XSS-Protection: 1; mode=block

Upvotes: 0

Views: 544

Answers (2)

user1048839
user1048839

Reputation: 958

I had to use another oauth lib(flask_oauthlib).

import os, requests, logging
import httplib as http_client
from datetime import datetime
from flask import Flask, request, flash, url_for, redirect

from flask_oauthlib.client import OAuth
from flask import session, redirect

app = Flask(__name__)
app.config.from_pyfile('flaskapp.cfg')

http_client.HTTPConnection.debuglevel = 1
logging.basicConfig(level=logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

oauth = OAuth()
uber_app = oauth.remote_app(
        'uber',
        request_token_url=None,
        access_token_url='https://login.uber.com/oauth/v2/token',
        authorize_url='https://login.uber.com/oauth/v2/authorize',
        consumer_key='<client_id>',
        consumer_secret='<client_secret>'
    )

@app.route('/')
def index():
    #Make call to Uber service to retrieve products
    headers = {'Authorization' : 'Bearer '+session['uber_token'][0]}
    url = "https://api.uber.com/v1.2/"
    response_profile = requests.get(url+'me', headers=headers)
    response_history = requests.get(url+'history', headers=headers)

    return "<h3>Profile</h3><p>"+response_profile.content+"<h3>History</h3>"+response_history.content, 200

@uber_app.tokengetter
def get_uber_token(token=None):
    return session.get('uber_token')

@app.route('/login')
def login():
    return uber_app.authorize(callback=url_for('oauth_authorized', _external=True,
        next=request.args.get('next') or request.referrer or None))

@app.route('/oauth-authorized')
def oauth_authorized():
    next_url = request.args.get('next') or url_for('index')
    resp = uber_app.authorized_response()
    if resp is None:
        flash(u'You denied the request to sign in.')
        return redirect(next_url)

    session['uber_token'] = (
        resp['access_token'],
        resp['refresh_token']
    )

    flash('You were signed in')
    return redirect(next_url)

if __name__ == '__main__':
    app.run(debug=True)
  1. First create an oauth instance and assign params into the the remote_app method.

Note: oauth2.0 does NOT have request_token_url, so set this to None.

  1. The get_uber_token method creates a global session to store your tokens which can be accessed from anywhere else in the code.

  2. /login redirects the user to the Uber login page. As part of the url is a redirect uri that Uber will make callbacks to your service with.

Note: make sure to add _external=True param in the url_for method so as to generate an absolute url that is need by the uber service for the callback.

  1. 'oauth_authorized' method and endpoint handle the redirections from the Uber service after the authorization phase. Remember to get and store the two important tokens that you'll need later; access_token and refresh_token

  2. In the index method where it ultimately redirects to after the authorization is successful, I've made a few calls to fetch the profile and rider history for demonstration. Take heed of the headers sent.

Note: Beware that the Bearer token expires after about 10mins and you'll there after need the refresh token to request another bearer token. The logging here just sets everything to DEBUG level so you can see what's being sent down the wire.

Upvotes: 0

Dustin Whittle
Dustin Whittle

Reputation: 1252

Thanks for your patience while I investigated this issue. This was an underlying bug in our v1 oauth endpoints which impacted newly created applications. I have released a new version of the sdk that resolves this problem. Please use v0.4.0 and you should not have any issues. Thanks for the detailed feedback!

Upvotes: 1

Related Questions