"""PredictoinIO Python SDK

The PredictoinIO Python SDK provides easy-to-use functions for integrating
Python applications with PredictionIO REST API services.
"""

__author__ = "The PredictionIO Team"
__email__ = "help@tappingstone.com"
__copyright__ = "Copyright 2014, TappingStone, Inc."
__license__ = "Apache License, Version 2.0"

__version__ = "0.7.0"


# import packages
import re
try:
  import httplib
except ImportError:
  # pylint: disable=F0401
  # http is a Python3 module, replacing httplib
  from http import client as httplib
import json
import urllib

from predictionio.connection import Connection
from predictionio.connection import AsyncRequest
from predictionio.connection import PredictionIOAPIError

"""Error exception defined for this API

Should be handled by the user
"""


class ServerStatusError(PredictionIOAPIError):

  "Error happened when tried to get status of the API server"
  pass


class UserNotCreatedError(PredictionIOAPIError):

  "Error happened when tried to create user"
  pass


class UserNotFoundError(PredictionIOAPIError):

  "Error happened when tried to get user"
  pass


class UserNotDeletedError(PredictionIOAPIError):

  "Error happened when tried to delete user"
  pass


class ItemNotCreatedError(PredictionIOAPIError):

  "Error happened when tried to create item"
  pass


class ItemNotFoundError(PredictionIOAPIError):

  "Error happened when tried to get item"
  pass


class ItemNotDeletedError(PredictionIOAPIError):

  "Error happened when tried to delete item"
  pass


class U2IActionNotCreatedError(PredictionIOAPIError):

  "Error happened when tried to create user-to-item action"
  pass


class ItemRecNotFoundError(PredictionIOAPIError):

  "Error happened when tried to get item recommendation"
  pass


class ItemSimNotFoundError(PredictionIOAPIError):

  "Error happened when tried to get similar items"
  pass

class ItemRankNotFoundError(PredictionIOAPIError):

  "Error happened when treid to rank item"
  pass

class InvalidArgumentError(PredictionIOAPIError):

  "Arguments are not valid"
  pass

# map to API
LIKE_API = "like"
DISLIKE_API = "dislike"
VIEW_API = "view"
CONVERSION_API = "conversion"
RATE_API = "rate"


class Client(object):

  """PredictionIO client object.

  This is an object representing a PredictionIO's client. This object
  provides methods for making PredictionIO API requests.

  :param appkey: the App Key provided by PredictionIO.
  :param threads: number of threads to handle PredictionIO API requests.
          Must be >= 1.
  :param apiurl: the PredictionIO API URL path.
  :param apiversion: the PredictionIO API version. (optional)
       (eg. "", or "/v1")
  :param qsize: the max size of the request queue (optional).
      The asynchronous request becomes blocking once this size has been
      reached, until the queued requests are handled.
      Default value is 0, which means infinite queue size.
  :param timeout: timeout for HTTP connection attempts and requests in
    seconds (optional).
    Default value is 5.

  """

  def __init__(self, appkey, threads=1, apiurl="http://localhost:8000",
         apiversion="", qsize=0, timeout=5):
    """Constructor of Client object.

    """
    self.appkey = appkey
    self.threads = threads
    self.apiurl = apiurl
    self.apiversion = apiversion
    self.qsize = qsize
    self.timeout = timeout

    # check connection type
    https_pattern = r'^https://(.*)'
    http_pattern = r'^http://(.*)'
    m = re.match(https_pattern, apiurl)
    self.https = True
    if m is None:  # not matching https
      m = re.match(http_pattern, apiurl)
      self.https = False
      if m is None:  # not matching http either
        raise InvalidArgumentError("apiurl is not valid: %s" % apiurl)
    self.host = m.group(1)

    self._uid = None  # identified uid
    self._connection = Connection(host=self.host, threads=self.threads,
                    qsize=self.qsize, https=self.https,
                    timeout=self.timeout)

  def close(self):
    """Close this client and the connection.

    Call this method when you want to completely terminate the connection
    with PredictionIO.
    It will wait for all pending requests to finish.
    """
    self._connection.close()

  def pending_requests(self):
    """Return the number of pending requests.

    :returns:
      The number of pending requests of this client.
    """
    return self._connection.pending_requests()

  def identify(self, uid):
    """Identify the uid

    :param uid: user id. type str.
    """
    self._uid = uid

  def get_status(self):
    """Get the status of the PredictionIO API Server

    :returns:
      status message.

    :raises:
      ServerStatusError.
    """
    path = "/"
    request = AsyncRequest("GET", path)
    request.set_rfunc(self._aget_status_resp)
    self._connection.make_request(request)
    result = self.aresp(request)
    return result

  def _aget_status_resp(self, response):
    """Handle the AsyncResponse of get status request"""
    if response.error is not None:
      raise ServerStatusError("Exception happened: %s for request %s" %
                  (response.error, response.request))
    elif response.status != httplib.OK:
      raise ServerStatusError("request: %s status: %s body: %s" %
                  (response.request, response.status,
                   response.body))

    # data = json.loads(response.body) # convert json string to dict
    return response.body

  def acreate_user(self, uid, params={}):
    """Asynchronously create a user.

    :param uid: user id. type str.
    :param params: optional attributes. type dictionary.
        For example,
        { 'custom': 'value', 'pio_inactive' : True,
        'pio_latlng': [4.5,67.8] }

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.

    """

    if "pio_latlng" in params:
      params["pio_latlng"] = ",".join(map(str, params["pio_latlng"]))
    if "pio_inactive" in params:
      params["pio_inactive"] = str(params["pio_inactive"]).lower()

    path = "%s/users.json" % self.apiversion
    request = AsyncRequest(
      "POST", path, pio_appkey=self.appkey, pio_uid=uid, **params)
    request.set_rfunc(self._acreate_user_resp)
    self._connection.make_request(request)

    return request

  def _acreate_user_resp(self, response):
    """Private function to handle the AsyncResponse of the acreate_user
    request.

    :param response: AsyncResponse object.

    :returns:
      None.

    :raises:
      UserNotCreatedError.

    """
    if response.error is not None:
      raise UserNotCreatedError("Exception happened: %s for request %s" %
                    (response.error, response.request))
    elif response.status != httplib.CREATED:
      raise UserNotCreatedError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))

    return None

  def aget_user(self, uid):
    """Asynchronously get user.

    :param uid: user id. type str.

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    enc_uid = urllib.quote(uid, "")  # replace special char with %xx
    path = "%s/users/%s.json" % (self.apiversion, enc_uid)
    request = AsyncRequest("GET", path, pio_appkey=self.appkey)
    request.set_rfunc(self._aget_user_resp)
    self._connection.make_request(request)

    return request

  def _aget_user_resp(self, response):
    """Private function to handle the AsyncResponse of the aget_user
    request .

    :param response: AsyncResponse object.

    :returns:
      User data in Dictionary format.

    :rasies:
      UserNotFoundError.

    """
    if response.error is not None:
      raise UserNotFoundError("Exception happened: %s for request %s" %
                  (response.error, response.request))
    elif response.status != httplib.OK:
      raise UserNotFoundError("request: %s status: %s body: %s" %
                  (response.request, response.status,
                   response.body))

    data = json.loads(response.body)  # convert json string to dict
    return data

  def adelete_user(self, uid):
    """Asynchronously delete user.

    :param uid: user id. type str.

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    enc_uid = urllib.quote(uid, "")  # replace special char with %xx
    path = "%s/users/%s.json" % (self.apiversion, enc_uid)
    request = AsyncRequest("DELETE", path, pio_appkey=self.appkey)
    request.set_rfunc(self._adelete_user_resp)
    self._connection.make_request(request)

    return request

  def _adelete_user_resp(self, response):
    """Private function to handle the AsyncResponse of the adelete_user
    request.

    :param response: AsyncResponse object.

    :returns:
      None.

    :raises:
      UserNotDeletedError.

    """
    if response.error is not None:
      raise UserNotDeletedError("Exception happened: %s for request %s" %
                    (response.error, response.request))
    elif response.status != httplib.OK:
      raise UserNotDeletedError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))
    return None

  def acreate_item(self, iid, itypes, params={}):
    """Asynchronously create item.

    :param iid: item id. type str.
    :param itypes: item types. Tuple of Str.
        For example, if this item belongs to item types "t1", "t2",
        "t3", "t4",then itypes=("t1", "t2", "t3", "t4").
        NOTE: if this item belongs to only one itype, use tuple of one
        element, eg. itypes=("t1",)
    :param params: optional attributes. type dictionary.
        For example,
        { 'custom': 'value', 'pio_inactive' : True,
        'pio_latlng': [4.5,67.8] }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    itypes_str = ",".join(itypes)  # join items with ","

    if "pio_latlng" in params:
      params["pio_latlng"] = ",".join(map(str, params["pio_latlng"]))
    if "pio_inactive" in params:
      params["pio_inactive"] = str(params["pio_inactive"]).lower()

    path = "%s/items.json" % self.apiversion
    request = AsyncRequest("POST", path, pio_appkey=self.appkey,
                 pio_iid=iid, pio_itypes=itypes_str, **params)
    request.set_rfunc(self._acreate_item_resp)
    self._connection.make_request(request)
    return request

  def _acreate_item_resp(self, response):
    """Private function to handle the AsyncResponse of the acreate_item
    request

    :param response: AsyncResponse object.

    :returns:
      None
    :raises:
      ItemNotCreatedError

    """
    if response.error is not None:
      raise ItemNotCreatedError("Exception happened: %s for request %s" %
                    (response.error, response.request))
    elif response.status != httplib.CREATED:
      raise ItemNotCreatedError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))
    return None

  def aget_item(self, iid):
    """Asynchronously get item

    :param iid: item id. type str.

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    enc_iid = urllib.quote(iid, "")
    path = "%s/items/%s.json" % (self.apiversion, enc_iid)
    request = AsyncRequest("GET", path, pio_appkey=self.appkey)
    request.set_rfunc(self._aget_item_resp)
    self._connection.make_request(request)
    return request

  def _aget_item_resp(self, response):
    """Private function to handle the AsyncResponse of the aget_item
    request

    :param response: AsyncResponse object.

    :returns:
      item data in dictionary format.

    :raises:
      ItemNotFoundError.

    """
    if response.error is not None:
      raise ItemNotFoundError("Exception happened: %s for request %s" %
                  (response.error, response.request))
    elif response.status != httplib.OK:
      raise ItemNotFoundError("request: %s status: %s body: %s" %
                  (response.request, response.status,
                   response.body))

    data = json.loads(response.body)  # convert json string to dict
    if "pio_itypes" in data:
      # convert from list to tuple
      data["pio_itypes"] = tuple(data["pio_itypes"])

    return data

  def adelete_item(self, iid):
    """Asynchronously delete item

    :param iid: item id. type str.

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    enc_iid = urllib.quote(iid, "")
    path = "%s/items/%s.json" % (self.apiversion, enc_iid)
    request = AsyncRequest("DELETE", path, pio_appkey=self.appkey)
    request.set_rfunc(self._adelete_item_resp)
    self._connection.make_request(request)
    return request

  def _adelete_item_resp(self, response):
    """Private function to handle the AsyncResponse of the adelete_item
    request

    :param response: AsyncResponse object

    :returns:
      None

    :raises:
      ItemNotDeletedError
    """
    if response.error is not None:
      raise ItemNotDeletedError("Exception happened: %s for request %s" %
                    (response.error, response.request))
    elif response.status != httplib.OK:
      raise ItemNotDeletedError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))
    return None

  def _aget_user_itemrec_topn(self, engine, uid, n, params={}):
    """Private function to asynchronously get recommendations for user

    :param engine: name of the prediction engine. type str.
    :param uid: user id. type str.
    :param n: number of recommendation. type int.
    :param params: optional parameters. type dictionary
        For example, { 'pio_itypes' : ("t1","t2") }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    if "pio_itypes" in params:
      params["pio_itypes"] = ",".join(params["pio_itypes"])
    if "pio_latlng" in params:
      params["pio_latlng"] = ",".join(map(str, params["pio_latlng"]))
    if "pio_attributes" in params:
      params["pio_attributes"] = ",".join(params["pio_attributes"])

    path = "%s/engines/itemrec/%s/topn.json" % (self.apiversion, engine)
    request = AsyncRequest("GET", path, pio_appkey=self.appkey,
                 pio_uid=uid, pio_n=n, **params)
    request.set_rfunc(self._aget_user_itemrec_topn_resp)
    self._connection.make_request(request)
    return request

  def _aget_user_itemrec_topn_resp(self, response):
    """Private function to handle the AsyncResponse of the aget_itemrec
    request

    :param response: AsyncResponse object

    :returns:
      data in dictionary format.

    :raises:
      ItemRecNotFoundError.
    """
    if response.error is not None:
      raise ItemRecNotFoundError(
        "Exception happened: %s for request %s" %
        (response.error, response.request))
    elif response.status != httplib.OK:
      raise ItemRecNotFoundError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))

    data = json.loads(response.body)  # convert json string to dict
    return data

  def aget_itemrec_topn(self, engine, n, params={}):
    """Asynchronously get recommendations for the identified user

    :param engine: name of the prediction engine. type str.
    :param n: number of recommendation. type int.
    :param params: optional parameters. type dictionary
        For example, { 'pio_itypes' : ("t1",) }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    if self._uid is None:
      raise InvalidArgumentError(
        "uid is not identified. Please call identify(uid) first.")

    request = self._aget_user_itemrec_topn(engine, self._uid, n, params)
    return request

  def aget_itemrec(self, uid, n, engine, **params):
    """Deprecated. Asynchronously get recommendations

    :param uid: user id. type str.
    :param n: number of recommendation. type int.
    :param engine: name of the prediction engine. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng="123.4, 56.7"
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    request = self._aget_user_itemrec_topn(engine, uid, n, params)
    return request

  def _aget_itemsim_topn(self, engine, iid, n, params={}):
    """Private function to asynchronously get top n similar items of the
    item

    :param engine: name of the prediction engine. type str.
    :param iid: item id. type str.
    :param n: number of similar items. type int.
    :param params: optional parameters. type dictionary
        For example, { 'pio_itypes' : ("t1","t2") }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    if "pio_itypes" in params:
      params["pio_itypes"] = ",".join(params["pio_itypes"])
    if "pio_latlng" in params:
      params["pio_latlng"] = ",".join(map(str, params["pio_latlng"]))
    if "pio_attributes" in params:
      params["pio_attributes"] = ",".join(params["pio_attributes"])

    path = "%s/engines/itemsim/%s/topn.json" % (self.apiversion, engine)
    request = AsyncRequest("GET", path, pio_appkey=self.appkey,
                 pio_iid=iid, pio_n=n, **params)
    request.set_rfunc(self._aget_itemsim_topn_resp)
    self._connection.make_request(request)
    return request

  def _aget_itemsim_topn_resp(self, response):
    """Private function to handle the AsyncResponse of the aget_itemsim
    request

    :param response: AsyncResponse object

    :returns:
      data in dictionary format.

    :raises:
      ItemSimNotFoundError.
    """
    if response.error is not None:
      raise ItemSimNotFoundError(
        "Exception happened: %s for request %s" %
        (response.error, response.request))
    elif response.status != httplib.OK:
      raise ItemSimNotFoundError("request: %s status: %s body: %s" %
                    (response.request, response.status,
                     response.body))

    data = json.loads(response.body)  # convert json string to dict
    return data

  def aget_itemsim_topn(self, engine, iid, n, params={}):
    """Asynchronously get top n similar items of the item

    :param engine: name of the prediction engine. type str.
    :param iid: item id. type str.
    :param n: number of similar items. type int.
    :param params: optional parameters. type dictionary
        For example, { 'pio_itypes' : ("t1",) }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    request = self._aget_itemsim_topn(engine, iid, n, params)
    return request

  def _aget_user_itemrank_ranked(self, engine, uid, iids, params={}):
    """Private function to asynchronously get ranked item for user

    :param engine: name of the prediction engine. type str.
    :param uid: user id. type str.
    :param iids: items to be ranked. type list of item ids.
      For example, ["i0", "i1", "i2"]
    :param params: optional parameters. type dictionary
      For example. { 'pio_attributes' : "name" }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    if "pio_attributes" in params:
      params["pio_attributes"] = ",".join(params["pio_attributes"])

    pio_iids = ",".join(iids)

    path = "%s/engines/itemrank/%s/ranked.json" % \
      (self.apiversion, engine)
    request = AsyncRequest("GET", path, pio_appkey=self.appkey,
                           pio_uid=uid, pio_iids=pio_iids, **params)
    request.set_rfunc(self._aget_user_itemrank_ranked_resp)
    self._connection.make_request(request)
    return request

  def _aget_user_itemrank_ranked_resp(self, response):
    """Private function to handle the AsyncResponse of the aget_itemreoder
      request

    :param response: AsyncResponse object

    :returns:
      data in dictionary format.

    :raises:
      ItemRankNotFoundError.
    """
    if response.error is not None:
      raise ItemRankNotFoundError(
        "Exception happened: %s for request %s" %
        (response.error, response.request))
    elif response.status != httplib.OK:
      raise ItemRankNotFoundError("request: %s status: %s body: %s" %
                                  (response.request, response.status,
                                   response.body))

    data = json.loads(response.body)  # convert json string to dict
    return data

  def aget_itemrank_ranked(self, engine, iids, params={}):
    """Asynchronously get ranked item for user

    :param engine: name of the prediction engine. type str.
    :param iids: items to be ranked. type list of item ids.
      For example, ["i0", "i1", "i2"]
    :param params: optional parameters. type dictionary
      For example. { 'pio_attributes' : "name" }
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    if self._uid is None:
      raise InvalidArgumentError(
        "uid is not identified. Please call identify(uid) first.")

    request = self._aget_user_itemrank_ranked(engine,
      self._uid, iids, params)
    return request

  def _auser_action_on_item(self, action, uid, iid, params):
    """Private function to asynchronously create an user action on an item

    :param action: action type. type str. ("like", "dislike", "conversion",
                         "rate", "view")
    :param uid: user id. type str or int.
    :param iid: item id. type str or int.
    :param params: optional attributes. type dictionary.
        For example, { 'pio_rate' : 4, 'pio_latlng' : [1.23,4.56] }
        NOTE: For "rate" action, pio_rate attribute is required.
            integer value of 1-5 (1 is least preferred and 5 is most
            preferred)

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    if "pio_latlng" in params:
      params["pio_latlng"] = ",".join(map(str, params["pio_latlng"]))

    path = "%s/actions/u2i.json" % (self.apiversion)
    request = AsyncRequest("POST", path, pio_appkey=self.appkey,
                 pio_action=action, pio_uid=uid, pio_iid=iid,
                 **params)
    request.set_rfunc(self._auser_action_on_item_resp)
    self._connection.make_request(request)
    return request

  def _auser_action_on_item_resp(self, response):
    """Private function to handle the AsyncResponse of the
    _auser_action_on_item request

    :param response: AsyncResponse object

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    if response.error is not None:
      raise U2IActionNotCreatedError(
        "Exception happened: %s for request %s" %
        (response.error, response.request))
    elif response.status != httplib.CREATED:
      raise U2IActionNotCreatedError("request: %s status: %s body: %s" %
                       (response.request, response.status,
                      response.body))
    return None

  def arecord_action_on_item(self, action, iid, params={}):
    """Asynchronously create action on item

    :param action: action name. type String. For example, "rate", "like",
             etc
    :param iid: item id. type str or int.
    :param params: optional attributes. type dictionary.
        For example, { 'pio_rate' : 4, 'pio_latlng': [4.5,67.8] }
        NOTE: For "rate" action, pio_rate attribute is required.
        integer value of 1-5 (1 is least preferred and 5 is most
        preferred)

    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.

    :raises:
      U2IActionNotCreatedError
    """

    if self._uid is None:
      raise InvalidArgumentError(
        "uid is not identified. Please call identify(uid) first.")

    request = self._auser_action_on_item(action, self._uid, iid, params)
    return request

  def auser_conversion_item(self, uid, iid, **params):
    """Deprecated. Asynchronously create an user conversion action on an
    item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    request = self._auser_action_on_item(CONVERSION_API, uid, iid, params)
    return request

  def auser_dislike_item(self, uid, iid, **params):
    """Deprecated. Asynchronously create an user dislike action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    request = self._auser_action_on_item(DISLIKE_API, uid, iid, params)
    return request

  def auser_like_item(self, uid, iid, **params):
    """Deprecated. Asynchronously create an user like action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    request = self._auser_action_on_item(LIKE_API, uid, iid, params)
    return request

  def auser_rate_item(self, uid, iid, rate, **params):
    """Deprecated. Asynchronously create an user rate action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param rate: rating. integer value of 1-5 (1 is least preferred and 5
           is most preferred)
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """

    params['pio_rate'] = rate
    request = self._auser_action_on_item(RATE_API, uid, iid, params)
    return request

  def auser_view_item(self, uid, iid, **params):
    """Deprecated. Asynchronously create an user view action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]
    :returns:
      AsyncRequest object. You should call the aresp() method using this
      AsyncRequest object as argument to get the final result or status
      of this asynchronous request.
    """
    request = self._auser_action_on_item(VIEW_API, uid, iid, params)
    return request

  def aresp(self, request):
    """Get the result of the asynchronous request

    :param request: AsyncRequest object. This object must be returned by
            the asynchronous request function
            For example, to get the result of a aget_user()
            request, call this aresp() with the argument of
            AsyncRequest object returned by aget_user().

    :returns:
      The result of this AsyncRequest. The return type is the same as
      the return type of corresponding blocking request.

      For example,

      Calling aresp() with acreate_user() AsyncRequest returns the same
      type as create_user(), which is None.

      Calling aresp() with aget_user() AsyncRequest returns the same
      type as get_user(), which is dictionary data.

    :raises:
      Exception may be raised if there is error happened. The type of
      exception is the same as exception type of the correspdoning
      blocking request.

      For example,

      Calling aresp() with acreate_user() AsyncRequest may raise
      UserNotCreatedError exception.

      Calling aresp() with aget_user() AsyncRequest may raise
      UserNotFoundError exception.

    """
    response = request.get_response()
    result = request.rfunc(response)
    return result

  def create_user(self, uid, params={}):
    """Blocking request to create user

    :param uid: user id. type str.
    :param params: optional attributes. type dictionary.
      For example, { 'custom': 'value', 'pio_inactive' : True,
      'pio_latlng': [4.5,67.8] }

    :returns:
      None.

    :raises:
      UserNotCreatedError.

    """
    request = self.acreate_user(uid, params)
    result = self.aresp(request)
    return result

  def get_user(self, uid):
    """Blocking request to get user

    :param uid: user id. type str or int.

    :returns:
      User data in Dictionary format.

    :rasies:
      UserNotFoundError.

    """
    request = self.aget_user(uid)
    result = self.aresp(request)
    return result

  def delete_user(self, uid):
    """Blocking request to delete the user

    :param uid: user id. type str.

    :returns:
      None.

    :raises:
      UserNotDeletedError.

    """
    request = self.adelete_user(uid)
    result = self.aresp(request)
    return result

  def create_item(self, iid, itypes, params={}):
    """Blocking request to create item

    :param iid: item id. type str.
    :param itypes: item types. Tuple of Str.
        For example, if this item belongs to item types "t1", "t2",
        "t3", "t4", then itypes=("t1", "t2", "t3", "t4").
        NOTE: if this item belongs to only one itype, use tuple of one
        element, eg. itypes=("t1",)
    :param params: optional attributes. type dictionary.
        For example,
        { 'custom': 'value', 'pio_inactive' : True,
        'pio_latlng': [4.5,67.8] }

    :returns:
      None

    :raises:
      ItemNotCreatedError

    """
    request = self.acreate_item(iid, itypes, params)
    result = self.aresp(request)
    return result

  def get_item(self, iid):
    """Blocking request to get item

    :param iid: item id. type str.

    :returns:
      item data in dictionary format.

    :raises:
      ItemNotFoundError.

    """
    request = self.aget_item(iid)
    result = self.aresp(request)
    return result

  def delete_item(self, iid):
    """Blocking request to delete item

    :param iid: item id. type str.

    :returns:
      None

    :raises:
      ItemNotDeletedError

    """
    request = self.adelete_item(iid)
    result = self.aresp(request)
    return result

  def get_itemrec_topn(self, engine, n, params={}):
    """Blocking request to get recommendations for the identified user

    :param engine: name of the prediction engine. type str.
    :param n: number of recommendation. type int.
    :param params: optional parameters. type dictionary
        For example, { 'pio_itypes' : ("t1", "t2") }
    :returns:
      data in dictionary format.

    :raises:
      ItemRecNotFoundError.
    """
    request = self.aget_itemrec_topn(engine, n, params)
    result = self.aresp(request)
    return result

  def get_itemrec(self, uid, n, engine, **params):
    """Deprecated. Blocking request to get recommendations

    :param uid: user id. type str or int.
    :param n: number of recommendation. type int.
    :param engine: name of the prediction engine. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]

    :returns:
      data in dictionary format.

    :raises:
      ItemRecNotFoundError.

    """
    request = self.aget_itemrec(uid, n, engine, **params)
    result = self.aresp(request)
    return result

  def get_itemsim_topn(self, engine, iid, n, params={}):
    """Blocking request to get top n similar items of the item

    :param engine: name of the prediction engine. type str.
    :param iid: item id. type str.
    :param n: number of similar items. type int.
    :param params: optional parameters. type dictionary
        For example, { 'pio_itypes' : ("t1",) }
    :returns:
      data in dictionary format.

    :raises:
      ItemSimNotFoundError.
    """

    request = self.aget_itemsim_topn(engine, iid, n, params)
    result = self.aresp(request)
    return result

  def get_itemrank_ranked(self, engine, iids, params={}):
    """Blocking request to get ranked item for user

    :param engine: name of the prediction engine. type str.
    :param iids: items to be ranked. type list of item ids.
        For example, ["i0", "i1", "i2"]
    :param params: optional parameters. type dictionary
        For example. { 'pio_attributes' : "name" }
    :returns:
      data in dictionary format.

    :raises:
      ItemRankNotFoundError.
    """
    request = self.aget_itemrank_ranked(engine, iids, params)
    result = self.aresp(request)
    return result

  def record_action_on_item(self, action, iid, params={}):
    """Blocking request to create action on an item

    :param action: action name. type String. For example, "rate", "like",
             etc
    :param iid: item id. type str.
    :param params: optional attributes. type dictionary.
        For example, { 'pio_rate' : 4, 'pio_latlng' : [1.23,4.56] }
        NOTE: For "rate" action, pio_rate attribute is required.
        integer value of 1-5 (1 is least preferred and 5 is most
        preferred)

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    request = self.arecord_action_on_item(action, iid, params)
    result = self.aresp(request)
    return result

  def user_conversion_item(self, uid, iid, **params):
    """Deprecated. Blocking request to create user conversion action on an
     item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    request = self.auser_conversion_item(uid, iid, **params)
    result = self.aresp(request)
    return result

  def user_dislike_item(self, uid, iid, **params):
    """Deprecated. Blocking request to create user dislike action on an
     item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    request = self.auser_dislike_item(uid, iid, **params)
    result = self.aresp(request)
    return result

  def user_like_item(self, uid, iid, **params):
    """Deprecated. Blocking request to create user like action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    request = self.auser_like_item(uid, iid, **params)
    result = self.aresp(request)
    return result

  def user_rate_item(self, uid, iid, rate, **params):
    """Deprecated. Blocking request to create user rate action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param rate: rating. integer value of 1-5 (1 is least preferred and 5
           is most preferred)
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    request = self.auser_rate_item(uid, iid, rate, **params)
    result = self.aresp(request)
    return result

  def user_view_item(self, uid, iid, **params):
    """Deprecated. Blocking request to create user view action on an item

    :param uid: user id. type str.
    :param iid: item id. type str.
    :param params: keyword arguments for optional attributes.
        For example, pio_latlng=[123.4, 56.7]

    :returns:
      None

    :raises:
      U2IActionNotCreatedError
    """
    request = self.auser_view_item(uid, iid, **params)
    result = self.aresp(request)
    return result
