From e7411c09b284e20f9595cdaca02ffc2661f405d8 Mon Sep 17 00:00:00 2001 From: Michael Whittaker Date: Thu, 28 Mar 2013 20:50:53 +0100 Subject: [PATCH] enables uploading from web url CHANGES IN API: * upload_face was renamed to new_face (in terms of expected behavior) --- api.py | 95 ++++++++++++++++------- example.py | 6 +- request_templates/UploadNewImage_File.xml | 2 +- request_templates/UploadNewImage_Url.xml | 10 +++ 4 files changed, 82 insertions(+), 31 deletions(-) create mode 100644 request_templates/UploadNewImage_Url.xml diff --git a/api.py b/api.py index dcb0754..7e64f79 100644 --- a/api.py +++ b/api.py @@ -31,10 +31,23 @@ def __init__(self, **kwargs): self.poll_interval = kwargs.get('poll_interval', DEFAULT_POLL_INTERVAL) self.logger = logging.getLogger(self.__class__.__name__) - def upload_face(self, file_name, person_id): - """ Uploads an image to BetaFace API, waits for it to be processed - by polling each poll_interval seconds, and then assigns a person_id - (alpha-numberic + '.') to that image. """ + def new_face(self, file_name, person_id): + """ Uploads an image to BetaFace API, waits for it to be processed + by polling each poll_interval seconds, and then assigns a person_id + (alpha-numberic + '.') to that image. """ + if "http://" in file_name or "https://" in file_name: + face_uid = self.download_face(file_name) + else: + face_uid = self.upload_face(file_name) + params = { + 'face_uid': face_uid, + 'person_id': person_id + } + result = self._api_call('Faces_SetPerson', params) + + def upload_face(self, file_name): + """ Uploads a local image to BetaFace API, waits for it to be processed + by polling each poll_interval seconds. """ # Step 1: Encode image in base 64, upload it to service and get image ID file_contents = open(file_name, "rb").read() @@ -59,21 +72,39 @@ def upload_face(self, file_name, person_id): else: return - # Step 3: associate the face with the person via Faces_SetPerson endpoint - params = { - 'face_uid': face_uid, - 'person_id': person_id - } - result = self._api_call('Faces_SetPerson', params) + # Step 3: return face id + return face_uid def recognize_faces(self, file_name, namespace): - # Step 1: Encode image in base 64, upload it to service and get image ID - file_contents = open(file_name, "rb").read() + # Step 1: upload it to service and get image ID + if "http://" in file_name or "https://" in file_name: + face_uid = self.download_face(file_name) + else: + face_uid = self.upload_face(file_name) + + # Step 3: Start a face recognition job + params = {'face_uid': face_uid, 'namespace': 'all@%s' % namespace} + result = self._api_call('Faces_Recognize', params) + + # Step 4: Wait for the recognition job to finish + params = {'recognize_job_id': result['recognize_job_id']} + result = self._api_call('GetRecognizeResult', params) + while not result['ready']: + time.sleep(self.poll_interval) + result = self._api_call('GetRecognizeResult', params) + + return result['matches'] + + def download_face(self, image_url): + """ Uploads a web image to BetaFace API and waits for it to be processed + by polling each poll_interval seconds. """ + + # Step 1: upload url to service and get image ID params = { - 'base64_data': b64encode(file_contents), - 'original_filename': file_name + 'image_url': image_url, + 'original_filename': image_url } - result = self._api_call('UploadNewImage_File', params) + result = self._api_call('UploadNewImage_Url', params) if result is None: self.logger.error("API call to upload image failed!") return None @@ -88,20 +119,11 @@ def recognize_faces(self, file_name, namespace): if 'face_uid' in result: face_uid = result['face_uid'] else: - return {} - - # Step 3: Start a face recognition job - params = {'face_uid': face_uid, 'namespace': 'all@%s' % namespace} - result = self._api_call('Faces_Recognize', params) - - # Step 4: Wait for the recognition job to finish - params = {'recognize_job_id': result['recognize_job_id']} - result = self._api_call('GetRecognizeResult', params) - while not result['ready']: - time.sleep(self.poll_interval) - result = self._api_call('GetRecognizeResult', params) + return - return result['matches'] + # Step 3: return face id + return face_uid + def _api_call(self, endpoint, params): """ Make an API call to a given endpoint, with given params. @@ -132,6 +154,7 @@ def _api_call(self, endpoint, params): if request.status_code != 200: self.logger.error("HTTP request failed with status code %d" % request.status_code) + self.logger.info("Error was:\n%s" % request.text) return None result = {'raw_content': request.text} @@ -180,6 +203,22 @@ def _parse_UploadNewImage_File(self, response): return result + def _parse_UploadNewImage_Url(self, response): + """ Parse the upload new image url response. """ + result = {} + + img_uid = response.findall('.//img_uid') + if len(img_uid) == 0: + return None + result['img_uid'] = img_uid[0].text + + ready = response.findall('.//int_response') + if len(ready) == 0: + return None + result['ready'] = (ready[0].text.strip() == '0') + + return result + def _parse_GetImageInfo(self, response): """ Parse the get image info response. """ result = {} diff --git a/example.py b/example.py index 3e6e2a3..0727fce 100644 --- a/example.py +++ b/example.py @@ -4,6 +4,8 @@ logging.basicConfig(level = logging.INFO) client = BetaFaceAPI() -client.upload_face('/Users/aismail/Desktop/obama_normal.jpg', 'obama@ami-lab.ro') -matches = client.recognize_faces('/Users/aismail/Desktop/obama_suparat.jpg', 'ami-lab.ro') +client.new_face('http://ucesy-sk.happyhair.sk/celebrity_img/madonna1j2312.jpg', 'madonna@celebs') +client.new_face('http://d1.stern.de/bilder/stern_5/lifestyle/2012/KW50/britney-spears_fitwidth_420.jpg', 'britney1@celebs') +client.new_face('/Volumes/Daten/Users/useraccount/Downloads/britney2.jpg', 'britney2@celebs') +matches = client.recognize_faces('http://ucesy-sk.happyhair.sk/celebrity_img/spears1j1712.jpg', 'celebs') print matches diff --git a/request_templates/UploadNewImage_File.xml b/request_templates/UploadNewImage_File.xml index 20902b2..6aa0ffa 100644 --- a/request_templates/UploadNewImage_File.xml +++ b/request_templates/UploadNewImage_File.xml @@ -5,7 +5,7 @@ {{api_key}} {{api_secret}} - 0 + 7 {{base64_data}} {{original_filename}} diff --git a/request_templates/UploadNewImage_Url.xml b/request_templates/UploadNewImage_Url.xml new file mode 100644 index 0000000..27d9d4d --- /dev/null +++ b/request_templates/UploadNewImage_Url.xml @@ -0,0 +1,10 @@ + + + + + {{api_key}} + {{api_secret}} + 7 + {{image_url}} + \ No newline at end of file