如何在App Engine上使用PATCH方法和Python API Client Library for Python?

时间:2013-01-01 01:47:46

标签: python google-app-engine google-drive-api

我正在尝试使用Google API Client Library for Python来重命名驱动器文件,这里是重命名功能:

def rename_file(service, file_id, new_title):
"""Rename a file.

Args:
    service: Drive API service instance.
    file_id: ID of the file to rename.
    new_title: New title for the file.
Returns:
    Updated file metadata if successful, None otherwise.
"""
try:
    file = {'title': new_title}
    # Rename the file.
    updated_file = service.files().patch(
            fileId=file_id,
            body=file,
            fields='title').execute()
    return updated_file
except errors.HttpError, error:
    logging.error('An error occurred: %s' % error)
    return None

但是得到错误,这里是引用:

    Traceback (most recent call last):
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/myproduct/libs/oauth2client/appengine.py", line 469, in check_oauth
    return method(request_handler, *args, **kwargs)
  File "/myproduct/main.py", line 31, in get
    new_title="file new name")
  File "/myproduct/gapi.py", line 148, in rename_file
    fields='title').execute()
  File "/myproduct/libs/oauth2client/util.py", line 120, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/myproduct/libs/apiclient/http.py", line 676, in execute
    headers=self.headers)
  File "/myproduct/libs/oauth2client/util.py", line 120, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/myproduct/libs/oauth2client/client.py", line 420, in new_request
    redirections, connection_type)
  File "/myproduct/libs/httplib2/__init__.py", line 1588, in request
    (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
  File "/myproduct/libs/httplib2/__init__.py", line 1336, in _request
    (response, content) = self._conn_request(conn, request_uri, method, body, headers)
  File "/myproduct/libs/httplib2/__init__.py", line 1273, in _conn_request
    conn.request(method, request_uri, body, headers)
  File "/myproduct/libs/httplib2/__init__.py", line 1112, in request
    validate_certificate=self.validate_certificate)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/urlfetch.py", line 265, in fetch
    allow_truncated, follow_redirects, validate_certificate)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/urlfetch.py", line 286, in make_fetch_call
    raise InvalidMethodError('Invalid method %s.' % str(method))
InvalidMethodError: Invalid method PATCH.

那么我该如何直接使用rename_file函数呢?

1 个答案:

答案 0 :(得分:3)

如错误消息所示,PATCH尚不支持urlfetch,但已向App Engine团队提交了issue,且问题已得到确认。

与此同时,您可以修补httplib2以发送X-HTTP-METHOD-OVERRIDE标头,而不是使用PATCH方法,如filed针对{{1}所示}}

由于该补丁引用了一些旧代码,因此我在此提供了相关代码:

httplib2

由于UNAUTHORIZED_METHODS = ['patch'] HTTP_METHOD_OVERRIDE_HEADER = 'X-HTTP-Method-Override' HTTP_OVERRIDE_METHOD = 'POST' class AppEngineHttpConnection(httplib.HTTPConnection): ... def request(self, method, url, body=None, headers={}): if method.lower() in UNAUTHORIZED_METHODS: # No side-effects on provided headers. new_headers = {} new_headers.update(headers) new_headers[HTTP_METHOD_OVERRIDE_HEADER] = method method = HTTP_OVERRIDE_METHOD headers = new_headers super(AppEngineHttpConnection, self).request(method, url, body, headers) 现在只是request中定义的那个,我们可以在更改我们需要的一个标头时重复使用它。

httplib.HTTPConnection版本需要类似的覆盖,因为它不会从HTTPS继承。