'''Request object abstractions'''
import abc
from wpull.url import URLInfo
[docs]class DictableMixin(object):
@abc.abstractmethod
[docs] def to_dict(self):
'''Convert to a dict suitable for JSON.'''
@classmethod
[docs] def call_to_dict_or_none(cls, instance):
'''Call ``to_dict`` or return ``None``.'''
if hasattr(instance, 'to_dict'):
return instance.to_dict()
[docs]class SerializableMixin(object):
'''Serialize and unserialize methods.'''
@abc.abstractmethod
[docs] def to_bytes(self):
'''Serialize to HTTP bytes.'''
@abc.abstractmethod
[docs] def parse(self, data):
'''Parse from HTTP bytes.'''
[docs]class URLPropertyMixin(object):
'''Provide URL as a property.
Attributes:
url (str): The complete URL string.
url_info (:class:`.url.URLInfo`): The URLInfo of the `url` attribute.
Setting :attr:`url` or :attr:`url_info` will update the other
respectively.
'''
def __init__(self):
self._url = None
self._url_info = None
@property
def url(self):
return self._url
@url.setter
def url(self, url_str):
self._url = url_str
self._url_info = URLInfo.parse(url_str)
@property
def url_info(self):
return self._url_info
@url_info.setter
def url_info(self, url_info):
self._url_info = url_info
self._url = url_info.url
[docs]class ProtocolResponseMixin(object):
'''Protocol abstraction for response objects.'''
@abc.abstractproperty
def protocol(self):
'''Name of the protocol.
Returns:
str: Either ``ftp`` or ``http``.
'''
@abc.abstractmethod
[docs] def response_code(self):
'''Response code representative for the protocol.
Returns:
int: The status code for HTTP or the final reply code for FTP.
'''
@abc.abstractmethod
[docs] def response_message(self):
'''Response message representative for the protocol.
Returns:
str: The status line reason for HTTP or a reply message for FTP.
'''
[docs]class BaseRequest(URLPropertyMixin):
@abc.abstractmethod
[docs] def set_continue(self, offset: int):
pass
[docs]class BaseResponse(ProtocolResponseMixin):
def __init__(self):
super().__init__()
self.body = None
self.request = None