Python and Secpay (paypoint) xml-rpc call - python

I have the next code somewhere in Pyramid application
import xmlrpclib
....
#view_config(route_name='api-paypoint', renderer='string')
def api_paypoint(request):
call_data = ["mid", "password", "name"]
api_server = xmlrpclib.ServerProxy('https://www.secpay.com/secxmlrpc/make_call')
response = api_server.SECVPN.validateCardFull(call_data)
print response
return {}
What I'm trying is to call Secpay API (here's JAVA's example http://www.paypoint.net/support/gateway/soap-xmlrpc/xmlrpc-java/ )
I'm getting the next error:
Exception Value: <Fault 0: 'java.lang.NoSuchMethodException: com.secpay.secvpn.SECVPN.validateCardFull(java.util.Vector)'>
Any idea what is wrong here?

I found a problem. I was trying to pass to api_server.SECVPN.validateCardFull() which is wrong. This should be changed to
api_server.SECVPN.validateCardFull('mid', 'password', 'name')

You're calling with the wrong number of arguments, and the java serverside can't find a method matching that signature. If you call with 14 strings the exception changes (something about the serverside failing to encode a null).
proxy.SECVPN.validateCardFull("","","","","","","","","","","","","","")

Related

Executing arbitrary Python code (user submitted) inside an Azure Function

I'm trying to run a sample function that allows a user to execute arbitrary code
Note: I"m assuming this is ok because Azure Functions will by default provide a sandbox. (And the end user will need to write code with dataframes, objects etc. I've looked into pypy.org but don't think I need it as I am not worried about attacks that use it as a spambot or something):
import os
import json
import ast
print('==============in python function========================')
postreqdata = json.loads(open(os.environ['req']).read())
response = open(os.environ['res'], 'w')
response.write("hello world from "+postreqdata['name'])
response.close()
logic = (postreqdata['logic'])
eval(logic)
but I keep getting the following output/error:
2018-01-17T09:09:08.949 ==============in python function========================
2018-01-17T09:09:09.207 Exception while executing function: Functions.ccfinopsRunModel. Microsoft.Azure.WebJobs.Script: Traceback (most recent call last):
File "D:\home\site\wwwroot\ccfinopsRunModel\run.py", line 12, in <module>
eval(logic)
File "<string>", line 1
print('code sent from client')
^
SyntaxError: invalid syntax
.
My POST request body contains the following:
{
"name": "Python Function App",
"logic": "print('code sent from client')"
}
So the "logic" variable is being read in, and eval() is trying to interpret the string as python code, but it is causing a Syntax Error where there appears to be none.
What am I doing wrong? If there was a restriction on 'eval' I'm assuming it would say that instead of "Syntax Error"
Thanks for any help you can provide!
Use exec to run your code. eval is used evaluating expressions.
logic = (postreqdata['logic'])
exec(logic)
Also can try sending your code as multi-line string as below,
>>> s = '''
for i in range(3):
print("i")
'''
>>> exec(s)
0
1
2

RESTful web service example in cherrypy

I am trying to write a RESTful web service in python. But while trying out the tutorials given on Cherrypy Website I ended up with an error like
Traceback (most recent call last):
File "rest.py", line 35, in <module>
cherrypy.quickstart(StringGeneratorWebService(), '/', conf)
TypeError: expose_() takes exactly 1 argument (0 given)
Where rest.py is my file which contains the exact same code on the site and under subtitle "Give us a REST".
I am clear that, obviously from error message, I am missing a parameter that should be passed in. But I am not clear where exactly I should amend that code to make it work.
I tried out fixing something on line number 35, but nothing helped me, and I am stuck! Please help me to clear this or please give some code snippet to make a REST service in cherrypy. Thank you!
The CherryPy version that you're using (3.2.2) doesn't support the cherrypy.expose decorator on classes, that functionality was added in version 6.
You can use the old syntax of setting the exposed attribute to True(it is also compatible with the newer versions).
The class would end up like:
class StringGeneratorWebService(object):
exposed = True
#cherrypy.tools.accept(media='text/plain')
def GET(self):
return cherrypy.session['mystring']
def POST(self, length=8):
some_string = ''.join(random.sample(string.hexdigits, int(length)))
cherrypy.session['mystring'] = some_string
return some_string
def PUT(self, another_string):
cherrypy.session['mystring'] = another_string
def DELETE(self):
cherrypy.session.pop('mystring', None)

Python suds error creating object

Trying to work with the echosign SOAP API.
The wsdl is here: https://secure.echosign.com/services/EchoSignDocumentService14?wsdl
When I try to create certain objects, it appears to not be able to find the type, even after listing it in print client
import suds
url = "https://secure.echosign.com/services/EchoSignDocumentService14?wsdl"
client = suds.client.Client(url)
print client
Service ( EchoSignDocumentService14 ) tns="http://api.echosign"
Prefixes (10)
ns0 = "http://api.echosign"
ns1 = "http://dto.api.echosign"
ns2 = "http://dto10.api.echosign"
ns3 = "http://dto11.api.echosign"
ns4 = "http://dto12.api.echosign"
ns5 = "http://dto13.api.echosign"
ns15 = "http://dto14.api.echosign"
ns16 = "http://dto7.api.echosign"
ns17 = "http://dto8.api.echosign"
ns18 = "http://dto9.api.echosign"
Ports (1):
(EchoSignDocumentService14HttpPort)
Methods (45):
...
Types (146):
ns1:CallbackInfo
ns17:WidgetCreationInfo
Trimmed for brevity, but showing the namespaces and the 2 types I'm concerned with right now.
Trying to run WCI = client.factory.create("ns17:WidgetCreationInfo") generates this error:
client.factory.create("ns17:WidgetCreationInfo")
Traceback (most recent call last):
File "", line 1, in
File "build/bdist.macosx-10.7-intel/egg/suds/client.py", line 244, in create
suds.BuildError:
An error occured while building a instance of (ns17:WidgetCreationInfo). As a result
the object you requested could not be constructed. It is recommended
that you construct the type manually using a Suds object.
Please open a ticket with a description of this error.
Reason: Type not found: '(CallbackInfo, http://dto.api.echosign, )'
So it doesn't appear to be able to find the CallbackInfo type. Maybe its because its missing the ns there?
Again, figured it out 15 min after posting here.
suds has an option to cross-pollinate all the namespaces so they all import each others schemas. autoblend can be set in the constructor or using the set_options method.
suds.client.Client(url, autoblend=True)
Take a look in the WSDL, it seems lots of definitions in http://*.api.echosign that suds cannot fetch.
Either update your /etc/hosts to make these not well-formed domains can be reached, or save the wsdl locally, modify it, then use Client('file://...', ...) to create your suds client.

How to raise Suds.WebFault from python code?

I am trying to raise a Suds.WebFault from python code. The __init__ method\constructor takes three arguments __init__(self, fault, document). The fault has fault.faultcode and fault.detail members\attributes\properties. I could not find out what class fault belongs to no matte what I tried. How do I raise Suds.WebFault type exception from python code?
Thanks in advance.
Not sure what exactly you are asking but you can throw a web fault using:
import suds
try:
client.service.Method(parameter)
except suds.WebFault, e:
print e
WebFault is defined in suds.__init__.py as:
class WebFault(Exception):
def __init__(self, fault, document):
if hasattr(fault, 'faultstring'):
Exception.__init__(self, u"Server raised fault: '%s'" %
fault.faultstring)
self.fault = fault
self.document = document
Therefore to raise a WebFault with a meaningful message you will need to pass an object as the first param with the message. Document can simply be None unless required.
import suds
class Fault(object):
faultstring = 'my error message'
raise suds.WebFault(Fault(), document=None)
WebFault is only meant to be actually raised when a <Fault> element is returned by the web server. So it's probably a bad idea to raise that yourself.
If you still would like to, I would start looking at the code where the framework raises it: https://github.com/unomena/suds/blob/4e90361e13fb3d74915eafc1f3a481400c798e0e/suds/bindings/binding.py#L182 - and work backwards from there.

String error in my python api wrapper class

I'm writing an API wrapper to a couple of different web services.
I have a method that has an article url, and I want to extract text from it using alchemyapi.
def extractText(self):
#All Extract Text Methods ---------------------------------------------------------//
#Extract page text from a web URL (ignoring navigation links, ads, etc.).
if self.alchemyapi == True:
self.full_text = self.alchemyObj.URLGetText(self.article_link)
which goes to the following code in the python wrapper
def URLGetText(self, url, textParams=None):
self.CheckURL(url)
if textParams == None:
textParams = AlchemyAPI_TextParams()
textParams.setUrl(url)
return self.GetRequest("URLGetText", "url", textParams)
def GetRequest(self, apiCall, apiPrefix, paramObject):
endpoint = 'http://' + self._hostPrefix + '.alchemyapi.com/calls/' + apiPrefix + '/' + apiCall
endpoint += '?apikey=' + self._apiKey + paramObject.getParameterString()
handle = urllib.urlopen(endpoint)
result = handle.read()
handle.close()
xpathQuery = '/results/status'
nodes = etree.fromstring(result).xpath(xpathQuery)
if nodes[0].text != "OK":
raise 'Error making API call.'
return result
However I get this error ---
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "text_proc.py", line 97, in __init__
self.alchemyObj.loadAPIKey("api_key.txt");
File "text_proc.py", line 115, in extractText
if self.alchemyapi == True:
File "/Users/Diesel/Desktop/AlchemyAPI.py", line 502, in URLGetText
return self.GetRequest("URLGetText", "url", textParams)
File "/Users/Diesel/Desktop/AlchemyAPI.py", line 618, in GetRequest
raise 'Error making API call.'
I know I'm somehow passing the url string to the api wrapper in a faulty format, but I can't figure out how to fix it.
The information provided is not actually very helpful to diagnose or solve the problem. Have you considered taking a look at the response from the server? You might inspect a complete traffic log using Fiddler.
Additionally, the SDK provided by Alchemy doesn't seem to be of - cough, cough - the greatest quality. Since it really consists only of around 600 lines of source code, I'd consider writing a shorter, more robust / pythonic / whatever SDK.
I might also add that right now, even the on-site demo at the Alchemy web site is failing, so maybe your problem is related to that. I really suggest taking a look at the traffic.
You should raise Exception or a subclass thereof, instead of a string.
You're getting the error because your function GetRequest() raising a string as an exception:
if nodes[0].text != "OK":
raise 'Error making API call.'
If that's not what you want, you have two options:
You can have the function return the string or None, or
You can pass the error message to a real subclass of Exception (as suggested by knutin)
In either case, if you are assigning that return value to a variable, you can handle it accordingly. Here is an example:
Option 1
Let's assume you decide to have GetRequest() return None:
def URLGetText(self, url, textParams=None):
self.CheckURL(url)
if textParams == None:
textParams = AlchemyAPI_TextParams()
textParams.setUrl(url)
# Capture the value of GetRequest() before returning it
retval = self.GetRequest("URLGetText", "url", textParams)
if retval is None:
print 'Error making API call.' # print the error but still return
return retval
def GetRequest(self, apiCall, apiPrefix, paramObject):
# ...
if nodes[0].text != "OK":
return None
return result
This option is a little ambiguous. How do you know that it was really an error, or the return value truly was None?
Option 2
This is probably the better way to do it:
First create an subclass of Exception:
class GetRequestError(Exception):
"""Error returned from GetRequest()"""
pass
Then raise it in GetRequest()`:
def URLGetText(self, url, textParams=None):
self.CheckURL(url)
if textParams == None:
textParams = AlchemyAPI_TextParams()
textParams.setUrl(url)
# Attempt to get a legit return value & handle errors
try:
retval = self.GetRequest(apiCall, apiPrefix, paramObject)
except GetRequestError as err:
print err # prints 'Error making API call.'
# handle the error here
retval = None
return retval
def GetRequest(self, apiCall, apiPrefix, paramObject):
# ...
if nodes[0].text != "OK":
raise GetRequestError('Error making API call.')
return result
This way you're raising a legitimate error when GetRequest() doesn't return the desired result, and then you can handle the error using a try..except block and optionally print the error, stop the program there, or keep going (which is what I think you want to do based on your question).
This is Shaun from AlchemyAPI. We just posted a new version of the python SDK that raises exceptions properly. You can get it here http://www.alchemyapi.com/tools/.
If you have any other feedback about the SDK, please message me. Thanks for using our NLP service.

Categories