如何确定我的应用程序在达到Twitter API速率限制之前可以提出多少请求?

问题描述 投票:0回答:2

我的应用程序习惯性地向Twitter API请求用户的时间线(用户的推文)。

顺便说一句,我正在使用twitter gem并配置了一个Twitter客户端,以便让我的应用程序发出请求:

client = Twitter::REST::Client.new do |config|
  config.consumer_key        = ENV["TWITTER_CONSUMER_KEY"]
  config.consumer_secret     = ENV["TWITTER_CONSUMER_SECRET"]
  config.access_token        = ENV["TWITTER_ACCESS_TOKEN"]
  config.access_token_secret = ENV["TWITTER_ACCESS_TOKEN_SECRET"]
end

The endpoint,我正在向https://api.twitter.com/1.1/statuses/user_timeline.json提出请求 - 每15分钟有900个请求的速率限制。

如果我理解正确,有两种常用方法可以确定我的应用是否已达到其速率限制 - 但我不需要:

第一种方法:

这是我编写的一个函数,试图为用户的推文发出请求,如果应用程序有速率限制,它会引发异常。

def get_tweets_from_TwitterAPI(twitter_handle)
  tweets = []
  begin
    tweets = CLIENT.user_timeline(twitter_handle)
  rescue Twitter::Error::TooManyRequests => error
    raise error
  end
  return tweets
end

这种方法的问题是,我想知道在我向Twitter API发出请求之前,我的应用程序可以安全地发出多少请求。我担心这种方法会让我的应用程序在达到速率限制后很长时间内ping Twitter,这会让我的应用程序被Twitter打开惩罚性操作(比如我的应用程序被列入黑名单)。

第二种方法第二种方法是向this Twitter endpoint --https://api.twitter.com/1.1/application/rate_limit_status.json发出请求,该请求将数据发回给应用程序在给定速率限制下的状态。

但同样,这个端点也有自己的速率限制(每15分钟180个请求) - 这不是很高。我的应用程序将超过该限制。在理想的世界中,我想在向API发出请求之前确定我的应用程序的当前速率限制状态。所以:

def start_tweets_fetch
  number_of_requests_in_last_15 minutes = WHERE DO I GET THIS NUMBER FROM??
  if number_of_requests_in_last_15 minutes <= 900
    get_tweets_from_TwitterAPI(twitter_handle)
  end
end

我想我必须增加一些我坚持到我的数据库的数字来跟踪对API的请求。或者有更简单的方法吗?

ruby-on-rails rest twitter twitter-gem
2个回答
0
投票

我不能说你正在使用的gem,但是跟踪你的请求限制而不必另外调用rate_limit_status端点的方法是在每次API调用时使用examine the X-Rate-Limit-Remaining headers。不过,我不知道你正在使用的Ruby gem上是否有这些数据。


0
投票

Edit

这是对Andy Piper's answer的回应,我认为这是跟踪剩余呼叫的最简单方法。

假设您正在使用this Twitter gem,看起来像来自gem的每个响应将populate a Twitter::RateLimit object与来自速率限制标题的信息一样,如Andy建议的那样。

您应该能够访问这样的信息:

tweets = CLIENT.user_timeline(twitter_handle)

remaining_calls = tweets.rate_limit.remaining

从那里,您可以保存该值,以便在下次要求时进行检查。你如何保存和检查取决于你,但我的答案的其余部分可能仍然有用。


注意:我之前没有尝试过这种方法,但如果我不永久存储请求日志,那么这是我在你的情况下尝试的第一件事。

一种方法可能是使用在Cache API中构建的Rails。这将允许您在缓存存储中存储您希望的任何值,该缓存存储应该比数据库更快更轻。

number_of_requests_in_last_15 = Rails.cache.fetch("twitter_requests", expires_in: 15.minutes) { 0 }
if number_of_requests_in_last_15 minutes <= 900
  get_tweets_from_TwitterAPI(twitter_handle)
  Rails.cache.increment("twitter_requests")
end

让我们打破这个

Rails.cache.fetch("twitter_requests", expires_in: 15.minutes) { 0 }

  • fetch上的Rails.cache方法将尝试拉出关键twitter_requests的值。
  • 如果该键不存在,它将评估该块并将返回值设置为键的新值并返回该值。在这种情况下,如果密钥twitter_requests不存在,则新密钥值将为0
  • 传递给fetch方法的expires_in: 15.minutes选项表示每15分钟自动清除一次该密钥(twitter_requests)。

Rails.cache.increment("twitter_requests")

  • twitter_requests键中的值增加1。

笔记

  • 默认情况下,Rails将使用内存数据存储区。这应该没有问题,但每次重新启动rails服务器时都会重置存储在缓存中的任何值。
  • 缓存的后端是可配置的,可以更改为其他流行的系统(即memcache,redis),但这些也需要由Rails运行和访问。
  • 您可能希望在调用API之前增加缓存,以减少在检查缓存和增加缓存之间缓存过期的可能性。增加一个不存在的密钥将返回nil
© www.soinside.com 2019 - 2024. All rights reserved.