SDKPYTHON-18 Support channel
diff --git a/examples/event_sample.py b/examples/event_sample.py
index 0a7a339..9c3fe25 100644
--- a/examples/event_sample.py
+++ b/examples/event_sample.py
@@ -98,7 +98,7 @@
 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))
diff --git a/examples/event_sample_channel.py b/examples/event_sample_channel.py
new file mode 100644
index 0000000..125086a
--- /dev/null
+++ b/examples/event_sample_channel.py
@@ -0,0 +1,82 @@
+# this is example of import events to a specific channel of an App
+
+from predictionio import EventClient
+from predictionio import NotFoundError
+from datetime import datetime
+import pytz
+import sys
+
+access_key = None
+channel = None
+
+assert access_key is not None, "Please create an access key with 'pio app new'"
+# Need to create channel first before
+assert channel is not None, "Please create new channel with 'pio app channel-new'"
+
+client = EventClient(access_key=access_key, url="http://localhost:7070",
+  channel=channel)
+
+# Check status
+print("Check status")
+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 ,
+    }
+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)
+print
+
+# 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)
+print
+
+
+# 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)
+print
+
+# Delete the first event from Event Server
+print("Delete Event")
+delete_response = client.delete_event(first_event_id)
+print(delete_response)
+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
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index 3175139..280fc65 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -18,6 +18,13 @@
   # pylint: disable=F0401
   # http is a Python3 module, replacing httplib
   from http import client as httplib
+
+try:
+  from urllib import urlencode
+except ImportError:
+  # pylint: disable=F0401,E0611
+  from urllib.parse import urlencode
+
 import json
 import urllib
 
@@ -165,11 +172,12 @@
   :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):
+      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.")
@@ -183,6 +191,7 @@
           "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,
@@ -228,7 +237,15 @@
     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, )
+    qparam = {
+        "accessKey" : self.access_key
+        }
+
+    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)
@@ -251,9 +268,16 @@
     :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, accessKey=self.access_key)
+    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
@@ -271,9 +295,16 @@
     :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, accessKey=self.access_key)
+    request = AsyncRequest("DELETE", path, **qparam)
     request.set_rfunc(self._adelete_resp)
     self._connection.make_request(request)
     return request