├── SOAPpy
├── .cvsignore
├── wstools
│ ├── .cvsignore
│ ├── test
│ │ ├── .cvsignore
│ │ ├── schema.tar.gz
│ │ ├── xmethods.tar.gz
│ │ ├── __init__.py
│ │ ├── test_wstools_net.py
│ │ ├── test_t1.py
│ │ ├── test_wstools.py
│ │ ├── README
│ │ └── test_wsdl.py
│ ├── __init__.py
│ ├── ZPL
│ ├── license.txt
│ ├── XMLname.py
│ ├── MIMEAttachment.py
│ ├── UserTuple.py
│ └── TimeoutSocket.py
├── version.py
├── __init__.py
├── URLopener.py
├── SOAP.py
├── Errors.py
├── NS.py
├── WSDL.py
├── GSIServer.py
├── Utilities.py
├── fpconst.py
└── Config.py
├── bid
├── .cvsignore
├── monitorClient.py
├── inventory.servers
└── inventoryServer.py
├── contrib
├── .cvsignore
└── soap_cli.py
├── tests
├── .cvsignore
├── ZeroLengthArray.py
├── simpleWSDL.py
├── excelTest.py
├── testleak.py
├── GoogleTest.py
├── echoHeader.py
├── whoisTest.py
├── ComplexTypes.py
├── weatherTest.py
├── cardClient.py
├── BabelfishWSDLTest.py
├── Bug1161780.py
├── xmethods.py
├── Bug916265.py
├── alanbushTest.py
├── Bug1356261.py
├── esj_test_server.py
├── largeDataTest.py
├── quoteTest.py
├── Bug1366752.py
├── Bug918216.py
├── newsTest.py
├── TemperatureService.wsdl
├── Bug1936883.py
├── Bug1001646.py
├── Makefile
├── README
├── esj_test_client.py
├── echoClient.py
├── speedTest.py
├── cardServer.py
├── testClient1.py
├── storageTest.py
├── TCtest.py
├── testWSDL.py
└── echoServer.py
├── tools
├── .cvsignore
└── interop2html.py
├── validate
├── .cvsignore
├── server.pem
├── soapware.py
└── silabserver.py
├── TODO
├── docs
├── attrs.txt
├── complexTypes.txt
├── WSDL.txt
├── UsingHeaders.txt
├── MethodParameterNaming.txt
├── GlobusSupport.txt
└── GettingStarted.txt
├── MANIFEST.in
├── zope
├── zope-soap-client.py
├── README
├── zope-2.5.0-soappy.diff
└── zope-2.6.2-soappy.diff
├── setup.py
├── LICENSE
├── SOAPpy.spec
└── README
/SOAPpy/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/bid/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/contrib/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/tests/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/tools/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/validate/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/.cvsignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/SOAPpy/version.py:
--------------------------------------------------------------------------------
1 | __version__="0.12.0"
2 |
3 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/schema.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grangier/python-soappy/master/SOAPpy/wstools/test/schema.tar.gz
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/xmethods.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/grangier/python-soappy/master/SOAPpy/wstools/test/xmethods.tar.gz
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/__init__.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | """wstools.WSDLTools.WSDLReader tests directory."""
3 |
4 | import utils
5 |
6 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/__init__.py:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env python
2 | """WSDL parsing services package for Web Services for Python."""
3 |
4 | ident = "$Id$"
5 |
6 | import WSDLTools
7 | import XMLname
8 | import logging
9 |
10 |
--------------------------------------------------------------------------------
/tests/ZeroLengthArray.py:
--------------------------------------------------------------------------------
1 | import sys
2 | sys.path.insert(1, "..")
3 | from SOAPpy import *
4 |
5 | one = typedArrayType(data=[1],typed=type(1))
6 | tmp = typedArrayType(data=[], typed=type(1))
7 | print buildSOAP( one )
8 | print buildSOAP( tmp )
9 |
--------------------------------------------------------------------------------
/tests/simpleWSDL.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | sys.path.insert(1, "..")
4 | import SOAPpy
5 |
6 | url = 'http://www.xmethods.org/sd/2001/TemperatureService.wsdl'
7 | zip = '06340'
8 | proxy = SOAPpy.WSDL.Proxy(url)
9 | temp = proxy.getTemp(zip)
10 | print 'Temperature at', zip, 'is', temp
11 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | # $Id$
2 |
3 | - figure out why parsing rules are broken
4 |
5 | - generate a test harness that will run all of the test code.
6 |
7 | - create unit-tests for all features, as well as for reported bugs.
8 |
9 | - write better documentation (!!!)
10 | - topics: WSDL, Globus, Authentication, ...
11 | - general introduction article
12 | - ...
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SOAPpy/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | ident = '$Id$'
3 | from version import __version__
4 |
5 | from Client import *
6 | from Config import *
7 | from Errors import *
8 | from NS import *
9 | from Parser import *
10 | from SOAPBuilder import *
11 | from Server import *
12 | from Types import *
13 | from Utilities import *
14 | import wstools
15 | import WSDL
16 |
--------------------------------------------------------------------------------
/tests/excelTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | sys.path.insert(1, "..")
5 |
6 | from SOAPpy import *
7 | server = SOAPProxy("http://206.135.217.234:8000/")
8 | server.COM_SetProperty("Visible", 1)
9 | server.Workbooks.Open("c:\\test.xls")
10 | server.COM_NestedCall('ActiveSheet.Range("A2").EntireRow.Delete()')
11 | server.quit()
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/docs/attrs.txt:
--------------------------------------------------------------------------------
1 |
2 | Using SOAPpy Attributes
3 | =======================
4 |
5 | All SOAPpy data classes implement methods to access and mutate
6 | individual attributes.
7 |
8 | The _setAttr method has as parameters a 'tag', the attribute name, and the
9 | value to which the attribute should be set.
10 |
11 | The _getAttrs method simply has the 'tag' parameter.
12 |
13 |
14 |
15 | $Id$
16 |
--------------------------------------------------------------------------------
/contrib/soap_cli.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import time
4 | from SOAPpy import SOAP
5 |
6 | srv = SOAP.SOAPProxy('http://localhost:10080/')
7 |
8 | for p in ('good param', 'ok param'):
9 | ret = srv.badparam(p)
10 | if isinstance(ret, SOAP.faultType):
11 | print ret
12 | else:
13 | print 'ok'
14 |
15 | dt = SOAP.dateTimeType(time.localtime(time.time()))
16 | print srv.dt(dt)
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tests/testleak.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import sys
4 | sys.path.insert(1, "..")
5 | import SOAPpy
6 | import time
7 | import gc
8 | import types
9 |
10 | gc.set_debug(gc.DEBUG_SAVEALL)
11 |
12 | for i in range(400):
13 | try:
14 | t = SOAPpy.SOAP.parseSOAPRPC('bad soap payload')
15 | except: pass
16 |
17 | gc.collect()
18 | if len(gc.garbage):
19 | print 'still leaking'
20 | else:
21 | print 'no leak'
22 |
--------------------------------------------------------------------------------
/tests/GoogleTest.py:
--------------------------------------------------------------------------------
1 | from SOAPpy import WSDL
2 | server = WSDL.Proxy('/home/warneg/src/google/googleapi/GoogleSearch.wsdl')
3 | key = "6k0oDPZQFHL0zpjy6ZO6ufUVFKBgvqTo"
4 |
5 | results = server.doGoogleSearch(key, 'warnes', 0, 10, False, "",
6 | False, "", "utf-8", "utf-8")
7 |
8 |
9 | for i in range(len(results.resultElements)):
10 | res = results.resultElements[i]
11 | print '%d: %s --> %s' % ( i, res.title, res.URL )
12 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README*
2 | include LICENSE
3 | include RELEASE_INFO
4 | include TODO
5 | include ChangeLog
6 | recursive-include SOAPpy *.py
7 | recursive-include bid *.py
8 | recursive-include contrib *.py
9 | recursive-include docs *.txt
10 | recursive-include tests *.py
11 | recursive-include tests *.wsdl
12 | recursive-include tools *.py
13 | recursive-include validate *.py
14 | include validate/server.pem
15 | include validate/silab.servers
16 |
--------------------------------------------------------------------------------
/zope/zope-soap-client.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 | from SOAPpy import SOAP
5 |
6 | # Uncomment to see outgoing HTTP headers and SOAP and incoming SOAP.
7 | SOAP.Config.debug = 1
8 |
9 | SOAP.Config.BuildWithNoType = 0
10 | SOAP.Config.BuildWithNoNamespacePrefix = 0
11 |
12 | if len(sys.argv) > 1 and sys.argv[1] == '-s':
13 | server = SOAP.SOAPProxy("https://localhost:8080")
14 | else:
15 | server = SOAP.SOAPProxy("http://admin:pw3340@localhost:8080/",encoding=None)
16 |
17 | x = server.sopa()
18 | print x
19 |
--------------------------------------------------------------------------------
/tests/echoHeader.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | import sys
6 | sys.path.insert(1, "..")
7 |
8 | from SOAPpy import *
9 |
10 | # Uncomment to see outgoing HTTP headers and SOAP and incoming
11 | #Config.debug = 1
12 |
13 | Config.BuildWithNoType = 1
14 | Config.BuildWithNoNamespacePrefix = 1
15 |
16 |
17 |
18 | hd = headerType(data = {"mystring": "Hello World"})
19 | server = SOAPProxy("http://localhost:9900/", header=hd)
20 |
21 | print server.echo("Hello world")
22 |
23 | server.quit()
24 |
--------------------------------------------------------------------------------
/SOAPpy/URLopener.py:
--------------------------------------------------------------------------------
1 | """Provide a class for loading data from URL's that handles basic
2 | authentication"""
3 |
4 | ident = '$Id$'
5 | from version import __version__
6 |
7 | from Config import Config
8 | from urllib import FancyURLopener
9 |
10 | class URLopener(FancyURLopener):
11 |
12 | username = None
13 | passwd = None
14 |
15 |
16 | def __init__(self, username=None, passwd=None, *args, **kw):
17 | FancyURLopener.__init__( self, *args, **kw)
18 | self.username = username
19 | self.passwd = passwd
20 |
21 |
22 | def prompt_user_passwd(self, host, realm):
23 | return self.username, self.passwd
24 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/test_wstools_net.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ############################################################################
4 | # Joshua R. Boverhof, David W. Robertson, LBNL
5 | # See LBNLCopyright for copyright notice!
6 | ###########################################################################
7 | import unittest
8 | import test_wsdl
9 |
10 | def makeTestSuite():
11 | suite = unittest.TestSuite()
12 | suite.addTest(test_wsdl.makeTestSuite("services_by_http"))
13 | return suite
14 |
15 | def main():
16 | unittest.main(defaultTest="makeTestSuite")
17 |
18 | if __name__ == "__main__" : main()
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/test_t1.py:
--------------------------------------------------------------------------------
1 | ############################################################################
2 | # Joshua R. Boverhof, David W. Robertson, LBNL
3 | # See LBNLCopyright for copyright notice!
4 | ###########################################################################
5 | import unittest
6 | import test_wsdl
7 | import utils
8 |
9 | def makeTestSuite():
10 | suite = unittest.TestSuite()
11 | suite.addTest(test_wsdl.makeTestSuite("services_by_file"))
12 | return suite
13 |
14 | def main():
15 | loader = utils.MatchTestLoader(True, None, "makeTestSuite")
16 | unittest.main(defaultTest="makeTestSuite", testLoader=loader)
17 |
18 | if __name__ == "__main__" : main()
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/complexTypes.txt:
--------------------------------------------------------------------------------
1 | COMPLEX TYPES HOWTO
2 | ===================
3 |
4 | The easiest way (at the moment) to create complex SOAP typs is to
5 | use the SOAPpy.structType class, which allows you to create an
6 | object with named arguments of arbitraty types. For example:
7 |
8 | >>> in0 = SOAPpy.structType()
9 | >>> in0._addItem('outwardDate', dep)
10 | >>> in0._addItem('returnDate', ret)
11 | >>> in0._addItem('originAirport', 'den')
12 | >>> in0._addItem('destinationAirport', 'iad')
13 |
14 | SOAPpy has code for declaring structured object templates including
15 | the type for each component, but this broke sometime in the past and
16 | has not yet been corrected. (See tests/TCtypes.py to see how it
17 | should work.)
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tests/whoisTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id$'
4 |
5 | import os, re
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | from SOAPpy import SOAPProxy
10 |
11 | # Check for a web proxy definition in environment
12 | try:
13 | proxy_url=os.environ['http_proxy']
14 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
15 | proxy = "%s:%s" % (phost, pport)
16 | except:
17 | proxy = None
18 |
19 | server = SOAPProxy("http://www.SoapClient.com/xml/SQLDataSoap.WSDL",
20 | http_proxy=proxy)
21 |
22 | print "whois>>", server.ProcessSRL(SRLFile="WHOIS.SRI",
23 | RequestName="whois",
24 | key = "microsoft.com")
25 |
26 |
--------------------------------------------------------------------------------
/tests/ComplexTypes.py:
--------------------------------------------------------------------------------
1 | import sys
2 | sys.path.insert(1, "..")
3 |
4 | import SOAPpy
5 |
6 | import time
7 | dep = SOAPpy.dateTimeType((2004, 3, 24, 12, 30, 59, 4, 86, 0))
8 | ret = SOAPpy.dateTimeType((2004, 3, 26, 12, 30, 59, 4, 86, 0))
9 |
10 | in0 = SOAPpy.structType()
11 | in0._addItem('outwardDate', dep)
12 | in0._addItem('returnDate', ret)
13 | in0._addItem('originAirport', 'den')
14 | in0._addItem('destinationAirport', 'iad')
15 |
16 |
17 | x = SOAPpy.buildSOAP(
18 | in0,
19 | method="getAirFareQuote",
20 | namespace="urn:SBGAirFareQuotes.sbg.travel.ws.dsdata.co.uk"
21 | )
22 |
23 |
24 | wsdl = 'http://www.xmethods.net/sd/2001/TemperatureService.wsdl'
25 | proxy = SOAPpy.WSDL.Proxy(wsdl)
26 |
27 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # $Id$
4 |
5 | CVS=0
6 |
7 | from distutils.core import setup, Command, Extension
8 | from SOAPpy.version import __version__
9 |
10 | url="http://pywebsvcs.sf.net/"
11 |
12 | long_description="SOAPpy provides tools for building SOAP clients and servers. For more information see " + url
13 |
14 |
15 | if CVS:
16 | import time
17 | __version__ += "_CVS_" + time.strftime('%Y_%m_%d')
18 |
19 |
20 | setup(name="SOAPpy",
21 | version=__version__,
22 | description="SOAP Services for Python",
23 | maintainer="Gregory Warnes",
24 | maintainer_email="Gregory.R.Warnes@Pfizer.com",
25 | url = url,
26 | long_description=long_description,
27 | packages=['SOAPpy','SOAPpy/wstools']
28 | )
29 |
30 |
--------------------------------------------------------------------------------
/tests/weatherTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id$'
4 |
5 | import os, re
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | from SOAPpy import SOAPProxy
10 |
11 | # Check for a web proxy definition in environment
12 | try:
13 | proxy_url=os.environ['http_proxy']
14 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
15 | proxy = "%s:%s" % (phost, pport)
16 | except:
17 | proxy = None
18 |
19 | SoapEndpointURL = 'http://services.xmethods.net:80/soap/servlet/rpcrouter'
20 | MethodNamespaceURI = 'urn:xmethods-Temperature'
21 |
22 | # Do it inline ala SOAP::LITE, also specify the actually ns
23 |
24 | server = SOAPProxy(SoapEndpointURL, http_proxy=proxy)
25 | print "inline", server._ns('ns1', MethodNamespaceURI).getTemp(zipcode='94063')
26 |
--------------------------------------------------------------------------------
/docs/WSDL.txt:
--------------------------------------------------------------------------------
1 |
2 | WSDL NOTES:
3 |
4 | Release 0.9.9 and later include logic for dealing with web service
5 | description language (WSDL) files.
6 |
7 | - SOAPpy.WSDL provides a SOAP Proxy object that parses a WSDL file
8 | and provides access to the listed services:
9 |
10 | url = 'http://www.xmethods.org/sd/2001/TemperatureService.wsdl'
11 | zip = '01072'
12 | proxy = SOAPpy.WSDL.Proxy(url)
13 | temp = proxy.getTemp(zip)
14 | print 'Temperature at', zip, 'is', temp
15 |
16 | - On the server, you can allow the client to download the WSDL for
17 | a service by sending a request of the form by adding a do_GET
18 | method to the SOAPRequestHandler. [Not yet working when
19 | debug=FALSE. Add example here when working]
20 |
21 |
22 | $Id$
23 |
--------------------------------------------------------------------------------
/tests/cardClient.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | import sys
6 |
7 | sys.path.insert (1, '..')
8 |
9 | from SOAPpy import *
10 |
11 | ident = '$Id$'
12 |
13 | endpoint = "http://localhost:12027/xmethodsInterop"
14 | sa = "urn:soapinterop"
15 | ns = "http://soapinterop.org/"
16 |
17 | serv = SOAPProxy(endpoint, namespace=ns, soapaction=sa)
18 | try: hand = serv.dealHand(NumberOfCards = 13, StringSeparator = '\n')
19 | except: print "no dealHand"; hand = 0
20 | try: sortedhand = serv.dealArrangedHand(NumberOfCards=13,StringSeparator='\n')
21 | except: print "no sorted"; sortedhand = 0
22 | try: card = serv.dealCard()
23 | except: print "no card"; card = 0
24 |
25 | print "*****hand****\n",hand,"\n*********"
26 | print "******sortedhand*****\n",sortedhand,"\n*********"
27 | print "card:",card
28 |
29 | serv.quit()
30 |
31 |
--------------------------------------------------------------------------------
/SOAPpy/SOAP.py:
--------------------------------------------------------------------------------
1 | """This file is here for backward compatibility with versions <= 0.9.9
2 |
3 | Delete when 1.0.0 is released!
4 | """
5 |
6 | ident = '$Id$'
7 | from version import __version__
8 |
9 | from Client import *
10 | from Config import *
11 | from Errors import *
12 | from NS import *
13 | from Parser import *
14 | from SOAPBuilder import *
15 | from Server import *
16 | from Types import *
17 | from Utilities import *
18 | import wstools
19 | import WSDL
20 |
21 | from warnings import warn
22 |
23 | warn("""
24 |
25 | The sub-module SOAPpy.SOAP is deprecated and is only
26 | provided for short-term backward compatibility. Objects are now
27 | available directly within the SOAPpy module. Thus, instead of
28 |
29 | from SOAPpy import SOAP
30 | ...
31 | SOAP.SOAPProxy(...)
32 |
33 | use
34 |
35 | from SOAPpy import SOAPProxy
36 | ...
37 | SOAPProxy(...)
38 |
39 | instead.
40 | """, DeprecationWarning)
41 |
--------------------------------------------------------------------------------
/tests/BabelfishWSDLTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id$'
4 |
5 | import os, re
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | from SOAPpy import WSDL
10 |
11 | # Check for a web proxy definition in environment
12 | try:
13 | proxy_url=os.environ['http_proxy']
14 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
15 | proxy = "%s:%s" % (phost, pport)
16 | except:
17 | proxy = None
18 |
19 | server = WSDL.Proxy('http://www.xmethods.net/sd/2001/BabelFishService.wsdl',
20 | http_proxy=proxy)
21 |
22 | english = "Hi Friend!"
23 |
24 | print "Babelfish Translations"
25 | print "------------------------"
26 | print "English: '%s'" % english
27 | print "French: '%s'" % server.BabelFish('en_fr',english)
28 | print "Spanish: '%s'" % server.BabelFish('en_es',english)
29 | print "Italian: '%s'" % server.BabelFish('en_it',english)
30 | print "German: '%s'" % server.BabelFish('en_de',english)
31 |
32 | print "Done."
33 |
--------------------------------------------------------------------------------
/tests/Bug1161780.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | sys.path.insert(1, "..")
4 | from SOAPpy.Errors import Error
5 | from SOAPpy.Parser import parseSOAPRPC
6 |
7 | original = """
8 |
12 |
13 |
14 |
15 |
16 | The CustomerID tag could not be found or the number contained in the tag was invalid
17 |
18 | """
19 |
20 | try:
21 | parseSOAPRPC(original, attrs = 1)
22 | except Error, e:
23 | if e.msg != "expected nothing, got `ErrorString'":
24 | raise AssertionError, "Incorrect error message generated: " + e.msg
25 | else:
26 | raise AssertionError, "Incorrect error message generated"
27 |
28 | print "Success"
29 |
--------------------------------------------------------------------------------
/tests/xmethods.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 | ident = '$Id$'
5 |
6 | import os, re
7 | import sys
8 | sys.path.insert(1, "..")
9 |
10 | from SOAPpy import SOAPProxy
11 |
12 | # Check for a web proxy definition in environment
13 | try:
14 | proxy_url=os.environ['http_proxy']
15 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
16 | proxy = "%s:%s" % (phost, pport)
17 | except:
18 | proxy = None
19 |
20 |
21 | print "##########################################"
22 | print " SOAP services registered at xmethods.net"
23 | print "##########################################"
24 |
25 | server = SOAPProxy("http://www.xmethods.net/interfaces/query",
26 | namespace = 'urn:xmethods-delayed-quotes',
27 | http_proxy=proxy)
28 |
29 | names = server.getAllServiceNames()
30 |
31 | for item in names:
32 | print 'name:', item['name']
33 | print 'id :', item['id']
34 | print
35 |
--------------------------------------------------------------------------------
/tests/Bug916265.py:
--------------------------------------------------------------------------------
1 | """
2 | Check handing of unicode.
3 | """
4 |
5 | import sys
6 | sys.path.insert(1, "..")
7 | from SOAPpy import *
8 |
9 | # Uncomment to see outgoing HTTP headers and SOAP and incoming
10 | #Config.debug = 1
11 | #Config.dumpHeadersIn = 1
12 | #Config.dumpSOAPIn = 1
13 | #Config.dumpSOAPOut = 1
14 |
15 | # ask for returned SOAP responses to be converted to basic python types
16 | Config.simplify_objects = 0
17 |
18 | #Config.BuildWithNoType = 1
19 | #Config.BuildWithNoNamespacePrefix = 1
20 |
21 | server = SOAPProxy("http://localhost:9900/")
22 |
23 | x = u'uMOO' # Single unicode string
24 | y = server.echo_simple((x,))
25 | assert( x==y[0] )
26 |
27 | x = [u'uMoo1',u'uMoo2'] # array of unicode strings
28 | y = server.echo_simple(x)
29 | assert( x[0] == y[0] )
30 | assert( x[1] == y[1] )
31 |
32 | x = {
33 | u'A':1,
34 | u'B':u'B',
35 | 'C':u'C',
36 | 'D':'D'
37 | }
38 | y = server.echo_simple(x)
39 |
40 | for key in x.keys():
41 | assert( x[key] == y[0][key] )
42 |
43 | print "Success"
44 |
--------------------------------------------------------------------------------
/tests/alanbushTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | ident = '$Id$'
6 |
7 | import os, re,sys
8 |
9 | # add local SOAPpy code to search path
10 | sys.path.insert(1, "..")
11 |
12 | from SOAPpy import *
13 | Config.debug=0
14 |
15 | # Check for a web proxy definition in environment
16 | try:
17 | proxy_url=os.environ['http_proxy']
18 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
19 | proxy = "%s:%s" % (phost, pport)
20 | except:
21 | proxy = None
22 |
23 | SoapEndpointURL = 'http://www.alanbushtrust.org.uk/soap/compositions.asp'
24 | MethodNamespaceURI = 'urn:alanbushtrust-org-uk:soap.methods'
25 | SoapAction = MethodNamespaceURI + ".GetCategories"
26 |
27 | server = SOAPProxy(SoapEndpointURL,
28 | namespace=MethodNamespaceURI,
29 | soapaction=SoapAction,
30 | http_proxy=proxy
31 | )
32 |
33 | for category in server.GetCategories():
34 | print category
35 |
--------------------------------------------------------------------------------
/zope/README:
--------------------------------------------------------------------------------
1 | Using SOAP with ZOPE
2 | --------------------
3 |
4 | We can use Zope to provide web services. The first is to support SOAP like
5 | XML-RPC. There are two patches for Zope 2.5.0 version and for Zope 2.6.2
6 | version. To apply the path, you only need to do:
7 |
8 | $ cd
9 | $ patch -p1 < //zope-2.6.2-soappy.diff
10 |
11 | You need to install SOAPpy and fpconst. You can download this two packages
12 | from here:
13 |
14 | http://sourceforge.net/projects/pywebsvcs
15 | http://software.biostat.washington.edu/statsoft/snake/fpconst/
16 |
17 | If you are using the precompiled version of Zope, you need to add the path
18 | to the PYTHONPATH environment variable to specify where this packages
19 | lives.
20 | To do this, add a line like this to your start script:
21 |
22 | export PYTHONPATH=$PYTHONPATH:/usr/lib/python2.3/site-packages/
23 |
24 | Note: This can be dangerous because in your machine you are using several
25 | versions of python.
26 |
27 | [NB: The contents of this directory contributed by Antonio Beamud
28 | Montero ]
29 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/test_wstools.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ############################################################################
4 | # Joshua R. Boverhof, David W. Robertson, LBNL
5 | # See LBNLCopyright for copyright notice!
6 | ###########################################################################
7 |
8 | import unittest, tarfile, os, ConfigParser
9 | import test_wsdl
10 |
11 |
12 | SECTION='files'
13 | CONFIG_FILE = 'config.txt'
14 |
15 | def extractFiles(section, option):
16 | config = ConfigParser.ConfigParser()
17 | config.read(CONFIG_FILE)
18 | archives = config.get(section, option)
19 | archives = eval(archives)
20 | for file in archives:
21 | tar = tarfile.open(file)
22 | if not os.access(tar.membernames[0], os.R_OK):
23 | for i in tar.getnames():
24 | tar.extract(i)
25 |
26 | def makeTestSuite():
27 | suite = unittest.TestSuite()
28 | suite.addTest(test_wsdl.makeTestSuite("services_by_file"))
29 | return suite
30 |
31 | def main():
32 | extractFiles(SECTION, 'archives')
33 | unittest.main(defaultTest="makeTestSuite")
34 |
35 | if __name__ == "__main__" : main()
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/Bug1356261.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id: SOAPtest.py,v 1.19 2004/04/01 13:25:46 warnes Exp $'
4 |
5 | import urllib
6 | import sys
7 | import unittest
8 | import re
9 |
10 | sys.path.insert(1, "..")
11 | from SOAPpy import *
12 | config=Config
13 | config.strict_range=1
14 |
15 |
16 | class SOAPTestCase(unittest.TestCase):
17 | def testAttributes(self):
18 | x = '''
19 |
20 |
21 |
22 |
23 |
24 | My Life and Work
25 |
26 |
27 | Henry Ford
28 | 49
29 | 5.5
30 |
31 |
32 |
33 |
34 |
35 | '''
36 | # parse rules
37 | y = parseSOAPRPC(x)
38 | self.assertEquals(y.Result.Book.title._attrs[(None, 'some_attr')], 'some_value');
39 |
40 | if __name__ == '__main__':
41 | unittest.main()
42 |
--------------------------------------------------------------------------------
/tests/esj_test_server.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | #standard imports
4 | import syslog, sys
5 |
6 | #domain specific imports
7 | sys.path.insert (1, '..')
8 | import SOAPpy
9 |
10 | class test_service:
11 |
12 | run = 1
13 |
14 | def test_integer(self,pass_integer):
15 | print type(pass_integer)
16 | return pass_integer
17 |
18 | def test_string(self,pass_string):
19 | print type(pass_string)
20 | return pass_string
21 |
22 | def test_float(self,pass_float):
23 | print type(pass_float)
24 | return pass_float
25 |
26 | def test_tuple(self,pass_tuple):
27 | print type(pass_tuple), pass_tuple
28 | return pass_tuple
29 |
30 | def test_list(self,pass_list):
31 | print type(pass_list), pass_list
32 | return pass_list
33 |
34 | def test_dictionary(self,pass_dictionary):
35 | print type(pass_dictionary), pass_dictionary
36 | return pass_dictionary
37 |
38 | def quit(self):
39 | self.run = 0
40 |
41 | server = SOAPpy.SOAPServer(("localhost",9999))
42 | SOAPpy.Config.simplify_objects=1
43 |
44 | access_object = test_service()
45 | server.registerObject(access_object)
46 |
47 | while access_object.run:
48 | server.handle_request()
49 |
--------------------------------------------------------------------------------
/tests/largeDataTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | import sys
6 | sys.path.insert(1, "..")
7 |
8 | from SOAPpy import *
9 | from SOAPpy import Parser
10 |
11 | # Uncomment to see outgoing HTTP headers and SOAP and incoming
12 | #Config.debug = 1
13 |
14 | if len(sys.argv) > 1 and sys.argv[1] == '-s':
15 | server = SOAPProxy("https://localhost:9900")
16 | else:
17 | server = SOAPProxy("http://localhost:9900")
18 |
19 |
20 | # BIG data:
21 |
22 | big = repr('.' * (1<<18) )
23 |
24 | # ...in an object
25 | print "server.echo_ino(big):..",
26 | tmp = server.echo_ino(big)
27 | print "done"
28 |
29 | # ...in an object in an object
30 | print "server.prop.echo2(big)..",
31 | tmp = server.prop.echo2(big)
32 | print "done"
33 |
34 | # ...with keyword arguments
35 | print 'server.echo_wkw(third = big, first = "one", second = "two")..',
36 | tmp = server.echo_wkw(third = big, first = "one", second = "two")
37 | print "done"
38 |
39 | # ...with a context object
40 | print "server.echo_wc(big)..",
41 | tmp = server.echo_wc(big)
42 | print "done"
43 |
44 | # ...with a header
45 | hd = headerType(data = {"mystring": "Hello World"})
46 | print "server._hd(hd).echo_wc(big)..",
47 | tmp = server._hd(hd).echo_wc(big)
48 | print "done"
49 |
50 | server.quit()
51 |
--------------------------------------------------------------------------------
/tests/quoteTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 | ident = '$Id$'
5 |
6 | import os, re
7 | import sys
8 | sys.path.insert(1, "..")
9 |
10 | from SOAPpy import SOAPProxy
11 |
12 | # Check for a web proxy definition in environment
13 | try:
14 | proxy_url=os.environ['http_proxy']
15 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
16 | proxy = "%s:%s" % (phost, pport)
17 | except:
18 | proxy = None
19 |
20 | # Three ways to do namespaces, force it at the server level
21 |
22 | server = SOAPProxy("http://services.xmethods.com:9090/soap",
23 | namespace = 'urn:xmethods-delayed-quotes',
24 | http_proxy=proxy)
25 |
26 | print "IBM>>", server.getQuote(symbol = 'IBM')
27 |
28 | # Do it inline ala SOAP::LITE, also specify the actually ns
29 |
30 | server = SOAPProxy("http://services.xmethods.com:9090/soap",
31 | http_proxy=proxy)
32 | print "IBM>>", server._ns('ns1',
33 | 'urn:xmethods-delayed-quotes').getQuote(symbol = 'IBM')
34 |
35 | # Create a namespaced version of your server
36 |
37 | dq = server._ns('urn:xmethods-delayed-quotes')
38 | print "IBM>>", dq.getQuote(symbol='IBM')
39 | print "ORCL>>", dq.getQuote(symbol='ORCL')
40 | print "INTC>>", dq.getQuote(symbol='INTC')
41 |
--------------------------------------------------------------------------------
/bid/monitorClient.py:
--------------------------------------------------------------------------------
1 | from SOAPpy import SOAP
2 | import sys
3 | import getopt
4 |
5 |
6 | def usage():
7 | print """usage: %s [options]
8 | -m, --method=METHOD#[,METHOD#...] specify METHOD# of ? for the list
9 | -p, --port=PORT# allows to specify PORT# of server
10 | """
11 | sys.exit(1)
12 |
13 | def methodUsage():
14 | print "The available methods are:"
15 | print "1. Monitor \t\t2. Clear"
16 | sys.exit(0)
17 |
18 |
19 | port = 12080
20 | methodnum = 1
21 |
22 | try:
23 | opts, args = getopt.getopt (sys.argv[1:], 'p:m:', ['method','port'])
24 | for opt, arg in opts:
25 | if opt in ('-m','--method'):
26 | if arg == '?':
27 | methodUsage()
28 | methodnum = int(arg)
29 | elif opt in ('-p', '--port'):
30 | port = int(arg)
31 | else:
32 | raise AttributeError, "Recognized but unimpl option '%s'" % opt
33 | except SystemExit:
34 | raise
35 | except:
36 | usage ()
37 |
38 | ep = "http://208.177.157.221:%d/xmethodsInterop" % (port)
39 | sa = "urn:soapinterop"
40 | ns = "http://www.soapinterop.org/Bid"
41 |
42 | serv = SOAP.SOAPProxy(ep, namespace =ns, soapaction = sa)
43 | if methodnum == 1:
44 | print serv.Monitor(str="actzero")
45 | elif methodnum == 2:
46 | print serv.Clear(str="actzero")
47 | else:
48 | print "invalid methodnum"
49 | methodUsage()
50 |
51 |
--------------------------------------------------------------------------------
/tests/Bug1366752.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id: speedTest.py 243 2003-05-21 14:52:37Z warnes $'
4 |
5 | import time
6 | import sys
7 | from SOAPpy import fpconst
8 | sys.path.insert(1, "..")
9 |
10 | from SOAPpy import parseSOAP, parseSOAPRPC
11 |
12 | env = '''
13 |
14 | %s
15 | '''
16 |
17 | xml = env % '''
18 |
19 | <_1 SOAP-ENC:arrayType="xsd:double[2]" xsi:type="SOAP-ENC:Array">
20 | - 3.3
21 | - 4.4
22 | - NaN
23 | - Inf
24 | - +Inf
25 | - Infinity
26 | - +Infinity
27 | - -Inf
28 | - -Infinity
29 |
30 |
31 | '''
32 |
33 |
34 | x = parseSOAPRPC(xml)['_1']
35 |
36 | assert( x[0:2] == [ 3.3, 4.4 ] )
37 | assert( fpconst.isNaN( x[2] ) )
38 | assert( fpconst.isPosInf( x[3] ) )
39 | assert( fpconst.isPosInf( x[4] ) )
40 | assert( fpconst.isPosInf( x[5] ) )
41 | assert( fpconst.isPosInf( x[6] ) )
42 | assert( fpconst.isNegInf( x[7] ) )
43 | assert( fpconst.isNegInf( x[8] ) )
44 |
45 | print "Success"
46 |
47 |
--------------------------------------------------------------------------------
/tests/Bug918216.py:
--------------------------------------------------------------------------------
1 | import sys
2 | sys.path.insert(1, "..")
3 | from SOAPpy import *
4 |
5 | detailed_fault = \
6 | """
7 |
8 |
9 |
10 |
11 |
12 | soapenv:Server.generalException
13 | Exception thrown on Server
14 |
15 |
16 |
17 | ...
18 |
19 |
20 |
21 |
22 |
23 | Login failure (504):Unknown User
24 | ...
25 | ...
26 | ...
27 | ...
28 |
29 |
30 |
31 |
32 | """
33 |
34 | z = parseSOAPRPC(detailed_fault.strip() )
35 | assert(z.__class__==faultType)
36 | assert(z.faultstring=="Exception thrown on Server")
37 | assert(z.detail.loginFailureFault.description=='Login failure (504):Unknown User')
38 | print "Success"
39 |
--------------------------------------------------------------------------------
/tests/newsTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id$'
4 |
5 | import os, re
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | from SOAPpy import SOAPProxy
10 |
11 | # Check for a web proxy definition in environment
12 | try:
13 | proxy_url=os.environ['http_proxy']
14 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
15 | proxy = "%s:%s" % (phost, pport)
16 | except:
17 | proxy = None
18 |
19 | SoapEndpointURL = 'http://www22.brinkster.com/prasads/BreakingNewsService.asmx?WSDL'
20 |
21 | MethodNamespaceURI = 'http://tempuri.org/'
22 |
23 | # Three ways to do namespaces, force it at the server level
24 |
25 | server = SOAPProxy(SoapEndpointURL, namespace = MethodNamespaceURI,
26 | soapaction='http://tempuri.org/GetCNNNews', encoding = None,
27 | http_proxy=proxy)
28 | print "[server level CNN News call]"
29 | print server.GetCNNNews()
30 |
31 | # Do it inline ala SOAP::LITE, also specify the actually ns (namespace) and
32 | # sa (soapaction)
33 |
34 | server = SOAPProxy(SoapEndpointURL, encoding = None)
35 | print "[inline CNNNews call]"
36 | print server._ns('ns1',
37 | MethodNamespaceURI)._sa('http://tempuri.org/GetCNNNews').GetCNNNews()
38 |
39 | # Create an instance of your server with specific namespace and then use
40 | # inline soapactions for each call
41 |
42 | dq = server._ns(MethodNamespaceURI)
43 | print "[namespaced CNNNews call]"
44 | print dq._sa('http://tempuri.org/GetCNNNews').GetCNNNews()
45 | print "[namespaced CBSNews call]"
46 | print dq._sa('http://tempuri.org/GetCBSNews').GetCBSNews()
47 |
--------------------------------------------------------------------------------
/tests/TemperatureService.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 | Returns current temperature in a given U.S. zipcode
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/Bug1936883.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id: speedTest.py 243 2003-05-21 14:52:37Z warnes $'
4 |
5 | import time
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | from SOAPpy import parseSOAP, parseSOAPRPC
10 |
11 | env = '''
12 |
13 | %s
14 | '''
15 |
16 | xml = env % '''
17 | <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[2]" xsi:type="SOAP-ENC:Array">
18 | <_2 SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array">
19 | - 1
20 | - 2
21 |
22 | <_3 SOAP-ENC:arrayType="xsd:double[2]" xsi:type="SOAP-ENC:Array">
23 | - 3.3
24 | - 4.4
25 |
26 | <_4 SOAP-ENC:arrayType="xsd:bool[2]" xsi:type="SOAP-ENC:Array">
27 | - 0
28 | - 1
29 |
30 | <_5 SOAP-ENC:arrayType="xsd:bool[2]" xsi:type="SOAP-ENC:Array">
31 | - False
32 | - True
33 |
34 |
35 | '''
36 |
37 |
38 | x = parseSOAPRPC(xml)
39 |
40 |
41 | assert( x[2] == [ 1, 2 ] )
42 | assert( x[3] == [ 3.3, 4.4 ] )
43 |
44 | # These previously failed, instead having strings
45 | assert( x[4] == [ False, True ] )
46 | assert( x[5] == [ False, True ] )
47 |
48 | print "Success"
49 |
50 |
--------------------------------------------------------------------------------
/tests/Bug1001646.py:
--------------------------------------------------------------------------------
1 | """
2 | Check handing of unicode.
3 | """
4 |
5 | import sys
6 | sys.path.insert(1, "..")
7 | from SOAPpy import *
8 |
9 | # Uncomment to see outgoing HTTP headers and SOAP and incoming
10 | #Config.debug = 1
11 | #Config.dumpHeadersIn = 1
12 | #Config.dumpSOAPIn = 1
13 | #Config.dumpSOAPOut = 1
14 |
15 | # ask for returned SOAP responses to be converted to basic python types
16 | Config.simplify_objects = 1
17 |
18 | #Config.BuildWithNoType = 1
19 | #Config.BuildWithNoNamespacePrefix = 1
20 |
21 |
22 | def headers():
23 | '''Return a soap header containing all the needed information.'''
24 | hd = Types.headerType()
25 | hd.useragent = Types.stringType("foo")
26 | return hd
27 |
28 | server = SOAPProxy("http://localhost:9900/",header=headers())
29 |
30 | adgroupid = 197497504
31 | keyword1 = { 'status': 'Moderate',
32 | 'adGroupId': 197497504,
33 | 'destinationURL': None,
34 | 'language': '',
35 | 'text': 'does not work',
36 | 'negative': bool(0),
37 | 'maxCpc': 50000,
38 | 'type': 'Keyword',
39 | 'id': 1 }
40 | keyword2 = { 'status': 'Moderate',
41 | 'adGroupId': 197497504,
42 | 'destinationURL': None,
43 | 'language': '',
44 | 'text': 'yes it does not',
45 | 'negative': bool(0),
46 | 'maxCpc': 50000,
47 | 'type': 'Keyword',
48 | 'id': 2 }
49 | keylist = [keyword1, keyword2]
50 |
51 | # Check that the data goes through properly
52 |
53 | retval = server.echo_simple(adgroupid, keylist)
54 |
55 | kw1 = retval[1][0]
56 | kw2 = retval[1][1]
57 |
58 | assert(retval[0] == adgroupid)
59 |
60 | for key in kw1.keys():
61 | assert(kw1[key]==keyword1[key])
62 |
63 | for key in kw2.keys():
64 | assert(kw2[key]==keyword2[key])
65 |
66 | # Check that the header is preserved
67 | retval = server.echo_header((adgroupid, keylist))
68 |
69 | assert(retval[1].has_key('useragent'))
70 | assert(retval[1]['useragent'] == 'foo')
71 |
72 | server.quit()
73 |
74 | print "Success!"
75 |
76 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/README:
--------------------------------------------------------------------------------
1 | Two top level modules have been provided to run the tests. "test_wstools.py"
2 | is used to run all of the local tests. "test_wstools_net.py" is used to run
3 | all of the tests that require network access.
4 |
5 | Add the -v option for more informative feedback.
6 |
7 | ADDING TESTS:
8 | 1. For Stand-Alone tests add WSDL FILE to appropriate archive file
9 | Need to add a NEW Archive?:
10 | config.txt [files] "archive" -- tuple of all archive files,
11 | if you need to create a new archive append the archive
12 | name to the 'archive' tuple.
13 |
14 | 2. Edit config.txt section(s):
15 | option -- name by which service will be referenced in test case.
16 | Need an entry under appropriate section(s), this name
17 | must be unique within each section it appears but it may
18 | appear in multiple sections.
19 |
20 | config.txt "test" sections:
21 | Stand-Alone -- add "option" under [services_by_file]
22 | eg. amazon = exports/AmazonWebServices.wsdl
23 |
24 | Network -- add "option" under [services_by_http]
25 | eg. amazon = http://soap.amazon.com/schemas/AmazonWebServices.wsdl
26 |
27 | Broken -- add "option" under [broken]
28 |
29 | 3. Done
30 |
31 |
32 | CONTENTS OF SAMPLE WSDL/XSD:
33 | schema -- Taken from globus-3.0.1(http://www.globus.org)
34 | xmethods -- Taken from XMethods(http://www.xmethods.com)
35 | airport.wsdl
36 | AmazonWebServices.wsdl
37 | books.wsdl
38 | Distance.wsdl
39 | freedb.wsdl
40 | globalweather.wsdl
41 | IHaddock.wsdl
42 | ip2geo.wsdl
43 | magic.wsdl
44 | query.wsdl
45 | RateInfo.wsdl
46 | SHA1Encrypt.wsdl
47 | siteInspect.wsdl
48 | TemperatureService.wsdl
49 | usweather.wsdl
50 | rtf2html.xml
51 | SolveSystem.wsdl.xml
52 | zip2geo.wsdl
53 |
--------------------------------------------------------------------------------
/tests/Makefile:
--------------------------------------------------------------------------------
1 | PYTHON=python
2 |
3 | default: echoClient echoHeader largeDataTest bugs \
4 | card independent \
5 | testClient1 outside_services
6 |
7 | bugs: Bug1001646 Bug916265 Bug1161780 Bug1936883
8 |
9 | echoClient:
10 | $(PYTHON) echoServer.py >& echoServer_echoClient.log &
11 | sleep 5s # wait for server to start up
12 | $(PYTHON) echoClient.py
13 |
14 | echoHeader:
15 | $(PYTHON) echoServer.py >& echoServer_echoHeader.log &
16 | sleep 5s # wait for server to start up
17 | $(PYTHON) echoHeader.py
18 |
19 | largeDataTest:
20 | $(PYTHON) echoServer.py >& echoServer_largeDataTest.log &
21 | sleep 5s # wait for server to start up
22 | $(PYTHON) largeDataTest.py
23 |
24 | card:
25 | $(PYTHON) cardServer.py >& cardServer.log &
26 | sleep 5s # wait for server to start up
27 | $(PYTHON) cardClient.py
28 |
29 | esj:
30 | $(PYTHON) esj_test_server.py >& esj_test.log &
31 | $(PYTHON) esj_test_client.py
32 |
33 |
34 | Bug1936883:
35 | $(PYTHON) Bug1936883.py
36 |
37 | Bug1161780:
38 | $(PYTHON) Bug1161780.py
39 |
40 | Bug1001646:
41 | $(PYTHON) echoServer.py >& echoServer_largeDataTest.log &
42 | sleep 5s # wait for server to start up
43 | $(PYTHON) Bug1001646.py
44 |
45 | Bug916265:
46 | $(PYTHON) echoServer.py >& echoServer_Bug916265.log &
47 | sleep 5s # wait for server to start up
48 | $(PYTHON) Bug916265.py
49 |
50 | outside_services:
51 | $(PYTHON) alanbushTest.py
52 | $(PYTHON) BabelfishWSDLTest.py
53 | $(PYTHON) GoogleTest.py
54 | $(PYTHON) quoteTest.py
55 | $(PYTHON) simpleWSDL.py
56 | $(PYTHON) testWSDL.py
57 |
58 | independent:
59 | $(PYTHON) speedTest.py
60 | $(PYTHON) Bug918216.py
61 | -$(PYTHON) ComplexTypes.py
62 | -$(PYTHON) SOAPtest.py # one subtest will fail
63 | $(PYTHON) TCtest.py
64 | $(PYTHON) testleak.py
65 | -$(PYTHON) translateTest.py
66 | -$(PYTHON) weatherTest.py
67 | -$(PYTHON) whoisTest.py
68 | -$(PYTHON) xmethods.py
69 | $(PYTHON) ZeroLengthArray.py
70 |
71 | testClient1:
72 | $(PYTHON) testClient1.py
73 |
74 | broken:
75 | $(PYTHON) newsTest.py
76 | $(PYTHON) excelTest.py
77 | $(PYTHON) storageTest.py
78 |
--------------------------------------------------------------------------------
/tests/README:
--------------------------------------------------------------------------------
1 | $Id$
2 |
3 | This file contains various python scripts for testing SOAPpy.
4 |
5 | Type "make" to run the tests. You can specify which Python interpreter
6 | to run the tests with, e.g. "make PYTHON=python2.5".
7 |
8 | All of the tests here work without generating errors EXCEPT:
9 |
10 | - SOAPtest.py
11 |
12 | Fails the 'testArray' test because 'referenced' elements are
13 | included in the return object. This is a known shortcoming of
14 | SOAPpy and is on the future features list. All other tests pass.
15 |
16 | - storageTest.py
17 |
18 | Fails because the hard-coded user/password combination is no
19 | longer valid.
20 |
21 | - translateTest.py
22 |
23 | Fails (gracefully) with a message that the service is no longer
24 | available.
25 |
26 | - excelTest.py
27 |
28 | Fails because the EXCEL service is not available.
29 |
30 | - testClient1.py
31 |
32 | This is experimental code for making unit tests that depend on
33 | running both a client and a server process. It failse because the
34 | code doesn't quite manage to get the server started up for the second
35 | test. This is a problem with the test, not with SOAPpy, but we
36 | intend to get it fixed so that we can create better unit tests.
37 |
38 | The test files which rely on no-longer available servers should be
39 | removed unless we can find a replacement. This will wait for a cleanup
40 | associated with release of version 1.0.
41 |
42 | Also note that serveral of the client tests need to have the
43 | corresponding server running:
44 |
45 | Client Server
46 | ---------------------- ------------------------
47 | cardClient.py cardServer.py
48 | echoClient.py echoServer.py
49 | echoHeader.py echoServer.py
50 | esj_test_client.py esj_test_server.py
51 | largeDataTest.py echoServer.py
52 | speedTest.py echoServer.py
53 |
54 | Of course, tests which rely on access to an external URL require that
55 | the web is accessible. If you are behind a firewall, try setting the
56 | http_proxy environment variable to the URL of your web proxy.
57 |
58 |
--------------------------------------------------------------------------------
/tests/esj_test_client.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 |
3 | #standard imports
4 | import syslog, sys
5 |
6 | #domain specific imports
7 | sys.path.insert (1, '..')
8 | import SOAPpy
9 |
10 | SOAPpy.Config.simplify_objects=1
11 |
12 | ## def test_integer(self,pass_integer):
13 | ## def test_string(self,pass_string):
14 | ## def test_float(self,pass_float):
15 | ## def test_tuple(self,pass_tuple):
16 | ## def test_list(self,pass_list):
17 | ## def test_dictionary(self,pass_dictionary):
18 |
19 | if __name__ == "__main__":
20 |
21 | server = SOAPpy.SOAPProxy("http://localhost:9999")
22 |
23 | original_integer = 5
24 | result_integer = server.test_integer(original_integer)
25 | print "original_integer %s" % original_integer
26 | print "result_integer %s" % result_integer
27 | assert(result_integer==original_integer)
28 | print
29 |
30 | original_string = "five"
31 | result_string = server.test_string(original_string)
32 | print "original_string %s" % original_string
33 | print "result_string %s" % result_string
34 | assert(result_string==original_string)
35 | print
36 |
37 | original_float = 5.0
38 | result_float = server.test_float(original_float)
39 | print "original_float %s" % original_float
40 | print "result_float %s" % result_float
41 | assert(result_float==original_float)
42 | print
43 |
44 | original_tuple = (1,2,"three","four",5)
45 | result_tuple = server.test_tuple(original_tuple)
46 | print "original_tuple %s" % str(original_tuple)
47 | print "result_tuple %s" % str(result_tuple)
48 | assert(tuple(result_tuple)==original_tuple)
49 | print
50 |
51 | original_list = [5,4,"three",2,1]
52 | result_list = server.test_list(original_list)
53 | print "original_list %s" % original_list
54 | print "result_list %s" % result_list
55 | assert(result_list==original_list)
56 | print
57 |
58 | original_dictionary = {
59 | 'one': 1,
60 | "two": 2,
61 | "three": 3,
62 | "four": 4,
63 | "five": 5,
64 | }
65 | result_dictionary = server.test_dictionary(original_dictionary)
66 | print "original_dictionary %s" % original_dictionary
67 | print "result_dictionary %s" % result_dictionary
68 | assert(result_dictionary==original_dictionary)
69 | print
70 |
71 | server.quit()
72 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ==============================================
2 | SOAPpy - Simple to use SOAP library for Python
3 | ==============================================
4 |
5 | Current Maintainers:
6 |
7 | Gregory R. Warnes
8 | Christopher Blunck
9 |
10 | Original Authors:
11 |
12 | Cayce Ullman
13 | Brian Matthews
14 |
15 | Contributions by:
16 |
17 | Brad Knotwell
18 | Mark Bucciarelli (ported WSDL
19 | client from ZSI)
20 | Ivan R. Judson (Globus support)
21 | Kirk Strauser
22 | Antonio Beamud Montero (patches
23 | for integrating SOAPpy into Zope)
24 |
25 | Copyright (c) 2002-2003, Pfizer, Inc.
26 | Copyright (c) 2001, Cayce Ullman.
27 | Copyright (c) 2001, Brian Matthews.
28 | All rights reserved.
29 |
30 | LICENSE:
31 | ----------------------------------------------------------------------------
32 | Redistribution and use in source and binary forms, with or without
33 | modification, are permitted provided that the following conditions are met:
34 |
35 | Redistributions of source code must retain the above copyright notice, this
36 | list of conditions and the following disclaimer.
37 | Redistributions in binary form must reproduce the above copyright notice,
38 | this list of conditions and the following disclaimer in the documentation
39 | and/or other materials provided with the distribution.
40 |
41 | Neither the name of actzero, inc. nor the names of its contributors may
42 | be used to endorse or promote products derived from this software without
43 | specific prior written permission.
44 |
45 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
49 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
52 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
55 | DAMAGE.
56 |
57 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/ZPL:
--------------------------------------------------------------------------------
1 | Zope Public License (ZPL) Version 2.0
2 | -----------------------------------------------
3 |
4 | This software is Copyright (c) Zope Corporation (tm) and
5 | Contributors. All rights reserved.
6 |
7 | This license has been certified as open source. It has also
8 | been designated as GPL compatible by the Free Software
9 | Foundation (FSF).
10 |
11 | Redistribution and use in source and binary forms, with or
12 | without modification, are permitted provided that the
13 | following conditions are met:
14 |
15 | 1. Redistributions in source code must retain the above
16 | copyright notice, this list of conditions, and the following
17 | disclaimer.
18 |
19 | 2. Redistributions in binary form must reproduce the above
20 | copyright notice, this list of conditions, and the following
21 | disclaimer in the documentation and/or other materials
22 | provided with the distribution.
23 |
24 | 3. The name Zope Corporation (tm) must not be used to
25 | endorse or promote products derived from this software
26 | without prior written permission from Zope Corporation.
27 |
28 | 4. The right to distribute this software or to use it for
29 | any purpose does not give you the right to use Servicemarks
30 | (sm) or Trademarks (tm) of Zope Corporation. Use of them is
31 | covered in a separate agreement (see
32 | http://www.zope.com/Marks).
33 |
34 | 5. If any files are modified, you must cause the modified
35 | files to carry prominent notices stating that you changed
36 | the files and the date of any change.
37 |
38 | Disclaimer
39 |
40 | THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS''
41 | AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
42 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
43 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
44 | NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE
45 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
46 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
51 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
53 | DAMAGE.
54 |
55 |
56 | This software consists of contributions made by Zope
57 | Corporation and many individuals on behalf of Zope
58 | Corporation. Specific attributions are listed in the
59 | accompanying credits file.
60 |
61 |
62 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/license.txt:
--------------------------------------------------------------------------------
1 | *********
2 |
3 | Copyright (c) 2003, The Regents of the University of California,
4 | through Lawrence Berkeley National Laboratory (subject to receipt of
5 | any required approvals from the U.S. Dept. of Energy). All rights
6 | reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are
10 | met:
11 | (1) Redistributions of source code must retain the above copyright
12 | notice, this list of conditions and the following disclaimer.
13 | (2) Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in the
15 | documentation and/or other materials provided with the distribution.
16 | (3) Neither the name of the University of California, Lawrence
17 | Berkeley National Laboratory, U.S. Dept. of Energy nor the names of
18 | its contributors may be used to endorse or promote products derived
19 | from this software without specific prior written permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 |
33 | You are under no obligation whatsoever to provide any bug fixes,
34 | patches, or upgrades to the features, functionality or performance of
35 | the source code ("Enhancements") to anyone; however, if you choose to
36 | make your Enhancements available either publicly, or directly to
37 | Lawrence Berkeley National Laboratory, without imposing a separate
38 | written license agreement for such Enhancements, then you hereby grant
39 | the following license: a non-exclusive, royalty-free perpetual
40 | license to install, use, modify, prepare derivative works, incorporate
41 | into other computer software, distribute, and sublicense such
42 | enhancements or derivative works thereof, in binary and source code form.
43 |
44 | *********
45 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/XMLname.py:
--------------------------------------------------------------------------------
1 | """Translate strings to and from SOAP 1.2 XML name encoding
2 |
3 | Implements rules for mapping application defined name to XML names
4 | specified by the w3 SOAP working group for SOAP version 1.2 in
5 | Appendix A of "SOAP Version 1.2 Part 2: Adjuncts", W3C Working Draft
6 | 17, December 2001,
7 |
8 | Also see .
9 |
10 | Author: Gregory R. Warnes
11 | Date:: 2002-04-25
12 | Version 0.9.0
13 |
14 | """
15 |
16 | ident = "$Id$"
17 |
18 | from re import *
19 |
20 |
21 | def _NCNameChar(x):
22 | return x.isalpha() or x.isdigit() or x=="." or x=='-' or x=="_"
23 |
24 |
25 | def _NCNameStartChar(x):
26 | return x.isalpha() or x=="_"
27 |
28 |
29 | def _toUnicodeHex(x):
30 | hexval = hex(ord(x[0]))[2:]
31 | hexlen = len(hexval)
32 | # Make hexval have either 4 or 8 digits by prepending 0's
33 | if (hexlen==1): hexval = "000" + hexval
34 | elif (hexlen==2): hexval = "00" + hexval
35 | elif (hexlen==3): hexval = "0" + hexval
36 | elif (hexlen==4): hexval = "" + hexval
37 | elif (hexlen==5): hexval = "000" + hexval
38 | elif (hexlen==6): hexval = "00" + hexval
39 | elif (hexlen==7): hexval = "0" + hexval
40 | elif (hexlen==8): hexval = "" + hexval
41 | else: raise Exception, "Illegal Value returned from hex(ord(x))"
42 |
43 | return "_x"+ hexval + "_"
44 |
45 |
46 | def _fromUnicodeHex(x):
47 | return eval( r'u"\u'+x[2:-1]+'"' )
48 |
49 |
50 | def toXMLname(string):
51 | """Convert string to a XML name."""
52 | if string.find(':') != -1 :
53 | (prefix, localname) = string.split(':',1)
54 | else:
55 | prefix = None
56 | localname = string
57 |
58 | T = unicode(localname)
59 |
60 | N = len(localname)
61 | X = [];
62 | for i in range(N) :
63 | if i< N-1 and T[i]==u'_' and T[i+1]==u'x':
64 | X.append(u'_x005F_')
65 | elif i==0 and N >= 3 and \
66 | ( T[0]==u'x' or T[0]==u'X' ) and \
67 | ( T[1]==u'm' or T[1]==u'M' ) and \
68 | ( T[2]==u'l' or T[2]==u'L' ):
69 | X.append(u'_xFFFF_' + T[0])
70 | elif (not _NCNameChar(T[i])) or (i==0 and not _NCNameStartChar(T[i])):
71 | X.append(_toUnicodeHex(T[i]))
72 | else:
73 | X.append(T[i])
74 |
75 | if prefix:
76 | return "%s:%s" % (prefix, u''.join(X))
77 | return u''.join(X)
78 |
79 |
80 | def fromXMLname(string):
81 | """Convert XML name to unicode string."""
82 |
83 | retval = sub(r'_xFFFF_','', string )
84 |
85 | def fun( matchobj ):
86 | return _fromUnicodeHex( matchobj.group(0) )
87 |
88 | retval = sub(r'_x[0-9A-Za-z]+_', fun, retval )
89 |
90 | return retval
91 |
--------------------------------------------------------------------------------
/tests/echoClient.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | import sys
6 | sys.path.insert(1, "..")
7 |
8 | from SOAPpy import *
9 |
10 | # Uncomment to see outgoing HTTP headers and SOAP and incoming
11 | #Config.debug = 1
12 | #Config.dumpHeadersIn = 1
13 | #Config.dumpSOAPIn = 1
14 | #Config.dumpSOAPOut = 1
15 |
16 | # ask for returned SOAP responses to be converted to basic python types
17 | Config.simplify_objects = 1
18 |
19 | #Config.BuildWithNoType = 1
20 | #Config.BuildWithNoNamespacePrefix = 1
21 |
22 | if len(sys.argv) > 1 and sys.argv[1] == '-s':
23 | # Use secure http
24 | pathserver = SOAPProxy("https://localhost:9900/pathtest")
25 | server = SOAPProxy("https://localhost:9900")
26 |
27 | elif len(sys.argv) > 1 and sys.argv[1] == '-g':
28 | # use Globus for communication
29 | import pyGlobus
30 | pathserver = SOAPProxy("httpg://localhost:9900/pathtest")
31 | server = SOAPProxy("httpg://localhost:9900")
32 |
33 | else:
34 | # Default: use standard http
35 | pathserver = SOAPProxy("http://localhost:9900/pathtest")
36 | server = SOAPProxy("http://localhost:9900")
37 |
38 | # Echo...
39 |
40 | try:
41 | print server.echo("MOO")
42 | except Exception, e:
43 | print "Caught exception: ", e
44 | try:
45 | print pathserver.echo("MOO")
46 | except Exception, e:
47 | print "Caught exception: ", e
48 |
49 | # ...in an object
50 | try:
51 | print server.echo_ino("moo")
52 | except Exception, e:
53 | print "Caught exception: ", e
54 | try:
55 | print pathserver.echo_ino("cow")
56 | except Exception, e:
57 | print "Caught exception: ", e
58 |
59 | # ...in an object in an object
60 | try:
61 | print server.prop.echo2("moo")
62 | except Exception, e:
63 | print "Caught exception: ", e
64 |
65 | try:
66 | print pathserver.prop.echo2("cow")
67 | except Exception, e:
68 | print "Caught exception: ", e
69 |
70 | # ...with keyword arguments
71 | try:
72 | print server.echo_wkw(third = "three", first = "one", second = "two")
73 | except Exception, e:
74 | print "Caught exception: ", e
75 | try:
76 | print pathserver.echo_wkw(third = "three", first = "one", second = "two")
77 | except Exception, e:
78 | print "Caught exception: ", e
79 |
80 | # ...with a context object
81 | try:
82 | print server.echo_wc("moo")
83 | except Exception, e:
84 | print "Caught exception: ", e
85 | try:
86 | print pathserver.echo_wc("cow")
87 | except Exception, e:
88 | print "Caught exception: ", e
89 |
90 | # ...with a header
91 | hd = headerType(data = {"mystring": "Hello World"})
92 | try:
93 | print server._hd(hd).echo_wc("moo")
94 | except Exception, e:
95 | print "Caught exception: ", e
96 | try:
97 | print pathserver._hd(hd).echo_wc("cow")
98 | except Exception, e:
99 | print "Caught exception: ", e
100 |
101 | # close down server
102 | server.quit()
103 |
--------------------------------------------------------------------------------
/SOAPpy.spec:
--------------------------------------------------------------------------------
1 | Summary: SOAPpy
2 | Name: SOAPpy
3 | Version: 0.9.7
4 | Release: 2
5 | License: Copyright (c) 2001, Cayce Ullman.
6 | Group: Productivity/Networking/Web/Applications
7 | Source: SOAPpy-%{version}.tgz
8 | Requires: python >= 2.2
9 | BuildArch: noarch
10 | AutoReq: no
11 | Packager: Antonio Beamud Montero
12 |
13 | %description
14 | SOAP implementation by Cayce Ullman and Brian Matthews.
15 | %prep
16 | %setup SOAPpy-%{version}
17 |
18 | %build
19 |
20 | %install
21 | mkdir -p /usr/share/doc/SOAPpy/bid
22 | cp -a bid/* /usr/share/doc/SOAPpy/bid
23 | mkdir -p /usr/share/doc/SOAPpy/tests
24 | cp -a tests/* /usr/share/doc/SOAPpy/tests
25 | cp -a TCtest.py /usr/share/doc/SOAPpy/tests
26 | mkdir -p /usr/share/doc/SOAPpy/contrib
27 | cp contrib/* /usr/share/doc/SOAPpy/contrib/
28 | cp docs/* /usr/share/doc/SOAPpy/
29 | mkdir -p /usr/share/doc/SOAPpy/tools
30 | cp -a tools/* /usr/share/doc/SOAPpy/tools
31 | cp README /usr/share/doc/SOAPpy/
32 | cp echoServer.py /usr/share/doc/SOAPpy/
33 | cp speedTest.py /usr/share/doc/SOAPpy/
34 | cp CHANGELOG /usr/share/doc/SOAPpy/
35 | cp SOAPtest.py /usr/share/doc/SOAPpy/tests
36 | cp excelTest.py /usr/share/doc/SOAPpy/
37 | cp echoClient.py /usr/share/doc/SOAPpy/
38 | mkdir -p /usr/share/doc/SOAPpy/validate
39 | cp -a validate/* /usr/share/doc/SOAPpy/validate
40 | cp SOAP.py /usr/lib/python/site-packages/
41 |
42 | %clean
43 |
44 | %pre
45 |
46 | %post
47 |
48 | %preun
49 |
50 | %postun
51 |
52 | %files
53 | %defattr(-,root,root)
54 | /usr/share/doc/SOAPpy/bid/monitorClient.py
55 | /usr/share/doc/SOAPpy/bid/inventoryServer.py
56 | /usr/share/doc/SOAPpy/bid/inventory.servers
57 | /usr/share/doc/SOAPpy/bid/inventoryClient.py
58 | /usr/share/doc/SOAPpy/tests/TCtest.py
59 | /usr/share/doc/SOAPpy/simpleTypes.txt
60 | /usr/share/doc/SOAPpy/attrs.txt
61 | /usr/share/doc/SOAPpy/quickstart.txt
62 | /usr/share/doc/SOAPpy/complexTypes.txt
63 | /usr/share/doc/SOAPpy/contrib/soap_cli.py
64 | /usr/share/doc/SOAPpy/contrib/soap_handler.py
65 | /usr/share/doc/SOAPpy/tests/cardServer.py
66 | /usr/share/doc/SOAPpy/tests/guidTest.py
67 | /usr/share/doc/SOAPpy/tests/alanbushTest.py
68 | /usr/share/doc/SOAPpy/tests/newsTest.py
69 | /usr/share/doc/SOAPpy/tests/weatherTest.py
70 | /usr/share/doc/SOAPpy/tests/fortuneTest.py
71 | /usr/share/doc/SOAPpy/tests/cardClient.py
72 | /usr/share/doc/SOAPpy/tests/quoteTest.py
73 | /usr/share/doc/SOAPpy/tests/storageTest.py
74 | /usr/share/doc/SOAPpy/tests/wordFindTest.py
75 | /usr/share/doc/SOAPpy/tests/itimeTest.py
76 | /usr/share/doc/SOAPpy/tests/whoisTest.py
77 | /usr/share/doc/SOAPpy/tests/translateTest.py
78 | /usr/share/doc/SOAPpy/tools/interop2html.py
79 | /usr/share/doc/SOAPpy/README
80 | /usr/share/doc/SOAPpy/echoServer.py
81 | /usr/share/doc/SOAPpy/speedTest.py
82 | /usr/share/doc/SOAPpy/CHANGELOG
83 | /usr/share/doc/SOAPpy/tests/SOAPtest.py
84 | /usr/share/doc/SOAPpy/excelTest.py
85 | /usr/share/doc/SOAPpy/echoClient.py
86 | /usr/share/doc/SOAPpy/validate/silab.servers
87 | /usr/share/doc/SOAPpy/validate/silabserver.py
88 | /usr/share/doc/SOAPpy/validate/server.pem
89 | /usr/share/doc/SOAPpy/validate/silabclient.py
90 | /usr/share/doc/SOAPpy/validate/soapware.py
91 | /usr/lib/python2.2/site-packages/SOAP.py
--------------------------------------------------------------------------------
/tests/speedTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id$'
4 |
5 | import time
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | x='''
13 |
14 |
15 | USA
16 | japan
17 |
18 |
19 | '''
20 |
21 | x2='''
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | West Virginia
33 | -546
34 | -5.398
35 |
36 |
37 | New Mexico
38 | -641
39 | -9.351
40 |
41 |
42 | Missouri
43 | -819
44 | 1.495
45 |
46 |
47 |
48 | '''
49 |
50 | # Import in function, because for some reason they slow each other
51 | # down in same namespace ???
52 | def SOAPParse(inxml):
53 | from SOAPpy import parseSOAPRPC
54 | t= time.time()
55 | parseSOAPRPC(inxml)
56 | return time.time()-t
57 |
58 | def SAXParse(inxml):
59 | import xml.sax
60 | y = xml.sax.handler.ContentHandler()
61 | t= time.time()
62 | xml.sax.parseString(inxml,y)
63 | return time.time()-t
64 |
65 | def DOMParse(inxml):
66 | import xml.dom.minidom
67 | t= time.time()
68 | xml.dom.minidom.parseString(inxml)
69 | return time.time()-t
70 |
71 | # Wierd but the SAX parser runs really slow the first time.
72 | # Probably got to load a c module or something
73 | SAXParse(x)
74 | print
75 | print "Simple XML"
76 | print "SAX Parse, no marshalling ", SAXParse(x)
77 | print "SOAP Parse, and marshalling ", SOAPParse(x)
78 | print "DOM Parse, no marshalling ", DOMParse(x)
79 | print
80 | print "Complex XML (references)"
81 | print "SAX Parse, no marshalling ", SAXParse(x2)
82 | print "SOAP Parse, and marshalling ", SOAPParse(x2)
83 | print "DOM Parse, no marshalling ", DOMParse(x2)
84 |
--------------------------------------------------------------------------------
/SOAPpy/Errors.py:
--------------------------------------------------------------------------------
1 | """
2 | ################################################################################
3 | #
4 | # SOAPpy - Cayce Ullman (cayce@actzero.com)
5 | # Brian Matthews (blm@actzero.com)
6 | # Gregory Warnes (Gregory.R.Warnes@Pfizer.com)
7 | # Christopher Blunck (blunck@gst.com)
8 | #
9 | ################################################################################
10 | # Copyright (c) 2003, Pfizer
11 | # Copyright (c) 2001, Cayce Ullman.
12 | # Copyright (c) 2001, Brian Matthews.
13 | #
14 | # All rights reserved.
15 | #
16 | # Redistribution and use in source and binary forms, with or without
17 | # modification, are permitted provided that the following conditions are met:
18 | # Redistributions of source code must retain the above copyright notice, this
19 | # list of conditions and the following disclaimer.
20 | #
21 | # Redistributions in binary form must reproduce the above copyright notice,
22 | # this list of conditions and the following disclaimer in the documentation
23 | # and/or other materials provided with the distribution.
24 | #
25 | # Neither the name of actzero, inc. nor the names of its contributors may
26 | # be used to endorse or promote products derived from this software without
27 | # specific prior written permission.
28 | #
29 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
33 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 | #
40 | ################################################################################
41 | """
42 |
43 | ident = '$Id$'
44 | from version import __version__
45 |
46 | import exceptions
47 |
48 | ################################################################################
49 | # Exceptions
50 | ################################################################################
51 | class Error(exceptions.Exception):
52 | def __init__(self, msg):
53 | self.msg = msg
54 | def __str__(self):
55 | return "" % self.msg
56 | __repr__ = __str__
57 | def __call__(self):
58 | return (msg,)
59 |
60 | class RecursionError(Error):
61 | pass
62 |
63 | class UnknownTypeError(Error):
64 | pass
65 |
66 | class HTTPError(Error):
67 | # indicates an HTTP protocol error
68 | def __init__(self, code, msg):
69 | self.code = code
70 | self.msg = msg
71 | def __str__(self):
72 | return "" % (self.code, self.msg)
73 | __repr__ = __str__
74 | def __call___(self):
75 | return (self.code, self.msg, )
76 |
77 | class UnderflowError(exceptions.ArithmeticError):
78 | pass
79 |
80 |
--------------------------------------------------------------------------------
/docs/UsingHeaders.txt:
--------------------------------------------------------------------------------
1 | Using Headers
2 | =============
3 |
4 | SOAPpy has a Header class to hold data for the header of a SOAP message.
5 | Each Header instance has methods to set/get the MustUnderstand attribute, and
6 | methods to set/get the Actor attribute.
7 |
8 | SOAPpy also has a SOAPContext class so that each server method can be
9 | implemented in such a way that it gets the context of the connecting client.
10 | This includes both common SOAP information and connection information (see
11 | below for an example).
12 |
13 | CLIENT EXAMPLES
14 | ---------------
15 |
16 | ## CODE
17 | import SOAPpy
18 | test = 42
19 | server = SOAPpy.SOAPProxy("http://localhost:8888")
20 | server = server._sa ("urn:soapinterop")
21 |
22 | hd = SOAPpy.Header()
23 | hd.InteropTestHeader ='This should fault, as you don\'t understand the header.'
24 | hd._setMustUnderstand ('InteropTestHeader', 0)
25 | hd._setActor ('InteropTestHeader','http://schemas.xmlsoap.org/soap/actor/next')
26 | server = server._hd (hd)
27 |
28 | print server.echoInteger (test)
29 | ## /CODE
30 |
31 | This should succeed (provided the server has defined echoInteger), as it
32 | builds a valid header into this client with MustUnderstand set to 0
33 | and then sends the SOAP with this header.
34 |
35 |
36 | ## CODE
37 | import SOAPpy
38 | test = 42
39 | server = SOAPpy.SOAPProxy("http://localhost:8888")
40 | server = server._sa ("urn:soapinterop")
41 | #Header
42 | hd = SOAPpy.Header()
43 | hd.InteropTestHeader = 'This should fault,as you don\'t understand the header.'
44 | hd._setMustUnderstand ('InteropTestHeader', 1)
45 | hd._setActor ('InteropTestHeader','http://schemas.xmlsoap.org/soap/actor/next')
46 | server = server._hd (hd)
47 |
48 | print server.echoInteger (test)
49 | ## /CODE
50 |
51 | This should fail (even if the server has defined 'echoInteger'), as it
52 | builds a valid header into this client, but sets MustUnderstand to 1
53 | for a message that the server presumably won't understand before sending.
54 |
55 |
56 |
57 |
58 | SERVER EXAMPLES
59 | ---------------
60 |
61 | ## CODE
62 | import SOAPpy
63 | def echoInteger (inputInteger):
64 | return inputInteger
65 | server = SOAPpy.SOAPServer ( ('localhost', 8080) )
66 | server.registerFunction (echoInteger)
67 | server.serve_forever()
68 | ## /CODE
69 |
70 | This is a simple server designed to work with the first 2 clients above.
71 |
72 |
73 | ## CODE
74 | import SOAPpy
75 | def echoInteger (inputInteger, _SOAPContext):
76 | c = _SOAPContext
77 | print c.xmldata
78 | print c.header
79 | print c.body
80 | print c.connection.getpeername()
81 | print c.soapaction
82 | print c.httpheaders
83 | return inputInteger
84 |
85 | host = 'localhost'
86 | port = 8888
87 |
88 | server = SOAPpy.SOAPServer ( (host, port) )
89 | server.registerFunction (SOAPpy.MethodSig(echoInteger, keywords=0,context=1))
90 |
91 | server.serve_forever()
92 | ## /CODE
93 |
94 | This is a server which shows off the SOAPContext feature. This
95 | server gets a context from the client that has connected to it, and
96 | prints some of the pertinent aspects of that client before
97 | returning. This server should also work with the code for the two
98 | clients written above.
99 |
100 |
101 |
102 |
103 |
104 | $Id$
105 |
--------------------------------------------------------------------------------
/tools/interop2html.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import string
4 | import cgi
5 |
6 | ident = '$Id$'
7 |
8 | lines = open('output.txt').readlines()
9 | #preserve the tally
10 | tally = lines[-6:]
11 | #whack the tally from lines
12 | lines = lines[:-6]
13 | table={}
14 | for line in lines:
15 | if line[:3] == ' ' or line == '>\n' : continue
16 | line = line[:-1] #delete end of line char
17 | row = [line[:line.find(': ')], line[line.find(': ')+2:]] #split server name from rest of line
18 | restofrow = row[1].split(' ',3) #break out method name, number, status code, status comment
19 | if len(restofrow) > 3:
20 | if restofrow[3].find('as expected') != -1:
21 | restofrow[2] = restofrow[2] + ' (as expected)'
22 | elif restofrow[3][:2] == '- ' :
23 | restofrow[3] = restofrow[3][2:]
24 | try: table[row[0]].append([restofrow[0],restofrow[2:]])
25 | except KeyError: table[row[0]] = [[restofrow[0],restofrow[2:]]]
26 |
27 | print ""
28 | print ""
34 | print "
| Summary |
"
35 | for x in tally:
36 | z = x[:-1].split(":",1)
37 | print "| ",z[0]," | ",z[1]," |
"
38 | print "
"
39 | c = 0
40 | totalmethods = len(table[table.keys()[0]])
41 | while c < totalmethods:
42 | print "
"
43 | print " | "
44 | cols = [c, c + 1, c + 2]
45 | if c != 16:
46 | cols += [c + 3]
47 | for i in cols:
48 | try: header = table[table.keys()[0]][i][0]
49 | except: break
50 | print "",header," | "
51 | print "
"
52 | l = table.keys()
53 | l.sort()
54 | for key in l:
55 | print "| ", key , " | "
56 | for i in cols:
57 | try: status = table[key][i][1][0]
58 | except: break
59 | if status.find("succeed") != -1:
60 | bgcolor = "#339900"
61 | status = "Pass"
62 | elif status.find("expected") != -1:
63 | bgcolor = "#FF9900"
64 | hreftitle = table[key][i][1][1].replace("'","") # remove apostrophes from title properties
65 | popuphtml = '"' + cgi.escape(cgi.escape(table[key][i][1][1]).replace("'","'").replace('"',""")) + '"'
66 | status = "Failed (expected)"
67 | else:
68 | bgcolor = "#CC0000"
69 | hreftitle = table[key][i][1][1].replace("'","") # remove apostrophes from title properties
70 | popuphtml = '"' + cgi.escape(cgi.escape(table[key][i][1][1]).replace("'","'").replace('"',""")) + '"'
71 | status = "Failed"
72 | print "" , status , " | "
73 | print "
"
74 | print "
"
75 | c = c + len(cols)
76 | print ""
77 |
--------------------------------------------------------------------------------
/tests/cardServer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | import string
6 | import sys
7 |
8 | sys.path.insert (1, '..')
9 |
10 | from SOAPpy import *
11 |
12 | ident = '$Id$'
13 |
14 | # create the list of all cards, and keep strings for each suit
15 | __cs = "Clubs"
16 | __ds = "Diamonds"
17 | __hs = "Hearts"
18 | __ss = "Spades"
19 | __cards = []
20 | for suit in [__cs, __ds, __hs, __ss]:
21 | for num in range(9):
22 | num += 1
23 | __cards.append(str(num+1)+" of "+suit)
24 | for face in ["ace","King","Queen","Jack"]:
25 | __cards.append(face+" of "+suit)
26 |
27 |
28 | def deal(num):
29 | if num not in range(1,53):
30 | return -1
31 | else:
32 | alreadydealt = []
33 | ignore = 0
34 | handdealt = []
35 | import whrandom
36 | while num > 0:
37 | idx = int(str(whrandom.random())[2:4])
38 | if idx in range(52) and idx not in alreadydealt:
39 | handdealt.append(__cards[idx])
40 | alreadydealt.append(idx)
41 | num -= 1
42 | else:
43 | ignore += 1
44 | continue
45 | return handdealt
46 |
47 | def arrangeHand(hand):
48 | c = []
49 | d = []
50 | h = []
51 | s = []
52 | import string
53 | for card in hand:
54 | if string.find(card, __cs) != -1:
55 | c.append(card)
56 | elif string.find(card, __ds) != -1:
57 | d.append(card)
58 | elif string.find(card, __hs) != -1:
59 | h.append(card)
60 | elif string.find(card, __ss) != -1:
61 | s.append(card)
62 | for cards, str in ((c, __cs),(d, __ds),(h,__hs), (s,__ss)):
63 | cards.sort()
64 | idx = 0
65 | if "10 of "+str in cards:
66 | cards.remove("10 of "+str)
67 | if "Jack of "+str in cards: idx += 1
68 | if "Queen of "+str in cards: idx += 1
69 | if "King of "+str in cards: idx += 1
70 | if "ace of "+str in cards: idx +=1
71 | cards.insert(len(cards)-idx,"10 of "+str)
72 | if "King of "+str in cards:
73 | cards.remove("King of "+str)
74 | if "ace of "+str in cards: cards.insert(len(cards)-1,"King of "+str)
75 | else: cards.append("King of "+str)
76 | return c+d+h+s
77 |
78 | def dealHand (NumberOfCards, StringSeparator):
79 | hand = deal(NumberOfCards)
80 | return string.join(hand,StringSeparator)
81 |
82 |
83 | def dealArrangedHand (NumberOfCards, StringSeparator):
84 | if NumberOfCards < 1 or NumberOfCards > 52:
85 | raise ValueError, "NumberOfCards must be between 1 and 52"
86 | unarranged = deal(NumberOfCards)
87 | hand = arrangeHand(unarranged)
88 | return string.join(hand, StringSeparator)
89 |
90 | def dealCard ():
91 | return deal(1)[0]
92 |
93 | run = 1
94 |
95 | def quit():
96 | global run
97 | run=0;
98 |
99 | namespace = 'http://soapinterop.org/'
100 |
101 | server = SOAPServer (("localhost", 12027))
102 |
103 | server.registerKWFunction (dealHand, namespace)
104 | server.registerKWFunction (dealArrangedHand, namespace)
105 | server.registerKWFunction (dealCard, namespace)
106 | server.registerKWFunction (quit, namespace)
107 |
108 | try:
109 | while run:
110 | server.handle_request()
111 | except KeyboardInterrupt:
112 | pass
113 |
--------------------------------------------------------------------------------
/tests/testClient1.py:
--------------------------------------------------------------------------------
1 | import gc
2 | import socket
3 | import threading
4 | import time
5 | import unittest
6 | import sys
7 | sys.path.insert(1, "..")
8 |
9 | import SOAPpy
10 | #SOAPpy.Config.debug=1
11 |
12 | # global to shut down server
13 | quit = 0
14 |
15 | def echoDateTime(dt):
16 | return dt
17 |
18 | def echo(s):
19 | """repeats a string twice"""
20 | return s + s
21 |
22 | def kill():
23 | """tell the server to quit"""
24 | global quit
25 | quit = 1
26 |
27 | def server1():
28 | """start a SOAP server on localhost:8000"""
29 |
30 | print "Starting SOAP Server...",
31 | server = SOAPpy.Server.SOAPServer(addr=('127.0.0.1', 8000))
32 | server.registerFunction(echoDateTime)
33 | server.registerFunction(echo)
34 | server.registerFunction(kill)
35 | print "Done."
36 |
37 | global quit
38 | while not quit:
39 | server.handle_request()
40 | quit = 0
41 | print "Server shut down."
42 |
43 | class ClientTestCase(unittest.TestCase):
44 |
45 | server = None
46 | startup_timeout = 5 # seconds
47 |
48 | def setUp(self):
49 | '''This is run once before each unit test.'''
50 |
51 | serverthread = threading.Thread(target=server1, name="SOAPServer")
52 | serverthread.start()
53 |
54 | start = time.time()
55 | connected = False
56 | server = None
57 | while not connected and time.time() - start < self.startup_timeout:
58 | print "Trying to connect to the SOAP server...",
59 | try:
60 | server = SOAPpy.Client.SOAPProxy('127.0.0.1:8000')
61 | server.echo('Hello World')
62 | except socket.error, e:
63 | print "Failure:", e
64 | time.sleep(0.5)
65 | else:
66 | connected = True
67 | self.server = server
68 | print "Success."
69 |
70 | if not connected: raise 'Server failed to start.'
71 |
72 | def tearDown(self):
73 | '''This is run once after each unit test.'''
74 |
75 | print "Trying to shut down SOAP server..."
76 | if self.server is not None:
77 | self.server.kill()
78 | time.sleep(5)
79 |
80 | return 1
81 |
82 | def testEcho(self):
83 | '''Test echo function.'''
84 |
85 | server = SOAPpy.Client.SOAPProxy('127.0.0.1:8000')
86 | s = 'Hello World'
87 | self.assertEquals(server.echo(s), s+s)
88 |
89 | def testNamedEcho(self):
90 | '''Test echo function.'''
91 |
92 | server = SOAPpy.Client.SOAPProxy('127.0.0.1:8000')
93 | s = 'Hello World'
94 | self.assertEquals(server.echo(s=s), s+s)
95 |
96 | def testEchoDateTime(self):
97 | '''Test passing DateTime objects.'''
98 |
99 | server = SOAPpy.Client.SOAPProxy('127.0.0.1:8000')
100 | dt = SOAPpy.Types.dateTimeType(data=time.time())
101 | dt_return = server.echoDateTime(dt)
102 | self.assertEquals(dt_return, dt)
103 |
104 |
105 | # def testNoLeak(self):
106 | # '''Test for memory leak.'''
107 |
108 | # gc.set_debug(gc.DEBUG_SAVEALL)
109 | # for i in range(400):
110 | # server = SOAPpy.Client.SOAPProxy('127.0.0.1:8000')
111 | # s = 'Hello World'
112 | # server.echo(s)
113 | # gc.collect()
114 | # self.assertEquals(len(gc.garbage), 0)
115 |
116 |
117 | if __name__ == '__main__':
118 | unittest.main()
119 |
--------------------------------------------------------------------------------
/validate/server.pem:
--------------------------------------------------------------------------------
1 | $Id$
2 | # Test certificate generated using CA.pl written by Steve Hensen
3 | # bundled with OpenSSL.
4 | #
5 | # Steps used to generate server.pem :
6 | # a)CA.pl -newca (creates a new CA heirarchy)
7 | # b)CA.pl -newreq (creates a new certificate request)
8 | # c)CA.pl -sign (sign the certificate request)
9 | # d)openssl rsa newkey.pem (unencrypt the private key)
10 | # e)Copy the certificate from newcert.pem, the unencrypted RSA
11 | # private key from newkey.pem and the certificate request from
12 | # newreq.pem and create server.pem to contain all three of them.
13 | -----BEGIN CERTIFICATE-----
14 | MIIDhjCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBgDELMAkGA1UEBhMCVVMx
15 | CzAJBgNVBAgTAkNBMQswCQYDVQQHEwJSQzEQMA4GA1UEChMHYWN0emVybzETMBEG
16 | A1UECxMKdGVjaG5vbG9neTEPMA0GA1UEAxMGc3lzYWRtMR8wHQYJKoZIhvcNAQkB
17 | FhBpbmZvQGFjdHplcm8uY29tMB4XDTAxMDUxNjIyMzkwM1oXDTAyMDUxNjIyMzkw
18 | M1owgYAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCUkMxEDAO
19 | BgNVBAoTB2FjdHplcm8xEzARBgNVBAsTCnRlY2hub2xvZ3kxDzANBgNVBAMTBnN5
20 | c2FkbTEfMB0GCSqGSIb3DQEJARYQaW5mb0BhY3R6ZXJvLmNvbTCBnzANBgkqhkiG
21 | 9w0BAQEFAAOBjQAwgYkCgYEAyRBB6l+DI3aMNeYf7IuodvZ9nNxnfQHVnGyRtwhb
22 | 1g2tugTwFsE67oHA5qvwaDBILtsqkr9agXYDbZwJmV58xtBY675tibf7/1R8mcDO
23 | d4Dremdn0CMyk4+n6Z8GpLJ59TZ3y98DXUOqbLvzzltDz0si2XVa8G7f4K5k/xxB
24 | GZcCAwEAAaOCAQwwggEIMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5T
25 | U0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBT/DGQzyXlwLXMWMaT4
26 | lp9O928tvzCBrQYDVR0jBIGlMIGigBSdjwZua1AI3XoUtwLyW0Optc/4O6GBhqSB
27 | gzCBgDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQswCQYDVQQHEwJSQzEQMA4G
28 | A1UEChMHYWN0emVybzETMBEGA1UECxMKdGVjaG5vbG9neTEPMA0GA1UEAxMGc3lz
29 | YWRtMR8wHQYJKoZIhvcNAQkBFhBpbmZvQGFjdHplcm8uY29tggEAMA0GCSqGSIb3
30 | DQEBBAUAA4GBABQodV+rrwMsvTEEza08EeS1Rf2ISuzh6e9VbfiJLVB5Xv1SeEt1
31 | sOv8ETZyN/4OXvZWQG/5md/5NNkf5K6CeKiwctztkyKTXdPIFS6FJVZdduWhiWPF
32 | 6gutQgOogtpCHTLwdSDk75n5MXFlnehORqOREMqqCJtFlHMEV1211Ssi
33 | -----END CERTIFICATE-----
34 | -----BEGIN RSA PRIVATE KEY-----
35 | MIICWwIBAAKBgQDJEEHqX4Mjdow15h/si6h29n2c3Gd9AdWcbJG3CFvWDa26BPAW
36 | wTrugcDmq/BoMEgu2yqSv1qBdgNtnAmZXnzG0Fjrvm2Jt/v/VHyZwM53gOt6Z2fQ
37 | IzKTj6fpnwaksnn1NnfL3wNdQ6psu/POW0PPSyLZdVrwbt/grmT/HEEZlwIDAQAB
38 | AoGALcho6gBjsRCObrt+63MFokkQY0aAviNLy7mhGIdrufsVYvU64kOPsr2S+jOO
39 | o3rTBPBc6ltuNWp072GHggfU61y4Bvfqxq2IRRDVH+yjmsdKSPYoBSIs3ZKjwJGx
40 | pFAT1nfNP05MfqUwZm8HbTnqqakrWm0p53Zvv6NP3vNjmzECQQD6EK5a7bD7VSVz
41 | MawUgUkZGZUtForbZL5nwIo1j94/TbnxUuuwej0MiCJ0MQsPCY/LML/gYaxTdQOg
42 | qYkGyIAPAkEAzdXbgTc81FflECxc5CXw9Yi1g0+nMkH5drlk+sct5dCzokPJZBQ3
43 | oxIaQcJP/rUMgG0A2mSpOnbAHNHX+z/F+QJAEQGbafGqTJ1wy5HAOzDDsOJNg+B5
44 | lwwV6uZsP9JF8hYuJBxYjQrzJewIM9C2CNLEpbPuCKt71b0qfv2opP5zvwJAMyjh
45 | WveAvgJuo5tzJx2rC0wEWXPVya8OMw0XZSFWbhV2YHFav+4qefSI5ClIurUDO3Rc
46 | TuvQCAD19PPPK9qI+QJADpbLUWw8NsMaHpJgeigXVIsRtJcroDw2r87bJxsgcgQz
47 | CsIH32VLvFOmpJdwnji6GX+vD2i0UH4ythnMCq4NUg==
48 | -----END RSA PRIVATE KEY-----
49 | -----BEGIN CERTIFICATE REQUEST-----
50 | MIIBwTCCASoCAQAwgYAxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UE
51 | BxMCUkMxEDAOBgNVBAoTB2FjdHplcm8xEzARBgNVBAsTCnRlY2hub2xvZ3kxDzAN
52 | BgNVBAMTBnN5c2FkbTEfMB0GCSqGSIb3DQEJARYQaW5mb0BhY3R6ZXJvLmNvbTCB
53 | nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyRBB6l+DI3aMNeYf7IuodvZ9nNxn
54 | fQHVnGyRtwhb1g2tugTwFsE67oHA5qvwaDBILtsqkr9agXYDbZwJmV58xtBY675t
55 | ibf7/1R8mcDOd4Dremdn0CMyk4+n6Z8GpLJ59TZ3y98DXUOqbLvzzltDz0si2XVa
56 | 8G7f4K5k/xxBGZcCAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GBAIoUVScm4lAkfo1o
57 | n4b2Mpq3oV+dZnnTgYog4vmn/2UF0OSSTWlWPvINVkRtfg0iskZsbcWGn+RDY5e/
58 | aTqN7Xz+BV5XlbQLZzuQdKPsfBcZ766El1chmUuO5tELpFtQkmlAgAXRMuh0Xeb+
59 | A9wmVNyCMU6/+ajqwO642nSPOLM0
60 | -----END CERTIFICATE REQUEST-----
61 |
--------------------------------------------------------------------------------
/bid/inventory.servers:
--------------------------------------------------------------------------------
1 | # This list of servers was taken from the SOAPBuilders Interoperability Lab
2 | # (http://www.xmethods.net/ilab/ilab.html) 4/23/01.
3 | #
4 | # $Id$
5 |
6 | Name: MST Bid (Microsoft SOAP Toolkit 2.0, Microsoft Windows 2000)
7 | Endpoint: http://131.107.72.13/stk/Bid.wsdl
8 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
9 | Namespace: http://www.soapinterop.org/Bid
10 |
11 | Name: KeithBa's BidBuy Service (.NET Web Services)
12 | Endpoint: http://131.107.72.13/test/bidbuy/bidbuy.asmx
13 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
14 | Namespace: http://soapinterop.org/xsd
15 |
16 | Name: JHawk's BidBuyService (.NET Remoting, Win2K)
17 | Endpoint: http://131.107.72.13/DotNetRemotingNI/BidBuy.soap
18 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
19 | Namespace: http://www.soapinterop.org/Bid
20 |
21 | #Name: Idoox WASP
22 | #Endpoint: http://soap.idoox.net:8888/soap/servlet/Bid/
23 | #SOAPAction: "http://www.soapinterop.org/%(methodname)s"
24 | #Namespace: http://www.soapinterop.org/Bid
25 |
26 | Name: Paul's Quick Bid (SOAP::Lite)
27 | Endpoint: http://services.soaplite.com/tradeit.cgi
28 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
29 | Namespace: http://www.soapinterop.org/Bid
30 |
31 | Name: Phalanx Bid Service
32 | Endpoint: http://www.phalanxsys.com/ni/listener.asp
33 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
34 | Namespace: http://www.soapinterop.org/Bid
35 | Nonfunctional: Buy admitted problem with the wsdl
36 |
37 | Name: PranishK's BidBuy Service (ATL Web Service)
38 | Endpoint: http://www.mssoapinterop.org/atls_soap/bidbuy.dll?Handler=Default
39 | SOAPAction: "#%(methodname)s"
40 | Namespace: http://www.soapinterop.org/Bid
41 |
42 | Name: GLUE Bid
43 | Endpoint: http://209.61.190.164:8004/glue/http://www.soapinterop.org/Bid
44 | SOAPAction: "http://www.soapinterop.org/Bid#(methodname)s"
45 | Namespace: http://www.soapinterop.org/Bid
46 |
47 | Name: Aumsoft's BidBuy
48 | Endpoint: http://soap.aumsoft.com:8080/soap/BidBuy
49 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
50 | Namespace: http://www.soapinterop.org/Bid
51 |
52 | Name: SOAP.py 0.9 (actzero.com)
53 | Endpoint: http://208.177.157.221:12080/xmethodsInterop
54 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
55 | Namespace: http://www.soapinterop.org/Bid
56 |
57 | Name: HP SOAP
58 | Endpoint: http://soap.bluestone.com/scripts/SaISAPI.dll/SaServletEngine.class/hp-soap/soap/rpc/interop/BidBuy
59 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
60 | Namespace: http://www.soapinterop.org/Bid
61 |
62 | Name: EasySoap++ Bid Service (San Diego)
63 | Endpoint: http://easysoap.no-ip.com:8080/cgi-bin/bidbuyservice
64 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
65 | Namespace: http://www.soapinterop.org/Bid
66 |
67 | Name: Jake's Frontier 7.0b43 Bid Service (Santa Clara, CA)
68 | Endpoint: http://www.soapware.org/BidBuy
69 | SOAPAction: "http://www.soapinterop.org/%(methodname)s"
70 | Namespace: http://www.soapinterop.org/Bid
71 |
72 | #Name: Pete's Clear Bids (CapeConnect/Win2000)
73 | #Endpoint: http://208.46.17.81/ccx/SOAPServlet
74 | #SOAPAction: "http://www.soapinterop.org/%(methodname)s"
75 | #Namespace: http://www.soapinterop.org/Bid
76 |
77 | #Name: (PranishK's) ATL Server BidBuy
78 | #Endpoint: http://208.46.17.121/bidbuy/bidbuy.dll?Handler=Default
79 | #SOAPAction: "http://www.soapinterop.org/%(methodname)s"
80 | #Namespace: http://www.soapinterop.org/Bid
81 |
82 | #Name: HP-SOAP @ N+I
83 | #Endpoint: http://208.46.17.112/scripts/SaISAPI.dll/SaServletEngine.class/hp-soap/soap/rpc/interop/BidBuy
84 | #SOAPAction: "http://www.soapinterop.org/%(methodname)s"
85 | #Namespace: http://www.soapinterop.org/Bid
86 |
87 |
--------------------------------------------------------------------------------
/validate/soapware.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # This server validates as of 4/23/01 when run with UserLand's SOAP validator
4 | # (http://validator.soapware.org/).
5 |
6 | import getopt
7 | import sys
8 |
9 | sys.path.insert (1, '..')
10 |
11 | from SOAPpy import SOAP
12 |
13 | ident = '$Id$'
14 |
15 | def whichToolkit ():
16 | return SOAP.SOAPUserAgent ()
17 |
18 | def countTheEntities (s):
19 | counts = {'ctLeftAngleBrackets': 0, 'ctRightAngleBrackets': 0,
20 | 'ctAmpersands': 0, 'ctApostrophes': 0, 'ctQuotes': 0}
21 |
22 | for i in s:
23 | if i == '<':
24 | counts['ctLeftAngleBrackets'] += 1
25 | elif i == '>':
26 | counts['ctRightAngleBrackets'] += 1
27 | elif i == '&':
28 | counts['ctAmpersands'] += 1
29 | elif i == "'":
30 | counts['ctApostrophes'] += 1
31 | elif i == '"':
32 | counts['ctQuotes'] += 1
33 |
34 | return counts
35 |
36 | def easyStructTest (stooges):
37 | return stooges['larry'] + stooges['moe'] + stooges['curly']
38 |
39 | def echoStructTest (myStruct):
40 | return myStruct
41 |
42 | def manyTypesTest (num, bool, state, doub, dat, bin):
43 | return [num, SOAP.booleanType (bool), state, doub,
44 | SOAP.dateTimeType (dat), bin]
45 |
46 | def moderateSizeArrayCheck (myArray):
47 | return myArray[0] + myArray[-1]
48 |
49 | def nestedStructTest (myStruct):
50 | return easyStructTest (myStruct.year2000.month04.day01)
51 |
52 | def simpleStructReturnTest (myNumber):
53 | return {'times10': myNumber * 10, 'times100': myNumber * 100,
54 | 'times1000': myNumber * 1000}
55 |
56 | namespace = 'http://www.soapware.org/'
57 |
58 | DEFAULT_HOST = 'localhost'
59 | DEFAULT_PORT = 8080
60 |
61 | def usage (error = None):
62 | sys.stdout = sys.stderr
63 |
64 | if error != None:
65 | print error
66 |
67 | print """usage: %s [options]
68 | If a long option shows an argument is mandatory, it's mandatory for the
69 | equivalent short option also. The default (if any) is shown in brackets.
70 |
71 | -?, --help display this usage
72 | -h, --host=HOST use HOST in the address to listen on [%s]
73 | -p, --port=PORT listen on PORT [%d]
74 | """ % (sys.argv[0], DEFAULT_HOST, DEFAULT_PORT),
75 |
76 | sys.exit (0)
77 |
78 | def main ():
79 | host = DEFAULT_HOST
80 | port = DEFAULT_PORT
81 |
82 | try:
83 | opts, args = getopt.getopt (sys.argv[1:], '?h:p:',
84 | ['help', 'host', 'port'])
85 |
86 | for opt, arg in opts:
87 | if opt in ('-?', '--help'):
88 | usage ()
89 | elif opt in ('-h', '--host'):
90 | host = arg
91 | elif opt in ('-p', '--port'):
92 | port = int (arg)
93 | else:
94 | raise AttributeError, \
95 | "Recognized but unimplemented option `%s'" % opt
96 | except SystemExit:
97 | raise
98 | except:
99 | usage (sys.exc_info ()[1])
100 |
101 | server = SOAP.SOAPServer ((host, port))
102 |
103 | server.registerFunction (whichToolkit, namespace)
104 | server.registerFunction (countTheEntities)
105 | server.registerFunction (easyStructTest)
106 | server.registerFunction (echoStructTest)
107 | server.registerFunction (manyTypesTest)
108 | server.registerFunction (moderateSizeArrayCheck)
109 | server.registerFunction (nestedStructTest)
110 | server.registerFunction (simpleStructReturnTest)
111 |
112 | server.serve_forever()
113 |
114 | if __name__ == '__main__':
115 | try:
116 | sys.exit (main ())
117 | except KeyboardInterrupt:
118 | sys.exit (0)
119 |
--------------------------------------------------------------------------------
/docs/MethodParameterNaming.txt:
--------------------------------------------------------------------------------
1 |
2 | Experimental method for handing ordered vs named method parameters
3 | ------------------------------------------------------------------
4 |
5 | There is an incompatibility with the way that Python and SOAP handle
6 | method arguments: SOAP requires that all arguments have names and that
7 | they are presented in the same order as the method signature. Python
8 | (like other scripting languages, notably the S language) has the
9 | concept of unnamed arguments. Further Python does not preserve the
10 | order of named arguments, since they are handled using the dictionary
11 | data type. It seems to me that this makes it impossible to fully meet
12 | the SOAP specification without significant modifications to the Python
13 | method of handling named arguments or to the Python dictionary class.
14 |
15 | Historically SOAPpy has attempted to work around this issue by
16 | handling all arguments as unnamed unless the method or function was
17 | explicitly flagged, in which case all arguments were considered named.
18 | This has resulted in a several problems, particularly for a SOAPpy
19 | client communicating with a SOAPpy server. First, when named
20 | arguments were used in call to a non-flagged function, the argument
21 | would silently be reordered by the sender (since they were stored
22 | using a Python dictionary), *and* the names would be ignored by the
23 | receiver, which assumed that the parameters were unnamed and only the
24 | order was significant. This results in incorrect argument matching.
25 | This problem also occurred with mixed named and unnamed arguments.
26 |
27 | For my primary SOAP application, it is not reasonable to flag all of
28 | the SOAPpy methods as requiring named arguments, for a variety of
29 | reasons. One reason is that the available methods are not known
30 | apriori by the client software, hence the names of the arguments are
31 | not known. Second, many of the methods provide a large number of
32 | optional arguments, making it impractical to specify them all.
33 |
34 | In an attempt to overcome this problem, I implemented an experimental
35 | and non-standard method of handling named and unnamed arguments. This
36 | mechanism is enabled in SOAPpy by setting
37 | SOAPpy.SOAP.Config.specialArgs=1, and disabled by setting
38 | SOAPpy.SOAP.Config.specialArgs=0.
39 |
40 | When enabled, parameters with names of the form v#### (i.e., matching
41 | the regexp "^v[0-9]+$") are assumed to be unnamed parameters and are
42 | passed to the method in numeric order. All other parameters are
43 | assumed to be named and are passed using the name. Outgoing SOAP
44 | method calls now always generate names in this way--whether or not
45 | specialArgs is enabled.
46 |
47 |
48 | I selected the form v#### because it is a valid XML name, but is
49 | unlikely to be used as a parameter name.
50 |
51 | [As it turns out, this choice was fortitous because Apache's SOAP tool
52 | uses the same system.]
53 |
54 | In my testing, this mechanism for handling method parameter names
55 | works fine between a SOAPpy client and a SOAPpy server, and resolves
56 | the parameter reordering problems I was experiencing. This system
57 | seems unlikely to have any negative side effects on other SOAP
58 | applications, except in the (hopefully) rare case when v#### might be
59 | used as an actual parameter name.
60 |
61 | **In version 0.9.9-pre1, this feature is enabled by default.** Please
62 | let me know if there are situations where this causes problems.
63 |
64 | Note that this mechanism is only a partial solution, since it is still
65 | impossible to return named parameters in a specified order using
66 | SOAPpy. SOAP applications or implementations which require this
67 | feature are simply not compatible with SOAPpy.
68 |
69 | -Greg Warnes
70 | 2003-03-07 (updated 2003-11-14)
71 |
72 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/MIMEAttachment.py:
--------------------------------------------------------------------------------
1 | #TODO add the license
2 | #I had to rewrite this class because the python MIME email.mime (version 2.5)
3 | #are buggy, they use \n instead \r\n for new line which is not compliant
4 | #to standard!
5 | # http://bugs.python.org/issue5525
6 |
7 | #TODO do not load all the message in memory stream it from the disk
8 |
9 | import re
10 | import random
11 | import sys
12 |
13 |
14 | #new line
15 | NL='\r\n'
16 |
17 | _width = len(repr(sys.maxint-1))
18 | _fmt = '%%0%dd' % _width
19 |
20 | class MIMEMessage:
21 |
22 | def __init__(self):
23 | self._files = []
24 | self._xmlMessage = ""
25 | self._startCID = ""
26 | self._boundary = ""
27 |
28 | def makeBoundary(self):
29 | #create the boundary
30 | msgparts = []
31 | msgparts.append(self._xmlMessage)
32 | for i in self._files:
33 | msgparts.append(i.read())
34 | #this sucks, all in memory
35 | alltext = NL.join(msgparts)
36 | self._boundary = _make_boundary(alltext)
37 | #maybe I can save some memory
38 | del alltext
39 | del msgparts
40 | self._startCID = "<" + (_fmt % random.randrange(sys.maxint)) + (_fmt % random.randrange(sys.maxint)) + ">"
41 |
42 |
43 | def toString(self):
44 | '''it return a string with the MIME message'''
45 | if len(self._boundary) == 0:
46 | #the makeBoundary hasn't been called yet
47 | self.makeBoundary()
48 | #ok we have everything let's start to spit the message out
49 | #first the XML
50 | returnstr = NL + "--" + self._boundary + NL
51 | returnstr += "Content-Type: text/xml; charset=\"us-ascii\"" + NL
52 | returnstr += "Content-Transfer-Encoding: 7bit" + NL
53 | returnstr += "Content-Id: " + self._startCID + NL + NL
54 | returnstr += self._xmlMessage + NL
55 | #then the files
56 | for file in self._files:
57 | returnstr += "--" + self._boundary + NL
58 | returnstr += "Content-Type: application/octet-stream" + NL
59 | returnstr += "Content-Transfer-Encoding: binary" + NL
60 | returnstr += "Content-Id: <" + str(id(file)) + ">" + NL + NL
61 | file.seek(0)
62 | returnstr += file.read() + NL
63 | #closing boundary
64 | returnstr += "--" + self._boundary + "--" + NL
65 | return returnstr
66 |
67 | def attachFile(self, file):
68 | '''
69 | it adds a file to this attachment
70 | '''
71 | self._files.append(file)
72 |
73 | def addXMLMessage(self, xmlMessage):
74 | '''
75 | it adds the XML message. we can have only one XML SOAP message
76 | '''
77 | self._xmlMessage = xmlMessage
78 |
79 | def getBoundary(self):
80 | '''
81 | this function returns the string used in the mime message as a
82 | boundary. First the write method as to be called
83 | '''
84 | return self._boundary
85 |
86 | def getStartCID(self):
87 | '''
88 | This function returns the CID of the XML message
89 | '''
90 | return self._startCID
91 |
92 |
93 | def _make_boundary(text=None):
94 | #some code taken from python stdlib
95 | # Craft a random boundary. If text is given, ensure that the chosen
96 | # boundary doesn't appear in the text.
97 | token = random.randrange(sys.maxint)
98 | boundary = ('=' * 10) + (_fmt % token) + '=='
99 | if text is None:
100 | return boundary
101 | b = boundary
102 | counter = 0
103 | while True:
104 | cre = re.compile('^--' + re.escape(b) + '(--)?$', re.MULTILINE)
105 | if not cre.search(text):
106 | break
107 | b = boundary + '.' + str(counter)
108 | counter += 1
109 | return b
110 |
111 |
--------------------------------------------------------------------------------
/SOAPpy/NS.py:
--------------------------------------------------------------------------------
1 | from __future__ import nested_scopes
2 |
3 | """
4 | ################################################################################
5 | #
6 | # SOAPpy - Cayce Ullman (cayce@actzero.com)
7 | # Brian Matthews (blm@actzero.com)
8 | # Gregory Warnes (Gregory.R.Warnes@Pfizer.com)
9 | # Christopher Blunck (blunck@gst.com)
10 | #
11 | ################################################################################
12 | # Copyright (c) 2003, Pfizer
13 | # Copyright (c) 2001, Cayce Ullman.
14 | # Copyright (c) 2001, Brian Matthews.
15 | #
16 | # All rights reserved.
17 | #
18 | # Redistribution and use in source and binary forms, with or without
19 | # modification, are permitted provided that the following conditions are met:
20 | # Redistributions of source code must retain the above copyright notice, this
21 | # list of conditions and the following disclaimer.
22 | #
23 | # Redistributions in binary form must reproduce the above copyright notice,
24 | # this list of conditions and the following disclaimer in the documentation
25 | # and/or other materials provided with the distribution.
26 | #
27 | # Neither the name of actzero, inc. nor the names of its contributors may
28 | # be used to endorse or promote products derived from this software without
29 | # specific prior written permission.
30 | #
31 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
35 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 | #
42 | ################################################################################
43 | """
44 |
45 | ident = '$Id$'
46 | from version import __version__
47 |
48 | ##############################################################################
49 | # Namespace Class
50 | ################################################################################
51 | def invertDict(dict):
52 | d = {}
53 |
54 | for k, v in dict.items():
55 | d[v] = k
56 |
57 | return d
58 |
59 | class NS:
60 | XML = "http://www.w3.org/XML/1998/namespace"
61 |
62 | ENV = "http://schemas.xmlsoap.org/soap/envelope/"
63 | ENC = "http://schemas.xmlsoap.org/soap/encoding/"
64 |
65 | XSD = "http://www.w3.org/1999/XMLSchema"
66 | XSD2 = "http://www.w3.org/2000/10/XMLSchema"
67 | XSD3 = "http://www.w3.org/2001/XMLSchema"
68 |
69 | XSD_L = [XSD, XSD2, XSD3]
70 | EXSD_L= [ENC, XSD, XSD2, XSD3]
71 |
72 | XSI = "http://www.w3.org/1999/XMLSchema-instance"
73 | XSI2 = "http://www.w3.org/2000/10/XMLSchema-instance"
74 | XSI3 = "http://www.w3.org/2001/XMLSchema-instance"
75 | XSI_L = [XSI, XSI2, XSI3]
76 |
77 | URN = "http://soapinterop.org/xsd"
78 |
79 | # For generated messages
80 | XML_T = "xml"
81 | ENV_T = "SOAP-ENV"
82 | ENC_T = "SOAP-ENC"
83 | XSD_T = "xsd"
84 | XSD2_T= "xsd2"
85 | XSD3_T= "xsd3"
86 | XSI_T = "xsi"
87 | XSI2_T= "xsi2"
88 | XSI3_T= "xsi3"
89 | URN_T = "urn"
90 |
91 | NSMAP = {ENV_T: ENV, ENC_T: ENC, XSD_T: XSD, XSD2_T: XSD2,
92 | XSD3_T: XSD3, XSI_T: XSI, XSI2_T: XSI2, XSI3_T: XSI3,
93 | URN_T: URN}
94 | NSMAP_R = invertDict(NSMAP)
95 |
96 | STMAP = {'1999': (XSD_T, XSI_T), '2000': (XSD2_T, XSI2_T),
97 | '2001': (XSD3_T, XSI3_T)}
98 | STMAP_R = invertDict(STMAP)
99 |
100 | def __init__(self):
101 | raise Error, "Don't instantiate this"
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/validate/silabserver.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | # This is a server for the XMethods matrix
6 | # (http://jake.soapware.org/currentXmethodsResults).
7 |
8 | import getopt
9 | import sys
10 |
11 | sys.path.insert (1, '..')
12 |
13 | from SOAPpy import SOAP
14 |
15 | if SOAP.Config.SSLserver:
16 | from M2Crypto import SSL
17 |
18 | ident = '$Id$'
19 |
20 | def echoFloat (inputFloat):
21 | return inputFloat
22 |
23 | def echoFloatArray (inputFloatArray):
24 | return inputFloatArray
25 |
26 | def echoInteger (inputInteger):
27 | return inputInteger
28 |
29 | def echoIntegerArray (inputIntegerArray):
30 | return inputIntegerArray
31 |
32 | def echoString (inputString):
33 | return inputString
34 |
35 | def echoStringArray (inputStringArray):
36 | return inputStringArray
37 |
38 | def echoStruct (inputStruct):
39 | return inputStruct
40 |
41 | def echoStructArray (inputStructArray):
42 | return inputStructArray
43 |
44 | def echoVoid ():
45 | return SOAP.voidType()
46 |
47 | def echoDate (inputDate):
48 | return SOAP.dateTimeType (inputDate)
49 |
50 | def echoBase64 (inputBase64):
51 | return SOAP.binaryType (inputBase64)
52 |
53 | namespace = 'http://soapinterop.org/'
54 |
55 | DEFAULT_HOST = 'localhost'
56 | DEFAULT_HTTP_PORT = 8080
57 | DEFAULT_HTTPS_PORT = 8443
58 |
59 | def usage (error = None):
60 | sys.stdout = sys.stderr
61 |
62 | if error != None:
63 | print error
64 |
65 | print """usage: %s [options]
66 | If a long option shows an argument is mandatory, it's mandatory for the
67 | equivalent short option also. The default (if any) is shown in brackets.
68 |
69 | -?, --help display this usage
70 | -h, --host=HOST use HOST in the address to listen on [%s]
71 | -p, --port=PORT listen on PORT [%d]
72 | """ % (sys.argv[0], DEFAULT_HOST, DEFAULT_HTTP_PORT),
73 |
74 | if SOAP.Config.SSLserver:
75 | print " -s, --ssl serve using SSL"
76 |
77 | sys.exit (0)
78 |
79 | def main ():
80 | host = DEFAULT_HOST
81 | port = None
82 | ssl = 0
83 |
84 | try:
85 | opts = '?h:p:'
86 | args = ['help', 'host', 'port']
87 |
88 | if SOAP.Config.SSLserver:
89 | opts += 's'
90 | args += ['ssl']
91 |
92 | opts, args = getopt.getopt (sys.argv[1:], opts, args)
93 |
94 | for opt, arg in opts:
95 | if opt in ('-?', '--help'):
96 | usage ()
97 | elif opt in ('-h', '--host'):
98 | host = arg
99 | elif opt in ('-p', '--port'):
100 | port = int (arg)
101 | elif opt in ('-s', '--ssl'):
102 | ssl = 1
103 | else:
104 | raise AttributeError, \
105 | "Recognized but unimplemented option `%s'" % opt
106 | except SystemExit:
107 | raise
108 | except:
109 | usage (sys.exc_info ()[1])
110 |
111 | if port == None:
112 | port = [DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT][ssl]
113 |
114 | if ssl:
115 | ssl_context = SSL.Context()
116 | ssl_context.load_cert('server.pem')
117 | else:
118 | ssl_context = None
119 |
120 | server = SOAP.SOAPServer ((host, port), namespace = namespace,
121 | ssl_context = ssl_context)
122 |
123 | server.registerFunction (echoFloat)
124 | server.registerFunction (echoFloatArray)
125 | server.registerFunction (echoInteger)
126 | server.registerFunction (echoIntegerArray)
127 | server.registerFunction (echoString)
128 | server.registerFunction (echoStringArray)
129 | server.registerFunction (echoStruct)
130 | server.registerFunction (echoStructArray)
131 | server.registerFunction (echoVoid)
132 | server.registerFunction (echoDate)
133 | server.registerFunction (echoBase64)
134 |
135 | server.serve_forever()
136 |
137 | if __name__ == '__main__':
138 | try:
139 | sys.exit (main ())
140 | except KeyboardInterrupt:
141 | sys.exit (0)
142 |
--------------------------------------------------------------------------------
/docs/GlobusSupport.txt:
--------------------------------------------------------------------------------
1 |
2 | Globus Support
3 | ==============
4 |
5 | Extensions have been added to the SOAPpy module to allow the use of the
6 | Globus Toolkit v2 for secure transport of SOAP calls. These extensions are
7 | possible by using the Globus Toolkit (http://www.globus.org) and the
8 | pyGlobus software (http://www-itg.lbl.gov/gtg/projects/pyGlobus/), which
9 | exposes the Globus Toolkit via a set of Python interfaces. This enables
10 | bi-directional PKI authentication so that the server and client are both
11 | guaranteed of the identity of the other. Using PKI this way also allows a
12 | more robust authorization solution above the SOAP hosting layer, which
13 | provides better application level authorization control. These tools are
14 | used by the Access Grid Project (http://www.accessgrid.org) to build a
15 | Grid-based, Web Services based, real-time collaboration environment.
16 |
17 | In order to use the SOAPpy module with the Globus Toolkit, you must first
18 | obtain and install the Globus Toolkit and pyGlobus software. Information on
19 | how to do that is at the respective web sites listed below. In order to use
20 | the Globus Toolkit it is necessary to have an x509 identity certificate.
21 | Information on how to obtain one of those is available on the web as well.
22 |
23 | To use GSI with an authorization method, set the SOAPConfig.authMethod =
24 | "methodname". You must have this method defined on any objects you register
25 | with SOAPpy, and/or as a registered method. It should return 0 or 1 to
26 | indicate if authorization is allowed or not.
27 |
28 | Once the software is installed, you have obtained your certificate, and the
29 | SOAPpy module is installed, the following code shows how to run a GSI
30 | secured SOAP server (These snippets are directly from the echoServer.py and
31 | echoClient.py in the test directory).
32 |
33 | Server
34 | ------
35 |
36 | def _authorize(self, *args, **kw):
37 | return 1
38 |
39 | Config.authMethod = "_authorize"
40 |
41 | addr = ('localhost', 9900)
42 | from SOAPpy.GSIServer import GSISOAPServer
43 | server = GSISOAPServer(addr)
44 |
45 | server.registerFunction(_authorize)
46 | server.registerFunction(echo)
47 |
48 | Then you use the server like the SSL server or the standard server.
49 |
50 | Client
51 | ------
52 |
53 | import pyGlobus
54 |
55 | # The httpg distinguishes this as a GSI TCP connection, so after
56 | # this you can use the SOAP proxy as you would any other SOAP Proxy.
57 |
58 | server = SOAPProxy("httpg://localhost:9900/")
59 | print server.echo("moo")
60 |
61 |
62 |
63 | Globus Toolkit http://www.globus.org
64 | ------------------------------------
65 |
66 | The Globus Toolkit is an open source software toolkit used for
67 | building grids. It is being developed by the Globus Alliance and
68 | many others all over the world. A growing number of projects and
69 | companies are using the Globus Toolkit to unlock the potential
70 | of grids for their cause.
71 |
72 | PyGlobus http://www-itg.lbl.gov/gtg/projects/pyGlobus/
73 | ------------------------------------------------------
74 |
75 | The goal of this project is to allow the use of the entire
76 | Globus toolkit from Python, a high-level scripting
77 | language. SWIG is used to generate the necessary interface
78 | code. Currently a substantial subset of the 2.2.4 and 2.4
79 | versions of the Globus toolkit has been wrapped.
80 |
81 | The Access Grid http://www.accessgrid.org/
82 | ------------------------------------------
83 |
84 | The Access GridT is an ensemble of resources including
85 | multimedia large-format displays, presentation and interactive
86 | environments, and interfaces to Grid middleware and to
87 | visualization environments. These resources are used to support
88 | group-to-group interactions across the Grid. For example, the
89 | Access Grid (AG) is used for large-scale distributed meetings,
90 | collaborative work sessions, seminars, lectures, tutorials, and
91 | training. The Access Grid thus differs from desktop-to-desktop
92 | tools that focus on individual communication.
93 |
94 | - Submitted 2004-01-08 by Ivan R. Judson
95 |
96 |
97 | $Id$
98 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/UserTuple.py:
--------------------------------------------------------------------------------
1 | """
2 | A more or less complete user-defined wrapper around tuple objects.
3 | Adapted version of the standard library's UserList.
4 |
5 | Taken from Stefan Schwarzer's ftputil library, available at
6 | , and used under this license:
7 |
8 |
9 |
10 |
11 | Copyright (C) 1999, Stefan Schwarzer
12 | All rights reserved.
13 |
14 | Redistribution and use in source and binary forms, with or without
15 | modification, are permitted provided that the following conditions are
16 | met:
17 |
18 | - Redistributions of source code must retain the above copyright
19 | notice, this list of conditions and the following disclaimer.
20 |
21 | - Redistributions in binary form must reproduce the above copyright
22 | notice, this list of conditions and the following disclaimer in the
23 | documentation and/or other materials provided with the distribution.
24 |
25 | - Neither the name of the above author nor the names of the
26 | contributors to the software may be used to endorse or promote
27 | products derived from this software without specific prior written
28 | permission.
29 |
30 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
34 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
36 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
37 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
38 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
39 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 |
42 | """
43 |
44 |
45 |
46 |
47 | # $Id$
48 |
49 | #XXX tuple instances (in Python 2.2) contain also:
50 | # __class__, __delattr__, __getattribute__, __hash__, __new__,
51 | # __reduce__, __setattr__, __str__
52 | # What about these?
53 |
54 | class UserTuple:
55 | def __init__(self, inittuple=None):
56 | self.data = ()
57 | if inittuple is not None:
58 | # XXX should this accept an arbitrary sequence?
59 | if type(inittuple) == type(self.data):
60 | self.data = inittuple
61 | elif isinstance(inittuple, UserTuple):
62 | # this results in
63 | # self.data is inittuple.data
64 | # but that's ok for tuples because they are
65 | # immutable. (Builtin tuples behave the same.)
66 | self.data = inittuple.data[:]
67 | else:
68 | # the same applies here; (t is tuple(t)) == 1
69 | self.data = tuple(inittuple)
70 | def __repr__(self): return repr(self.data)
71 | def __lt__(self, other): return self.data < self.__cast(other)
72 | def __le__(self, other): return self.data <= self.__cast(other)
73 | def __eq__(self, other): return self.data == self.__cast(other)
74 | def __ne__(self, other): return self.data != self.__cast(other)
75 | def __gt__(self, other): return self.data > self.__cast(other)
76 | def __ge__(self, other): return self.data >= self.__cast(other)
77 | def __cast(self, other):
78 | if isinstance(other, UserTuple): return other.data
79 | else: return other
80 | def __cmp__(self, other):
81 | return cmp(self.data, self.__cast(other))
82 | def __contains__(self, item): return item in self.data
83 | def __len__(self): return len(self.data)
84 | def __getitem__(self, i): return self.data[i]
85 | def __getslice__(self, i, j):
86 | i = max(i, 0); j = max(j, 0)
87 | return self.__class__(self.data[i:j])
88 | def __add__(self, other):
89 | if isinstance(other, UserTuple):
90 | return self.__class__(self.data + other.data)
91 | elif isinstance(other, type(self.data)):
92 | return self.__class__(self.data + other)
93 | else:
94 | return self.__class__(self.data + tuple(other))
95 | # dir( () ) contains no __radd__ (at least in Python 2.2)
96 | def __mul__(self, n):
97 | return self.__class__(self.data*n)
98 | __rmul__ = __mul__
99 |
100 |
--------------------------------------------------------------------------------
/tests/storageTest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ident = '$Id$'
4 |
5 | import sys, os, time, signal, re
6 | sys.path.insert(1, "..")
7 | from SOAPpy import SOAPProxy, SOAPConfig, SOAPUserAgent
8 |
9 | # Check for a web proxy definition in environment
10 | try:
11 | proxy_url=os.environ['http_proxy']
12 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
13 | http_proxy = "%s:%s" % (phost, pport)
14 | except:
15 | http_proxy = None
16 |
17 |
18 | PROXY="http://www.soapware.org/xmlStorageSystem"
19 | EMAIL="SOAPpy@actzero.com"
20 | NAME="test_user"
21 | PASSWORD="mypasswd"
22 | SERIAL=1123214
23 |
24 | MY_PORT=15600
25 |
26 | def resourceChanged (url):
27 | print "\n##### NOTIFICATION MESSAGE: Resource %s has changed #####\n" % url
28 | return booleanType(1)
29 |
30 | def printstatus (cmd, stat):
31 | print
32 | if stat.flError:
33 | print "### %s failed: %s ###" % (cmd, stat.message)
34 | else:
35 | print "### %s successful: %s ###" % (cmd, stat.message)
36 | return not stat.flError
37 |
38 | server = SOAPProxy(encoding="US-ASCII",
39 | proxy=PROXY,
40 | soapaction="/xmlStorageSystem",
41 | http_proxy=http_proxy,
42 | # config=SOAPConfig(debug=1)
43 | )
44 |
45 | # Register as a new user or update user information
46 | reg = server.registerUser(email=EMAIL, name=NAME, password=PASSWORD,
47 | clientPort=MY_PORT, userAgent=SOAPUserAgent(),
48 | serialnumber=SERIAL)
49 | printstatus("registerUser", reg)
50 |
51 | # See what this server can do
52 | reg = server.getServerCapabilities (email=EMAIL, password=PASSWORD)
53 | if printstatus("getServerCapabilities", reg):
54 | print "Legal file extensions: " + str(reg.legalFileExtensions)
55 | print "Maximum file size: " + str(reg.maxFileSize)
56 | print "Maximum bytes per user: " + str(reg.maxBytesPerUser)
57 | print "Number of bytes in use by the indicated user: " + str(reg.ctBytesInUse)
58 | print "URL of the folder containing your files: " + str(reg.yourUpstreamFolderUrl)
59 |
60 | # Store some files
61 | reg = server.saveMultipleFiles (email=EMAIL, password=PASSWORD,
62 | relativepathList=['index.html','again.html'],
63 | fileTextList=['bennett@actzero.com home page' +
64 | 'Hello Earth',
65 | 'bennett@actzero.com home page' +
66 | 'Hello Earth Again'])
67 | if printstatus("saveMultipleFiles", reg):
68 | print "Files stored:"
69 | for file in reg.urlList:
70 | print " %s" % file
71 |
72 | # Save this for call to test pleaseNotify
73 | mylist = reg.urlList
74 | else:
75 | mylist = []
76 |
77 | # Check to see what files are stored
78 | reg = server.getMyDirectory (email=EMAIL, password=PASSWORD)
79 | if printstatus("getMyDirectory", reg):
80 | i = 1
81 | while hasattr(reg.directory, "file%05d" % i):
82 | d = getattr(reg.directory, "file%05d" % i)
83 | print "Relative Path: %s" % d.relativePath
84 | print "Size: %d" % d.size
85 | print "Created: %s" % d.whenCreated
86 | print "Last Uploaded: %s" % d.whenLastUploaded
87 | print "URL: %s" % d.url
88 | print
89 | i += 1
90 |
91 | # Set up notification
92 | reg = server.pleaseNotify(notifyProcedure="resourceChanged", port=MY_PORT, path="/", protocol="soap", urlList=mylist)
93 | printstatus("notifyProcedure", reg)
94 |
95 | pid = os.fork()
96 | if pid == 0:
97 | # I am a child process. Set up SOAP server to receive notification
98 | print
99 | print "## Starting notification server ##"
100 |
101 | s = SOAPServer(('localhost', MY_PORT))
102 | s.registerFunction(resourceChanged)
103 | s.serve_forever()
104 |
105 | else:
106 |
107 | def handler(signum, frame):
108 | # Kill child process
109 | print "Killing child process %d" % pid
110 | os.kill(pid, signal.SIGINT)
111 |
112 | signal.signal(signal.SIGINT, handler)
113 |
114 | # I am a parent process
115 | # Change some files
116 | time.sleep(3)
117 | reg = server.saveMultipleFiles (email=EMAIL, password=PASSWORD,
118 | relativepathList=['index.html'],
119 | fileTextList=['bennett@actzero.com home page' +
120 | 'Hello Bennett'])
121 | if printstatus("saveMultipleFiles", reg):
122 | print "Files stored:"
123 | for file in reg.urlList:
124 | print " %s" % file
125 |
126 | os.waitpid(pid, 0)
127 |
--------------------------------------------------------------------------------
/tests/TCtest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys, unittest
4 | sys.path.insert(1, "..")
5 | from SOAPpy import *
6 | Config.debug=1
7 |
8 | class ClientTestCase(unittest.TestCase):
9 | def testParseRules(self):
10 | x = """
11 |
15 |
17 |
18 |
19 |
20 | My Life and Work
21 |
22 |
23 | Henry Ford
24 | 49
25 | 5.5
26 |
27 |
28 |
29 |
30 |
31 | """
32 |
33 | def negfloat(x):
34 | return float(x) * -1.0
35 |
36 | # parse rules
37 | pr = {'SomeMethod':
38 | {'Result':
39 | {
40 | 'Book': {'title':'string'},
41 | 'Person': {'age':'int',
42 | 'height':negfloat}
43 | }
44 | }
45 | }
46 | y = parseSOAPRPC(x, rules=pr)
47 |
48 | assert y.Result.Person.age == 49
49 | assert y.Result.Person.height == -5.5
50 |
51 |
52 | x = '''
58 |
59 |
60 |
61 | - 12
62 | - 23
63 | - 0
64 | - -31
65 |
66 |
67 |
68 |
69 |
70 | '''
71 |
72 |
73 | # parse rules
74 | pr = {'Bounds':
75 | {'param': 'arrayType=string[]',
76 | }
77 | }
78 |
79 | pr2 = {'Bounds':
80 | {'param': 'arrayType=int[4]',
81 | }
82 | }
83 |
84 | y = parseSOAPRPC(x, rules=pr)
85 | assert y.param[1]=='23'
86 |
87 | y = parseSOAPRPC(x, rules=pr2)
88 | assert y.param[1]==23
89 |
90 | x = '''
96 |
97 |
98 |
99 |
100 | - 12
101 | - 23
102 | - 0
103 | - -31
104 |
105 |
106 |
107 |
108 |
109 | '''
110 |
111 | pr = {'Bounds':
112 | {'param': 'arrayType=ur-type[]'
113 | }
114 | }
115 | y = parseSOAPRPC(x, rules=pr)
116 | assert y.param[0]==12
117 | assert y.param[1]=='23'
118 | assert y.param[2]==float(0)
119 | assert y.param[3]==-31
120 |
121 | # Try the reverse, not implemented yet.
122 |
123 | def testBuildObject(self):
124 |
125 | class Book(structType):
126 | def __init__(self):
127 | self.title = "Title of a book"
128 |
129 | class Person(structType):
130 | def __init__(self):
131 | self.age = "49"
132 | self.height = "5.5"
133 |
134 | class Library(structType):
135 | def __init__(self):
136 | self._name = "Result"
137 | self.Book = Book()
138 | self.Person = Person()
139 |
140 | obj = Library()
141 |
142 | x = buildSOAP( kw={'Library':obj} )
143 |
144 | print(x)
145 |
146 | if __name__ == '__main__':
147 | unittest.main()
148 |
--------------------------------------------------------------------------------
/bid/inventoryServer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Copyright (c) 2001, actzero, inc.
3 | import sys
4 | sys.path.insert(1,"..")
5 | from SOAPpy import SOAP
6 | #SOAP.Config.debug = 1
7 | serverstring = "SOAP.py (actzero.com) running "+sys.platform
8 | NUMBUYS = 0
9 | NUMSIMPLEBUYS = 0
10 | NUMREQUESTS = 0
11 | NUMPINGS = 0
12 |
13 | def SimpleBuy(Address, ProductName, Quantity):
14 | # currently, this type-checks the params, and makes sure
15 | # the strings are of len > 0
16 | global NUMSIMPLEBUYS
17 | NUMSIMPLEBUYS += 1
18 | if Quantity < 1: raise ValueError, "must order at least one"
19 | else: return "Receipt for %d %s(s) bought from %s" % (int(Quantity), ProductName, serverstring)
20 |
21 |
22 | def RequestForQuote(ProductName, Quantity):
23 | # type-checks and makes sure Quantity >= 1
24 | global NUMREQUESTS
25 | NUMREQUESTS += 1
26 | if Quantity < 1: raise ValueError, "must order at least 1"
27 | else:
28 | import whrandom
29 | mult = whrandom.random()
30 | times = 0
31 | while mult > 0.25:
32 | mult = mult - 0.25
33 | times += 1
34 | mult += 0.5
35 | mult = round(mult, 3)
36 | print mult, times
37 | return SOAP.doubleType(round(mult*int(Quantity),2))
38 |
39 |
40 | def Buy(**kw):
41 |
42 | global NUMBUYS
43 | NUMBUYS += 1
44 | try:
45 | PurchaseOrder = kw["PurchaseOrder"]
46 | except:
47 | PurchaseOrder = kw["PO"]
48 | try:
49 | POkeys = PurchaseOrder['_keyord']
50 | POkeys.sort()
51 | POkeys_expected = ["shipTo","billTo","items","poID","createDate"]
52 | POkeys_expected.sort()
53 | if POkeys != POkeys_expected:
54 | raise ValueError, "struct 'PurchaseOrder' needs %s, %s, %s, %s, and %s" % tuple(POkeys_expected)
55 | except:
56 | raise TypeError, "'PurchaseOrder' missing one or more element(s)"
57 |
58 | try:
59 | btkeys = PurchaseOrder["billTo"]["_keyord"]
60 | btkeys.sort()
61 | btkeys_expected = ["address","zipCode","name","state","city"]
62 | btkeys_expected.sort()
63 | except:
64 | raise TypeError, "'billTo' missing one or more elements"
65 |
66 | try:
67 | stkeys = PurchaseOrder["shipTo"]["_keyord"]
68 | stkeys.sort()
69 | stkeys_expected = ["address","zipCode","name","state","city"]
70 | stkeys_expected.sort()
71 | except:
72 | raise TypeError, "'shipTo' missing one or more elements"
73 |
74 |
75 | try:
76 | items = PurchaseOrder["items"].__dict__
77 | data = items["data"]
78 | retstring = ""
79 | for item in data:
80 | itemdict = item["_asdict"]
81 | q = itemdict["quantity"]
82 | p = itemdict["price"]
83 | name = itemdict["name"]
84 | if retstring != "":
85 | retstring += ", "
86 | else:
87 | retstring = "bought "
88 | retstring += "%d %s(s) for %.2f" % (q,name,p)
89 | retstring += " from "+serverstring
90 | return retstring
91 |
92 | except:
93 | raise TypeError, "items must be an array of 'item' structs"
94 |
95 | def Ping():
96 | global NUMPINGS
97 | NUMPINGS += 1
98 | return
99 |
100 | def Monitor(str):
101 | if str=="actzero":
102 | global NUMBUYS
103 | global NUMREQUESTS
104 | global NUMSIMPLEBUYS
105 | global NUMPINGS
106 | return "(Buys, RequestForQuote(s),SimpleBuy(s), Ping(s)) = " + \
107 | repr( (NUMBUYS,NUMREQUESTS,NUMSIMPLEBUYS, NUMPINGS) )
108 | else:
109 | raise ValueError, "not the right string"
110 |
111 | def Clear(str):
112 | if str=="actzero":
113 | global NUMBUYS
114 | global NUMREQUESTS
115 | global NUMSIMPLEBUYS
116 | global NUMPINGS
117 | NUMBUYS = 0
118 | NUMREQUESTS = 0
119 | NUMSIMPLEBUYS = 0
120 | NUMPINGS = 0
121 | return "(Buys, RequestForQuote(s),SimpleBuy(s), Ping(s)) = " + \
122 | repr( (NUMBUYS,NUMREQUESTS,NUMSIMPLEBUYS, NUMPINGS) )
123 | else:
124 | raise ValueError, "not the right string"
125 |
126 |
127 | if __name__ == "__main__":
128 | if len(sys.argv) > 1:
129 | try:
130 | port = int(sys.argv[1])
131 | if port not in range(2000,15000): raise ValueError
132 | except:
133 | print "port must be a number between 2000 and 15000"
134 | sys.exit(1)
135 | else: port = 9000
136 | namespace = "http://www.soapinterop.org/Bid"
137 | server = SOAP.SOAPServer( ('zoo',port) )
138 |
139 | server.registerKWFunction(SimpleBuy, namespace )
140 | server.registerKWFunction(RequestForQuote, namespace )
141 | server.registerKWFunction(Buy, namespace )
142 | server.registerKWFunction(Ping, namespace )
143 | server.registerKWFunction(Monitor, namespace )
144 | server.registerKWFunction(Clear, namespace )
145 |
146 | try:
147 | server.serve_forever()
148 | except KeyboardInterrupt:
149 | pass
150 |
--------------------------------------------------------------------------------
/tests/testWSDL.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import unittest
4 | import os, re
5 | import sys
6 | sys.path.insert (1, '..')
7 | import SOAPpy
8 |
9 | ident = '$Id$'
10 |
11 | # Check for a web proxy definition in environment
12 | try:
13 | proxy_url=os.environ['http_proxy']
14 | phost, pport = re.search('http://([^:]+):([0-9]+)', proxy_url).group(1,2)
15 | http_proxy = "%s:%s" % (phost, pport)
16 | except:
17 | http_proxy = None
18 |
19 |
20 |
21 | class IntegerArithmenticTestCase(unittest.TestCase):
22 |
23 | def setUp(self):
24 | self.wsdlstr1 = '''
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
51 | Returns current temperature in a given U.S. zipcode
52 |
53 |
54 |
55 |
56 |
57 | '''
58 |
59 | def testParseWsdlString(self):
60 | '''Parse XMethods TemperatureService wsdl from a string.'''
61 |
62 | wsdl = SOAPpy.WSDL.Proxy(self.wsdlstr1, http_proxy=http_proxy)
63 | self.assertEquals(len(wsdl.methods), 1)
64 | method = wsdl.methods.values()[0]
65 | self.assertEquals(method.methodName, 'getTemp')
66 | self.assertEquals(method.namespace, 'urn:xmethods-Temperature')
67 | self.assertEquals(method.location,
68 | 'http://services.xmethods.net:80/soap/servlet/rpcrouter')
69 |
70 | def testParseWsdlFile(self):
71 | '''Parse XMethods TemperatureService wsdl from a file.'''
72 |
73 | # figure out path to the test directory
74 | dir = os.path.abspath('.')
75 | fname = './TemperatureService.wsdl'
76 |
77 | try:
78 | f = file(fname)
79 | except (IOError, OSError):
80 | self.assert_(0, 'Cound not find wsdl file "%s"' % file)
81 |
82 | wsdl = SOAPpy.WSDL.Proxy(fname, http_proxy=http_proxy)
83 | self.assertEquals(len(wsdl.methods), 1)
84 | method = wsdl.methods.values()[0]
85 | self.assertEquals(method.methodName, 'getTemp')
86 | self.assertEquals(method.namespace, 'urn:xmethods-Temperature')
87 | self.assertEquals(method.location,
88 | 'http://services.xmethods.net:80/soap/servlet/rpcrouter')
89 |
90 | def testParseWsdlUrl(self):
91 | '''Parse XMethods TemperatureService wsdl from a url.'''
92 |
93 | wsdl = SOAPpy.WSDL.Proxy('http://www.xmethods.net/sd/2001/TemperatureService.wsdl', http_proxy=http_proxy)
94 | self.assertEquals(len(wsdl.methods), 1)
95 | method = wsdl.methods.values()[0]
96 | self.assertEquals(method.methodName, 'getTemp')
97 | self.assertEquals(method.namespace, 'urn:xmethods-Temperature')
98 | self.assertEquals(method.location,
99 | 'http://services.xmethods.net:80/soap/servlet/rpcrouter')
100 |
101 | def testGetTemp(self):
102 | '''Parse TemperatureService and call getTemp.'''
103 |
104 | zip = '01072'
105 | proxy = SOAPpy.WSDL.Proxy(self.wsdlstr1, http_proxy=http_proxy)
106 | temp = proxy.getTemp(zip)
107 | print 'Temperature at', zip, 'is', temp
108 |
109 |
110 | if __name__ == '__main__':
111 | unittest.main()
112 |
113 |
--------------------------------------------------------------------------------
/SOAPpy/WSDL.py:
--------------------------------------------------------------------------------
1 | """Parse web services description language to get SOAP methods.
2 |
3 | Rudimentary support."""
4 |
5 | ident = '$Id$'
6 | from version import __version__
7 |
8 | import wstools
9 | import xml
10 | from Errors import Error
11 | from Client import SOAPProxy, SOAPAddress
12 | from Config import Config
13 | import urllib
14 |
15 | class Proxy:
16 | """WSDL Proxy.
17 |
18 | SOAPProxy wrapper that parses method names, namespaces, soap actions from
19 | the web service description language (WSDL) file passed into the
20 | constructor. The WSDL reference can be passed in as a stream, an url, a
21 | file name, or a string.
22 |
23 | Loads info into self.methods, a dictionary with methodname keys and values
24 | of WSDLTools.SOAPCallinfo.
25 |
26 | For example,
27 |
28 | url = 'http://www.xmethods.org/sd/2001/TemperatureService.wsdl'
29 | wsdl = WSDL.Proxy(url)
30 | print len(wsdl.methods) # 1
31 | print wsdl.methods.keys() # getTemp
32 |
33 |
34 | See WSDLTools.SOAPCallinfo for more info on each method's attributes.
35 | """
36 |
37 | def __init__(self, wsdlsource, config=Config, **kw ):
38 |
39 | reader = wstools.WSDLTools.WSDLReader()
40 | self.wsdl = None
41 |
42 | # From Mark Pilgrim's "Dive Into Python" toolkit.py--open anything.
43 | if self.wsdl is None and hasattr(wsdlsource, "read"):
44 | print 'stream:', wsdlsource
45 | try:
46 | self.wsdl = reader.loadFromStream(wsdlsource)
47 | except xml.parsers.expat.ExpatError, e:
48 | newstream = urllib.urlopen(wsdlsource)
49 | buf = newstream.readlines()
50 | raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
51 | (wsdlsource, "\t".join(buf))
52 |
53 |
54 | # NOT TESTED (as of April 17, 2003)
55 | #if self.wsdl is None and wsdlsource == '-':
56 | # import sys
57 | # self.wsdl = reader.loadFromStream(sys.stdin)
58 | # print 'stdin'
59 |
60 | if self.wsdl is None:
61 | try:
62 | file(wsdlsource)
63 | self.wsdl = reader.loadFromFile(wsdlsource)
64 | #print 'file'
65 | except (IOError, OSError): pass
66 | except xml.parsers.expat.ExpatError, e:
67 | newstream = urllib.urlopen(wsdlsource)
68 | buf = newstream.readlines()
69 | raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
70 | (wsdlsource, "\t".join(buf))
71 |
72 | if self.wsdl is None:
73 | try:
74 | stream = urllib.urlopen(wsdlsource)
75 | self.wsdl = reader.loadFromStream(stream, wsdlsource)
76 | except (IOError, OSError): pass
77 | except xml.parsers.expat.ExpatError, e:
78 | newstream = urllib.urlopen(wsdlsource)
79 | buf = newstream.readlines()
80 | raise Error, "Unable to parse WSDL file at %s: \n\t%s" % \
81 | (wsdlsource, "\t".join(buf))
82 |
83 | if self.wsdl is None:
84 | import StringIO
85 | self.wsdl = reader.loadFromString(str(wsdlsource))
86 | #print 'string'
87 |
88 | # Package wsdl info as a dictionary of remote methods, with method name
89 | # as key (based on ServiceProxy.__init__ in ZSI library).
90 | self.methods = {}
91 | service = self.wsdl.services[0]
92 | port = service.ports[0]
93 | name = service.name
94 | binding = port.getBinding()
95 | portType = binding.getPortType()
96 | for operation in portType.operations:
97 | callinfo = wstools.WSDLTools.callInfoFromWSDL(port, operation.name)
98 | self.methods[callinfo.methodName] = callinfo
99 |
100 | self.soapproxy = SOAPProxy('http://localhost/dummy.webservice',
101 | config=config, **kw)
102 |
103 | def __str__(self):
104 | s = ''
105 | for method in self.methods.values():
106 | s += str(method)
107 | return s
108 |
109 | def __getattr__(self, name):
110 | """Set up environment then let parent class handle call.
111 |
112 | Raises AttributeError is method name is not found."""
113 |
114 | if not self.methods.has_key(name): raise AttributeError, name
115 |
116 | callinfo = self.methods[name]
117 | self.soapproxy.proxy = SOAPAddress(callinfo.location)
118 | self.soapproxy.namespace = callinfo.namespace
119 | self.soapproxy.soapaction = callinfo.soapAction
120 | return self.soapproxy.__getattr__(name)
121 |
122 | def show_methods(self):
123 | for key in self.methods.keys():
124 | method = self.methods[key]
125 | print "Method Name:", key.ljust(15)
126 | print
127 | inps = method.inparams
128 | for parm in range(len(inps)):
129 | details = inps[parm]
130 | print " In #%d: %s (%s)" % (parm, details.name, details.type)
131 | print
132 | outps = method.outparams
133 | for parm in range(len(outps)):
134 | details = outps[parm]
135 | print " Out #%d: %s (%s)" % (parm, details.name, details.type)
136 | print
137 |
138 |
--------------------------------------------------------------------------------
/SOAPpy/GSIServer.py:
--------------------------------------------------------------------------------
1 | from __future__ import nested_scopes
2 |
3 | """
4 | GSIServer - Contributed by Ivan R. Judson
5 |
6 |
7 | ################################################################################
8 | #
9 | # SOAPpy - Cayce Ullman (cayce@actzero.com)
10 | # Brian Matthews (blm@actzero.com)
11 | # Gregory Warnes (Gregory.R.Warnes@Pfizer.com)
12 | # Christopher Blunck (blunck@gst.com)
13 | #
14 | ################################################################################
15 | # Copyright (c) 2003, Pfizer
16 | # Copyright (c) 2001, Cayce Ullman.
17 | # Copyright (c) 2001, Brian Matthews.
18 | #
19 | # All rights reserved.
20 | #
21 | # Redistribution and use in source and binary forms, with or without
22 | # modification, are permitted provided that the following conditions are met:
23 | # Redistributions of source code must retain the above copyright notice, this
24 | # list of conditions and the following disclaimer.
25 | #
26 | # Redistributions in binary form must reproduce the above copyright notice,
27 | # this list of conditions and the following disclaimer in the documentation
28 | # and/or other materials provided with the distribution.
29 | #
30 | # Neither the name of actzero, inc. nor the names of its contributors may
31 | # be used to endorse or promote products derived from this software without
32 | # specific prior written permission.
33 | #
34 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
35 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
38 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
41 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 | #
45 | ################################################################################
46 | """
47 |
48 | ident = '$Id$'
49 | from version import __version__
50 |
51 | #import xml.sax
52 | import re
53 | import socket
54 | import sys
55 | import SocketServer
56 | from types import *
57 | import BaseHTTPServer
58 |
59 | # SOAPpy modules
60 | from Parser import parseSOAPRPC
61 | from Config import SOAPConfig
62 | from Types import faultType, voidType, simplify
63 | from NS import NS
64 | from SOAPBuilder import buildSOAP
65 | from Utilities import debugHeader, debugFooter
66 |
67 | try: from M2Crypto import SSL
68 | except: pass
69 |
70 | #####
71 |
72 | from Server import *
73 |
74 | from pyGlobus.io import GSITCPSocketServer, ThreadingGSITCPSocketServer
75 | from pyGlobus import ioc
76 |
77 | def GSIConfig():
78 | config = SOAPConfig()
79 | config.channel_mode = ioc.GLOBUS_IO_SECURE_CHANNEL_MODE_GSI_WRAP
80 | config.delegation_mode = ioc.GLOBUS_IO_SECURE_DELEGATION_MODE_FULL_PROXY
81 | config.tcpAttr = None
82 | config.authMethod = "_authorize"
83 | return config
84 |
85 | Config = GSIConfig()
86 |
87 | class GSISOAPServer(GSITCPSocketServer, SOAPServerBase):
88 | def __init__(self, addr = ('localhost', 8000),
89 | RequestHandler = SOAPRequestHandler, log = 0,
90 | encoding = 'UTF-8', config = Config, namespace = None):
91 |
92 | # Test the encoding, raising an exception if it's not known
93 | if encoding != None:
94 | ''.encode(encoding)
95 |
96 | self.namespace = namespace
97 | self.objmap = {}
98 | self.funcmap = {}
99 | self.encoding = encoding
100 | self.config = config
101 | self.log = log
102 |
103 | self.allow_reuse_address= 1
104 |
105 | GSITCPSocketServer.__init__(self, addr, RequestHandler,
106 | self.config.channel_mode,
107 | self.config.delegation_mode,
108 | tcpAttr = self.config.tcpAttr)
109 |
110 | def get_request(self):
111 | sock, addr = GSITCPSocketServer.get_request(self)
112 |
113 | return sock, addr
114 |
115 | class ThreadingGSISOAPServer(ThreadingGSITCPSocketServer, SOAPServerBase):
116 |
117 | def __init__(self, addr = ('localhost', 8000),
118 | RequestHandler = SOAPRequestHandler, log = 0,
119 | encoding = 'UTF-8', config = Config, namespace = None):
120 |
121 | # Test the encoding, raising an exception if it's not known
122 | if encoding != None:
123 | ''.encode(encoding)
124 |
125 | self.namespace = namespace
126 | self.objmap = {}
127 | self.funcmap = {}
128 | self.encoding = encoding
129 | self.config = config
130 | self.log = log
131 |
132 | self.allow_reuse_address= 1
133 |
134 | ThreadingGSITCPSocketServer.__init__(self, addr, RequestHandler,
135 | self.config.channel_mode,
136 | self.config.delegation_mode,
137 | tcpAttr = self.config.tcpAttr)
138 |
139 | def get_request(self):
140 | sock, addr = ThreadingGSITCPSocketServer.get_request(self)
141 |
142 | return sock, addr
143 |
144 |
--------------------------------------------------------------------------------
/tests/echoServer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright (c) 2001 actzero, inc. All rights reserved.
4 |
5 | import sys
6 | sys.path.insert(1, "..")
7 |
8 | from SOAPpy import *
9 |
10 | # Uncomment to see outgoing HTTP headers and SOAP and incoming
11 | Config.dumpSOAPIn = 1
12 | Config.dumpSOAPOut = 1
13 | Config.debug = 1
14 |
15 | # specify name of authorization function
16 | Config.authMethod = "_authorize"
17 |
18 | # Set this to 0 to test authorization
19 | allowAll = 1
20 |
21 | # ask for returned SOAP responses to be converted to basic python types
22 | Config.simplify_objects = 1
23 |
24 |
25 | # provide a mechanism to stop the server
26 | run = 1
27 | def quit():
28 | global run
29 | run=0;
30 |
31 |
32 | if Config.SSLserver:
33 | from M2Crypto import SSL
34 |
35 | def _authorize(*args, **kw):
36 | global allowAll, Config
37 |
38 | if Config.debug:
39 | print "Authorize (function) called! (result = %d)" % allowAll
40 | print "Arguments: %s" % kw
41 |
42 | if allowAll:
43 | return 1
44 | else:
45 | return 0
46 |
47 | # Simple echo
48 | def echo(s):
49 | global Config
50 |
51 | # Test of context retrieval
52 | ctx = Server.GetSOAPContext()
53 | if Config.debug:
54 | print "SOAP Context: ", ctx
55 |
56 | return s + s
57 |
58 | # An echo class
59 | class echoBuilder2:
60 | def echo2(self, val):
61 | return val * 3
62 |
63 | # A class that has an instance variable which is an echo class
64 | class echoBuilder:
65 | def __init__(self):
66 | self.prop = echoBuilder2()
67 |
68 | def echo_ino(self, val):
69 | return val + val
70 | def _authorize(self, *args, **kw):
71 | global allowAll, Config
72 |
73 | if Config.debug:
74 | print "Authorize (method) called with arguments:"
75 | print "*args=%s" % str(args)
76 | print "**kw =%s" % str(kw)
77 | print "Approved -> %d" % allowAll
78 |
79 | if allowAll:
80 | return 1
81 | else:
82 | return 0
83 |
84 | # Echo with context
85 | def echo_wc(s, _SOAPContext):
86 | global Config
87 |
88 | c = _SOAPContext
89 |
90 | sep = '-' * 72
91 |
92 | # The Context object has extra info about the call
93 | if Config.debug:
94 | print "-- XML", sep[7:]
95 | # The original XML request
96 | print c.xmldata
97 |
98 | print "-- Header", sep[10:]
99 | # The SOAP Header or None if not present
100 | print c.header
101 |
102 | if c.header:
103 | print "-- Header.mystring", sep[19:]
104 | # An element of the SOAP Header
105 | print c.header.mystring
106 |
107 | print "-- Body", sep[8:]
108 | # The whole Body object
109 | print c.body
110 |
111 | print "-- Peer", sep[8:]
112 | if not GSI:
113 | # The socket object, useful for
114 | print c.connection.getpeername()
115 | else:
116 | # The socket object, useful for
117 | print c.connection.get_remote_address()
118 | ctx = c.connection.get_security_context()
119 | print ctx.inquire()[0].display()
120 |
121 | print "-- SOAPAction", sep[14:]
122 | # The SOAPaction HTTP header
123 | print c.soapaction
124 |
125 | print "-- HTTP headers", sep[16:]
126 | # All the HTTP headers
127 | print c.httpheaders
128 |
129 | return s + s
130 |
131 | # Echo with keyword arguments
132 | def echo_wkw(**kw):
133 | return kw['first'] + kw['second'] + kw['third']
134 |
135 | # Simple echo
136 | def echo_simple(*arg):
137 | return arg
138 |
139 | def echo_header(s, _SOAPContext):
140 | global Config
141 |
142 | c = _SOAPContext
143 | return s, c.header
144 |
145 |
146 | addr = ('localhost', 9900)
147 | GSI = 0
148 | SSL = 0
149 | if len(sys.argv) > 1 and sys.argv[1] == '-s':
150 | SSL = 1
151 | if not Config.SSLserver:
152 | raise RuntimeError, \
153 | "this Python installation doesn't have OpenSSL and M2Crypto"
154 | ssl_context = SSL.Context()
155 | ssl_context.load_cert('validate/server.pem')
156 | server = SOAPServer(addr, ssl_context = ssl_context)
157 | prefix = 'https'
158 | elif len(sys.argv) > 1 and sys.argv[1] == '-g':
159 | GSI = 1
160 | from SOAPpy.GSIServer import GSISOAPServer
161 | server = GSISOAPServer(addr)
162 | prefix = 'httpg'
163 | else:
164 | server = SOAPServer(addr)
165 | prefix = 'http'
166 |
167 | print "Server listening at: %s://%s:%d/" % (prefix, addr[0], addr[1])
168 |
169 | # register the method
170 | server.registerFunction(echo)
171 | server.registerFunction(echo, path = "/pathtest")
172 | server.registerFunction(_authorize)
173 | server.registerFunction(_authorize, path = "/pathtest")
174 |
175 | # Register a whole object
176 | o = echoBuilder()
177 | server.registerObject(o, path = "/pathtest")
178 | server.registerObject(o)
179 |
180 | # Register a function which gets called with the Context object
181 | server.registerFunction(MethodSig(echo_wc, keywords = 0, context = 1),
182 | path = "/pathtest")
183 | server.registerFunction(MethodSig(echo_wc, keywords = 0, context = 1))
184 |
185 | # Register a function that takes keywords
186 | server.registerKWFunction(echo_wkw, path = "/pathtest")
187 | server.registerKWFunction(echo_wkw)
188 |
189 | server.registerFunction(echo_simple)
190 | server.registerFunction(MethodSig(echo_header, keywords=0, context=1))
191 | server.registerFunction(quit)
192 |
193 | # Start the server
194 | try:
195 | while run:
196 | server.handle_request()
197 | except KeyboardInterrupt:
198 | pass
199 |
--------------------------------------------------------------------------------
/SOAPpy/Utilities.py:
--------------------------------------------------------------------------------
1 | """
2 | ################################################################################
3 | # Copyright (c) 2003, Pfizer
4 | # Copyright (c) 2001, Cayce Ullman.
5 | # Copyright (c) 2001, Brian Matthews.
6 | #
7 | # All rights reserved.
8 | #
9 | # Redistribution and use in source and binary forms, with or without
10 | # modification, are permitted provided that the following conditions are met:
11 | # Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # Neither the name of actzero, inc. nor the names of its contributors may
19 | # be used to endorse or promote products derived from this software without
20 | # specific prior written permission.
21 | #
22 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
26 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | #
33 | ################################################################################
34 | """
35 |
36 | ident = '$Id$'
37 | from version import __version__
38 |
39 | import re
40 | import string
41 | import sys
42 | from types import *
43 |
44 | # SOAPpy modules
45 | from Errors import *
46 |
47 | ################################################################################
48 | # Utility infielders
49 | ################################################################################
50 | def collapseWhiteSpace(s):
51 | return re.sub('\s+', ' ', s).strip()
52 |
53 | def decodeHexString(data):
54 | conv = {
55 | '0': 0x0, '1': 0x1, '2': 0x2, '3': 0x3, '4': 0x4,
56 | '5': 0x5, '6': 0x6, '7': 0x7, '8': 0x8, '9': 0x9,
57 |
58 | 'a': 0xa, 'b': 0xb, 'c': 0xc, 'd': 0xd, 'e': 0xe,
59 | 'f': 0xf,
60 |
61 | 'A': 0xa, 'B': 0xb, 'C': 0xc, 'D': 0xd, 'E': 0xe,
62 | 'F': 0xf,
63 | }
64 |
65 | ws = string.whitespace
66 |
67 | bin = ''
68 |
69 | i = 0
70 |
71 | while i < len(data):
72 | if data[i] not in ws:
73 | break
74 | i += 1
75 |
76 | low = 0
77 |
78 | while i < len(data):
79 | c = data[i]
80 |
81 | if c in string.whitespace:
82 | break
83 |
84 | try:
85 | c = conv[c]
86 | except KeyError:
87 | raise ValueError, \
88 | "invalid hex string character `%s'" % c
89 |
90 | if low:
91 | bin += chr(high * 16 + c)
92 | low = 0
93 | else:
94 | high = c
95 | low = 1
96 |
97 | i += 1
98 |
99 | if low:
100 | raise ValueError, "invalid hex string length"
101 |
102 | while i < len(data):
103 | if data[i] not in string.whitespace:
104 | raise ValueError, \
105 | "invalid hex string character `%s'" % c
106 |
107 | i += 1
108 |
109 | return bin
110 |
111 | def encodeHexString(data):
112 | h = ''
113 |
114 | for i in data:
115 | h += "%02X" % ord(i)
116 |
117 | return h
118 |
119 | def leapMonth(year, month):
120 | return month == 2 and \
121 | year % 4 == 0 and \
122 | (year % 100 != 0 or year % 400 == 0)
123 |
124 | def cleanDate(d, first = 0):
125 | ranges = (None, (1, 12), (1, 31), (0, 23), (0, 59), (0, 61))
126 | months = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
127 | names = ('year', 'month', 'day', 'hours', 'minutes', 'seconds')
128 |
129 | if len(d) != 6:
130 | raise ValueError, "date must have 6 elements"
131 |
132 | for i in range(first, 6):
133 | s = d[i]
134 |
135 | if type(s) == FloatType:
136 | if i < 5:
137 | try:
138 | s = int(s)
139 | except OverflowError:
140 | if i > 0:
141 | raise
142 | s = long(s)
143 |
144 | if s != d[i]:
145 | raise ValueError, "%s must be integral" % names[i]
146 |
147 | d[i] = s
148 | elif type(s) == LongType:
149 | try: s = int(s)
150 | except: pass
151 | elif type(s) != IntType:
152 | raise TypeError, "%s isn't a valid type" % names[i]
153 |
154 | if i == first and s < 0:
155 | continue
156 |
157 | if ranges[i] != None and \
158 | (s < ranges[i][0] or ranges[i][1] < s):
159 | raise ValueError, "%s out of range" % names[i]
160 |
161 | if first < 6 and d[5] >= 61:
162 | raise ValueError, "seconds out of range"
163 |
164 | if first < 2:
165 | leap = first < 1 and leapMonth(d[0], d[1])
166 |
167 | if d[2] > months[d[1]] + leap:
168 | raise ValueError, "day out of range"
169 |
170 | def debugHeader(title):
171 | s = '*** ' + title + ' '
172 | print s + ('*' * (72 - len(s)))
173 |
174 | def debugFooter(title):
175 | print '*' * 72
176 | sys.stdout.flush()
177 |
--------------------------------------------------------------------------------
/docs/GettingStarted.txt:
--------------------------------------------------------------------------------
1 |
2 | Getting Started
3 | ===============
4 |
5 | NEW:
6 |
7 | Mark Pilgrims' online book _Dive Into Python_ at
8 | http://diveintopython.org includes a nice tutorial for SOAPpy in
9 | Chapter 12. "SOAP Web Services" at
10 | http://diveintopython.org/soap_web_services.
11 |
12 |
13 |
14 | The easiest way to get up to speed is to run and read the scripts in the
15 | tests directory. Better documentation is coming.
16 |
17 | Here are some examples of how to use SOAPpy:
18 |
19 |
20 | CLIENT EXAMPLES:
21 |
22 | ## CODE
23 | from SOAPpy import SOAPProxy
24 | server = SOAPProxy("http://localhost:8080/")
25 | print server.echo("Hello world")
26 | ## /CODE
27 |
28 | This opens a connection to the server listening on localhost:8080, calls the
29 | method echo with the ordered parameter of "Hello World", and prints the
30 | results.
31 |
32 |
33 | ## CODE
34 | from SOAPpy import SOAPProxy
35 | server = SOAPProxy("https://localhost:8443/")
36 | print server.echo("Hello world")
37 | ## /CODE
38 |
39 | This opens a secure connection to the SSL server listening on
40 | localhost:8443, calls the method echo with the ordered parameter of
41 | "Hello World" and prints the results. Python must be built with OpenSSL.
42 |
43 |
44 | ## CODE
45 | from SOAPpy import SOAPProxy
46 | server = SOAPProxy("http://services.xmethods.com/soap",
47 | namespace = "urn:xmethods-delayed-quotes")
48 | print server.getQuote(symbol = "IBM")
49 | ## /CODE
50 |
51 | This calls method getQuote that is in the namespace URI of
52 | urn:xmethods-delayed-quotes on server services.xmethods.com. getQuote is
53 | passed a named parameter, symbol.
54 |
55 |
56 | ## CODE
57 | from SOAPpy import SOAPProxy
58 | server = SOAPProxy("http://services.xmethods.com/soap")
59 |
60 | print server._ns("urn:xmethods-delayed-quotes").getQuote(symbol = "IBM")
61 | ## /CODE
62 |
63 | This does the same thing as the previous example, however namespace is
64 | specified inline on a per call basis rather than at the server level.
65 |
66 |
67 | ## CODE
68 | from SOAPpy import SOAPProxy
69 | server = SOAPProxy("http://services.xmethods.com/soap",
70 | soapaction = "http://somesite.com/myaction")
71 |
72 | print server._ns("urn:xmethods-delayed-quotes").getQuote(symbol = "IBM")
73 | ## /CODE
74 |
75 | This is the same quote call with a soapaction specified.
76 |
77 |
78 | ## CODE
79 | from SOAPpy import SOAPProxy
80 | server = SOAPProxy("http://services.xmethods.com:80/soap")
81 |
82 | ns = "urn:xmethods-delayed-quotes")
83 | sa = "http://somesite.com/myaction"
84 | my_call = server._ns(ns)._sa(sa)
85 | my_call.getQuote(symbol = "IBM")
86 | my_call.getQuote(symbol = "IBM")
87 | my_call.getQuote(symbol = "IBM")
88 | ## /CODE
89 |
90 | The same example, this time with both the soapaction and the namespace
91 | specified inline and saved in a local variable for getQuote to be called
92 | against.
93 |
94 | ** What SOAPpy does with the results of a call could seem surprising. If
95 | there is only one element in the structType that has the return value and
96 | unwrap_results is turned on (the default) it will bubble up the single
97 | attribute, otherwise it will return you a structType object with all of the
98 | attributes.
99 |
100 |
101 |
102 | SERVER EXAMPLES:
103 |
104 | ## CODE
105 | from SOAPpy import SOAPServer
106 | def echo(s):
107 | return s + s # repeats a string twice
108 |
109 | server = SOAPServer(("localhost", 8080))
110 | server.registerFunction(echo)
111 | server.serve_forever()
112 | ## /CODE
113 |
114 | This exposes the function echo (that takes an unnamed arguement) on a server
115 | running on localhost:8080.
116 |
117 |
118 | ## CODE
119 | from SOAPpy import SOAPServer
120 | def echo(s):
121 | return s + s # repeats a string twice
122 |
123 | server = SOAPServer()
124 | server.registerFunction(echo, "echo-space")
125 | server.serve_forever()
126 | ## /CODE
127 |
128 | The same as above, but this time the method is available in the namespace
129 | "echo-space".
130 |
131 |
132 | ## CODE
133 | from SOAPpy import SOAPServer
134 |
135 | class echoBuilder:
136 | def echo(self, val):
137 | return val + val
138 |
139 | server = SOAPServer()
140 | e = echoBuilder()
141 | server.registerObject(e)
142 | server.serve_forever()
143 | ## /CODE
144 |
145 | This registers the whole instance of the object echoBuilder, e. Every
146 | method of the instance is exposed on the server.
147 |
148 |
149 | ## CODE
150 | from SOAPpy import SOAPServer
151 |
152 | def echo(**kw):
153 | return kw['first'] + kw['second'] + kw['third']
154 |
155 | server = SOAPServer()
156 | server.registerKWFunction(echo)
157 | server.serve_forever()
158 | ## /CODE
159 |
160 | This time the method echo is exposed and it expects named arguments. The
161 | main thing to notice here is the use of the method registerKWFunction over
162 | registerFunction.
163 |
164 |
165 | ## CODE
166 | from SOAPpy import SOAPServer
167 |
168 | from M2Crypto import SSL
169 |
170 | def echo(s):
171 | return s+s # repeats a string twice
172 |
173 | ssl_context = SSL.Context()
174 | ssl_context.load_cert('server.pem')
175 |
176 | server = SOAPServer(("localhost",8443), ssl_context = ssl_context)
177 | server.registerFunction(echo)
178 | server.serve_forever()
179 | ## /CODE
180 |
181 | This exposes the function echo (taking an unnamed arguement) on a server
182 | accepting SSL connections at localhost:8443. Ng Pheng Siong's M2Crypto
183 | package (available at ) must be
184 | installed. Also see tests/silabserver.py.
185 |
186 | $Id$
187 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/TimeoutSocket.py:
--------------------------------------------------------------------------------
1 | """Based on code from timeout_socket.py, with some tweaks for compatibility.
2 | These tweaks should really be rolled back into timeout_socket, but it's
3 | not totally clear who is maintaining it at this point. In the meantime,
4 | we'll use a different module name for our tweaked version to avoid any
5 | confusion.
6 |
7 | The original timeout_socket is by:
8 |
9 | Scott Cotton
10 | Lloyd Zusman
11 | Phil Mayes
12 | Piers Lauder
13 | Radovan Garabik
14 | """
15 |
16 | ident = "$Id$"
17 |
18 | import string, socket, select, errno
19 |
20 | WSAEINVAL = getattr(errno, 'WSAEINVAL', 10022)
21 |
22 |
23 | class TimeoutSocket:
24 | """A socket imposter that supports timeout limits."""
25 |
26 | def __init__(self, timeout=20, sock=None):
27 | self.timeout = float(timeout)
28 | self.inbuf = ''
29 | if sock is None:
30 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
31 | self.sock = sock
32 | self.sock.setblocking(0)
33 | self._rbuf = ''
34 | self._wbuf = ''
35 |
36 | def __getattr__(self, name):
37 | # Delegate to real socket attributes.
38 | return getattr(self.sock, name)
39 |
40 | def connect(self, *addr):
41 | timeout = self.timeout
42 | sock = self.sock
43 | try:
44 | # Non-blocking mode
45 | sock.setblocking(0)
46 | apply(sock.connect, addr)
47 | sock.setblocking(timeout != 0)
48 | return 1
49 | except socket.error,why:
50 | if not timeout:
51 | raise
52 | sock.setblocking(1)
53 | if len(why.args) == 1:
54 | code = 0
55 | else:
56 | code, why = why
57 | if code not in (
58 | errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK
59 | ):
60 | raise
61 | r,w,e = select.select([],[sock],[],timeout)
62 | if w:
63 | try:
64 | apply(sock.connect, addr)
65 | return 1
66 | except socket.error,why:
67 | if len(why.args) == 1:
68 | code = 0
69 | else:
70 | code, why = why
71 | if code in (errno.EISCONN, WSAEINVAL):
72 | return 1
73 | raise
74 | raise TimeoutError('socket connect() timeout.')
75 |
76 | def send(self, data, flags=0):
77 | total = len(data)
78 | next = 0
79 | while 1:
80 | r, w, e = select.select([],[self.sock], [], self.timeout)
81 | if w:
82 | buff = data[next:next + 8192]
83 | sent = self.sock.send(buff, flags)
84 | next = next + sent
85 | if next == total:
86 | return total
87 | continue
88 | raise TimeoutError('socket send() timeout.')
89 |
90 | def recv(self, amt, flags=0):
91 | if select.select([self.sock], [], [], self.timeout)[0]:
92 | return self.sock.recv(amt, flags)
93 | raise TimeoutError('socket recv() timeout.')
94 |
95 | buffsize = 4096
96 | handles = 1
97 |
98 | def makefile(self, mode="r", buffsize=-1):
99 | self.handles = self.handles + 1
100 | self.mode = mode
101 | return self
102 |
103 | def close(self):
104 | self.handles = self.handles - 1
105 | if self.handles == 0 and self.sock.fileno() >= 0:
106 | self.sock.close()
107 |
108 | def read(self, n=-1):
109 | if not isinstance(n, type(1)):
110 | n = -1
111 | if n >= 0:
112 | k = len(self._rbuf)
113 | if n <= k:
114 | data = self._rbuf[:n]
115 | self._rbuf = self._rbuf[n:]
116 | return data
117 | n = n - k
118 | L = [self._rbuf]
119 | self._rbuf = ""
120 | while n > 0:
121 | new = self.recv(max(n, self.buffsize))
122 | if not new: break
123 | k = len(new)
124 | if k > n:
125 | L.append(new[:n])
126 | self._rbuf = new[n:]
127 | break
128 | L.append(new)
129 | n = n - k
130 | return "".join(L)
131 | k = max(4096, self.buffsize)
132 | L = [self._rbuf]
133 | self._rbuf = ""
134 | while 1:
135 | new = self.recv(k)
136 | if not new: break
137 | L.append(new)
138 | k = min(k*2, 1024**2)
139 | return "".join(L)
140 |
141 | def readline(self, limit=-1):
142 | data = ""
143 | i = self._rbuf.find('\n')
144 | while i < 0 and not (0 < limit <= len(self._rbuf)):
145 | new = self.recv(self.buffsize)
146 | if not new: break
147 | i = new.find('\n')
148 | if i >= 0: i = i + len(self._rbuf)
149 | self._rbuf = self._rbuf + new
150 | if i < 0: i = len(self._rbuf)
151 | else: i = i+1
152 | if 0 <= limit < len(self._rbuf): i = limit
153 | data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
154 | return data
155 |
156 | def readlines(self, sizehint = 0):
157 | total = 0
158 | list = []
159 | while 1:
160 | line = self.readline()
161 | if not line: break
162 | list.append(line)
163 | total += len(line)
164 | if sizehint and total >= sizehint:
165 | break
166 | return list
167 |
168 | def writelines(self, list):
169 | self.send(''.join(list))
170 |
171 | def write(self, data):
172 | self.send(data)
173 |
174 | def flush(self):
175 | pass
176 |
177 |
178 | class TimeoutError(Exception):
179 | pass
180 |
--------------------------------------------------------------------------------
/SOAPpy/wstools/test/test_wsdl.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | ############################################################################
4 | # Joshua R. Boverhof, David W. Robertson, LBNL
5 | # See LBNLCopyright for copyright notice!
6 | ###########################################################################
7 |
8 | import sys, unittest
9 | import ConfigParser
10 | from ZSI.wstools.Utility import DOM
11 | from ZSI.wstools.WSDLTools import WSDLReader
12 | from ZSI.wstools.TimeoutSocket import TimeoutError
13 |
14 | class WSDLToolsTestCase(unittest.TestCase):
15 |
16 | def __init__(self, methodName='runTest'):
17 | unittest.TestCase.__init__(self, methodName)
18 |
19 | def setUp(self):
20 | self.path = nameGenerator.next()
21 | print self.path
22 | sys.stdout.flush()
23 |
24 | def __str__(self):
25 | teststr = unittest.TestCase.__str__(self)
26 | if hasattr(self, "path"):
27 | return "%s: %s" % (teststr, self.path )
28 | else:
29 | return "%s" % (teststr)
30 |
31 | def checkWSDLCollection(self, tag_name, component, key='name'):
32 | if self.wsdl is None:
33 | return
34 | definition = self.wsdl.document.documentElement
35 | version = DOM.WSDLUriToVersion(definition.namespaceURI)
36 | nspname = DOM.GetWSDLUri(version)
37 | for node in DOM.getElements(definition, tag_name, nspname):
38 | name = DOM.getAttr(node, key)
39 | comp = component[name]
40 | self.failUnlessEqual(eval('comp.%s' %key), name)
41 |
42 | def checkXSDCollection(self, tag_name, component, node, key='name'):
43 | for cnode in DOM.getElements(node, tag_name):
44 | name = DOM.getAttr(cnode, key)
45 | component[name]
46 |
47 | def test_all(self):
48 | try:
49 | if self.path[:7] == 'http://':
50 | self.wsdl = WSDLReader().loadFromURL(self.path)
51 | else:
52 | self.wsdl = WSDLReader().loadFromFile(self.path)
53 |
54 | except TimeoutError:
55 | print "connection timed out"
56 | sys.stdout.flush()
57 | return
58 | except:
59 | self.path = self.path + ": load failed, unable to start"
60 | raise
61 |
62 | try:
63 | self.checkWSDLCollection('service', self.wsdl.services)
64 | except:
65 | self.path = self.path + ": wsdl.services"
66 | raise
67 |
68 | try:
69 | self.checkWSDLCollection('message', self.wsdl.messages)
70 | except:
71 | self.path = self.path + ": wsdl.messages"
72 | raise
73 |
74 | try:
75 | self.checkWSDLCollection('portType', self.wsdl.portTypes)
76 | except:
77 | self.path = self.path + ": wsdl.portTypes"
78 | raise
79 |
80 | try:
81 | self.checkWSDLCollection('binding', self.wsdl.bindings)
82 | except:
83 | self.path = self.path + ": wsdl.bindings"
84 | raise
85 |
86 | try:
87 | self.checkWSDLCollection('import', self.wsdl.imports, key='namespace')
88 | except:
89 | self.path = self.path + ": wsdl.imports"
90 | raise
91 |
92 | try:
93 | for key in self.wsdl.types.keys():
94 | schema = self.wsdl.types[key]
95 | self.failUnlessEqual(key, schema.getTargetNamespace())
96 |
97 | definition = self.wsdl.document.documentElement
98 | version = DOM.WSDLUriToVersion(definition.namespaceURI)
99 | nspname = DOM.GetWSDLUri(version)
100 | for node in DOM.getElements(definition, 'types', nspname):
101 | for snode in DOM.getElements(node, 'schema'):
102 | tns = DOM.findTargetNS(snode)
103 | schema = self.wsdl.types[tns]
104 | self.schemaAttributesDeclarations(schema, snode)
105 | self.schemaAttributeGroupDeclarations(schema, snode)
106 | self.schemaElementDeclarations(schema, snode)
107 | self.schemaTypeDefinitions(schema, snode)
108 | except:
109 | self.path = self.path + ": wsdl.types"
110 | raise
111 |
112 | if self.wsdl.extensions:
113 | print 'No check for WSDLTools(%s) Extensions:' %(self.wsdl.name)
114 | for ext in self.wsdl.extensions: print '\t', ext
115 |
116 | def schemaAttributesDeclarations(self, schema, node):
117 | self.checkXSDCollection('attribute', schema.attr_decl, node)
118 |
119 | def schemaAttributeGroupDeclarations(self, schema, node):
120 | self.checkXSDCollection('group', schema.attr_groups, node)
121 |
122 | def schemaElementDeclarations(self, schema, node):
123 | self.checkXSDCollection('element', schema.elements, node)
124 |
125 | def schemaTypeDefinitions(self, schema, node):
126 | self.checkXSDCollection('complexType', schema.types, node)
127 | self.checkXSDCollection('simpleType', schema.types, node)
128 |
129 |
130 | def setUpOptions(section):
131 | cp = ConfigParser.ConfigParser()
132 | cp.read('config.txt')
133 | if not cp.sections():
134 | print 'fatal error: configuration file config.txt not present'
135 | sys.exit(0)
136 | if not cp.has_section(section):
137 | print '%s section not present in configuration file, exiting' % section
138 | sys.exit(0)
139 | return cp, len(cp.options(section))
140 |
141 | def getOption(cp, section):
142 | for name, value in cp.items(section):
143 | yield value
144 |
145 | def makeTestSuite(section='services_by_file'):
146 | global nameGenerator
147 |
148 | cp, numTests = setUpOptions(section)
149 | nameGenerator = getOption(cp, section)
150 | suite = unittest.TestSuite()
151 | for i in range(0, numTests):
152 | suite.addTest(unittest.makeSuite(WSDLToolsTestCase, 'test_'))
153 | return suite
154 |
155 |
156 | def main():
157 | unittest.main(defaultTest="makeTestSuite")
158 |
159 |
160 | if __name__ == "__main__" : main()
161 |
--------------------------------------------------------------------------------
/SOAPpy/fpconst.py:
--------------------------------------------------------------------------------
1 | """Utilities for handling IEEE 754 floating point special values
2 |
3 | This python module implements constants and functions for working with
4 | IEEE754 double-precision special values. It provides constants for
5 | Not-a-Number (NaN), Positive Infinity (PosInf), and Negative Infinity
6 | (NegInf), as well as functions to test for these values.
7 |
8 | The code is implemented in pure python by taking advantage of the
9 | 'struct' standard module. Care has been taken to generate proper
10 | results on both big-endian and little-endian machines. Some efficiency
11 | could be gained by translating the core routines into C.
12 |
13 | See
14 | for reference material on the IEEE 754 floating point standard.
15 |
16 | Further information on this package is available at
17 | .
18 |
19 | ------------------------------------------------------------------
20 | Author: Gregory R. Warnes
21 | Date: 2005-02-24
22 | Version: 0.7.2
23 | Copyright: (c) 2003-2005 Pfizer, Licensed to PSF under a Contributor Agreement
24 | License: Licensed under the Apache License, Version 2.0 (the"License");
25 | you may not use this file except in compliance with the License.
26 | You may obtain a copy of the License at
27 |
28 | http://www.apache.org/licenses/LICENSE-2.0
29 |
30 | Unless required by applicable law or agreed to in
31 | writing, software distributed under the License is
32 | distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
33 | CONDITIONS OF ANY KIND, either express or implied. See
34 | the License for the specific language governing
35 | permissions and limitations under the License.
36 | ------------------------------------------------------------------
37 | """
38 |
39 | __version__ = "0.7.2"
40 | ident = "$Id: fpconst.py,v 1.16 2005/02/24 17:42:03 warnes Exp $"
41 |
42 | import struct, operator
43 |
44 | # check endianess
45 | _big_endian = struct.pack('i',1)[0] != '\x01'
46 |
47 | # and define appropriate constants
48 | if(_big_endian):
49 | NaN = struct.unpack('d', '\x7F\xF8\x00\x00\x00\x00\x00\x00')[0]
50 | PosInf = struct.unpack('d', '\x7F\xF0\x00\x00\x00\x00\x00\x00')[0]
51 | NegInf = -PosInf
52 | else:
53 | NaN = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf8\xff')[0]
54 | PosInf = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf0\x7f')[0]
55 | NegInf = -PosInf
56 |
57 | def _double_as_bytes(dval):
58 | "Use struct.unpack to decode a double precision float into eight bytes"
59 | tmp = list(struct.unpack('8B',struct.pack('d', dval)))
60 | if not _big_endian:
61 | tmp.reverse()
62 | return tmp
63 |
64 | ##
65 | ## Functions to extract components of the IEEE 754 floating point format
66 | ##
67 |
68 | def _sign(dval):
69 | "Extract the sign bit from a double-precision floating point value"
70 | bb = _double_as_bytes(dval)
71 | return bb[0] >> 7 & 0x01
72 |
73 | def _exponent(dval):
74 | """Extract the exponentent bits from a double-precision floating
75 | point value.
76 |
77 | Note that for normalized values, the exponent bits have an offset
78 | of 1023. As a consequence, the actual exponentent is obtained
79 | by subtracting 1023 from the value returned by this function
80 | """
81 | bb = _double_as_bytes(dval)
82 | return (bb[0] << 4 | bb[1] >> 4) & 0x7ff
83 |
84 | def _mantissa(dval):
85 | """Extract the _mantissa bits from a double-precision floating
86 | point value."""
87 |
88 | bb = _double_as_bytes(dval)
89 | mantissa = bb[1] & 0x0f << 48
90 | mantissa += bb[2] << 40
91 | mantissa += bb[3] << 32
92 | mantissa += bb[4]
93 | return mantissa
94 |
95 | def _zero_mantissa(dval):
96 | """Determine whether the mantissa bits of the given double are all
97 | zero."""
98 | bb = _double_as_bytes(dval)
99 | return ((bb[1] & 0x0f) | reduce(operator.or_, bb[2:])) == 0
100 |
101 | ##
102 | ## Functions to test for IEEE 754 special values
103 | ##
104 |
105 | def isNaN(value):
106 | "Determine if the argument is a IEEE 754 NaN (Not a Number) value."
107 | return (_exponent(value)==0x7ff and not _zero_mantissa(value))
108 |
109 | def isInf(value):
110 | """Determine if the argument is an infinite IEEE 754 value (positive
111 | or negative inifinity)"""
112 | return (_exponent(value)==0x7ff and _zero_mantissa(value))
113 |
114 | def isFinite(value):
115 | """Determine if the argument is an finite IEEE 754 value (i.e., is
116 | not NaN, positive or negative inifinity)"""
117 | return (_exponent(value)!=0x7ff)
118 |
119 | def isPosInf(value):
120 | "Determine if the argument is a IEEE 754 positive infinity value"
121 | return (_sign(value)==0 and _exponent(value)==0x7ff and \
122 | _zero_mantissa(value))
123 |
124 | def isNegInf(value):
125 | "Determine if the argument is a IEEE 754 negative infinity value"
126 | return (_sign(value)==1 and _exponent(value)==0x7ff and \
127 | _zero_mantissa(value))
128 |
129 | ##
130 | ## Functions to test public functions.
131 | ##
132 |
133 | def test_isNaN():
134 | assert( not isNaN(PosInf) )
135 | assert( not isNaN(NegInf) )
136 | assert( isNaN(NaN ) )
137 | assert( not isNaN( 1.0) )
138 | assert( not isNaN( -1.0) )
139 |
140 | def test_isInf():
141 | assert( isInf(PosInf) )
142 | assert( isInf(NegInf) )
143 | assert( not isInf(NaN ) )
144 | assert( not isInf( 1.0) )
145 | assert( not isInf( -1.0) )
146 |
147 | def test_isFinite():
148 | assert( not isFinite(PosInf) )
149 | assert( not isFinite(NegInf) )
150 | assert( not isFinite(NaN ) )
151 | assert( isFinite( 1.0) )
152 | assert( isFinite( -1.0) )
153 |
154 | def test_isPosInf():
155 | assert( isPosInf(PosInf) )
156 | assert( not isPosInf(NegInf) )
157 | assert( not isPosInf(NaN ) )
158 | assert( not isPosInf( 1.0) )
159 | assert( not isPosInf( -1.0) )
160 |
161 | def test_isNegInf():
162 | assert( not isNegInf(PosInf) )
163 | assert( isNegInf(NegInf) )
164 | assert( not isNegInf(NaN ) )
165 | assert( not isNegInf( 1.0) )
166 | assert( not isNegInf( -1.0) )
167 |
168 | # overall test
169 | def test():
170 | test_isNaN()
171 | test_isInf()
172 | test_isFinite()
173 | test_isPosInf()
174 | test_isNegInf()
175 |
176 | if __name__ == "__main__":
177 | test()
178 |
179 |
--------------------------------------------------------------------------------
/zope/zope-2.5.0-soappy.diff:
--------------------------------------------------------------------------------
1 | diff -urN Zope-2.5.0-linux2-x86/lib/python/ZPublisher/HTTPRequest.py Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py
2 | --- Zope-2.5.0-linux2-x86/lib/python/ZPublisher/HTTPRequest.py 2002-01-03 20:41:05.000000000 +0100
3 | +++ Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py 2003-11-12 13:17:57.000000000 +0100
4 | @@ -21,6 +21,7 @@
5 | from Converters import get_converter
6 | from maybe_lock import allocate_lock
7 | xmlrpc=None # Placeholder for module that we'll import if we have to.
8 | +soap=None
9 |
10 | #cgi hotfix:
11 | if not hasattr(cgi, 'valid_boundary'):
12 | @@ -347,18 +348,28 @@
13 | meth=None
14 | fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
15 | if not hasattr(fs,'list') or fs.list is None:
16 | - # Hm, maybe it's an XML-RPC
17 | - if (fs.headers.has_key('content-type') and
18 | - fs.headers['content-type'] == 'text/xml' and
19 | + # Hm, maybe it's an XML-RPC or SOAP
20 | + if (fs.headers.has_key('content-type') and
21 | + fs.headers['content-type'][:8] == 'text/xml' and
22 | method == 'POST'):
23 | - # Ye haaa, XML-RPC!
24 | - global xmlrpc
25 | - if xmlrpc is None: import xmlrpc
26 | - meth, self.args = xmlrpc.parse_input(fs.value)
27 | - response=xmlrpc.response(response)
28 | - other['RESPONSE']=self.response=response
29 | - other['REQUEST_METHOD']='' # We don't want index_html!
30 | - self.maybe_webdav_client = 0
31 | + if environ.has_key('HTTP_SOAPACTION'):
32 | + # this is a SOAP request
33 | + global soap
34 | + if soap is None:
35 | + import soap
36 | + meth, self.args = soap.parse_input(fs.value)
37 | + response = soap.response(response)
38 | + other['RESPONSE'] = self.response = response
39 | + other['REQUEST_METHOD'] = ''
40 | + else:
41 | + # Ye haaa, XML-RPC!
42 | + global xmlrpc
43 | + if xmlrpc is None: import xmlrpc
44 | + meth, self.args = xmlrpc.parse_input(fs.value)
45 | + response=xmlrpc.response(response)
46 | + other['RESPONSE']=self.response=response
47 | + other['REQUEST_METHOD']='' # We don't want index_html!
48 | + self.maybe_webdav_client = 0
49 | else:
50 | self._file=fs.file
51 | else:
52 | diff -urN Zope-2.5.0-linux2-x86/lib/python/ZPublisher/soap.py Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/soap.py
53 | --- Zope-2.5.0-linux2-x86/lib/python/ZPublisher/soap.py 1970-01-01 01:00:00.000000000 +0100
54 | +++ Zope-2.5.0-linux2-x86.1/lib/python/ZPublisher/soap.py 2003-11-12 13:20:39.000000000 +0100
55 | @@ -0,0 +1,108 @@
56 | +"""SOAP support module
57 | +
58 | +by Antonio Beamud Montero
59 | +
60 | +Based on the XML-RPC Zope support module written by Eric Kidd at UserLand
61 | +software and the modifications made by Petru Paler, with much help
62 | +from Jim Fulton at DC.
63 | +
64 | +This code hooks Zope up to SOAPpy library.
65 | +"""
66 | +
67 | +import sys
68 | +from string import replace
69 | +from HTTPResponse import HTTPResponse
70 | +from SOAPpy import *
71 | +from zLOG import LOG, PROBLEM, ERROR, DEBUG, INFO,TRACE
72 | +
73 | +Config.specialArgs=0.
74 | +
75 | +def parse_input(data):
76 | + """Parse input data and return a method path and argument tuple
77 | +
78 | + The data is a string.
79 | + """
80 | + obj = Parser.parseSOAPRPC(data)
81 | + method = obj._name
82 | + args = tuple(obj._aslist)
83 | +
84 | + # Translate '.' to '/' in meth to represent object traversal.
85 | + method = replace(method, '.', '/')
86 | + return method, args
87 | +
88 | +#######################################################################
89 | +# New Object response based on SOAPpy
90 | +#
91 | +class SOAPResponse:
92 | + def __init__(self, real): self.__dict__['_real']=real
93 | + def __getattr__(self, name): return getattr(self._real, name)
94 | + def __setattr__(self, name, v): return setattr(self._real, name, v)
95 | + def __delattr__(self, name): return delattr(self._real, name)
96 | +
97 | + def setBody(self, body, title='', is_error=0, bogus_str_search=None):
98 | + # Marshall our body as an SOAP response. Strings will be sent
99 | + # strings, integers as integers, etc. We do *not* convert
100 | + # everything to a string first.
101 | + status = 200
102 | + if isinstance(body, Types.faultType):
103 | + status = 500
104 | + # Convert Fault object to SOAP response.
105 | + soapbody = Types.faulType("%s:Server" % NS.ENV_T, body)
106 | + body = buildSOAP(soapbody,encoding=None)
107 | + else:
108 | + try:
109 | + body = buildSOAP((body,),encoding=None)
110 | + except Exception,e:
111 | + self.exception()
112 | + return self
113 | +
114 | + t = 'text/xml'
115 | + # Set our body to the XML-RPC message, and fix our MIME type.
116 | + self._real.setBody(body)
117 | + self._real.setHeader('content-type', t)
118 | + self._real.setHeader("content-length", str(len(body)))
119 | + self._real.setStatus(status)
120 | + return self
121 | +
122 | + def exception(self, fatal=0, info=None,
123 | + absuri_match=None, tag_search=None):
124 | + # Fetch our exception info. t is type, v is value and tb is the
125 | + # traceback object.
126 | +
127 | + if type(info) is type(()) and len(info)==3: t,v,tb = info
128 | + else: t,v,tb = sys.exc_info()
129 | + LOG('SOAPException', TRACE, tb)
130 | + # Create an appropriate Fault object. Unfortunately, we throw away
131 | + # most of the debugging information. More useful error reporting is
132 | + # left as an exercise for the reader.
133 | + Fault=Types.faultType
134 | + f=None
135 | + try:
136 | + if isinstance(v, Fault):
137 | + f=v
138 | + elif isinstance(v, Exception):
139 | + f=Fault("%s:Server" % NS.ENV_T,
140 | + "Unexpected Zope exception: %s"%str(v))
141 | + else:
142 | + f=Fault("%s:Server" % NS.ENV_T,
143 | + "Unexpected Zope error value: %s"%str(v))
144 | + except:
145 | + f=Fault("%s:Server" % NS.ENV_T,
146 | + "Unknown Zope fault type")
147 | +
148 | + # Do the damage.
149 | + body = buildSOAP(f)
150 | + self._real.setBody(body)
151 | + self._real.setHeader('content-type', 'text/xml')
152 | + self._real.setStatus(500)
153 | + return tb
154 | +
155 | +response=SOAPResponse
156 | +
157 | +
158 | +
159 | +
160 | +
161 | +
162 | +
163 | +
164 |
--------------------------------------------------------------------------------
/zope/zope-2.6.2-soappy.diff:
--------------------------------------------------------------------------------
1 | diff -urN Zope-2.6.2-linux2-x86/lib/python/ZPublisher/HTTPRequest.py Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py
2 | --- Zope-2.6.2-linux2-x86/lib/python/ZPublisher/HTTPRequest.py 2003-04-09 16:00:27.000000000 +0200
3 | +++ Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/HTTPRequest.py 2003-11-12 14:51:01.000000000 +0100
4 | @@ -24,6 +24,7 @@
5 | from TaintedString import TaintedString
6 | from maybe_lock import allocate_lock
7 | xmlrpc=None # Placeholder for module that we'll import if we have to.
8 | +soap=None # Placeholder for module that we'll import if we have to.
9 |
10 | #cgi hotfix:
11 | if not hasattr(cgi, 'valid_boundary'):
12 | @@ -369,16 +370,26 @@
13 | meth=None
14 | fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
15 | if not hasattr(fs,'list') or fs.list is None:
16 | - # Hm, maybe it's an XML-RPC
17 | + # Hm, maybe it's an XML-RPC or SOAP
18 | if (fs.headers.has_key('content-type') and
19 | - fs.headers['content-type'] == 'text/xml' and
20 | + fs.headers['content-type'][:8] == 'text/xml' and
21 | method == 'POST'):
22 | - # Ye haaa, XML-RPC!
23 | - global xmlrpc
24 | - if xmlrpc is None: import xmlrpc
25 | - meth, self.args = xmlrpc.parse_input(fs.value)
26 | - response=xmlrpc.response(response)
27 | - other['RESPONSE']=self.response=response
28 | + if environ.has_key('HTTP_SOAPACTION'):
29 | + # this is a SOAP request
30 | + global soap
31 | + if soap is None:
32 | + import soap
33 | + meth, self.args = soap.parse_input(fs.value)
34 | + response = soap.response(response)
35 | + other['RESPONSE'] = self.response = response
36 | + other['REQUEST_METHOD'] = ''
37 | + else:
38 | + # Ye haaa, XML-RPC!
39 | + global xmlrpc
40 | + if xmlrpc is None: import xmlrpc
41 | + meth, self.args = xmlrpc.parse_input(fs.value)
42 | + response=xmlrpc.response(response)
43 | + other['RESPONSE']=self.response=response
44 | self.maybe_webdav_client = 0
45 | else:
46 | self._file=fs.file
47 | diff -urN Zope-2.6.2-linux2-x86/lib/python/ZPublisher/soap.py Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/soap.py
48 | --- Zope-2.6.2-linux2-x86/lib/python/ZPublisher/soap.py 1970-01-01 01:00:00.000000000 +0100
49 | +++ Zope-2.6.2-linux2-x86.1/lib/python/ZPublisher/soap.py 2003-11-12 14:51:01.000000000 +0100
50 | @@ -0,0 +1,125 @@
51 | +"""SOAP support module
52 | +
53 | +by Antonio Beamud Montero
54 | +
55 | +Based on the XML-RPC Zope support module written by Eric Kidd at UserLand
56 | +software and the modifications made by Petru Paler, with much help
57 | +from Jim Fulton at DC.
58 | +
59 | +This code hooks Zope up to SOAPpy library.
60 | +"""
61 | +
62 | +import sys
63 | +from string import replace
64 | +from HTTPResponse import HTTPResponse
65 | +from SOAPpy import *
66 | +from zLOG import LOG, PROBLEM, ERROR, DEBUG, INFO,TRACE
67 | +
68 | +Config.specialArgs=0.
69 | +
70 | +def parse_input(data):
71 | + """Parse input data and return a method path and argument tuple
72 | +
73 | + The data is a string.
74 | + """
75 | + obj = Parser.parseSOAPRPC(data)
76 | + method = obj._name
77 | + args = tuple(obj._aslist)
78 | +
79 | + # Translate '.' to '/' in meth to represent object traversal.
80 | + method = replace(method, '.', '/')
81 | + return method, args
82 | +
83 | +# See below
84 | +#
85 | +# def response(anHTTPResponse):
86 | +# """Return a valid ZPublisher response object
87 | +#
88 | +# Use data already gathered by the existing response.
89 | +# The new response will replace the existing response.
90 | +# """
91 | +# # As a first cut, lets just clone the response and
92 | +# # put all of the logic in our refined response class below.
93 | +# r=Response()
94 | +# r.__dict__.update(anHTTPResponse.__dict__)
95 | +# return r
96 | +
97 | +
98 | +
99 | +
100 | +#######################################################################
101 | +# New Object response based on SoapPy
102 | +#
103 | +class SOAPResponse:
104 | + def __init__(self, real): self.__dict__['_real']=real
105 | + def __getattr__(self, name): return getattr(self._real, name)
106 | + def __setattr__(self, name, v): return setattr(self._real, name, v)
107 | + def __delattr__(self, name): return delattr(self._real, name)
108 | +
109 | + def setBody(self, body, title='', is_error=0, bogus_str_search=None):
110 | + # Marshall our body as an SOAP response. Strings will be sent
111 | + # strings, integers as integers, etc. We do *not* convert
112 | + # everything to a string first.
113 | + status = 200
114 | + if isinstance(body, Types.faultType):
115 | + status = 500
116 | + # Convert Fault object to SOAP response.
117 | + soapbody = Types.faulType("%s:Server" % NS.ENV_T, body)
118 | + body = buildSOAP(soapbody,encoding=None)
119 | + else:
120 | + try:
121 | + body = buildSOAP((body,),encoding=None)
122 | + except Exception,e:
123 | + self.exception()
124 | + return self
125 | +
126 | + t = 'text/xml'
127 | + # Set our body to the XML-RPC message, and fix our MIME type.
128 | + self._real.setBody(body)
129 | + self._real.setHeader('content-type', t)
130 | + self._real.setHeader("content-length", str(len(body)))
131 | + self._real.setStatus(status)
132 | + return self
133 | +
134 | + def exception(self, fatal=0, info=None,
135 | + absuri_match=None, tag_search=None):
136 | + # Fetch our exception info. t is type, v is value and tb is the
137 | + # traceback object.
138 | +
139 | + if type(info) is type(()) and len(info)==3: t,v,tb = info
140 | + else: t,v,tb = sys.exc_info()
141 | + LOG('SOAPException', TRACE, tb)
142 | + # Create an appropriate Fault object. Unfortunately, we throw away
143 | + # most of the debugging information. More useful error reporting is
144 | + # left as an exercise for the reader.
145 | + Fault=Types.faultType
146 | + f=None
147 | + try:
148 | + if isinstance(v, Fault):
149 | + f=v
150 | + elif isinstance(v, Exception):
151 | + f=Fault("%s:Server" % NS.ENV_T,
152 | + "Unexpected Zope exception: %s"%str(v))
153 | + else:
154 | + f=Fault("%s:Server" % NS.ENV_T,
155 | + "Unexpected Zope error value: %s"%str(v))
156 | + except:
157 | + f=Fault("%s:Server" % NS.ENV_T,
158 | + "Unknown Zope fault type")
159 | +
160 | + # Do the damage.
161 | + body = buildSOAP(f)
162 | + self._real.setBody(body)
163 | + self._real.setHeader('content-type', 'text/xml')
164 | + self._real.setStatus(500)
165 | + return tb
166 | +
167 | +response=SOAPResponse
168 | +
169 | +
170 | +
171 | +
172 | +
173 | +
174 | +
175 | +
176 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | ==============================================
2 | SOAPpy - Simple to use SOAP library for Python
3 | ==============================================
4 |
5 | Current Maintainer:
6 |
7 | Gregory R. Warnes
8 |
9 | Original Authors:
10 |
11 | Cayce Ullman
12 | Brian Matthews
13 |
14 | Contributions by:
15 |
16 | Christopher Blunck
17 | Brad Knotwell
18 | Mark Bucciarelli (ported WSDL
19 | client from ZSI)
20 | Ivan R. Judson (Globus support)
21 | Kirk Strauser
22 | Antonio Beamud Montero (patches
23 | for integrating SOAPpy into Zope)
24 | And others.
25 |
26 | Copyright (c) 2002-2005, Pfizer, Inc.
27 | Copyright (c) 2001, Cayce Ullman.
28 | Copyright (c) 2001, Brian Matthews.
29 | All rights reserved, see the file LICENSE for conditions of use.
30 |
31 | INTRODUCTION
32 | ============
33 |
34 | The goal of the SOAPpy team is to provide a full-featured SOAP library
35 | for Python that is very simple to use and that fully supports dynamic
36 | interaction between clients and servers.
37 |
38 | INCLUDED
39 | --------
40 |
41 | - General SOAP Parser based on sax.xml
42 | - General SOAP Builder
43 | - SOAP Proxy for RPC client code
44 | - SOAP Server framework for RPC server code
45 |
46 | FEATURES
47 | --------
48 |
49 | - Handles all SOAP 1.0 types
50 | - Handles faults
51 | - Allows namespace specification
52 | - Allows SOAPAction specification
53 | - Homogeneous typed arrays
54 | - Supports multiple schemas
55 | - Header support (mustUnderstand and actor)
56 | - XML attribute support
57 | - Multi-referencing support (Parser/Builder)
58 | - Understands SOAP-ENC:root attribute
59 | - Good interop, passes all client tests for Frontier, SOAP::LITE, SOAPRMI
60 | - Encodings
61 | - SSL clients (with Python compiled with OpenSSL support)
62 | - SSL servers (with Python compiled with OpenSSL support and M2Crypto
63 | installed)
64 | - Encodes XML tags per SOAP 1.2 name mangling specification (Gregory Warnes)
65 | - Automatic stateful SOAP server support (Apache v2.x) (blunck2)
66 | - WSDL client support
67 | - WSDL server support
68 |
69 | TODO (See RELEASE_INFO and CHANGELOG for recent changes)
70 | ----
71 |
72 | - Timeout on method calls
73 | - Advanced arrays (sparse, multidimensional and partial)
74 | - Attachments
75 | - mod_python example
76 | - medusa example
77 | - Improved documentation
78 |
79 | MANIFEST
80 | --------
81 |
82 | Files
83 |
84 |
85 | README This file
86 | RELEASE_NOTES General information about each release
87 | ChangeLog Detailed list of changes
88 | TODO List of tasks that need to be done
89 |
90 | setup.py Python installation control files
91 | MANIFEST
92 | MANIFEST.in
93 |
94 | SOAPpy.spec* RPM package control file
95 |
96 | Directories
97 |
98 | SOAPpy/* Source code for the package
99 | SOAPpy/wstools/* Source code for WSDL tools
100 | tests/* unit tests and examples
101 | validate/* interop client and servers
102 | bid/* N+I interop client and server
103 | doc/* Documentation
104 | contrib/ Contributed examples (also see test/)
105 | docs/ Documentation
106 | tools/ Misc tools useful for the SOAPpy developers
107 | zope/ Patches to Zope allowing it to provide SOAP services
108 |
109 |
110 | INSTALLATION
111 | ============
112 |
113 | REQUIRED PACKAGES:
114 | -----------------
115 |
116 | - fpconst 0.6.0 or later, available from PyPI:
117 |
118 |
119 | - pyXML 0.8.3 or later,
120 |
121 | OPTIONAL PACKAGES
122 | -----------------
123 |
124 | - pyGlobus, optional support for Globus,
125 |
126 |
127 | - M2Crypto.SSL, optional support for server-side SSL
128 |
129 |
130 | - If Python is compiled with SSL support (Python 2.3 does so by
131 | default), client-side use of SSL is supported
132 |
133 | INSTALLATION STEPS
134 | ------------------
135 |
136 | As of version 0.9.8 SOAPpy can be installed using the standard python
137 | package installation tools.
138 |
139 | To install:
140 |
141 | 1) Unpack the distribution package:
142 |
143 | On Windows, use your favorite zip file uncompression tool.
144 |
145 | On Unix:
146 |
147 | $ tar -xvzf SOAPpy-$VERSION$.tar.gz
148 |
149 | if you have gnu tar, otherwise
150 |
151 | $ gzcat SOAPpy-$VERSION$.tar.gz | tar -xvf -
152 |
153 | 2) Change into the source directory
154 |
155 | $ cd SOAPpy-$VERSION$
156 |
157 | 3) Compile the package
158 |
159 | $ python setup.py build
160 |
161 | 4) Install the package
162 |
163 | On Windows:
164 |
165 | $ python setup.py install
166 |
167 | On Unix install as the owner of the python directories
168 | (usally root):
169 |
170 | $ su root
171 | Password: XXXXXX
172 | $ python setup.py install
173 |
174 |
175 | DOCUMENTATION
176 | =============
177 |
178 | QUICK START
179 | -----------
180 |
181 | A simple "Hello World" http SOAP server:
182 |
183 | import SOAPpy
184 | def hello():
185 | return "Hello World"
186 |
187 | server = SOAPpy.SOAPServer(("localhost", 8080))
188 | server.registerFunction(hello)
189 | server.serve_forever()
190 |
191 | And the corresponding client:
192 |
193 | import SOAPpy
194 | server = SOAPpy.SOAPProxy("http://localhost:8080/")
195 | print server.hello()
196 |
197 | BASIC TUTORIAL
198 | --------------
199 |
200 | Mark Pilgrims' _Dive Into Python_, published in printed form by
201 | Apress and online at at http://diveintopython.org provides a
202 | nice tutorial for SOAPpy in Chapter 12, "SOAP Web Services".
203 | See http://diveintopython.org/soap_web_services .
204 |
205 | OTHER DOCUMENTATION
206 | -------------------
207 |
208 | For further information see the files in the docs/ directory.
209 |
210 | Note that documentation is one of SOAPpy's current weak points.
211 | Please help us out!
212 |
213 |
214 | GETTING HELP
215 | ============
216 |
217 | REPORTING BUGS
218 | --------------
219 |
220 | Please submit bug reports, feature requests, patches, etc at the
221 | Python Web Services web site: http://pywebsvcs.sourceforge.net.
222 |
223 | MAILING LIST
224 | ============
225 |
226 | Please address questions and general discussion to the
227 | pywebsvcs-talk mailing list, pywebsvcs-talk@lists.sourceforge.net.
228 |
229 | For subscription information visit
230 | http://lists.sourceforge.net/lists/listinfo/pywebsvcs-talk.
231 | List archives are available at
232 | http://sourceforge.net/mailarchive/forum.php?forum=pywebsvcs-talk
233 |
234 | Please remember that the authors do have day jobs, so please try
235 | the mailing list before contacting them directy.
236 |
237 | $Id$
238 |
--------------------------------------------------------------------------------
/SOAPpy/Config.py:
--------------------------------------------------------------------------------
1 | """
2 | ################################################################################
3 | # Copyright (c) 2003, Pfizer
4 | # Copyright (c) 2001, Cayce Ullman.
5 | # Copyright (c) 2001, Brian Matthews.
6 | #
7 | # All rights reserved.
8 | #
9 | # Redistribution and use in source and binary forms, with or without
10 | # modification, are permitted provided that the following conditions are met:
11 | # Redistributions of source code must retain the above copyright notice, this
12 | # list of conditions and the following disclaimer.
13 | #
14 | # Redistributions in binary form must reproduce the above copyright notice,
15 | # this list of conditions and the following disclaimer in the documentation
16 | # and/or other materials provided with the distribution.
17 | #
18 | # Neither the name of actzero, inc. nor the names of its contributors may
19 | # be used to endorse or promote products derived from this software without
20 | # specific prior written permission.
21 | #
22 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
26 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | #
33 | ################################################################################
34 | """
35 |
36 | ident = '$Id$'
37 | from version import __version__
38 |
39 | import socket
40 | from types import *
41 |
42 | from NS import NS
43 |
44 | ################################################################################
45 | # Configuration class
46 | ################################################################################
47 |
48 | class SOAPConfig:
49 | __readonly = ('SSLserver', 'SSLclient', 'GSIserver', 'GSIclient')
50 |
51 | def __init__(self, config = None, **kw):
52 | d = self.__dict__
53 |
54 | if config:
55 | if not isinstance(config, SOAPConfig):
56 | raise AttributeError, \
57 | "initializer must be SOAPConfig instance"
58 |
59 | s = config.__dict__
60 |
61 | for k, v in s.items():
62 | if k[0] != '_':
63 | d[k] = v
64 | else:
65 | # Setting debug also sets returnFaultInfo,
66 | # dumpHeadersIn, dumpHeadersOut, dumpSOAPIn, and dumpSOAPOut
67 | self.debug = 0
68 | self.dumpFaultInfo = 1
69 | # Setting namespaceStyle sets typesNamespace, typesNamespaceURI,
70 | # schemaNamespace, and schemaNamespaceURI
71 | self.namespaceStyle = '1999'
72 | self.strictNamespaces = 0
73 | self.typed = 1
74 | self.buildWithNamespacePrefix = 1
75 | self.returnAllAttrs = 0
76 |
77 | # Strict checking of range for floats and doubles
78 | self.strict_range = 0
79 |
80 | # Default encoding for dictionary keys
81 | self.dict_encoding = 'ascii'
82 |
83 | # New argument name handling mechanism. See
84 | # README.MethodParameterNaming for details
85 | self.specialArgs = 1
86 |
87 | # If unwrap_results=1 and there is only element in the struct,
88 | # SOAPProxy will assume that this element is the result
89 | # and return it rather than the struct containing it.
90 | # Otherwise SOAPproxy will return the struct with all the
91 | # elements as attributes.
92 | self.unwrap_results = 1
93 |
94 | # Automatically convert SOAP complex types, and
95 | # (recursively) public contents into the corresponding
96 | # python types. (Private subobjects have names that start
97 | # with '_'.)
98 | #
99 | # Conversions:
100 | # - faultType --> raise python exception
101 | # - arrayType --> array
102 | # - compoundType --> dictionary
103 | #
104 | self.simplify_objects = 0
105 |
106 | # Per-class authorization method. If this is set, before
107 | # calling a any class method, the specified authorization
108 | # method will be called. If it returns 1, the method call
109 | # will proceed, otherwise the call will throw with an
110 | # authorization error.
111 | self.authMethod = None
112 |
113 | # Globus Support if pyGlobus.io available
114 | try:
115 | from pyGlobus import io;
116 | d['GSIserver'] = 1
117 | d['GSIclient'] = 1
118 | except:
119 | d['GSIserver'] = 0
120 | d['GSIclient'] = 0
121 |
122 |
123 | # Server SSL support if M2Crypto.SSL available
124 | try:
125 | from M2Crypto import SSL
126 | d['SSLserver'] = 1
127 | except:
128 | d['SSLserver'] = 0
129 |
130 | # Client SSL support if socket.ssl available
131 | try:
132 | from socket import ssl
133 | d['SSLclient'] = 1
134 | except:
135 | d['SSLclient'] = 0
136 |
137 | for k, v in kw.items():
138 | if k[0] != '_':
139 | setattr(self, k, v)
140 |
141 | def __setattr__(self, name, value):
142 | if name in self.__readonly:
143 | raise AttributeError, "readonly configuration setting"
144 |
145 | d = self.__dict__
146 |
147 | if name in ('typesNamespace', 'typesNamespaceURI',
148 | 'schemaNamespace', 'schemaNamespaceURI'):
149 |
150 | if name[-3:] == 'URI':
151 | base, uri = name[:-3], 1
152 | else:
153 | base, uri = name, 0
154 |
155 | if type(value) == StringType:
156 | if NS.NSMAP.has_key(value):
157 | n = (value, NS.NSMAP[value])
158 | elif NS.NSMAP_R.has_key(value):
159 | n = (NS.NSMAP_R[value], value)
160 | else:
161 | raise AttributeError, "unknown namespace"
162 | elif type(value) in (ListType, TupleType):
163 | if uri:
164 | n = (value[1], value[0])
165 | else:
166 | n = (value[0], value[1])
167 | else:
168 | raise AttributeError, "unknown namespace type"
169 |
170 | d[base], d[base + 'URI'] = n
171 |
172 | try:
173 | d['namespaceStyle'] = \
174 | NS.STMAP_R[(d['typesNamespace'], d['schemaNamespace'])]
175 | except:
176 | d['namespaceStyle'] = ''
177 |
178 | elif name == 'namespaceStyle':
179 | value = str(value)
180 |
181 | if not NS.STMAP.has_key(value):
182 | raise AttributeError, "unknown namespace style"
183 |
184 | d[name] = value
185 | n = d['typesNamespace'] = NS.STMAP[value][0]
186 | d['typesNamespaceURI'] = NS.NSMAP[n]
187 | n = d['schemaNamespace'] = NS.STMAP[value][1]
188 | d['schemaNamespaceURI'] = NS.NSMAP[n]
189 |
190 | elif name == 'debug':
191 | d[name] = \
192 | d['returnFaultInfo'] = \
193 | d['dumpHeadersIn'] = \
194 | d['dumpHeadersOut'] = \
195 | d['dumpSOAPIn'] = \
196 | d['dumpSOAPOut'] = value
197 |
198 | else:
199 | d[name] = value
200 |
201 |
202 | Config = SOAPConfig()
203 |
--------------------------------------------------------------------------------