def fail(self, message = None): if self._colorize: self._spinner.fail(color(self._current_message, 'error', self._colorize)) self._spinner.stop() self.start(message) self._spinner.fail(color(message, 'error', self._colorize)) self._spinner.stop() else: msg('ERROR: ' + message)
def update(self, message = None): if self._quiet: return if self._colorize: self._spinner.succeed(color(self._current_message, 'info', self._colorize)) self._spinner.stop() self.start(message) else: msg(message)
def warn(self, message=None): if self._quiet: return if self._colorize: self._spinner.succeed( color(self._current_message, 'info', self._colorize)) self._spinner.stop() self._spinner.warn(color(message, 'warn', self._colorize)) self._current_message = '' else: msg('WARNING: ' + message)
def start(self, message = None): if self._quiet: return if message is None: message = '' if self._colorize: text = color(message, 'info') self._spinner = Halo(spinner='bouncingBall', text = text) self._spinner.start() self._current_message = message else: msg(message)
def all_results(self, path): '''Returns all the results from the service as a Python dict.''' # Check if we already processed it. if path in self._results: return self._results[path] if __debug__: log('Reading {}', path) with io.open(path, 'rb') as image_file: image_data = image_file.read() # Google Cloud Vision API docs state that images cannot exceed 20 MB: # https://cloud.google.com/vision/docs/supported-files if len(image_data) > 20 * 1024 * 1024: text = 'Error: file "{}" is too large for Google service'.format( path) msg(text, 'warn') return text try: if __debug__: log('Building Google vision API object') client = gv.ImageAnnotatorClient() image = gv.types.Image(content=image_data) context = gv.types.ImageContext( language_hints=['en-t-i0-handwrit']) # Iterate over the known API calls and store each result. results = {} for feature in self._known_features: if __debug__: log('Sending image to Google for {} ...', feature) response = getattr(client, feature)(image=image, image_context=context) if __debug__: log('Received result.') results[feature] = MessageToDict(response) self._results[path] = results return results except google.api_core.exceptions.PermissionDenied as err: text = 'Authentication failure for Google service -- {}'.format( err) raise ServiceFailure(text) except Exception as err: text = 'Error: failed to convert "{}": {}'.format(path, err) return text
def all_results(self, path): '''Returns all the results from the service as a Python dict.''' # Check if we already processed it. if path in self._results: return self._results[path] vision_base_url = "https://westus.api.cognitive.microsoft.com/vision/v2.0/" text_recognition_url = vision_base_url + "recognizeText" headers = { 'Ocp-Apim-Subscription-Key': self.credentials, 'Content-Type': 'application/octet-stream' } params = {'mode': 'Handwritten'} image_data = open(path, 'rb').read() # https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/home # states "The file size of the image must be less than 4 megabytes (MB)" if len(image_data) > 4 * 1024 * 1024: text = 'File "{}" is too large for Microsoft service'.format(path) msg(text, 'warn') return text # Post it to the Microsoft cloud service. if __debug__: log('Sending file to MS cloud service') response = requests.post(text_recognition_url, headers=headers, params=params, data=image_data) try: response.raise_for_status() except HTTPError as err: # FIXME this might be a good place to suggest to the user that they # visit https://blogs.msdn.microsoft.com/kwill/2017/05/17/http-401-access-denied-when-calling-azure-cognitive-services-apis/ if response.status_code in [401, 402, 403, 407, 451, 511]: text = 'Authentication failure for MS service -- {}'.format( err) raise ServiceFailure(text) elif response.status_code == 429: text = 'Server blocking further requests due to rate limits' raise ServiceFailure(text) elif response.status_code == 503: text = 'Server is unavailable -- try again later' raise ServiceFailure(text) else: text = 'Encountered network communications problem -- {}'.format( err) raise ServiceFailure(text) except Exception as err: import pdb pdb.set_trace() msg('MS rejected "{}"'.format(path), 'warn') return '' # The Microsoft API for extracting handwritten text requires two API # calls: one call to submit the image for processing, the other to # retrieve the text found in the image. We have to poll and wait # until a result is available. analysis = {} poll = True if __debug__: log('Polling MS for results ...') while (poll): response_final = requests.get( response.headers["Operation-Location"], headers=headers) analysis = response_final.json() time.sleep(1) if ("recognitionResult" in analysis): poll = False if ("status" in analysis and analysis['status'] == 'Failed'): poll = False if __debug__: log('Results received.') self._results[path] = analysis return analysis