This repository has been archived by the owner on Jan 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 630
Add pagination and ratelimit support for responses from Instagram #76
Open
weyus
wants to merge
6
commits into
facebookarchive:master
Choose a base branch
from
weyus:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f84b520
Allow for pagination results to be requested from a given Instagram::…
4c9bdf9
Remove unnecessary regex interpolation.
3969d3d
Use class method to get Instagram client object instead of direct ins…
fb48951
Return an empty array to conform with initialization of Response object.
e82f64e
Fix test.
9d2fec8
Add ratelimit header information to every normal Instagram response.
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,29 @@ | ||
module Instagram | ||
module Response | ||
def self.create( response_hash ) | ||
def self.create( response_hash, ratelimit_hash ) | ||
data = response_hash.data.dup rescue response_hash | ||
data.extend( self ) | ||
data.instance_exec do | ||
@pagination = response_hash.pagination | ||
@meta = response_hash.meta | ||
@ratelimit = ::Hashie::Mash.new(ratelimit_hash) | ||
end | ||
data | ||
end | ||
|
||
def next | ||
if pagination.next_url | ||
client = Instagram.client(Instagram.options) | ||
pagination.next_url.sub!('http://', 'https://') #Make the URL secure if it isn't already | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really a problem? Aren't all of the API methods limited to https? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The next URLs that were returned to me in result sets were 'http'. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😞 |
||
response = client.get(pagination.next_url.sub(Instagram.endpoint, ''), {}, false, true) | ||
response | ||
else | ||
[] | ||
end | ||
end | ||
|
||
attr_reader :pagination | ||
attr_reader :meta | ||
attr_reader :ratelimit | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"pagination": {}, "meta": {"code": 200}, "data": []} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
require File.expand_path('../../spec_helper', __FILE__) | ||
|
||
describe Instagram::Response do | ||
Instagram::Configuration::VALID_FORMATS.each do |format| | ||
context ".new(:format => '#{format}')" do | ||
before do | ||
@client = Instagram::Client.new(:format => format, :client_id => 'CID', :client_secret => 'CS', :access_token => 'AT') | ||
end | ||
|
||
context 'to a standard request' do | ||
before do | ||
stub_get("users/4.#{format}"). | ||
with(:query => {:access_token => @client.access_token}). | ||
to_return(:body => fixture("mikeyk.#{format}"), :headers => {:content_type => "application/#{format}; charset=utf-8", | ||
'x-ratelimit-limit' => '5000', | ||
'x-ratelimit-remaining' => '4999'}) | ||
end | ||
|
||
it 'should provide rate limit information on every object returned' do | ||
user = @client.user(4) | ||
user.ratelimit.should_not be_nil | ||
user.ratelimit.limit.should == 5000 | ||
user.ratelimit.remaining.should == 4999 | ||
end | ||
end | ||
end | ||
end | ||
end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you feel this is less than ideal, in my opinion it is a deal-breaker.
Consider the use-case:
access_token
next
methodInstagram.options[:client_id]
or perhaps a default tokenInstagram.options[:access_token]
that does not have access to the protected contentThe client object will need to be passed to the response so it can be used again for the next page. I considered suggesting the parsing of the
next_url
param, but that solution is nearly as clunky since it doesn't accomodate for the client's connection parameters or other options unless they are baked into the::Instagram.options
singleton (which is a bad pattern in many applications).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused.
Instagram.options[:access_token]
is set upon the initial client creation, so wouldn't that be what is used for the call tonext
?Are you raising a case where there may be multiple Instagram clients acting in an application, each with their own access_token, and interleaving calls between them would cause problems?
Agreed that passing the client object is a better approach. I didn't want to "break" the current architecture, which is based on one-request/one-response. I couldn't come up with a seemingly good way to share the client object internally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use
Instagram::Client.new(options)
as our primary interface for creating a new client, and yes we use many clients with many access tokens in our application, avoiding theInstagram.options
defaults entirely. This enables us to use each client separately, concurrently in a threadsafe manner.In this case, you're already changing the API a bit by adding the non-optional
ratelimit_hash
param, so it's a good time to really take a look at it, to make sure that the changes we're introducing now make potential future changes simple to do without breaking interface.Since the response object is only ever created by a client request, its API isn't as critical as the public object-creators. In this case, I'd consider this as a possible new interface:
Also, why
Instagram::Response
is a module and not a class, especially since they bake in class-ish stuff on top of it with this::create
method is beyond me.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems much better. Agreed on Response being a class and not a module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(just a note that I'm not a maintainer, so you don't have to follow my suggestions; I just use this and many other API clients and therefore I Have Opinions 😸 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are good suggestions and I appreciate them.