92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
|
|
from enum import Enum
|
||
|
|
from typing import Any, Dict, Tuple, Union
|
||
|
|
from urllib.parse import urlencode
|
||
|
|
|
||
|
|
|
||
|
|
class Match(Enum):
|
||
|
|
ANY = "*"
|
||
|
|
|
||
|
|
|
||
|
|
class Request(object):
|
||
|
|
"""
|
||
|
|
An HTTP request.
|
||
|
|
"""
|
||
|
|
|
||
|
|
def __init__(
|
||
|
|
self,
|
||
|
|
method: Union[str, Match] = Match.ANY,
|
||
|
|
url: Union[str, Match] = Match.ANY,
|
||
|
|
auth: Union[Tuple[str, str], Match] = Match.ANY,
|
||
|
|
params: Union[Dict[str, str], Match] = Match.ANY,
|
||
|
|
data: Union[Dict[str, str], Match] = Match.ANY,
|
||
|
|
headers: Union[Dict[str, str], Match] = Match.ANY,
|
||
|
|
**kwargs: Any
|
||
|
|
):
|
||
|
|
self.method = method
|
||
|
|
if method and method is not Match.ANY:
|
||
|
|
self.method = method.upper()
|
||
|
|
self.url = url
|
||
|
|
self.auth = auth
|
||
|
|
self.params = params
|
||
|
|
self.data = data
|
||
|
|
self.headers = headers
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def attribute_equal(cls, lhs, rhs) -> bool:
|
||
|
|
if lhs == Match.ANY or rhs == Match.ANY:
|
||
|
|
# ANY matches everything
|
||
|
|
return True
|
||
|
|
|
||
|
|
lhs = lhs or None
|
||
|
|
rhs = rhs or None
|
||
|
|
|
||
|
|
return lhs == rhs
|
||
|
|
|
||
|
|
def __eq__(self, other) -> bool:
|
||
|
|
if not isinstance(other, Request):
|
||
|
|
return False
|
||
|
|
|
||
|
|
return (
|
||
|
|
self.attribute_equal(self.method, other.method)
|
||
|
|
and self.attribute_equal(self.url, other.url)
|
||
|
|
and self.attribute_equal(self.auth, other.auth)
|
||
|
|
and self.attribute_equal(self.params, other.params)
|
||
|
|
and self.attribute_equal(self.data, other.data)
|
||
|
|
and self.attribute_equal(self.headers, other.headers)
|
||
|
|
)
|
||
|
|
|
||
|
|
def __str__(self) -> str:
|
||
|
|
auth = ""
|
||
|
|
if self.auth and self.auth != Match.ANY:
|
||
|
|
auth = "{} ".format(self.auth)
|
||
|
|
|
||
|
|
params = ""
|
||
|
|
if self.params and self.params != Match.ANY:
|
||
|
|
params = "?{}".format(urlencode(self.params, doseq=True))
|
||
|
|
|
||
|
|
data = ""
|
||
|
|
if self.data and self.data != Match.ANY:
|
||
|
|
if self.method == "GET":
|
||
|
|
data = "\n -G"
|
||
|
|
data += "\n{}".format(
|
||
|
|
"\n".join(' -d "{}={}"'.format(k, v) for k, v in self.data.items())
|
||
|
|
)
|
||
|
|
|
||
|
|
headers = ""
|
||
|
|
if self.headers and self.headers != Match.ANY:
|
||
|
|
headers = "\n{}".format(
|
||
|
|
"\n".join(' -H "{}: {}"'.format(k, v) for k, v in self.headers.items())
|
||
|
|
)
|
||
|
|
|
||
|
|
return "{auth}{method} {url}{params}{data}{headers}".format(
|
||
|
|
auth=auth,
|
||
|
|
method=self.method,
|
||
|
|
url=self.url,
|
||
|
|
params=params,
|
||
|
|
data=data,
|
||
|
|
headers=headers,
|
||
|
|
)
|
||
|
|
|
||
|
|
def __repr__(self) -> str:
|
||
|
|
return str(self)
|