Skip to content
Open
Changes from all commits
Commits
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
41 changes: 40 additions & 1 deletion ph_py/product_hunt_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .helpers import parse_notifications
from .helpers import parse_related_links
from simplejson.scanner import JSONDecodeError
import time


class ProductHuntClient:
Expand All @@ -26,8 +27,34 @@ def __init__(self, client_id, client_secret, redirect_uri, dev_token=None):
else:
self.user_auth = None

# Rate limit information recovered from the header
self._rate_lim_limit = 900
self._rate_lim_remaining = 900
self._rate_lim_reset = 15*60

self.client_auth = self.oauth_client_token()

def get_rate_limits(self):
"""Return the three rate limit headers from the last request made

Returns
-------
rate_lim_limit: float
The application limit for the 15 minute period
rate_lim_remaining: float
Remaining allowed requests for the reset period
rate_lim_reset: float
Seconds until the rate limit is reset
"""
return self._rate_lim_limit, self._rate_lim_remaining, \
self._rate_lim_reset

def wait_if_no_rate_limit_remaining(self):
if self._rate_lim_remaining <= 0:
print("Waiting {:d} seconds until next request".format(
self._rate_lim_reset))
time.sleep(self._rate_lim_reset)

def build_header(self, context):
if context == "client":
if self.client_auth is None:
Expand All @@ -40,6 +67,16 @@ def build_header(self, context):

return {"Authorization": "Bearer %s" % self.user_auth["access_token"]}

def _update_time_limits(self, headers):
if headers:
if 'X-Rate-Limit-Limit' in headers:
self._rate_lim_limit = int(headers['X-Rate-Limit-Limit'])
if 'X-Rate-Limit-Remaining' in headers:
self._rate_lim_remaining = int(
headers['X-Rate-Limit-Remaining'])
if 'X-Rate-Limit-Reset' in headers:
self._rate_lim_reset = int(headers['X-Rate-Limit-Reset'])

def make_request(self, method, route, data, context="", retry=False):
url = self.API_BASE + route

Expand All @@ -56,6 +93,8 @@ def make_request(self, method, route, data, context="", retry=False):
elif method == "DELETE":
response = r.delete(url, headers=headers, params=data)

self._update_time_limits(response.headers)

try:
json_data = response.json()
if response.status_code in self.ERROR_CODES:
Expand Down Expand Up @@ -114,9 +153,9 @@ def get_previous_days_posts(self, days_ago, context="client"):
def get_specific_days_posts(self, day, context="client"):
responses = self.make_request("GET", "posts", {"day": day}, context)
responses = responses["posts"]

return parse_posts(responses)


def get_details_of_post(self, post_id, context="client"):
post = self.make_request("GET", "posts/%d" % post_id, None, context)
return parse_posts(post["post"])
Expand Down