how to prevent SUDS from checking WSDL - python

Now I am writing simple OpenERP module for my customer. I use SUDS to connect with bank, to get Statements.
I wrote xml request, that works without problem. I get response from bank, that also looks ok. Problem is that response from bank use type, that is not defined in WSDL (I wrote to bank support, that they have a bug).
Traceback (most recent call last):
File "example3.py", line 112, in <module>
wiadomosc = client.service.GetStatement(__inject={'msg': xml})
File "/usr/lib/python2.7/dist-packages/suds/client.py", line 542, in __call__
return client.invoke(args, kwargs)
File "/usr/lib/python2.7/dist-packages/suds/client.py", line 773, in invoke
return self.send(msg)
File "/usr/lib/python2.7/dist-packages/suds/client.py", line 647, in send
result = self.succeeded(binding, reply.message)
File "/usr/lib/python2.7/dist-packages/suds/client.py", line 684, in succeeded
reply, result = binding.get_reply(self.method, reply)
File "/usr/lib/python2.7/dist-packages/suds/bindings/binding.py", line 156, in get_reply
result = self.replycomposite(rtypes, nodes)
File "/usr/lib/python2.7/dist-packages/suds/bindings/binding.py", line 230, in replycomposite
sobject = unmarshaller.process(node, resolved)
File "/usr/lib/python2.7/dist-packages/suds/umx/typed.py", line 66, in process
return Core.process(self, content)
File "/usr/lib/python2.7/dist-packages/suds/umx/core.py", line 48, in process
return self.append(content)
File "/usr/lib/python2.7/dist-packages/suds/umx/core.py", line 63, in append
self.append_children(content)
File "/usr/lib/python2.7/dist-packages/suds/umx/core.py", line 140, in append_children
cval = self.append(cont)
File "/usr/lib/python2.7/dist-packages/suds/umx/core.py", line 61, in append
self.start(content)
File "/usr/lib/python2.7/dist-packages/suds/umx/typed.py", line 80, in start
raise TypeNotFound(content.node.qname())
suds.TypeNotFound: Type not found: 'ns29:BkToCstmrStmt'
And types, they provide
....
ns37:BaselineStatus3Code
ns32:BatchBookingIndicator
ns33:BatchBookingIndicator
ns36:BatchBookingIndicator
ns30:BatchInformation1
ns31:BatchInformation2
ns29:BatchInformation2
ns39:BilateralLimitDetails3
ns27:BkToCstmrCardRptType
ns27:BkTxCdType
ns27:BookgDtType
ns10:BookingDate
ns4:Bool
ns16:Bool
ns2:Bool
ns15:Bool
ns17:BouldingNumber
....
So there is no BkToCstmrStmt. How can I make suds to just get response from server, and not analyse it? Just build tree?
Thank you

Still I don't know what is wrong with my code. I solved it in that way:
class MessageInterceptor(suds.plugin.MessagePlugin):
def __init__(self, *args, **kwargs):
self.message = None
def received(self, context):
#recieved xml as a string
#print "%s bytes received" % len(context.reply)
self.message = context.reply
#clean up reply to prevent parsing
context.reply = ""
return context
message_interceptor = MessageInterceptor()
client = Client('https://some-adress-to?wsdl',plugins=[message_interceptor])
So now I can call client method
xml = Raw("""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
<soapenv:Header>
...
</soapenv:Header>
<soapenv:Body>
<urn1:GetStatement>
...
</urn1:GetStatement>
</soapenv:Body>
</soapenv:Envelope>
""")
response = client.service.GetStatement(__inject={'msg': xml})
Now suds thinks that got nothing from server. But message we recieved is stored in
message_interceptor.message
Now to get normal dict object from message I do it like that:
import xmltodict
message_interceptor.message = message_interceptor.message.replace('ns17:','')
message_interceptor.message = message_interceptor.message.replace('ns40:','')
message_interceptor.message = message_interceptor.message.replace('soap:','')
response = xmltodict.parse(message_interceptor.message)['Envelope']['Body']['GetStatementResponse']['Document']
Now I can use response as normal response from suds.

Related

Trouble using configparser to pass API credentials

I have a config.ini file that looks like this
[REDDIT]
client_id = 'myclientid23jd934g'
client_secret = 'myclientsecretjf30gj5g'
password = 'mypassword'
user_agent = 'myuseragent'
username = 'myusername'
When I try to use reddit's API praw like this:
import configparser
import praw
class redditImageScraper:
def __init__(self, sub, limit):
config = configparser.ConfigParser()
config.read('config.ini')
self.sub = sub
self.limit = limit
self.reddit = praw.Reddit(client_id=config.get('REDDIT','client_id'),
client_secret=config.get('REDDIT','client_secret'),
password=config.get('REDDIT','password'),
user_agent=config.get('REDDIT','user_agent'),
username=config.get('REDDIT','username'))
def get_content(self):
submissions = self.reddit.subreddit(self.sub).hot(limit=self.limit)
for submission in submissions:
print(submission.id)
def main():
scraper = redditImageScraper('aww', 25)
scraper.get_content()
if __name__ == '__main__':
main()
I get this traceback
Traceback (most recent call last):
File "config.py", line 30, in <module>
main()
File "config.py", line 27, in main
scraper.get_content()
File "config.py", line 22, in get_content
for submission in submissions:
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\models\listing\generator.py", line 61, in __next__
self._next_batch()
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\models\listing\generator.py", line 71, in _next_batch
self._listing = self._reddit.get(self.url, params=self.params)
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\reddit.py", line 454, in get
data = self.request("GET", path, params=params)
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\reddit.py", line 627, in request
method, path, data=data, files=files, params=params
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 185, in request
params=params, url=url)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 116, in _request_with_retries
data, files, json, method, params, retries, url)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 101, in _make_request
params=params)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\rate_limit.py", line 35, in call
kwargs['headers'] = set_header_callback()
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 145, in _set_header_callback
self._authorizer.refresh()
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\auth.py", line 328, in refresh
password=self._password)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\auth.py", line 138, in _request_token
response = self._authenticator._post(url, **data)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\auth.py", line 31, in _post
raise ResponseException(response)
prawcore.exceptions.ResponseException: received 401 HTTP response
However when I manually insert the credentials, my code runs exactly as expected. Also, if I run the line
print(config.get('REDDIT', 'client_id'))
I get the output 'myclientid23jd934g' as expected.
Is there some reason that praw won't allow me to pass my credentials using configparser?
Double check what your inputs to praw.Reddit are:
kwargs = dict(client_id=config.get('REDDIT','client_id'),
client_secret=config.get('REDDIT','client_secret'),
password=config.get('REDDIT','password'),
user_agent=config.get('REDDIT','user_agent'),
username=config.get('REDDIT','username')))
print(kwargs)
praw.Reddit(**kwargs)
You're overcomplicating configuration here — PRAW will take care of this for you.
If you rename config.ini to praw.ini, you can replace your whole initialization with just
self.reddit = praw.Reddit('REDDIT')
This is because PRAW will look for a praw.ini file and parse it for you. If you want to give the section a more descriptive name, make sure to update it in the praw.ini as well as in the single parameter passed to Reddit (which specifies the section of the file to use).
See https://praw.readthedocs.io/en/latest/getting_started/configuration/prawini.html.
As this page notes, values like username and password should not have quotation marks around them. For example,
password=mypassword
is correct, but
password="mypassword"
is incorrect.

python, suds and client certificate: SAXParseException: not well-formed (invalid token)

I have implementing a SOAP client with python (2.6.6) and suds. The server needs a certificate from the client for authentication. For implementing this in python and with suds I have use this answer from Andre Miras. This seem's also to work because I can access and get the WSDL from the server. But I have another problem. While parsing the WSDL I get a xml.sax._exceptions.SAXParseException: <unknown>:1:1: not well-formed (invalid token) error.
To check if I can realy get the WSDL I have manipulate the "open" method (please note the "print"s)
def open(self, request):
"""
Fetches the WSDL using cert.
"""
print "11 "
# self.addcredentials(request)
resp = requests.get(request.url, data=request.message,
headers=request.headers, cert=self.cert)
result = io.StringIO(resp.content.decode('utf-8'))
print str(result.getvalue())
print "<<WSDL END>>"
return result
If I run the script I get the output:
11
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://webService.net.app.my.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="CStatisticService" targetNamespace="http://webService.net.app.my.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://webService.net.app.my.com/" elementFormDefault="unqualified" targetNamespace="http://webService.net.app.my.com/" version="1.0">
<xs:element name="getFileActionsNmbr" type="tns:getFileActionsNmbr"/>
...
...
...
</wsdl:service>
</wsdl:definitions>
<<WSDL END>>
Traceback (most recent call last):
File "./c-App_jvmThreads", line 63, in <module>
client = suds.client.Client(wsdl_url, headers=headers, transport=t)
File "/usr/lib/python2.6/site-packages/suds/client.py", line 112, in __init__
self.wsdl = reader.open(url)
File "/usr/lib/python2.6/site-packages/suds/reader.py", line 152, in open
d = self.fn(url, self.options)
File "/usr/lib/python2.6/site-packages/suds/wsdl.py", line 136, in __init__
d = reader.open(url)
File "/usr/lib/python2.6/site-packages/suds/reader.py", line 79, in open
d = self.download(url)
File "/usr/lib/python2.6/site-packages/suds/reader.py", line 101, in download
return sax.parse(string=content)
File "/usr/lib/python2.6/site-packages/suds/sax/parser.py", line 136, in parse
sax.parse(source)
File "/usr/lib64/python2.6/xml/sax/expatreader.py", line 107, in parse
xmlreader.IncrementalParser.parse(self, source)
File "/usr/lib64/python2.6/xml/sax/xmlreader.py", line 123, in parse
self.feed(buffer)
File "/usr/lib64/python2.6/xml/sax/expatreader.py", line 211, in feed
self._err_handler.fatalError(exc)
File "/usr/lib64/python2.6/xml/sax/handler.py", line 38, in fatalError
raise exception
xml.sax._exceptions.SAXParseException: <unknown>:1:1: not well-formed (invalid token)
I have cut the WSDL because clarity. But I have also a Java client which use the SOAP service and can read and parse the WSDL successfully.
Anybody knows what's can be wrong?
I found I have to replace the following lines. The commented out code is the old code, the uncommented line the new new code:
#import io
import StringIO
...
# result = io.StringIO(resp.content.decode('utf-8'))
result = StringIO.StringIO(resp.content)
Not sure why, but this works for me (changing only io.StringIO(resp.content) doesn't work).

Fault: No Attribute in xmlrpclib.py

I'm working on an application in which a server and client are being created; the ServerAPI is using SimpleXMLRPCServer and the ClientAPI is using xmlrpclib. The client is initiated with:
class w_Client:
def __init__(self, ServerIP, ServerPort, ClientIP):
self.conn = xmlrpclib.ServerProxy("http://" + ServerIP + ":" + str(ServerPort))
self.ClientIP = ClientIP
upon a button being pressed in the application, an xml specification file is created and passed thru
def Create(self, XMLstring):
return self.conn.Create(XMLstring, self.ClientIP)
I've already checked to make sure that the XMLstring is valid XML; however, when I get press the button, I get the following error:
Traceback (most recent call last):
File "/home/app/UI/MainWindow.py", line 461, in compile
xmlFile = compiler.compile()
File "/home/app/Core/Compiler.py", line 75, in compile
self.compile_top()
File "/home/app/Core/Compiler.py", line 354, in compile_top
status = mainWidgets["w_client"].Create(xmlString)
File "/home/app/Wireless/ClientAPI.py", line 12, in Create
return self.conn.Create(XMLstring, self.ClientIP)
File "/usr/lib/python2.7/xmlrpclib.py", line 1233, in __call__
return self.__send(self.__name, args)
File "/usr/lib/python2.7/xmlrpclib.py", line 1591, in __request
verbose=self.__verbose
File "/usr/lib/python2.7/xmlrpclib.py", line 1273, in request
return self.single_request(host, handler, request_body, verbose)
File "/usr/lib/python2.7/xmlrpclib.py", line 1306, in single_request
return self.parse_response(response)
File "/usr/lib/python2.7/xmlrpclib.py", line 1482, in parse_response
return u.close()
File "/usr/lib/python2.7/xmlrpclib.py", line 794, in close
raise Fault(**self._stack[0])
xmlrpclib.Fault: <Fault 1: "<type 'exceptions.TypeError'>:'NoneType' object has no attribute '__getitem__'">
I've also made sure that the ClientIP is passed correctly. Otherwise, I'm not entirely sure what's going on or how to even go about fixing it.
<type 'exceptions.TypeError'>:'NoneType' object has no attribute '__getitem__'
This exception may have been generated by the xmlrpc method you were calling (i.e. server side).
I suggest that you add verbose=True to your instantiation of the server proxy:
xmlrpclib.ServerProxy("http://" + ServerIP + ":" + str(ServerPort),verbose=True)
This will allow you to see what you're sending and receiving.
It seems the method you're calling is expecting a dict

SSL Error occurs on one computer but not the other?

I can't figure out why all of a sudden the below code that uses Asana's API generates the below SSL error. Something must have changed on my laptop, since it runs perfectly on my other computer.
from asana import asana
class Login(object):
def __init__(self):
api = 'API'
self.asana_api = asana.AsanaAPI(api, debug=False)
self.user_id = 7359085011308L
class Test(Login):
def Test(self):
Id = 2467584555313L
print self.asana_api.list_tasks(Id,self.user_id)
Traceback (most recent call last):
File "/Users/Chris/Dropbox/AsanaPullPush.py", line 75, in <module>
if __name__ == "__main__": main()
File "/Users/Chris/Dropbox/AsanaPullPush.py", line 72, in main
print Test().Test()
File "/Users/Chris/Dropbox/AsanaPullPush.py", line 15, in Test
print self.asana_api.list_tasks(Id,self.user_id)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/asana/asana.py", line 174, in list_tasks
return self._asana(target)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/asana/asana.py", line 74, in _asana
r = requests.get(target, auth=(self.apikey, ""))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api.py", line 55, in get
return request('get', url, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/sessions.py", line 383, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/sessions.py", line 486, in send
r = adapter.send(request, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/adapters.py", line 389, in send
raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:507: error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
We recently changed our SSL key in response to the Heartbleed bug you may have heard about. http://blog.asana.com/2014/04/heartbleed/
It looks like your laptop may not have the right SSL. See https://github.com/pypa/pip/issues/829 for discussion of a similar issue.
You should be able to check SSL version on the two machines with python -c "import ssl; print ssl.OPENSSL_VERSION". If indeed the laptop is behind, you'll need to update your python's SSL.

Python soap using soaplib (server) and suds (client)

This question is related to:
Python SOAP server / client
In the case of soap with python, there are recommendation to use soaplib (http://wiki.github.com/jkp/soaplib) as soap server and suds (https://fedorahosted.org/suds/) as soap client.
My target is to create soap services in python that can be consumed by several clients (java, etc).
I tried the HelloWorld example from soaplib (http://trac.optio.webfactional.com/wiki/HelloWorld).
It works well when the client is also using soaplib.
Then, I tried to use suds as client consuming the HelloWorld services and it fail.
-Why this is happening? Does soaplib server has problems to consumed by different clients?
Here the code for the server:
from soaplib.wsgi_soap import SimpleWSGISoapApp
from soaplib.service import soapmethod
from soaplib.serializers.primitive import String, Integer, Arraycode
class HelloWorldService(SimpleWSGISoapApp):
#soapmethod(String,Integer,_returns=Array(String))
def say_hello(self,name,times):
results = []
for i in range(0,times):
results.append('Hello, %s'%name)
return results
if __name__=='__main__':
from cherrypy.wsgiserver import CherryPyWSGIServer
#from cherrypy._cpwsgiserver import CherryPyWSGIServer
# this example uses CherryPy2.2, use cherrypy.wsgiserver.CherryPyWSGIServer for CherryPy 3.0
server = CherryPyWSGIServer(('localhost',7789),HelloWorldService())
server.start()
This is the soaplib client:
from soaplib.client import make_service_client
from SoapServerTest_1 import HelloWorldService
client = make_service_client('http://localhost:7789/',HelloWorldService())
print client.say_hello("Dave",5)
Results:
>>> ['Hello, Dave', 'Hello, Dave', 'Hello, Dave', 'Hello, Dave', 'Hello, Dave']
This is the suds client:
from suds.client import Client
url = 'http://localhost:7789/HelloWordService?wsdl'
client1 = Client(url)
client1.service.say_hello("Dave",5)
Results:
>>> Unhandled exception while debugging...
Traceback (most recent call last):
File "C:\Python25\Lib\site-packages\RTEP\Sequencing\SoapClientTest_1.py", line 10, in <module>
client1.service.say_hello("Dave",5)
File "c:\python25\lib\site-packages\suds\client.py", line 537, in __call__
return client.invoke(args, kwargs)
File "c:\python25\lib\site-packages\suds\client.py", line 597, in invoke
result = self.send(msg)
File "c:\python25\lib\site-packages\suds\client.py", line 626, in send
result = self.succeeded(binding, reply.message)
File "c:\python25\lib\site-packages\suds\client.py", line 658, in succeeded
r, p = binding.get_reply(self.method, reply)
File "c:\python25\lib\site-packages\suds\bindings\binding.py", line 158, in get_reply
result = unmarshaller.process(nodes[0], resolved)
File "c:\python25\lib\site-packages\suds\umx\typed.py", line 66, in process
return Core.process(self, content)
File "c:\python25\lib\site-packages\suds\umx\core.py", line 48, in process
return self.append(content)
File "c:\python25\lib\site-packages\suds\umx\core.py", line 63, in append
self.append_children(content)
File "c:\python25\lib\site-packages\suds\umx\core.py", line 140, in append_children
cval = self.append(cont)
File "c:\python25\lib\site-packages\suds\umx\core.py", line 61, in append
self.start(content)
File "c:\python25\lib\site-packages\suds\umx\typed.py", line 77, in start
found = self.resolver.find(content.node)
File "c:\python25\lib\site-packages\suds\resolver.py", line 341, in find
frame = Frame(result, resolved=known, ancestry=ancestry)
File "c:\python25\lib\site-packages\suds\resolver.py", line 473, in __init__
resolved = type.resolve()
File "c:\python25\lib\site-packages\suds\xsd\sxbasic.py", line 63, in resolve
raise TypeNotFound(qref)
TypeNotFound: Type not found: '(string, HelloWorldService.HelloWorldService, )'
try to import primitives into your class:
class HelloWorldService(SimpleWSGISoapApp):
from soaplib.serializers.primitive import String, Integer, Arraycode
#soapmethod(String,Integer,_returns=Array(String))
this bug is fixed if you get the latest sources from the trunk, see https://github.com/soaplib/soaplib/pull/12 for details

Categories

Resources