Skip to content
This repository has been archived by the owner on Aug 9, 2022. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ytaichi committed Aug 4, 2017
0 parents commit 142c136
Show file tree
Hide file tree
Showing 23 changed files with 1,240 additions and 0 deletions.
5 changes: 5 additions & 0 deletions LICENSE
@@ -0,0 +1,5 @@
The MIT License (MIT)
Copyright (c) 2017 Ricoh Co., Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68 changes: 68 additions & 0 deletions README.rst
@@ -0,0 +1,68 @@
=========
RICOH Cloud SDK for Python
=========

Python client library for RICOH Cloud API.

------------
Installation
------------
::

$ git clone https://github.com/ricohapi/ricoh-cloud-sdk-python.git
$ cd ricoh-cloud-sdk-python
$ pip install .

You can also download the SDK in a zip file from https://github.com/ricohapi/ricoh-cloud-sdk-python/releases and unzip it to ``<install_dir>``.

--------
SDK Usage
--------

Auth Constructor
--------------
To use any modules of the RICOH Cloud SDK, initialize ``AuthClient`` with your valid Client Credentials.

::

from ricohcloudsdk.auth.client import AuthClient
aclient = AuthClient('<your_client_id>', '<your_client_secret>')


Visual Recognition
------------------
Initialize ``VisualRecognition`` with an ``AuthClient`` object.

::

from ricohcloudsdk.auth.client import AuthClient
from ricohcloudsdk.vrs.client import VisualRecognition
aclient = AuthClient('<your_client_id>', '<your_client_secret>')
vr_client = VisualRecognition(aclient)

For ``detect_faces()`` and ``detect_humans()``, set either ``<image_uri>`` or ``<image_path>`` as an argument.

::

vr_client.detect_faces('<image_uri> or <image_path>')
vr_client.detect_humans('<image_uri> or <image_path>')

For ``compare_faces()``, set two arguments; one for source image location and the other for target image location.

You need to make sure that those two arguments are a pair of URIs OR a pair of paths. You cannot set a URI and a path at the same time.

::

vr_client.compare_faces('<source_image_uri> or <source_image_path>', '<target_image_uri> or <target_image_path>')

--------
Sample Codes
--------

- `Visual Recognition Sample Code <./samples/visual-recognition/>`_

--------
See Also
--------

- `RICOH Cloud API Developer Guide <https://api.ricoh/docs/ricoh-cloud-api/>`_
1 change: 1 addition & 0 deletions ricohcloudsdk/__init__.py
@@ -0,0 +1 @@
__version__ = '0.3.0'
Empty file added ricohcloudsdk/auth/__init__.py
Empty file.
90 changes: 90 additions & 0 deletions ricohcloudsdk/auth/client.py
@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 Ricoh Co., Ltd. All Rights Reserved.

"""
RICOH Cloud API AUTH
"""

import time
import json
import requests
from requests.auth import HTTPBasicAuth


class AuthClient(object):
"""auth client"""
__ENDPOINT = 'https://auth.api.ricoh'
__MARGIN_SEC = 10

SCOPES = {
'vrs': ('ips.api.ricoh/v1/detect_faces',
'ips.api.ricoh/v1/compare_faces',
'ips.api.ricoh/v1/detect_humans')
}

@staticmethod
def __raise_value_error():
raise ValueError('Could not get an access token to allow your access. '
'Make sure that your Client ID and Client Secret are correct.')

def __init__(self, client_id, client_secret):
self.__scopes = ''
self.__grant_type = 'client_credentials'
self.__bauth = HTTPBasicAuth(client_id, client_secret)
self.__access_token = ''
self.__api_key = ''
self.__expire = 0

def __auth(self):
params = {
'grant_type': self.__grant_type,
'scope': self.__scopes
}
try:
req = requests.post(AuthClient.__ENDPOINT +
'/v1/token',
auth=self.__bauth,
data=params)
req.raise_for_status()
except requests.exceptions.RequestException:
raise
try:
ret = json.loads(req.text)
except ValueError:
AuthClient.__raise_value_error()
return ret

def __store_token_info(self, retval):
try:
self.__access_token = retval['access_token']
self.__api_key = retval['api_key']
self.__expire = retval['expires_in'] + \
int(time.time()) - AuthClient.__MARGIN_SEC
except KeyError:
AuthClient.__raise_value_error()

def session(self, scope):
"""Start session."""
self.__scopes = ' '.join(scope)

ret = self.__auth()
self.__store_token_info(ret)
return ret

def get_access_token(self):
"""Get AccessToken."""
if int(time.time()) < self.__expire:
return self.__access_token

ret = self.__auth()
self.__store_token_info(ret)
return self.__access_token

def get_api_key(self):
"""Get APIKey."""
if int(time.time()) < self.__expire:
return self.__api_key

ret = self.__auth()
self.__store_token_info(ret)
return self.__api_key
44 changes: 44 additions & 0 deletions ricohcloudsdk/exceptions.py
@@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 Ricoh Co., Ltd. All Rights Reserved.

"""
Exceptions for RICOH Cloud SDK
"""


class BaseError(Exception):
"""Base class for exceptions in this module."""

def __init__(self, status_code, response):
_UNDEFINED = 'undefined'
_MESSAGE = 'http_status: {status_code}, code: {code}, message: {message}'
if not isinstance(response, dict):
code = _UNDEFINED
message = response
elif 'message' in response:
code = _UNDEFINED
message = response.get('message', _UNDEFINED)
elif 'error' in response:
code = response['error'].get('code', _UNDEFINED),
message = response['error'].get('message', _UNDEFINED)
else:
code = _UNDEFINED
message = _UNDEFINED
error_message = _MESSAGE.format(
status_code=status_code,
code=code,
message=message
)
super(BaseError, self).__init__(error_message)
self.status_code = status_code
self.response = response


class ClientError(BaseError):
"""Exception raised for 4xx errors in the HTTP response."""
pass


class ServerError(BaseError):
"""Exception raised for 5xx errors in the HTTP response."""
pass
Empty file added ricohcloudsdk/vrs/__init__.py
Empty file.
83 changes: 83 additions & 0 deletions ricohcloudsdk/vrs/client.py
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 Ricoh Co., Ltd. All Rights Reserved.

"""
RICOH Cloud API Visual Recognition
"""
import json
from ricohcloudsdk.auth.client import AuthClient
from . import util


class VisualRecognition(object):
"""visual recognition client"""
__ENDPOINT = 'https://ips.api.ricoh/v1'
__SCOPE = AuthClient.SCOPES['vrs']
__CTYPE_JSON = 'application/json'

def __init__(self, aclient):
self.__aclient = aclient
self.__aclient.session(VisualRecognition.__SCOPE)

def __get_common_headers(self):
return {
'Authorization': 'Bearer ' + self.__aclient.get_access_token(),
'x-api-key': self.__aclient.get_api_key()
}

def __send_detect(self, api_path, resource):
api_path = VisualRecognition.__ENDPOINT + api_path
headers = self.__get_common_headers()
r_type = util.get_type(resource)

if r_type == 'uri':
headers['Content-Type'] = VisualRecognition.__CTYPE_JSON
payload = json.dumps({
'image': resource
})
ret = util.post(api_path, headers=headers, data=payload)
else:
headers['Content-Type'] = 'image/' + r_type
with open(resource, 'rb') as payload:
ret = util.post(api_path, headers=headers, data=payload)
return ret

def __send_compare(self, source, target):
api_path = VisualRecognition.__ENDPOINT + '/compare_faces'
headers = self.__get_common_headers()
src_type = util.get_type(source)
tar_type = util.get_type(target)

if src_type == 'uri' and tar_type == 'uri':
headers['Content-Type'] = VisualRecognition.__CTYPE_JSON
payload = json.dumps({
'source': source,
'target': target
})
ret = util.post(api_path, headers=headers, data=payload)
elif src_type in util.SUPPORTED_IMAGE_TYPE and tar_type in util.SUPPORTED_IMAGE_TYPE:
with open(source, 'rb') as src_img, open(target, 'rb') as tar_img:
file_payload = {
'source': src_img,
'target': tar_img
}
ret = util.post(api_path, headers=headers, files=file_payload)
else:
util.raise_combination_error()

return ret

def detect_faces(self, resource):
"""Face detection method."""
res = self.__send_detect('/detect_faces', resource)
return res

def detect_humans(self, resource):
"""Human detection method."""
res = self.__send_detect('/detect_humans', resource)
return res

def compare_faces(self, source, target):
"""Face recognition method."""
res = self.__send_compare(source, target)
return res
56 changes: 56 additions & 0 deletions ricohcloudsdk/vrs/util.py
@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017 Ricoh Co., Ltd. All Rights Reserved.

"""
Utility for the Visual Recognition
"""
import os
import imghdr
import json
import re
import requests
from ricohcloudsdk.exceptions import ClientError, ServerError

SUPPORTED_IMAGE_TYPE = {'jpeg', 'png'}


def raise_unsupported_error():
raise ValueError('One of the image resource was unsupported format.')


def raise_resource_error():
raise ValueError(
'An invalid value was specified for one of the image resource parameters.')


def raise_combination_error():
raise ValueError(
'Different combinations for image resource format are not allowed.')


def get_type(resource):
"""Check the resource type."""
if os.path.isfile(resource):
image_type = imghdr.what(resource)
if image_type not in SUPPORTED_IMAGE_TYPE:
raise_unsupported_error()
r_type = image_type
elif re.match(r'^https?:\/\/', resource):
r_type = 'uri'
else:
raise_resource_error()
return r_type


def post(api_path, **kwargs):
"""Send data to the API endpoint and receive the result."""
req = requests.post(api_path, **kwargs)
try:
ret = json.loads(req.text)
except ValueError:
ret = req.text
if 400 <= req.status_code < 500:
raise ClientError(req.status_code, ret)
elif req.status_code >= 500:
raise ServerError(req.status_code, ret)
return ret
5 changes: 5 additions & 0 deletions samples/visual-recognition/LICENSE
@@ -0,0 +1,5 @@
The MIT License (MIT)
Copyright (c) 2017 Ricoh Co., Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

0 comments on commit 142c136

Please sign in to comment.