# Copyright 2017 Xiaomi, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== # -*- coding: utf-8 -*- import copy import rfc822 import time import utils import configs import httpclient from models import * class Credential: def __init__(self, galaxy_access_key=None, galaxy_key_secret=None): """ :param galaxy_access_key: string user's access key id :param galaxy_key_secret: string user's secret access key :return : Credential object """ self.galaxy_access_key = galaxy_access_key self.galaxy_key_secret = galaxy_key_secret class VisionClient: IMAGE_DETECT_RESOURCE = "/v1/image:detect" def __init__(self, credential=None, endpoint=None, https_enables=False): """ :param credential: object user's credential information :param endpoint: string the service cluster region user want to use :return: VisionClient object """ self.__credential = credential self.__endpoint = endpoint if ":" in endpoint: token = endpoint.strip().split(":") self.__host = token[0] self.__port = int(token[1]) else: self.__host = endpoint self.__port = 80 self.__uri_prefix = "http://" self.__method = "POST" if https_enables: self.__uri_prefix = "https://" self.__uri = self.__uri_prefix + self.__endpoint + VisionClient.IMAGE_DETECT_RESOURCE def __set_headers(self): headers = dict() headers[configs.CONTENT_TYPE] = "application/json; charset=UTF-8" headers[configs.DATE] = rfc822.formatdate(time.time()) headers[configs.REQUEST_ID] = utils.request_id() headers[configs.CONTENT_MD5] = "" return headers def __check_parameter(self, image): if not isinstance(image,Image): raise TypeError("the image parameter of request Object must be Image instance!") if image.content is None and image.uri is None: raise VisionException(errMsg="the uri and the content of Image object can't all be None") def __result2obj(self, response): """ convert a dict to DetectFaceResult, DetectLabelsResult :param response: dict a dict convert by json string :return: Object such as DetectFaceResult, DetectLabelsResult etc """ result = None if response is None: return result if isinstance(response, dict) and "detectFacesResult" in response: result = DetectFacesResult() detect_faces_result = response["detectFacesResult"] if "faceDetails" in detect_faces_result: face_details_list = detect_faces_result["faceDetails"] face_details = [] for x in face_details_list: box = x["boundingBox"] bounding_box = BoundingBox(left=box["left"], top=box["top"], width=box["width"], height=box['hight']) face_details.append(bounding_box) result.faceDetails = bounding_box if isinstance(response, dict) and "detectLabelsResult" in response: result = DetectLabelsResult() detect_labels_result = response["detectLabelsResult"] if "labels" in detect_labels_result: detect_labels_list = detect_labels_result["labels"] labels = [] for x in detect_labels_list: label = Label(confidence=x["confidence"], name=x["name"]) labels.append(label) result.labels = labels return result def load_image(self, path): bytes_source = None try: image_file = open(path, "r") bytes_source = image_file.read() except Exception, e: print Exception, ":", e finally: if image_file is not None: image_file.close() return bytes_source def detect_labels(self, *args, **kwargs): """ # the interface form hasn't been decided, so here use the common form :param args: args[0]: ImageDetectRequest Object :param kwargs: dict Temporarily not used, remain :return:DetectLabelsResult Object """ if not isinstance(args[0], DetectLabelsRequest): raise TypeError("The first argument must be a ImageDetectRequest Object!") # here temporary use deepcopy avoid image content be changed detect_labels_request = copy.deepcopy(args[0]) image_detect_request = ImageDetectRequest() image_detect_request.set_detect_labels_request(detect_labels_request) if image_detect_request.detectLabelsRequest is not None \ and image_detect_request.detectLabelsRequest.image is not None: image = image_detect_request.detectLabelsRequest.image self.__check_parameter(image) if image.content is not None: image_detect_request.detectLabelsRequest.image.content = \ utils.base64_encode(image_detect_request.detectLabelsRequest.image.content) params = utils.obj2json(image_detect_request) headers = utils.auth_headers(self.__method, self.__uri, self.__set_headers(), self.__credential) http_conf = {"method": self.__method, "host": self.__host, "port": self.__port, "resource": self.IMAGE_DETECT_RESOURCE, "timeout": configs.DEFAULT_CLIENT_TIMEOUT} response = httpclient.execute_http_request(http_conf, params, headers) try: result = self.__result2obj(response) if result is None: raise VisionException(errMsg="error is occurred, the response is none!") except VisionException, ve: print ve return result def detect_faces(self, *args, **kwargs): """ # the interface form hasn't been decided, so here use the common form :param args: args[0]: ImageDetectRequest Object :param kwargs: dict Temporarily not used, remain :return:DetectFacesResult Object """ if not isinstance(args[0], DetectFacesRequest): raise TypeError("The first argument must be a DetectRequest Object!") # here temporary use deepcopy avoid image content be changed detect_faces_request = copy.deepcopy(args[0]) image_detect_request = ImageDetectRequest() image_detect_request.set_detect_faces_request(detect_faces_request) # if only uri specified, the content will be None if image_detect_request.detectFacesRequest is not None \ and image_detect_request.detectFacesRequest.image is not None: image = image_detect_request.detectFacesRequest.image self.__check_parameter(image) if image.content is not None: image_detect_request.detectFacesRequest.image.content = \ utils.base64_encode(image_detect_request.detectFacesRequest.image.content) params = utils.obj2json(image_detect_request) headers = utils.auth_headers(self.__method, self.__uri, self.__set_headers(), self.__credential) http_conf = {"method": self.__method, "host": self.__host, "port": self.__port, "resource": self.IMAGE_DETECT_RESOURCE, "timeout": configs.DEFAULT_CLIENT_TIMEOUT} response = httpclient.execute_http_request(http_conf, params, headers) try: result = self.__result2obj(response) if result is None: raise VisionException(errMsg="error is occurred, the response is none!") except VisionException, ve: print ve return result