Suds
Suds is a lightweight SOAP python client for consuming Web Services. A community fork of the jurko fork.
Install / Use
/learn @suds-community/SudsREADME
Overview
Suds is a lightweight SOAP-based web service client for Python
licensed under LGPL (see the LICENSE.txt file included in the
distribution).
Although the original suds package stopped releasing versions after 0.4,
many (but not all) other open source projects moved to a maintained fork known
as "suds-jurko". This is a community fork of that fork that is releasing
packages under the main suds package name (and suds-community for
consistency until version 2.x of this package).
Forked project information
- Project site - https://github.com/suds-community/suds
- Official releases can be downloaded from:
Original suds Python library development project information
For development notes see the HACKING.rst document included in the
distribution.
Installation
Standard Python installation.
Here are the basic instructions for 3 different installation methods:
- Using
pip- Have the
pippackage installed. - Run
pip install suds.
- Have the
- Using
easy-install- Have the
setuptoolspackage installed. - Run
easy_install suds.
- Have the
- From sources
- Unpack the source package somewhere.
- Run
python setup.py installfrom the source distribution's top level folder.
Installation troubleshooting
- Released prior to
0.7have many known installation issues requiring the target Python environment to be manually prepared when using some ancient Python versions, e.g. 2.4, 2.5 or 3.1. - Releases
0.4.1. jurko 5 < x <= 0.6may not be installed usingpipinto a Python environment with an already installedsetuptoolspackage older than the version expected by our project. Displayed error message includes instructions on how to manually upgrade the installedsetuptoolspackage before rerunning our installation.pipinternally imports existingsetuptoolspackages before running our setup, thus preventing us from upgrading the existingsetuptoolsinstallation inplace.
- If automated
setuptoolsPython package installation fails (used in releases0.4.1 jurko 5and later), e.g. due to PyPI web site not being available, user might need to install it manually and then rerun the installation. - Releases prior to
0.4.1. jurko 5will fail if thedistributePython package is not already installed on the system. - Python 2.4.3 on Windows has problems using automated
setuptoolsPython package downloads via the HTTPS protocol, and therefore does not work correctly with PyPI which uses HTTPS links to all of its packages. The same does not occur when using Python version 2.4.4.
Features
Basic features:
- No class generation
- Provides an object-like API.
- Reads wsdl at runtime for encoding/decoding
- Provides for the following SOAP (style) binding/encoding:
- Document/Literal
- RPC/Literal
- RPC/Encoded (section 5)
The goal of suds is to present an RPC-like interface into soap-based web services. This means that in most cases, users do not need to be concerned with the complexities of the WSDL and referenced schemas. Regardless of which soap message style is specified, the signature of the service methods remain the same. Uses that do examine the WSDL will notice that even with the document soap message style, the signature of each method resembles an RPC. The method signature contains the contents of the document defined for the message instead of the document itself.
The primary interface into the library is the
Client object. It provides methods for configuring the library and (2)
sub-namespaces defined below. When the
Client is created, it processes the wsdl and referenced schema(s).
From this information, it derives a representation of this information
which is used to provide the user with a service description and
for message/reply processing.
Python Support
See .github/workflows/test_and_release.yml for supported Python versions. The goal is to support
currently maintained versions of Python.
Logging
The suds package use the Python standard lib logging package: all messages are at level DEBUG or ERROR.
To register a console handler you can use basicConfig:
import logging
logging.basicConfig(level=logging.INFO)
Once the console handler is configured, the user can enable module specific debugging doing the following: logging.getLogger(<desired package>).setLevel(logging.<desired-level>) A common example (show sent/received soap messages):
logging.getLogger('suds.client').setLevel(logging.DEBUG)
Suggested modules for debugging:
- suds.client:: Set the logging level to DEBUG on this module to see soap messages (in & out) and http headers.
- suds.transport:: Set the logging level to DEBUG on this module to see more details about soap messages (in& out) and http headers.
- suds.xsd.schema:: Set the logging level to DEBUG on this module to see digestion of the schema(s).
- suds.wsdl:: Set the logging level to
DEBUGon this module to see digestion WSDL.
Basic Usage
Version: API^3^
The suds
Client class provides a consolidated API for consuming web services.
The object contains (2) sub-namespaces:
service:: The
service namespace provides a proxy for the consumed service. This
object is used to invoke operations (methods) provided by the service
endpoint.
factory:: The
factory namespace provides a factory that may be used to create
instances of objects and types defined in the WSDL.
You will need to know the url for WSDL for each service used. Simply create a client for that service as follows:
from suds.client import Client
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)
You can inspect service object with: __str()__ as follows to get a
list of methods provide by the service:
print(client)
Suds - version: 0.3.3 build: (beta) R397-20081121
Service (WebServiceTestBeanService) tns="http://test.server.enterprise.rhq.org/"
Prefixes (1):
ns0 = "http://test.server.enterprise.rhq.org/"
Ports (1):
(Soap)
Methods:
addPerson(Person person, )
echo(xs:string arg0, )
getList(xs:string str, xs:int length, )
getPercentBodyFat(xs:string name, xs:int height, xs:int weight)
getPersonByName(Name name, )
hello()
testExceptions()
testListArg(xs:string[] list, )
testVoid()
updatePerson(AnotherPerson person, name name, )
Types (23):
Person
Name
Phone
AnotherPerson
note: See example of service with multiple ports below.
The sample output lists that the service named
WebServiceTestBeanService has methods such as
getPercentBodyFat() and addPerson().
Simple Arguments
Let's start with the simple example. The getPercentBodyFat() method has
the signature of getPercentBodyFat(xs:string name,
xs:int height, xs:int weight). In this case, the
parameters are simple types. That is, they not objects. This
method would be invoked as follows:
result = client.service.getPercentBodyFat('jeff', 68, 170)
print(result)
You have 21% body fat.
result = client.service.getPercentBodyFat(name='jeff', height=68, weight=170)
print(result)
You have 21% body fat.
d = dict(name='jeff', height=68, weight=170)
result = client.service.getPercentBodyFat(**d)
print(result)
You have 21% body fat.
Complex Arguments
The addPerson() method takes a person argument of type:
Person and has a signature of: addPerson(Person person,
) where parameter type is printed followed by it's name. There is a
type (or class) named 'person' which is coincidentally the same name
as the argument. Or in the case of getPercentBodyFat() the parameters
are string of type xs:string and integer of type xs:int.
So, to create a Person object to pass as an argument we need to
get a person argument using the factory sub-namespace as
follows:
person = client.factory.create('Person')
print(person)
(Person)=
{
phone = []
age = NONE
name(Name) =
{
last = NONE
first = NONE
}
}
As you can see, the object is created as defined by the WSDL. The list
of phone number is empty so we'll have to create a Phone
object:
phone = client.factory.create('Phone')
phone.npa = 202
phone.nxx = 555
phone.number = 1212
... and the name (Name object) and age need to be set and we need to create a name object first:
name = client.factory.create('Name')
name.first = 'Elmer'
name.last = 'Fudd'
Now, let's set the properties of our Person object
person.name = name
person.age = 35
person.phone = [phone]
or
person.phone.append(phone)
\... and invoke our method named addPerson() as follows:
```py
try:
person_added = client.service.addPerson(person)
except WebFault as e:
print(e)
It's that easy.
The ability to use python dict to represent complex objects was
re-introduced in 0.3.8. However, this is not the preferred
method because it may lead to passing incomplete objects. Also, this
approach has a significant limitation. Users may not use python
dict for complex objects when they are subclasses (or
extensions) of types defined in the wsdl/schema. In other words, if the
schema defines a type to be an Animal and you wish to pass a
Dog (assumes Dog isa Animal), you may not use a
dict to represent the dog. In this case, suds needs to set the
xsi:type="Dog" but cannot because the python dict does not
provide enough informatio
