Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions gcloud/vision/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

"""Google Cloud Vision API package."""


from gcloud.vision.client import Client
from gcloud.vision.feature import FeatureTypes
90 changes: 90 additions & 0 deletions gcloud/vision/annotation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

"""Define annotations."""


class EntityAnnotation(object):
def __init__(self, mid, locale, description, score, confidence, topicality,
bounding_poly, locations, properties):
self._mid = mid
self._locale = locale
self._description = description
self._score = score
self._confidence = confidence
self._topicality = topicality
self._bounding_poly = bounding_poly
self._locations = locations
self._properties = properties

@property
def mid(self):
return self._mid

@property
def locale(self):
return self._locale

@property
def description(self):
return self._description

@property
def score(self):
return self._score

@property
def confidence(self):
return self._confidence

@property
def topicality(self):
return self._topicality

@property
def bounding_poly(self):
return self._bounding_poly

@property
def locations(self):
return self._locations

@property
def properties(self):
return self._properties


class LabelAnnotation(EntityAnnotation):
def __init__(self):
raise NotImplementedError


class LandmarkAnnotation(EntityAnnotation):
def __init__(self):
raise NotImplementedError


class LogoAnnotation(EntityAnnotation):
def __init__(self):
raise NotImplementedError


class TextAnnotation(EntityAnnotation):
def __init__(self):
raise NotImplementedError


class SafeSearchAnnotation(EntityAnnotation):
def __init__(self):
raise NotImplementedError
139 changes: 139 additions & 0 deletions gcloud/vision/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# 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.

"""Client for interacting with the Google Cloud Vision API."""

import json
from json import JSONEncoder

from gcloud.client import JSONClient
from gcloud.vision.connection import Connection
from gcloud.vision.feature import Feature
from gcloud.vision.image import Image


class VisionJSONEncoder(JSONEncoder):

This comment was marked as spam.

def default(self, o):
if 'as_dict' in dir(o):
return o.as_dict()
else:
return o.__dict__


class VisionRequest(object):
def __init__(self, image, feature):
self._features = []
self._image = image

if isinstance(feature, list):
self._features.extend(feature)
elif isinstance(feature, Feature):
self._features.append(feature)

def as_dict(self):
return {
'image': self.image,
'features': self.features
}

@property
def features(self):
return self._features

@property
def image(self):
return self._image


class Client(JSONClient):
"""Client to bundle configuration needed for API requests.

:type project: str
:param project: the project which the client acts on behalf of.
If not passed, falls back to the default inferred
from the environment.

:type credentials: :class:`oauth2client.client.OAuth2Credentials` or
:class:`NoneType`
:param credentials: The OAuth2 Credentials to use for the connection
owned by this client. If not passed (and if no ``http``
object is passed), falls back to the default inferred
from the environment.

:type http: :class:`httplib2.Http` or class that defines ``request()``.
:param http: An optional HTTP object to make requests. If not passed, an
``http`` object is created that is bound to the
``credentials`` for the current object.

Usage:

This comment was marked as spam.

This comment was marked as spam.

.. code::
>>> from gcloud import vision
>>> vision_client = vision.Client()
>>> with open('/tmp/car.jpg', 'r') as f:
... vision_client.annotate(f.read(), vision.LABEL_DETECTION, 3)

Multiple images example:

This comment was marked as spam.

.. code::
>>> images = (('./image.jpg', [vision.FeatureTypes.LABEL_DETECTION,
... vision.FeatureTypes.LANDMARK_DETECTION]),
... ('./image2.jpg', [vision.FeatureTypes.FACE_DETECTION,
vision.FeatureTypes.TEXT_DETECTION]),)
>>> annotated_images = []
>>> for image, feature_types in images:
... annotated_images.append(vision_client.annotate(image,
... feature_types))
"""

_connection_class = Connection

def annotate(self, image, feature_type, max_results=1):
"""Annotate an image to discover it's attributes.

:type image: str
:param image: A string which can be a URL, a Google Cloud Storage path,
or a byte stream of the image.

:type feature_type: str or list
:param feature_type: The type of detection that the Vision API should
use to determine image attributes. *Pricing is
based on the number of Feature Types.

See:
https://cloud.google.com/vision/docs/pricing


:type max_results: int
:param max_results: The number of results per feature type to be
returned.
"""
data = {'requests': []}
features = []

if isinstance(image, str):
img = Image(image)

if isinstance(feature_type, list):
for feature in feature_type:
features.append(Feature(feature, max_results))
else:
features.append(Feature(feature_type, max_results))

data['requests'].append(VisionRequest(img, features))

data = json.dumps(data, cls=VisionJSONEncoder)

This comment was marked as spam.

This comment was marked as spam.

resp = self.connection.api_request(method='POST',
path='/images:annotate',
data=data)
resp = resp['responses']
return resp
47 changes: 47 additions & 0 deletions gcloud/vision/connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# 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.


"""Create / interact with gcloud Vision connections."""


from gcloud import connection as base_connection


class Connection(base_connection.JSONConnection):
"""A connection to Google Cloud Vision via the JSON REST API.

:type credentials: :class:`oauth2client.client.OAuth2Credentials`
:param credentials: (Optional) The OAuth2 Credentials to use for this
connection.

:type http: :class:`httplib2.Http` or class that defines ``request()``.
:param http: (Optional) HTTP object to make requests.

:type api_base_url: string
:param api_base_url: The base of the API call URL. Defaults to the value
:attr:`Connection.API_BASE_URL`.
"""

API_BASE_URL = 'https://vision.googleapis.com'
"""The base of the API call URL."""

API_VERSION = 'v1'
"""The version of the API, used in building the API call's URL."""

API_URL_TEMPLATE = '{api_base_url}/{api_version}{path}'
"""A template for the URL of a particular API call."""

SCOPE = ('https://www.googleapis.com/auth/cloud-platform',)
"""The scopes required for authenticating as a Cloud Vision consumer."""
62 changes: 62 additions & 0 deletions gcloud/vision/feature.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2016 Google Inc. All rights reserved.
#
# 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.


class FeatureTypes(object):
"""Feature Types to indication which annotations to perform.

See:
https://cloud.google.com/vision/reference/rest/v1/images/annotate#Type
"""
FACE_DETECTION = 'FACE_DETECTION'
LANDMARK_DETECTION = 'LANDMARK_DETECTION'
LOGO_DETECTION = 'LOGO_DETECTION'
LABEL_DETECTION = 'LABEL_DETECTION'
TEXT_DETECTION = 'TEXT_DETECTION'
SAFE_SEARCH_DETECTION = 'SAFE_SEARCH_DETECTION'


class Feature(object):
"""Feature object specifying the annotation type and maximum results.

:type feature_type: str
:param feature_type: String representation of feature type.

:type max_results: int
:param max_results: Number of results to return for the specified
feature type.

See:
https://cloud.google.com/vision/reference/rest/v1/images/annotate#Feature
"""
def __init__(self, feature_type, max_results=1):
self._feature_type = getattr(FeatureTypes, feature_type)
self._max_results = int(max_results)

def as_dict(self):
"""Generate dictionary for Feature request format."""
return {
'type': self.feature_type,
'maxResults': self.max_results
}

@property
def feature_type(self):
""""Feature type string."""
return self._feature_type

@property
def max_results(self):
"""Maximum number of results for feature type."""
return self._max_results
Loading