diff --git a/docs/vision-usage.rst b/docs/vision-usage.rst index 6b35edb6b486..216b9dad19e3 100644 --- a/docs/vision-usage.rst +++ b/docs/vision-usage.rst @@ -116,15 +116,15 @@ was detected. >>> faces = image.detect_faces(limit=10) >>> first_face = faces[0] >>> first_face.landmarks.left_eye.landmark_type - 'LEFT_EYE' + >>> first_face.landmarks.left_eye.position.x_coordinate 1301.2404 >>> first_face.detection_confidence 0.9863683 >>> first_face.joy - 0.54453093 + >>> first_face.anger - 0.02545464 + *************** @@ -227,13 +227,13 @@ categorize the entire contents of the image under four categories. >>> safe_search_results = image.detect_safe_search() >>> safe_search = safe_search_results[0] >>> safe_search.adult - 'VERY_UNLIKELY' + >>> safe_search.spoof - 'POSSIBLE' + >>> safe_search.medical - 'VERY_LIKELY' + >>> safe_search.violence - 'LIKELY' + ************** diff --git a/vision/google/cloud/vision/face.py b/vision/google/cloud/vision/face.py index dc1c6470225a..75ed4573cb81 100644 --- a/vision/google/cloud/vision/face.py +++ b/vision/google/cloud/vision/face.py @@ -15,6 +15,8 @@ """Face class representing the Vision API's face detection response.""" +from enum import Enum + from google.cloud.vision.geometry import BoundsBase from google.cloud.vision.likelihood import Likelihood from google.cloud.vision.geometry import Position @@ -91,11 +93,10 @@ def from_api_repr(cls, response): :rtype: :class:`~google.cloud.vision.face.Emotions` :returns: Populated instance of `Emotions`. """ - joy_likelihood = getattr(Likelihood, response['joyLikelihood']) - sorrow_likelihood = getattr(Likelihood, response['sorrowLikelihood']) - surprise_likelihood = getattr(Likelihood, - response['surpriseLikelihood']) - anger_likelihood = getattr(Likelihood, response['angerLikelihood']) + joy_likelihood = Likelihood[response['joyLikelihood']] + sorrow_likelihood = Likelihood[response['sorrowLikelihood']] + surprise_likelihood = Likelihood[response['surpriseLikelihood']] + anger_likelihood = Likelihood[response['angerLikelihood']] return cls(joy_likelihood, sorrow_likelihood, surprise_likelihood, anger_likelihood) @@ -172,8 +173,7 @@ def from_api_repr(cls, response): detection_confidence = response['detectionConfidence'] emotions = Emotions.from_api_repr(response) fd_bounds = FDBounds.from_api_repr(response['fdBoundingPoly']) - headwear_likelihood = getattr(Likelihood, - response['headwearLikelihood']) + headwear_likelihood = Likelihood[response['headwearLikelihood']] image_properties = FaceImageProperties.from_api_repr(response) landmarks = Landmarks(response['landmarks']) landmarking_confidence = response['landmarkingConfidence'] @@ -321,12 +321,10 @@ def from_api_repr(cls, response): :rtype: :class:`~google.cloud.vision.face.FaceImageProperties` :returns: Instance populated with image property data. """ - blurred_likelihood = getattr(Likelihood, - response['blurredLikelihood']) - underexposed_likelihood = getattr(Likelihood, - response['underExposedLikelihood']) + blurred = Likelihood[response['blurredLikelihood']] + underexposed = Likelihood[response['underExposedLikelihood']] - return cls(blurred_likelihood, underexposed_likelihood) + return cls(blurred, underexposed) @property def blurred(self): @@ -349,7 +347,7 @@ def underexposed(self): return self._underexposed_likelihood -class FaceLandmarkTypes(object): +class LandmarkTypes(Enum): """A representation of the face detection landmark types. See: @@ -413,7 +411,7 @@ def from_api_repr(cls, response_landmark): :returns: Populated instance of `Landmark`. """ position = Position.from_api_repr(response_landmark['position']) - landmark_type = getattr(FaceLandmarkTypes, response_landmark['type']) + landmark_type = LandmarkTypes[response_landmark['type']] return cls(position, landmark_type) @property @@ -440,4 +438,4 @@ class Landmarks(object): def __init__(self, landmarks): for landmark_response in landmarks: landmark = Landmark.from_api_repr(landmark_response) - setattr(self, landmark.landmark_type.lower(), landmark) + setattr(self, landmark.landmark_type.value.lower(), landmark) diff --git a/vision/google/cloud/vision/likelihood.py b/vision/google/cloud/vision/likelihood.py index 6239efe18251..93c9ddacd81d 100644 --- a/vision/google/cloud/vision/likelihood.py +++ b/vision/google/cloud/vision/likelihood.py @@ -15,7 +15,10 @@ """Likelihood constants returned from Vision API.""" -class Likelihood(object): +from enum import Enum + + +class Likelihood(Enum): """A representation of likelihood to give stable results across upgrades. See: diff --git a/vision/setup.py b/vision/setup.py index b9ee28770610..e5125b8cc4e8 100644 --- a/vision/setup.py +++ b/vision/setup.py @@ -50,6 +50,7 @@ REQUIREMENTS = [ + 'enum34', 'google-cloud-core >= 0.21.0, < 0.22dev', ] diff --git a/vision/tox.ini b/vision/tox.ini index e0d8c2b172de..c93fc5aab862 100644 --- a/vision/tox.ini +++ b/vision/tox.ini @@ -7,6 +7,7 @@ localdeps = pip install --quiet --upgrade {toxinidir}/../core deps = {toxinidir}/../core + enum34 mock pytest covercmd = diff --git a/vision/unit_tests/test_client.py b/vision/unit_tests/test_client.py index edac6adb0e5f..81baa18c1d5c 100644 --- a/vision/unit_tests/test_client.py +++ b/vision/unit_tests/test_client.py @@ -359,6 +359,7 @@ def test_text_detection_from_source(self): self.assertEqual(694, text[0].bounds.vertices[0].y_coordinate) def test_safe_search_detection_from_source(self): + from google.cloud.vision.likelihood import Likelihood from google.cloud.vision.safe import SafeSearchAnnotation from unit_tests._fixtures import SAFE_SEARCH_DETECTION_RESPONSE @@ -373,10 +374,10 @@ def test_safe_search_detection_from_source(self): image_request = client._connection._requested[0]['data']['requests'][0] self.assertEqual(IMAGE_SOURCE, image_request['image']['source']['gcs_image_uri']) - self.assertEqual('VERY_UNLIKELY', safe_search.adult) - self.assertEqual('UNLIKELY', safe_search.spoof) - self.assertEqual('POSSIBLE', safe_search.medical) - self.assertEqual('VERY_UNLIKELY', safe_search.violence) + self.assertEqual(safe_search.adult, Likelihood.VERY_UNLIKELY) + self.assertEqual(safe_search.spoof, Likelihood.UNLIKELY) + self.assertEqual(safe_search.medical, Likelihood.POSSIBLE) + self.assertEqual(safe_search.violence, Likelihood.VERY_UNLIKELY) def test_safe_search_no_results(self): RETURNED = { diff --git a/vision/unit_tests/test_face.py b/vision/unit_tests/test_face.py index 0c2a568268d6..7e4739056f08 100644 --- a/vision/unit_tests/test_face.py +++ b/vision/unit_tests/test_face.py @@ -29,6 +29,8 @@ def setUp(self): self.FACE_ANNOTATIONS['faceAnnotations'][0]) def test_face_landmarks(self): + from google.cloud.vision.face import LandmarkTypes + self.assertEqual(0.54453093, self.face.landmarking_confidence) self.assertEqual(0.9863683, self.face.detection_confidence) self.assertTrue(hasattr(self.face.landmarks, 'left_eye')) @@ -38,8 +40,8 @@ def test_face_landmarks(self): self.face.landmarks.left_eye.position.y_coordinate) self.assertEqual(0.0016593217, self.face.landmarks.left_eye.position.z_coordinate) - self.assertEqual('LEFT_EYE', - self.face.landmarks.left_eye.landmark_type) + self.assertEqual(self.face.landmarks.left_eye.landmark_type, + LandmarkTypes.LEFT_EYE) def test_facial_emotions(self): from google.cloud.vision.face import Likelihood