httplib.ResponseNotReady正在刷新访问令牌时;

时间:2017-09-21 18:54:27

标签: python python-2.7 web2py httplib google-calendar-api

我的任务是在客户的网站上实施Google日历 - 他们希望能够从已登录的Google帐户中选择可用的日历,查看/添加/编辑/删除活动。

我已经关注了https://developers.google.com/api-client-library/python/auth/web-app示例(虽然我使用的是web2py框架,但它非常相似)

首先 - 在我的本地机器上一切正常; 其次 - 一切工作正常一小时(很少多一点),然后休息,然后在生产服务器上再次开始工作;

我正在将凭据存储到数据库中(在我(希望)完成此操作后,我将致力于保护/加密数据)我的代码是这样的:

# just to show what "user.auth_user.google_credentials" is, from another function, where I do the oauth2callback stuff, and store it to the database
def oauth2callback():
    ...
    auth_code = request.vars['code']
    credentials = auth_flow.step2_exchange(auth_code)
    db(db.auth_user.id == auth.user_id).update(google_credentials=credentials.to_json())
    redirect(URL(..))

# where it starts to fall apart
credentials = client.OAuth2Credentials.from_json(user.auth_user.google_credentials)
http_auth = credentials.authorize(httplib2.Http())  # fails here if access_token_expired

calendar_service = discovery.build('calendar', 'v3', http=http_auth, cache_discovery=False)
all_calendars = calendar_service.calendarList().list().execute()

user_info_service = discovery.build('oauth2', 'v2', http=http_auth, cache_discovery=False)
user_info = user_info_service.userinfo().get().execute()

然后我将一些数据返回到一个视图,在那里我生成一个选项框,其中选项是日历,在选择框更改事件上,我调用一个不同的函数,以获取所选日历的事件;

def get_google_calendar_events():
    user = db(db.auth_user.id == auth.user_id).select().first() # retrieve logged in user from db
    credentials = client.OAuth2Credentials.from_json(user.auth_user.google_credentials)
    http_auth = credentials.authorize(httplib2.Http()) # also fails here if access token expired
    calendar_id = request.vars.calendar_id  # e.x. "primary"
    calendar_service = discovery.build('calendar', 'v3', http=http_auth, cache_discovery=False)
    events = calendar_service.events().list(calendarId=calendar_id, ...).execute()  # I have more options here, but I doubt it's relevant, just min/max dates etc;
    # Then I do some parsing, and just return the events where I apply styles, javascript, etc.

我收到错误: httplib.py方法" getresponse"行~1025;

if self.__state != _CS_REQ_SENT or self.__response:
    raise ResponseNotReady()

我已经发现这是它失败的地方:

if self.__state != _CS_REQ_SENT
# in my case, all failed cases were:
"Idle" != "Request-sent"
# self.__response was (probably?) correctly None

我不知道从哪里开始调试"闲置" !="请求发送",也许有人知道?

正如我所说,这一切都在我的本地机器上运行,完美无缺; 有趣的是,如果我将服务器ssh隧道传输到localhost,它也可以完美运行。 一小时后,它开始提高这些异常,但几分钟后它可以开始工作〜再次Okayish,但有(似乎随机数量)的错误;

我没有卷曲的经验,也没有写我自己的请求,但此时我想考虑一下 - 是否可以用curl刷新access_token?

使用Javascript重写所有内容不是一种选择;

对不起这里的文字墙,我现在把头发拉了两天; 任何见解都非常赞赏!

P.S。我已经证明我有多个" discovery.build"一个动作中的方法 - 我尝试删除" user_info_service" - 无济于事,事实并非如此,我可能会对某些事情做错,这就是为什么我把它留在了片段中

1 个答案:

答案 0 :(得分:0)

找不到解决方案,Ipv6不是问题,有时只是套接字连接失败,“Errno 0:Error”

套接字正在被“包裹”?通过SSLSocket,有时在握手时失败,我把它包裹在一个愚蠢的尝试/除了块〜行140ish ssl.py python 2.7.3:

try:
   self.do_handshake()
except Exception, e:
   print 'handshake err: {0}\n'.format(e)

我得到:“握手错误:[Errno 0]错误” 我对这里实际做什么一无所知,因为do_handshake是编译C?