50

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?

alfredo
  • 961
  • 3
  • 10
  • 11
  • You could use a sniffer such as Wireshark to look at what is transmitted. – jfs Dec 13 '10 at 07:35
  • 1
    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? – chrisg Dec 15 '10 at 16:11
  • 3
    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. – simao Jan 24 '12 at 16:44

7 Answers7

75

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.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
olly_uk
  • 11,559
  • 3
  • 39
  • 45
  • 11
    jurko-sudo 0.4+ doesn't have these methods. see http://stackoverflow.com/questions/22487165/how-can-i-inspect-what-suds-is-generating-receiving-in-sudo-0-4-1-jurko-5-and?lq=1 – Eduard Gamonal Jun 17 '15 at 15:33
  • 11
    `print client.last_sent().str()` and `print client.last_received().str()` will pretty print the XML request and response. – Vanni Totaro Aug 07 '15 at 12:14
  • Eduard is correct - those methods were removed in the following commit: https://bitbucket.org/jurko/suds/commits/f0034d6826c179625478bc19ae2a39a0b803fc3a – Peter Hanley Jun 24 '16 at 16:23
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()])
Damian
  • 528
  • 5
  • 9
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))
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
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)
Fernando César
  • 681
  • 1
  • 8
  • 16
  • 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. – Wodin Apr 15 '14 at 03:55
3

try changing

logging.basicConfig(level=logging.INFO)

to

logging.basicConfig(filename="/tmp/suds.log", level=logging.DEBUG)
Dustin
  • 3,965
  • 5
  • 27
  • 33
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)
Alex Punnen
  • 5,287
  • 3
  • 59
  • 71
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.

Oly
  • 370
  • 5
  • 16