Merge PR #11, prep 0.9.6 . Clobbered the PR's predictionio/__init__.py conflicting changes, fixed the rest
diff --git a/.gitignore b/.gitignore
index 66fa4a6..1822229 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
+*.egg-info
+.idea
+.tox
+.coverage
*.pyc
.project
.pydevproject
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 0d87655..d52d83e 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -11,13 +11,13 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os
+import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-#sys.path.append("..")
+# sys.path.insert(0, os.path.abspath('.'))
+# sys.path.append("..")
# Use path in the SDK. Hence need to override system package path by inserting
# to position 0.
sys.path.insert(0, "..")
@@ -25,7 +25,7 @@
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
+# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
@@ -38,7 +38,7 @@
source_suffix = '.rst'
# The encoding of source files.
-#source_encoding = 'utf-8-sig'
+# source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
@@ -54,41 +54,41 @@
# The short X.Y version.
version = '0.9'
# The full version, including alpha/beta/rc tags.
-release = '0.9.2'
+release = '0.9.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
-#language = None
+# language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
-#today = ''
+# today = ''
# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
+# default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
+# add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
-#add_module_names = True
+# add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
-#show_authors = False
+# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
@@ -100,72 +100,72 @@
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-#html_theme_options = {}
+# html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
+# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-#html_title = None
+# html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
+# html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
-#html_logo = None
+# html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
-#html_favicon = None
+# html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['_static']
+# html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+# html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
-#html_use_smartypants = True
+# html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
# If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
# If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
# If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'PredictionIO-Python-SDKdoc'
@@ -174,42 +174,42 @@
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
+ # The paper size ('letterpaper' or 'a4paper').
+ # 'papersize': 'letterpaper',
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
+ # The font size ('10pt', '11pt' or '12pt').
+ # 'pointsize': '10pt',
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
+ # Additional stuff for the LaTeX preamble.
+ # 'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'PredictionIO-Python-SDK.tex', u'PredictionIO-Python-SDK Documentation',
- u'TappingStone', 'manual'),
+ ('index', 'PredictionIO-Python-SDK.tex', u'PredictionIO-Python-SDK Documentation',
+ u'TappingStone', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
-#latex_logo = None
+# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
# If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
# If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
# Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
# If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
@@ -222,27 +222,27 @@
]
# If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
-# dir menu entry, description, category)
+# dir menu entry, description, category)
texinfo_documents = [
- ('index', 'PredictionIO-Python-SDK', u'PredictionIO-Python-SDK Documentation',
- u'TappingStone', 'PredictionIO-Python-SDK', 'One line description of project.',
- 'Miscellaneous'),
+ ('index', 'PredictionIO-Python-SDK', u'PredictionIO-Python-SDK Documentation',
+ u'TappingStone', 'PredictionIO-Python-SDK', 'One line description of project.',
+ 'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
+# texinfo_appendices = []
# If false, no module index is generated.
-#texinfo_domain_indices = True
+# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
+# texinfo_show_urls = 'footnote'
autodoc_member_order = 'bysource'
diff --git a/examples/demo-movielens/appdata.py b/examples/demo-movielens/appdata.py
index d9637ef..354f31e 100644
--- a/examples/demo-movielens/appdata.py
+++ b/examples/demo-movielens/appdata.py
@@ -1,6 +1,5 @@
-
import datetime
-from operator import itemgetter, attrgetter
+from operator import attrgetter
# can get sample data here:
# wget http://www.grouplens.org/system/files/ml-100k.zip
@@ -15,169 +14,170 @@
class User:
- def __init__(self, uid):
- self.uid = uid
- self.rec = [] # recommendations, list of iid
+ def __init__(self, uid):
+ self.uid = uid
+ self.rec = [] # recommendations, list of iid
- def __str__(self):
- return "User[uid=%s,rec=%s]" % (self.uid, self.rec)
+ def __str__(self):
+ return "User[uid=%s,rec=%s]" % (self.uid, self.rec)
+
class Item:
- def __init__(self, iid, name, release_date, genres, year):
- self.iid = iid
- self.name = name
- self.release_date = release_date # datetime.datetime object
- self.genres = genres
- self.year = year
+ def __init__(self, iid, name, release_date, genres, year):
+ self.iid = iid
+ self.name = name
+ self.release_date = release_date # datetime.datetime object
+ self.genres = genres
+ self.year = year
- def __str__(self):
- return "Item[iid=%s,name=%s,release_date=%s,genres=%s]" % (self.iid, self.name, self.release_date, self.genres)
+ def __str__(self):
+ return "Item[iid=%s,name=%s,release_date=%s,genres=%s]" % (self.iid, self.name, self.release_date, self.genres)
+
class RateAction:
- def __init__(self, uid, iid, rating, t):
- self.uid = uid
- self.iid = iid
- self.rating = rating
- self.t = t
+ def __init__(self, uid, iid, rating, t):
+ self.uid = uid
+ self.iid = iid
+ self.rating = rating
+ self.t = t
- def __str__(self):
- return "RateAction[uid=%s,iid=%s,rating=%s,t=%s]" % (self.uid, self.iid, self.rating, self.t)
+ def __str__(self):
+ return "RateAction[uid=%s,iid=%s,rating=%s,t=%s]" % (self.uid, self.iid, self.rating, self.t)
class AppData:
+ def __init__(self):
+ self._users = {} # dict of User obj
+ self._items = {} # dict of Item obj
+ self._rate_actions = [] # list of RateAction obj
- def __init__(self):
- self._users = {} # dict of User obj
- self._items = {} # dict of Item obj
- self._rate_actions = [] # list of RateAction obj
+ self._users_file = "%s/%s" % (APPDATA_DIRNAME, USERS_FILENAME)
+ self._items_file = "%s/%s" % (APPDATA_DIRNAME, ITEMS_FILENAME)
+ self._rate_actions_file = "%s/%s" % (APPDATA_DIRNAME, RATE_ACTIONS_FILENAME)
+ self.__init_users()
+ self.__init_items()
+ self.__init_rate_actions()
- self._users_file = "%s/%s" % (APPDATA_DIRNAME, USERS_FILENAME)
- self._items_file = "%s/%s" % (APPDATA_DIRNAME, ITEMS_FILENAME)
- self._rate_actions_file = "%s/%s" % (APPDATA_DIRNAME, RATE_ACTIONS_FILENAME)
- self.__init_users()
- self.__init_items()
- self.__init_rate_actions()
+ def __init_users(self):
+ """
+ uid|
+ """
+ print("[Info] Initializing users...")
+ f = open(self._users_file, 'r')
+ for line in f:
+ data = line.rstrip('\r\n').split(USERS_FILE_DELIMITER)
+ self.add_user(User(data[0]))
+ f.close()
+ print("[Info] %s users were initialized." % len(self._users))
- def __init_users(self):
- """
- uid|
- """
- print "[Info] Initializing users..."
- f = open(self._users_file, 'r')
- for line in f:
- data = line.rstrip('\r\n').split(USERS_FILE_DELIMITER)
- self.add_user(User(data[0]))
- f.close()
- print "[Info] %s users were initialized." % len(self._users)
+ def __init_items(self):
+ """
+ movie id | movie title | release date | video release date |
+ IMDb URL | unknown | Action | Adventure | Animation |
+ Children's | Comedy | Crime | Documentary | Drama | Fantasy |
+ Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi |
+ Thriller | War | Western |
+ The last 19 fields are the genres, a 1 indicates the movie
+ is of that genre, a 0 indicates it is not; movies can be in
+ several genres at once.
- def __init_items(self):
- """
- movie id | movie title | release date | video release date |
- IMDb URL | unknown | Action | Adventure | Animation |
- Children's | Comedy | Crime | Documentary | Drama | Fantasy |
- Film-Noir | Horror | Musical | Mystery | Romance | Sci-Fi |
- Thriller | War | Western |
- The last 19 fields are the genres, a 1 indicates the movie
- is of that genre, a 0 indicates it is not; movies can be in
- several genres at once.
+ """
+ genre_names = ["unknown", "Action", "Adventure", "Animation",
+ "Children's", "Comedy", "Crime", "Documentary", "Drama", "Fantasy",
+ "Film-Noir", "Horror", "Musical", "Mystery", "Romance", "Sci-Fi",
+ "Thriller", "War", "Western"]
- """
- genre_names = [ "unknown", "Action", "Adventure", "Animation",
- "Children's", "Comedy", "Crime", "Documentary", "Drama", "Fantasy",
- "Film-Noir", "Horror", "Musical", "Mystery", "Romance", "Sci-Fi",
- "Thriller", "War", "Western"]
+ print("[Info] Initializing items...")
+ f = open(self._items_file, 'r')
+ for line in f:
+ data = line.rstrip('\r\n').split(ITEMS_FILE_DELIMITER)
+ genres_flags = data[5:24]
- print "[Info] Initializing items..."
- f = open(self._items_file, 'r')
- for line in f:
- data = line.rstrip('\r\n').split(ITEMS_FILE_DELIMITER)
- genres_flags = data[5:24]
+ genres = () # tuple of genres
+ for g, flag in zip(genre_names, genres_flags):
+ if flag == '1':
+ genres = genres + (g,)
- genres = () # tuple of genres
- for g,flag in zip(genre_names, genres_flags):
- if flag == '1':
- genres = genres + (g,)
+ try:
+ # eg. 01-Jan-1994
+ release_date = datetime.datetime.strptime(data[2], "%d-%b-%Y").replace(microsecond=1)
+ (day, month, year) = data[2].split('-')
+ except:
+ print("[Note] item %s %s doesn't have release date. Skip it." % (data[0], data[1]))
+ else:
+ self.add_item(Item(
+ iid=data[0],
+ name=data[1],
+ release_date=release_date,
+ genres=genres,
+ year=year))
+ f.close()
+ print("[Info] %s items were initialized." % len(self._items))
- try:
- # eg. 01-Jan-1994
- release_date = datetime.datetime.strptime(data[2], "%d-%b-%Y").replace(microsecond=1)
- (day, month, year) = data[2].split('-')
- except:
- print "[Note] item %s %s doesn't have release date. Skip it." % (data[0], data[1])
- else:
- self.add_item(Item(
- iid=data[0],
- name=data[1],
- release_date=release_date,
- genres=genres,
- year=year))
- f.close()
- print "[Info] %s items were initialized." % len(self._items)
+ def __init_rate_actions(self):
+ """
+ uid|iid|rating|timestamp
+ """
+ print("[Info] Initializing rate actions...")
+ f = open(self._rate_actions_file, 'r')
+ for line in f:
+ data = line.rstrip('\r\n').split(RATE_ACTIONS_DELIMITER)
+ t = datetime.datetime.utcfromtimestamp(int(data[3])).replace(microsecond=1)
+ self.add_rate_action(RateAction(data[0], data[1], data[2], t))
+ f.close()
+ print("[Info] %s rate actions were initialized." % len(self._rate_actions))
- def __init_rate_actions(self):
- """
- uid|iid|rating|timestamp
- """
- print "[Info] Initializing rate actions..."
- f = open(self._rate_actions_file, 'r')
- for line in f:
- data = line.rstrip('\r\n').split(RATE_ACTIONS_DELIMITER)
- t = datetime.datetime.utcfromtimestamp(int(data[3])).replace(microsecond=1)
- self.add_rate_action(RateAction(data[0], data[1], data[2], t))
- f.close()
- print "[Info] %s rate actions were initialized." % len(self._rate_actions)
+ def add_user(self, user):
+ self._users[user.uid] = user
- def add_user(self, user):
- self._users[user.uid] = user
+ def add_item(self, item):
+ self._items[item.iid] = item
- def add_item(self, item):
- self._items[item.iid] = item
+ def add_rate_action(self, action):
+ self._rate_actions.append(action)
- def add_rate_action(self, action):
- self._rate_actions.append(action)
+ def get_users(self):
+ return self._users
- def get_users(self):
- return self._users
+ def get_items(self):
+ return self._items
- def get_items(self):
- return self._items
+ def get_rate_actions(self):
+ return self._rate_actions
- def get_rate_actions(self):
- return self._rate_actions
+ def get_user(self, uid):
+ """return single user
+ """
+ if uid in self._users:
+ return self._users[uid]
+ else:
+ return None
- def get_user(self, uid):
- """return single user
- """
- if uid in self._users:
- return self._users[uid]
- else:
- return None
+ def get_item(self, iid):
+ """return single item
+ """
+ if iid in self._items:
+ return self._items[iid]
+ else:
+ return None
- def get_item(self, iid):
- """return single item
- """
- if iid in self._items:
- return self._items[iid]
- else:
- return None
+ def get_top_rated_items(self, uid, n):
+ """get top n rated iids by this uid
+ """
+ if uid in self._users:
+ actions = filter(lambda u: u.uid == uid, self._rate_actions)
+ top = sorted(actions, key=attrgetter('rating'), reverse=True)
+ topn_iids = map(lambda a: a.iid, top[:n])
+ return topn_iids
+ else:
+ return None
- def get_top_rated_items(self, uid, n):
- """get top n rated iids by this uid
- """
- if uid in self._users:
- actions = filter(lambda u: u.uid==uid, self._rate_actions)
- top = sorted(actions, key=attrgetter('rating'), reverse=True)
- topn_iids = map(lambda a: a.iid, top[:n])
- return topn_iids
- else:
- return None
-
- def get_top_rate_actions(self, uid, n):
- """get top n rated actions by this uid
- """
- if uid in self._users:
- actions = filter(lambda u: u.uid==uid, self._rate_actions)
- top = sorted(actions, key=attrgetter('rating'), reverse=True)
- return top[:n]
- else:
- return None
+ def get_top_rate_actions(self, uid, n):
+ """get top n rated actions by this uid
+ """
+ if uid in self._users:
+ actions = filter(lambda u: u.uid == uid, self._rate_actions)
+ top = sorted(actions, key=attrgetter('rating'), reverse=True)
+ return top[:n]
+ else:
+ return None
diff --git a/examples/demo-movielens/batch_import.py b/examples/demo-movielens/batch_import.py
index f0fcb7c..af9c4f5 100644
--- a/examples/demo-movielens/batch_import.py
+++ b/examples/demo-movielens/batch_import.py
@@ -1,133 +1,135 @@
+import sys
+import datetime
+
+import pytz
from appdata import AppData
import predictionio
-import sys
-import pytz
-import datetime
+
def batch_import_task(app_data, client, all_info=False):
- # event_time is an important properties used by the PredictionIO platform. It
- # is particularly useful in generating training and testing set, which uses
- # event_time for splitting. Hence, when we import data, better to make the
- # event_time as approximate to fact as possible.
- #
- # However, in many cases, the data doesn't come with a time. Movie-lens' user
- # data, for example, only reveals the age, gender, occupation, and zip code of
- # a user. It doesn't report when the user is "created". Likewise, for items,
- # it only reports the release date.
- #
- # To remedy this problem, we have to make some assumptions to the data. In
- # this import script, the event_time for user is set to epoch=0, and the
- # event_time for item is set to the release_date + 00:00:00 UTC.
+ # event_time is an important properties used by the PredictionIO platform. It
+ # is particularly useful in generating training and testing set, which uses
+ # event_time for splitting. Hence, when we import data, better to make the
+ # event_time as approximate to fact as possible.
+ #
+ # However, in many cases, the data doesn't come with a time. Movie-lens' user
+ # data, for example, only reveals the age, gender, occupation, and zip code of
+ # a user. It doesn't report when the user is "created". Likewise, for items,
+ # it only reports the release date.
+ #
+ # To remedy this problem, we have to make some assumptions to the data. In
+ # this import script, the event_time for user is set to epoch=0, and the
+ # event_time for item is set to the release_date + 00:00:00 UTC.
- print "[Info] Importing users to PredictionIO..."
- user_create_time = datetime.datetime.fromtimestamp(0, tz=pytz.utc)
- count = 0
- set_user_request_list = []
- for k, v in app_data.get_users().iteritems():
- count += 1
- if all_info:
- print "[Info] Importing %s..." % v
- else:
- if (count % 32 == 0):
- sys.stdout.write('\r[Info] %s' % count)
- sys.stdout.flush()
+ print("[Info] Importing users to PredictionIO...")
+ user_create_time = datetime.datetime.fromtimestamp(0, tz=pytz.utc)
+ count = 0
+ set_user_request_list = []
+ for k, v in app_data.get_users().iteritems():
+ count += 1
+ if all_info:
+ print("[Info] Importing %s..." % v)
+ else:
+ if count % 32 == 0:
+ sys.stdout.write('\r[Info] %s' % count)
+ sys.stdout.flush()
- set_user_request_list.append(
- client.aset_user(uid=v.uid, event_time=user_create_time))
+ set_user_request_list.append(
+ client.aset_user(uid=v.uid, event_time=user_create_time))
- [r.get_response() for r in set_user_request_list]
- sys.stdout.write('\r[Info] %s users were imported.\n' % count)
- sys.stdout.flush()
+ [r.get_response() for r in set_user_request_list]
+ sys.stdout.write('\r[Info] %s users were imported.\n' % count)
+ sys.stdout.flush()
- print "[Info] Importing items to PredictionIO..."
- count = 0
- set_item_request_list = []
- # event_time is a datetime, hence need to add a time component to the release
- # date.
- midnight_utc = datetime.time(0, 0, 0, tzinfo=pytz.utc)
- epoch = datetime.datetime.fromtimestamp(0, tz=pytz.utc)
- for k, v in app_data.get_items().iteritems():
- count += 1
- if all_info:
- print "[Info] Importing %s..." % v
- else:
- if (count % 32 == 0):
- sys.stdout.write('\r[Info] %s' % count)
- sys.stdout.flush()
+ print("[Info] Importing items to PredictionIO...")
+ count = 0
+ set_item_request_list = []
+ # event_time is a datetime, hence need to add a time component to the release
+ # date.
+ midnight_utc = datetime.time(0, 0, 0, tzinfo=pytz.utc)
+ epoch = datetime.datetime.fromtimestamp(0, tz=pytz.utc)
+ for k, v in app_data.get_items().iteritems():
+ count += 1
+ if all_info:
+ print("[Info] Importing %s..." % v)
+ else:
+ if count % 32 == 0:
+ sys.stdout.write('\r[Info] %s' % count)
+ sys.stdout.flush()
- itypes = ("movie",) + v.genres
+ itypes = ("movie",) + v.genres
- release_datetime = datetime.datetime.combine(
- v.release_date,
- midnight_utc)
+ release_datetime = datetime.datetime.combine(
+ v.release_date,
+ midnight_utc)
- # event_time must be after epoch.
- event_time = release_datetime if release_datetime > epoch else epoch
+ # event_time must be after epoch.
+ event_time = release_datetime if release_datetime > epoch else epoch
- utf8_name = v.name.decode('utf-8', 'ignore')
-
- set_item_request = client.aset_item(
- iid=v.iid,
- event_time=event_time,
- properties={
- "itypes": list(itypes),
- "starttime": release_datetime.isoformat(),
- "name": utf8_name,
- "year": v.year } )
+ utf8_name = v.name.decode('utf-8', 'ignore')
- set_item_request_list.append(set_item_request)
+ set_item_request = client.aset_item(
+ iid=v.iid,
+ event_time=event_time,
+ properties={
+ "itypes": list(itypes),
+ "starttime": release_datetime.isoformat(),
+ "name": utf8_name,
+ "year": v.year})
- [r.get_response() for r in set_item_request_list]
- sys.stdout.write('\r[Info] %s items were imported.\n' % count)
- sys.stdout.flush()
+ set_item_request_list.append(set_item_request)
- print "[Info] Importing rate actions to PredictionIO..."
- count = 0
- create_event_request_list = []
- for v in app_data.get_rate_actions():
- count += 1
- if all_info:
- print "[Info] Importing %s..." % v
- else:
- if (count % 32 == 0):
- sys.stdout.write('\r[Info] %s' % count)
- sys.stdout.flush()
+ [r.get_response() for r in set_item_request_list]
+ sys.stdout.write('\r[Info] %s items were imported.\n' % count)
+ sys.stdout.flush()
- properties = { "rating" : int(v.rating) }
- req = client.acreate_event(
- event="rate",
- entity_type="user",
- entity_id=v.uid,
- target_entity_type="item",
- target_entity_id=v.iid,
- properties=properties,
- event_time=v.t.replace(tzinfo=pytz.utc),
+ print("[Info] Importing rate actions to PredictionIO...")
+ count = 0
+ create_event_request_list = []
+ for v in app_data.get_rate_actions():
+ count += 1
+ if all_info:
+ print("[Info] Importing %s..." % v)
+ else:
+ if count % 32 == 0:
+ sys.stdout.write('\r[Info] %s' % count)
+ sys.stdout.flush()
+
+ properties = {"rating": int(v.rating)}
+ req = client.acreate_event(
+ event="rate",
+ entity_type="user",
+ entity_id=v.uid,
+ target_entity_type="item",
+ target_entity_id=v.iid,
+ properties=properties,
+ event_time=v.t.replace(tzinfo=pytz.utc),
)
- create_event_request_list.append(req)
+ create_event_request_list.append(req)
- [r.get_response() for r in create_event_request_list]
- sys.stdout.write('\r[Info] %s rate actions were imported.\n' % count)
- sys.stdout.flush()
+ [r.get_response() for r in create_event_request_list]
+ sys.stdout.write('\r[Info] %s rate actions were imported.\n' % count)
+ sys.stdout.flush()
if __name__ == '__main__':
- if len(sys.argv) < 3:
- sys.exit("Usage: python -m examples.demo-movielens.batch_import "
- "<access_key> <url>")
+ if len(sys.argv) < 3:
+ sys.exit("Usage: python -m examples.demo-movielens.batch_import "
+ "<access_key> <url>")
- access_key = sys.argv[1]
+ access_key = sys.argv[1]
- client = predictionio.EventClient(
- access_key=access_key,
- url=sys.argv[2],
- threads=5,
- qsize=500)
+ client = predictionio.EventClient(
+ access_key=access_key,
+ url=sys.argv[2],
+ threads=5,
+ qsize=500)
- # Test connection
- print "Status:", client.get_status()
-
- app_data = AppData()
- batch_import_task(app_data, client)
- client.close()
+ # Test connection
+ print("Status:", client.get_status())
+
+ app_data = AppData()
+ batch_import_task(app_data, client)
+ client.close()
diff --git a/examples/event_sample.py b/examples/event_sample.py
index 9c3fe25..b76bcf7 100644
--- a/examples/event_sample.py
+++ b/examples/event_sample.py
@@ -1,10 +1,12 @@
+from datetime import datetime
+
+import pytz
+
from predictionio import EventClient
from predictionio import NotFoundError
-from datetime import datetime
-import pytz
-import sys
-access_key = None
+
+access_key = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
assert access_key is not None, "Please create an access key with 'pio app new'"
client = EventClient(access_key=access_key, url="http://localhost:7070")
@@ -15,13 +17,13 @@
# First event
first_event_properties = {
- "prop1" : 1,
- "prop2" : "value2",
- "prop3" : [1, 2, 3],
- "prop4" : True,
- "prop5" : ["a", "b", "c"],
- "prop6" : 4.56 ,
- }
+ "prop1": 1,
+ "prop2": "value2",
+ "prop3": [1, 2, 3],
+ "prop4": True,
+ "prop5": ["a", "b", "c"],
+ "prop6": 4.56,
+}
first_event_time = datetime(
2004, 12, 13, 21, 39, 45, 618000, pytz.timezone('US/Mountain'))
first_event_response = client.create_event(
@@ -30,16 +32,16 @@
entity_id="uid",
properties=first_event_properties,
event_time=first_event_time,
- )
+)
print("First Event response")
print(first_event_response)
-print
+print()
# Second event
second_event_properties = {
- "someProperty" : "value1",
- "anotherProperty" : "value2",
- }
+ "someProperty": "value1",
+ "anotherProperty": "value2",
+}
second_event_response = client.create_event(
event="my_event",
entity_type="user",
@@ -50,7 +52,7 @@
event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
print("Second Event response")
print(second_event_response)
-print
+print()
# Get the first event from Event Server
@@ -58,21 +60,21 @@
print("Get Event")
event = client.get_event(first_event_id)
print(event)
-print
+print()
# Delete the first event from Event Server
print("Delete Event")
delete_response = client.delete_event(first_event_id)
print(delete_response)
-print
+print()
# Delete the first event from Event Server again should yield exception.
print("Delete Event Again")
try:
- delete_response = client.delete_event(first_event_id)
-except NotFoundError, ex:
- print("The expected error: {0}".format(ex))
-print
+ delete_response = client.delete_event(first_event_id)
+except NotFoundError as ex:
+ print("The expected error: {0}".format(ex))
+print()
# "user"-helper methods
diff --git a/examples/import_yahoo.py b/examples/import_yahoo.py
index 93b367d..584a8c9 100644
--- a/examples/import_yahoo.py
+++ b/examples/import_yahoo.py
@@ -3,13 +3,14 @@
"""
from datetime import datetime
+import sys
+
+import pytz
+
from pandas.io import data as pdata
-import argparse
import numpy
import predictionio
-import pytz
-import sys
-import time
+
EPOCH = datetime(1970, 1, 1, tzinfo=pytz.utc)
@@ -63,151 +64,151 @@
"WU", "WY", "WYN", "WYNN", "X", "XEL", "XL", "XLNX", "XOM", "XRAY", "XRX",
"XYL", "YHOO", "YUM", "ZION", "ZMH", "ZTS"]
-ETF_LIST = ["QQQ", "SPY", "XLY", "XLP", "XLE", "XLF", "XLV",
- "XLI", "XLB", "XLK", "XLU"]
+ETF_LIST = ["QQQ", "SPY", "XLY", "XLP", "XLE", "XLF", "XLV",
+ "XLI", "XLB", "XLK", "XLU"]
def since_epoch(dt):
- return (dt - EPOCH).total_seconds()
+ return (dt - EPOCH).total_seconds()
def import_data(client, access_key, ticker, start_time, end_time, event_time):
- print "Importing:", ticker, start_time, end_time
+ print("Importing:", ticker, start_time, end_time)
- try:
- df = pdata.DataReader(ticker, 'yahoo', start_time, end_time)
- print "Extracted:", df.index[0], df.index[-1]
- except IOError, ex:
- print ex
- print "Data not exist. Returning"
- return
+ try:
+ df = pdata.DataReader(ticker, 'yahoo', start_time, end_time)
+ print("Extracted:", df.index[0], df.index[-1])
+ except IOError as ex:
+ print(ex)
+ print("Data not exist. Returning")
+ return
- # assume we only extract US data
- eastern = pytz.timezone('US/Eastern')
+ # assume we only extract US data
+ eastern = pytz.timezone('US/Eastern')
- columns = [
- ('Open', 'open'),
- ('High', 'high'),
- ('Low', 'low'),
- ('Close', 'close'),
- ('Volume', 'volume'),
- ('Adj Close', 'adjclose')]
+ columns = [
+ ('Open', 'open'),
+ ('High', 'high'),
+ ('Low', 'low'),
+ ('Close', 'close'),
+ ('Volume', 'volume'),
+ ('Adj Close', 'adjclose')]
- yahoo_data = dict()
- yahoo_data['ticker'] = ticker
- yahoo_data['t'] = [
- # hour=16 to indicate market close time
- since_epoch(eastern.localize(date_.to_pydatetime().replace(hour=16)))
- for date_ in df.index]
+ yahoo_data = dict()
+ yahoo_data['ticker'] = ticker
+ yahoo_data['t'] = [
+ # hour=16 to indicate market close time
+ since_epoch(eastern.localize(date_.to_pydatetime().replace(hour=16)))
+ for date_ in df.index]
- for column in columns:
- yahoo_data[column[1]] = map(numpy.asscalar, df[column[0]].values)
+ for column in columns:
+ yahoo_data[column[1]] = map(numpy.asscalar, df[column[0]].values)
- properties = {'yahoo': yahoo_data}
+ properties = {'yahoo': yahoo_data}
- response = client.create_event(
- event='$set',
- entity_type='yahoo',
- entity_id=ticker,
- properties=properties,
- event_time=event_time.replace(tzinfo=pytz.utc))
-
- print(response)
+ response = client.create_event(
+ event='$set',
+ entity_type='yahoo',
+ entity_id=ticker,
+ properties=properties,
+ event_time=event_time.replace(tzinfo=pytz.utc))
+
+ print(response)
def import_all(access_key):
- """This method import all SP500 stocks and some SPDR ETFs."""
- time_slices = [
- (datetime(1999, 1, 1), datetime(2004, 1, 1), datetime(2004, 1, 2)),
- (datetime(2003, 12, 1), datetime(2009, 1, 1), datetime(2009, 1, 2)),
- (datetime(2008, 12, 1), datetime(2014, 9, 1), datetime(2014, 9, 2)),
- ]
+ """This method import all SP500 stocks and some SPDR ETFs."""
+ time_slices = [
+ (datetime(1999, 1, 1), datetime(2004, 1, 1), datetime(2004, 1, 2)),
+ (datetime(2003, 12, 1), datetime(2009, 1, 1), datetime(2009, 1, 2)),
+ (datetime(2008, 12, 1), datetime(2014, 9, 1), datetime(2014, 9, 2)),
+ ]
- url = 'http://localhost:7070'
- client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
+ url = 'http://localhost:7070'
+ client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
- tickers = SP500_LIST + ETF_LIST
+ tickers = SP500_LIST + ETF_LIST
- for ticker in tickers:
- for time_slice in time_slices:
- import_data(client, access_key, ticker,
- time_slice[0], time_slice[1], time_slice[2])
+ for ticker in tickers:
+ for time_slice in time_slices:
+ import_data(client, access_key, ticker,
+ time_slice[0], time_slice[1], time_slice[2])
def import_data_with_gaps(access_key):
- """This method import data with time gaps.
-
- Data imported by this method is used by stock engine, it demonsrates how it
- can handle time series data with gaps.
- """
+ """This method import data with time gaps.
- # time_slices is discontinuted
- # startTime, endTime, eventDate
- time_slices = [
- (datetime(2013, 12, 1), datetime(2014, 2, 1), datetime(2014, 2, 2)),
- (datetime(2014, 1, 1), datetime(2014, 1, 20), datetime(2014, 2, 10)),
- (datetime(2014, 1, 10), datetime(2014, 2, 20), datetime(2014, 2, 28)),
- (datetime(2014, 2, 10), datetime(2014, 3, 31), datetime(2014, 4, 2)),
- (datetime(2014, 5, 1), datetime(2014, 6, 15), datetime(2014, 6, 20)),
- (datetime(2014, 6, 1), datetime(2014, 7, 1), datetime(2014, 7, 15)),
- ]
+ Data imported by this method is used by stock engine, it demonsrates how it
+ can handle time series data with gaps.
+ """
- tickers = ['SPY', 'AAPL', 'IBM', 'MSFT']
-
- url = 'http://localhost:7070'
- client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
+ # time_slices is discontinuted
+ # startTime, endTime, eventDate
+ time_slices = [
+ (datetime(2013, 12, 1), datetime(2014, 2, 1), datetime(2014, 2, 2)),
+ (datetime(2014, 1, 1), datetime(2014, 1, 20), datetime(2014, 2, 10)),
+ (datetime(2014, 1, 10), datetime(2014, 2, 20), datetime(2014, 2, 28)),
+ (datetime(2014, 2, 10), datetime(2014, 3, 31), datetime(2014, 4, 2)),
+ (datetime(2014, 5, 1), datetime(2014, 6, 15), datetime(2014, 6, 20)),
+ (datetime(2014, 6, 1), datetime(2014, 7, 1), datetime(2014, 7, 15)),
+ ]
- for ticker in tickers:
- for time_slice in time_slices:
- import_data(client, access_key, ticker,
- time_slice[0], time_slice[1], time_slice[2])
+ tickers = ['SPY', 'AAPL', 'IBM', 'MSFT']
- # below are data with holes
- time_slices = [
- (datetime(2014, 1, 1), datetime(2014, 1, 20), datetime(2014, 2, 10)),
- (datetime(2014, 2, 10), datetime(2014, 3, 31), datetime(2014, 4, 2)),
- (datetime(2014, 6, 1), datetime(2014, 7, 1), datetime(2014, 7, 15)),
- ]
+ url = 'http://localhost:7070'
+ client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
- tickers = ['AMZN']
- for ticker in tickers:
- for time_slice in time_slices:
- import_data(client, access_key, ticker,
- time_slice[0], time_slice[1], time_slice[2])
+ for ticker in tickers:
+ for time_slice in time_slices:
+ import_data(client, access_key, ticker,
+ time_slice[0], time_slice[1], time_slice[2])
- time_slices = [
- (datetime(2014, 1, 10), datetime(2014, 2, 20), datetime(2014, 2, 28)),
- (datetime(2014, 2, 10), datetime(2014, 3, 31), datetime(2014, 4, 2)),
- ]
- tickers = ['FB']
- for ticker in tickers:
- for time_slice in time_slices:
- import_data(client, access_key, ticker,
- time_slice[0], time_slice[1], time_slice[2])
+ # below are data with holes
+ time_slices = [
+ (datetime(2014, 1, 1), datetime(2014, 1, 20), datetime(2014, 2, 10)),
+ (datetime(2014, 2, 10), datetime(2014, 3, 31), datetime(2014, 4, 2)),
+ (datetime(2014, 6, 1), datetime(2014, 7, 1), datetime(2014, 7, 15)),
+ ]
+
+ tickers = ['AMZN']
+ for ticker in tickers:
+ for time_slice in time_slices:
+ import_data(client, access_key, ticker,
+ time_slice[0], time_slice[1], time_slice[2])
+
+ time_slices = [
+ (datetime(2014, 1, 10), datetime(2014, 2, 20), datetime(2014, 2, 28)),
+ (datetime(2014, 2, 10), datetime(2014, 3, 31), datetime(2014, 4, 2)),
+ ]
+ tickers = ['FB']
+ for ticker in tickers:
+ for time_slice in time_slices:
+ import_data(client, access_key, ticker,
+ time_slice[0], time_slice[1], time_slice[2])
def import_one(access_key):
- """Import TSLA.
-
- Import data with from 2014-01-01 until 2014-03-01. event_time specifies when
- this data is extracted.
- """
- start_time = datetime(2014, 1, 1)
- end_time = datetime(2014, 3, 1)
- event_time = datetime(2014, 9, 1)
- ticker = 'TSLA'
-
- url = 'http://localhost:7070'
- client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
+ """Import TSLA.
- import_data(client, access_key, ticker, start_time, end_time, event_time)
+ Import data with from 2014-01-01 until 2014-03-01. event_time specifies when
+ this data is extracted.
+ """
+ start_time = datetime(2014, 1, 1)
+ end_time = datetime(2014, 3, 1)
+ event_time = datetime(2014, 9, 1)
+ ticker = 'TSLA'
+
+ url = 'http://localhost:7070'
+ client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
+
+ import_data(client, access_key, ticker, start_time, end_time, event_time)
if __name__ == '__main__':
- if len(sys.argv) < 2:
- sys.exit("Usage: python -m examples.import_yahoo <access_key>")
+ if len(sys.argv) < 2:
+ sys.exit("Usage: python -m examples.import_yahoo <access_key>")
- access_key = sys.argv[1]
- import_all(access_key=access_key)
- #import_data_with_gaps(access_key=access_key)
- #import_one(access_key=access_key)
+ access_key = sys.argv[1]
+ import_all(access_key=access_key)
+ # import_data_with_gaps(access_key=access_key)
+ # import_one(access_key=access_key)
diff --git a/examples/itemrank_quick_query.py b/examples/itemrank_quick_query.py
index 3c43713..2beb29b 100644
--- a/examples/itemrank_quick_query.py
+++ b/examples/itemrank_quick_query.py
@@ -10,14 +10,14 @@
item_ids = [str(i) for i in range(1, 6)]
user_ids = [str(x) for x in range(1, 6)] + ["NOT_EXIST_USER"]
for user_id in user_ids:
- print "Rank item 1 to 5 for user", user_id
- try:
- response = client.send_query({
- "uid": user_id,
- "iids": item_ids
- })
- print response
- except predictionio.PredictionIOAPIError as e:
- print 'Caught exception:', e
+ print("Rank item 1 to 5 for user ", user_id)
+ try:
+ response = client.send_query({
+ "uid": user_id,
+ "iids": item_ids
+ })
+ print(response)
+ except predictionio.PredictionIOAPIError as e:
+ print("Caught exception: ", e)
client.close()
diff --git a/examples/itemrank_quick_start.py b/examples/itemrank_quick_start.py
index 6333ea0..a231373 100644
--- a/examples/itemrank_quick_start.py
+++ b/examples/itemrank_quick_start.py
@@ -2,44 +2,47 @@
itemrank quickstart import data
"""
-import predictionio
-
import random
import sys
+import predictionio
+
+
def import_itemrank(access_key):
+ random.seed()
- random.seed()
-
- client = predictionio.EventClient(access_key)
+ client = predictionio.EventClient(access_key)
- print client.get_status()
-
- # generate 10 users, with user ids 1,2,....,10
- user_ids = [str(i) for i in range(1, 11)]
- for user_id in user_ids:
- print "Set user", user_id
- client.set_user(user_id)
-
- # generate 50 items, with item ids 1,2,....,50
- # assign type id 1 to all of them
- item_ids = [str(i) for i in range(1, 51)]
- for item_id in item_ids:
- print "Set item", item_id
- client.set_item(item_id, {
- "itypes" : ['1']
- })
-
- # each user randomly views 10 items
- for user_id in user_ids:
- for viewed_item in random.sample(item_ids, 10):
- print "User", user_id ,"views item", viewed_item
- client.record_user_action_on_item("view", user_id, viewed_item)
-
- client.close()
+ print(client.get_status())
+
+ # generate 10 users, with user ids 1,2,....,10
+ user_ids = [str(i) for i in range(1, 11)]
+ for user_id in user_ids:
+ print
+ "Set user", user_id
+ client.set_user(user_id)
+
+ # generate 50 items, with item ids 1,2,....,50
+ # assign type id 1 to all of them
+ item_ids = [str(i) for i in range(1, 51)]
+ for item_id in item_ids:
+ print
+ "Set item", item_id
+ client.set_item(item_id, {
+ "itypes": ['1']
+ })
+
+ # each user randomly views 10 items
+ for user_id in user_ids:
+ for viewed_item in random.sample(item_ids, 10):
+ print
+ "User", user_id, "views item", viewed_item
+ client.record_user_action_on_item("view", user_id, viewed_item)
+
+ client.close()
if __name__ == '__main__':
- if len(sys.argv) < 2:
- sys.exit("Usage: python -m examples.itemrank_quick_start <access_key>")
- import_itemrank(sys.argv[1])
+ if len(sys.argv) < 2:
+ sys.exit("Usage: python -m examples.itemrank_quick_start <access_key>")
+ import_itemrank(sys.argv[1])
diff --git a/examples/obsolete/itemrec/__init__.py b/examples/obsolete/itemrec/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/examples/obsolete/itemrec/__init__.py
+++ /dev/null
diff --git a/examples/obsolete/itemrec/movies/.gitignore b/examples/obsolete/itemrec/movies/.gitignore
deleted file mode 100644
index 7b1ef3e..0000000
--- a/examples/obsolete/itemrec/movies/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-test/
-ml-100k/
-ml-100k.zip
diff --git a/examples/obsolete/itemrec/movies/README.md b/examples/obsolete/itemrec/movies/README.md
deleted file mode 100644
index 9ef357a..0000000
--- a/examples/obsolete/itemrec/movies/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-PredictionIO Python SDK Example
-===============================
-
-Please execute all commands from repository root.
-
-Step 1. Get sample data and unzip it.
-
- > wget http://www.grouplens.org/system/files/ml-100k.zip
- > unzip ml-100k.zip
-
-Step 2. Configurate examples/itemrec/movies/appdata.py
-
-Step 3. Run this app:
-
- > python -m examples.itemrec.movies.movie_rec_app
diff --git a/examples/obsolete/itemrec/movies/__init__.py b/examples/obsolete/itemrec/movies/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/examples/obsolete/itemrec/movies/__init__.py
+++ /dev/null
diff --git a/examples/obsolete/itemrec/movies/app_config.py b/examples/obsolete/itemrec/movies/app_config.py
deleted file mode 100644
index 5efa7a0..0000000
--- a/examples/obsolete/itemrec/movies/app_config.py
+++ /dev/null
@@ -1,2 +0,0 @@
-APP_KEY = 'uJKTKyUAFNZYQQO5yxkdrSo3XIlaf9LXejI63CWE0mtZVEYF89hyVtOwpMKfXXXX'
-API_URL = 'http://localhost:8000'
diff --git a/examples/obsolete/itemrec/movies/appdata.py b/examples/obsolete/itemrec/movies/appdata.py
deleted file mode 100644
index fb3c7fd..0000000
--- a/examples/obsolete/itemrec/movies/appdata.py
+++ /dev/null
@@ -1,148 +0,0 @@
-
-import datetime
-from operator import itemgetter, attrgetter
-
-# can get sample data here:
-# wget http://www.grouplens.org/system/files/ml-100k.zip
-# app data file config
-APPDATA_DIRNAME = "ml-100k"
-USERS_FILENAME = "u.user"
-USERS_FILE_DELIMITER = "|"
-ITEMS_FILENAME = "u.item"
-ITEMS_FILE_DELIMITER = "|"
-RATE_ACTIONS_FILENAME = "u.data"
-RATE_ACTIONS_DELIMITER = "\t"
-
-
-class User:
- def __init__(self, uid):
- self.uid = uid
- self.rec = [] # recommendations, list of iid
-
- def __str__(self):
- return "User[uid=%s,rec=%s]" % (self.uid, self.rec)
-
-class Item:
- def __init__(self, iid, name):
- self.iid = iid
- self.name = name
-
- def __str__(self):
- return "Item[iid=%s,name=%s]" % (self.iid, self.name)
-
-class RateAction:
- def __init__(self, uid, iid, rating, t):
- self.uid = uid
- self.iid = iid
- self.rating = rating
- self.t = t
-
- def __str__(self):
- return "RateAction[uid=%s,iid=%s,rating=%s,t=%s]" % (self.uid, self.iid, self.rating, self.t)
-
-
-class AppData:
-
- def __init__(self):
- self._users = {} # dict of User obj
- self._items = {} # dict of Item obj
- self._rate_actions = [] # list of RateAction obj
-
- self._users_file = "%s/%s" % (APPDATA_DIRNAME, USERS_FILENAME)
- self._items_file = "%s/%s" % (APPDATA_DIRNAME, ITEMS_FILENAME)
- self._rate_actions_file = "%s/%s" % (APPDATA_DIRNAME, RATE_ACTIONS_FILENAME)
- self.__init_users()
- self.__init_items()
- self.__init_rate_actions()
-
- def __init_users(self):
- """
- uid|
- """
- print "[Info] Initializing users..."
- f = open(self._users_file, 'r')
- for line in f:
- data = line.rstrip('\r\n').split(USERS_FILE_DELIMITER)
- self.add_user(User(data[0]))
- f.close()
- print "[Info] %s users were initialized." % len(self._users)
-
- def __init_items(self):
- """
- iid|name
- """
- print "[Info] Initializing items..."
- f = open(self._items_file, 'r')
- for line in f:
- data = line.rstrip('\r\n').split(ITEMS_FILE_DELIMITER)
- self.add_item(Item(data[0], data[1]))
- f.close()
- print "[Info] %s items were initialized." % len(self._items)
-
- def __init_rate_actions(self):
- """
- uid|iid|rating|timestamp
- """
- print "[Info] Initializing rate actions..."
- f = open(self._rate_actions_file, 'r')
- for line in f:
- data = line.rstrip('\r\n').split(RATE_ACTIONS_DELIMITER)
- t = datetime.datetime.utcfromtimestamp(int(data[3])).isoformat()
- self.add_rate_action(RateAction(data[0], data[1], data[2], t))
- f.close()
- print "[Info] %s rate actions were initialized." % len(self._rate_actions)
-
- def add_user(self, user):
- self._users[user.uid] = user
-
- def add_item(self, item):
- self._items[item.iid] = item
-
- def add_rate_action(self, action):
- self._rate_actions.append(action)
-
- def get_users(self):
- return self._users
-
- def get_items(self):
- return self._items
-
- def get_rate_actions(self):
- return self._rate_actions
-
- def get_user(self, uid):
- """return single user
- """
- if uid in self._users:
- return self._users[uid]
- else:
- return None
-
- def get_item(self, iid):
- """return single item
- """
- if iid in self._items:
- return self._items[iid]
- else:
- return None
-
- def get_top_rated_items(self, uid, n):
- """get top n rated iids by this uid
- """
- if uid in self._users:
- actions = filter(lambda u: u.uid==uid, self._rate_actions)
- top = sorted(actions, key=attrgetter('rating'), reverse=True)
- topn_iids = map(lambda a: a.iid, top[:n])
- return topn_iids
- else:
- return None
-
- def get_top_rate_actions(self, uid, n):
- """get top n rated actions by this uid
- """
- if uid in self._users:
- actions = filter(lambda u: u.uid==uid, self._rate_actions)
- top = sorted(actions, key=attrgetter('rating'), reverse=True)
- return top[:n]
- else:
- return None
diff --git a/examples/obsolete/itemrec/movies/batch_import.py b/examples/obsolete/itemrec/movies/batch_import.py
deleted file mode 100644
index b2e0e63..0000000
--- a/examples/obsolete/itemrec/movies/batch_import.py
+++ /dev/null
@@ -1,65 +0,0 @@
-from appdata import AppData
-import predictionio
-import sys
-
-from app_config import APP_KEY, API_URL
-
-def batch_import_task(app_data, client, all_info=False):
-
- print "[Info] Importing users to PredictionIO..."
- count = 0
- for k, v in app_data.get_users().iteritems():
- count += 1
- if all_info:
- print "[Info] Importing %s..." % v
- else:
- if (count % 32 == 0):
- sys.stdout.write('\r[Info] %s' % count)
- sys.stdout.flush()
-
- client.create_user(v.uid)
-
- sys.stdout.write('\r[Info] %s users were imported.\n' % count)
- sys.stdout.flush()
-
- print "[Info] Importing items to PredictionIO..."
- count = 0
- for k, v in app_data.get_items().iteritems():
- count += 1
- if all_info:
- print "[Info] Importing %s..." % v
- else:
- if (count % 32 == 0):
- sys.stdout.write('\r[Info] %s' % count)
- sys.stdout.flush()
-
- client.create_item(v.iid, ("movie",))
-
- sys.stdout.write('\r[Info] %s items were imported.\n' % count)
- sys.stdout.flush()
-
- print "[Info] Importing rate actions to PredictionIO..."
- count = 0
- for v in app_data.get_rate_actions():
- count += 1
- if all_info:
- print "[Info] Importing %s..." % v
- else:
- if (count % 32 == 0):
- sys.stdout.write('\r[Info] %s' % count)
- sys.stdout.flush()
-
- client.identify(v.uid)
- client.record_action_on_item("rate", v.iid, { "pio_rate": v.rating, "pio_t": v.t })
-
- sys.stdout.write('\r[Info] %s rate actions were imported.\n' % count)
- sys.stdout.flush()
-
-
-if __name__ == '__main__':
-
- app_data = AppData()
- client = predictionio.Client(APP_KEY, 1, API_URL)
- batch_import_task(app_data, client)
- client.close()
-
diff --git a/examples/obsolete/itemrec/movies/movie_rec_app.py b/examples/obsolete/itemrec/movies/movie_rec_app.py
deleted file mode 100644
index 436af38..0000000
--- a/examples/obsolete/itemrec/movies/movie_rec_app.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# To run this example app
-#
-# Please execute all commands from repository root.
-#
-# Step 1. Get sample data and unzip it.
-# > wget http://www.grouplens.org/system/files/ml-100k.zip
-# > unzip ml-100k.zip
-#
-# Step 2. Configurate examples/itemrec/movies/appdata.py
-#
-# Step 3. Run this app:
-# python -m examples.itemrec.movies.movie_rec_app
-
-from appdata import AppData
-import predictionio
-import sys
-
-from app_config import APP_KEY, API_URL
-
-ENGINE_NAME = 'movie-rec'
-
-class App:
-
- def __init__(self):
- self._app_data = AppData()
- self._client = predictionio.Client(APP_KEY, 1, API_URL)
-
- def run(self):
- state = "[Main Menu]"
-
- prompt = "\n"\
- "%s\n"\
- "%s\n"\
- "Please input selection:\n"\
- " 0: Quit application.\n"\
- " 1: Get Recommendations from PredictionIO.\n"\
- " 2: Display user's data." % (state, '-'*len(state))
-
- while True:
- print prompt
- choice = raw_input().lower()
- if choice == '0':
- print "\nGood Bye!\n"
- break
- elif choice == '1':
- self.recommend_task(state)
- elif choice == '2':
- self.display_user_task(state)
- else:
- print '[Error] \'%s\' is not a valid selection.' % choice
-
- self._client.close()
-
- def recommend_task(self, prev_state):
- state = prev_state + " / [Get Recommendations]"
- prompt = "\n"\
- "%s\n"\
- "%s\n"\
- "Please enter user id:" % (state, '-'*len(state))
-
- while True:
- print prompt
- choice = raw_input().lower()
- u = self._app_data.get_user(choice)
- if u:
- n = 10
- print "[Info] Getting top %s item recommendations for user %s..." % (n, u.uid)
- try:
- self._client.identify(u.uid)
- rec = self._client.get_itemrec_topn(ENGINE_NAME, n)
- u.rec = rec['pio_iids']
- self.display_items(u.rec)
- except predictionio.ItemRecNotFoundError:
- print "[Info] Recommendation not found"
-
- print "[Info] Go back to previous menu..."
- break
- else:
- print "[Error] invalid user id %s. Go back to previous menu..." % choice
- break
-
- def display_user_task(self, prev_state):
- state = prev_state + " / [Display User]"
- prompt = "\n"\
- "%s\n"\
- "%s\n"\
- "Please enter user id:" % (state, '-'*len(state))
-
- while True:
- print prompt
- choice = raw_input().lower()
- u = self._app_data.get_user(choice)
- if u:
- print "[Info] User %s:" % u.uid
- n = 10
- topn_rate_actions = self._app_data.get_top_rate_actions(u.uid, n)
- print "\n[Info] Top %s movies rated by this user:" % n
- self.display_rate_actions(topn_rate_actions)
-
- print "\n[Info] Movies recommended to this user:"
- self.display_items(u.rec)
-
- self.wait_for_ack()
- print "\n[Info] Go back to previous menu..."
- break
- else:
- print "[Error] invalid user id %s. Go back to previous menu..." % choice
- break
-
- def display_items(self, iids, all_info=False):
- """print item info for each iid in the list
- """
- if iids:
- for iid in iids:
- item = self._app_data.get_item(iid)
- if item:
- if all_info:
- print "[Info] %s" % item
- else:
- print "[Info] %s" % item.name
- else:
- print "[Error] Invalid item id %s" % iid
- else:
- print "[Info] Empty."
-
- def display_rate_actions(self, actions):
- """print iid and rating
- """
- if actions:
- for a in actions:
- item = self._app_data.get_item(a.iid)
- if item:
- print "[Info] %s, rating = %s" % (item.name, a.rating)
- else:
- print "[Error] Invalid item id %s" % a.iid
- else:
- print "[Info] Empty."
-
- def wait_for_ack(self):
-
- prompt = "\nPress enter to continue..."
- print prompt
- choice = raw_input().lower()
-
-
-if __name__ == '__main__':
-
- print "\nWelcome To PredictionIO Python-SDK Demo App!"
- print "============================================\n"
-
- my_app = App()
- my_app.run()
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 290c31e..e5e5387 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -1,11 +1,10 @@
-"""PredictoinIO Python SDK
-
-The PredictoinIO Python SDK provides easy-to-use functions for integrating
+"""PredictionIO Python SDK
+The PredictionIO Python SDK provides easy-to-use functions for integrating
Python applications with PredictionIO REST API services.
"""
-__version__ = "0.9.2"
+__version__ = "0.9.6"
# import deprecated libraries.
from predictionio.obsolete import Client, InvalidArgumentError
@@ -64,7 +63,6 @@
class BaseClient(object):
def __init__(self, url, threads=1, qsize=0, timeout=5):
"""Constructor of Client object.
-
"""
self.threads = threads
self.url = url
@@ -90,7 +88,6 @@
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.
@@ -99,7 +96,6 @@
def pending_requests(self):
"""Return the number of pending requests.
-
:returns:
The number of pending requests of this client.
"""
@@ -107,10 +103,8 @@
def get_status(self):
"""Get the status of the PredictionIO API Server
-
:returns:
status message.
-
:raises:
ServerStatusError.
"""
@@ -157,10 +151,8 @@
class EventClient(BaseClient):
"""Client for importing data into PredictionIO Event Server.
-
Notice that app_id has been deprecated as of 0.8.2. Please use access_token
instead.
-
:param access_key: the access key for your application.
:param url: the url of PredictionIO Event Server.
:param threads: number of threads to handle PredictionIO API requests.
@@ -197,7 +189,6 @@
target_entity_type=None, target_entity_id=None, properties=None,
event_time=None):
"""Asynchronously create an event.
-
:param event: event name. type str.
:param entity_type: entity type. It is the namespace of the entityId and
analogous to the table name of a relational database. The entityId must be
@@ -211,7 +202,6 @@
:param properties: a custom dict associated with an event. type dict.
:param event_time: the time of the event. type datetime, must contain
timezone info.
-
:returns:
AsyncRequest object. You can call the get_response() method using this
object to get the final resuls or status of this asynchronous request.
@@ -261,10 +251,8 @@
def aget_event(self, event_id):
"""Asynchronouly get an event from Event Server.
-
:param event_id: event id returned by the EventServer when creating the
event.
-
:returns:
AsyncRequest object.
"""
@@ -288,14 +276,12 @@
def aget_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
"""Asynchronouly get events from Event Server. (Getting events through the Event Server API is used for debugging and not recommended for production)
-
:param startTime: time in ISO8601 format. Return events with eventTime >= startTime.
:param untilTime: time in ISO8601 format. Return events with eventTime < untilTime.
:param entityId: String. The entityId. Return events for this entityId only.
:param limit: Integer. The number of record events returned. Default is 20. -1 to get all.
:param reversed: Boolean. Must be used with both entityType and entityId specified,
returns events in reversed chronological order. Default is false.
-
:returns:
AsyncRequest object.
"""
@@ -340,10 +326,8 @@
def adelete_event(self, event_id):
"""Asynchronouly delete an event from Event Server.
-
:param event_id: event id returned by the EventServer when creating the
event.
-
:returns:
AsyncRequest object.
"""
@@ -369,7 +353,6 @@
def aset_user(self, uid, properties={}, event_time=None):
"""Set properties of a user.
-
Wrapper of acreate_event function, setting event to "$set" and entity_type
to "user".
"""
@@ -387,7 +370,6 @@
def aunset_user(self, uid, properties, event_time=None):
"""Unset properties of an user.
-
Wrapper of acreate_event function, setting event to "$unset" and entity_type
to "user".
"""
@@ -406,7 +388,6 @@
def adelete_user(self, uid, event_time=None):
"""Delete a user.
-
Wrapper of acreate_event function, setting event to "$delete" and entity_type
to "user".
"""
@@ -422,7 +403,6 @@
def aset_item(self, iid, properties={}, event_time=None):
"""Set properties of an item.
-
Wrapper of acreate_event function, setting event to "$set" and entity_type
to "item".
"""
@@ -439,7 +419,6 @@
def aunset_item(self, iid, properties={}, event_time=None):
"""Unset properties of an item.
-
Wrapper of acreate_event function, setting event to "$unset" and entity_type
to "item".
"""
@@ -456,7 +435,6 @@
def adelete_item(self, iid, event_time=None):
"""Delete an item.
-
Wrapper of acreate_event function, setting event to "$delete" and entity_type
to "item".
"""
@@ -473,7 +451,6 @@
def arecord_user_action_on_item(self, action, uid, iid, properties={},
event_time=None):
"""Create a user-to-item action.
-
Wrapper of acreate_event function, setting entity_type to "user" and
target_entity_type to "item".
"""
@@ -496,7 +473,6 @@
class EngineClient(BaseClient):
"""Client for extracting prediction results from an PredictionIO Engine
Instance.
-
:param url: the url of the PredictionIO Engine Instance.
:param threads: number of threads to handle PredictionIO API requests.
Must be >= 1.
@@ -507,7 +483,6 @@
:param timeout: timeout for HTTP connection attempts and requests in
seconds (optional).
Default value is 5.
-
"""
def __init__(self, url="http://localhost:8000", threads=1,
qsize=0, timeout=5):
@@ -516,10 +491,8 @@
def asend_query(self, data):
"""Asynchronously send a request to the engine instance with data as the
query.
-
:param data: the query: It is coverted to an json object using json.dumps
method. type dict.
-
:returns:
AsyncRequest object. You can call the get_response() method using this
object to get the final resuls or status of this asynchronous request.
@@ -532,22 +505,18 @@
def send_query(self, data):
"""Synchronously send a request.
-
:param data: the query: It is coverted to an json object using json.dumps
method. type dict.
-
:returns: the prediction.
"""
return self.asend_query(data).get_response()
class FileExporter(object):
"""File exporter to write events to JSON file for batch import
-
:param file_name: the destination file name
"""
def __init__(self, file_name):
"""Constructor of Exporter.
-
"""
self._file = open(file_name, 'w')
@@ -555,9 +524,7 @@
target_entity_type=None, target_entity_id=None, properties=None,
event_time=None):
"""Create an event and write to the file.
-
(please refer to EventClient's create_event())
-
"""
data = {
"event": event,
@@ -585,7 +552,6 @@
def close(self):
"""Close the FileExporter
-
Call this method when you finish writing all events to JSON file
"""
self._file.close()
diff --git a/predictionio/connection.py b/predictionio/connection.py
index 04fe7b5..8205bb2 100644
--- a/predictionio/connection.py
+++ b/predictionio/connection.py
@@ -1,23 +1,22 @@
-
try:
- import Queue
+ import Queue
except ImportError:
- # pylint: disable=F0401
- # http is a Python3 module, replacing httplib. Ditto.
- import queue as Queue
+ # pylint: disable=F0401
+ # http is a Python3 module, replacing httplib. Ditto.
+ import queue as Queue
import threading
try:
- import httplib
+ import httplib
except ImportError:
- # pylint: disable=F0401
- from http import client as httplib
+ # pylint: disable=F0401
+ from http import client as httplib
try:
- from urllib import urlencode
+ from urllib import urlencode
except ImportError:
- # pylint: disable=F0401,E0611
- from urllib.parse import urlencode
+ # pylint: disable=F0401,E0611
+ from urllib.parse import urlencode
import datetime
import json
@@ -25,9 +24,9 @@
# use generators for python2 and python3
try:
- xrange
+ xrange
except NameError:
- xrange = range
+ xrange = range
# some constants
MAX_RETRY = 1 # 0 means no retry
@@ -39,81 +38,124 @@
def enable_log(filename=None):
- global logger
- global DEBUG_LOG
- timestamp = datetime.datetime.today()
- if not filename:
- logfile = "./log/predictionio_%s.log" % timestamp.strftime(
- "%Y-%m-%d_%H:%M:%S.%f")
- else:
- logfile = filename
- logging.basicConfig(filename=logfile,
- filemode='w',
- level=logging.DEBUG,
- format='[%(levelname)s] %(name)s (%(threadName)s) %(message)s')
- logger = logging.getLogger(__name__)
- DEBUG_LOG = True
+ global logger
+ global DEBUG_LOG
+ timestamp = datetime.datetime.today()
+ if not filename:
+ logfile = "./log/predictionio_%s.log" % timestamp.strftime(
+ "%Y-%m-%d_%H:%M:%S.%f")
+ else:
+ logfile = filename
+ logging.basicConfig(filename=logfile,
+ filemode='w',
+ level=logging.DEBUG,
+ format='[%(levelname)s] %(name)s (%(threadName)s) %(message)s')
+ logger = logging.getLogger(__name__)
+ DEBUG_LOG = True
class PredictionIOAPIError(Exception):
- pass
+ pass
class NotSupportMethodError(PredictionIOAPIError):
- pass
+ pass
class ProgramError(PredictionIOAPIError):
- pass
+ pass
class AsyncRequest(object):
+ """AsyncRequest object
- """AsyncRequest object
-
- """
-
- def __init__(self, method, path, **params):
- self.method = method # "GET" "POST" etc
- # the sub path eg. POST /v1/users.json GET /v1/users/1.json
- self.path = path
- # dictionary format eg. {"appkey" : 123, "id" : 3}
- self.params = params
- # use queue to implement response, store AsyncResponse object
- self.response_q = Queue.Queue(1)
- self.qpath = "%s?%s" % (self.path, urlencode(self.params))
- self._response = None
- # response function to be called to handle the response
- self.rfunc = None
-
- def __str__(self):
- return "%s %s %s %s" % (self.method, self.path, self.params,
- self.qpath)
-
- def set_rfunc(self, func):
- self.rfunc = func
-
- def set_response(self, response):
- """ store the response
-
- NOTE: Must be only called once
"""
- self.response_q.put(response)
- def get_response(self):
- """Get the response. Blocking.
+ def __init__(self, method, path, **params):
+ self.method = method # "GET" "POST" etc
+ # the sub path eg. POST /v1/users.json GET /v1/users/1.json
+ self.path = path
+ # dictionary format eg. {"appkey" : 123, "id" : 3}
+ self.params = params
+ # use queue to implement response, store AsyncResponse object
+ self.response_q = Queue.Queue(1)
+ self.qpath = "%s?%s" % (self.path, urlencode(self.params))
+ self._response = None
+ # response function to be called to handle the response
+ self.rfunc = None
- :returns: self.rfunc's return type.
+ def __str__(self):
+ return "%s %s %s %s" % (self.method, self.path, self.params,
+ self.qpath)
+
+ def set_rfunc(self, func):
+ self.rfunc = func
+
+ def set_response(self, response):
+ """ store the response
+
+ NOTE: Must be only called once
+ """
+ self.response_q.put(response)
+
+ def get_response(self):
+ """Get the response. Blocking.
+
+ :returns: self.rfunc's return type.
+ """
+ if self._response is None:
+ tmp_response = self.response_q.get(True) # NOTE: blocking
+ if self.rfunc is None:
+ self._response = tmp_response
+ else:
+ self._response = self.rfunc(tmp_response)
+
+ return self._response
+
+
+class AsyncResponse(object):
+ """Store the response of asynchronous request
+
+ When get the response, user should check if error is None (which means no
+ Exception happens).
+ If error is None, then should check if the status is expected.
"""
- if self._response is None:
- tmp_response = self.response_q.get(True) # NOTE: blocking
- if self.rfunc is None:
- self._response = tmp_response
- else:
- self._response = self.rfunc(tmp_response)
- return self._response
+ def __init__(self):
+ #: exception object if any happens
+ self.error = None
+ self.version = None
+ self.status = None
+ self.reason = None
+ #: Response header. str
+ self.headers = None
+ #: Response body. str
+ self.body = None
+ #: Jsonified response body. Remains None if conversion is unsuccessful.
+ self.json_body = None
+ #: Point back to the AsyncRequest object
+ self.request = None
+
+ def __str__(self):
+ return "e:%s v:%s s:%s r:%s h:%s b:%s" % (self.error, self.version,
+ self.status, self.reason,
+ self.headers, self.body)
+
+ def set_resp(self, version, status, reason, headers, body):
+ self.version = version
+ self.status = status
+ self.reason = reason
+ self.headers = headers
+ self.body = body
+ # Try to extract the json.
+ try:
+ self.json_body = json.loads(body)
+ except ValueError as ex: # noqa
+ self.json_body = None
+
+ def set_error(self, error):
+ self.error = error
class AsyncResponse(object):
"""Store the response of asynchronous request
@@ -162,209 +204,206 @@
def set_request(self, request):
self.request = request
-
class PredictionIOHttpConnection(object):
+ def __init__(self, host, https=True, timeout=5):
+ if https: # https connection
+ self._connection = httplib.HTTPSConnection(host, timeout=timeout)
+ else:
+ self._connection = httplib.HTTPConnection(host, timeout=timeout)
- def __init__(self, host, https=True, timeout=5):
- if https: # https connection
- self._connection = httplib.HTTPSConnection(host, timeout=timeout)
- else:
- self._connection = httplib.HTTPConnection(host, timeout=timeout)
+ def connect(self):
+ self._connection.connect()
- def connect(self):
- self._connection.connect()
-
- def close(self):
- self._connection.close()
-
- def request(self, method, url, body={}, headers={}):
- """
- http request wrapper function, with retry capability in case of error.
- catch error exception and store it in AsyncResponse object
- return AsyncResponse object
-
- Args:
- method: http method, type str
- url: url path, type str
- body: http request body content, type dict
- header: http request header , type dict
- """
-
- response = AsyncResponse()
-
- try:
- # number of retry in case of error (minimum 0 means no retry)
- retry_limit = MAX_RETRY
- mod_headers = dict(headers) # copy the headers
- mod_headers["Connection"] = "keep-alive"
- enc_body = None
- if body: # if body is not empty
- #enc_body = urlencode(body)
- #mod_headers[
- # "Content-type"] = "application/x-www-form-urlencoded"
- enc_body = json.dumps(body)
- mod_headers[
- "Content-type"] = "application/json"
- #mod_headers["Accept"] = "text/plain"
- except Exception as e:
- response.set_error(e)
- return response
-
- if DEBUG_LOG:
- logger.debug("Request m:%s u:%s h:%s b:%s", method, url,
- mod_headers, enc_body)
- # retry loop
- for i in xrange(retry_limit + 1):
- try:
- if i != 0:
- if DEBUG_LOG:
- logger.debug("retry request %s times" % i)
- if self._connection.sock is None:
- self._connection.connect()
- self._connection.request(method, url, enc_body, mod_headers)
- except Exception as e:
+ def close(self):
self._connection.close()
- if i == retry_limit:
- # new copy of e created everytime??
- response.set_error(e)
- else: # NOTE: this is try's else clause
- # connect() and request() OK
+
+ def request(self, method, url, body={}, headers={}):
+ """
+ http request wrapper function, with retry capability in case of error.
+ catch error exception and store it in AsyncResponse object
+ return AsyncResponse object
+
+ Args:
+ method: http method, type str
+ url: url path, type str
+ body: http request body content, type dict
+ header: http request header , type dict
+ """
+
+ response = AsyncResponse()
+
try:
- resp = self._connection.getresponse()
+ # number of retry in case of error (minimum 0 means no retry)
+ retry_limit = MAX_RETRY
+ mod_headers = dict(headers) # copy the headers
+ mod_headers["Connection"] = "keep-alive"
+ enc_body = None
+ if body: # if body is not empty
+ # enc_body = urlencode(body)
+ # mod_headers[
+ # "Content-type"] = "application/x-www-form-urlencoded"
+ enc_body = json.dumps(body)
+ mod_headers[
+ "Content-type"] = "application/json"
+ # mod_headers["Accept"] = "text/plain"
except Exception as e:
- self._connection.close()
- if i == retry_limit:
response.set_error(e)
- else: # NOTE: this is try's else clause
- # getresponse() OK
- resp_version = resp.version # int
- resp_status = resp.status # int
- resp_reason = resp.reason # str
- # resp.getheaders() returns list of tuples
- # converted to dict format
- resp_headers = dict(resp.getheaders())
- # NOTE: have to read the response before sending out next
- # http request
- resp_body = resp.read() # str
- response.set_resp(version=resp_version, status=resp_status,
- reason=resp_reason, headers=resp_headers,
- body=resp_body)
- break # exit retry loop
- # end of retry loop
- if DEBUG_LOG:
- logger.debug("Response %s", response)
- return response # AsyncResponse object
+ return response
+
+ if DEBUG_LOG:
+ logger.debug("Request m:%s u:%s h:%s b:%s", method, url,
+ mod_headers, enc_body)
+ # retry loop
+ for i in xrange(retry_limit + 1):
+ try:
+ if i != 0:
+ if DEBUG_LOG:
+ logger.debug("retry request %s times" % i)
+ if self._connection.sock is None:
+ self._connection.connect()
+ self._connection.request(method, url, enc_body, mod_headers)
+ except Exception as e:
+ self._connection.close()
+ if i == retry_limit:
+ # new copy of e created everytime??
+ response.set_error(e)
+ else: # NOTE: this is try's else clause
+ # connect() and request() OK
+ try:
+ resp = self._connection.getresponse()
+ except Exception as e:
+ self._connection.close()
+ if i == retry_limit:
+ response.set_error(e)
+ else: # NOTE: this is try's else clause
+ # getresponse() OK
+ resp_version = resp.version # int
+ resp_status = resp.status # int
+ resp_reason = resp.reason # str
+ # resp.getheaders() returns list of tuples
+ # converted to dict format
+ resp_headers = dict(resp.getheaders())
+ # NOTE: have to read the response before sending out next
+ # http request
+ resp_body = resp.read() # str
+ response.set_resp(version=resp_version, status=resp_status,
+ reason=resp_reason, headers=resp_headers,
+ body=resp_body)
+ break # exit retry loop
+ # end of retry loop
+ if DEBUG_LOG:
+ logger.debug("Response %s", response)
+ return response # AsyncResponse object
def connection_worker(host, request_queue, https=True, timeout=5, loop=True):
- """worker function which establishes connection and wait for request jobs
- from the request_queue
+ """worker function which establishes connection and wait for request jobs
+ from the request_queue
- Args:
- request_queue: the request queue storing the AsyncRequest object
- valid requests:
- GET
- POST
- DELETE
- KILL
- https: HTTPS (True) or HTTP (False)
- timeout: timeout for HTTP connection attempts and requests in seconds
- loop: This worker function stays in a loop waiting for request
- For testing purpose only. should always be set to True.
- """
+ Args:
+ request_queue: the request queue storing the AsyncRequest object
+ valid requests:
+ GET
+ POST
+ DELETE
+ KILL
+ https: HTTPS (True) or HTTP (False)
+ timeout: timeout for HTTP connection attempts and requests in seconds
+ loop: This worker function stays in a loop waiting for request
+ For testing purpose only. should always be set to True.
+ """
- connect = PredictionIOHttpConnection(host, https, timeout)
+ connect = PredictionIOHttpConnection(host, https, timeout)
- # loop waiting for job form request queue
- killed = not loop
+ # loop waiting for job form request queue
+ killed = not loop
- while True:
- # print "thread %s waiting for request" % thread.get_ident()
- request = request_queue.get(True) # NOTE: blocking get
- # print "get request %s" % request
- method = request.method
- if method == "GET":
- path = request.qpath
- d = connect.request("GET", path)
- elif method == "POST":
- path = request.path
- body = request.params
- d = connect.request("POST", path, body)
- elif method == "DELETE":
- path = request.qpath
- d = connect.request("DELETE", path)
- elif method == "KILL":
- # tell the thread to kill the connection
- killed = True
- d = AsyncResponse()
- else:
- d = AsyncResponse()
- d.set_error(NotSupportMethodError(
- "Don't Support the method %s" % method))
+ while True:
+ # print "thread %s waiting for request" % thread.get_ident()
+ request = request_queue.get(True) # NOTE: blocking get
+ # print "get request %s" % request
+ method = request.method
+ if method == "GET":
+ path = request.qpath
+ d = connect.request("GET", path)
+ elif method == "POST":
+ path = request.path
+ body = request.params
+ d = connect.request("POST", path, body)
+ elif method == "DELETE":
+ path = request.qpath
+ d = connect.request("DELETE", path)
+ elif method == "KILL":
+ # tell the thread to kill the connection
+ killed = True
+ d = AsyncResponse()
+ else:
+ d = AsyncResponse()
+ d.set_error(NotSupportMethodError(
+ "Don't Support the method %s" % method))
- d.set_request(request)
- request.set_response(d)
- request_queue.task_done()
- if killed:
- break
+ d.set_request(request)
+ request.set_response(d)
+ request_queue.task_done()
+ if killed:
+ break
- # end of while loop
- connect.close()
+ # end of while loop
+ connect.close()
class Connection(object):
+ """abstract object for connection with server
- """abstract object for connection with server
-
- spawn multiple connection_worker threads to handle jobs in the queue q
- """
-
- def __init__(self, host, threads=1, qsize=0, https=True, timeout=5):
- """constructor
-
- Args:
- host: host of the server.
- threads: type int, number of threads to be spawn
- qsize: size of the queue q
- https: indicate it is httpS (True) or http connection (False)
- timeout: timeout for HTTP connection attempts and requests in
- seconds
+ spawn multiple connection_worker threads to handle jobs in the queue q
"""
- self.host = host
- self.https = https
- self.q = Queue.Queue(qsize) # if qsize=0, means infinite
- self.threads = threads
- self.timeout = timeout
- # start thread based on threads number
- self.tid = {} # dictionary of thread object
- for i in xrange(threads):
- tname = "PredictionIOThread-%s" % i # thread name
- self.tid[i] = threading.Thread(
- target=connection_worker, name=tname,
- kwargs={'host': self.host, 'request_queue': self.q,
- 'https': self.https, 'timeout': self.timeout})
- self.tid[i].setDaemon(True)
- self.tid[i].start()
+ def __init__(self, host, threads=1, qsize=0, https=True, timeout=5):
+ """constructor
- def make_request(self, request):
- """put the request into the q
- """
- self.q.put(request)
+ Args:
+ host: host of the server.
+ threads: type int, number of threads to be spawn
+ qsize: size of the queue q
+ https: indicate it is httpS (True) or http connection (False)
+ timeout: timeout for HTTP connection attempts and requests in
+ seconds
+ """
+ self.host = host
+ self.https = https
+ self.q = Queue.Queue(qsize) # if qsize=0, means infinite
+ self.threads = threads
+ self.timeout = timeout
+ # start thread based on threads number
+ self.tid = {} # dictionary of thread object
- def pending_requests(self):
- """number of pending requests in the queue
- """
- return self.q.qsize()
+ for i in xrange(threads):
+ tname = "PredictionIOThread-%s" % i # thread name
+ self.tid[i] = threading.Thread(
+ target=connection_worker, name=tname,
+ kwargs={'host': self.host, 'request_queue': self.q,
+ 'https': self.https, 'timeout': self.timeout})
+ self.tid[i].setDaemon(True)
+ self.tid[i].start()
- def close(self):
- """close this Connection. Call this when main program exits
- """
- # set kill message to q
- for i in xrange(self.threads):
- self.make_request(AsyncRequest("KILL", ""))
+ def make_request(self, request):
+ """put the request into the q
+ """
+ self.q.put(request)
- self.q.join() # wait for q empty
+ def pending_requests(self):
+ """number of pending requests in the queue
+ """
+ return self.q.qsize()
- for i in xrange(self.threads): # wait for all thread finish
- self.tid[i].join()
+ def close(self):
+ """close this Connection. Call this when main program exits
+ """
+ # set kill message to q
+ for i in xrange(self.threads):
+ self.make_request(AsyncRequest("KILL", ""))
+
+ self.q.join() # wait for q empty
+
+ for i in xrange(self.threads): # wait for all thread finish
+ self.tid[i].join()
diff --git a/predictionio/obsolete.py b/predictionio/obsolete.py
deleted file mode 100644
index dc19a09..0000000
--- a/predictionio/obsolete.py
+++ /dev/null
@@ -1,1205 +0,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
-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
-
diff --git a/setup.py b/setup.py
index 15163d1..67b12e3 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
try:
- from setuptools import setup
+ from setuptools import setup
except ImportError:
- from distutils.core import setup
+ from distutils.core import setup
__author__ = "The PredictionIO Team"
__email__ = "help@tappingstone.com"
@@ -10,7 +10,7 @@
setup(
name='PredictionIO',
- version="0.9.2",
+ version="0.9.6",
author=__author__,
author_email=__email__,
packages=['predictionio'],
@@ -18,17 +18,17 @@
license='LICENSE.txt',
description='PredictionIO Python SDK',
classifiers=[
- 'Programming Language :: Python',
- 'License :: OSI Approved :: Apache Software License',
- 'Operating System :: OS Independent',
- 'Development Status :: 4 - Beta',
- 'Intended Audience :: Developers',
- 'Intended Audience :: Science/Research',
- 'Environment :: Web Environment',
- 'Topic :: Internet :: WWW/HTTP',
- 'Topic :: Scientific/Engineering :: Artificial Intelligence',
- 'Topic :: Scientific/Engineering :: Information Analysis',
- 'Topic :: Software Development :: Libraries :: Python Modules'],
+ 'Programming Language :: Python',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Operating System :: OS Independent',
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Science/Research',
+ 'Environment :: Web Environment',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Scientific/Engineering :: Artificial Intelligence',
+ 'Topic :: Scientific/Engineering :: Information Analysis',
+ 'Topic :: Software Development :: Libraries :: Python Modules'],
long_description="""PredictionIO Python SDK
PredictionIO is a prediction server for building smart
@@ -50,5 +50,5 @@
PredictionIO API to Python programmers so that they
can focus on their application logic.
""",
- install_requires=["pytz >= 2014.2",],
- )
+ install_requires=["pytz >= 2014.2", ],
+)
diff --git a/tests-obsolete/conversion_test.py b/tests-obsolete/conversion_test.py
new file mode 100644
index 0000000..b9dca97
--- /dev/null
+++ b/tests-obsolete/conversion_test.py
@@ -0,0 +1,16 @@
+import timeit
+
+if __name__ == "__main__":
+ a = True
+
+ t = timeit.Timer("json.dumps(True)", "import json")
+
+ t_bool2json = t.timeit(1000) / 1000
+ print("bool 2 json")
+ print(t_bool2json)
+
+ t = timeit.Timer("str(True).lower()", "")
+
+ t_bool2string = t.timeit(1000) / 1000
+ print("bool 2 string")
+ print(t_bool2string)
diff --git a/tests-obsolete/import_testdata.py b/tests-obsolete/import_testdata.py
new file mode 100644
index 0000000..e5338c0
--- /dev/null
+++ b/tests-obsolete/import_testdata.py
@@ -0,0 +1,46 @@
+"""
+Import simple test data for testing getting itemrec
+"""
+import predictionio
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
+API_URL = "http://localhost:7070"
+
+MIN_VERSION = '0.5.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+if __name__ == "__main__":
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.create_user("u0")
+ client.create_user("u1")
+ client.create_user("u2")
+ client.create_user("u3")
+
+ client.create_item("i0", ("t1",), {"custom1": "i0c1"})
+ client.create_item("i1", ("t1", "t2"), {"custom1": "i1c1", "custom2": "i1c2"})
+ client.create_item("i2", ("t1", "t2"), {"custom2": "i2c2"})
+ client.create_item("i3", ("t1",))
+
+ client.identify("u0")
+ client.record_action_on_item("rate", "i0", {"pio_rate": 2})
+ client.record_action_on_item("rate", "i1", {"pio_rate": 3})
+ client.record_action_on_item("rate", "i2", {"pio_rate": 4})
+
+ client.identify("u1")
+ client.record_action_on_item("rate", "i2", {"pio_rate": 4})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 1})
+
+ client.identify("u2")
+ client.record_action_on_item("rate", "i1", {"pio_rate": 2})
+ client.record_action_on_item("rate", "i2", {"pio_rate": 1})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 3})
+
+ client.identify("u3")
+ client.record_action_on_item("rate", "i0", {"pio_rate": 5})
+ client.record_action_on_item("rate", "i1", {"pio_rate": 3})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 2})
+
+ client.close()
diff --git a/tests-obsolete/import_testdata_id_mismatch.py b/tests-obsolete/import_testdata_id_mismatch.py
new file mode 100644
index 0000000..104f75c
--- /dev/null
+++ b/tests-obsolete/import_testdata_id_mismatch.py
@@ -0,0 +1,46 @@
+"""
+Import simple test data for testing getting itemrec
+"""
+import predictionio
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
+API_URL = "http://localhost:8000"
+
+MIN_VERSION = '0.5.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+if __name__ == "__main__":
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.create_user("u0")
+ client.create_user("u1")
+ client.create_user("u2")
+ client.create_user("u3")
+
+ client.create_item("i0", ("t1",), {"custom1": "i0c1"})
+ client.create_item("i1", ("t1", "t2"), {"custom1": "i1c1", "custom2": "i1c2"})
+ client.create_item("i2", ("t1", "t2"), {"custom2": "i2c2"})
+ client.create_item("i3", ("t1",))
+
+ client.identify("u0x")
+ client.record_action_on_item("rate", "i0", {"pio_rate": 2})
+ client.record_action_on_item("rate", "i1", {"pio_rate": 3})
+ client.record_action_on_item("rate", "i2", {"pio_rate": 4})
+
+ client.identify("u1x")
+ client.record_action_on_item("rate", "i2", {"pio_rate": 4})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 1})
+
+ client.identify("u2x")
+ client.record_action_on_item("rate", "i1", {"pio_rate": 2})
+ client.record_action_on_item("rate", "i2", {"pio_rate": 1})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 3})
+
+ client.identify("u3x")
+ client.record_action_on_item("rate", "i0", {"pio_rate": 5})
+ client.record_action_on_item("rate", "i1", {"pio_rate": 3})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 2})
+
+ client.close()
diff --git a/tests-obsolete/import_testdata_special_char.py b/tests-obsolete/import_testdata_special_char.py
new file mode 100644
index 0000000..c047b6a
--- /dev/null
+++ b/tests-obsolete/import_testdata_special_char.py
@@ -0,0 +1,46 @@
+"""
+Import simple test data (id with special characters) for testing getting itemrec
+"""
+import predictionio
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
+API_URL = "http://localhost:8000"
+
+MIN_VERSION = '0.5.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+if __name__ == "__main__":
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.create_user("u0@u.n")
+ client.create_user("u1@u.n")
+ client.create_user("http://u2.com")
+ client.create_user("u3@u.n")
+
+ client.create_item("http://i0.com", ("t1",), {"custom1": "i0c1"})
+ client.create_item("i1@i1", ("t1", "t2"), {"custom1": "i1c1", "custom2": "i1c2"})
+ client.create_item("i2.org", ("t1", "t2"), {"custom2": "i2c2"})
+ client.create_item("i3", ("t1",))
+
+ client.identify("u0@u.n")
+ client.record_action_on_item("rate", "http://i0.com", {"pio_rate": 2})
+ client.record_action_on_item("rate", "i1@i1", {"pio_rate": 3})
+ client.record_action_on_item("rate", "i2.org", {"pio_rate": 4})
+
+ client.identify("u1@u.n")
+ client.record_action_on_item("rate", "i2.org", {"pio_rate": 4})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 1})
+
+ client.identify("http://u2.com")
+ client.record_action_on_item("rate", "i1@i1", {"pio_rate": 2})
+ client.record_action_on_item("rate", "i2.org", {"pio_rate": 1})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 3})
+
+ client.identify("u3@u.n")
+ client.record_action_on_item("rate", "http://i0.com", {"pio_rate": 5})
+ client.record_action_on_item("rate", "i1@i1", {"pio_rate": 3})
+ client.record_action_on_item("rate", "i3", {"pio_rate": 2})
+
+ client.close()
diff --git a/tests-obsolete/predictionio_itemrec_test.py b/tests-obsolete/predictionio_itemrec_test.py
new file mode 100644
index 0000000..3105f0f
--- /dev/null
+++ b/tests-obsolete/predictionio_itemrec_test.py
@@ -0,0 +1,336 @@
+"""
+Test getting itemrec after algo training completes.
+"""
+
+from __future__ import print_function
+
+import unittest
+
+import predictionio
+
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ" # replace this with your AppKey
+API_URL = "http://localhost:8000" # PredictoinIO Server
+
+DEBUG = True
+
+MIN_VERSION = '0.6.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+
+class TestPredictionIO(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_get_itemrec_exception_deprecated(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ try:
+ client.get_itemrec("uidwithoutrec", 10, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e: # noqa
+ pass # expected exception
+ except:
+ raise
+
+ client.close()
+
+ def test_get_itemrec_exception(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.identify("uidwithoutrec")
+
+ try:
+ client.get_itemrec_topn("python-itemrec-engine", 10)
+ except predictionio.ItemRecNotFoundError as e: # noqa
+ pass # expected exception
+ except:
+ raise
+
+ try:
+ client.get_itemrec_topn("python-itemrec-engine", 10,
+ {"pio_itypes": ("t1",), "pio_latlng": [1.34, 5.67], "pio_within": 5.0,
+ "pio_unit": "km", "pio_attributes": ["custom1", "custom2"]})
+ except predictionio.ItemRecNotFoundError as e: # noqa
+ pass # expected exception
+ except:
+ raise
+
+ client.close()
+
+ def test_get_itemrec_deprecated(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ # request more
+ try:
+ itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
+
+ try:
+ itemrec = client.get_itemrec("u1", 10, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": ["i2", "i1", "i0", "i3"]}) or
+ (itemrec == {"pio_iids": ["i2", "i0", "i1", "i3"]}))
+
+ try:
+ itemrec = client.get_itemrec("u2", 10, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertTrue((itemrec == {"pio_iids": ["i3", "i0", "i1", "i2"]}) or
+ (itemrec == {"pio_iids": ["i3", "i1", "i0", "i2"]}))
+
+ try:
+ itemrec = client.get_itemrec("u3", 6, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertTrue((itemrec == {"pio_iids": ["i0", "i1", "i2", "i3"]}) or
+ (itemrec == {"pio_iids": ["i0", "i2", "i1", "i3"]}))
+
+ # request less
+ try:
+ itemrec = client.get_itemrec("u0", 1, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2"]})
+
+ try:
+ itemrec = client.get_itemrec("u0", 2, "python-itemrec-engine")
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3"]})
+
+ # request with optional attributes
+
+ # pio_itypes
+ try:
+ itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t1", "t2"))
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
+
+ # subset itypes
+ try:
+ itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t2",))
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i1"]})
+
+ # nonexisting itypes
+ try:
+ itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("other-itype",))
+ except predictionio.ItemRecNotFoundError as e:
+ pass # expected no recommendation
+ except:
+ raise
+
+ # pio_attributes
+ try:
+ itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t1",),
+ pio_attributes=["custom1", "custom2"])
+ except predictionio.ItemRecNotFoundError as e: # noqa
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"], "custom1": [None, None, "i1c1", "i0c1"],
+ "custom2": ["i2c2", None, "i1c2", None]})
+
+ client.close()
+
+ def test_get_itemrec(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ # request more
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
+
+ client.identify("u1")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertTrue((itemrec == {"pio_iids": ["i2", "i1", "i0", "i3"]}) or
+ (itemrec == {"pio_iids": ["i2", "i0", "i1", "i3"]}))
+
+ client.identify("u2")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertTrue((itemrec == {"pio_iids": ["i3", "i0", "i1", "i2"]}) or
+ (itemrec == {"pio_iids": ["i3", "i1", "i0", "i2"]}))
+
+ client.identify("u3")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 6)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertTrue((itemrec == {"pio_iids": ["i0", "i1", "i2", "i3"]}) or
+ (itemrec == {"pio_iids": ["i0", "i2", "i1", "i3"]}))
+
+ # request less
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 1)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2"]})
+
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 2)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3"]})
+
+ # request with optional attributes
+
+ # pio_itypes
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t1", "t2")})
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
+
+ # subset itypes
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t2",)})
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+ if DEBUG:
+ print(itemrec)
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i1"]})
+
+ # nonexisting itypes
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("other-itype",)})
+ except predictionio.ItemRecNotFoundError as e:
+ pass # expected no recommendation
+ except:
+ raise
+
+ # pio_attributes
+ client.identify("u0")
+ try:
+ itemrec = client.get_itemrec_topn("python-itemrec-engine", 10,
+ {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
+ except predictionio.ItemRecNotFoundError as e: # noqa
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"], "custom1": [None, None, "i1c1", "i0c1"],
+ "custom2": ["i2c2", None, "i1c2", None]})
+
+ # TODO pio_latlng
+ # TODO pio_within
+ # TODO pio_unit
+
+ client.close()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tests-obsolete/predictionio_itemrec_test_special_char.py b/tests-obsolete/predictionio_itemrec_test_special_char.py
new file mode 100644
index 0000000..a622800
--- /dev/null
+++ b/tests-obsolete/predictionio_itemrec_test_special_char.py
@@ -0,0 +1,366 @@
+"""
+Test getting itemrec after algo training completes.
+"""
+import unittest
+
+import predictionio
+
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ" # replace this with your AppKey
+API_URL = "http://localhost:8000" # PredictoinIO Server
+
+DEBUG = True
+
+MIN_VERSION = '0.6.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+
+class TestPredictionIO(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_get_itemrec_deprecated(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ uid0 = "u0@u.n"
+ uid1 = "u1@u.n"
+ uid2 = "http://u2.com"
+ uid3 = "u3@u.n"
+
+ iid0 = "http://i0.com"
+ iid1 = "i1@i1"
+ iid2 = "i2.org"
+ iid3 = "i3"
+
+ engine_name = "itemrec"
+
+ # request more
+ try:
+ itemrec = client.get_itemrec(uid0, 10, engine_name)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
+
+ try:
+ itemrec = client.get_itemrec(uid1, 10, engine_name)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": [iid2, iid1, iid0, iid3]}) or
+ (itemrec == {"pio_iids": [iid2, iid0, iid1, iid3]}))
+
+ try:
+ itemrec = client.get_itemrec(uid2, 10, engine_name)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": [iid3, iid0, iid1, iid2]}) or
+ (itemrec == {"pio_iids": [iid3, iid1, iid0, iid2]}))
+
+ try:
+ itemrec = client.get_itemrec(uid3, 6, engine_name)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": [iid0, iid1, iid2, iid3]}) or
+ (itemrec == {"pio_iids": [iid0, iid2, iid1, iid3]}))
+
+ # request less
+ try:
+ itemrec = client.get_itemrec(uid0, 1, engine_name)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2]})
+
+ try:
+ itemrec = client.get_itemrec(uid0, 2, engine_name)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3]})
+
+ # request with optional attributes
+
+ # pio_itypes
+ try:
+ itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t1", "t2"))
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
+
+ # subset itypes
+ try:
+ itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t2",))
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid1]})
+
+ # nonexisting itypes
+ try:
+ client.get_itemrec(uid0, 10, engine_name, pio_itypes=("other-itype",))
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ pass # expected no recommendation
+ except:
+ raise
+
+ # pio_attributes
+ try:
+ itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t1",),
+ pio_attributes=["custom1", "custom2"])
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0], "custom1": [None, None, "i1c1", "i0c1"],
+ "custom2": ["i2c2", None, "i1c2", None]})
+
+ client.close()
+
+ def test_get_itemrec(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ uid0 = "u0@u.n"
+ uid1 = "u1@u.n"
+ uid2 = "http://u2.com"
+ uid3 = "u3@u.n"
+
+ iid0 = "http://i0.com"
+ iid1 = "i1@i1"
+ iid2 = "i2.org"
+ iid3 = "i3"
+
+ engine_name = "itemrec"
+
+ # request more
+ client.identify(uid0)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 10)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
+
+ client.identify(uid1)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 10)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": [iid2, iid1, iid0, iid3]}) or
+ (itemrec == {"pio_iids": [iid2, iid0, iid1, iid3]}))
+
+ client.identify(uid2)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 10)
+ except predictionio.ItemRecNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": [iid3, iid0, iid1, iid2]}) or
+ (itemrec == {"pio_iids": [iid3, iid1, iid0, iid2]}))
+
+ client.identify(uid3)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 6)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertTrue((itemrec == {"pio_iids": [iid0, iid1, iid2, iid3]}) or
+ (itemrec == {"pio_iids": [iid0, iid2, iid1, iid3]}))
+
+ # request less
+ client.identify(uid0)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 1)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2]})
+
+ client.identify(uid0)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 2)
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3]})
+
+ # request with optional attributes
+
+ # pio_itypes
+ client.identify(uid0)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t1", "t2")})
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
+
+ # subset itypes
+ client.identify(uid0)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t2",)})
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid1]})
+
+ # nonexisting itypes
+ client.identify(uid0)
+ try:
+ client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("other-itype",)})
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ pass # expected no recommendation
+ except:
+ raise
+
+ # pio_attributes
+ client.identify(uid0)
+ try:
+ itemrec = client.get_itemrec_topn(engine_name, 10,
+ {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
+ except predictionio.ItemRecNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemrec)
+
+ self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0], "custom1": [None, None, "i1c1", "i0c1"],
+ "custom2": ["i2c2", None, "i1c2", None]})
+
+ # TODO pio_latlng
+ # TODO pio_within
+ # TODO pio_unit
+
+ client.close()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tests-obsolete/predictionio_itemsim_test.py b/tests-obsolete/predictionio_itemsim_test.py
new file mode 100644
index 0000000..45fa151
--- /dev/null
+++ b/tests-obsolete/predictionio_itemsim_test.py
@@ -0,0 +1,200 @@
+"""
+Test getting itemsim after algo training completes (pdio-itemsimcf with cosine sim).
+"""
+import unittest
+
+import predictionio
+
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ" # replace this with your AppKey
+API_URL = "http://localhost:8000" # PredictoinIO Server
+
+DEBUG = True
+
+MIN_VERSION = '0.6.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+
+class TestPredictionIO(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_get_itemsim_exception(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ try:
+ client.get_itemsim_topn("python-itemsim-engine", "iidwithoutsim", 10)
+ except predictionio.ItemSimNotFoundError as e:
+ pass # expected exception
+ except:
+ raise
+
+ try:
+ client.get_itemsim_topn("python-itemsim-engine", "iidwithoutsim", 10,
+ {"pio_itypes": ("t1",), "pio_latlng": [1.34, 5.67], "pio_within": 5.0,
+ "pio_unit": "km", "pio_attributes": ["custom1", "custom2"]})
+ except predictionio.ItemSimNotFoundError as e:
+ if DEBUG:
+ print(e)
+ pass # expected exception
+ except:
+ raise
+
+ client.close()
+
+ def test_get_itemsim(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ # request more than what is available
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i0", 10)
+ except predictionio.ItemSimNotFoundError as e:
+ print
+ "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertTrue((itemsim == {"pio_iids": ["i1", "i2", "i3"]}) or
+ (itemsim == {"pio_iids": ["i1", "i3", "i2"]}))
+
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10)
+ except predictionio.ItemSimNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertTrue((itemsim == {"pio_iids": ["i2", "i3", "i0"]}))
+
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i2", 10)
+ except predictionio.ItemSimNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertTrue((itemsim == {"pio_iids": ["i1", "i3", "i0"]}))
+
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i3", 10)
+ except predictionio.ItemSimNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertTrue((itemsim == {"pio_iids": ["i1", "i2", "i0"]}))
+
+ # request less
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 1)
+ except predictionio.ItemSimNotFoundError as e:
+ print
+ "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertEqual(itemsim, {"pio_iids": ["i2"]})
+
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 2)
+ except predictionio.ItemSimNotFoundError as e:
+ print
+ "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertEqual(itemsim, {"pio_iids": ["i2", "i3"]})
+
+ # request with optional attributes
+
+ # pio_itypes
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t1", "t2")})
+ except predictionio.ItemSimNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertEqual(itemsim, {"pio_iids": ["i2", "i3", "i0"]})
+
+ # subset itypes
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t2",)})
+ except predictionio.ItemSimNotFoundError as e:
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertEqual(itemsim, {"pio_iids": ["i2"]})
+
+ # nonexisting itypes
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i0", 10, {"pio_itypes": ("other-itype",)})
+ except predictionio.ItemSimNotFoundError as e:
+ pass # expected no recommendation
+ except:
+ raise
+
+ # pio_attributes
+ try:
+ itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10,
+ {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
+ except predictionio.ItemSimNotFoundError as e:
+ print(e)
+ print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
+ raise
+ except:
+ raise
+
+ if DEBUG:
+ print(itemsim)
+
+ self.assertEqual(itemsim, {"pio_iids": ["i2", "i3", "i0"], "custom1": [None, None, "i0c1"],
+ "custom2": ["i2c2", None, None]})
+
+ # TODO pio_latlng
+ # TODO pio_within
+ # TODO pio_unit
+
+ client.close()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/tests-obsolete/predictionio_test.py b/tests-obsolete/predictionio_test.py
new file mode 100644
index 0000000..696718c
--- /dev/null
+++ b/tests-obsolete/predictionio_test.py
@@ -0,0 +1,257 @@
+"""
+Test Python SDK
+"""
+import unittest
+
+import predictionio
+import time
+
+
+APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ" # replace this with your AppKey
+API_URL = "http://localhost:8000" # PredictoinIO Server
+
+MIN_VERSION = '0.6.0'
+if predictionio.__version__ < MIN_VERSION:
+ err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
+ raise Exception(err)
+
+# print predictionio.__version__
+# predictionio.connection.enable_log()
+
+
+class TestPredictionIO(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_status(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+ status = client.get_status()
+ self.assertEqual(status, "PredictionIO Output API is online.")
+ client.close()
+
+ def _test_user(self, uids):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ uid1 = uids[0]
+ uid2 = uids[1]
+ uid3 = uids[2]
+ uid4 = uids[3]
+ uid5 = uids[4]
+
+ # create users and get them back
+ client.create_user(uid1)
+ # create user with optional attributes
+ client.create_user(uid2, {"pio_latlng": [1.2, 33.3]})
+ client.create_user(uid3, {"pio_latlng": [4.5, 67.8], "pio_inactive": True})
+ # create user with custom attributes
+ client.create_user(uid4, {"pio_latlng": [1.2, 33.3], "custom1": "value1", "custom2": "value2"})
+ client.create_user(uid5, {"custom1": "u5c1", "custom2": "u5c2"})
+
+ user1 = client.get_user(uid1)
+ user2 = client.get_user(uid2)
+ user3 = client.get_user(uid3)
+ user4 = client.get_user(uid4)
+ user5 = client.get_user(uid5)
+
+ self.assertEqual(user1, {"pio_uid": uid1})
+ self.assertEqual(user2, {"pio_uid": uid2, "pio_latlng": [1.2, 33.3]})
+ self.assertEqual(user3, {"pio_uid": uid3, "pio_latlng": [4.5, 67.8], "pio_inactive": True})
+ self.assertEqual(user4, {"pio_uid": uid4, "pio_latlng": [1.2, 33.3], "custom1": "value1", "custom2": "value2"})
+ self.assertEqual(user5, {"pio_uid": uid5, "custom1": "u5c1", "custom2": "u5c2"})
+
+ # delete user and then try to get it
+ client.delete_user(uid1)
+
+ try:
+ client.get_user(uid1)
+ except predictionio.UserNotFoundError as e: # noqa
+ pass # expected exception
+ except:
+ raise
+
+ # other users still exist
+ user2 = client.get_user(uid2)
+ self.assertEqual(user2, {"pio_uid": uid2, "pio_latlng": [1.2, 33.3]})
+
+ # read, modify, write
+ user3 = client.get_user(uid3)
+ self.assertEqual(user3, {"pio_uid": uid3, "pio_latlng": [4.5, 67.8], "pio_inactive": True})
+ del user3["pio_uid"]
+ user3["pio_latlng"] = [5.6, 10.11]
+ user3["pio_inactive"] = False
+ user3["custom1"] = "food"
+ client.create_user(uid3, user3)
+ updated_user3 = client.get_user(uid3)
+ self.assertEqual(updated_user3,
+ {"pio_uid": uid3, "pio_latlng": [5.6, 10.11], "pio_inactive": False, "custom1": "food"})
+
+ user4 = client.get_user(uid4)
+ self.assertEqual(user4, {"pio_uid": uid4, "pio_latlng": [1.2, 33.3], "custom1": "value1", "custom2": "value2"})
+ del user4["pio_uid"]
+ user4["custom1"] = "new value"
+ client.create_user(uid4, user4)
+ updated_user4 = client.get_user(uid4)
+ self.assertEqual(updated_user4,
+ {"pio_uid": uid4, "pio_latlng": [1.2, 33.3], "custom1": "new value", "custom2": "value2"})
+
+ client.close()
+
+ def test_user(self):
+ self._test_user(["u1", "u2", "u3", "u4", "u5"])
+ # test special characters in uid
+ self._test_user(["u1@a.com", "u2@ap/ple", "u3@foo.bar", "u4/a/b", "&^%$()u5"])
+
+ def _test_item(self, iids):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ iid1 = iids[0]
+ iid2 = iids[1]
+ iid3 = iids[2]
+ iid4 = iids[3]
+ iid5 = iids[4]
+
+ # create items and read back
+ client.create_item(iid1, ("t1", "t2", "t3"))
+ client.create_item(iid2, ("t1",))
+ client.create_item(iid3, ("t2",),
+ {"pio_price": 4.99, "pio_profit": 2.0, "pio_startT": 12345667, "pio_endT": 4567788,
+ "pio_latlng": [1.345, 9.876], "pio_inactive": True})
+ client.create_item(iid4, ("t2",), {"pio_latlng": [1.2345, 10.11], "custom1": "value1"})
+ client.create_item(iid5, ("t1", "t2"), {"custom1": "i5value1", "custom2": "i5value2"})
+
+ item1 = client.get_item(iid1)
+ item2 = client.get_item(iid2)
+ item3 = client.get_item(iid3)
+ item4 = client.get_item(iid4)
+ item5 = client.get_item(iid5)
+
+ del item1["pio_startT"] # pio_startT is automatically inserted, don't compare
+ self.assertEqual(item1, {"pio_iid": iid1, "pio_itypes": ("t1", "t2", "t3")})
+ del item2["pio_startT"]
+ self.assertEqual(item2, {"pio_iid": iid2, "pio_itypes": ("t1",)})
+ self.assertEqual(item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 4.99, "pio_profit": 2.0,
+ "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876],
+ "pio_inactive": True})
+ del item4["pio_startT"]
+ self.assertEqual(item4,
+ {"pio_iid": iid4, "pio_itypes": ("t2",), "pio_latlng": [1.2345, 10.11], "custom1": "value1"})
+ del item5["pio_startT"]
+ self.assertEqual(item5,
+ {"pio_iid": iid5, "pio_itypes": ("t1", "t2"), "custom1": "i5value1", "custom2": "i5value2"})
+
+ # delete and then try to get it
+ client.delete_item(iid2)
+
+ try:
+ item2 = client.get_item(iid2)
+ except predictionio.ItemNotFoundError as e: # noqa
+ pass # expected exception
+ except:
+ raise
+
+ # others still exist
+ item3 = client.get_item(iid3)
+ self.assertEqual(item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 4.99, "pio_profit": 2.0,
+ "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876],
+ "pio_inactive": True})
+
+ # read, modify, write
+ del item3["pio_iid"]
+ item3_itypes = item3.pop("pio_itypes")
+ item3["pio_price"] = 6.99
+ item3["custom1"] = "some value"
+ client.create_item(iid3, item3_itypes, item3)
+ updated_item3 = client.get_item(iid3)
+ self.assertEqual(updated_item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 6.99, "pio_profit": 2.0,
+ "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876],
+ "pio_inactive": True, "custom1": "some value"})
+
+ client.close()
+
+ def test_item(self):
+ self._test_item(["i1", "i2", "i3", "i4", "i5"])
+ # test special characters in iid
+ self._test_item(["i1@abc.com", "i2/f/bar//@@foo", "$$i3%%$~~", "http://www.i4.com", "``i5/apple/"])
+
+ def test_u2iAction_deprecated(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.user_like_item("u1", "i1")
+ client.user_dislike_item("u2", "i2")
+ client.user_view_item("u3", "i3")
+ client.user_rate_item("u4", "i4", 4)
+ client.user_conversion_item("u5", "i5")
+
+ client.close()
+
+ def test_u2iAction(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.identify("u101")
+
+ # required param
+ client.record_action_on_item("like", "i1")
+ client.record_action_on_item("dislike", "i2")
+ client.record_action_on_item("view", "i3")
+ client.record_action_on_item("rate", "i4", {"pio_rate": 1})
+ client.record_action_on_item("conversion", "i5")
+
+ client.identify("u102")
+
+ # with optional param
+ client.record_action_on_item("like", "i1", {"pio_latlng": [1.23, 4.56]})
+ client.record_action_on_item("dislike", "i2", {"pio_t": 1234567689})
+ client.record_action_on_item("view", "i3", {"pio_latlng": [4.67, 1.44], "pio_t": 3445566778})
+ client.record_action_on_item("rate", "i4", {"pio_rate": 1, "pio_latlng": [66.78, 9.10]})
+ client.record_action_on_item("conversion", "i5", {"pio_price": 12.5})
+
+ # uid and iid with special characters
+ client.identify("u1@a.com")
+ client.record_action_on_item("view", "i3@bb.com")
+ client.record_action_on_item("view", "http://www.yahoo.com")
+
+ client.close()
+
+ def test_pending_requests(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL)
+
+ client.identify("u111")
+ for i in range(100):
+ client.arecord_action_on_item("like", str(i))
+
+ n = 1
+ while n > 0:
+ n = client.pending_requests()
+ time.sleep(0.1)
+ # print n
+
+ client.close()
+
+ def test_qsize(self):
+ client = predictionio.Client(APP_KEY, 1, API_URL, qsize=10)
+
+ client.identify("u222")
+ for i in range(100):
+ client.arecord_action_on_item("like", str(i))
+
+ n = 1
+ while n > 0:
+ n = client.pending_requests()
+ time.sleep(0.1)
+ # print n
+
+ client.close()
+
+
+"""
+to run individual test:
+$ python -m unittest predictionio_test.TestPredictionIO.test_user
+
+to run ALL tests:
+% python predictionio_test.py
+"""
+if __name__ == "__main__":
+ unittest.main()
diff --git a/examples/obsolete/__init__.py b/tests/.keep
similarity index 100%
rename from examples/obsolete/__init__.py
rename to tests/.keep
diff --git a/tests/conversion_test.py b/tests/conversion_test.py
deleted file mode 100644
index ffcd90f..0000000
--- a/tests/conversion_test.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import timeit
-import json
-
-if __name__ == "__main__":
- a = True
-
- t = timeit.Timer("json.dumps(True)", "import json")
-
- t_bool2json = t.timeit(1000)/1000
- print "bool 2 json"
- print t_bool2json
-
- t = timeit.Timer("str(True).lower()", "")
-
- t_bool2string = t.timeit(1000)/1000
- print "bool 2 string"
- print t_bool2string
-
-
-
-
-
-
diff --git a/tests/import_testdata.py b/tests/import_testdata.py
deleted file mode 100644
index 57ec48c..0000000
--- a/tests/import_testdata.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
-Import simple test data for testing getting itemrec
-"""
-import predictionio
-
-APP_KEY = "tGgZ7bJDpSyxLndJUBWgyAUwfBgVSTjO6KkhjnMpzCi7vSgPoYnXYptyVlg3vjLH"
-API_URL = "http://localhost:8000"
-
-MIN_VERSION = '0.5.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-if __name__ == "__main__":
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.create_user("u0")
- client.create_user("u1")
- client.create_user("u2")
- client.create_user("u3")
-
- client.create_item("i0", ("t1",), {"custom1": "i0c1"})
- client.create_item("i1", ("t1","t2"), {"custom1": "i1c1", "custom2": "i1c2"})
- client.create_item("i2", ("t1","t2"), {"custom2": "i2c2"})
- client.create_item("i3", ("t1",))
-
- client.identify("u0")
- client.record_action_on_item("rate", "i0", { "pio_rate": 2 })
- client.record_action_on_item("rate", "i1", { "pio_rate": 3 })
- client.record_action_on_item("rate", "i2", { "pio_rate": 4 })
-
- client.identify("u1")
- client.record_action_on_item("rate", "i2", { "pio_rate": 4 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 1 })
-
- client.identify("u2")
- client.record_action_on_item("rate", "i1", { "pio_rate": 2 })
- client.record_action_on_item("rate", "i2", { "pio_rate": 1 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 3 })
-
- client.identify("u3")
- client.record_action_on_item("rate", "i0", { "pio_rate": 5 })
- client.record_action_on_item("rate", "i1", { "pio_rate": 3 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 2 })
-
- client.close()
-
-
-
-
-
-
diff --git a/tests/import_testdata_id_mismatch.py b/tests/import_testdata_id_mismatch.py
deleted file mode 100644
index 17d707a..0000000
--- a/tests/import_testdata_id_mismatch.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
-Import simple test data for testing getting itemrec
-"""
-import predictionio
-
-APP_KEY = "7zwXYnroz52gemLdHEU20Nn8c2SyobFpnrzoTGOolCe8ZRH2zmGyhVknj9Sa7P6x"
-API_URL = "http://localhost:8000"
-
-MIN_VERSION = '0.5.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-if __name__ == "__main__":
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.create_user("u0")
- client.create_user("u1")
- client.create_user("u2")
- client.create_user("u3")
-
- client.create_item("i0", ("t1",), {"custom1": "i0c1"})
- client.create_item("i1", ("t1","t2"), {"custom1": "i1c1", "custom2": "i1c2"})
- client.create_item("i2", ("t1","t2"), {"custom2": "i2c2"})
- client.create_item("i3", ("t1",))
-
- client.identify("u0x")
- client.record_action_on_item("rate", "i0", { "pio_rate": 2 })
- client.record_action_on_item("rate", "i1", { "pio_rate": 3 })
- client.record_action_on_item("rate", "i2", { "pio_rate": 4 })
-
- client.identify("u1x")
- client.record_action_on_item("rate", "i2", { "pio_rate": 4 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 1 })
-
- client.identify("u2x")
- client.record_action_on_item("rate", "i1", { "pio_rate": 2 })
- client.record_action_on_item("rate", "i2", { "pio_rate": 1 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 3 })
-
- client.identify("u3x")
- client.record_action_on_item("rate", "i0", { "pio_rate": 5 })
- client.record_action_on_item("rate", "i1", { "pio_rate": 3 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 2 })
-
- client.close()
-
-
-
-
-
-
diff --git a/tests/import_testdata_special_char.py b/tests/import_testdata_special_char.py
deleted file mode 100644
index e9445be..0000000
--- a/tests/import_testdata_special_char.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
-Import simple test data (id with special characters) for testing getting itemrec
-"""
-import predictionio
-
-APP_KEY = "GToKwk78As0LBp2fAx2YNUBPZFZvtwy6MJkGwRASiD6Q77JjBnTaXBxzBTd52ICE"
-API_URL = "http://localhost:8000"
-
-MIN_VERSION = '0.5.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-if __name__ == "__main__":
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.create_user("u0@u.n")
- client.create_user("u1@u.n")
- client.create_user("http://u2.com")
- client.create_user("u3@u.n")
-
- client.create_item("http://i0.com", ("t1",), {"custom1": "i0c1"})
- client.create_item("i1@i1", ("t1","t2"), {"custom1": "i1c1", "custom2": "i1c2"})
- client.create_item("i2.org", ("t1","t2"), {"custom2": "i2c2"})
- client.create_item("i3", ("t1",))
-
- client.identify("u0@u.n")
- client.record_action_on_item("rate", "http://i0.com", { "pio_rate": 2 })
- client.record_action_on_item("rate", "i1@i1", { "pio_rate": 3 })
- client.record_action_on_item("rate", "i2.org", { "pio_rate": 4 })
-
- client.identify("u1@u.n")
- client.record_action_on_item("rate", "i2.org", { "pio_rate": 4 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 1 })
-
- client.identify("http://u2.com")
- client.record_action_on_item("rate", "i1@i1", { "pio_rate": 2 })
- client.record_action_on_item("rate", "i2.org", { "pio_rate": 1 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 3 })
-
- client.identify("u3@u.n")
- client.record_action_on_item("rate", "http://i0.com", { "pio_rate": 5 })
- client.record_action_on_item("rate", "i1@i1", { "pio_rate": 3 })
- client.record_action_on_item("rate", "i3", { "pio_rate": 2 })
-
- client.close()
-
-
-
-
-
-
diff --git a/tests/predictionio_itemrec_test.py b/tests/predictionio_itemrec_test.py
deleted file mode 100644
index 5f91501..0000000
--- a/tests/predictionio_itemrec_test.py
+++ /dev/null
@@ -1,300 +0,0 @@
-"""
-Test getting itemrec after algo training completes.
-"""
-import predictionio
-import unittest
-import time
-
-APP_KEY = "y2Fk4BACEGYeJnqBF4zL9TmrIBdF9va3gyFaLsnM7PVyUNf0G00zC8vCnyBx5hdA" # replace this with your AppKey
-API_URL = "http://localhost:8000" # PredictoinIO Server
-
-DEBUG = True
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-class TestPredictionIO(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def test_get_itemrec_exception_deprecated(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- try:
- itemrec = client.get_itemrec("uidwithoutrec", 10, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- client.close()
-
- def test_get_itemrec_exception(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.identify("uidwithoutrec")
-
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
- except predictionio.ItemRecNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, { "pio_itypes": ("t1",), "pio_latlng": [1.34, 5.67], "pio_within": 5.0, "pio_unit": "km", "pio_attributes": ["custom1", "custom2"] })
- except predictionio.ItemRecNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- client.close()
-
- def test_get_itemrec_deprecated(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- # request more
- try:
- itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
- try:
- itemrec = client.get_itemrec("u1", 10, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": ["i2", "i1", "i0", "i3"]}) or
- (itemrec == {"pio_iids": ["i2", "i0", "i1", "i3"]}) )
-
- try:
- itemrec = client.get_itemrec("u2", 10, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": ["i3", "i0", "i1", "i2"]}) or
- (itemrec == {"pio_iids": ["i3", "i1", "i0", "i2"]}) )
-
- try:
- itemrec = client.get_itemrec("u3", 6, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": ["i0", "i1", "i2", "i3"]}) or
- (itemrec == {"pio_iids": ["i0", "i2", "i1", "i3"]}) )
-
- # request less
- try:
- itemrec = client.get_itemrec("u0", 1, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2"]})
-
- try:
- itemrec = client.get_itemrec("u0", 2, "python-itemrec-engine")
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3"]})
-
- # request with optional attributes
-
- # pio_itypes
- try:
- itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t1","t2"))
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
- # subset itypes
- try:
- itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t2",))
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i1"]})
-
- # nonexisting itypes
- try:
- itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("other-itype",))
- except predictionio.ItemRecNotFoundError as e:
- pass # expected no recommendation
- except:
- raise
-
- # pio_attributes
- try:
- itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t1",), pio_attributes=["custom1", "custom2"])
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"], "custom1": [None, None, "i1c1", "i0c1"], "custom2": ["i2c2", None, "i1c2", None]})
-
- client.close()
-
-
- def test_get_itemrec(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- # request more
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
- client.identify("u1")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": ["i2", "i1", "i0", "i3"]}) or
- (itemrec == {"pio_iids": ["i2", "i0", "i1", "i3"]}) )
-
- client.identify("u2")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": ["i3", "i0", "i1", "i2"]}) or
- (itemrec == {"pio_iids": ["i3", "i1", "i0", "i2"]}) )
-
- client.identify("u3")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 6)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": ["i0", "i1", "i2", "i3"]}) or
- (itemrec == {"pio_iids": ["i0", "i2", "i1", "i3"]}) )
-
- # request less
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 1)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2"]})
-
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 2)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3"]})
-
- # request with optional attributes
-
- # pio_itypes
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t1","t2")})
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
- # subset itypes
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t2",)})
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i1"]})
-
- # nonexisting itypes
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("other-itype",)})
- except predictionio.ItemRecNotFoundError as e:
- pass # expected no recommendation
- except:
- raise
-
- # pio_attributes
- client.identify("u0")
- try:
- itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"], "custom1": [None, None, "i1c1", "i0c1"], "custom2": ["i2c2", None, "i1c2", None]})
-
- # TODO pio_latlng
- # TODO pio_within
- # TODO pio_unit
-
- client.close()
-
-if __name__ == "__main__" :
- unittest.main()
diff --git a/tests/predictionio_itemrec_test_special_char.py b/tests/predictionio_itemrec_test_special_char.py
deleted file mode 100644
index e4ac6c8..0000000
--- a/tests/predictionio_itemrec_test_special_char.py
+++ /dev/null
@@ -1,291 +0,0 @@
-"""
-Test getting itemrec after algo training completes.
-"""
-import predictionio
-import unittest
-import time
-
-APP_KEY = "GToKwk78As0LBp2fAx2YNUBPZFZvtwy6MJkGwRASiD6Q77JjBnTaXBxzBTd52ICE" # replace this with your AppKey
-API_URL = "http://localhost:8000" # PredictoinIO Server
-
-DEBUG = True
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-class TestPredictionIO(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def test_get_itemrec_deprecated(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- uid0 = "u0@u.n"
- uid1 = "u1@u.n"
- uid2 = "http://u2.com"
- uid3 = "u3@u.n"
-
- iid0 = "http://i0.com"
- iid1 = "i1@i1"
- iid2 = "i2.org"
- iid3 = "i3"
-
- engine_name = "itemrec"
-
- # request more
- try:
- itemrec = client.get_itemrec(uid0, 10, engine_name)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
- try:
- itemrec = client.get_itemrec(uid1, 10, engine_name)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": [iid2, iid1, iid0, iid3]}) or
- (itemrec == {"pio_iids": [iid2, iid0, iid1, iid3]}) )
-
- try:
- itemrec = client.get_itemrec(uid2, 10, engine_name)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": [iid3, iid0, iid1, iid2]}) or
- (itemrec == {"pio_iids": [iid3, iid1, iid0, iid2]}) )
-
- try:
- itemrec = client.get_itemrec(uid3, 6, engine_name)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": [iid0, iid1, iid2, iid3]}) or
- (itemrec == {"pio_iids": [iid0, iid2, iid1, iid3]}) )
-
- # request less
- try:
- itemrec = client.get_itemrec(uid0, 1, engine_name)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2]})
-
- try:
- itemrec = client.get_itemrec(uid0, 2, engine_name)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3]})
-
- # request with optional attributes
-
- # pio_itypes
- try:
- itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t1","t2"))
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
- # subset itypes
- try:
- itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t2",))
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid1]})
-
- # nonexisting itypes
- try:
- itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("other-itype",))
- except predictionio.ItemRecNotFoundError as e:
- pass # expected no recommendation
- except:
- raise
-
- # pio_attributes
- try:
- itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t1",), pio_attributes=["custom1", "custom2"])
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0], "custom1": [None, None, "i1c1", "i0c1"], "custom2": ["i2c2", None, "i1c2", None]})
-
- client.close()
-
-
- def test_get_itemrec(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- uid0 = "u0@u.n"
- uid1 = "u1@u.n"
- uid2 = "http://u2.com"
- uid3 = "u3@u.n"
-
- iid0 = "http://i0.com"
- iid1 = "i1@i1"
- iid2 = "i2.org"
- iid3 = "i3"
-
- engine_name = "itemrec"
-
- # request more
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
- client.identify(uid1)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": [iid2, iid1, iid0, iid3]}) or
- (itemrec == {"pio_iids": [iid2, iid0, iid1, iid3]}) )
-
- client.identify(uid2)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": [iid3, iid0, iid1, iid2]}) or
- (itemrec == {"pio_iids": [iid3, iid1, iid0, iid2]}) )
-
- client.identify(uid3)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 6)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertTrue( (itemrec == {"pio_iids": [iid0, iid1, iid2, iid3]}) or
- (itemrec == {"pio_iids": [iid0, iid2, iid1, iid3]}) )
-
- # request less
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 1)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2]})
-
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 2)
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3]})
-
- # request with optional attributes
-
- # pio_itypes
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t1","t2")})
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
- # subset itypes
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t2",)})
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid1]})
-
- # nonexisting itypes
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("other-itype",)})
- except predictionio.ItemRecNotFoundError as e:
- pass # expected no recommendation
- except:
- raise
-
- # pio_attributes
- client.identify(uid0)
- try:
- itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
- except predictionio.ItemRecNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemrec
- self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0], "custom1": [None, None, "i1c1", "i0c1"], "custom2": ["i2c2", None, "i1c2", None]})
-
- # TODO pio_latlng
- # TODO pio_within
- # TODO pio_unit
-
- client.close()
-
-if __name__ == "__main__" :
- unittest.main()
diff --git a/tests/predictionio_itemsim_test.py b/tests/predictionio_itemsim_test.py
deleted file mode 100644
index c540f02..0000000
--- a/tests/predictionio_itemsim_test.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""
-Test getting itemsim after algo training completes (pdio-itemsimcf with cosine sim).
-"""
-import predictionio
-import unittest
-import time
-
-APP_KEY = "y2Fk4BACEGYeJnqBF4zL9TmrIBdF9va3gyFaLsnM7PVyUNf0G00zC8vCnyBx5hdA" # replace this with your AppKey
-API_URL = "http://localhost:8000" # PredictoinIO Server
-
-DEBUG = True
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-class TestPredictionIO(unittest.TestCase):
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def test_get_itemsim_exception(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "iidwithoutsim", 10)
- except predictionio.ItemSimNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "iidwithoutsim", 10, { "pio_itypes": ("t1",), "pio_latlng": [1.34, 5.67], "pio_within": 5.0, "pio_unit": "km", "pio_attributes": ["custom1", "custom2"] })
- except predictionio.ItemSimNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- client.close()
-
- def test_get_itemsim(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- # request more than what is available
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i0", 10)
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertTrue( (itemsim == {"pio_iids": ["i1", "i2", "i3"]}) or
- (itemsim == {"pio_iids": ["i1", "i3", "i2"]}) )
-
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10)
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertTrue( (itemsim == {"pio_iids": ["i2", "i3", "i0"]}) )
-
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i2", 10)
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertTrue( (itemsim == {"pio_iids": ["i1", "i3", "i0"]}) )
-
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i3", 10)
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertTrue( (itemsim == {"pio_iids": ["i1", "i2", "i0"]}) )
-
- # request less
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 1)
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertEqual(itemsim, {"pio_iids": ["i2"]})
-
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 2)
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertEqual(itemsim, {"pio_iids": ["i2", "i3"]})
-
- # request with optional attributes
-
- # pio_itypes
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t1","t2")})
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertEqual(itemsim, {"pio_iids": ["i2", "i3", "i0"]})
-
- # subset itypes
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t2",)})
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertEqual(itemsim, {"pio_iids": ["i2"]})
-
- # nonexisting itypes
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i0", 10, {"pio_itypes": ("other-itype",)})
- except predictionio.ItemSimNotFoundError as e:
- pass # expected no recommendation
- except:
- raise
-
- # pio_attributes
- try:
- itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
- except predictionio.ItemSimNotFoundError as e:
- print "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
- raise
- except:
- raise
- if DEBUG: print itemsim
- self.assertEqual(itemsim, {"pio_iids": ["i2", "i3", "i0"], "custom1": [None, None, "i0c1"], "custom2": ["i2c2", None, None]})
-
- # TODO pio_latlng
- # TODO pio_within
- # TODO pio_unit
-
- client.close()
-
-if __name__ == "__main__" :
- unittest.main()
diff --git a/tests/predictionio_test.py b/tests/predictionio_test.py
deleted file mode 100644
index 28b3d06..0000000
--- a/tests/predictionio_test.py
+++ /dev/null
@@ -1,246 +0,0 @@
-"""
-Test Python SDK
-"""
-import predictionio
-import unittest
-import time
-
-APP_KEY = "GToKwk78As0LBp2fAx2YNUBPZFZvtwy6MJkGwRASiD6Q77JjBnTaXBxzBTd52ICE" # replace this with your AppKey
-API_URL = "http://localhost:8000" # PredictoinIO Server
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
- err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
- raise Exception(err)
-
-#print predictionio.__version__
-#predictionio.connection.enable_log()
-
-class TestPredictionIO(unittest.TestCase):
-
- def setUp(self):
- pass
-
- def tearDown(self):
- pass
-
- def test_status(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
- status = client.get_status()
- self.assertEqual(status, "PredictionIO Output API is online.")
- client.close()
-
- def _test_user(self, uids):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- uid1 = uids[0]
- uid2 = uids[1]
- uid3 = uids[2]
- uid4 = uids[3]
- uid5 = uids[4]
-
- # create users and get them back
- client.create_user(uid1)
- # create user with optional attributes
- client.create_user(uid2, { "pio_latlng": [1.2,33.3] })
- client.create_user(uid3, { "pio_latlng": [4.5,67.8], "pio_inactive": True } )
- # create user with custom attributes
- client.create_user(uid4, { "pio_latlng": [1.2,33.3], "custom1": "value1", "custom2": "value2" })
- client.create_user(uid5, { "custom1": "u5c1", "custom2": "u5c2" })
-
- user1 = client.get_user(uid1)
- user2 = client.get_user(uid2)
- user3 = client.get_user(uid3)
- user4 = client.get_user(uid4)
- user5 = client.get_user(uid5)
-
- self.assertEqual(user1, {"pio_uid" : uid1})
- self.assertEqual(user2, {"pio_uid" : uid2, "pio_latlng": [1.2,33.3]})
- self.assertEqual(user3, {"pio_uid" : uid3, "pio_latlng" : [4.5,67.8], "pio_inactive" : True})
- self.assertEqual(user4, {"pio_uid" : uid4, "pio_latlng": [1.2,33.3], "custom1": "value1", "custom2": "value2" })
- self.assertEqual(user5, {"pio_uid" : uid5, "custom1": "u5c1", "custom2": "u5c2" })
-
- # delete user and then try to get it
- client.delete_user(uid1)
-
- try:
- user = client.get_user(uid1)
- except predictionio.UserNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- # other users still exist
- user2 = client.get_user(uid2)
- self.assertEqual(user2, {"pio_uid" : uid2, "pio_latlng": [1.2,33.3]})
-
- # read, modify, write
- user3 = client.get_user(uid3)
- self.assertEqual(user3, {"pio_uid" : uid3, "pio_latlng" : [4.5,67.8], "pio_inactive" : True})
- del user3["pio_uid"]
- user3["pio_latlng"] = [5.6,10.11]
- user3["pio_inactive"] = False
- user3["custom1"] = "food"
- client.create_user(uid3, user3)
- updated_user3 = client.get_user(uid3)
- self.assertEqual(updated_user3, {"pio_uid" : uid3, "pio_latlng" : [5.6,10.11], "pio_inactive" : False, "custom1" : "food"} )
-
- user4 = client.get_user(uid4)
- self.assertEqual(user4, {"pio_uid" : uid4, "pio_latlng": [1.2,33.3], "custom1": "value1", "custom2": "value2" })
- del user4["pio_uid"]
- user4["custom1"] = "new value"
- client.create_user(uid4, user4)
- updated_user4 = client.get_user(uid4)
- self.assertEqual(updated_user4, {"pio_uid" : uid4, "pio_latlng": [1.2,33.3], "custom1": "new value", "custom2": "value2" })
-
- client.close()
-
- def test_user(self):
- self._test_user(["u1", "u2", "u3", "u4", "u5"])
- # test special characters in uid
- self._test_user(["u1@a.com", "u2@ap/ple", "u3@foo.bar", "u4/a/b", "&^%$()u5"])
-
- def _test_item(self, iids):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- iid1 = iids[0]
- iid2 = iids[1]
- iid3 = iids[2]
- iid4 = iids[3]
- iid5 = iids[4]
-
- # create items and read back
- client.create_item(iid1, ("t1","t2","t3"))
- client.create_item(iid2, ("t1",))
- client.create_item(iid3, ("t2",), {"pio_price": 4.99, "pio_profit": 2.0, "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876], "pio_inactive": True })
- client.create_item(iid4, ("t2",), {"pio_latlng": [1.2345, 10.11], "custom1": "value1"})
- client.create_item(iid5, ("t1", "t2"), {"custom1": "i5value1", "custom2": "i5value2"} )
-
- item1 = client.get_item(iid1)
- item2 = client.get_item(iid2)
- item3 = client.get_item(iid3)
- item4 = client.get_item(iid4)
- item5 = client.get_item(iid5)
-
- del item1["pio_startT"] # pio_startT is automatically inserted, don't compare
- self.assertEqual(item1, {"pio_iid": iid1, "pio_itypes": ("t1", "t2", "t3") } )
- del item2["pio_startT"]
- self.assertEqual(item2, {"pio_iid": iid2, "pio_itypes": ("t1",)} )
- self.assertEqual(item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 4.99, "pio_profit": 2.0, "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876], "pio_inactive": True } )
- del item4["pio_startT"]
- self.assertEqual(item4, {"pio_iid": iid4, "pio_itypes": ("t2",), "pio_latlng": [1.2345, 10.11], "custom1": "value1"})
- del item5["pio_startT"]
- self.assertEqual(item5, {"pio_iid": iid5, "pio_itypes": ("t1","t2"), "custom1": "i5value1", "custom2": "i5value2"})
-
- # delete and then try to get it
- client.delete_item(iid2)
-
- try:
- item2 = client.get_item(iid2)
- except predictionio.ItemNotFoundError as e:
- pass # expected exception
- except:
- raise
-
- # others still exist
- item3 = client.get_item(iid3)
- self.assertEqual(item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 4.99, "pio_profit": 2.0, "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876], "pio_inactive": True } )
-
- # read, modify, write
- del item3["pio_iid"]
- item3_itypes = item3.pop("pio_itypes")
- item3["pio_price"] = 6.99
- item3["custom1"] = "some value"
- client.create_item(iid3, item3_itypes, item3)
- updated_item3 = client.get_item(iid3)
- self.assertEqual(updated_item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 6.99, "pio_profit": 2.0, "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876], "pio_inactive": True, "custom1": "some value" } )
-
- client.close()
-
- def test_item(self):
- self._test_item(["i1", "i2", "i3", "i4", "i5"])
- # test special characters in iid
- self._test_item(["i1@abc.com", "i2/f/bar//@@foo", "$$i3%%$~~", "http://www.i4.com", "``i5/apple/"])
-
- def test_u2iAction_deprecated(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.user_like_item("u1", "i1")
- client.user_dislike_item("u2", "i2")
- client.user_view_item("u3", "i3")
- client.user_rate_item("u4", "i4", 4)
- client.user_conversion_item("u5", "i5")
-
- client.close()
-
- def test_u2iAction(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.identify("u101")
-
- # required param
- client.record_action_on_item("like", "i1")
- client.record_action_on_item("dislike", "i2")
- client.record_action_on_item("view", "i3")
- client.record_action_on_item("rate", "i4", { "pio_rate": 1 })
- client.record_action_on_item("conversion", "i5")
-
- client.identify("u102")
-
- # with optional param
- client.record_action_on_item("like", "i1", { "pio_latlng": [1.23, 4.56] })
- client.record_action_on_item("dislike", "i2", { "pio_t": 1234567689 })
- client.record_action_on_item("view", "i3", { "pio_latlng": [4.67, 1.44], "pio_t": 3445566778})
- client.record_action_on_item("rate", "i4", { "pio_rate": 1, "pio_latlng": [66.78, 9.10] })
- client.record_action_on_item("conversion", "i5", { "pio_price" : 12.5 })
-
-
- # uid and iid with special characters
- client.identify("u1@a.com")
- client.record_action_on_item("view", "i3@bb.com")
- client.record_action_on_item("view", "http://www.yahoo.com")
-
- client.close()
-
-
- def test_pending_requests(self):
- client = predictionio.Client(APP_KEY, 1, API_URL)
-
- client.identify("u111")
- for i in range(100):
- client.arecord_action_on_item("like", str(i))
-
- n = 1
- while n > 0:
- n = client.pending_requests()
- time.sleep(0.1)
- #print n
-
- client.close()
-
- def test_qsize(self):
- client = predictionio.Client(APP_KEY, 1, API_URL, qsize=10)
-
- client.identify("u222")
- for i in range(100):
- client.arecord_action_on_item("like", str(i))
-
- n = 1
- while n > 0:
- n = client.pending_requests()
- time.sleep(0.1)
- #print n
-
- client.close()
-
-
-
-"""
-to run individual test:
-$ python -m unittest predictionio_test.TestPredictionIO.test_user
-
-to run ALL tests:
-% python predictionio_test.py
-"""
-if __name__ == "__main__" :
- unittest.main()
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..23d96e4
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,9 @@
+[tox]
+envlist = py27,py34
+
+[testenv]
+deps = flake8
+ pandas
+
+commands = flake8 --ignore=E501 --filename=*.py --exclude=doc,setup.py,*/tests/*
+ python -m unittest discover --pattern=*.py tests