Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coinbase rate limits impact calls for arbitrarily large number of pages #389

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
458bce5
Request limit in paginated message
angelaponte Feb 18, 2020
11930c4
sleep_interval added to paginated calls
angelaponte Feb 18, 2020
1e463a5
Decreased performance penalty
angelaponte Feb 18, 2020
9e6c291
Added get_profile and get_profiles calls
angelaponte Apr 19, 2020
069cc43
Made sleep_interval a keyword argument
angelaponte Aug 15, 2020
55b48b2
Removed sleep_interval keyword parameters
angelaponte Aug 15, 2020
e697d11
Trying to handle exception in paginated generator
angelaponte Jan 13, 2021
1b40752
More pagination exceptions in generator
angelaponte Jan 13, 2021
6256edf
Sending troubleshooting output
angelaponte Jan 13, 2021
b07dfec
Fixed indentation issue in _send_paginated_message
angelaponte Jan 13, 2021
8f9e43a
Added more output to the exception
angelaponte Jan 13, 2021
a9827a2
Added check for empty result
angelaponte Jan 13, 2021
d270a98
Trying to remove empty results
angelaponte Jan 13, 2021
d8f9833
Added output every time I sleep
angelaponte Jan 13, 2021
b51ba2a
Flushed the print statements
angelaponte Jan 13, 2021
cb5fd1e
Added sleep higher up
angelaponte Jan 13, 2021
af70242
Is sleep_interval being passed?
angelaponte Jan 13, 2021
e7c0ace
Fixed the sleep code . . .
angelaponte Jan 13, 2021
a36c72a
Reinserted exception code
angelaponte Jan 13, 2021
f6a2162
Converted the generated result to a string
angelaponte Jan 13, 2021
ac09443
Removed exception and extra sleep calls
angelaponte Jan 13, 2021
97f53e4
How long do I sleep?
angelaponte Jan 13, 2021
5635e4c
Code cleanup for many pages of results
angelaponte Jan 13, 2021
ebb9ff3
Maybe the sleep works correctly now.
angelaponte Jan 13, 2021
de098e0
Moved the cast to a string to the results line
angelaponte Jan 13, 2021
216e221
Moved the cast to a string again
angelaponte Jan 13, 2021
eaa8429
Removed the string cast and added an empty yield
angelaponte Jan 13, 2021
bdc1067
Ugh!
angelaponte Jan 13, 2021
9925599
Back to casting the result to a string
angelaponte Jan 13, 2021
fdc3e68
Fixing cast to string
angelaponte Jan 13, 2021
7238b00
Removed the cast to a string
angelaponte Jan 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions cbpro/authenticated_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,45 @@ def get_account_holds(self, account_id, **kwargs):
endpoint = '/accounts/{}/holds'.format(account_id)
return self._send_paginated_message(endpoint, params=kwargs)

def get_profiles(self, **kwargs):
"""List Profiles

List all account profiles (also known as portfolios).

Returns:
[
{
"id": "86602c68-306a-4500-ac73-4ce56a91d83c",
"user_id": "5844eceecf7e803e259d0365",
"name": "default",
"active": true,
"is_default": true,
"created_at": "2019-11-18T15:08:40.236309Z"
}
]
"""
return self._send_message('get', '/profiles')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GET /profile has a parameter active so we should add some logic in case this parameter is provided (pass as keyword argument data to _send_message()


def get_profile(self, profile_id, **kwargs):
"""Get a Profile

Get a single profile by profile id.

Args:
profile_id(str): The profile id to get

Returns:
{
"id": "86602c68-306a-4500-ac73-4ce56a91d83c",
"user_id": "5844eceecf7e803e259d0365",
"name": "default",
"active": true,
"is_default": true,
"created_at": "2019-11-18T15:08:40.236309Z"
}
"""
return self._send_message('get', '/profile/' + profile_id)

def place_order(self, product_id, side, order_type, **kwargs):
""" Place an order.

Expand Down
10 changes: 8 additions & 2 deletions cbpro/public_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# For public requests to the Coinbase exchange

import requests

import time

class PublicClient(object):
"""cbpro public client API.
Expand Down Expand Up @@ -269,7 +269,7 @@ def _send_message(self, method, endpoint, params=None, data=None):
auth=self.auth, timeout=30)
return r.json()

def _send_paginated_message(self, endpoint, params=None):
def _send_paginated_message(self, endpoint, params=None, **kwargs):
""" Send API message that results in a paginated response.

The paginated responses are abstracted away by making API requests on
Expand All @@ -287,6 +287,7 @@ def _send_paginated_message(self, endpoint, params=None):
Args:
endpoint (str): Endpoint (to be added to base URL)
params (Optional[dict]): HTTP request parameters
sleep_interval (Optional[float]): Number of seconds to sleep between paginated calls

Yields:
dict: API response objects
Expand All @@ -306,6 +307,11 @@ def _send_paginated_message(self, endpoint, params=None):
# cbpro API doesn't support multiple pages in that case.
if not r.headers.get('cb-after') or \
params.get('before') is not None:
#If a sleep_interval was sent, use it
if "sleep_interval" in kwargs.keys():
time.sleep(sleep_interval)
break
else:
params['after'] = r.headers['cb-after']
if "sleep_interval" in kwargs.keys():
time.sleep(sleep_interval)