HTTP
The http.py module comes filled with classes designed to handle all the features related to HTTP, such as making connections, setting up headers, sending requests, and much more.
The http module provides a simple interface for making HTTP requests. It is built on top of the httpx library, which has support for
HTTP 1.0, HTTP 1.1 and HTTP 2 protocols.
The way of using this module is inheriting from its classes and implementing what is needed or using the classes directly.
GET connection¶
To make a GET connection, you can use the HttpGETConnection class. This class is a subclass of HttpConnection and is designed to be used
for GET requests.
Each attribute could be set in the class or in the constructor.
url: str -> The URL to make the request.headers: dict -> The headers to be sent in the request.params: dict -> The parameters to be added to the url.timeout: int -> The maximum waiting time for the request to return.user: str -> The user to be used in the request if it needs authentication.password: str -> The password to be used in the request if it needs authentication.cert: str -> The content of the certificate.
These are the methods that you can implement in your class if you wish.
get_url()-> Return the URL to be used in the request.get_headers()-> Return the headers to be used in the request.message_error_check(message: str, status_code: int)-> Returns True or False to retry the request.get_response()-> Make the request and return the response.get_params()-> Return the parameters to be added in the url.
POST connection¶
To make a POST connection, you can use the HttpPOSTConnection class. This class is a subclass of HttpConnection and is designed to be used
for POST requests.
Attributes¶
Each attribute could be set in the class or in the constructor.
url: str -> The URL to make the request.headers: dict -> The headers to be sent in the request.payload: dict -> The payload to be sent in the request.timeout: int -> The maximum waiting time for the request to return.is_json: bool -> If the request should be sent as JSON or Form Data.cert: str -> The content of the certificate.
Methods¶
These are the methods that you can implement in your class if you wish.
get_url() -> str: Return the URL to be used in the request.get_headers() -> dict: Return the headers to be used in the request.message_error_check(message: str, status_code: int) -> bool: Returns True or False to retry the request.get_response() -> httpx.Response: Make the request and return the response.get_payload() -> dict: Return the payload to be sent in the request.
The below examples show how to use the http module to make HTTP requests. We use the HttpGETConnection to show how to use the module, but the same applies to the HttpPOSTConnection and other classes. We use the url attribute to demonstrate, but you could use every attribute in the same way.
Simple GET/POST¶
We could use the class directly to make a simple GET/POST request and pass the attributes in the constructor.
Or we could set the attributes in the instance and use the methods.
connection = HttpGETConnection()
connection.url = 'http://example.com'
response = connection.get_response()
Inheriting from the class¶
Other way to use the class is inheriting from it and setting the attributes in the class.
class MyGETConnection(HttpGETConnection):
url = 'http://example.com'
connection = MyGETConnection()
response = connection.get_response()
Context GET/POST¶
Every connection class is a context manager, so you can use it in a with statement.
with HttpGETConnection(url='http://example.com') as connection:
response = connection.get_response()
The same concept of setting the attributes in the instance applies to the context manager.
with HttpGETConnection() as connection:
connection.url = 'http://example.com'
response = connection.get_response()
Context GET/POST with for loop¶
You can use the HttpConnection class in a for loop to make multiple requests. This is useful when you need to make multiple requests and need to gain some performance because in this case the HttpConnection uses a pool of connections.
securities = ['AAPL', 'GOOGL', 'MSFT']
results = {}
with HttpGETConnection() as connection:
for sec in securities:
connection.url = f'http://example.com/{sec}'
results[sec] = connection.get_response()
Retry logic¶
Every connection class has a method called message_error_check that you can implement to check if the request should be retried. This method receives the message and the status code of the response and should return True or False.
If the method returns True the request will be retried:
class MyGETConnection(HttpGETConnection):
url = 'http://example.com'
def message_error_check(self, message: str, status_code: int):
if status_code == 503:
return True
return False
connection = MyGETConnection()
# This will retry the request if the status code is 503 five times before raise the Exception.
response = connection.get_response()
More complex approach¶
If you need a more complex approach, you can inherit from the HttpGETConnection or HttpPOSTConnection and override the methods that you need.
Below is an example of a class that makes a POST request with a compressed payload, it's already implemented in the http module so you could use it directly.
from everysk.core.compress import compress
from everysk.core.http import HttpPOSTConnection
class HttpPOSTCompressedConnection(HttpPOSTConnection):
def get_headers(self) -> dict:
""" Headers needed to send HTTP Post methods. """
headers = super().get_headers()
headers['Content-Encoding'] = 'gzip'
return headers
def get_payload(self) -> dict:
""" Make the correct payload body to pass on POST request. """
return compress(self.payload, protocol='gzip', serialize='json', use_undefined=True, add_class_path=True)
# The usage is the same as the other classes.
connection = HttpPOSTCompressedConnection(url='http://example.com', payload={'key': 'value'})
response = connection.get_response()