- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用镜像 API 进行玻璃器皿项目。
我的应用类似于新闻应用,它会在文章发布时向所有订阅用户发送文章时间轴卡片。随着我的用户群的增长,这将成为一个问题,因为就目前的应用程序而言,它正在为每个文章卡片的每个用户进行一次 API 调用。根据用户的设置,我们每天最多可以发送 50 篇文章。考虑到 Google 每天只有 1000 次 Mirror API 调用的礼貌限制,我已经达到了只有 20 个用户的要求。我知道当我的应用程序获得批准后,这会增加,但我仍然想优化我的代码。
问题 1:我假设实现批处理会减少 API 调用的数量是否正确我在这里找不到答案:https://developers.google.com/glass/batch假设我进行单个批处理调用以将单个时间线项目发布到我用户的玻璃时间线中的 1000 个,这算作 1 个 Mirror API 请求还是 1000 个 Mirror API 请求?如果是后者,(问题 1.1)我假设批处理的唯一好处是减少我的应用程序的流量是否正确?
我遇到的问题是,如果用户在批处理运行时从 ( https://security.google.com/settings/security/permissions ) 撤消对我的应用程序的访问权限,则会引发异常并失败。它最终将用户(仍然具有权限)注销,并且他们被迫重新进行身份验证。根据我的测试,我认为它不会在整个批处理中失败,所以我不确定它是否将时间线卡发送给所有其他没有删除访问权限的用户。
目前,在没有批处理的情况下,我能够捕获此错误并在用户撤销访问权限时将其从我的数据库中删除。 问题 2:如何在我的代码中捕获此错误并确定它对应于哪个用户。示例代码如下:
def _insert_item_all_users(self):
"""Insert a timeline item to all authorized users."""
logging.info('Inserting timeline item to all users')
users = Credentials.all()
total_users = users.count()
if total_users > 10:
return 'Total user count is %d. Aborting broadcast to save your quota' % (
total_users)
body = {
'text': 'Hello Everyone!',
'notification': {'level': 'DEFAULT'}
}
batch_responses = _BatchCallback()
batch = BatchHttpRequest(callback = batch_responses.callback)
for user in users:
creds = StorageByKeyName(
Credentials, user.key().name(), 'credentials').get()
mirror_service = util.create_service('mirror', 'v1', creds)
batch.add(
mirror_service.timeline().insert(body = body),
request_id = user.key().name())
batch.execute(httplib2.Http())
return 'Successfully sent cards to %d users (%d failed).' % (
batch_responses.success, batch_responses.failure)
我得到的错误是这样的:
INFO 2014-01-15 22:42:06,031 client.py:699] Failed to retrieve access token: {
"error" : "invalid_grant"
}
访问 token 刷新失败并引发了 oauth2client.client.AccessTokenRefreshError
重现步骤:
应用项目日志
--Send timeline card to all users (before revoking access)
INFO 2014-01-15 22:41:41,217 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:41,217 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:41,217 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:41:41,999 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:41,999 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:41,999 client.py:680] Refreshing access_token
INFO 2014-01-15 22:41:42,519 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:42,519 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:42,521 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:42,521 appengine.py:265] get: Got type <class 'model.Credentials'>
INFO 2014-01-15 22:41:42,523 main_handler.py:275] Inserting timeline item to all users
INFO 2014-01-15 22:41:42,529 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:42,530 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:42,532 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:42,532 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:42,532 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:41:42,945 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/timeline?alt=json
INFO 2014-01-15 22:41:42,946 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:42,946 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:42,949 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:42,950 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:42,950 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:41:43,666 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/timeline?alt=json
WARNING 2014-01-15 22:41:43,666 util.py:125] execute() takes at most 1 positional argument (2 given)
INFO 2014-01-15 22:41:44,641 module.py:617] default: "POST / HTTP/1.1" 302 -
INFO 2014-01-15 22:41:44,648 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:44,648 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:44,649 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:41:45,092 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:45,093 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:45,093 client.py:680] Refreshing access_token
INFO 2014-01-15 22:41:45,841 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:41:45,841 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:45,842 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:41:45,843 appengine.py:265] get: Got type <class 'model.Credentials'>
INFO 2014-01-15 22:41:45,850 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/contacts/python-quick-start?alt=json
WARNING 2014-01-15 22:41:45,852 urlfetch_stub.py:482] Stripped prohibited headers from URLFetch request: ['content-length']
INFO 2014-01-15 22:41:46,472 main_handler.py:93] Unable to find Python Quick Start contact.
INFO 2014-01-15 22:41:46,492 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/timeline?maxResults=3&alt=json
WARNING 2014-01-15 22:41:46,494 urlfetch_stub.py:482] Stripped prohibited headers from URLFetch request: ['content-length']
INFO 2014-01-15 22:41:47,028 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/subscriptions?alt=json
WARNING 2014-01-15 22:41:47,031 urlfetch_stub.py:482] Stripped prohibited headers from URLFetch request: ['content-length']
INFO 2014-01-15 22:41:47,562 module.py:617] default: "GET / HTTP/1.1" 200 8163
INFO 2014-01-15 22:41:47,664 module.py:617] default: "GET /static/bootstrap/css/bootstrap-responsive.min.css HTTP/1.1" 304 -
INFO 2014-01-15 22:41:47,665 module.py:617] default: "GET /static/bootstrap/css/bootstrap.min.css HTTP/1.1" 304 -
INFO 2014-01-15 22:41:47,666 module.py:617] default: "GET /static/main.css HTTP/1.1" 304 -
INFO 2014-01-15 22:41:47,668 module.py:617] default: "GET /static/images/chipotle-tube-640x360.jpg HTTP/1.1" 304 -
INFO 2014-01-15 22:41:47,672 module.py:617] default: "GET /static/bootstrap/js/bootstrap.min.js HTTP/1.1" 304 -
--Send timeline card to all users (after revoking access)
INFO 2014-01-15 22:42:02,892 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:02,893 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:02,893 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:42:03,278 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:03,279 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:03,279 client.py:680] Refreshing access_token
INFO 2014-01-15 22:42:03,829 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:03,829 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:03,830 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:03,830 appengine.py:265] get: Got type <class 'model.Credentials'>
INFO 2014-01-15 22:42:03,834 main_handler.py:275] Inserting timeline item to all users
INFO 2014-01-15 22:42:03,844 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:03,844 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:03,846 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:03,847 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:03,847 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:42:04,270 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/timeline?alt=json
INFO 2014-01-15 22:42:04,271 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:04,271 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:04,275 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:04,276 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:04,276 discovery.py:190] URL being requested: https://www.googleapis.com/discovery/v1/apis/mirror/v1/rest?userIp=127.0.0.1
INFO 2014-01-15 22:42:04,705 discovery.py:709] URL being requested: https://www.googleapis.com/mirror/v1/timeline?alt=json
WARNING 2014-01-15 22:42:04,705 util.py:125] execute() takes at most 1 positional argument (2 given)
INFO 2014-01-15 22:42:05,531 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:05,531 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:05,532 client.py:680] Refreshing access_token
INFO 2014-01-15 22:42:06,031 client.py:699] Failed to retrieve access token: {
"error" : "invalid_grant"
}
INFO 2014-01-15 22:42:06,035 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:06,035 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:06,038 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:06,038 appengine.py:265] get: Got type <class 'model.Credentials'>
INFO 2014-01-15 22:42:06,043 appengine.py:276] make: Got type <class 'google.appengine.api.datastore_types.Blob'>
INFO 2014-01-15 22:42:06,043 appengine.py:289] validate: Got type <class 'oauth2client.client.OAuth2Credentials'>
INFO 2014-01-15 22:42:06,056 module.py:617] default: "POST / HTTP/1.1" 302 -
INFO 2014-01-15 22:42:06,066 module.py:617] default: "GET /auth HTTP/1.1" 302 -
最佳答案
两个问题的两个答案,收集 self 们在上面评论中讨论的内容。
没有。批处理中的 API 请求仍然算作一个完整的 API 请求。
批处理是为了提高性能。它减少了您必须打开的套接字数量并节省了带宽,尤其是当您使用 gzip 并将相同的有效负载发送给许多用户时。
如果您想要更多配额,请填写 Glassware submission form .即使您只需要更多配额来继续开发,也可以使用它。
如您所见,它是 a bug在 Python API 客户端库中。即使请求失败,它也应该调用您的回调。你像这样修补它:
--- /google-api-python-client-1ab344e0a34d/apiclient/http.py
+++ /google-api-python-client-patched/apiclient/http.py
@@ -50,7 +50,7 @@
from model import JsonModel
from oauth2client import util
from oauth2client.anyjson import simplejson
-
+from oauth2client.client import AccessTokenRefreshError
DEFAULT_CHUNK_SIZE = 512*1024
@@ -1299,10 +1299,13 @@
for request_id in self._order:
resp, content = self._responses[request_id]
if resp['status'] == '401':
- redo_order.append(request_id)
- request = self._requests[request_id]
- self._refresh_and_apply_credentials(request, http)
- redo_requests[request_id] = request
+ try:
+ request = self._requests[request_id]
+ self._refresh_and_apply_credentials(request, http)
+ redo_order.append(request_id)
+ redo_requests[request_id] = request
+ except AccessTokenRefreshError:
+ pass
if redo_requests:
self._execute(http, redo_order, redo_requests)
关于google-app-engine - 如果一个用户撤消访问权限,则对多个用户的批量请求会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21150275/
在为 Web 应用程序用例图建模时,为用户可以拥有的每个角色创建一个角色是否更好?或拥有一个角色、用户和一个具有特权的矩阵? guest < 用户 < 版主 < 管理员 1: guest 、用户、版主
我无法使用 Elixir 连接到 Postgres: ** (Mix) The database for PhoenixChat.Repo couldn't be created: FATAL 28P
这个问题已经有答案了: Group by field name in Java (7 个回答) 已关闭 7 年前。 我必须编写一个需要 List 的方法并返回 Map> . User包含 Person
感谢您的帮助,首先我将显示代码: $dotaz = "Select * from customers JOIN contracts where customers.user_id ='".$_SESS
我只想向所有用户中的一个用户显示一个按钮。我尝试了 orderByKey() 但没有成功! 用户模型有 id 成员,我尝试使用 orderByChild("id") 但结果相同! 我什至尝试了以下技巧
我们在工作中从 MongoDB 切换到 Postgres,我正在建立一个 BDR 组。 在这一步,我正在考虑安全性并尽可能锁定。因此,我希望设置一个 replication 用户(角色)并让 BDR
export class UserListComponent implements OnInit{ users; constructor(private userService: UserS
我可以使用 Sonata User Bundle 将 FOS 包集成到 sonata Admin 包中。我的登录功能正常。现在我想添加 FOSUserBundle 中的更改密码等功能到 sonata
在 LinkedIn 中创建新应用程序时,我得到 4 个单独的代码: API key 秘钥 OAuth 用户 token OAuth 用户密码 我在 OAuth 流程中使用前两个。 的目的是什么?最后
所以..我几乎解决了所有问题。但现在我要处理另一个问题。我使用了这个连接字符串: SqlConnection con = new SqlConnection(@"Data Source=.\SQLEX
我有一组“用户”和一组“订单”。我想列出每个 user_id 的所有 order_id。 var users = { 0: { user_id: 111, us
我已经为我的Django应用创建了一个用户模型 class User(Model): """ The Authentication model. This contains the u
我被这个问题困住了,找不到解决方案。寻找一些方向。我正在用 laravel 开发一个新的项目,目前正致力于用户认证。我正在使用 Laravels 5.8 身份验证模块。 对密码恢复 View 做了一些
安装后我正在使用ansible配置几台计算机。 为此,我在机器上本地运行 ansible。安装中的“主要”用户通常具有不同的名称。我想将该用户用于诸如 become_user 之类的变量. “主要”用
我正在尝试制作一个运行 syncdb 的批处理文件来创建一个数据库文件,然后使用用户名“admin”和密码“admin”创建一个 super 用户。 到目前为止我的代码: python manage.
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我已在 Azure 数据库服务器上设置异地复制。 服务器上运行的数据库之一具有我通过 SSMS 创建的登录名和用户: https://learn.microsoft.com/en-us/azure/s
我有一个 ionic 2 应用程序,正在使用 native FB Login 来检索名称/图片并将其保存到 NativeStorage。流程是我打开WelcomePage、登录并保存数据。从那里,na
这是我的用户身份验证方法: def user_login(request): if request.method == 'POST': username = request.P
我试图获取来自特定用户的所有推文,但是当我迭代在模板中抛出推文时,我得到“User”对象不可迭代 观看次数 tweets = User.objects.get(username__iexact='us
我是一名优秀的程序员,十分优秀!