Source code for jsonwspclient.jsonwspresponse

# -*- coding: utf-8 -*-
"""
====================================================
Jsonwspresponse :mod:`jsonwspclient.jsonwspresponse`
====================================================
"""
import logging
from . import jsonwsputils as utils
from .jsonwspmultipart import MultiPartReader
from . import jsonwspexceptions as excs
log = logging.getLogger('jsonwspclient')


[docs]class JsonWspResponse(object): """JsonWspResponse (wrapper for `requests Response object <http://docs .python-requests.org/en/master/api/#requests.Response>`_) is not meant to be instantiate manually but only as response from :any:`JsonWspClient` requests. """ def __init__(self, response, trigger): self._response = response self.__reader = None self._boundary = utils.get_boundary(self.headers) self._multipart = None self._raise_for_fault = False self._trigger = trigger self.attachments = {} """(dict): Attachments dictionary, not really useful.""" self.fault = {} """(dict): Fault dictionary if response has fault.""" self.fault_code = None """(str): Fault code if response has fault.""" self.has_fault = False """(bool): True if response has fault.""" self.is_multipart = True if self._boundary else False """(bool): True if response is multipart.""" self.length = int(self.headers.get('Content-Length', '0')) """(int): response content length""" self.response_dict = {} """(dict): JSON part of the response.""" self.result = {} """(dict,list): **data** of the JSON part of the response.""" self._process() def __getattr__(self, name): return getattr(self._response, name) def __nonzero__(self): return self.has_fault is False __bool__ = __nonzero__ def _process(self): """_process.""" if self._boundary: self.__reader = self._get_reader() self.response_dict = self.next() else: try: self.response_dict = self._response.json() except ValueError as error: log.debug('error %s', error) self.response_dict = {} self._check_fault() self._get_attchments_id() def _check_fault(self): """Check fault.""" self.has_fault = self.response_dict.get('type') == "jsonwsp/fault" if self.has_fault: self.fault = self.response_dict['fault'] self.fault_code = self.response_dict['fault']['code'] else: self.result = self.response_dict.get('result', {}) def _get_attchments_id(self): """get info.""" if self.is_multipart and isinstance(self.result, (dict, list)): self.attachments.update(utils.check_attachment(self.result)) def _get_reader(self): """get all.""" self._multipart = MultiPartReader( self.headers, utils.FileWithCallBack(self.raw, self._trigger, size=self.length), size=self.length) return self._multipart.iterator() @property def _reader(self): if self.__reader is None: raise IOError("Reader is None") elif not self.is_multipart: raise TypeError("Is not a multipart response") return self.__reader
[docs] def read_all(self, chunk_size=None): """Read all the data and return a Dictionary containig the Attachments. Args: chunk_size (int): bytes to read each time. Returns: dict: Dictionary with all attachments. """ self._multipart.read_all(chunk_size) return self._multipart.by_id
[docs] def next(self): """If JsonWspResponse is multipart returns the next attachment. Returns: JsonWspAttachment: the attachment object. """ return next(self._reader)
[docs] def save_all(self, path, name='name', overwrite=True): """Save all the attachments ad once. Args: path (str): Path where to save. name (str, optional): key with which the file name is specified in the dictionary (default ``name``). overwrite (bool, optional): overwrite the file if exists (defautl True). """ for attach in self._reader: if not attach: break filename = self.attachments[attach.att_id][name] attach.save(path, filename=filename, overwrite=overwrite)
[docs] def raise_for_fault(self): """Reise error if needed else return self.""" if self.fault_code == 'server': raise excs.ServerFault(response=self) elif self.fault_code == 'client': raise excs.ClientFault(response=self) elif self.fault_code == 'incompatible': raise excs.IncompatibleFault(response=self) return self
def __iter__(self): return self def __next__(self): return self.next() def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.close() def __del__(self): del self.__reader del self._multipart del self.attachments del self._response