diff --git a/face_client/face_client.py b/face_client/face_client.py index 28ac92f..ab4d76e 100644 --- a/face_client/face_client.py +++ b/face_client/face_client.py @@ -73,7 +73,7 @@ def faces_detect(self, urls=None, file=None, aggressive=False): if file: # Check if the file exists if not os.path.exists(file): - raise IOError('File %s does not exist' % (file)) + raise IOError(f'File {file} does not exist') data = {'file': file} else: @@ -82,8 +82,7 @@ def faces_detect(self, urls=None, file=None, aggressive=False): if aggressive: data['detector'] = 'Aggressive' - response = self.send_request('faces/detect', data) - return response + return self.send_request('faces/detect', data) def faces_status(self, uids=None, namespace=None): """ @@ -95,14 +94,13 @@ def faces_status(self, uids=None, namespace=None): raise AttributeError('Missing user IDs') (facebook_uids, twitter_uids) = \ - self.__check_user_auth_credentials(uids) + self.__check_user_auth_credentials(uids) data = {'uids': uids} self.__append_user_auth_data(data, facebook_uids, twitter_uids) self.__append_optional_arguments(data, namespace=namespace) - response = self.send_request('faces/status', data) - return response + return self.send_request('faces/status', data) def faces_recognize(self, uids=None, urls=None, file=None, train=None, namespace=None): @@ -120,25 +118,24 @@ def faces_recognize(self, uids=None, urls=None, file=None, train=None, raise AttributeError('Missing required arguments') (facebook_uids, twitter_uids) = \ - self.__check_user_auth_credentials(uids) + self.__check_user_auth_credentials(uids) data = {'uids': uids} if file: # Check if the file exists if not os.path.exists(file): - raise IOError('File %s does not exist' % (file)) + raise IOError(f'File {file} does not exist') - data.update({'file': file}) + data['file'] = file else: - data.update({'urls': urls}) + data['urls'] = urls self.__append_user_auth_data(data, facebook_uids, twitter_uids) self.__append_optional_arguments(data, train=train, namespace=namespace) - response = self.send_request('faces/recognize', data) - return response + return self.send_request('faces/recognize', data) def faces_train(self, uids=None, namespace=None): """ @@ -151,18 +148,17 @@ def faces_train(self, uids=None, namespace=None): raise AttributeError('Missing user IDs') (facebook_uids, twitter_uids) = \ - self.__check_user_auth_credentials(uids) + self.__check_user_auth_credentials(uids) data = {'uids': uids} self.__append_user_auth_data(data, facebook_uids, twitter_uids) self.__append_optional_arguments(data, namespace=namespace) - response = self.send_request('faces/train', data) - return response + return self.send_request('faces/train', data) ### Methods for managing face tags ### def tags_get(self, uids=None, urls=None, pids=None, order='recent', \ - limit=5, together=False, filter=None, namespace=None): + limit=5, together=False, filter=None, namespace=None): """ Returns saved tags in one or more photos, or for the specified User ID(s). @@ -173,7 +169,7 @@ def tags_get(self, uids=None, urls=None, pids=None, order='recent', \ http://developers.face.com/docs/api/tags-get/ """ (facebook_uids, twitter_uids) = \ - self.__check_user_auth_credentials(uids) + self.__check_user_auth_credentials(uids) data = {'uids': uids, 'urls': urls, @@ -183,8 +179,7 @@ def tags_get(self, uids=None, urls=None, pids=None, order='recent', \ self.__append_optional_arguments(data, pids=pids, filter=filter, namespace=namespace) - response = self.send_request('tags/get', data) - return response + return self.send_request('tags/get', data) def tags_add(self, url=None, x=None, y=None, width=None, uid=None, tagger_id=None, label=None, password=None): @@ -208,11 +203,10 @@ def tags_add(self, url=None, x=None, y=None, width=None, uid=None, self.__append_user_auth_data(data, facebook_uids, twitter_uids) self.__append_optional_arguments(data, label=label, password=password) - response = self.send_request('tags/add', data) - return response + return self.send_request('tags/add', data) def tags_save(self, tids=None, uid=None, tagger_id=None, label=None, \ - password=None): + password=None): """ Saves a face tag. Use this method to save tags for training the face.com index, or for future use of the faces.detect and tags.get @@ -231,8 +225,7 @@ def tags_save(self, tids=None, uid=None, tagger_id=None, label=None, \ self.__append_optional_arguments(data, tagger_id=tagger_id, label=label, password=password) - response = self.send_request('tags/save', data) - return response + return self.send_request('tags/save', data) def tags_remove(self, tids=None, password=None): """ @@ -245,8 +238,7 @@ def tags_remove(self, tids=None, password=None): data = {'tids': tids} - response = self.send_request('tags/remove', data) - return response + return self.send_request('tags/remove', data) ### Account management methods ### def account_limits(self): @@ -269,10 +261,7 @@ def account_users(self, namespaces=None): if not namespaces: raise AttributeError('Missing namespaces argument') - response = self.send_request('account/users', - {'namespaces': namespaces}) - - return response + return self.send_request('account/users', {'namespaces': namespaces}) def __check_user_auth_credentials(self, uids): # Check if needed credentials are provided @@ -293,9 +282,11 @@ def __check_user_auth_credentials(self, uids): def __append_user_auth_data(self, data, facebook_uids, twitter_uids): if facebook_uids: - data.update({'user_auth': 'fb_user:%s,fb_session:%s' % - (self.facebook_credentials['fb_user'], - self.facebook_credentials['fb_session'])}) + data.update( + { + 'user_auth': f"fb_user:{self.facebook_credentials['fb_user']},fb_session:{self.facebook_credentials['fb_session']}" + } + ) if twitter_uids: # If both user/password and OAuth credentials are provided, use @@ -309,10 +300,11 @@ def __append_user_auth_data(self, data, facebook_uids, twitter_uids): self.twitter_credentials['twitter_oauth_token']))} ) else: - data.update({'user_auth': - 'twitter_user:%s,twitter_password:%s' % - (self.twitter_credentials['twitter_user'], - self.twitter_credentials['twitter_password'])}) + data.update( + { + 'user_auth': f"twitter_user:{self.twitter_credentials['twitter_user']},twitter_password:{self.twitter_credentials['twitter_password']}" + } + ) def __append_optional_arguments(self, data, **kwargs): for key, value in kwargs.iteritems(): @@ -320,14 +312,14 @@ def __append_optional_arguments(self, data, **kwargs): data.update({key: value}) def send_request(self, method=None, parameters=None): - url = '%s/%s' % (API_URL, method) + url = f'{API_URL}/{method}' data = {'api_key': self.api_key, 'api_secret': self.api_secret, 'format': self.format} if parameters: - data.update(parameters) + data |= parameters # Local file is provided, use multi-part form if 'file' in parameters: @@ -355,7 +347,7 @@ def send_request(self, method=None, parameters=None): response_data = json.loads(response) if 'status' in response_data and \ - response_data['status'] == 'failure': + response_data['status'] == 'failure': raise FaceError(response_data['error_code'], response_data['error_message']) diff --git a/face_client/multipart.py b/face_client/multipart.py index 9d294ab..5e703b0 100644 --- a/face_client/multipart.py +++ b/face_client/multipart.py @@ -48,15 +48,14 @@ def __init__(self, name, filename, body, headers): self._body = body # We respect any content type passed in, but otherwise set it here. # We set the content disposition now, overwriting any prior value. - if self._filename == None: - self._headers[Part.CONTENT_DISPOSITION] = \ - ('form-data; name="%s"' % self._name) + if self._filename is None: + self._headers[Part.CONTENT_DISPOSITION] = f'form-data; name="{self._name}"' self._headers.setdefault(Part.CONTENT_TYPE, Part.DEFAULT_CONTENT_TYPE) else: - self._headers[Part.CONTENT_DISPOSITION] = \ - ('form-data; name="%s"; filename="%s"' % - (self._name, self._filename)) + self._headers[ + Part.CONTENT_DISPOSITION + ] = f'form-data; name="{self._name}"; filename="{self._filename}"' self._headers.setdefault(Part.CONTENT_TYPE, mimetypes.guess_type(filename)[0] or Part.DEFAULT_CONTENT_TYPE) @@ -71,12 +70,9 @@ def get(self): @return: Lines of this part. @rtype: list ''' - lines = [] - lines.append('--' + Part.BOUNDARY) - for (key, val) in self._headers.items(): - lines.append('%s: %s' % (key, val)) - lines.append('') - lines.append(self._body) + lines = [f'--{Part.BOUNDARY}'] + lines.extend(f'{key}: {val}' for key, val in self._headers.items()) + lines.extend(('', self._body)) return lines @@ -142,8 +138,8 @@ def get(self): all = [] for part in self.parts: all += part.get() - all.append('--' + Part.BOUNDARY + '--') + all.append(f'--{Part.BOUNDARY}--') all.append('') # We have to return the content type, since it specifies the boundary. - content_type = 'multipart/form-data; boundary=%s' % Part.BOUNDARY + content_type = f'multipart/form-data; boundary={Part.BOUNDARY}' return content_type, Part.CRLF.join(all) diff --git a/setup.py b/setup.py index 89a1d65..e25f27b 100644 --- a/setup.py +++ b/setup.py @@ -8,18 +8,14 @@ r'__version__ = (\(.*?\))') cwd = os.path.dirname(os.path.abspath(__file__)) -fp = open(os.path.join(cwd, 'face_client', '__init__.py')) - -version = None -for line in fp: - match = version_re.search(line) - if match: - version = eval(match.group(1)) - break -else: - raise Exception('Cannot find version in __init__.py') -fp.close() - +with open(os.path.join(cwd, 'face_client', '__init__.py')) as fp: + version = None + for line in fp: + if match := version_re.search(line): + version = eval(match[1]) + break + else: + raise Exception('Cannot find version in __init__.py') setup(name='face_client', version='.' . join(map(str, version)), description='face.com face recognition Python API client library',