# 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
import warnings

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.

    """
    warnings.warn("predictionio.Client is deprecated. " + 
      "Please consider upgrading to our latest version.")

    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

