Created
October 17, 2022 23:13
-
-
Save wrouesnel/3b8506b78015bc7bb80acb647fd3493a to your computer and use it in GitHub Desktop.
Make request without requests
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
# https://dev.to/bowmanjd/http-calls-in-python-without-requests-or-other-external-dependencies-5aj1 | |
import json | |
import typing | |
import urllib.error | |
import urllib.parse | |
import urllib.request | |
from email.message import Message | |
class Response(typing.NamedTuple): | |
body: str | |
headers: Message | |
status: int | |
error_count: int = 0 | |
def json(self) -> typing.Any: | |
""" | |
Decode body's JSON. | |
Returns: | |
Pythonic representation of the JSON object | |
""" | |
try: | |
output = json.loads(self.body) | |
except json.JSONDecodeError: | |
output = "" | |
return output | |
def request( | |
url: str, | |
data: dict = None, | |
params: dict = None, | |
headers: dict = None, | |
method: str = "GET", | |
data_as_json: bool = True, | |
error_count: int = 0, | |
) -> Response: | |
if not url.casefold().startswith("http"): | |
raise urllib.error.URLError("Incorrect and possibly insecure protocol in url") | |
method = method.upper() | |
request_data = None | |
headers = headers or {} | |
data = data or {} | |
params = params or {} | |
headers = {"Accept": "application/json", **headers} | |
if method == "GET": | |
params = {**params, **data} | |
data = None | |
if params: | |
url += "?" + urllib.parse.urlencode(params, doseq=True, safe="/") | |
if data: | |
if data_as_json: | |
request_data = json.dumps(data).encode() | |
headers["Content-Type"] = "application/json; charset=UTF-8" | |
else: | |
request_data = urllib.parse.urlencode(data).encode() | |
httprequest = urllib.request.Request( | |
url, data=request_data, headers=headers, method=method | |
) | |
try: | |
with urllib.request.urlopen(httprequest) as httpresponse: | |
response = Response( | |
headers=httpresponse.headers, | |
status=httpresponse.status, | |
body=httpresponse.read().decode( | |
httpresponse.headers.get_content_charset("utf-8") | |
), | |
) | |
except urllib.error.HTTPError as e: | |
response = Response( | |
body=str(e.reason), | |
headers=e.headers, | |
status=e.code, | |
error_count=error_count + 1, | |
) | |
return response |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment