使用Uber Rides Python SDK检索数据失败,出现500错误

时间:2017-01-11 18:15:10

标签: python uber-api

在完成本教程https://developer.uber.com/docs/riders/ride-requests/tutorials/api/python之后,我在尝试获取用户个人资料或活动等数据时遇到错误。

这是我的示例(Flask)代码:

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)

跟踪错误:

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.

这可能是优步服务的问题吗?

更新: 对请求进行调试跟踪。

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:

更新2:请求模块记录

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:

更新3: 我已经挖掘了rides_python_sdk并添加了额外的标题,如文档https://developer.uber.com/docs/riders/ride-requests/tutorials/api/curl#get-a-list-of-products-available

中所示

我还将Accept-Encoding参数更正为sdk ['gzip, deflate']

中的内容

仍然收到500错误

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

2 个答案:

答案 0 :(得分:1)

感谢您在调查此问题时的耐心等待。这是我们的v1 oauth端点中的一个潜在错误,它影响了新创建的应用程序。我发布了一个新版本的sdk来解决这个问题。请使用v0.4.0,您不应该有任何问题。感谢您提供详细的反馈!

答案 1 :(得分:0)

我不得不使用另一个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. 首先创建一个oauth实例并将params分配给remote_app方法。
  2. 注意: oauth2.0没有request_token_url,因此将其设置为None

    1. get_uber_token方法创建一个全局会话来存储您的令牌,可以从代码中的任何其他位置访问。

    2. /login将用户重定向到优步登录页面。网址的一部分是重定向uri,优步将使用它来回调您的服务。

    3. 注意:请务必在_external=True方法中添加url_for param,以便生成uber服务为回调所需的绝对网址。

      1. &#39; oauth_authorized&#39;方法和端点在授权阶段之后处理来自Uber服务的重定向。请记住获取并存储您以后需要的两个重要令牌; access_tokenrefresh_token

      2. 在授权成功后最终重定向到的index方法中,我已经拨打了一些电话来获取个人资料和车手历史记录以进行演示。注意发送的标题。

      3. 注意:请注意,承载令牌在大约10分钟后过期,并且您需要刷新令牌后才能请求另一个承载令牌。此处的日志记录只会将所有内容设置为DEBUG级别,以便您可以查看正在发送的内容。