[Checkins] SVN: z3c.suds/ helper for using suds within a threaded ZODB-based application

David Glick davidglick at onenw.org
Fri Sep 17 18:59:17 EDT 2010


Log message for revision 116543:
  helper for using suds within a threaded ZODB-based application

Changed:
  A   z3c.suds/
  A   z3c.suds/trunk/
  A   z3c.suds/trunk/.installed.cfg
  A   z3c.suds/trunk/CHANGES.txt
  A   z3c.suds/trunk/COPYRIGHT.txt
  A   z3c.suds/trunk/LICENSE.txt
  A   z3c.suds/trunk/README.txt
  A   z3c.suds/trunk/bootstrap.py
  A   z3c.suds/trunk/buildout.cfg
  A   z3c.suds/trunk/setup.py
  A   z3c.suds/trunk/z3c/
  A   z3c.suds/trunk/z3c/__init__.py
  A   z3c.suds/trunk/z3c/suds/
  A   z3c.suds/trunk/z3c/suds/__init__.py
  A   z3c.suds/trunk/z3c/suds/test.wsdl
  A   z3c.suds/trunk/z3c/suds/tests.py

-=-
Added: z3c.suds/trunk/.installed.cfg
===================================================================
--- z3c.suds/trunk/.installed.cfg	                        (rev 0)
+++ z3c.suds/trunk/.installed.cfg	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,26 @@
+[buildout]
+installed_develop_eggs = /Users/davidg/Plone/z3c.suds/develop-eggs/z3c.suds.egg-link
+parts = test
+
+[test]
+__buildout_installed__ = /Users/davidg/Plone/z3c.suds/parts/test
+	/Users/davidg/Plone/z3c.suds/parts/test/site-packages
+	/Users/davidg/Plone/z3c.suds/parts/test/working-directory
+	/Users/davidg/Plone/z3c.suds/bin/test
+__buildout_signature__ = zc.recipe.testrunner-1.4.0-py2.6.egg z3c.recipe.scripts-1.0.1-py2.6.egg setuptools-0.6c12dev_r84273-py2.6.egg zope.testrunner-4.0.0b5-py2.6.egg zc.buildout-1.5.1-py2.6.egg zc.recipe.egg-1.3.2-py2.6.egg zope.interface-3.6.1-py2.6-macosx-10.6-x86_64.egg zope.exceptions-3.6.1-py2.6.egg
+_b = /Users/davidg/Plone/z3c.suds/bin
+_d = /Users/davidg/Plone/z3c.suds/develop-eggs
+_e = /Users/davidg/.buildout/eggs
+allowed-eggs-from-site-packages = *
+bin-directory = /Users/davidg/Plone/z3c.suds/bin
+develop-eggs-directory = /Users/davidg/Plone/z3c.suds/develop-eggs
+eggs = z3c.suds
+eggs-directory = /Users/davidg/.buildout/eggs
+exec-sitecustomize = false
+executable = /opt/local/bin/python2.6
+include-site-packages = false
+location = /Users/davidg/Plone/z3c.suds/parts/test/working-directory
+parts-directory = /Users/davidg/Plone/z3c.suds/parts/test
+python = buildout
+recipe = zc.recipe.testrunner
+script = /Users/davidg/Plone/z3c.suds/bin/test

Added: z3c.suds/trunk/CHANGES.txt
===================================================================
--- z3c.suds/trunk/CHANGES.txt	                        (rev 0)
+++ z3c.suds/trunk/CHANGES.txt	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,7 @@
+Changelog
+=========
+
+1.0 (unreleased)
+----------------
+
+- Initial release

Added: z3c.suds/trunk/COPYRIGHT.txt
===================================================================
--- z3c.suds/trunk/COPYRIGHT.txt	                        (rev 0)
+++ z3c.suds/trunk/COPYRIGHT.txt	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1 @@
+Zope Foundation and Contributors
\ No newline at end of file

Added: z3c.suds/trunk/LICENSE.txt
===================================================================
--- z3c.suds/trunk/LICENSE.txt	                        (rev 0)
+++ z3c.suds/trunk/LICENSE.txt	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,44 @@
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that identifies the
+copyright holders.
+
+This license has been certified as open source. It has also been designated as
+GPL compatible by the Free Software Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions in source code must retain the accompanying copyright
+notice, this list of conditions, and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying copyright
+notice, this list of conditions, and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to endorse or promote
+products derived from this software without prior written permission from the
+copyright holders.
+
+4. The right to distribute this software or to use it for any purpose does not
+give you the right to use Servicemarks (sm) or Trademarks (tm) of the
+copyright
+holders. Use of them is covered by separate agreement with the copyright
+holders.
+
+5. If any files are modified, you must cause the modified files to carry
+prominent notices stating that you changed the files and the date of any
+change.
+
+Disclaimer
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Added: z3c.suds/trunk/README.txt
===================================================================
--- z3c.suds/trunk/README.txt	                        (rev 0)
+++ z3c.suds/trunk/README.txt	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,36 @@
+Introduction
+============
+
+z3c.suds manages a connection pool of `suds`_ client objects in the context of
+a ZODB-based application.  (suds is a lightweight client library for consuming
+SOAP web services in Python.)  Using it avoids the need for instantiating a new
+client for the same webservice in multiple requests (which may be expensive due
+to parsing WSDL, etc.)
+
+.. _`suds`: https://fedorahosted.org/suds/
+
+Usage
+-----
+
+A client may be obtained via the `get_suds_client` method::
+
+  client = get_suds_client(wsdl_uri, context=None)
+
+This returns an existing suds client if one is found in the cache for the given
+WSDL; otherwise it returns a new client object and stores it in the cache.
+
+`wsdl_path` is the URI of the WSDL (web service definition language)
+description of the web service. (Use a file:// URI for a locally stored WSDL.)
+
+`context` is a persistent object (in the ZODB sense). If not provided, the
+`getSite` method of zope.site.hooks will be used to obtain an object (which
+is probably only sensible within the context of a Zopish framework). If the
+context object is associated with a ZODB connection, the client will be cached
+in the connection's `foreign_connections` dictionary. If the context object is
+not yet associated with a ZODB connection, the client will be cached in a
+volatile attribute instead. This approach to piggybacking a pool of connections
+on the ZODB connection pool is based on `alm.solrindex`, and further documented
+there.
+
+.. _`alm.solrindex`: http://pypi.python.org/pypi/alm.solrindex
+

Added: z3c.suds/trunk/bootstrap.py
===================================================================
--- z3c.suds/trunk/bootstrap.py	                        (rev 0)
+++ z3c.suds/trunk/bootstrap.py	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,116 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, urllib2
+from optparse import OptionParser
+
+tmpeggs = tempfile.mkdtemp()
+
+is_jython = sys.platform.startswith('java')
+
+# parsing arguments
+parser = OptionParser()
+parser.add_option("-v", "--version", dest="version",
+                          help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+                   action="store_true", dest="distribute", default=False,
+                   help="Use Disribute rather than Setuptools.")
+
+parser.add_option("-c", None, action="store", dest="config_file",
+                   help=("Specify the path to the buildout configuration "
+                         "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout' main function
+if options.config_file is not None:
+    args += ['-c', options.config_file]
+
+if options.version is not None:
+    VERSION = '==%s' % options.version
+else:
+    VERSION = ''
+
+USE_DISTRIBUTE = options.distribute
+args = args + ['bootstrap']
+
+try:
+    import pkg_resources
+    import setuptools
+    if not hasattr(pkg_resources, '_distribute'):
+        raise ImportError
+except ImportError:
+    ez = {}
+    if USE_DISTRIBUTE:
+        exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py'
+                         ).read() in ez
+        ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
+    else:
+        exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                             ).read() in ez
+        ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+    reload(sys.modules['pkg_resources'])
+    import pkg_resources
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    def quote (c):
+        return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws  = pkg_resources.working_set
+
+if USE_DISTRIBUTE:
+    requirement = 'distribute'
+else:
+    requirement = 'setuptools'
+
+if is_jython:
+    import subprocess
+
+    assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
+           quote(tmpeggs), 'zc.buildout' + VERSION],
+           env=dict(os.environ,
+               PYTHONPATH=
+               ws.find(pkg_resources.Requirement.parse(requirement)).location
+               ),
+           ).wait() == 0
+
+else:
+    assert os.spawnle(
+        os.P_WAIT, sys.executable, quote (sys.executable),
+        '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
+        dict(os.environ,
+            PYTHONPATH=
+            ws.find(pkg_resources.Requirement.parse(requirement)).location
+            ),
+        ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout' + VERSION)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+shutil.rmtree(tmpeggs)

Added: z3c.suds/trunk/buildout.cfg
===================================================================
--- z3c.suds/trunk/buildout.cfg	                        (rev 0)
+++ z3c.suds/trunk/buildout.cfg	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,7 @@
+[buildout]
+parts = test
+develop = .
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.suds

Added: z3c.suds/trunk/setup.py
===================================================================
--- z3c.suds/trunk/setup.py	                        (rev 0)
+++ z3c.suds/trunk/setup.py	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,28 @@
+from setuptools import setup, find_packages
+
+version = '1.0'
+
+setup(name='z3c.suds',
+      version=version,
+      description="Manages a pool of suds SOAP clients within the context of a Zope application",
+      long_description=open("README.txt").read() + "\n" +
+                       open("CHANGES.txt").read(),
+      classifiers=[
+        "Framework :: Plone",
+        "Programming Language :: Python",
+        ],
+      keywords='suds soap zope zodb',
+      author='David Glick, Groundwire',
+      author_email='davidglick at groundwire.org',
+      url='http://svn.zope.org/z3c.suds/trunk',
+      license='ZPL 2.1',
+      packages=find_packages(exclude=['ez_setup']),
+      namespace_packages=['z3c'],
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          'setuptools',
+          'suds',
+          # -*- Extra requirements: -*-
+      ],
+      )

Added: z3c.suds/trunk/z3c/__init__.py
===================================================================
--- z3c.suds/trunk/z3c/__init__.py	                        (rev 0)
+++ z3c.suds/trunk/z3c/__init__.py	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: z3c.suds/trunk/z3c/suds/__init__.py
===================================================================
--- z3c.suds/trunk/z3c/suds/__init__.py	                        (rev 0)
+++ z3c.suds/trunk/z3c/suds/__init__.py	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,39 @@
+from suds.client import Client
+
+try:
+    from zope.site.hooks import getSite
+    _get_default_context = getSite
+except ImportError:
+    try:
+        from zope.app.component.hooks import getSite
+        _get_default_context = getSite
+    except ImportError:
+        _get_default_context = lambda: None
+
+def get_suds_client(wsdl_uri, context=None):
+    if context is None:
+        context = _get_default_context()
+
+    if context is None:
+        # no cache
+        client = Client(wsdl_uri)
+    else:
+        jar = getattr(context, '_p_jar', None)
+        oid = getattr(context, '_p_oid', None)
+        if jar is None or oid is None:
+            # object is not persistent or is not yet associated with a
+            # connection
+            cache = context._v_suds_client_cache = {}
+        else:
+            cache = getattr(jar, 'foreign_connections', None)
+            if cache is None:
+                cache = jar.foreign_connections = {}
+        
+        cache_key = 'suds_%s' % wsdl_uri
+        client = cache.get(cache_key)
+        if client is None:
+            client = cache[cache_key] = Client(wsdl_uri)
+    
+    return client
+
+__all__ = ('get_suds_client',)

Added: z3c.suds/trunk/z3c/suds/test.wsdl
===================================================================
--- z3c.suds/trunk/z3c/suds/test.wsdl	                        (rev 0)
+++ z3c.suds/trunk/z3c/suds/test.wsdl	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>

Added: z3c.suds/trunk/z3c/suds/tests.py
===================================================================
--- z3c.suds/trunk/z3c/suds/tests.py	                        (rev 0)
+++ z3c.suds/trunk/z3c/suds/tests.py	2010-09-17 22:59:16 UTC (rev 116543)
@@ -0,0 +1,49 @@
+import pkg_resources
+import unittest
+
+from z3c.suds import get_suds_client
+
+class Dummy(object):
+    pass
+
+class TestCase(unittest.TestCase):
+
+    def setUp(self):
+        test_wsdl = pkg_resources.resource_filename('z3c.suds', 'test.wsdl')
+        self.test_wsdl = 'file://%s' % test_wsdl
+    
+    def tearDown(self):
+        pkg_resources.cleanup_resources()
+    
+    def test_get_suds_client(self):
+        client = get_suds_client(self.test_wsdl, context=Dummy())
+        self.assertTrue(client)
+    
+    def test_get_suds_client_persistent_context(self):
+        dummy_connection = Dummy()
+        dummy_context = Dummy()
+        dummy_context._p_jar = dummy_connection
+        dummy_context._p_oid = 0
+        
+        get_suds_client(self.test_wsdl, dummy_context)
+        self.assertTrue(hasattr(dummy_connection, 'foreign_connections'))
+        self.assertTrue('suds_%s' % self.test_wsdl in dummy_connection.foreign_connections)
+    
+    def test_get_suds_client_default_context(self):
+        import z3c.suds
+        old_get_default_context = z3c.suds._get_default_context
+        dummy = Dummy()
+        z3c.suds._get_default_context = lambda: dummy
+        
+        get_suds_client(self.test_wsdl)
+        self.assertTrue(hasattr(dummy, '_v_suds_client_cache'))
+        
+        z3c.suds._get_default_context = old_get_default_context
+    
+    def test_get_suds_client_missing_default_context(self):
+        client = get_suds_client(self.test_wsdl)
+        self.assertTrue(client)
+
+def test_suite():
+    import unittest
+    return unittest.defaultTestLoader.loadTestsFromName(__name__)



More information about the checkins mailing list