You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@predictionio.apache.org by sh...@apache.org on 2017/10/25 13:51:08 UTC
[01/24] incubator-predictionio-sdk-python git commit: Fixed
indentation Deleted obsolete examples Moved obsolete test suite to
'test-obsolete' (port as we go) Added tox test bootstrapping Ignored pycharm,
test output Removed obsolete (<0.8) support PEP8/
Repository: incubator-predictionio-sdk-python
Updated Branches:
refs/heads/master 41d0c11c0 -> 903b2f6e7
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/predictionio_test.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/.keep
----------------------------------------------------------------------
diff --git a/tests/.keep b/tests/.keep
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/conversion_test.py
----------------------------------------------------------------------
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
-
-
-
-
-
-
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/import_testdata.py
----------------------------------------------------------------------
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()
-
-
-
-
-
-
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/import_testdata_id_mismatch.py
----------------------------------------------------------------------
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()
-
-
-
-
-
-
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/import_testdata_special_char.py
----------------------------------------------------------------------
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()
-
-
-
-
-
-
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/predictionio_itemrec_test.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/predictionio_itemrec_test_special_char.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/predictionio_itemsim_test.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests/predictionio_test.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tox.ini
----------------------------------------------------------------------
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
[13/24] incubator-predictionio-sdk-python git commit: remove
reference to obsolete
Posted by sh...@apache.org.
remove reference to obsolete
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/73adea9d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/73adea9d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/73adea9d
Branch: refs/heads/master
Commit: 73adea9d6f5093538f4f738f7d01941309500496
Parents: e63bf7f
Author: EmergentOrder <le...@gmail.com>
Authored: Tue Nov 3 14:11:32 2015 -0400
Committer: EmergentOrder <le...@gmail.com>
Committed: Tue Nov 3 14:11:32 2015 -0400
----------------------------------------------------------------------
predictionio/__init__.py | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/73adea9d/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index e5e5387..699b2db 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -6,9 +6,6 @@ Python applications with PredictionIO REST API services.
__version__ = "0.9.6"
-# import deprecated libraries.
-from predictionio.obsolete import Client, InvalidArgumentError
-
# import packages
import re
try:
[11/24] incubator-predictionio-sdk-python git commit: Merge branch
'fcvarela-develop' into develop
Posted by sh...@apache.org.
Merge branch 'fcvarela-develop' into develop
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/77ef0dd3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/77ef0dd3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/77ef0dd3
Branch: refs/heads/master
Commit: 77ef0dd39669157a18ca1ff260e735107eeb8e82
Parents: b85d044 7b6e210
Author: EmergentOrder <le...@gmail.com>
Authored: Tue Nov 3 13:04:46 2015 -0400
Committer: EmergentOrder <le...@gmail.com>
Committed: Tue Nov 3 13:04:46 2015 -0400
----------------------------------------------------------------------
.gitignore | 4 +
docs/source/conf.py | 110 +-
examples/demo-movielens/appdata.py | 316 ++---
examples/demo-movielens/batch_import.py | 246 ++--
examples/event_sample.py | 48 +-
examples/import_yahoo.py | 261 ++--
examples/itemrank_quick_query.py | 18 +-
examples/itemrank_quick_start.py | 69 +-
examples/obsolete/__init__.py | 0
examples/obsolete/itemrec/__init__.py | 0
examples/obsolete/itemrec/movies/.gitignore | 3 -
examples/obsolete/itemrec/movies/README.md | 15 -
examples/obsolete/itemrec/movies/__init__.py | 0
examples/obsolete/itemrec/movies/app_config.py | 2 -
examples/obsolete/itemrec/movies/appdata.py | 148 ---
.../obsolete/itemrec/movies/batch_import.py | 65 -
.../obsolete/itemrec/movies/movie_rec_app.py | 152 ---
predictionio/__init__.py | 40 +-
predictionio/connection.py | 537 ++++----
predictionio/obsolete.py | 1205 ------------------
setup.py | 32 +-
tests-obsolete/conversion_test.py | 16 +
tests-obsolete/import_testdata.py | 46 +
tests-obsolete/import_testdata_id_mismatch.py | 46 +
tests-obsolete/import_testdata_special_char.py | 46 +
tests-obsolete/predictionio_itemrec_test.py | 336 +++++
.../predictionio_itemrec_test_special_char.py | 366 ++++++
tests-obsolete/predictionio_itemsim_test.py | 200 +++
tests-obsolete/predictionio_test.py | 257 ++++
tests/.keep | 0
tests/conversion_test.py | 23 -
tests/import_testdata.py | 52 -
tests/import_testdata_id_mismatch.py | 52 -
tests/import_testdata_special_char.py | 52 -
tests/predictionio_itemrec_test.py | 300 -----
tests/predictionio_itemrec_test_special_char.py | 291 -----
tests/predictionio_itemsim_test.py | 160 ---
tests/predictionio_test.py | 246 ----
tox.ini | 9 +
39 files changed, 2171 insertions(+), 3598 deletions(-)
----------------------------------------------------------------------
[15/24] incubator-predictionio-sdk-python git commit: Add travis test
and Refactoring
Posted by sh...@apache.org.
Add travis test and Refactoring
Closes #22
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/8e35e33d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/8e35e33d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/8e35e33d
Branch: refs/heads/master
Commit: 8e35e33da89323b8f49d026d7035dac172997cf1
Parents: cd72584
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Sun Sep 10 10:35:50 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Sun Sep 10 10:35:50 2017 +0900
----------------------------------------------------------------------
.travis.yml | 34 ++
README.txt | 122 +++----
predictionio/__init__.py | 14 +-
tests-obsolete/conversion_test.py | 16 -
tests-obsolete/import_testdata.py | 46 ---
tests-obsolete/import_testdata_id_mismatch.py | 46 ---
tests-obsolete/import_testdata_special_char.py | 46 ---
tests-obsolete/predictionio_itemrec_test.py | 336 -----------------
.../predictionio_itemrec_test_special_char.py | 366 -------------------
tests-obsolete/predictionio_itemsim_test.py | 200 ----------
tests-obsolete/predictionio_test.py | 257 -------------
tests/.keep | 0
tests/after_script.travis.sh | 5 +
tests/before_script.travis.sh | 27 ++
tests/engineclient_test.py | 48 +++
tests/eventclient_test.py | 251 +++++++++++++
tests/fileexport_test.py | 74 ++++
tox.ini | 7 +-
18 files changed, 511 insertions(+), 1384 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..50d98a9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,34 @@
+sudo: required
+
+language: python
+
+jdk:
+ - oraclejdk8
+
+python:
+ - 2.7
+ - 3.4
+ - 3.5
+ - 3.6
+
+cache:
+ directories:
+ - $HOME/.ivy2/cache
+ - $HOME/.sbt/boot
+ - $HOME/.sbt/launchers
+
+install:
+ - pip install tox tox-travis
+ - pip install coverage coveralls
+
+before_script:
+ - java -version
+ - ./tests/before_script.travis.sh
+ - export PATH=$PATH:$PWD/predictionio-setup/predictionio/bin
+
+script:
+ - pio status
+ - tox -r
+
+after_script:
+ - ./tests/after_script.travis.sh
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/README.txt
----------------------------------------------------------------------
diff --git a/README.txt b/README.txt
index 2a542a0..4740ff5 100644
--- a/README.txt
+++ b/README.txt
@@ -1,63 +1,59 @@
-PredictionIO Python SDK
-=======================
-
-
-Installation
-============
-
-To install the module from PyPI, you may
-
- $ pip install predictionio
-
-or
-
- $ easy_install predictionio
-
-If you have cloned the repository and want to install directly from there,
-do the following in the root directory of the repository:
-
- $ python setup.py install
-
-This will install the "predictionio" module to your Python distribution.
-
-
-Usage
-=====
-
-To use predictionio in your Python script,
-
- >>> import predictionio
-
-
-Documentation
-=============
-
-The latest documentation is located at http://pythonhosted.org/PredictionIO/
-
-If you want to build a local copy, please install Sphinx
-(http://sphinx-doc.org/install.html).
-
-To generate documentation,
-
- % cd docs
- % make html
-
-To view the generated documentation, go to docs/build/html/index.html.
-
-
-SUPPORT
-=======
-
-
-Forum
------
-
-https://groups.google.com/group/predictionio-user
-
-
-Issue Tracker
--------------
-
-https://predictionio.atlassian.net
-
-If you are unsure whether a behavior is an issue, bringing it up in the forum is highly encouraged.
+PredictionIO Python SDK
+=======================
+
+
+Installation
+============
+
+To install the module from PyPI, you may
+
+ $ pip install predictionio
+
+or
+
+ $ easy_install predictionio
+
+If you have cloned the repository and want to install directly from there,
+do the following in the root directory of the repository:
+
+ $ python setup.py install
+
+This will install the "predictionio" module to your Python distribution.
+
+
+Usage
+=====
+
+To use predictionio in your Python script,
+
+ >>> import predictionio
+
+
+Documentation
+=============
+
+The latest documentation is located at http://pythonhosted.org/PredictionIO/
+
+If you want to build a local copy, please install Sphinx
+(http://sphinx-doc.org/install.html).
+
+To generate documentation,
+
+ % cd docs
+ % make html
+
+To view the generated documentation, go to docs/build/html/index.html.
+
+
+SUPPORT
+=======
+
+http://predictionio.incubator.apache.org/support/
+
+
+Issue Tracker
+-------------
+
+https://issues.apache.org/jira/projects/PIO
+
+If you are unsure whether a behavior is an issue, bringing it up in the forum is highly encouraged.
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index b429b4e..01ac045 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -21,6 +21,12 @@ except ImportError:
# pylint: disable=F0401,E0611
from urllib.parse import urlencode
+try:
+ from urllib import quote
+except ImportError:
+ # pylint: disable=F0401,E0611
+ from urllib.parse import quote
+
import json
import urllib
@@ -260,7 +266,7 @@ class EventClient(BaseClient):
if self.channel is not None:
qparam["channel"] = self.channel
- enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+ enc_event_id = quote(event_id, "") # replace special char with %xx
path = "/events/%s.json" % (enc_event_id, )
request = AsyncRequest("GET", path, **qparam)
request.set_rfunc(self._aget_resp)
@@ -335,7 +341,7 @@ class EventClient(BaseClient):
if self.channel is not None:
qparam["channel"] = self.channel
- enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+ enc_event_id = quote(event_id, "") # replace special char with %xx
path = "/events/%s.json" % (enc_event_id, )
request = AsyncRequest("DELETE", path, **qparam)
request.set_rfunc(self._adelete_resp)
@@ -519,7 +525,7 @@ class FileExporter(object):
def create_event(self, event, entity_type, entity_id,
target_entity_type=None, target_entity_id=None, properties=None,
- event_time=None):
+ event_time=None, ensure_ascii=True):
"""Create an event and write to the file.
(please refer to EventClient's create_event())
"""
@@ -544,7 +550,7 @@ class FileExporter(object):
et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
data["eventTime"] = et_str
- j = json.dumps(data)
+ j = json.dumps(data, ensure_ascii=ensure_ascii)
self._file.write(j+"\n")
def close(self):
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/conversion_test.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/conversion_test.py b/tests-obsolete/conversion_test.py
deleted file mode 100644
index b9dca97..0000000
--- a/tests-obsolete/conversion_test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-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)
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/import_testdata.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/import_testdata.py b/tests-obsolete/import_testdata.py
deleted file mode 100644
index e5338c0..0000000
--- a/tests-obsolete/import_testdata.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/import_testdata_id_mismatch.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/import_testdata_id_mismatch.py b/tests-obsolete/import_testdata_id_mismatch.py
deleted file mode 100644
index 104f75c..0000000
--- a/tests-obsolete/import_testdata_id_mismatch.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/import_testdata_special_char.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/import_testdata_special_char.py b/tests-obsolete/import_testdata_special_char.py
deleted file mode 100644
index c047b6a..0000000
--- a/tests-obsolete/import_testdata_special_char.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/predictionio_itemrec_test.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/predictionio_itemrec_test.py b/tests-obsolete/predictionio_itemrec_test.py
deleted file mode 100644
index 3105f0f..0000000
--- a/tests-obsolete/predictionio_itemrec_test.py
+++ /dev/null
@@ -1,336 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/predictionio_itemrec_test_special_char.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/predictionio_itemrec_test_special_char.py b/tests-obsolete/predictionio_itemrec_test_special_char.py
deleted file mode 100644
index a622800..0000000
--- a/tests-obsolete/predictionio_itemrec_test_special_char.py
+++ /dev/null
@@ -1,366 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/predictionio_itemsim_test.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/predictionio_itemsim_test.py b/tests-obsolete/predictionio_itemsim_test.py
deleted file mode 100644
index 45fa151..0000000
--- a/tests-obsolete/predictionio_itemsim_test.py
+++ /dev/null
@@ -1,200 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests-obsolete/predictionio_test.py
----------------------------------------------------------------------
diff --git a/tests-obsolete/predictionio_test.py b/tests-obsolete/predictionio_test.py
deleted file mode 100644
index 696718c..0000000
--- a/tests-obsolete/predictionio_test.py
+++ /dev/null
@@ -1,257 +0,0 @@
-"""
-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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests/.keep
----------------------------------------------------------------------
diff --git a/tests/.keep b/tests/.keep
deleted file mode 100644
index e69de29..0000000
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests/after_script.travis.sh
----------------------------------------------------------------------
diff --git a/tests/after_script.travis.sh b/tests/after_script.travis.sh
new file mode 100755
index 0000000..e2ea03f
--- /dev/null
+++ b/tests/after_script.travis.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+cd predictionio-setup
+./bin/pio-setup stop
+
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests/before_script.travis.sh
----------------------------------------------------------------------
diff --git a/tests/before_script.travis.sh b/tests/before_script.travis.sh
new file mode 100755
index 0000000..a38a6ee
--- /dev/null
+++ b/tests/before_script.travis.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+mkdir -p predictionio-setup/bin
+cd predictionio-setup
+curl -o bin/pio-setup https://raw.githubusercontent.com/jpioug/predictionio-setup/master/bin/pio-setup
+chmod +x bin/pio-setup
+
+PIO_GIT_USER=apache PIO_GIT_BRANCH=develop PIO_EVENTDATA_REFRESH=true ./bin/pio-setup deploy
+touch target/pio-setup.log
+tail -f target/pio-setup.log &
+
+counter=1
+ret=7
+while [ $ret = 7 -a $counter != 10 ] ; do
+ ./bin/pio-setup start
+ sleep 5
+ curl -v 127.0.0.1:7070/events.json
+ ret=$?
+ echo "Checking Java processes..."
+ ps aux | grep java
+ echo "Checking 7070 port..."
+ netstat | grep 7070
+ counter=`expr $counter + 1`
+done
+
+./bin/pio-setup status
+tail -f ~/pio.log &
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests/engineclient_test.py
----------------------------------------------------------------------
diff --git a/tests/engineclient_test.py b/tests/engineclient_test.py
new file mode 100644
index 0000000..276328b
--- /dev/null
+++ b/tests/engineclient_test.py
@@ -0,0 +1,48 @@
+import random
+import subprocess
+import unittest
+
+from predictionio import EventClient
+
+app_name ='EngineClientApp'
+access_key = 'FILE_EXPORT_TEST'
+
+class EngineClientTest(unittest.TestCase):
+
+ def setUp(self):
+ subprocess.call(['pio', 'app', 'new', '--access-key', access_key, app_name])
+
+ def tearDown(self):
+ subprocess.call(['pio', 'app', 'delete', '-f', app_name])
+
+ def test_query(self):
+ random.seed()
+
+ client = EventClient(access_key=access_key, url="http://127.0.0.1:7070")
+
+ # Check status
+ print("Check status")
+ print(client.get_status())
+ self.assertEqual(client.get_status(), {'status': 'alive'})
+
+ user_ids = [str(i) for i in range(1, 3)]
+ for user_id in user_ids:
+ print("Set user", user_id)
+ client.set_user(user_id)
+ # TODO assert
+
+ item_ids = [str(i) for i in range(1, 5)]
+ for item_id in item_ids:
+ print("Set item", item_id)
+ client.set_item(item_id, {"itypes": ['1']})
+ # TODO assert
+
+ # each user randomly views 10 items
+ for user_id in user_ids:
+ for viewed_item in random.sample(item_ids, 2):
+ print("User", user_id, "views item", viewed_item)
+ client.record_user_action_on_item("view", user_id, viewed_item)
+ # TODO assert
+
+ client.close()
+
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests/eventclient_test.py
----------------------------------------------------------------------
diff --git a/tests/eventclient_test.py b/tests/eventclient_test.py
new file mode 100644
index 0000000..900c48b
--- /dev/null
+++ b/tests/eventclient_test.py
@@ -0,0 +1,251 @@
+import pytz
+import subprocess
+import unittest
+
+from datetime import datetime
+from predictionio import EventClient
+from predictionio import NotFoundError
+
+app_name ='EventClientApp'
+access_key = 'EVENT_CLIENT_TEST'
+channel = 'Test'
+
+class EventClientTest(unittest.TestCase):
+
+ def setUp(self):
+ subprocess.call(['pio', 'app', 'new', '--access-key', access_key, app_name])
+ subprocess.call(['pio', 'app', 'show', app_name])
+
+ def tearDown(self):
+ subprocess.call(['pio', 'app', 'delete', '-f', app_name])
+
+ def test_eventclient(self):
+ client = EventClient(access_key=access_key, url="http://127.0.0.1:7070")
+
+ # Check status
+ print("Check status")
+ print(client.get_status())
+ self.assertEqual(client.get_status(), {'status': 'alive'})
+
+ # First event
+ first_event_properties = {
+ "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(
+ event="my_event",
+ entity_type="user",
+ entity_id="uid",
+ properties=first_event_properties,
+ event_time=first_event_time,
+ )
+ print("First Event response")
+ print(first_event_response)
+ self.assertEqual(first_event_response.status, 201)
+
+ # Second event
+ second_event_properties = {
+ "someProperty": "value1",
+ "anotherProperty": "value2",
+ }
+ second_event_response = client.create_event(
+ event="my_event",
+ entity_type="user",
+ entity_id="uid",
+ target_entity_type="item",
+ target_entity_id="iid",
+ properties=second_event_properties,
+ event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
+ print("Second Event response")
+ print(second_event_response)
+ self.assertEqual(second_event_response.status, 201)
+
+
+ # Get the first event from Event Server
+ first_event_id = first_event_response.json_body["eventId"]
+ print("Get Event")
+ event = client.get_event(first_event_id)
+ print(event)
+ self.assertEqual(event.get('eventId'), first_event_id)
+
+
+ # Delete the first event from Event Server
+ print("Delete Event")
+ delete_response = client.delete_event(first_event_id)
+ print(delete_response)
+ self.assertEqual(delete_response.decode('utf-8'), '{"message":"Found"}')
+
+
+ # Delete the first event from Event Server again should yield exception.
+ print("Delete Event Again")
+ try:
+ delete_response = client.delete_event(first_event_id)
+ self.fail()
+ except NotFoundError as ex:
+ print("The expected error: {0}".format(ex))
+
+
+ # "user"-helper methods
+
+ # Set user properties implicitly create a user
+ # This call creates a user "foo", and set the properties of "foo".
+ print("Create user foo")
+ foo_properties = {"city": "sunnyvale", "car": "honda fit"}
+ response = client.set_user("foo", properties=foo_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # This call overrides the existing properties for user "foo", setting "car" to
+ # a new "honda odyssey" and create a new property "food" to "seafood".
+ print("Set new properties")
+ foo_properties = {"car": "honda odyssey", "food": "seafood"}
+ response = client.set_user("foo", properties=foo_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # This call removes the specified properties. It ignores the value of the dict.
+ # After this call, the "city" will become an unset field.
+ print("Unset properties")
+ foo_properties = {"city": "x"}
+ response = client.unset_user("foo", properties=foo_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # This call deletes a user
+ print("Delete user")
+ response = client.delete_user("foo")
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # The SDK also support specifying the eventTime. It is useful for importing
+ # events happened in the past.
+ foo_time = datetime(2014, 8, 31, 4, 56, tzinfo=pytz.timezone('US/Pacific'))
+ print("Create user at " + str(foo_time))
+ response = client.set_user("Jarvis", {}, foo_time)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # "item"-helper methods
+
+ # Set item properties implicitly create a item
+ # This call creates a item "bar", and set the properties of "bar".
+ print("Create item bar")
+ bar_properties = {"city": "santa clara", "weight": 6.9}
+ response = client.set_item("bar", properties=bar_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # Similar to user-methods, we can do the same thing with item
+ print("Set new properties")
+ bar_properties = {"weight": 6.2}
+ response = client.set_item("bar", properties=bar_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # This call removes the specified properties. It ignores the value of the dict.
+ # After this call, the "city" will become an unset field.
+ print("Unset properties")
+ bar_properties = {"city": None}
+ response = client.unset_item("bar", properties=bar_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+ # This call deletes a item
+ print("Delete item")
+ response = client.delete_item("bar")
+ print(response)
+ self.assertEqual(response.status, 201)
+
+
+ # "record" action helper functions
+
+ # This call creates a event between a user and an item. In particular, this set
+ # the price of the action
+ print("Record user action")
+ action_properties = {"price": 10.0}
+ response = client.record_user_action_on_item("buy", "foo", "bar", action_properties)
+ print(response)
+ self.assertEqual(response.status, 201)
+
+
+ def test_eventclient_channel(self):
+ subprocess.call(['pio', 'app', 'channel-new', app_name, channel])
+
+ client = EventClient(access_key=access_key, url="http://127.0.0.1:7070",
+ channel=channel)
+
+ # Check status
+ print("Check status")
+ print(client.get_status())
+ self.assertEqual(client.get_status(), {'status': 'alive'})
+
+ # First event
+ first_event_properties = {
+ "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(
+ event="my_event",
+ entity_type="user",
+ entity_id="uid",
+ properties=first_event_properties,
+ event_time=first_event_time,
+ )
+ print("First Event response")
+ print(first_event_response)
+ self.assertEqual(first_event_response.status, 201)
+
+ # Second event
+ second_event_properties = {
+ "someProperty" : "value1",
+ "anotherProperty" : "value2",
+ }
+ second_event_response = client.create_event(
+ event="my_event",
+ entity_type="user",
+ entity_id="uid",
+ target_entity_type="item",
+ target_entity_id="iid",
+ properties=second_event_properties,
+ event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
+ print("Second Event response")
+ print(second_event_response)
+ self.assertEqual(second_event_response.status, 201)
+
+
+ # Get the first event from Event Server
+ first_event_id = first_event_response.json_body["eventId"]
+ print("Get Event")
+ event = client.get_event(first_event_id)
+ print(event)
+ self.assertEqual(event.get('eventId'), first_event_id)
+
+ # Delete the first event from Event Server
+ print("Delete Event")
+ delete_response = client.delete_event(first_event_id)
+ print(delete_response)
+ self.assertEqual(delete_response.decode('utf-8'), '{"message":"Found"}')
+
+ # Delete the first event from Event Server again should yield exception.
+ print("Delete Event Again")
+ try:
+ delete_response = client.delete_event(first_event_id)
+ self.fail()
+ except NotFoundError as ex:
+ print("The expected error: {0}".format(ex))
+
+
+if __name__ == "__main__":
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tests/fileexport_test.py
----------------------------------------------------------------------
diff --git a/tests/fileexport_test.py b/tests/fileexport_test.py
new file mode 100644
index 0000000..0fad97e
--- /dev/null
+++ b/tests/fileexport_test.py
@@ -0,0 +1,74 @@
+import pytz
+import re
+import subprocess
+import unittest
+
+from datetime import datetime
+import predictionio
+from predictionio import EventClient
+
+app_name ='FileExporterApp'
+access_key = 'FILE_EXPORT_TEST'
+filename = 'export_events.json'
+
+class FileExporterTest(unittest.TestCase):
+
+ def setUp(self):
+ subprocess.call(['pio', 'app', 'new', '--access-key', access_key, app_name])
+
+ def tearDown(self):
+ subprocess.call(['pio', 'app', 'delete', '-f', app_name])
+
+ def test_export(self):
+ app_info = subprocess.check_output(['pio', 'app', 'show', app_name])
+ app_id = re.search('App ID: ([0-9]+)', app_info.decode('utf-8')).group(1)
+ print(app_id)
+
+ exporter = predictionio.FileExporter(file_name=filename)
+
+ first_event_properties = {
+ "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'))
+ exporter.create_event(
+ event="my_event",
+ entity_type="user",
+ entity_id="uid",
+ properties=first_event_properties,
+ event_time=first_event_time,
+ )
+
+ # Second event
+ second_event_properties = {
+ "someProperty" : "value1",
+ "anotherProperty" : "value2",
+ }
+ exporter.create_event(
+ event="my_event",
+ entity_type="user",
+ entity_id="uid",
+ target_entity_type="item",
+ target_entity_id="iid",
+ properties=second_event_properties,
+ event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
+
+ exporter.close()
+
+ subprocess.call(['pio', 'import', '--appid', app_id, '--input ', filename])
+
+ # TODO
+ # client = EventClient(access_key=access_key, url="http://127.0.0.1:7070")
+ #
+ # print("Get Event")
+ # event = client.get_event(event_id)
+ # print(event)
+ # self.assertEqual(event.get('eventId'), event_id)
+
+if __name__ == "__main__":
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8e35e33d/tox.ini
----------------------------------------------------------------------
diff --git a/tox.ini b/tox.ini
index 87b57e9..6f5cd20 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,13 +1,12 @@
[tox]
-envlist = py27,py34
+envlist = py27,py34,py35,py36
[testenv]
deps = flake8
- pandas
+passenv = HOME TRAVIS*
+commands = python -m unittest discover --pattern=*.py tests
[flake8]
ignore = E111
-
commands = flake8 --ignore=E501 --filename=*.py --exclude=doc,setup.py,*/tests/*
- python -m unittest discover --pattern=*.py tests
[21/24] incubator-predictionio-sdk-python git commit: Update project
info
Posted by sh...@apache.org.
Update project info
Closes #23
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/a71d14eb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/a71d14eb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/a71d14eb
Branch: refs/heads/master
Commit: a71d14eb656da38599c71553e31645ec6c9d5f7b
Parents: 579ab32
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Mon Sep 18 09:42:22 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Mon Sep 18 09:42:22 2017 +0900
----------------------------------------------------------------------
LICENSE.txt | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
setup.py | 10 +--
2 files changed, 204 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/a71d14eb/LICENSE.txt
----------------------------------------------------------------------
diff --git a/LICENSE.txt b/LICENSE.txt
index 11c8530..d645695 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,13 +1,202 @@
-Copyright 2013 TappingStone Inc.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
- http://www.apache.org/licenses/LICENSE-2.0
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/a71d14eb/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index eeafe17..f34003f 100644
--- a/setup.py
+++ b/setup.py
@@ -3,9 +3,9 @@ try:
except ImportError:
from distutils.core import setup
-__author__ = "The PredictionIO Team"
-__email__ = "help@tappingstone.com"
-__copyright__ = "Copyright 2014, TappingStone, Inc."
+__author__ = "Apache PredictionIO"
+__email__ = "user@predictionio.incubator.apache.org"
+__copyright__ = "Copyright 2017 The Apache Software Foundation"
__license__ = "Apache License, Version 2.0"
setup(
@@ -14,7 +14,7 @@ setup(
author=__author__,
author_email=__email__,
packages=['predictionio'],
- url='http://prediction.io',
+ url='http://predictionio.incubator.apache.org/',
license='LICENSE.txt',
description='PredictionIO Python SDK',
classifiers=[
@@ -44,7 +44,7 @@ setup(
- without worrying about scalability
Detailed documentation is available on our
- `documentation site <http://docs.prediction.io>`_.
+ `documentation site <http://predictionio.incubator.apache.org/>`_.
This module provides convenient access of the
PredictionIO API to Python programmers so that they
[17/24] incubator-predictionio-sdk-python git commit: add test case
and remove unused imports
Posted by sh...@apache.org.
add test case and remove unused imports
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/88a11a84
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/88a11a84
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/88a11a84
Branch: refs/heads/master
Commit: 88a11a84eac281c06b9a29fa90323ff4c706401e
Parents: a151e0c
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Sun Sep 10 23:16:45 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Sun Sep 10 23:16:45 2017 +0900
----------------------------------------------------------------------
predictionio/__init__.py | 2 --
tests/eventclient_test.py | 8 ++++++++
2 files changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/88a11a84/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index d70c85c..c067689 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -28,14 +28,12 @@ except ImportError:
from urllib.parse import quote
import json
-import urllib
from datetime import datetime
import pytz
from predictionio.connection import Connection
from predictionio.connection import AsyncRequest
-from predictionio.connection import AsyncResponse
from predictionio.connection import PredictionIOAPIError
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/88a11a84/tests/eventclient_test.py
----------------------------------------------------------------------
diff --git a/tests/eventclient_test.py b/tests/eventclient_test.py
index 900c48b..ac8a72d 100644
--- a/tests/eventclient_test.py
+++ b/tests/eventclient_test.py
@@ -5,6 +5,7 @@ import unittest
from datetime import datetime
from predictionio import EventClient
from predictionio import NotFoundError
+from predictionio import InvalidArgumentError
app_name ='EventClientApp'
access_key = 'EVENT_CLIENT_TEST'
@@ -246,6 +247,13 @@ class EventClientTest(unittest.TestCase):
except NotFoundError as ex:
print("The expected error: {0}".format(ex))
+ def test_invalidurl(self):
+ try:
+ EventClient(access_key=access_key, url="invalid")
+ self.fail()
+ except InvalidArgumentError as ex:
+ print("The expected error: {0}".format(ex))
+
if __name__ == "__main__":
unittest.main()
[24/24] incubator-predictionio-sdk-python git commit: Merge
remote-tracking branch 'apache/release/0.9.9'
Posted by sh...@apache.org.
Merge remote-tracking branch 'apache/release/0.9.9'
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/903b2f6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/903b2f6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/903b2f6e
Branch: refs/heads/master
Commit: 903b2f6e76cb3fbfc05c99e971c2bfa08e3bdc40
Parents: 41d0c11 4d8c843
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Wed Oct 25 22:49:39 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Wed Oct 25 22:49:39 2017 +0900
----------------------------------------------------------------------
.DS_Store | Bin 6148 -> 0 bytes
.gitignore | 5 +
.travis.yml | 34 +
LICENSE.txt | 209 ++-
README.txt | 122 +-
docs/source/conf.py | 110 +-
examples/demo-movielens/appdata.py | 316 ++---
examples/demo-movielens/batch_import.py | 246 ++--
examples/event_sample.py | 48 +-
examples/import_yahoo.py | 261 ++--
examples/itemrank_quick_query.py | 18 +-
examples/itemrank_quick_start.py | 69 +-
examples/obsolete/__init__.py | 0
examples/obsolete/itemrec/__init__.py | 0
examples/obsolete/itemrec/movies/.gitignore | 3 -
examples/obsolete/itemrec/movies/README.md | 15 -
examples/obsolete/itemrec/movies/__init__.py | 0
examples/obsolete/itemrec/movies/app_config.py | 2 -
examples/obsolete/itemrec/movies/appdata.py | 148 ---
.../obsolete/itemrec/movies/batch_import.py | 65 -
.../obsolete/itemrec/movies/movie_rec_app.py | 152 ---
predictionio/__init__.py | 115 +-
predictionio/connection.py | 537 ++++----
predictionio/obsolete.py | 1205 ------------------
setup.py | 42 +-
tests/after_script.travis.sh | 5 +
tests/before_script.travis.sh | 27 +
tests/conversion_test.py | 23 -
tests/engineclient_test.py | 48 +
tests/eventclient_test.py | 259 ++++
tests/fileexport_test.py | 74 ++
tests/import_testdata.py | 52 -
tests/import_testdata_id_mismatch.py | 52 -
tests/import_testdata_special_char.py | 52 -
tests/predictionio_itemrec_test.py | 300 -----
tests/predictionio_itemrec_test_special_char.py | 291 -----
tests/predictionio_itemsim_test.py | 160 ---
tests/predictionio_test.py | 246 ----
tox.ini | 12 +
39 files changed, 1638 insertions(+), 3685 deletions(-)
----------------------------------------------------------------------
[23/24] incubator-predictionio-sdk-python git commit: update to 0.9.9
in __init__.py and remove incubator
Posted by sh...@apache.org.
update to 0.9.9 in __init__.py and remove incubator
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/4d8c843e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/4d8c843e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/4d8c843e
Branch: refs/heads/master
Commit: 4d8c843e3f7d940c8df01b2295d086857391ae40
Parents: 72a5092
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Fri Oct 20 22:12:44 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Fri Oct 20 22:12:44 2017 +0900
----------------------------------------------------------------------
README.txt | 2 +-
predictionio/__init__.py | 2 +-
setup.py | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/4d8c843e/README.txt
----------------------------------------------------------------------
diff --git a/README.txt b/README.txt
index 4740ff5..9a7da1d 100644
--- a/README.txt
+++ b/README.txt
@@ -48,7 +48,7 @@ To view the generated documentation, go to docs/build/html/index.html.
SUPPORT
=======
-http://predictionio.incubator.apache.org/support/
+http://predictionio.apache.org/support/
Issue Tracker
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/4d8c843e/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 3ef8d96..a20f4cc 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -4,7 +4,7 @@ Python applications with PredictionIO REST API services.
"""
-__version__ = "0.9.8"
+__version__ = "0.9.9"
# import packages
import re
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/4d8c843e/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index fd735a0..968a9e5 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ except ImportError:
from distutils.core import setup
__author__ = "Apache PredictionIO"
-__email__ = "user@predictionio.incubator.apache.org"
+__email__ = "user@predictionio.apache.org"
__copyright__ = "Copyright 2017 The Apache Software Foundation"
__license__ = "Apache License, Version 2.0"
@@ -14,7 +14,7 @@ setup(
author=__author__,
author_email=__email__,
packages=['predictionio'],
- url='http://predictionio.incubator.apache.org/',
+ url='http://predictionio.apache.org/',
license='LICENSE.txt',
description='PredictionIO Python SDK',
classifiers=[
@@ -44,7 +44,7 @@ setup(
- without worrying about scalability
Detailed documentation is available on our
- `documentation site <http://predictionio.incubator.apache.org/>`_.
+ `documentation site <http://predictionio.apache.org/>`_.
This module provides convenient access of the
PredictionIO API to Python programmers so that they
[06/24] incubator-predictionio-sdk-python git commit: Get events from
Event Server.
Posted by sh...@apache.org.
Get events from Event Server.
: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.
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/8bdf59f7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/8bdf59f7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/8bdf59f7
Branch: refs/heads/master
Commit: 8bdf59f7c4bcddffbe2b155e5c05d6c855647bf5
Parents: c8dda1a
Author: Nguyen Viet Anh <vi...@gmail.com>
Authored: Mon Jul 27 16:26:33 2015 +0700
Committer: Nguyen Viet Anh <vi...@gmail.com>
Committed: Mon Jul 27 16:26:33 2015 +0700
----------------------------------------------------------------------
predictionio/__init__.py | 52 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/8bdf59f7/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 8f40a4f..01b7cc2 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -286,6 +286,58 @@ class EventClient(BaseClient):
"""Synchronouly get an event from Event Server."""
return self.aget_event(event_id).get_response()
+ def aget_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
+ """Asynchronouly get events from Event Server.
+
+ :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.
+ """
+ qparam = {
+ "accessKey" : self.access_key,
+ "reversed": reversed
+ }
+
+ if startTime is not None:
+ qparam["startTime"] = startTime
+
+ if untilTime is not None:
+ qparam["untilTime"] = untilTime
+
+ if entityType is not None:
+ qparam["entityType"] = entityType
+
+ if entityId is not None:
+ qparam["entityId"] = entityId
+
+ if limit is not None:
+ qparam["limit"] = limit
+
+ if self.channel is not None:
+ qparam["channel"] = self.channel
+ path = "/events.json"
+ request = AsyncRequest("GET", path, **qparam)
+ request.set_rfunc(self._aget_resp)
+ self._connection.make_request(request)
+ return request
+
+ def get_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
+ """Synchronouly get event from Event Server."""
+ return self.aget_events(
+ startTime=startTime,
+ untilTime=untilTime,
+ entityType=entityType,
+ entityId=entityId,
+ limit=limit,
+ reversed=reversed
+ ).get_response()
+
def adelete_event(self, event_id):
"""Asynchronouly delete an event from Event Server.
[02/24] incubator-predictionio-sdk-python git commit: Fixed
indentation Deleted obsolete examples Moved obsolete test suite to
'test-obsolete' (port as we go) Added tox test bootstrapping Ignored pycharm,
test output Removed obsolete (<0.8) support PEP8/
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/predictionio/obsolete.py
----------------------------------------------------------------------
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
-
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index 24bfc03..f0e1038 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 @@ __license__ = "Apache License, Version 2.0"
setup(
name='PredictionIO',
- version="0.8.3",
+ version="0.8.5",
author=__author__,
author_email=__email__,
packages=['predictionio'],
@@ -18,17 +18,17 @@ setup(
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 @@ setup(
PredictionIO API to Python programmers so that they
can focus on their application logic.
""",
- install_requires=["pytz >= 2014.2",],
- )
+ install_requires=["pytz >= 2014.2", ],
+)
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/conversion_test.py
----------------------------------------------------------------------
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)
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/import_testdata.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/import_testdata_id_mismatch.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/import_testdata_special_char.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/predictionio_itemrec_test.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/predictionio_itemrec_test_special_char.py
----------------------------------------------------------------------
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/tests-obsolete/predictionio_itemsim_test.py
----------------------------------------------------------------------
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()
[04/24] incubator-predictionio-sdk-python git commit: Fixed
indentation Deleted obsolete examples Moved obsolete test suite to
'test-obsolete' (port as we go) Added tox test bootstrapping Ignored pycharm,
test output Removed obsolete (<0.8) support PEP8/
Posted by sh...@apache.org.
Fixed indentation
Deleted obsolete examples
Moved obsolete test suite to 'test-obsolete' (port as we go)
Added tox test bootstrapping
Ignored pycharm, test output
Removed obsolete (<0.8) support
PEP8/Flake + py2&3 support
Bumped version
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/bc678328
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/bc678328
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/bc678328
Branch: refs/heads/master
Commit: bc6783282a198ea417e84c1bbc882aa41dd3ffae
Parents: 7b66a7a
Author: Filipe Varela <fc...@gmail.com>
Authored: Tue Jan 13 17:29:45 2015 +0000
Committer: Filipe Varela <fc...@gmail.com>
Committed: Thu Jan 15 12:20:40 2015 +0000
----------------------------------------------------------------------
.gitignore | 4 +
docs/source/conf.py | 108 +-
examples/demo-movielens/appdata.py | 316 ++---
examples/demo-movielens/batch_import.py | 246 ++--
examples/event_sample.py | 50 +-
examples/import_yahoo.py | 261 ++--
examples/itemrank_quick_query.py | 18 +-
examples/itemrank_quick_start.py | 69 +-
examples/obsolete/__init__.py | 0
examples/obsolete/itemrec/__init__.py | 0
examples/obsolete/itemrec/movies/.gitignore | 3 -
examples/obsolete/itemrec/movies/README.md | 15 -
examples/obsolete/itemrec/movies/__init__.py | 0
examples/obsolete/itemrec/movies/app_config.py | 2 -
examples/obsolete/itemrec/movies/appdata.py | 148 ---
.../obsolete/itemrec/movies/batch_import.py | 65 -
.../obsolete/itemrec/movies/movie_rec_app.py | 152 ---
predictionio/__init__.py | 809 ++++++------
predictionio/connection.py | 584 +++++----
predictionio/obsolete.py | 1205 ------------------
setup.py | 32 +-
tests-obsolete/conversion_test.py | 16 +
tests-obsolete/import_testdata.py | 46 +
tests-obsolete/import_testdata_id_mismatch.py | 46 +
tests-obsolete/import_testdata_special_char.py | 46 +
tests-obsolete/predictionio_itemrec_test.py | 336 +++++
.../predictionio_itemrec_test_special_char.py | 366 ++++++
tests-obsolete/predictionio_itemsim_test.py | 200 +++
tests-obsolete/predictionio_test.py | 257 ++++
tests/.keep | 0
tests/conversion_test.py | 23 -
tests/import_testdata.py | 52 -
tests/import_testdata_id_mismatch.py | 52 -
tests/import_testdata_special_char.py | 52 -
tests/predictionio_itemrec_test.py | 300 -----
tests/predictionio_itemrec_test_special_char.py | 291 -----
tests/predictionio_itemsim_test.py | 160 ---
tests/predictionio_test.py | 246 ----
tox.ini | 9 +
39 files changed, 2573 insertions(+), 4012 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/.gitignore
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/docs/source/conf.py
----------------------------------------------------------------------
diff --git a/docs/source/conf.py b/docs/source/conf.py
index cbcb864..539cf04 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 @@ sys.path.insert(0, "..")
# -- 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 @@ templates_path = ['_templates']
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'
@@ -58,37 +58,37 @@ release = '0.8.3'
# 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 @@ html_theme = 'default'
# 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 @@ htmlhelp_basename = 'PredictionIO-Python-SDKdoc'
# -- 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 @@ man_pages = [
]
# 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'
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/demo-movielens/appdata.py
----------------------------------------------------------------------
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 @@ RATE_ACTIONS_DELIMITER = "\t"
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
-
- 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):
- """
- 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"]
-
- 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,)
-
- 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 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
+ 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):
+ """
+ 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"]
+
+ 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,)
+
+ 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 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
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/demo-movielens/batch_import.py
----------------------------------------------------------------------
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.
-
- 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))
-
- [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()
-
- itypes = ("movie",) + v.genres
-
- 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
-
- 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 } )
-
- set_item_request_list.append(set_item_request)
-
- [r.get_response() for r in set_item_request_list]
- sys.stdout.write('\r[Info] %s items were imported.\n' % count)
- sys.stdout.flush()
-
- 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),
+ # 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()
+
+ 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()
+
+ 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
+
+ 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
+
+ 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})
+
+ set_item_request_list.append(set_item_request)
+
+ [r.get_response() for r in set_item_request_list]
+ sys.stdout.write('\r[Info] %s items were imported.\n' % count)
+ sys.stdout.flush()
+
+ 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>")
-
- access_key = sys.argv[1]
-
- 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()
+ if len(sys.argv) < 3:
+ sys.exit("Usage: python -m examples.demo-movielens.batch_import "
+ "<access_key> <url>")
+
+ access_key = sys.argv[1]
+
+ 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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/event_sample.py
----------------------------------------------------------------------
diff --git a/examples/event_sample.py b/examples/event_sample.py
index 0a7a339..b76bcf7 100644
--- a/examples/event_sample.py
+++ b/examples/event_sample.py
@@ -1,10 +1,12 @@
-from predictionio import EventClient
-from predictionio import NotFoundError
from datetime import datetime
+
import pytz
-import sys
-access_key = None
+from predictionio import EventClient
+from predictionio import NotFoundError
+
+
+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 @@ print(client.get_status())
# 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 @@ first_event_response = client.create_event(
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 @@ second_event_response = client.create_event(
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 @@ first_event_id = first_event_response.json_body["eventId"]
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
@@ -98,7 +100,7 @@ print(client.unset_user("foo", properties=foo_properties))
print("Delete user")
print(client.delete_user("foo"))
-# The SDK also support specifying the eventTime. It is useful for importing
+# The SDK also support specifying the eventTime. It is useful for importing
# events happened in the past.
foo_time = datetime(2014, 8, 31, 4, 56, tzinfo=pytz.timezone('US/Pacific'))
print("Create user at " + str(foo_time))
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/import_yahoo.py
----------------------------------------------------------------------
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 @@ Import historical stock data from yahoo finance.
"""
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 @@ SP500_LIST = [
"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
-
- 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
-
- # 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')]
-
- 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)
-
- 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)
+ 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 as ex:
+ print(ex)
+ print("Data not exist. Returning")
+ return
+
+ # 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')]
+
+ 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)
+
+ 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)
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.
- """
-
- # 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)),
- ]
-
- tickers = ['SPY', 'AAPL', 'IBM', 'MSFT']
-
- url = 'http://localhost:7070'
- client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
-
- 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])
+ """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.
+ """
+
+ # 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)),
+ ]
+
+ tickers = ['SPY', 'AAPL', 'IBM', 'MSFT']
+
+ url = 'http://localhost:7070'
+ client = predictionio.EventClient(access_key=access_key, threads=1, url=url)
+
+ 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_data(client, access_key, ticker, start_time, end_time, event_time)
+ """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_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)
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/itemrank_quick_query.py
----------------------------------------------------------------------
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 @@ client = predictionio.EngineClient("http://localhost:8000")
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()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/itemrank_quick_start.py
----------------------------------------------------------------------
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()
+
+ 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)
- random.seed()
-
- 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()
+ 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])
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/__init__.py
----------------------------------------------------------------------
diff --git a/examples/obsolete/__init__.py b/examples/obsolete/__init__.py
deleted file mode 100644
index e69de29..0000000
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/__init__.py
----------------------------------------------------------------------
diff --git a/examples/obsolete/itemrec/__init__.py b/examples/obsolete/itemrec/__init__.py
deleted file mode 100644
index e69de29..0000000
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/.gitignore
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/README.md
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/__init__.py
----------------------------------------------------------------------
diff --git a/examples/obsolete/itemrec/movies/__init__.py b/examples/obsolete/itemrec/movies/__init__.py
deleted file mode 100644
index e69de29..0000000
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/app_config.py
----------------------------------------------------------------------
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'
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/appdata.py
----------------------------------------------------------------------
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
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/batch_import.py
----------------------------------------------------------------------
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()
-
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/examples/obsolete/itemrec/movies/movie_rec_app.py
----------------------------------------------------------------------
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()
[18/24] incubator-predictionio-sdk-python git commit: Update
__init__.py (Updated Deprecation Error Message)
Posted by sh...@apache.org.
Update __init__.py (Updated Deprecation Error Message)
Closes #15
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/55109536
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/55109536
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/55109536
Branch: refs/heads/master
Commit: 55109536075352a555ab7f56f7ba4b8e0ea539af
Parents: 88a11a8
Author: thomas-idmt <th...@users.noreply.github.com>
Authored: Sun Sep 10 23:19:12 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Sun Sep 10 23:19:12 2017 +0900
----------------------------------------------------------------------
predictionio/__init__.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/55109536/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index c067689..3ef8d96 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -183,8 +183,8 @@ class EventClient(BaseClient):
if len(access_key) <= 8:
raise DeprecationWarning(
- "It seems like you are specifying an app_id. It is deprecated in "
- "Prediction.IO 0.8.2. Please use access_key instead. Or, "
+ "The entered access key is very short, it seems like you are specifying an app_id."
+ "This is deprecated in Prediction.IO 0.8.2. Please use (a longer) access_key instead. Or, "
"you may use an earlier version of this sdk.")
self.access_key = access_key
[08/24] incubator-predictionio-sdk-python git commit: Merge pull
request #14 from vietanh85/develop
Posted by sh...@apache.org.
Merge pull request #14 from vietanh85/develop
Get events from Event Server.
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/849c2d54
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/849c2d54
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/849c2d54
Branch: refs/heads/master
Commit: 849c2d54099b3274a7485d86ea98a652175613c3
Parents: c8dda1a 6c95d7f
Author: EmergentOrder <le...@gmail.com>
Authored: Wed Oct 28 11:29:38 2015 -0300
Committer: EmergentOrder <le...@gmail.com>
Committed: Wed Oct 28 11:29:38 2015 -0300
----------------------------------------------------------------------
predictionio/__init__.py | 52 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
----------------------------------------------------------------------
[05/24] incubator-predictionio-sdk-python git commit: added missing
import for InvalidArgumentError. Fix NameError when url provided to client is
malformed.
Posted by sh...@apache.org.
added missing import for InvalidArgumentError. Fix NameError when url provided to client is malformed.
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/a6f841f6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/a6f841f6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/a6f841f6
Branch: refs/heads/master
Commit: a6f841f6c3135189dd647845414c0b49a8c1d00e
Parents: c8dda1a
Author: Almog Cohen <al...@gmail.com>
Authored: Wed Jun 17 13:41:33 2015 +0300
Committer: Almog Cohen <al...@gmail.com>
Committed: Wed Jun 17 13:41:33 2015 +0300
----------------------------------------------------------------------
predictionio/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/a6f841f6/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 8f40a4f..02bd101 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -8,7 +8,7 @@ Python applications with PredictionIO REST API services.
__version__ = "0.9.2"
# import deprecated libraries.
-from predictionio.obsolete import Client
+from predictionio.obsolete import Client, InvalidArgumentError
# import packages
import re
[22/24] incubator-predictionio-sdk-python git commit: Prepare 0.9.9rc1
Posted by sh...@apache.org.
Prepare 0.9.9rc1
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/72a50929
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/72a50929
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/72a50929
Branch: refs/heads/master
Commit: 72a509296d355328bdfaa7a4125ff65496d0d937
Parents: a71d14e
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Thu Oct 19 17:50:19 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Thu Oct 19 17:50:19 2017 +0900
----------------------------------------------------------------------
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/72a50929/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index f34003f..fd735a0 100644
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ __license__ = "Apache License, Version 2.0"
setup(
name='PredictionIO',
- version="0.9.8",
+ version="0.9.9",
author=__author__,
author_email=__email__,
packages=['predictionio'],
[10/24] incubator-predictionio-sdk-python git commit: Merge PR #11,
prep 0.9.6 . Clobbered the PR's predictionio/__init__.py conflicting
changes, fixed the rest
Posted by sh...@apache.org.
Merge PR #11, prep 0.9.6 . Clobbered the PR's predictionio/__init__.py conflicting changes, fixed the rest
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/7b6e210d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/7b6e210d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/7b6e210d
Branch: refs/heads/master
Commit: 7b6e210d7ad8147358685f513fab98f58a79039b
Parents: b85d044 bc67832
Author: EmergentOrder <le...@gmail.com>
Authored: Tue Nov 3 13:04:18 2015 -0400
Committer: EmergentOrder <le...@gmail.com>
Committed: Tue Nov 3 13:04:18 2015 -0400
----------------------------------------------------------------------
.gitignore | 4 +
docs/source/conf.py | 110 +-
examples/demo-movielens/appdata.py | 316 ++---
examples/demo-movielens/batch_import.py | 246 ++--
examples/event_sample.py | 48 +-
examples/import_yahoo.py | 261 ++--
examples/itemrank_quick_query.py | 18 +-
examples/itemrank_quick_start.py | 69 +-
examples/obsolete/__init__.py | 0
examples/obsolete/itemrec/__init__.py | 0
examples/obsolete/itemrec/movies/.gitignore | 3 -
examples/obsolete/itemrec/movies/README.md | 15 -
examples/obsolete/itemrec/movies/__init__.py | 0
examples/obsolete/itemrec/movies/app_config.py | 2 -
examples/obsolete/itemrec/movies/appdata.py | 148 ---
.../obsolete/itemrec/movies/batch_import.py | 65 -
.../obsolete/itemrec/movies/movie_rec_app.py | 152 ---
predictionio/__init__.py | 40 +-
predictionio/connection.py | 537 ++++----
predictionio/obsolete.py | 1205 ------------------
setup.py | 32 +-
tests-obsolete/conversion_test.py | 16 +
tests-obsolete/import_testdata.py | 46 +
tests-obsolete/import_testdata_id_mismatch.py | 46 +
tests-obsolete/import_testdata_special_char.py | 46 +
tests-obsolete/predictionio_itemrec_test.py | 336 +++++
.../predictionio_itemrec_test_special_char.py | 366 ++++++
tests-obsolete/predictionio_itemsim_test.py | 200 +++
tests-obsolete/predictionio_test.py | 257 ++++
tests/.keep | 0
tests/conversion_test.py | 23 -
tests/import_testdata.py | 52 -
tests/import_testdata_id_mismatch.py | 52 -
tests/import_testdata_special_char.py | 52 -
tests/predictionio_itemrec_test.py | 300 -----
tests/predictionio_itemrec_test_special_char.py | 291 -----
tests/predictionio_itemsim_test.py | 160 ---
tests/predictionio_test.py | 246 ----
tox.ini | 9 +
39 files changed, 2171 insertions(+), 3598 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/7b6e210d/docs/source/conf.py
----------------------------------------------------------------------
diff --cc docs/source/conf.py
index 0d87655,539cf04..d52d83e
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@@ -52,9 -52,9 +52,9 @@@ copyright = u'2014, TappingStone, Inc.
# built documents.
#
# The short X.Y version.
-version = '0.8'
+version = '0.9'
# The full version, including alpha/beta/rc tags.
- release = '0.9.2'
-release = '0.8.3'
++release = '0.9.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/7b6e210d/predictionio/__init__.py
----------------------------------------------------------------------
diff --cc predictionio/__init__.py
index 290c31e,f4eb87a..e5e5387
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@@ -1,14 -1,10 +1,13 @@@
--"""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.8.5"
+
- __version__ = "0.9.2"
++__version__ = "0.9.6"
+
+# import deprecated libraries.
+from predictionio.obsolete import Client, InvalidArgumentError
# import packages
import re
@@@ -62,530 -51,405 +61,497 @@@ def event_time_validation(t)
class BaseClient(object):
- def __init__(self, url, threads=1, qsize=0, timeout=5):
- """Constructor of Client object.
-
- """
- self.threads = threads
- self.url = url
- self.qsize = qsize
- self.timeout = timeout
-
- # check connection type
- https_pattern = r'^https://(.*)'
- http_pattern = r'^http://(.*)'
- m = re.match(https_pattern, url)
- self.https = True
- if m is None: # not matching https
- m = re.match(http_pattern, url)
- self.https = False
- if m is None: # not matching http either
- raise InvalidArgumentError("url is not valid: %s" % url) # noqa
- 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 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_resp)
- self._connection.make_request(request)
- result = request.get_response()
- return result
-
- def _acreate_resp(self, response):
- if response.error is not None:
- raise NotCreatedError("Exception happened: %s for request %s" %
- (response.error, response.request))
- elif response.status != httplib.CREATED:
- raise NotCreatedError("request: %s status: %s body: %s" %
- (response.request, response.status,
- response.body))
-
- return response
-
- def _aget_resp(self, response):
- if response.error is not None:
- raise NotFoundError("Exception happened: %s for request %s" %
- (response.error, response.request))
- elif response.status != httplib.OK:
- raise NotFoundError("request: %s status: %s body: %s" %
- (response.request, response.status,
- response.body))
-
- return response.json_body
-
- def _adelete_resp(self, response):
- if response.error is not None:
- raise NotFoundError("Exception happened: %s for request %s" %
- (response.error, response.request))
- elif response.status != httplib.OK:
- raise NotFoundError("request: %s status: %s body: %s" %
- (response.request, response.status,
- response.body))
-
- return response.body
+ def __init__(self, url, threads=1, qsize=0, timeout=5):
+ """Constructor of Client object.
-
+ """
+ self.threads = threads
+ self.url = url
+ self.qsize = qsize
+ self.timeout = timeout
+
+ # check connection type
+ https_pattern = r'^https://(.*)'
+ http_pattern = r'^http://(.*)'
+ m = re.match(https_pattern, url)
+ self.https = True
+ if m is None: # not matching https
+ m = re.match(http_pattern, url)
+ self.https = False
+ if m is None: # not matching http either
+ raise InvalidArgumentError("url is not valid: %s" % url)
+ 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 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_resp)
+ self._connection.make_request(request)
+ result = request.get_response()
+ return result
+
+ def _acreate_resp(self, response):
+ if response.error is not None:
+ raise NotCreatedError("Exception happened: %s for request %s" %
+ (response.error, response.request))
+ elif response.status != httplib.CREATED:
+ raise NotCreatedError("request: %s status: %s body: %s" %
+ (response.request, response.status,
+ response.body))
+
+ return response
+
+ def _aget_resp(self, response):
+ if response.error is not None:
+ raise NotFoundError("Exception happened: %s for request %s" %
+ (response.error, response.request))
+ elif response.status != httplib.OK:
+ raise NotFoundError("request: %s status: %s body: %s" %
+ (response.request, response.status,
+ response.body))
+
+ return response.json_body
+
+ def _adelete_resp(self, response):
+ if response.error is not None:
+ raise NotFoundError("Exception happened: %s for request %s" %
+ (response.error, response.request))
+ elif response.status != httplib.OK:
+ raise NotFoundError("request: %s status: %s body: %s" %
+ (response.request, response.status,
+ response.body))
+
+ return response.body
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.
- Must be >= 1.
- :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.
+ """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.
+ Must be >= 1.
+ :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.
+ :param channel: channel name (optional)
+ """
+
+ def __init__(self, access_key,
+ url="http://localhost:7070",
+ threads=1, qsize=0, timeout=5, channel=None):
+ assert type(access_key) is str, ("access_key must be string. "
+ "Notice that app_id has been deprecated in Prediction.IO 0.8.2. "
+ "Please use access_key instead.")
+
+ super(EventClient, self).__init__(url, threads, qsize, timeout)
+
+ if len(access_key) <= 8:
+ raise DeprecationWarning(
+ "It seems like you are specifying an app_id. It is deprecated in "
+ "Prediction.IO 0.8.2. Please use access_key instead. Or, "
+ "you may use an earlier version of this sdk.")
+
+ self.access_key = access_key
+ self.channel = channel
+
+ def acreate_event(self, event, entity_type, entity_id,
+ 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
+ unique within same entityType. type str.
+ :param entity_id: entity id. *entity_type-entity_id* becomes the unique
+ identifier of the entity. For example, you may have entityType named user,
+ and different entity IDs, say 1 and 2. In this case, user-1 and user-2
+ uniquely identifies entities. type str
+ :param target_entity_type: target entity type. type str.
+ :param target_entity_id: target entity id. type str.
+ :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.
"""
+ data = {
+ "event": event,
+ "entityType": entity_type,
+ "entityId": entity_id,
+ }
+
+ if target_entity_type is not None:
+ data["targetEntityType"] = target_entity_type
+
+ if target_entity_id is not None:
+ data["targetEntityId"] = target_entity_id
+
+ if properties is not None:
+ data["properties"] = properties
- def __init__(self, access_key,
- url="http://localhost:7070",
- threads=1, qsize=0, timeout=5):
- assert type(access_key) is str, ("access_key must be string. "
- "Notice that app_id has been deprecated in Prediction.IO 0.8.2. "
- "Please use access_key instead.")
-
- super(EventClient, self).__init__(url, threads, qsize, timeout)
-
- if len(access_key) <= 8:
- raise DeprecationWarning(
- "It seems like you are specifying an app_id. It is deprecated in "
- "Prediction.IO 0.8.2. Please use access_key instead. Or, "
- "you may use an earlier version of this sdk.")
-
- self.access_key = access_key
-
- def acreate_event(self, event, entity_type, entity_id,
- 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
- unique within same entityType. type str.
- :param entity_id: entity id. *entity_type-entity_id* becomes the unique
- identifier of the entity. For example, you may have entityType named user,
- and different entity IDs, say 1 and 2. In this case, user-1 and user-2
- uniquely identifies entities. type str
- :param target_entity_type: target entity type. type str.
- :param target_entity_id: target entity id. type str.
- :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.
- """
- data = {
- "event": event,
- "entityType": entity_type,
- "entityId": entity_id,
+ et = event_time_validation(event_time)
+ # EventServer uses milliseconds, but python datetime class uses micro. Hence
+ # need to skip the last three digits.
+ et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
+ data["eventTime"] = et_str
+
+ qparam = {
+ "accessKey" : self.access_key
}
- if target_entity_type is not None:
- data["targetEntityType"] = target_entity_type
-
- if target_entity_id is not None:
- data["targetEntityId"] = target_entity_id
-
- if properties is not None:
- data["properties"] = properties
-
- et = event_time_validation(event_time)
- # EventServer uses milliseconds, but python datetime class uses micro. Hence
- # need to skip the last three digits.
- et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
- data["eventTime"] = et_str
-
- path = "/events.json?accessKey=%s" % (self.access_key, )
- request = AsyncRequest("POST", path, **data)
- request.set_rfunc(self._acreate_resp)
- self._connection.make_request(request)
- return request
-
- def create_event(self, event, entity_type, entity_id,
- target_entity_type=None, target_entity_id=None, properties=None,
- event_time=None):
- """Synchronously (blocking) create an event."""
- return self.acreate_event(event, entity_type, entity_id,
- target_entity_type, target_entity_id, properties,
- event_time).get_response()
-
- 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.
- """
- enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
- path = "/events/%s.json" % enc_event_id
- request = AsyncRequest("GET", path, accessKey=self.access_key)
- request.set_rfunc(self._aget_resp)
- self._connection.make_request(request)
- return request
-
- def get_event(self, event_id):
- """Synchronouly get an event from Event Server."""
- return self.aget_event(event_id).get_response()
-
- 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.
- """
- enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
- path = "/events/%s.json" % (enc_event_id, )
- request = AsyncRequest("DELETE", path, accessKey=self.access_key)
- request.set_rfunc(self._adelete_resp)
- self._connection.make_request(request)
- return request
-
- def delete_event(self, event_id):
- """Synchronouly delete an event from Event Server."""
- return self.adelete_event(event_id).get_response()
-
- # Below are helper functions
-
- 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".
- """
- return self.acreate_event(
- event="$set",
- entity_type="user",
- entity_id=uid,
- properties=properties,
- event_time=event_time,
- )
+ if self.channel is not None:
+ qparam["channel"] = self.channel
+
+ path = "/events.json?%s" % (urlencode(qparam), )
+
+ request = AsyncRequest("POST", path, **data)
+ request.set_rfunc(self._acreate_resp)
+ self._connection.make_request(request)
+ return request
+
+ def create_event(self, event, entity_type, entity_id,
+ target_entity_type=None, target_entity_id=None, properties=None,
+ event_time=None):
+ """Synchronously (blocking) create an event."""
+ return self.acreate_event(event, entity_type, entity_id,
+ target_entity_type, target_entity_id, properties,
+ event_time).get_response()
+
+ 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.
+ """
+ qparam = {
+ "accessKey" : self.access_key
+ }
+
+ if self.channel is not None:
+ qparam["channel"] = self.channel
+
+ enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+ path = "/events/%s.json" % (enc_event_id, )
+ request = AsyncRequest("GET", path, **qparam)
+ request.set_rfunc(self._aget_resp)
+ self._connection.make_request(request)
+ return request
+
+ def get_event(self, event_id):
+ """Synchronouly get an event from Event Server."""
+ return self.aget_event(event_id).get_response()
+
+ 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.
+ """
+ qparam = {
+ "accessKey" : self.access_key,
+ "reversed": reversed
+ }
+
+ if startTime is not None:
+ qparam["startTime"] = startTime
+
+ if untilTime is not None:
+ qparam["untilTime"] = untilTime
+
+ if entityType is not None:
+ qparam["entityType"] = entityType
+
+ if entityId is not None:
+ qparam["entityId"] = entityId
+
+ if limit is not None:
+ qparam["limit"] = limit
+
+ if self.channel is not None:
+ qparam["channel"] = self.channel
+ path = "/events.json"
+ request = AsyncRequest("GET", path, **qparam)
+ request.set_rfunc(self._aget_resp)
+ self._connection.make_request(request)
+ return request
+
+ def get_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
+ """Synchronouly get event from Event Server. (Getting events through the Event Server API is used for debugging and not recommended for production)"""
+ return self.aget_events(
+ startTime=startTime,
+ untilTime=untilTime,
+ entityType=entityType,
+ entityId=entityId,
+ limit=limit,
+ reversed=reversed
+ ).get_response()
+
+ 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.
+ """
+ qparam = {
+ "accessKey" : self.access_key
+ }
+
+ if self.channel is not None:
+ qparam["channel"] = self.channel
+
+ enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+ path = "/events/%s.json" % (enc_event_id, )
+ request = AsyncRequest("DELETE", path, **qparam)
+ request.set_rfunc(self._adelete_resp)
+ self._connection.make_request(request)
+ return request
+
+ def delete_event(self, event_id):
+ """Synchronouly delete an event from Event Server."""
+ return self.adelete_event(event_id).get_response()
- def set_user(self, uid, properties={}, event_time=None):
- """Set properties of a user"""
- return self.aset_user(uid, properties, event_time).get_response()
-
- 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".
- """
- # check properties={}, it cannot be empty
- return self.acreate_event(
- event="$unset",
- entity_type="user",
- entity_id=uid,
- properties=properties,
- event_time=event_time,
+ ## Below are helper functions
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$set",
+ entity_type="user",
+ entity_id=uid,
+ properties=properties,
+ event_time=event_time,
+ )
+
+ def set_user(self, uid, properties={}, event_time=None):
+ """Set properties of a user"""
+ return self.aset_user(uid, properties, event_time).get_response()
+
+ 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".
+ """
+ # check properties={}, it cannot be empty
+ return self.acreate_event(
+ event="$unset",
+ entity_type="user",
+ entity_id=uid,
+ properties=properties,
+ event_time=event_time,
)
- def unset_user(self, uid, properties, event_time=None):
- """Set properties of a user"""
- return self.aunset_user(uid, properties, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$delete",
- entity_type="user",
- entity_id=uid,
- event_time=event_time)
-
- def delete_user(self, uid, event_time=None):
- """Delete a user."""
- return self.adelete_user(uid, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$set",
- entity_type="item",
- entity_id=iid,
- properties=properties,
- event_time=event_time)
-
- def set_item(self, iid, properties={}, event_time=None):
- """Set properties of an item."""
- return self.aset_item(iid, properties, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$unset",
- entity_type="item",
- entity_id=iid,
- properties=properties,
- event_time=event_time)
-
- def unset_item(self, iid, properties={}, event_time=None):
- """Unset properties of an item."""
- return self.aunset_item(iid, properties, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$delete",
- entity_type="item",
- entity_id=iid,
- event_time=event_time)
-
- def delete_item(self, iid, event_time=None):
- """Delete an item."""
- return self.adelete_item(iid, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event=action,
- entity_type="user",
- entity_id=uid,
- target_entity_type="item",
- target_entity_id=iid,
- properties=properties,
- event_time=event_time)
-
- def record_user_action_on_item(self, action, uid, iid, properties={},
- event_time=None):
- """Create a user-to-item action."""
- return self.arecord_user_action_on_item(
- action, uid, iid, properties, event_time).get_response()
+ def unset_user(self, uid, properties, event_time=None):
+ """Set properties of a user"""
+ return self.aunset_user(uid, properties, event_time).get_response()
+ 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".
+ """
+ return self.acreate_event(
+ event="$delete",
+ entity_type="user",
+ entity_id=uid,
+ event_time=event_time)
+
+ def delete_user(self, uid, event_time=None):
+ """Delete a user."""
+ return self.adelete_user(uid, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$set",
+ entity_type="item",
+ entity_id=iid,
+ properties=properties,
+ event_time=event_time)
+
+ def set_item(self, iid, properties={}, event_time=None):
+ """Set properties of an item."""
+ return self.aset_item(iid, properties, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$unset",
+ entity_type="item",
+ entity_id=iid,
+ properties=properties,
+ event_time=event_time)
+
+ def unset_item(self, iid, properties={}, event_time=None):
+ """Unset properties of an item."""
+ return self.aunset_item(iid, properties, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$delete",
+ entity_type="item",
+ entity_id=iid,
+ event_time=event_time)
+
+ def delete_item(self, iid, event_time=None):
+ """Delete an item."""
+ return self.adelete_item(iid, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event=action,
+ entity_type="user",
+ entity_id=uid,
+ target_entity_type="item",
+ target_entity_id=iid,
+ properties=properties,
+ event_time=event_time)
+
+ def record_user_action_on_item(self, action, uid, iid, properties={},
+ event_time=None):
+ """Create a user-to-item action."""
+ return self.arecord_user_action_on_item(
+ action, uid, iid, properties, event_time).get_response()
-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.
- :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.
+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.
+ :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, url="http://localhost:8000", threads=1,
+ qsize=0, timeout=5):
+ super(EngineClient, self).__init__(url, threads, qsize, timeout)
+
+ 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.
"""
+ path = "/queries.json"
+ request = AsyncRequest("POST", path, **data)
+ request.set_rfunc(self._aget_resp)
+ self._connection.make_request(request)
+ return request
+
+ 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')
- def __init__(self, url="http://localhost:8000", threads=1,
- qsize=0, timeout=5):
- super(EngineClient, self).__init__(url, threads, qsize, timeout)
+ def create_event(self, event, entity_type, entity_id,
+ 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,
+ "entityType": entity_type,
+ "entityId": entity_id,
+ }
- def asend_query(self, data):
- """Asynchronously send a request to the engine instance with data as the
- query.
+ if target_entity_type is not None:
+ data["targetEntityType"] = target_entity_type
- :param data: the query: It is coverted to an json object using json.dumps
- method. type dict.
+ if target_entity_id is not None:
+ data["targetEntityId"] = target_entity_id
- :returns:
- AsyncRequest object. You can call the get_response() method using this
- object to get the final resuls or status of this asynchronous request.
- """
- path = "/queries.json"
- request = AsyncRequest("POST", path, **data)
- request.set_rfunc(self._aget_resp)
- self._connection.make_request(request)
- return request
+ if properties is not None:
+ data["properties"] = properties
- def send_query(self, data):
- """Synchronously send a request.
+ et = event_time_validation(event_time)
+ # EventServer uses milliseconds, but python datetime class uses micro. Hence
+ # need to skip the last three digits.
+ et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
+ data["eventTime"] = et_str
- :param data: the query: It is coverted to an json object using json.dumps
- method. type dict.
+ j = json.dumps(data)
+ self._file.write(j+"\n")
- :returns: the prediction.
- """
- return self.asend_query(data).get_response()
+ def close(self):
+ """Close the FileExporter
-
+ Call this method when you finish writing all events to JSON file
+ """
+ self._file.close()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/7b6e210d/predictionio/connection.py
----------------------------------------------------------------------
diff --cc predictionio/connection.py
index 04fe7b5,8c231f4..8205bb2
--- a/predictionio/connection.py
+++ b/predictionio/connection.py
@@@ -68,192 -67,190 +67,233 @@@ class ProgramError(PredictionIOAPIError
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 __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 __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_rfunc(self, func):
- self.rfunc = func
+ def set_response(self, response):
+ """ store the response
- 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
- NOTE: Must be only called once
- """
- self.response_q.put(response)
- def get_response(self):
- """Get the response. Blocking.
+ class AsyncResponse(object):
+ """Store the response of asynchronous request
- :returns: self.rfunc's return type.
+ 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
- def set_request(self, request):
- self.request = request
-
+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.
+ """
+
+ 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.decode('utf8'))
+ except ValueError as ex:
+ self.json_body = None
+
+ def set_error(self, error):
+ self.error = error
+
+ 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 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
+ 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
- """
+ 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()
+ 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:
- 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()
+ # 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):
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/7b6e210d/setup.py
----------------------------------------------------------------------
diff --cc setup.py
index 15163d1,f0e1038..67b12e3
--- a/setup.py
+++ b/setup.py
@@@ -10,7 -10,7 +10,7 @@@ __license__ = "Apache License, Version
setup(
name='PredictionIO',
- version="0.9.2",
- version="0.8.5",
++ version="0.9.6",
author=__author__,
author_email=__email__,
packages=['predictionio'],
[20/24] incubator-predictionio-sdk-python git commit: ignore .DS_Store
Posted by sh...@apache.org.
ignore .DS_Store
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/579ab327
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/579ab327
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/579ab327
Branch: refs/heads/master
Commit: 579ab327d3ef8685f7e98bd97c4320e331d4272a
Parents: 4b51a30
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Wed Sep 13 15:15:37 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Wed Sep 13 15:15:37 2017 +0900
----------------------------------------------------------------------
.DS_Store | Bin 6148 -> 0 bytes
.gitignore | 1 +
2 files changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/579ab327/.DS_Store
----------------------------------------------------------------------
diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index af48d0a..0000000
Binary files a/.DS_Store and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/579ab327/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 1822229..0c3ae58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ MANIFEST
docs/build/
tests_env/
*.zip
+.DS_Store
[03/24] incubator-predictionio-sdk-python git commit: Fixed
indentation Deleted obsolete examples Moved obsolete test suite to
'test-obsolete' (port as we go) Added tox test bootstrapping Ignored pycharm,
test output Removed obsolete (<0.8) support PEP8/
Posted by sh...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 45a379f..f4eb87a 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -4,21 +4,17 @@ The PredictoinIO Python SDK provides easy-to-use functions for integrating
Python applications with PredictionIO REST API services.
"""
-
-__version__ = "0.8.3"
-
-# import deprecated libraries.
-from predictionio.obsolete import Client
+__version__ = "0.8.5"
# import packages
import re
+
try:
- import httplib
+ import httplib
except ImportError:
- # pylint: disable=F0401
- # http is a Python3 module, replacing httplib
- from http import client as httplib
-import json
+ # pylint: disable=F0401
+ # http is a Python3 module, replacing httplib
+ from http import client as httplib
import urllib
from datetime import datetime
@@ -26,433 +22,434 @@ import pytz
from predictionio.connection import Connection
from predictionio.connection import AsyncRequest
-from predictionio.connection import AsyncResponse
+from predictionio.connection import AsyncResponse # noqa
from predictionio.connection import PredictionIOAPIError
class NotCreatedError(PredictionIOAPIError):
- pass
+ pass
class NotFoundError(PredictionIOAPIError):
- pass
+ pass
def event_time_validation(t):
- """ Validate event_time according to EventAPI Specification.
- """
+ """ Validate event_time according to EventAPI Specification.
+ """
- if t is None:
- return datetime.now(pytz.utc)
+ if t is None:
+ return datetime.now(pytz.utc)
- if type(t) != datetime:
- raise AttributeError("event_time must be datetime.datetime")
+ if type(t) != datetime:
+ raise AttributeError("event_time must be datetime.datetime")
- if t.tzinfo is None:
- raise AttributeError("event_time must have tzinfo")
+ if t.tzinfo is None:
+ raise AttributeError("event_time must have tzinfo")
- return t
+ return t
class BaseClient(object):
- def __init__(self, url, threads=1, qsize=0, timeout=5):
- """Constructor of Client object.
+ def __init__(self, url, threads=1, qsize=0, timeout=5):
+ """Constructor of Client object.
+
+ """
+ self.threads = threads
+ self.url = url
+ self.qsize = qsize
+ self.timeout = timeout
+
+ # check connection type
+ https_pattern = r'^https://(.*)'
+ http_pattern = r'^http://(.*)'
+ m = re.match(https_pattern, url)
+ self.https = True
+ if m is None: # not matching https
+ m = re.match(http_pattern, url)
+ self.https = False
+ if m is None: # not matching http either
+ raise InvalidArgumentError("url is not valid: %s" % url) # noqa
+ 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 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_resp)
+ self._connection.make_request(request)
+ result = request.get_response()
+ return result
+
+ def _acreate_resp(self, response):
+ if response.error is not None:
+ raise NotCreatedError("Exception happened: %s for request %s" %
+ (response.error, response.request))
+ elif response.status != httplib.CREATED:
+ raise NotCreatedError("request: %s status: %s body: %s" %
+ (response.request, response.status,
+ response.body))
+
+ return response
+
+ def _aget_resp(self, response):
+ if response.error is not None:
+ raise NotFoundError("Exception happened: %s for request %s" %
+ (response.error, response.request))
+ elif response.status != httplib.OK:
+ raise NotFoundError("request: %s status: %s body: %s" %
+ (response.request, response.status,
+ response.body))
+
+ return response.json_body
+
+ def _adelete_resp(self, response):
+ if response.error is not None:
+ raise NotFoundError("Exception happened: %s for request %s" %
+ (response.error, response.request))
+ elif response.status != httplib.OK:
+ raise NotFoundError("request: %s status: %s body: %s" %
+ (response.request, response.status,
+ response.body))
+
+ return response.body
- """
- self.threads = threads
- self.url = url
- self.qsize = qsize
- self.timeout = timeout
-
- # check connection type
- https_pattern = r'^https://(.*)'
- http_pattern = r'^http://(.*)'
- m = re.match(https_pattern, url)
- self.https = True
- if m is None: # not matching https
- m = re.match(http_pattern, url)
- self.https = False
- if m is None: # not matching http either
- raise InvalidArgumentError("url is not valid: %s" % url)
- 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.
+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.
+ Must be >= 1.
+ :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.
"""
- return self._connection.pending_requests()
- def get_status(self):
- """Get the status of the PredictionIO API Server
+ def __init__(self, access_key,
+ url="http://localhost:7070",
+ threads=1, qsize=0, timeout=5):
+ assert type(access_key) is str, ("access_key must be string. "
+ "Notice that app_id has been deprecated in Prediction.IO 0.8.2. "
+ "Please use access_key instead.")
+
+ super(EventClient, self).__init__(url, threads, qsize, timeout)
+
+ if len(access_key) <= 8:
+ raise DeprecationWarning(
+ "It seems like you are specifying an app_id. It is deprecated in "
+ "Prediction.IO 0.8.2. Please use access_key instead. Or, "
+ "you may use an earlier version of this sdk.")
+
+ self.access_key = access_key
+
+ def acreate_event(self, event, entity_type, entity_id,
+ 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
+ unique within same entityType. type str.
+ :param entity_id: entity id. *entity_type-entity_id* becomes the unique
+ identifier of the entity. For example, you may have entityType named user,
+ and different entity IDs, say 1 and 2. In this case, user-1 and user-2
+ uniquely identifies entities. type str
+ :param target_entity_type: target entity type. type str.
+ :param target_entity_id: target entity id. type str.
+ :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.
+ """
+ data = {
+ "event": event,
+ "entityType": entity_type,
+ "entityId": entity_id,
+ }
- :returns:
- status message.
+ if target_entity_type is not None:
+ data["targetEntityType"] = target_entity_type
+
+ if target_entity_id is not None:
+ data["targetEntityId"] = target_entity_id
+
+ if properties is not None:
+ data["properties"] = properties
+
+ et = event_time_validation(event_time)
+ # EventServer uses milliseconds, but python datetime class uses micro. Hence
+ # need to skip the last three digits.
+ et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
+ data["eventTime"] = et_str
+
+ path = "/events.json?accessKey=%s" % (self.access_key, )
+ request = AsyncRequest("POST", path, **data)
+ request.set_rfunc(self._acreate_resp)
+ self._connection.make_request(request)
+ return request
+
+ def create_event(self, event, entity_type, entity_id,
+ target_entity_type=None, target_entity_id=None, properties=None,
+ event_time=None):
+ """Synchronously (blocking) create an event."""
+ return self.acreate_event(event, entity_type, entity_id,
+ target_entity_type, target_entity_id, properties,
+ event_time).get_response()
+
+ 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.
+ """
+ enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+ path = "/events/%s.json" % enc_event_id
+ request = AsyncRequest("GET", path, accessKey=self.access_key)
+ request.set_rfunc(self._aget_resp)
+ self._connection.make_request(request)
+ return request
+
+ def get_event(self, event_id):
+ """Synchronouly get an event from Event Server."""
+ return self.aget_event(event_id).get_response()
+
+ 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.
+ """
+ enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+ path = "/events/%s.json" % (enc_event_id, )
+ request = AsyncRequest("DELETE", path, accessKey=self.access_key)
+ request.set_rfunc(self._adelete_resp)
+ self._connection.make_request(request)
+ return request
+
+ def delete_event(self, event_id):
+ """Synchronouly delete an event from Event Server."""
+ return self.adelete_event(event_id).get_response()
+
+ # Below are helper functions
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$set",
+ entity_type="user",
+ entity_id=uid,
+ properties=properties,
+ event_time=event_time,
+ )
- :raises:
- ServerStatusError.
- """
- path = "/"
- request = AsyncRequest("GET", path)
- request.set_rfunc(self._aget_resp)
- self._connection.make_request(request)
- result = request.get_response()
- return result
-
- def _acreate_resp(self, response):
- if response.error is not None:
- raise NotCreatedError("Exception happened: %s for request %s" %
- (response.error, response.request))
- elif response.status != httplib.CREATED:
- raise NotCreatedError("request: %s status: %s body: %s" %
- (response.request, response.status,
- response.body))
-
- return response
-
- def _aget_resp(self, response):
- if response.error is not None:
- raise NotFoundError("Exception happened: %s for request %s" %
- (response.error, response.request))
- elif response.status != httplib.OK:
- raise NotFoundError("request: %s status: %s body: %s" %
- (response.request, response.status,
- response.body))
-
- return response.json_body
-
- def _adelete_resp(self, response):
- if response.error is not None:
- raise NotFoundError("Exception happened: %s for request %s" %
- (response.error, response.request))
- elif response.status != httplib.OK:
- raise NotFoundError("request: %s status: %s body: %s" %
- (response.request, response.status,
- response.body))
-
- return response.body
+ def set_user(self, uid, properties={}, event_time=None):
+ """Set properties of a user"""
+ return self.aset_user(uid, properties, event_time).get_response()
+
+ 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".
+ """
+ # check properties={}, it cannot be empty
+ return self.acreate_event(
+ event="$unset",
+ entity_type="user",
+ entity_id=uid,
+ properties=properties,
+ event_time=event_time,
+ )
+ def unset_user(self, uid, properties, event_time=None):
+ """Set properties of a user"""
+ return self.aunset_user(uid, properties, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$delete",
+ entity_type="user",
+ entity_id=uid,
+ event_time=event_time)
+
+ def delete_user(self, uid, event_time=None):
+ """Delete a user."""
+ return self.adelete_user(uid, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$set",
+ entity_type="item",
+ entity_id=iid,
+ properties=properties,
+ event_time=event_time)
+
+ def set_item(self, iid, properties={}, event_time=None):
+ """Set properties of an item."""
+ return self.aset_item(iid, properties, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$unset",
+ entity_type="item",
+ entity_id=iid,
+ properties=properties,
+ event_time=event_time)
+
+ def unset_item(self, iid, properties={}, event_time=None):
+ """Unset properties of an item."""
+ return self.aunset_item(iid, properties, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event="$delete",
+ entity_type="item",
+ entity_id=iid,
+ event_time=event_time)
+
+ def delete_item(self, iid, event_time=None):
+ """Delete an item."""
+ return self.adelete_item(iid, event_time).get_response()
+
+ 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".
+ """
+ return self.acreate_event(
+ event=action,
+ entity_type="user",
+ entity_id=uid,
+ target_entity_type="item",
+ target_entity_id=iid,
+ properties=properties,
+ event_time=event_time)
+
+ def record_user_action_on_item(self, action, uid, iid, properties={},
+ event_time=None):
+ """Create a user-to-item action."""
+ return self.arecord_user_action_on_item(
+ action, uid, iid, properties, event_time).get_response()
-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.
- Must be >= 1.
- :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, access_key,
- url="http://localhost:7070",
- threads=1, qsize=0, timeout=5):
- assert type(access_key) is str, ("access_key must be string. "
- "Notice that app_id has been deprecated in Prediction.IO 0.8.2. "
- "Please use access_key instead.")
-
- super(EventClient, self).__init__(url, threads, qsize, timeout)
-
- if len(access_key) <= 8:
- raise DeprecationWarning(
- "It seems like you are specifying an app_id. It is deprecated in "
- "Prediction.IO 0.8.2. Please use access_key instead. Or, "
- "you may use an earlier version of this sdk.")
-
- self.access_key = access_key
-
- def acreate_event(self, event, entity_type, entity_id,
- 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
- unique within same entityType. type str.
- :param entity_id: entity id. *entity_type-entity_id* becomes the unique
- identifier of the entity. For example, you may have entityType named user,
- and different entity IDs, say 1 and 2. In this case, user-1 and user-2
- uniquely identifies entities. type str
- :param target_entity_type: target entity type. type str.
- :param target_entity_id: target entity id. type str.
- :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.
- """
- data = {
- "event": event,
- "entityType": entity_type,
- "entityId": entity_id,
- }
- if target_entity_type is not None:
- data["targetEntityType"] = target_entity_type
-
- if target_entity_id is not None:
- data["targetEntityId"] = target_entity_id
-
- if properties is not None:
- data["properties"] = properties
-
- et = event_time_validation(event_time)
- # EventServer uses milliseconds, but python datetime class uses micro. Hence
- # need to skip the last three digits.
- et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
- data["eventTime"] = et_str
-
- path = "/events.json?accessKey=%s" % (self.access_key, )
- request = AsyncRequest("POST", path, **data)
- request.set_rfunc(self._acreate_resp)
- self._connection.make_request(request)
- return request
-
- def create_event(self, event, entity_type, entity_id,
- target_entity_type=None, target_entity_id=None, properties=None,
- event_time=None):
- """Synchronously (blocking) create an event."""
- return self.acreate_event(event, entity_type, entity_id,
- target_entity_type, target_entity_id, properties,
- event_time).get_response()
-
- 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.
+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.
+ :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.
+
"""
- enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
- path = "/events/%s.json" % enc_event_id
- request = AsyncRequest("GET", path, accessKey=self.access_key)
- request.set_rfunc(self._aget_resp)
- self._connection.make_request(request)
- return request
- def get_event(self, event_id):
- """Synchronouly get an event from Event Server."""
- return self.aget_event(event_id).get_response()
+ def __init__(self, url="http://localhost:8000", threads=1,
+ qsize=0, timeout=5):
+ super(EngineClient, self).__init__(url, threads, qsize, timeout)
- def adelete_event(self, event_id):
- """Asynchronouly delete an event from Event Server.
+ def asend_query(self, data):
+ """Asynchronously send a request to the engine instance with data as the
+ query.
- :param event_id: event id returned by the EventServer when creating the
- event.
+ :param data: the query: It is coverted to an json object using json.dumps
+ method. type dict.
- :returns:
- AsyncRequest object.
- """
- enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
- path = "/events/%s.json" % (enc_event_id, )
- request = AsyncRequest("DELETE", path, accessKey=self.access_key)
- request.set_rfunc(self._adelete_resp)
- self._connection.make_request(request)
- return request
-
- def delete_event(self, event_id):
- """Synchronouly delete an event from Event Server."""
- return self.adelete_event(event_id).get_response()
-
- ## Below are helper functions
-
- 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".
- """
- return self.acreate_event(
- event="$set",
- entity_type="user",
- entity_id=uid,
- properties=properties,
- event_time=event_time,
- )
-
- def set_user(self, uid, properties={}, event_time=None):
- """Set properties of a user"""
- return self.aset_user(uid, properties, event_time).get_response()
-
- 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".
- """
- # check properties={}, it cannot be empty
- return self.acreate_event(
- event="$unset",
- entity_type="user",
- entity_id=uid,
- properties=properties,
- event_time=event_time,
- )
+ :returns:
+ AsyncRequest object. You can call the get_response() method using this
+ object to get the final resuls or status of this asynchronous request.
+ """
+ path = "/queries.json"
+ request = AsyncRequest("POST", path, **data)
+ request.set_rfunc(self._aget_resp)
+ self._connection.make_request(request)
+ return request
- def unset_user(self, uid, properties, event_time=None):
- """Set properties of a user"""
- return self.aunset_user(uid, properties, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$delete",
- entity_type="user",
- entity_id=uid,
- event_time=event_time)
-
- def delete_user(self, uid, event_time=None):
- """Delete a user."""
- return self.adelete_user(uid, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$set",
- entity_type="item",
- entity_id=iid,
- properties=properties,
- event_time=event_time)
-
- def set_item(self, iid, properties={}, event_time=None):
- """Set properties of an item."""
- return self.aset_item(iid, properties, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$unset",
- entity_type="item",
- entity_id=iid,
- properties=properties,
- event_time=event_time)
-
- def unset_item(self, iid, properties={}, event_time=None):
- """Unset properties of an item."""
- return self.aunset_item(iid, properties, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event="$delete",
- entity_type="item",
- entity_id=iid,
- event_time=event_time)
-
- def delete_item(self, iid, event_time=None):
- """Delete an item."""
- return self.adelete_item(iid, event_time).get_response()
-
- 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".
- """
- return self.acreate_event(
- event=action,
- entity_type="user",
- entity_id=uid,
- target_entity_type="item",
- target_entity_id=iid,
- properties=properties,
- event_time=event_time)
-
- def record_user_action_on_item(self, action, uid, iid, properties={},
- event_time=None):
- """Create a user-to-item action."""
- return self.arecord_user_action_on_item(
- action, uid, iid, properties, event_time).get_response()
+ 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.
-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.
- :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, url="http://localhost:8000", threads=1,
- qsize=0, timeout=5):
- super(EngineClient, self).__init__(url, threads, qsize, timeout)
-
- 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.
- """
- path = "/queries.json"
- request = AsyncRequest("POST", path, **data)
- request.set_rfunc(self._aget_resp)
- self._connection.make_request(request)
- return request
-
- 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()
+ :returns: the prediction.
+ """
+ return self.asend_query(data).get_response()
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/bc678328/predictionio/connection.py
----------------------------------------------------------------------
diff --git a/predictionio/connection.py b/predictionio/connection.py
index 2c79d64..8c231f4 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 @@ import logging
# 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,332 +38,329 @@ DEBUG_LOG = False
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 __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 __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_rfunc(self, func):
- self.rfunc = func
+ def set_response(self, response):
+ """ store the response
- def set_response(self, response):
- """ store the response
+ NOTE: Must be only called once
+ """
+ self.response_q.put(response)
- NOTE: Must be only called once
- """
- self.response_q.put(response)
+ def get_response(self):
+ """Get the response. Blocking.
- 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
- :returns: self.rfunc's return type.
+ 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
-
- 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.
- """
-
- 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:
- self.json_body = None
-
- def set_error(self, error):
- self.error = error
-
- def set_request(self, request):
- self.request = request
+ 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 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
- 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
+ """
- 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()
- 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:
- 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()
+ # 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
-
- 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)
-
- # 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))
+ """worker function which establishes connection and wait for request jobs
+ from the request_queue
- d.set_request(request)
- request.set_response(d)
- request_queue.task_done()
- if killed:
- break
+ 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.
+ """
- # end of while loop
- connect.close()
+ connect = PredictionIOHttpConnection(host, https, timeout)
+
+ # 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))
+
+ d.set_request(request)
+ request.set_response(d)
+ request_queue.task_done()
+ if killed:
+ break
+
+ # 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
- """
- 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 make_request(self, request):
- """put the request into the q
- """
- self.q.put(request)
-
- def pending_requests(self):
- """number of pending requests in the queue
+ spawn multiple connection_worker threads to handle jobs in the queue q
"""
- return self.q.qsize()
-
- 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()
+ 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
+ """
+ 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 make_request(self, request):
+ """put the request into the q
+ """
+ self.q.put(request)
+
+ def pending_requests(self):
+ """number of pending requests in the queue
+ """
+ return self.q.qsize()
+
+ 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()
[19/24] incubator-predictionio-sdk-python git commit: Closes #21
Posted by sh...@apache.org.
Closes #21
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/4b51a300
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/4b51a300
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/4b51a300
Branch: refs/heads/master
Commit: 4b51a300e95c123de67742f7679d55f8045e07d7
Parents: 5510953
Author: Shinsuke Sugaya <sh...@apache.org>
Authored: Sun Sep 10 23:20:52 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Sun Sep 10 23:20:52 2017 +0900
----------------------------------------------------------------------
----------------------------------------------------------------------
[09/24] incubator-predictionio-sdk-python git commit: Merge pull
request #13 from AlmogCohen/develop
Posted by sh...@apache.org.
Merge pull request #13 from AlmogCohen/develop
Added missing import for InvalidArgumentError
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/b85d044f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/b85d044f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/b85d044f
Branch: refs/heads/master
Commit: b85d044f83bb4f811232d97db4bb7626222cac83
Parents: 849c2d5 a6f841f
Author: EmergentOrder <le...@gmail.com>
Authored: Wed Oct 28 11:31:42 2015 -0300
Committer: EmergentOrder <le...@gmail.com>
Committed: Wed Oct 28 11:31:42 2015 -0300
----------------------------------------------------------------------
predictionio/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/b85d044f/predictionio/__init__.py
----------------------------------------------------------------------
[14/24] incubator-predictionio-sdk-python git commit: fix version
numbers
Posted by sh...@apache.org.
fix version numbers
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/cd72584e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/cd72584e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/cd72584e
Branch: refs/heads/master
Commit: cd72584e3617109eb9f77fe9e7489dd3cc2c9d6b
Parents: 73adea9
Author: EmergentOrder <le...@gmail.com>
Authored: Tue Nov 3 14:13:23 2015 -0400
Committer: EmergentOrder <le...@gmail.com>
Committed: Tue Nov 3 14:13:23 2015 -0400
----------------------------------------------------------------------
docs/source/conf.py | 2 +-
predictionio/__init__.py | 2 +-
setup.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/cd72584e/docs/source/conf.py
----------------------------------------------------------------------
diff --git a/docs/source/conf.py b/docs/source/conf.py
index d52d83e..5139b89 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -54,7 +54,7 @@ copyright = u'2014, TappingStone, Inc.'
# The short X.Y version.
version = '0.9'
# The full version, including alpha/beta/rc tags.
-release = '0.9.6'
+release = '0.9.8'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/cd72584e/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 699b2db..b429b4e 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -4,7 +4,7 @@ Python applications with PredictionIO REST API services.
"""
-__version__ = "0.9.6"
+__version__ = "0.9.8"
# import packages
import re
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/cd72584e/setup.py
----------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index 67b12e3..eeafe17 100644
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ __license__ = "Apache License, Version 2.0"
setup(
name='PredictionIO',
- version="0.9.6",
+ version="0.9.8",
author=__author__,
author_email=__email__,
packages=['predictionio'],
[07/24] incubator-predictionio-sdk-python git commit: adding comment:
(getting events through the Event Server API is used for debugging and not
recommended for production)
Posted by sh...@apache.org.
adding comment: (getting events through the Event Server API is used for debugging and not recommended for production)
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/6c95d7f5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/6c95d7f5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/6c95d7f5
Branch: refs/heads/master
Commit: 6c95d7f5d8e060c339b617cd9de342740a21de43
Parents: 8bdf59f
Author: Nguyen Viet Anh <vi...@gmail.com>
Authored: Sat Aug 1 09:53:42 2015 +0700
Committer: Nguyen Viet Anh <vi...@gmail.com>
Committed: Sat Aug 1 09:53:42 2015 +0700
----------------------------------------------------------------------
predictionio/__init__.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/6c95d7f5/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 01b7cc2..f4db10c 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -287,7 +287,7 @@ class EventClient(BaseClient):
return self.aget_event(event_id).get_response()
def aget_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
- """Asynchronouly get events from Event Server.
+ """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.
@@ -328,7 +328,7 @@ class EventClient(BaseClient):
return request
def get_events(self, startTime=None, untilTime=None, entityType=None, entityId=None, limit=None, reversed=False):
- """Synchronouly get event from Event Server."""
+ """Synchronouly get event from Event Server. (Getting events through the Event Server API is used for debugging and not recommended for production)"""
return self.aget_events(
startTime=startTime,
untilTime=untilTime,
[12/24] incubator-predictionio-sdk-python git commit: exclude
indentation error
Posted by sh...@apache.org.
exclude indentation error
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/e63bf7f6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/e63bf7f6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/e63bf7f6
Branch: refs/heads/master
Commit: e63bf7f697c50b9ec23496fc8dc39fe556f97cef
Parents: 77ef0dd
Author: EmergentOrder <le...@gmail.com>
Authored: Tue Nov 3 13:56:00 2015 -0400
Committer: EmergentOrder <le...@gmail.com>
Committed: Tue Nov 3 13:56:00 2015 -0400
----------------------------------------------------------------------
tox.ini | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/e63bf7f6/tox.ini
----------------------------------------------------------------------
diff --git a/tox.ini b/tox.ini
index 23d96e4..87b57e9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,5 +5,9 @@ envlist = py27,py34
deps = flake8
pandas
+[flake8]
+ignore = E111
+
+
commands = flake8 --ignore=E501 --filename=*.py --exclude=doc,setup.py,*/tests/*
python -m unittest discover --pattern=*.py tests
[16/24] incubator-predictionio-sdk-python git commit: fix
InvalidArgumentError is not defined
Posted by sh...@apache.org.
fix InvalidArgumentError is not defined
Closes #19
Project: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/commit/a151e0cd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/tree/a151e0cd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/diff/a151e0cd
Branch: refs/heads/master
Commit: a151e0cdfc9f84334cb29c6bb429a829606f5c4b
Parents: 8e35e33
Author: goodspeed <ca...@gmail.com>
Authored: Sun Sep 10 23:12:50 2017 +0900
Committer: Shinsuke Sugaya <sh...@apache.org>
Committed: Sun Sep 10 23:12:50 2017 +0900
----------------------------------------------------------------------
predictionio/__init__.py | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-predictionio-sdk-python/blob/a151e0cd/predictionio/__init__.py
----------------------------------------------------------------------
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 01ac045..d70c85c 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -47,6 +47,10 @@ class NotFoundError(PredictionIOAPIError):
pass
+class InvalidArgumentError(PredictionIOAPIError):
+ pass
+
+
def event_time_validation(t):
""" Validate event_time according to EventAPI Specification.
"""