diff --git a/twilio/http/request.py b/twilio/http/request.py index 4aef7017b..729e61bad 100644 --- a/twilio/http/request.py +++ b/twilio/http/request.py @@ -4,12 +4,22 @@ class Match(Enum): + """ + Special enumeration used to represent a wildcard match. + + The value ANY ("*") is used to indicate that any value + for a given attribute should be considered a match. + """ ANY = "*" class Request(object): """ - An HTTP request. + Represents an HTTP request definition. + + This class is mainly used to describe or compare HTTP requests + based on attributes such as method, URL, parameters, headers, + authentication, and request body data. """ def __init__( @@ -22,27 +32,52 @@ def __init__( headers: Union[Dict[str, str], Match] = Match.ANY, **kwargs: Any ): + # HTTP method (GET, POST, etc.) or Match.ANY as a wildcard self.method = method + + # Normalize the HTTP method to uppercase if provided if method and method is not Match.ANY: self.method = method.upper() + + # Request URL or wildcard self.url = url + + # Authentication tuple (username, password) or wildcard self.auth = auth + + # Query parameters sent with the request self.params = params + + # Request body data self.data = data + + # HTTP headers included in the request self.headers = headers @classmethod def attribute_equal(cls, lhs, rhs) -> bool: + """ + Compares two request attributes, supporting wildcard matching. + + If either side is Match.ANY, the attributes are considered equal. + """ if lhs == Match.ANY or rhs == Match.ANY: # ANY matches everything return True + # Normalize falsy values to None before comparison lhs = lhs or None rhs = rhs or None return lhs == rhs def __eq__(self, other) -> bool: + """ + Compares two Request objects for equality. + + Each attribute is compared individually using attribute_equal + to allow wildcard matching. + """ if not isinstance(other, Request): return False @@ -56,20 +91,31 @@ def __eq__(self, other) -> bool: ) def __str__(self) -> str: + """ + Returns a human-readable representation of the request. + + The format resembles a curl-like representation including + parameters, headers, and request body. + """ params = "" if self.params and self.params != Match.ANY: + # Encode query parameters for URL usage params = "?{}".format(urlencode(self.params, doseq=True)) data = "" if self.data and self.data != Match.ANY: + # If the request is GET, mimic curl's -G option if self.method == "GET": data = "\n -G" + + # Format request body parameters 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: + # Format headers, excluding authorization for security reasons headers = "\n{}".format( "\n".join( ' -H "{}: {}"'.format(k, v) @@ -87,4 +133,9 @@ def __str__(self) -> str: ) def __repr__(self) -> str: + """ + Returns the string representation of the Request object. + + Used mainly for debugging or logging. + """ return str(self) diff --git a/twilio/http/response.py b/twilio/http/response.py index af5a3b170..095417988 100644 --- a/twilio/http/response.py +++ b/twilio/http/response.py @@ -2,6 +2,12 @@ class Response(object): + """ + Represents a simplified HTTP response. + + This class stores the HTTP status code, response body content, + and optional HTTP headers returned by a request. + """ def __init__( self, status_code: int, @@ -16,7 +22,18 @@ def __init__( @property def text(self) -> str: + """ + Returns the response body as text. + + This property provides a clearer way to access the response + content stored in `self.content`. + """ return self.content def __repr__(self) -> str: + """ + Returns a string representation of the Response object. + + Mainly used for debugging purposes. + """ return "HTTP {} {}".format(self.status_code, self.content)