aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
authorDevendra2013-02-24 00:58:24 +0530
committerDevendra2013-02-24 00:58:24 +0530
commit7d76f9d0d9c04c2fbc7740a08122fdc4c5622fa3 (patch)
tree4c71abce3b3c8d0fa7ab217f5b742aa2fbd36e86 /python
downloadpubnub-python-7d76f9d0d9c04c2fbc7740a08122fdc4c5622fa3.tar.bz2
copying python, python-twisted, python-tornado
Diffstat (limited to 'python')
-rw-r--r--python/3.2/Pubnub.py345
-rwxr-xr-xpython/3.2/history-example.py12
-rwxr-xr-xpython/3.2/publish-example.py14
-rwxr-xr-xpython/3.2/subscribe-example.py64
-rwxr-xr-xpython/3.2/unit-test.py77
-rw-r--r--python/3.3/Pubnub.py401
-rw-r--r--python/3.3/Pubnub.pycbin0 -> 9208 bytes
-rwxr-xr-xpython/3.3/detailed-history-unit-test.py134
-rwxr-xr-xpython/3.3/history-example.py12
-rwxr-xr-xpython/3.3/publish-example.py14
-rwxr-xr-xpython/3.3/subscribe-example.py64
-rwxr-xr-xpython/3.3/unit-test.py77
-rw-r--r--python/README123
13 files changed, 1337 insertions, 0 deletions
diff --git a/python/3.2/Pubnub.py b/python/3.2/Pubnub.py
new file mode 100644
index 0000000..79086cf
--- /dev/null
+++ b/python/3.2/Pubnub.py
@@ -0,0 +1,345 @@
+## www.pubnub.com - PubNub Real-time push service in the cloud.
+# coding=utf8
+
+## PubNub Real-time Push APIs and Notifications Framework
+## Copyright (c) 2010 Stephen Blum
+## http://www.pubnub.com/
+
+## -----------------------------------
+## PubNub 3.0 Real-time Push Cloud API
+## -----------------------------------
+
+try: import json
+except ImportError: import simplejson as json
+
+import time
+import hashlib
+import urllib2
+import uuid
+
+class Pubnub():
+ def __init__(
+ self,
+ publish_key,
+ subscribe_key,
+ secret_key = False,
+ ssl_on = False,
+ origin = 'pubsub.pubnub.com',
+ pres_uuid = None
+ ) :
+ """
+ #**
+ #* Pubnub
+ #*
+ #* Init the Pubnub Client API
+ #*
+ #* @param string publish_key required key to send messages.
+ #* @param string subscribe_key required key to receive messages.
+ #* @param string secret_key optional key to sign messages.
+ #* @param boolean ssl required for 2048 bit encrypted messages.
+ #* @param string origin PUBNUB Server Origin.
+ #* @param string pres_uuid optional identifier for presence (auto-generated if not supplied)
+ #**
+
+ ## Initiat Class
+ pubnub = Pubnub( 'PUBLISH-KEY', 'SUBSCRIBE-KEY', 'SECRET-KEY', False )
+
+ """
+ self.origin = origin
+ self.limit = 1800
+ self.publish_key = publish_key
+ self.subscribe_key = subscribe_key
+ self.secret_key = secret_key
+ self.ssl = ssl_on
+
+ if self.ssl :
+ self.origin = 'https://' + self.origin
+ else :
+ self.origin = 'http://' + self.origin
+
+ self.uuid = pres_uuid or str(uuid.uuid4())
+
+ if not isinstance(self.uuid, basestring):
+ raise AttributeError("pres_uuid must be a string")
+
+ def publish( self, args ) :
+ """
+ #**
+ #* Publish
+ #*
+ #* Send a message to a channel.
+ #*
+ #* @param array args with channel and message.
+ #* @return array success information.
+ #**
+
+ ## Publish Example
+ info = pubnub.publish({
+ 'channel' : 'hello_world',
+ 'message' : {
+ 'some_text' : 'Hello my World'
+ }
+ })
+ print(info)
+
+ """
+ ## Fail if bad input.
+ if not (args['channel'] and args['message']) :
+ return [ 0, 'Missing Channel or Message' ]
+
+ ## Capture User Input
+ channel = str(args['channel'])
+ message = json.dumps(args['message'], separators=(',',':'))
+
+ ## Sign Message
+ if self.secret_key :
+ signature = hashlib.md5('/'.join([
+ self.publish_key,
+ self.subscribe_key,
+ self.secret_key,
+ channel,
+ message
+ ])).hexdigest()
+ else :
+ signature = '0'
+
+ ## Send Message
+ return self._request([
+ 'publish',
+ self.publish_key,
+ self.subscribe_key,
+ signature,
+ channel,
+ '0',
+ message
+ ])
+
+
+ def subscribe( self, args ) :
+ """
+ #**
+ #* Subscribe
+ #*
+ #* This is BLOCKING.
+ #* Listen for a message on a channel.
+ #*
+ #* @param array args with channel and callback.
+ #* @return false on fail, array on success.
+ #**
+
+ ## Subscribe Example
+ def receive(message) :
+ print(message)
+ return True
+
+ pubnub.subscribe({
+ 'channel' : 'hello_world',
+ 'callback' : receive
+ })
+
+ """
+
+ ## Fail if missing channel
+ if not 'channel' in args :
+ raise Exception('Missing Channel.')
+ return False
+
+ ## Fail if missing callback
+ if not 'callback' in args :
+ raise Exception('Missing Callback.')
+ return False
+
+ ## Capture User Input
+ channel = str(args['channel'])
+ callback = args['callback']
+ subscribe_key = args.get('subscribe_key') or self.subscribe_key
+
+ ## Begin Subscribe
+ while True :
+
+ timetoken = 'timetoken' in args and args['timetoken'] or 0
+ try :
+ ## Wait for Message
+ response = self._request(self._encode([
+ 'subscribe',
+ subscribe_key,
+ channel,
+ '0',
+ str(timetoken)
+ ])+['?uuid='+self.uuid], encode=False)
+
+ messages = response[0]
+ args['timetoken'] = response[1]
+
+ ## If it was a timeout
+ if not len(messages) :
+ continue
+
+ ## Run user Callback and Reconnect if user permits.
+ for message in messages :
+ if not callback(message) :
+ return
+
+ except Exception:
+ time.sleep(1)
+
+ return True
+
+ def presence( self, args ) :
+ """
+ #**
+ #* presence
+ #*
+ #* This is BLOCKING.
+ #* Listen for presence events on a channel.
+ #*
+ #* @param array args with channel and callback.
+ #* @return false on fail, array on success.
+ #**
+
+ ## Presence Example
+ def pres_event(message) :
+ print(message)
+ return True
+
+ pubnub.presence({
+ 'channel' : 'hello_world',
+ 'callback' : receive
+ })
+ """
+
+ ## Fail if missing channel
+ if not 'channel' in args :
+ raise Exception('Missing Channel.')
+ return False
+
+ ## Fail if missing callback
+ if not 'callback' in args :
+ raise Exception('Missing Callback.')
+ return False
+
+ ## Capture User Input
+ channel = str(args['channel'])
+ callback = args['callback']
+ subscribe_key = args.get('subscribe_key') or self.subscribe_key
+
+ return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': callback})
+
+
+ def here_now( self, args ) :
+ """
+ #**
+ #* Here Now
+ #*
+ #* Load current occupancy from a channel.
+ #*
+ #* @param array args with 'channel'.
+ #* @return mixed false on fail, array on success.
+ #*
+
+ ## Presence Example
+ here_now = pubnub.here_now({
+ 'channel' : 'hello_world',
+ })
+ print(here_now['occupancy'])
+ print(here_now['uuids'])
+
+ """
+ channel = str(args['channel'])
+
+ ## Fail if bad input.
+ if not channel :
+ raise Exception('Missing Channel')
+ return False
+
+ ## Get Presence Here Now
+ return self._request([
+ 'v2','presence',
+ 'sub_key', self.subscribe_key,
+ 'channel', channel
+ ]);
+
+
+ def history( self, args ) :
+ """
+ #**
+ #* History
+ #*
+ #* Load history from a channel.
+ #*
+ #* @param array args with 'channel' and 'limit'.
+ #* @return mixed false on fail, array on success.
+ #*
+
+ ## History Example
+ history = pubnub.history({
+ 'channel' : 'hello_world',
+ 'limit' : 1
+ })
+ print(history)
+
+ """
+ ## Capture User Input
+ limit = args.has_key('limit') and int(args['limit']) or 10
+ channel = str(args['channel'])
+
+ ## Fail if bad input.
+ if not channel :
+ raise Exception('Missing Channel')
+ return False
+
+ ## Get History
+ return self._request([
+ 'history',
+ self.subscribe_key,
+ channel,
+ '0',
+ str(limit)
+ ]);
+
+
+ def time(self) :
+ """
+ #**
+ #* Time
+ #*
+ #* Timestamp from PubNub Cloud.
+ #*
+ #* @return int timestamp.
+ #*
+
+ ## PubNub Server Time Example
+ timestamp = pubnub.time()
+ print(timestamp)
+
+ """
+ return self._request([
+ 'time',
+ '0'
+ ])[0]
+
+
+ def _encode( self, request ) :
+ return [
+ "".join([ ' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and
+ hex(ord(ch)).replace( '0x', '%' ).upper() or
+ ch for ch in list(bit)
+ ]) for bit in request]
+
+
+ def _request( self, request, origin = None, encode = True ) :
+ ## Build URL
+ url = (origin or self.origin) + '/' + "/".join(
+ encode and self._encode(request) or request
+ )
+
+ ## Send Request Expecting JSONP Response
+ try:
+ try: usock = urllib2.urlopen( url, None, 200 )
+ except TypeError: usock = urllib2.urlopen( url, None )
+ response = usock.read()
+ usock.close()
+ return json.loads( response )
+ except:
+ return None
+
diff --git a/python/3.2/history-example.py b/python/3.2/history-example.py
new file mode 100755
index 0000000..cedf69e
--- /dev/null
+++ b/python/3.2/history-example.py
@@ -0,0 +1,12 @@
+from Pubnub import Pubnub
+
+## Initiat Class
+pubnub = Pubnub( 'demo', 'demo', None, False )
+
+## History Example
+history = pubnub.history({
+ 'channel' : 'hello_world',
+ 'limit' : 1
+})
+print(history)
+
diff --git a/python/3.2/publish-example.py b/python/3.2/publish-example.py
new file mode 100755
index 0000000..725df0b
--- /dev/null
+++ b/python/3.2/publish-example.py
@@ -0,0 +1,14 @@
+from Pubnub import Pubnub
+
+## Initiate Class
+pubnub = Pubnub( 'demo', 'demo', None, False )
+
+## Publish Example
+info = pubnub.publish({
+ 'channel' : 'hello_world',
+ 'message' : {
+ 'some_text' : 'Hello my World'
+ }
+})
+print(info)
+
diff --git a/python/3.2/subscribe-example.py b/python/3.2/subscribe-example.py
new file mode 100755
index 0000000..e458e2b
--- /dev/null
+++ b/python/3.2/subscribe-example.py
@@ -0,0 +1,64 @@
+import sys
+import threading
+import time
+import random
+import string
+from Pubnub import Pubnub
+
+## Initiate Class
+pubnub = Pubnub( 'demo', 'demo', None, False )
+
+print("My UUID is: "+pubnub.uuid)
+
+channel = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(20))
+
+## Subscribe Example
+def receive(message) :
+ print(message)
+ return False
+
+def pres_event(message):
+ print(message)
+ return False
+
+def subscribe():
+ print("Listening for messages on '%s' channel..." % channel)
+ pubnub.subscribe({
+ 'channel' : channel,
+ 'callback' : receive
+ })
+
+def presence():
+ print("Listening for presence events on '%s' channel..." % channel)
+ pubnub.presence({
+ 'channel' : channel,
+ 'callback' : pres_event
+ })
+
+def publish():
+ print("Publishing a test message on '%s' channel..." % channel)
+ pubnub.publish({
+ 'channel' : channel,
+ 'message' : { 'text':'foo bar' }
+ })
+
+pres_thread = threading.Thread(target=presence)
+pres_thread.daemon=True
+pres_thread.start()
+
+sub_thread = threading.Thread(target=subscribe)
+sub_thread.daemon=True
+sub_thread.start()
+
+time.sleep(3)
+
+publish()
+
+
+print("waiting for subscribes and presence")
+pres_thread.join()
+
+print pubnub.here_now({'channel':channel})
+
+sub_thread.join()
+
diff --git a/python/3.2/unit-test.py b/python/3.2/unit-test.py
new file mode 100755
index 0000000..88391a0
--- /dev/null
+++ b/python/3.2/unit-test.py
@@ -0,0 +1,77 @@
+## www.pubnub.com - PubNub Real-time push service in the cloud.
+# coding=utf8
+
+## PubNub Real-time Push APIs and Notifications Framework
+## Copyright (c) 2010 Stephen Blum
+## http://www.pubnub.com/
+
+## -----------------------------------
+## PubNub 3.0 Real-time Push Cloud API
+## -----------------------------------
+
+from Pubnub import Pubnub
+import sys
+
+publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo'
+subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo'
+secret_key = len(sys.argv) > 3 and sys.argv[3] or None
+ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False
+
+
+## -----------------------------------------------------------------------
+## Initiat Class
+## -----------------------------------------------------------------------
+
+pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on )
+crazy = ' ~`!@#$%^&*(顶顅Ȓ)+=[]\\{}|;\':",./<>?abcd'
+
+## ---------------------------------------------------------------------------
+## Unit Test Function
+## ---------------------------------------------------------------------------
+def test( trial, name ) :
+ if trial :
+ print( 'PASS: ' + name )
+ else :
+ print( 'FAIL: ' + name )
+
+## -----------------------------------------------------------------------
+## Publish Example
+## -----------------------------------------------------------------------
+pubish_success = pubnub.publish({
+ 'channel' : crazy,
+ 'message' : crazy
+})
+test( pubish_success[0] == 1, 'Publish First Message Success' )
+
+## -----------------------------------------------------------------------
+## History Example
+## -----------------------------------------------------------------------
+history = pubnub.history({
+ 'channel' : crazy,
+ 'limit' : 1
+})
+test(
+ history[0].encode('utf-8') == crazy,
+ 'History Message: ' + history[0]
+)
+test( len(history) == 1, 'History Message Count' )
+
+## -----------------------------------------------------------------------
+## PubNub Server Time Example
+## -----------------------------------------------------------------------
+timestamp = pubnub.time()
+test( timestamp > 0, 'PubNub Server Time: ' + str(timestamp) )
+
+## -----------------------------------------------------------------------
+## Subscribe Example
+## -----------------------------------------------------------------------
+def receive(message) :
+ print(message)
+ return True
+
+pubnub.subscribe({
+ 'channel' : crazy,
+ 'callback' : receive
+})
+
+
diff --git a/python/3.3/Pubnub.py b/python/3.3/Pubnub.py
new file mode 100644
index 0000000..a3f4d6f
--- /dev/null
+++ b/python/3.3/Pubnub.py
@@ -0,0 +1,401 @@
+## www.pubnub.com - PubNub Real-time push service in the cloud.
+# coding=utf8
+
+## PubNub Real-time Push APIs and Notifications Framework
+## Copyright (c) 2010 Stephen Blum
+## http://www.pubnub.com/
+
+## -----------------------------------
+## PubNub 3.0 Real-time Push Cloud API
+## -----------------------------------
+
+try: import json
+except ImportError: import simplejson as json
+
+import time
+import hashlib
+import urllib2
+import uuid
+
+class Pubnub():
+ def __init__(
+ self,
+ publish_key,
+ subscribe_key,
+ secret_key = False,
+ ssl_on = False,
+ origin = 'pubsub.pubnub.com',
+ pres_uuid = None
+ ) :
+ """
+ #**
+ #* Pubnub
+ #*
+ #* Init the Pubnub Client API
+ #*
+ #* @param string publish_key required key to send messages.
+ #* @param string subscribe_key required key to receive messages.
+ #* @param string secret_key optional key to sign messages.
+ #* @param boolean ssl required for 2048 bit encrypted messages.
+ #* @param string origin PUBNUB Server Origin.
+ #* @param string pres_uuid optional identifier for presence (auto-generated if not supplied)
+ #**
+
+ ## Initiat Class
+ pubnub = Pubnub( 'PUBLISH-KEY', 'SUBSCRIBE-KEY', 'SECRET-KEY', False )
+
+ """
+ self.origin = origin
+ self.limit = 1800
+ self.publish_key = publish_key
+ self.subscribe_key = subscribe_key
+ self.secret_key = secret_key
+ self.ssl = ssl_on
+
+ if self.ssl :
+ self.origin = 'https://' + self.origin
+ else :
+ self.origin = 'http://' + self.origin
+
+ self.uuid = pres_uuid or str(uuid.uuid4())
+
+ if not isinstance(self.uuid, basestring):
+ raise AttributeError("pres_uuid must be a string")
+
+ def publish( self, args ) :
+ """
+ #**
+ #* Publish
+ #*
+ #* Send a message to a channel.
+ #*
+ #* @param array args with channel and message.
+ #* @return array success information.
+ #**
+
+ ## Publish Example
+ info = pubnub.publish({
+ 'channel' : 'hello_world',
+ 'message' : {
+ 'some_text' : 'Hello my World'
+ }
+ })
+ print(info)
+
+ """
+ ## Fail if bad input.
+ if not (args['channel'] and args['message']) :
+ return [ 0, 'Missing Channel or Message' ]
+
+ ## Capture User Input
+ channel = str(args['channel'])
+ message = json.dumps(args['message'], separators=(',',':'))
+
+ ## Sign Message
+ if self.secret_key :
+ signature = hashlib.md5('/'.join([
+ self.publish_key,
+ self.subscribe_key,
+ self.secret_key,
+ channel,
+ message
+ ])).hexdigest()
+ else :
+ signature = '0'
+
+ ## Send Message
+ return self._request([
+ 'publish',
+ self.publish_key,
+ self.subscribe_key,
+ signature,
+ channel,
+ '0',
+ message
+ ])
+
+
+ def subscribe( self, args ) :
+ """
+ #**
+ #* Subscribe
+ #*
+ #* This is BLOCKING.
+ #* Listen for a message on a channel.
+ #*
+ #* @param array args with channel and callback.
+ #* @return false on fail, array on success.
+ #**
+
+ ## Subscribe Example
+ def receive(message) :
+ print(message)
+ return True
+
+ pubnub.subscribe({
+ 'channel' : 'hello_world',
+ 'callback' : receive
+ })
+
+ """
+
+ ## Fail if missing channel
+ if not 'channel' in args :
+ raise Exception('Missing Channel.')
+ return False
+
+ ## Fail if missing callback
+ if not 'callback' in args :
+ raise Exception('Missing Callback.')
+ return False
+
+ ## Capture User Input
+ channel = str(args['channel'])
+ callback = args['callback']
+ subscribe_key = args.get('subscribe_key') or self.subscribe_key
+
+ ## Begin Subscribe
+ while True :
+
+ timetoken = 'timetoken' in args and args['timetoken'] or 0
+ try :
+ ## Wait for Message
+ response = self._request(self._encode([
+ 'subscribe',
+ subscribe_key,
+ channel,
+ '0',
+ str(timetoken)
+ ])+['?uuid='+self.uuid], encode=False)
+
+ messages = response[0]
+ args['timetoken'] = response[1]
+
+ ## If it was a timeout
+ if not len(messages) :
+ continue
+
+ ## Run user Callback and Reconnect if user permits.
+ for message in messages :
+ if not callback(message) :
+ return
+
+ except Exception:
+ time.sleep(1)
+
+ return True
+
+ def presence( self, args ) :
+ """
+ #**
+ #* presence
+ #*
+ #* This is BLOCKING.
+ #* Listen for presence events on a channel.
+ #*
+ #* @param array args with channel and callback.
+ #* @return false on fail, array on success.
+ #**
+
+ ## Presence Example
+ def pres_event(message) :
+ print(message)
+ return True
+
+ pubnub.presence({
+ 'channel' : 'hello_world',
+ 'callback' : receive
+ })
+ """
+
+ ## Fail if missing channel
+ if not 'channel' in args :
+ raise Exception('Missing Channel.')
+ return False
+
+ ## Fail if missing callback
+ if not 'callback' in args :
+ raise Exception('Missing Callback.')
+ return False
+
+ ## Capture User Input
+ channel = str(args['channel'])
+ callback = args['callback']
+ subscribe_key = args.get('subscribe_key') or self.subscribe_key
+
+ return self.subscribe({'channel': channel+'-pnpres', 'subscribe_key':subscribe_key, 'callback': callback})
+
+
+ def here_now( self, args ) :
+ """
+ #**
+ #* Here Now
+ #*
+ #* Load current occupancy from a channel.
+ #*
+ #* @param array args with 'channel'.
+ #* @return mixed false on fail, array on success.
+ #*
+
+ ## Presence Example
+ here_now = pubnub.here_now({
+ 'channel' : 'hello_world',
+ })
+ print(here_now['occupancy'])
+ print(here_now['uuids'])
+
+ """
+ channel = str(args['channel'])
+
+ ## Fail if bad input.
+ if not channel :
+ raise Exception('Missing Channel')
+ return False
+
+ ## Get Presence Here Now
+ return self._request([
+ 'v2','presence',
+ 'sub_key', self.subscribe_key,
+ 'channel', channel
+ ]);
+
+
+ def history( self, args ) :
+ """
+ #**
+ #* History
+ #*
+ #* Load history from a channel.
+ #*
+ #* @param array args with 'channel' and 'limit'.
+ #* @return mixed false on fail, array on success.
+ #*
+
+ ## History Example
+ history = pubnub.history({
+ 'channel' : 'hello_world',
+ 'limit' : 1
+ })
+ print(history)
+
+ """
+ ## Capture User Input
+ limit = args.has_key('limit') and int(args['limit']) or 10
+ channel = str(args['channel'])
+
+ ## Fail if bad input.
+ if not channel :
+ raise Exception('Missing Channel')
+ return False
+
+ ## Get History
+ return self._request([
+ 'history',
+ self.subscribe_key,
+ channel,
+ '0',
+ str(limit)
+ ]);
+
+ def detailedHistory(self, args) :
+ """
+ #**
+ #* Detailed History
+ #*
+ #* Load Detailed history from a channel.
+ #*
+ #* @param array args with 'channel', optional: 'start', 'end', 'reverse', 'count'
+ #* @return mixed false on fail, array on success.
+ #*
+
+ ## History Example
+ history = pubnub.detailedHistory({
+ 'channel' : 'hello_world',
+ 'count' : 5
+ })
+ print(history)
+
+ """
+ ## Capture User Input
+ channel = str(args['channel'])
+
+ params = []
+ count = 100
+
+ if args.has_key('count'):
+ count = int(args['count'])
+
+ params.append('count' + '=' + str(count))
+
+ if args.has_key('reverse'):
+ params.append('reverse' + '=' + str(args['reverse']).lower())
+
+ if args.has_key('start'):
+ params.append('start' + '=' + str(args['start']))
+
+ if args.has_key('end'):
+ params.append('end' + '=' + str(args['end']))
+
+ ## Fail if bad input.
+ if not channel :
+ raise Exception('Missing Channel')
+ return False
+
+ ## Get History
+ return self._request([
+ 'v2',
+ 'history',
+ 'sub-key',
+ self.subscribe_key,
+ 'channel',
+ channel,
+ ],params=params);
+
+ def time(self) :
+ """
+ #**
+ #* Time
+ #*
+ #* Timestamp from PubNub Cloud.
+ #*
+ #* @return int timestamp.
+ #*
+
+ ## PubNub Server Time Example
+ timestamp = pubnub.time()
+ print(timestamp)
+
+ """
+ return self._request([
+ 'time',
+ '0'
+ ])[0]
+
+
+ def _encode( self, request ) :
+ return [
+ "".join([ ' ~`!@#$%^&*()+=[]\\{}|;\':",./<>?'.find(ch) > -1 and
+ hex(ord(ch)).replace( '0x', '%' ).upper() or
+ ch for ch in list(bit)
+ ]) for bit in request]
+
+
+ def _request( self, request, origin = None, encode = True, params = None ) :
+ ## Build URL
+ url = (origin or self.origin) + '/' + "/".join(
+ encode and self._encode(request) or request
+ )
+ ## Add query params
+ if params is not None and len(params) > 0:
+ url = url + "?" + "&".join(params)
+
+ ## Send Request Expecting JSONP Response
+ try:
+ try: usock = urllib2.urlopen( url, None, 200 )
+ except TypeError: usock = urllib2.urlopen( url, None )
+ response = usock.read()
+ usock.close()
+ return json.loads( response )
+ except:
+ return None
+
diff --git a/python/3.3/Pubnub.pyc b/python/3.3/Pubnub.pyc
new file mode 100644
index 0000000..76bebc4
--- /dev/null
+++ b/python/3.3/Pubnub.pyc
Binary files differ
diff --git a/python/3.3/detailed-history-unit-test.py b/python/3.3/detailed-history-unit-test.py
new file mode 100755
index 0000000..2169e52
--- /dev/null
+++ b/python/3.3/detailed-history-unit-test.py
@@ -0,0 +1,134 @@
+## www.pubnub.com - PubNub Real-time push service in the cloud.
+# coding=utf8
+
+## PubNub Real-time Push APIs and Notifications Framework
+## Copyright (c) 2010 Stephen Blum
+## http://www.pubnub.com/
+
+## -----------------------------------
+## PubNub 3.0 Real-time Push Cloud API
+## -----------------------------------
+
+from Pubnub import Pubnub
+import unittest2 as unittest
+import sys
+
+
+publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo'
+subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo'
+secret_key = len(sys.argv) > 3 and sys.argv[3] or None
+ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False
+pubnub = Pubnub(publish_key, subscribe_key, secret_key, ssl_on)
+crazy = ' ~`!@#$%^&*(顶顅Ȓ)+=[]\\{}|;\':",./<>?abcd'
+
+
+class TestDetailedHistory(unittest.TestCase):
+ total_msg = 10
+ channel = pubnub.time()
+ starttime = None
+ inputs = []
+ endtime = None
+ slice_a = 8
+ slice_b = 2
+ slice_size = slice_a - slice_b
+
+ @classmethod
+ def publish_msg(cls, start, end, offset):
+ print 'Publishing messages'
+ inputs = []
+ for i in range(start + offset, end + offset):
+ message = str(i) + " " + crazy
+ success = pubnub.publish({
+ 'channel': cls.channel,
+ 'message': message,
+ })
+ t = pubnub.time()
+ inputs.append({'timestamp': t, 'message': message})
+ print 'Message # ', i, ' published'
+ return inputs
+
+ @classmethod
+ def setUpClass(cls):
+ print 'Setting up context for Detailed History tests. Please wait ...'
+ cls.starttime = pubnub.time()
+ cls.inputs = cls.inputs + cls.publish_msg(0, cls.total_msg / 2, 0)
+ cls.midtime = pubnub.time()
+ cls.inputs = cls.inputs + cls.publish_msg(
+ 0, cls.total_msg / 2, cls.total_msg / 2)
+ cls.endtime = pubnub.time()
+ print 'Context setup for Detailed History tests. Now running tests'
+
+ def test_begin_to_end_count(self):
+ count = 5
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'start': self.__class__.starttime,
+ 'end': self.__class__.endtime,
+ 'count': count
+ })[0]
+ self.assertTrue(len(history) == count and history[-1].encode(
+ 'utf-8') == self.__class__.inputs[count - 1]['message'])
+
+ def test_end_to_begin_count(self):
+ count = 5
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'start': self.__class__.endtime,
+ 'end': self.__class__.starttime,
+ 'count': count
+ })[0]
+ self.assertTrue(len(history) == count and history[-1]
+ .encode('utf-8') == self.__class__.inputs[-1]['message'])
+
+ def test_start_reverse_true(self):
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'start': self.__class__.midtime,
+ 'reverse': True
+ })[0]
+ self.assertTrue(len(history) == self.__class__.total_msg / 2)
+ expected_msg = self.__class__.inputs[-1]['message']
+ self.assertTrue(history[-1].encode('utf-8') == expected_msg)
+
+ def test_start_reverse_false(self):
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'start': self.__class__.midtime,
+ })[0]
+ self.assertTrue(history[0].encode('utf-8')
+ == self.__class__.inputs[0]['message'])
+
+ def test_end_reverse_true(self):
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'end': self.__class__.midtime,
+ 'reverse': True
+ })[0]
+ self.assertTrue(history[0].encode('utf-8')
+ == self.__class__.inputs[0]['message'])
+
+ def test_end_reverse_false(self):
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'end': self.__class__.midtime,
+ })[0]
+ self.assertTrue(len(history) == self.__class__.total_msg / 2)
+ self.assertTrue(history[-1].encode('utf-8')
+ == self.__class__.inputs[-1]['message'])
+
+ def test_count(self):
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'count': 5
+ })[0]
+ self.assertTrue(len(history) == 5)
+
+ def test_count_zero(self):
+ history = pubnub.detailedHistory({
+ 'channel': self.__class__.channel,
+ 'count': 0
+ })[0]
+ self.assertTrue(len(history) == 0)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/python/3.3/history-example.py b/python/3.3/history-example.py
new file mode 100755
index 0000000..cedf69e
--- /dev/null
+++ b/python/3.3/history-example.py
@@ -0,0 +1,12 @@
+from Pubnub import Pubnub
+
+## Initiat Class
+pubnub = Pubnub( 'demo', 'demo', None, False )
+
+## History Example
+history = pubnub.history({
+ 'channel' : 'hello_world',
+ 'limit' : 1
+})
+print(history)
+
diff --git a/python/3.3/publish-example.py b/python/3.3/publish-example.py
new file mode 100755
index 0000000..725df0b
--- /dev/null
+++ b/python/3.3/publish-example.py
@@ -0,0 +1,14 @@
+from Pubnub import Pubnub
+
+## Initiate Class
+pubnub = Pubnub( 'demo', 'demo', None, False )
+
+## Publish Example
+info = pubnub.publish({
+ 'channel' : 'hello_world',
+ 'message' : {
+ 'some_text' : 'Hello my World'
+ }
+})
+print(info)
+
diff --git a/python/3.3/subscribe-example.py b/python/3.3/subscribe-example.py
new file mode 100755
index 0000000..e458e2b
--- /dev/null
+++ b/python/3.3/subscribe-example.py
@@ -0,0 +1,64 @@
+import sys
+import threading
+import time
+import random
+import string
+from Pubnub import Pubnub
+
+## Initiate Class
+pubnub = Pubnub( 'demo', 'demo', None, False )
+
+print("My UUID is: "+pubnub.uuid)
+
+channel = ''.join(random.choice(string.ascii_letters + string.digits) for x in range(20))
+
+## Subscribe Example
+def receive(message) :
+ print(message)
+ return False
+
+def pres_event(message):
+ print(message)
+ return False
+
+def subscribe():
+ print("Listening for messages on '%s' channel..." % channel)
+ pubnub.subscribe({
+ 'channel' : channel,
+ 'callback' : receive
+ })
+
+def presence():
+ print("Listening for presence events on '%s' channel..." % channel)
+ pubnub.presence({
+ 'channel' : channel,
+ 'callback' : pres_event
+ })
+
+def publish():
+ print("Publishing a test message on '%s' channel..." % channel)
+ pubnub.publish({
+ 'channel' : channel,
+ 'message' : { 'text':'foo bar' }
+ })
+
+pres_thread = threading.Thread(target=presence)
+pres_thread.daemon=True
+pres_thread.start()
+
+sub_thread = threading.Thread(target=subscribe)
+sub_thread.daemon=True
+sub_thread.start()
+
+time.sleep(3)
+
+publish()
+
+
+print("waiting for subscribes and presence")
+pres_thread.join()
+
+print pubnub.here_now({'channel':channel})
+
+sub_thread.join()
+
diff --git a/python/3.3/unit-test.py b/python/3.3/unit-test.py
new file mode 100755
index 0000000..88391a0
--- /dev/null
+++ b/python/3.3/unit-test.py
@@ -0,0 +1,77 @@
+## www.pubnub.com - PubNub Real-time push service in the cloud.
+# coding=utf8
+
+## PubNub Real-time Push APIs and Notifications Framework
+## Copyright (c) 2010 Stephen Blum
+## http://www.pubnub.com/
+
+## -----------------------------------
+## PubNub 3.0 Real-time Push Cloud API
+## -----------------------------------
+
+from Pubnub import Pubnub
+import sys
+
+publish_key = len(sys.argv) > 1 and sys.argv[1] or 'demo'
+subscribe_key = len(sys.argv) > 2 and sys.argv[2] or 'demo'
+secret_key = len(sys.argv) > 3 and sys.argv[3] or None
+ssl_on = len(sys.argv) > 4 and bool(sys.argv[4]) or False
+
+
+## -----------------------------------------------------------------------
+## Initiat Class
+## -----------------------------------------------------------------------
+
+pubnub = Pubnub( publish_key, subscribe_key, secret_key, ssl_on )
+crazy = ' ~`!@#$%^&*(顶顅Ȓ)+=[]\\{}|;\':",./<>?abcd'
+
+## ---------------------------------------------------------------------------
+## Unit Test Function
+## ---------------------------------------------------------------------------
+def test( trial, name ) :
+ if trial :
+ print( 'PASS: ' + name )
+ else :
+ print( 'FAIL: ' + name )
+
+## -----------------------------------------------------------------------
+## Publish Example
+## -----------------------------------------------------------------------
+pubish_success = pubnub.publish({
+ 'channel' : crazy,
+ 'message' : crazy
+})
+test( pubish_success[0] == 1, 'Publish First Message Success' )
+
+## -----------------------------------------------------------------------
+## History Example
+## -----------------------------------------------------------------------
+history = pubnub.history({
+ 'channel' : crazy,
+ 'limit' : 1
+})
+test(
+ history[0].encode('utf-8') == crazy,
+ 'History Message: ' + history[0]
+)
+test( len(history) == 1, 'History Message Count' )
+
+## -----------------------------------------------------------------------
+## PubNub Server Time Example
+## -----------------------------------------------------------------------
+timestamp = pubnub.time()
+test( timestamp > 0, 'PubNub Server Time: ' + str(timestamp) )
+
+## -----------------------------------------------------------------------
+## Subscribe Example
+## -----------------------------------------------------------------------
+def receive(message) :
+ print(message)
+ return True
+
+pubnub.subscribe({
+ 'channel' : crazy,
+ 'callback' : receive
+})
+
+
diff --git a/python/README b/python/README
new file mode 100644
index 0000000..ba65e53
--- /dev/null
+++ b/python/README
@@ -0,0 +1,123 @@
+## ---------------------------------------------------
+##
+## YOU MUST HAVE A PUBNUB ACCOUNT TO USE THE API.
+## http://www.pubnub.com/account
+##
+## ----------------------------------------------------
+
+## --------------------------------------------------
+## PubNub 3.3 Web Data Push Cloud-hosted API - PYTHON
+## --------------------------------------------------
+##
+## www.pubnub.com - PubNub Web Data Push Service in the Cloud.
+## http://github.com/pubnub/pubnub-api/tree/master/python
+##
+## PubNub is a Massively Scalable Data Push Service for Web and Mobile Games.
+## This is a cloud-based service for broadcasting messages
+## to thousands of web and mobile clients simultaneously.
+
+## ---------------
+## Python Push API
+## ---------------
+
+### Check out additional tests and examples in the 3.2 directory!
+
+pubnub = Pubnub(
+ "demo", ## PUBLISH_KEY
+ "demo", ## SUBSCRIBE_KEY
+ None, ## SECRET_KEY
+ False ## SSL_ON?
+)
+
+# -------
+# PUBLISH
+# -------
+# Send Message
+info = pubnub.publish({
+ 'channel' : 'hello_world',
+ 'message' : {
+ 'some_text' : 'Hello my World'
+ }
+})
+print(info)
+
+# ---------
+# SUBSCRIBE
+# ---------
+# Listen for Messages *BLOCKING*
+def receive(message) :
+ print(message)
+ return True
+
+pubnub.subscribe({
+ 'channel' : 'hello_world',
+ 'callback' : receive
+})
+
+# ---------
+# PRESENCE
+# ---------
+# Listen for Presence Event Messages *BLOCKING*
+
+def pres_event(message) :
+ print(message)
+ return True
+
+pubnub.presence({
+ 'channel' : 'hello_world',
+ 'callback' : receive
+})
+
+# ---------
+# HERE_NOW
+# ---------
+# Get info on who is here right now!
+
+here_now = pubnub.here_now({
+ 'channel' : 'hello_world',
+})
+
+print(here_now['occupancy'])
+print(here_now['uuids'])
+
+
+# ------------------
+## Channel Analytics
+# ------------------
+analytics = pubnub.analytics({
+ 'channel' : 'channel-name-here', ## Leave blank for all channels
+ 'limit' : 100, ## aggregation range
+ 'ago' : 0, ## minutes ago to look backward
+ 'duration' : 100 ## minutes offset
+})
+print(analytics)
+
+# -------
+# HISTORY
+# -------
+# Load Previously Published Messages
+history = pubnub.history({
+ 'channel' : 'hello_world',
+ 'limit' : 1
+})
+print(history)
+
+
+# -------
+# DETAILED HISTORY
+# -------
+# Load Previously Published Messages in Detail
+ @param array args with 'channel', optional: 'start', 'end', 'reverse', 'count'
+ 'channel'-Channel name
+ 'start'-Start timestamp
+ 'end'-End timestamp
+ 'reverse'-Order of History
+ 'count'-Number of History messages
+
+ NSInteger count = 3;
+ NSNumber * aCountInt = [NSNumber numberWithInteger:count];
+ [pubnub detailedHistory:[NSDictionary dictionaryWithObjectsAndKeys:
+ aCountInt,@"count",
+ @"hello_world",@"channel",
+ nil]];
+