-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into rookie-subletting
- Loading branch information
Showing
11 changed files
with
988 additions
and
681 deletions.
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
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
Large diffs are not rendered by default.
Oops, something went wrong.
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
Empty file.
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,68 @@ | ||
from json.decoder import JSONDecodeError | ||
from unittest.mock import patch | ||
|
||
from django.test import TestCase | ||
|
||
from utils.r_request import RRequest | ||
|
||
|
||
def raise_decode_error(): | ||
raise JSONDecodeError("Invalid JSON data", "invalid_json", 0) | ||
|
||
|
||
class RRequestTestCase(TestCase): | ||
def setUp(self): | ||
self.url = "https://pennlabs.org" | ||
self.json = {"data": "data"} | ||
self.rrequest = RRequest() | ||
|
||
@patch("requests.request") | ||
def test_successful_request(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
response = self.rrequest.request("get", self.url) | ||
self.assertEqual(200, response.status_code) | ||
|
||
@patch("requests.request") | ||
def test_unsuccessful_request(self, mock_response): | ||
mock_response.return_value.status_code = 400 | ||
mock_response.return_value.content = "Bad Error" | ||
response = self.rrequest.request("post", self.url, json=self.json) | ||
self.assertEqual(400, response.status_code) | ||
self.assertEqual("Bad Error", response.content) | ||
|
||
@patch("requests.request") | ||
def test_bad_json(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
mock_response.return_value.json = raise_decode_error | ||
response = self.rrequest.delete(self.url, json=self.json) | ||
self.assertEqual(200, response.status_code) | ||
|
||
@patch("requests.request") | ||
def test_get_request(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
response = self.rrequest.get(self.url) | ||
self.assertEqual(200, response.status_code) | ||
|
||
@patch("requests.request") | ||
def test_post_request(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
response = self.rrequest.post(self.url, json=self.json) | ||
self.assertEqual(200, response.status_code) | ||
|
||
@patch("requests.request") | ||
def test_patch_request(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
response = self.rrequest.patch(self.url) | ||
self.assertEqual(200, response.status_code) | ||
|
||
@patch("requests.request") | ||
def test_put_request(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
response = self.rrequest.put(self.url, json=self.json) | ||
self.assertEqual(200, response.status_code) | ||
|
||
@patch("requests.request") | ||
def test_delete_request(self, mock_response): | ||
mock_response.return_value.status_code = 200 | ||
response = self.rrequest.delete(self.url, json=self.json) | ||
self.assertEqual(200, response.status_code) |
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,101 @@ | ||
from enum import Enum | ||
from json.decoder import JSONDecodeError | ||
|
||
import requests | ||
|
||
|
||
class Method(str, Enum): | ||
POST = "post" | ||
GET = "get" | ||
PATCH = "patch" | ||
PUT = "put" | ||
DELETE = "delete" | ||
|
||
|
||
class RRequest: | ||
""" | ||
Robust wrapper around Python requests library | ||
Primary use case is to interact with unstable APIs where responses | ||
return one-off malformed data or failures | ||
""" | ||
|
||
NUM_RETRIES = 2 | ||
|
||
def __init__(self, num_retries=NUM_RETRIES): | ||
self.num_retries = num_retries | ||
|
||
def get(self, *args, **kwargs): | ||
return self.request(Method.GET, *args, **kwargs) | ||
|
||
def post(self, *args, **kwargs): | ||
return self.request(Method.POST, *args, **kwargs) | ||
|
||
def patch(self, *args, **kwargs): | ||
return self.request(Method.PATCH, *args, **kwargs) | ||
|
||
def put(self, *args, **kwargs): | ||
return self.request(Method.PUT, *args, **kwargs) | ||
|
||
def delete(self, *args, **kwargs): | ||
return self.request(Method.DELETE, *args, **kwargs) | ||
|
||
def request( | ||
self, | ||
method, | ||
url, | ||
params=None, | ||
data=None, | ||
headers=None, | ||
cookies=None, | ||
files=None, | ||
auth=None, | ||
timeout=None, | ||
allow_redirects=True, | ||
proxies=None, | ||
hooks=None, | ||
stream=None, | ||
verify=None, | ||
cert=None, | ||
json=None, | ||
): | ||
response = self.__default_response() | ||
|
||
for _ in range(self.num_retries): | ||
response = requests.request( | ||
method, | ||
url, | ||
params=params, | ||
data=data, | ||
headers=headers, | ||
cookies=cookies, | ||
files=files, | ||
auth=auth, | ||
timeout=timeout, | ||
allow_redirects=allow_redirects, | ||
proxies=proxies, | ||
hooks=hooks, | ||
stream=stream, | ||
verify=verify, | ||
cert=cert, | ||
json=json, | ||
) | ||
|
||
if response.status_code != 200: | ||
continue | ||
|
||
try: | ||
response.json() | ||
except (TypeError, JSONDecodeError): | ||
continue | ||
return response | ||
|
||
if not response.content: | ||
response.content = "RRequest: Default Error" | ||
|
||
return response | ||
|
||
def __default_response(self): | ||
response = requests.models.Response | ||
response.status_code = 400 | ||
return response |
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