Skip to content

Commit 34111e4

Browse files
committed
Merge pull request #8 from Staffjoy/avoid-ratelimit
Pace requests to avoid rate limits
2 parents ea6619d + 87f0e81 commit 34111e4

4 files changed

Lines changed: 18 additions & 2 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ Authentication keys are currently tied to an individual user's account. To issue
2020

2121
To get your organization ID, look at the URL path when you go to the Manager app while logged in.
2222

23+
## Rate Limits
24+
25+
This client sleeps for .5 seconds after every request. Thus, in a single thread, requests are limited to 120 per minute. This is done to avoid rate limiting. Staffjoy's API currently rate limits to 300 requests per second across keys and IPs. Thus, by using this library, you should never encounter a rate limit (assuming one executing thread per IP address).
26+
2327
## Updates
2428

2529
If you use this library, please subscribe to the [Staffjoy API Updates Google Group](https://groups.google.com/forum/#!forum/staffjoy-api-updates) for important notifications about changes and deprecations.
@@ -62,4 +66,3 @@ loc.delete()
6266
```
6367

6468

65-

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from setuptools import setup, find_packages
22

3-
version = "0.13"
3+
version = "0.14"
44
setup(name="staffjoy",
55
packages=find_packages(),
66
version=version,

staffjoy/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class DefaultConfig:
55
ENV = "prod"
66
LOG_LEVEL = logging.INFO
77
BASE = "https://www.staffjoy.com/api/v2/"
8+
REQUEST_SLEEP = 0.5
89

910

1011
class StageConfig(DefaultConfig):

staffjoy/resource.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import requests
2+
import time
23
from copy import copy
34

45
from .config import config_from_env
56
from .exceptions import UnauthorizedException, NotFoundException, BadRequestException
67

78

89
class Resource:
10+
# Seconds to sleep between requests (bc of rate limits)
11+
REQUEST_SLEEP = 0.5
12+
913
PATH = "" # URL path added to base, including route variables
1014
ID_NAME = None # What is this ID called in the route of children?
1115
META_ENVELOPES = [] # Metadata keys for what to unpack from response
@@ -70,6 +74,7 @@ def get_all(cls, parent=None, **params):
7074
r = requests.get(base_obj._url(),
7175
auth=(base_obj.key, ""),
7276
params=params)
77+
time.sleep(cls.REQUEST_SLEEP)
7378

7479
if r.status_code not in cls.TRUTHY_CODES:
7580
return base_obj._handle_request_exception(r)
@@ -117,6 +122,8 @@ def _handle_request_exception(request):
117122
def fetch(self):
118123
"""Perform a read request against the resource"""
119124
r = requests.get(self._url(), auth=(self.key, ""))
125+
time.sleep(self.REQUEST_SLEEP)
126+
120127
if r.status_code not in self.TRUTHY_CODES:
121128
return self._handle_request_exception(r)
122129

@@ -138,12 +145,16 @@ def delete(self):
138145
"""Delete the object"""
139146

140147
r = requests.delete(self._url(), auth=(self.key, ""))
148+
time.sleep(self.REQUEST_SLEEP)
149+
141150
if r.status_code not in self.TRUTHY_CODES:
142151
return self._handle_request_exception(r)
143152

144153
def patch(self, **kwargs):
145154
"""Change attributes of the item"""
146155
r = requests.patch(self._url(), auth=(self.key, ""), data=kwargs)
156+
time.sleep(self.REQUEST_SLEEP)
157+
147158
if r.status_code not in self.TRUTHY_CODES:
148159
return self._handle_request_exception(r)
149160

@@ -165,6 +176,7 @@ def create(cls, parent=None, **kwargs):
165176
obj = cls(key=parent.key, route=route, config=parent.config)
166177

167178
response = requests.post(obj._url(), auth=(obj.key, ""), data=kwargs)
179+
time.sleep(cls.REQUEST_SLEEP)
168180

169181
if response.status_code not in cls.TRUTHY_CODES:
170182
return cls._handle_request_exception(response)

0 commit comments

Comments
 (0)