How can I output what SUDs is generating/receiving?
Asked Answered
C

7

51

I have the following code:

from suds.client import Client
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)

SB_PRIVATE_ACCESS = {"PATH":"https://thisurl.com:443/services/",}

client = Client(SB_PRIVATE_ACCESS['PATH'])
print client

but I am getting 500 errors. I am trying to send what XML is being generated and received through SUDs, to the wsdl developer, but I can't figure how to output it? I have been looking in the documentation of SUDs, but can't seem to find it :/ Does anyone know how to output the raw xml that is sent and received?

Crusty answered 13/12, 2010 at 6:3 Comment(3)
You could use a sniffer such as Wireshark to look at what is transmitted.Malik
The second, third and fourth line is the correct three lines to output the XML. There must be a problem else where. Can you connect to the WSDL file with the interpreter?Gorgon
btw If you want to set the same level for all those logger, you can use logging.getLogger('suds').setLevel(logging.DEBUG) All loggers that descend from this logger (suds.*) will have the same logging level.Kwashiorkor
G
76

SUDS provides some convenience methods to do just that:

 client.last_sent()
 client.last_received()

These should provide you with what you need. I use them for error logging. The API doc for Client class should have any extra info you need.

Gerent answered 20/5, 2011 at 7:59 Comment(3)
jurko-sudo 0.4+ doesn't have these methods. see #22487665Hyaluronidase
print client.last_sent().str() and print client.last_received().str() will pretty print the XML request and response.Tamah
Eduard is correct - those methods were removed in the following commit: bitbucket.org/jurko/suds/commits/…Trochelminth
J
21

You can use the MessagePlugin to do this (this will work on the newer Jurko fork where last_sent and last_received have been removed)

from suds.plugin import MessagePlugin

class LogPlugin(MessagePlugin):
  def sending(self, context):
    print(str(context.envelope))
  def received(self, context):
    print(str(context.reply))

client = Client("http://localhost/wsdl.wsdl", plugins=[LogPlugin()])
Joel answered 5/6, 2014 at 15:53 Comment(3)
any clean way to attach the context.envelope and context.reply to the suds client object?Eventuate
@Eventuate check this: #26267347Vadose
@GustavoBezerra A little late, but pretty sweet, thanksEventuate
M
15

Suds supports internal logging, as you have been doing.

I am setting info levels like you:

logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport').setLevel(logging.DEBUG) # MUST BE THIS?
logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG)
logging.getLogger('suds.wsdl').setLevel(logging.DEBUG)
logging.getLogger('suds.resolver').setLevel(logging.DEBUG)
logging.getLogger('suds.xsd.query').setLevel(logging.DEBUG)
logging.getLogger('suds.xsd.basic').setLevel(logging.DEBUG)
logging.getLogger('suds.binding.marshaller').setLevel(logging.DEBUG)

And I also sometimes need to override the root logger logging level, depending on the framework being used under Suds calls (Django, Plone). If the root logger has a higher logging threshold, log messaegs may never appear (not sure how logger hierarchies should go). Below is an example how to override:

def enableDebugLog(self):
    """ Enable context.plone_log() output from Python scripts """
    import sys, logging
    logger = logging.getLogger()        
    logger.root.setLevel(logging.DEBUG)
    logger.root.addHandler(logging.StreamHandler(sys.stdout))
Motherinlaw answered 17/5, 2011 at 17:39 Comment(0)
D
8

To get only the generated message this also works:

from suds.client import Client
import sys

SB_PRIVATE_ACCESS = {"PATH":"https://thisurl.com:443/services/",}

client = Client(SB_PRIVATE_ACCESS['PATH'])

client.set_options(nosend=True)

resp = ...<invoke client here>...

sys.stdout.buffer.write(resp.envelope)
Demagogue answered 12/1, 2014 at 18:41 Comment(1)
This of course only gets the message sent to the server, but does not actually send it and therefore cannot be used to get the response. Still useful, though.Sequential
J
3

try changing

logging.basicConfig(level=logging.INFO)

to

logging.basicConfig(filename="/tmp/suds.log", level=logging.DEBUG)
Jaime answered 8/6, 2011 at 15:15 Comment(0)
L
1

If you want to reduce logging by jurko-suds

 logging.basicConfig(level=logging.INFO)

    logging.getLogger('suds.client').setLevel(logging.INFO)
    logging.getLogger('suds.transport').setLevel(logging.INFO) 
    logging.getLogger('suds.xsd.schema').setLevel(logging.INFO)
    logging.getLogger('suds.wsdl').setLevel(logging.INFO)
    logging.getLogger('suds.resolver').setLevel(logging.INFO)
    logging.getLogger('suds.xsd.query').setLevel(logging.INFO)
    logging.getLogger('suds.xsd.sxbasic').setLevel(logging.INFO)
    logging.getLogger('suds.xsd.sxbase').setLevel(logging.INFO)
    logging.getLogger('suds.metrics').setLevel(logging.INFO)
    logging.getLogger('suds.binding.marshaller').setLevel(logging.INFO)
Luisaluise answered 8/1, 2016 at 6:29 Comment(0)
G
1

I have hit this problem working with the bingads API, worth noting the order is important I had to import logging then import suds start the logging then import bingads, any other order and nothing was output in the logs from suds.

So check your import order, and move your logging statements and it may fix your issue.

Glidden answered 21/5, 2018 at 15:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.