Skip to content

Instantly share code, notes, and snippets.

@wonderbeyond
Created March 29, 2023 06:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wonderbeyond/4e03a9f942307bfc9a0a59f1738c65f0 to your computer and use it in GitHub Desktop.
Save wonderbeyond/4e03a9f942307bfc9a0a59f1738c65f0 to your computer and use it in GitHub Desktop.
Simple Requestor - A easy wrapper over python's urllib.request
from typing import cast
import logging
import json
import urllib.request
import http.client
import urllib.parse
logger = logging.getLogger(__name__)
class Response(http.client.HTTPResponse):
@classmethod
def tune(cls, resp: http.client.HTTPResponse) -> 'Response':
resp.__class__ = cls
return cast(Response, resp)
def json(self):
return json.loads(self.read().decode('utf-8'))
class SimpleRequestor:
def __init__(self, base_url):
self.base_url = base_url
def request(self, method, path, params=None, data=None, headers=None) -> Response:
headers = headers or {}
path = f'{self.base_url}{path}'
if params:
path = f'{path}?{urllib.parse.urlencode(params)}'
req = urllib.request.Request(
url=path,
method=method.upper(),
data=json.dumps(data).encode('utf-8') if data else None,
headers=headers,
)
if data and not req.get_header('Content-Type'):
req.add_header('Content-Type', 'application/json')
logger.info(f'{method} {req.full_url} with headers: {req.headers!r} and body: {req.data!r}')
return Response.tune(urllib.request.urlopen(req))
if __name__ == '__main__':
import logging
logging.basicConfig(level=logging.INFO)
requestor = SimpleRequestor('https://httpbin.org/')
requestor.request('GET', 'anything', params={"limit": 10})
resp = requestor.request('POST', 'anything', params={"a": 1}, data={"a": 2})
print('Response:', resp.json())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment