changeset 22:9459d63c1558

Added full support for Python 3
author Ben Croston <ben@croston.org>
date Sun, 01 Jan 2012 15:50:18 +0000
parents 6df12f09f4f4
children 8c4357842947
files AuthRPC/client/__init__.py AuthRPC/server/__init__.py AuthRPC/tests.py CHANGELOG.txt INSTALL INSTALL.txt LICENCE LICENCE.txt README.txt setup.py
diffstat 10 files changed, 76 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/AuthRPC/client/__init__.py	Sun Jan 01 11:42:25 2012 +0000
+++ b/AuthRPC/client/__init__.py	Sun Jan 01 15:50:18 2012 +0000
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Copyright (c) 2011 Ben Croston
+# Copyright (c) 2011-2012 Ben Croston
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy of
 # this software and associated documentation files (the "Software"), to deal in
@@ -27,18 +27,9 @@
 import copy
 import socket
 import hashlib
-import platform
-
-if platform.python_version().startswith('3'):
-    IS_PY3 = True
-else:
-    IS_PY3 = False
 
 def _encrypt_password(password):
-    if IS_PY3:
-        return hashlib.md5(password.encode()).hexdigest()
-    else:
-        return hashlib.md5(password).hexdigest()
+    return hashlib.md5(password.encode()).hexdigest()
 
 class _Method(object):
     def __init__(self, call, name, username=None, password=None):
@@ -174,15 +165,9 @@
         except socket.error:
             raise NetworkSocketException
         if response.status == 200:
-            if IS_PY3:
-                return json.loads(response.read().decode())
-            else:
-                return json.loads(response.read())
+            return json.loads(response.read().decode())
         elif response.status == 400:
-            if IS_PY3:
-                raise BadRequestException(response.read().decode())
-            else:
-                raise BadRequestException(response.read())
+            raise BadRequestException(response.read().decode())
         elif response.status == 401:
             raise UnauthorisedException
         elif response.status == 403:
--- a/AuthRPC/server/__init__.py	Sun Jan 01 11:42:25 2012 +0000
+++ b/AuthRPC/server/__init__.py	Sun Jan 01 15:50:18 2012 +0000
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Copyright (c) 2011 Ben Croston
+# Copyright (c) 2011-2012 Ben Croston
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy of
 # this software and associated documentation files (the "Software"), to deal in
@@ -42,7 +42,7 @@
         req = Request(environ)
         try:
             resp = self._process(req)
-        except exc.HTTPException, e:
+        except exc.HTTPException as e:
             resp = e
         return resp(environ, start_response)
 
@@ -52,11 +52,11 @@
         req - a webob Request object
         """
         if not req.method == 'POST':
-            raise exc.HTTPMethodNotAllowed("Only POST allowed").exception
+            raise exc.HTTPMethodNotAllowed("Only POST allowed")
 
         try:
-            json = loads(req.body)
-        except ValueError, e:
+             json = loads(req.body.decode())
+        except ValueError as e:
             raise exc.HTTPBadRequest('Bad JSON: %s' % e)
 
         if isinstance(json, list):
@@ -83,14 +83,13 @@
                 id = json['id']
                 method = json['method']
                 params = json['params']
-            except KeyError, e:
+            except KeyError as e:
                 raise exc.HTTPBadRequest("JSON body missing parameter: %s" % e)
             self._check_auth(username, password, req.user_agent, id)
             result = self._process_single(method, params, id)
 
         return Response(content_type='application/json',
-                        body=dumps(result))
-
+                        body=dumps(result).encode())
 
     def _check_auth(self, username, password, user_agent, id=None):
         if self.auth is not None:
@@ -111,7 +110,7 @@
                                     error=error_value,
                                     id=id)))
             if not auth_result:
-                raise exc.HTTPUnauthorized().exception
+                raise exc.HTTPUnauthorized()
 
     def _process_single(self, method, params, id):
         retval = {}
@@ -136,7 +135,7 @@
             return retval
         try:
             method = getattr(obj, method)
-        except AttributeError, e:
+        except AttributeError as e:
             raise exc.HTTPBadRequest(str(e))
 
         try:
--- a/AuthRPC/tests.py	Sun Jan 01 11:42:25 2012 +0000
+++ b/AuthRPC/tests.py	Sun Jan 01 15:50:18 2012 +0000
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Copyright (c) 2011 Ben Croston
+# Copyright (c) 2011-2012 Ben Croston
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy of
 # this software and associated documentation files (the "Software"), to deal in
@@ -28,6 +28,8 @@
 import platform
 import urllib
 
+IS_PY3 = platform.python_version().startswith('3')
+
 try:
     urllib.urlopen('http://www.wyre-it.co.uk/')
     NO_INTERNET = False
@@ -53,7 +55,7 @@
 
 def myauth(username, password, useragent=None):
     return username == 'testuser' and \
-           hashlib.md5('s3cr3t').hexdigest() == password and \
+           password == hashlib.md5('s3cr3t'.encode()).hexdigest() and \
            useragent == 'AuthRPC_unittest'
 
 def make_server():
@@ -131,7 +133,7 @@
 
 class EchoTest(AuthRPCTests):
     def runTest(self):
-        if platform.python_version().startswith('3'):
+        if IS_PY3:
             POUND = '\u00A3'
         else:
             POUND = unicode('\u00A3')
@@ -172,19 +174,24 @@
         batch.api.FunctionDoesNotExist()
         with self.assertRaises(BadRequestException):
             batch()
+
+class SetFinishedFlag(unittest.TestCase):
+    def runTest(self):
+        global finished 
+        finished = True
 ##### client ^^^ #####
 
-finished = False
 def suite():
-    if platform.python_version().startswith('2'):
-        # create server
-        def test_wrapper():
-            server = make_server()
-            while not finished:
-                server.handle_request()
-        thread = Thread(target=test_wrapper)
-        thread.start()
-        time.sleep(0.1) # wait for server thread to start
+    global finished
+    finished = False
+    # create server
+    def test_wrapper():
+        server = make_server()
+        while not finished:
+            server.handle_request()
+    thread = Thread(target=test_wrapper)
+    thread.start()
+    time.sleep(0.1) # wait for server thread to start
 
     # tests are as client
     suite = unittest.TestSuite()
@@ -199,27 +206,11 @@
     suite.addTest(ReturnNothing())
     suite.addTest(ProtocolErrorTest())
     suite.addTest(BatchTest())
+    suite.addTest(SetFinishedFlag())
     suite.addTest(BadBatchTest())
     # btc fixme - test a list/tuple of api classes in another server
     return suite
 
 if __name__ == '__main__':
-    import sys
-    if platform.python_version().startswith('2') and 'serve' in sys.argv:
-        print 'Listening on port 1337 (Ctrl-C qo quit)...'
-        server = make_server()
-        try:
-            server.serve_forever()
-        except KeyboardInterrupt:
-            sys.exit()
+    unittest.TextTestRunner(verbosity=2).run(suite())
 
-    unittest.TextTestRunner(verbosity=2).run(suite())
-    finished = True
-
-    # make a dummy request to get server thread out of loop
-    try:
-       import urllib
-       urllib.urlopen('http://localhost:1337/')
-    except:
-       pass
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGELOG.txt	Sun Jan 01 15:50:18 2012 +0000
@@ -0,0 +1,12 @@
+Change Log
+==========
+
+0.0.2a
+------
+- Added batch requests
+- Added Python 3 support for server
+
+0.0.1a
+------
+- First version
+
--- a/INSTALL	Sun Jan 01 11:42:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-python setup.py install
-  or
-python3 setup.py install
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL.txt	Sun Jan 01 15:50:18 2012 +0000
@@ -0,0 +1,4 @@
+python setup.py install
+  or
+python3 setup.py install
+
--- a/LICENCE	Sun Jan 01 11:42:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-Copyright (c) 2011 Ben Croston
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENCE.txt	Sun Jan 01 15:50:18 2012 +0000
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Ben Croston
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
--- a/README.txt	Sun Jan 01 11:42:25 2012 +0000
+++ b/README.txt	Sun Jan 01 15:50:18 2012 +0000
@@ -1,8 +1,6 @@
 This package provides a service based on JSONRPC with some small additions to the standard in order to enable authenticated requests.  The WSGI specification is used for data communication.  The package is broken down into two halves - a client and a server.  For security, the server is best run over HTTPS, although this is not enforced.
 
-The server depends on WebOb 1.0.0 and above.  This is automatically installed if you have an internet connection, otherwise download and install from http://pypi.python.org/pypi/WebOb
-
-If you install under Python 3, only the client package is available at the moment, until WebOb has been ported to python 3.
+This package depends on WebOb 1.2 (or above).  This is automatically installed if you have an internet connection, otherwise download and install from http://pypi.python.org/pypi/WebOb
 
 Example Usage (Server):
 
--- a/setup.py	Sun Jan 01 11:42:25 2012 +0000
+++ b/setup.py	Sun Jan 01 15:50:18 2012 +0000
@@ -13,27 +13,18 @@
                'Topic :: Software Development',
                'Topic :: Internet :: WWW/HTTP :: WSGI']
 
-install_requires = []
-exclude = []
 extra = {}
-
-if platform.python_version().startswith('2'):
-    # we can build server with python 2
-    install_requires.append('webob>=1.0.0')
-
 if platform.python_version().startswith('3'):
-    # we can't build server with python 3
-    exclude.append('AuthRPC.server')
     extra['use_2to3'] = True
 
 setup(name             = 'AuthRPC',
-      version          = '0.0.2a',
-      packages         = find_packages(exclude=exclude),
-      install_requires = install_requires,
+      version          = '0.1.0a',
+      packages         = find_packages(),
+      install_requires = 'WebOb>=1.2b2',
       author           = 'Ben Croston',
       author_email     = 'ben@croston.org',
       description      = 'A JSONRPC-like client and server with additions to enable authenticated requests',
-      long_description = open('README.txt').read(),
+      long_description = open('README.txt').read() + open('CHANGELOG.txt').read(),
       license          = 'MIT',
       keywords         = 'json, rpc, wsgi, auth',
       url              = 'http://www.wyre-it.co.uk/authrpc/',