parent
a1a4a4fd7f
commit
425bb809ed
@ -24,6 +24,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
@ -46,6 +47,8 @@ __all__ = (
|
|||||||
'Webhook',
|
'Webhook',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class WebhookAdapter:
|
class WebhookAdapter:
|
||||||
"""Base class for all webhook adapters.
|
"""Base class for all webhook adapters.
|
||||||
|
|
||||||
@ -182,7 +185,7 @@ class AsyncWebhookAdapter(WebhookAdapter):
|
|||||||
if payload:
|
if payload:
|
||||||
headers['Content-Type'] = 'application/json'
|
headers['Content-Type'] = 'application/json'
|
||||||
data = utils.to_json(payload)
|
data = utils.to_json(payload)
|
||||||
|
|
||||||
if reason:
|
if reason:
|
||||||
headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
|
headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
|
||||||
|
|
||||||
@ -194,11 +197,14 @@ class AsyncWebhookAdapter(WebhookAdapter):
|
|||||||
else:
|
else:
|
||||||
data.add_field(key, value)
|
data.add_field(key, value)
|
||||||
|
|
||||||
|
base_url = url.replace(self._request_url, '/') or '/'
|
||||||
|
_id = self._webhook_id
|
||||||
for tries in range(5):
|
for tries in range(5):
|
||||||
for file in files:
|
for file in files:
|
||||||
file.reset(seek=tries)
|
file.reset(seek=tries)
|
||||||
|
|
||||||
async with self.session.request(verb, url, headers=headers, data=data) as r:
|
async with self.session.request(verb, url, headers=headers, data=data) as r:
|
||||||
|
log.debug('Webhook ID %s with %s %s has returned status code %s', _id, verb, base_url, r.status)
|
||||||
# Coerce empty strings to return None for hygiene purposes
|
# Coerce empty strings to return None for hygiene purposes
|
||||||
response = (await r.text(encoding='utf-8')) or None
|
response = (await r.text(encoding='utf-8')) or None
|
||||||
if r.headers['Content-Type'] == 'application/json':
|
if r.headers['Content-Type'] == 'application/json':
|
||||||
@ -208,6 +214,7 @@ class AsyncWebhookAdapter(WebhookAdapter):
|
|||||||
remaining = r.headers.get('X-Ratelimit-Remaining')
|
remaining = r.headers.get('X-Ratelimit-Remaining')
|
||||||
if remaining == '0' and r.status != 429:
|
if remaining == '0' and r.status != 429:
|
||||||
delta = utils._parse_ratelimit_header(r)
|
delta = utils._parse_ratelimit_header(r)
|
||||||
|
log.debug('Webhook ID %s has been pre-emptively rate limited, waiting %.2f seconds', _id, delta)
|
||||||
await asyncio.sleep(delta)
|
await asyncio.sleep(delta)
|
||||||
|
|
||||||
if 300 > r.status >= 200:
|
if 300 > r.status >= 200:
|
||||||
@ -216,6 +223,7 @@ class AsyncWebhookAdapter(WebhookAdapter):
|
|||||||
# we are being rate limited
|
# we are being rate limited
|
||||||
if r.status == 429:
|
if r.status == 429:
|
||||||
retry_after = response['retry_after'] / 1000.0
|
retry_after = response['retry_after'] / 1000.0
|
||||||
|
log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds', _id, retry_after)
|
||||||
await asyncio.sleep(retry_after)
|
await asyncio.sleep(retry_after)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -271,13 +279,15 @@ class RequestsWebhookAdapter(WebhookAdapter):
|
|||||||
if payload:
|
if payload:
|
||||||
headers['Content-Type'] = 'application/json'
|
headers['Content-Type'] = 'application/json'
|
||||||
data = utils.to_json(payload)
|
data = utils.to_json(payload)
|
||||||
|
|
||||||
if reason:
|
if reason:
|
||||||
headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
|
headers['X-Audit-Log-Reason'] = _uriquote(reason, safe='/ ')
|
||||||
|
|
||||||
if multipart is not None:
|
if multipart is not None:
|
||||||
data = {'payload_json': multipart.pop('payload_json')}
|
data = {'payload_json': multipart.pop('payload_json')}
|
||||||
|
|
||||||
|
base_url = url.replace(self._request_url, '/') or '/'
|
||||||
|
_id = self._webhook_id
|
||||||
for tries in range(5):
|
for tries in range(5):
|
||||||
for file in files:
|
for file in files:
|
||||||
file.reset(seek=tries)
|
file.reset(seek=tries)
|
||||||
@ -290,6 +300,7 @@ class RequestsWebhookAdapter(WebhookAdapter):
|
|||||||
# compatibility with aiohttp
|
# compatibility with aiohttp
|
||||||
r.status = r.status_code
|
r.status = r.status_code
|
||||||
|
|
||||||
|
log.debug('Webhook ID %s with %s %s has returned status code %s', _id, verb, base_url, r.status)
|
||||||
if r.headers['Content-Type'] == 'application/json':
|
if r.headers['Content-Type'] == 'application/json':
|
||||||
response = json.loads(response)
|
response = json.loads(response)
|
||||||
|
|
||||||
@ -297,6 +308,7 @@ class RequestsWebhookAdapter(WebhookAdapter):
|
|||||||
remaining = r.headers.get('X-Ratelimit-Remaining')
|
remaining = r.headers.get('X-Ratelimit-Remaining')
|
||||||
if remaining == '0' and r.status != 429 and self.sleep:
|
if remaining == '0' and r.status != 429 and self.sleep:
|
||||||
delta = utils._parse_ratelimit_header(r)
|
delta = utils._parse_ratelimit_header(r)
|
||||||
|
log.debug('Webhook ID %s has been pre-emptively rate limited, waiting %.2f seconds', _id, delta)
|
||||||
time.sleep(delta)
|
time.sleep(delta)
|
||||||
|
|
||||||
if 300 > r.status >= 200:
|
if 300 > r.status >= 200:
|
||||||
@ -306,6 +318,7 @@ class RequestsWebhookAdapter(WebhookAdapter):
|
|||||||
if r.status == 429:
|
if r.status == 429:
|
||||||
if self.sleep:
|
if self.sleep:
|
||||||
retry_after = response['retry_after'] / 1000.0
|
retry_after = response['retry_after'] / 1000.0
|
||||||
|
log.warning('Webhook ID %s is rate limited. Retrying in %.2f seconds', _id, retry_after)
|
||||||
time.sleep(retry_after)
|
time.sleep(retry_after)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@ -409,22 +422,22 @@ class Webhook(Hashable):
|
|||||||
webhook.send('Hello World', username='Foo')
|
webhook.send('Hello World', username='Foo')
|
||||||
|
|
||||||
.. container:: operations
|
.. container:: operations
|
||||||
|
|
||||||
.. describe:: x == y
|
.. describe:: x == y
|
||||||
|
|
||||||
Checks if two webhooks are equal.
|
Checks if two webhooks are equal.
|
||||||
|
|
||||||
.. describe:: x != y
|
.. describe:: x != y
|
||||||
|
|
||||||
Checks if two webhooks are not equal.
|
Checks if two webhooks are not equal.
|
||||||
|
|
||||||
.. describe:: hash(x)
|
.. describe:: hash(x)
|
||||||
|
|
||||||
Returns the webhooks's hash.
|
Returns the webhooks's hash.
|
||||||
|
|
||||||
.. versionchanged:: 1.4
|
.. versionchanged:: 1.4
|
||||||
Webhooks are now comparable and hashable.
|
Webhooks are now comparable and hashable.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
------------
|
------------
|
||||||
id: :class:`int`
|
id: :class:`int`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user