简体   繁体   English

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

[英]How to determine how many more requests my app can make before it hits the Twitter API's rate limit?

My application habitually makes a request to the Twitter API for a user's timeline (the user's tweets). 我的应用程序习惯性地向Twitter API请求用户的时间轴(用户的推文)。

As an aside, I'm using the twitter gem and configured a Twitter client in order to enable my app to make the request: 顺便说一句,我正在使用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 that I'm making a request to -- https://api.twitter.com/1.1/statuses/user_timeline.json -- has a rate limit of 900 requests every 15 minutes. 端点 -我正在做一个请求https://api.twitter.com/1.1/statuses/user_timeline.json -具有每15分钟900所请求的速率限制。

If I understand it correctly, there are 2 common ways to determine if my app has hit its rate limit -- but neither is what I need: 如果我正确理解它,可以通过两种常用方法确定我的应用是否达到了速率限制-但我都不需要:

First Approach: 第一种方法:

This is a function I wrote that attempts to make the request for a user's tweets, and if the app has it the rate limit, it'll raise an exception. 这是我写的一个函数,试图向用户发送tweet请求,如果应用程序具有速率限制,则会引发异常。

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

The problem with that approach is I'd like to find out how many more requests my app can safely make before I even make the request to the Twitter API. 这种方法的问题是,我想在我向Twitter API发出请求之前 ,找出我的应用程序可以安全发出的更多请求 I fear that this approach would have my app pinging the Twitter API long after it hit the rate limit, and that would open my app up to punitive actions by Twitter (like my app being blacklisted for instance.) 我担心这种方法会使我的应用在达到速率限制后很长一段时间就对Twitter API进行ping操作,这会使我的应用受到Twitter惩罚性行为的影响(例如,我的应用被列入黑名单)。

Second Approach The second approach is to make a request to this Twitter endpoint -- https://api.twitter.com/1.1/application/rate_limit_status.json -- that sends data back about where the application's status for a given rate limit. 第二种方法第二种方法是向该Twitter端点发出请求-https : https://api.twitter.com/1.1/application/rate_limit_status.json该请求将有关给定速率限制的应用程序状态的数据发送回去。

But again, this endpoint also has its own rate limit (180 requests every 15 minutes) -- which isn't very high. 但是同样,此端点也有自己的速率限制(每15分钟有180个请求)-并不是很高。 My app would blow past that limit. 我的应用程序将超过该限制。 In an ideal world, I would like to determine my app's current rate-limit status before I make a request to the API at all. 在理想的情况下,我想确定我的应用程序当前的限速状态,然后再向API提出请求。 And so: 所以:

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

I'm imagining I would have to increment some number that I've persisted to my database to keep track of requests to the API. 我在想我必须增加一些我坚持到数据库中的数字,以跟踪对API的请求。 Or is there an easier way? 还是有更简单的方法?

Edit 编辑

This is in response to Andy Piper's answer which I think is the simplest way to keep track of the remaining calls. 这是对安迪·派珀(Andy Piper)的回答的回应 ,我认为这是跟踪其余电话的最简单方法。

Assuming you're using this Twitter gem , it looks like each response from the gem will populate a Twitter::RateLimit object with the information from the rate limiting headers like Andy has suggested. 假设您正在使用此Twitter gem ,则好像来自该gem的每个响应都将使用Andy建议的速率限制标头中的信息填充Twitter::RateLimit对象

You should be able to access that information like this: 您应该能够像这样访问该信息:

tweets = CLIENT.user_timeline(twitter_handle)

remaining_calls = tweets.rate_limit.remaining

From there you can save that value to check it the next time you want to make a request. 您可以从那里保存该值,以在下次要发出请求时进行检查。 How you save it and check is up to you but the rest of my answer may still be useful for that. 如何保存和检查取决于您自己,但是我的其余回答可能仍然有用。


Note: I haven't tried this method before but it's one of the first things I would try in your situation if I didn't to permanently store request logs. 注意:我以前没有尝试过这种方法,但是如果我不永久存储请求日志,这是在您遇到的情况下要尝试的第一件事。

One way might to be to use Rails' built in Cache API . 一种方法可能是使用Rails内置的Cache API This will allow you to store any value you wish in a cache store which should be faster and lighter than a database. 这将允许您将所需的任何值存储在高速缓存存储中,该值应该比数据库更快更轻。

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

Let's break this down 让我们分解一下

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

  • The fetch method on Rails.cache will attempt to pull the value for the key twitter_requests . Rails.cache上的fetch方法将尝试提取键twitter_requests的值。
  • If the key doesn't exist, it will evaluate the block and set the return value as the key's new value and return that. 如果键不存在,它将评估该块并将返回值设置为键的新值,然后将其返回。 In this case, if the key twitter_requests doesn't exist, the new key value will be 0 . 在这种情况下,如果键twitter_requests不存在,则新键值将为0
  • The expires_in: 15.minutes option passed to the fetch method says to automatically clear this key ( twitter_requests ) every 15 minutes. 传递给fetch方法的expires_in: 15.minutes选项表示每15分钟自动清除一次此键( twitter_requests )。

Rails.cache.increment("twitter_requests") : Rails.cache.increment("twitter_requests")

  • Increments the value in the twitter_requests key by 1. twitter_requests键中的值增加1。

Notes 笔记

  • By default, Rails will use an in memory datastore. 默认情况下,Rails将使用内存数据存储。 This should work without issue but any values stored in the cache will be reset every time you restart the rails server. 这应该可以正常工作,但是每次重新启动Rails服务器时,存储在缓存中的所有值都会被重置。
  • The backend of the cache is configurable and can be changed to other popular systems (ie memcache, redis) but those will also need to be running and accessible by Rails. 缓存的后端是可配置的,可以更改为其他流行的系统(例如,memcache,redis),但这些也需要运行并可由Rails访问。
  • You may want to increment the cache before calling the API to reduce the chance of the cache expiring between when you checked it and when you increment it. 您可能需要在调用API之前增加缓存,以减少在检查缓存和递增缓存之间缓存过期的机会。 Incrementing a key that doesn't exist will return nil . 增加不存在的键将返回nil

I can't speak for the gem you are using, but a way to track your request limits without having to additionally call the rate_limit_status endpoint is to examine the X-Rate-Limit-Remaining headers on each API call. 我不能说您正在使用的gem,但是无需额外调用rate_limit_status端点即可跟踪请求限制的一种方法是检查每个API调用X-Rate-Limit-Remaining标头 I don't know whether that data is available on the Ruby gem you're using, though. 不过,我不知道该数据是否在您使用的Ruby gem上可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM