In this article i am going to explain briefly the implementation of Suds Client. Suds is a lightweight library that uses SOAP based clients for python. SOAP is an RPC (Remote Procedure Call) that uses object-oriented protocol. Suds is actually lightweight SOAP python client that provides a service proxy for web services.
Implementing suds Client
For implementing the suds client follow the below steps.
- Install suds library. Suds can be installed as,
sudo pip install suds or sudo apt-get install python-suds - Import Client from suds as shown in the example below.
- Instantiate the suds client by providing the WSDL path. The WSDL path can be a WSDL URL or WSDL file(with .wsdl extension, local or remote). In the below example i have given a WSDL URL and i will explain how to create a client using this WSDL URL.
from suds.client import Client client = Client("https://wsvc.cdiscount.com/MarketplaceAPIService.svc?wsdl")
- Now the suds client is ready to use. The suds client contains the operations present in the WSDL as methods and all the data types as a factory of Types. If you want to see what actually the client contains you can console it. In the below image i have shown the output of above created client.
from suds.client import Client client = Client("https://wsvc.cdiscount.com/MarketplaceAPIService.svc?wsdl") print client # Content inside the client Suds ( https://fedorahosted.org/suds/ ) version: 0.7.dev0 Service ( MarketplaceAPIService ) tns="http://tempuri.org/" Prefixes (7) ns0 = "http://schemas.datacontract.org/2004/07/Cdiscount.Framework.Core.Communication.Messages" ns1 = "http://schemas.datacontract.org/2004/07/Cdiscount.Service.Marketplace.API.External.Contract.Data.Mail" Ports (1): (BasicHttpBinding_IMarketplaceAPIService) Methods (30): GetAllowedCategoryTree(ns0:HeaderMessage headerMessage) GetBrandList(ns0:HeaderMessage headerMessage) GetDiscussionMailList(ns0:HeaderMessage headerMessage, ns6:GetDiscussionMailListRequest request) GetSellerIndicators(ns0:HeaderMessage headerMessage) GetSellerInformation(ns0:HeaderMessage headerMessage) ManageParcel(ns0:HeaderMessage headerMessage, ns6:ManageParcelRequest manageParcelRequest) SubmitOfferPackage(ns0:HeaderMessage headerMessage, ns6:OfferPackageRequest offerPackageRequest) Types (193): ns6:AcceptationStateEnum ns6:Address aginatedMessage ns6:OfferOrder ns6:OfferPackageRequest ns6:OfferPool ns6:OfferPriceBenchMark
- In this article i will consider only “GetSellerInformation”. For calling a method in suds we need to create a factory and i will explain how to create the factory for this method. GetSellerInformation takes “HeaderMessage” as an argument and we need to create first a factory for “HeaderMessage”. Before creating the factory of the “HeaderMessage” we should be aware of how we have to create it. In order to see the architecture of it we can console it. Let us print the how actually “HeaderMessage” factory looks like and how we need to create it.
from suds.client import Client client = Client("https://wsvc.cdiscount.com/MarketplaceAPIService.svc?wsdl") HeaderMessage = client.factory.create('ns0:HeaderMessage') print HeaderMessage (HeaderMessage){ Context = (ContextMessage){ CatalogID = None CustomerID = None CustomerId = None } Localization = (LocalizationMessage){ Country = (Country){ value = None } Currency = (Currency){ value = None } Language = (Language){ value = None } } Security = (SecurityContext){ DomainRightsList = (ArrayOfDomainRights){ DomainRights[] = <empty> } IssuerID = None SessionID = None TokenId = None UserName = None } Version = None }
- This is how the “HeaderMessage” actually looks like and we have to create the factory for a method accordingly based on this format. Once the factory for “HeaderMessage” is ready we can call the “GetSellerInformation” method and pass the HeaderMessage in it as a paramater. I have explained in the below example how we can create the suds factory for “HeaderMessage”.
from suds.client import Client client = Client("https://wsvc.cdiscount.com/MarketplaceAPIService.svc?wsdl") HeaderMessage = client.factory.create('ns0:HeaderMessage') # Create a factory and assign the values HeaderMessage.Context = { "CatalogID" = XXXXX "CustomerID" = XXXXX "SiteID" = XXXXX } HeaderMessage.Localization = { "Country": "Fr", "Currency": "Eur", "DecimalPosition": XXXXX, "Language": "French" } SecurityContext = client.factory.create('ns0:SecurityContext') ArrayOfDomainRights = client.factory.create('ns0:ArrayOfDomainRights') ArrayOfDomainRights.DomainRights = [XXXXXXXXXXXXX, XXXXXXXXXXXX] SecurityContext.DomainRightsList = ArrayOfDomainRights SecurityContext.IssuerID = XXXXXXXX SecurityContext.UserName = XXXXXXXXX SecurityContext.TokenId = XXXXXXXXXXXXXXXXXXXXXX HeaderMessage.Security = SecurityContext HeaderMessage.Version = '1.0' # call the GetSellerInformation and pass the HeaderMessage response = client.service.GetSellerInformation(HeaderMessage)
- The response from a suds call is in the object format, we can access the content inside the response directly using the dot(.) This is an example of the suds response.
print response
# Suds response of GetSellerInformation (SellerMessage){ ErrorMessage = None OperationSuccess = True ErrorList = None SellerLogin = "XXXXXXXXXXXX" TokenId = "XXXXXXXXXXXXXXXXX" Seller = (Seller){ Email = "XXXXXXXXXXXXXXXXXX" IsAvailable = "ActiveSeller" Login = "XXXXXXXXXXXXXX" MobileNumber = "XXXXXXXXXXXXXXX" PhoneNumber = "XXXXXXXXXXXXX" SellerAddress = (Address){ Address1 = "XXXXXXXXXXXX" Address2 = "XXXXXXXXXXXX" ApartmentNumber = None Building = None City = "XXXXXXXXXXX" FirstName = None ZipCode = "XXXXXXXXXXXX" } ShopName = "XXXXXXXXXXXXXXX" ShopUrl = None SiretNumber = "XXXXXXXXXXXXX" State = "Activated" } }
- If you want to convert the response into the serializable json format you need to add the following code to convert it into the serializable json format.
import json from suds.sudsobject import asdict def recursive_dict(d): out = {} for k, v in asdict(d).iteritems(): if hasattr(v, '__keylist__'): out[k] = recursive_dict(v) elif isinstance(v, list): out[k] = [] for item in v: if hasattr(item, '__keylist__'): out[k].append(recursive_dict(item)) else: out[k].append(item) else: out[k] = v return out response = json.dumps(recursive_dict(response))
- After the suds response is passed through this method it converts it into the serilizable json format as shown below.
{"SellerLogin": "webkultest", "OperationSuccess": true, "TokenId": "XXXXXXXXXXXXXXXXXXXX", "ErrorMessage": null, "ErrorList": null, "Seller": { "ShopUrl": null, "MobileNumber": "XXXXXXXXXXXXX", "ShopName": "XXXXXXXXX", "IsAvailable": "ActiveSeller", "State": "Activated", "PhoneNumber": "XXXXXXXXXXXX", "Login": "webkultest", "Email": "XXXXXXXXXXXXXX", "ZipCode": "XXXXXXXXXXX"} }
Some useful methods used in suds
- client.last_sent() # displays the latest the request of the suds call
client.last_received() #displays the latest response of the suds call. - For full debugging the output use the following methods.
import logging
logging.basicConfig(level=logging.INFO)
logging.getLogger(‘suds.client’).setLevel(logging.DEBUG)
logging.getLogger(‘suds.transport’).setLevel(logging.DEBUG)
logging.getLogger(‘suds.xsd.schema’).setLevel(logging.DEBUG
logging.getLogger(‘suds.wsdl’).setLevel(logging.DEBUG)
That is it.!!!
If you liked this post, It would be very grateful if you write your opinions, comments and suggestions to keep the post updated and interesting.
Thank you!
Current Product Version - 1.0
Supported Framework Version - python
I need to implement a client with a web services but being a beginner I have some serious difficulties.
I insert the program lines that attach to the foot; everything seems ok but last instruction – client.service.process(serviceId, data) – write in console!
Could you please explain why?
Thank you,
Sincerely
Francesco
client = Client(URLWSDL, username=XXXXXXX, password=XXXXXXX, faults=False)
serviceId = client.factory.create(‘ns0:serviceId’)
serviceId = ‘request’
data = client.factory.create(‘ns0:data’)
data[‘dichiarante’] = ‘XXXXXXXXXX’
data[‘xml’] = xml
security = Security()
token = UsernameToken(username=AUTHUSERNAME, password=AUTHPASSWORD)
security.tokens.append(token)
client.set_options(wsse=security)
response = client.service.process(serviceId, data)