I'm using cherrypy server to receive requests over a pyAMF channel from a python client. I started with the mock up below and it works fine:
Server:
import cherrypy
from pyamf.remoting.gateway.wsgi import WSGIGateway
def echo(*args, **kwargs):
return (args, kwargs)
class Root(object):
def index(self):
return "running"
index.exposed = True
services = {
'myService.echo': echo,
}
gateway = WSGIGateway(services, debug=True)
cherrypy.tree.graft(gateway, "/gateway/")
cherrypy.quickstart(Root())
Client:
from pyamf.remoting.client import RemotingService
path = 'http://localhost:8080/gateway/'
gw = RemotingService(path)
service = gw.getService('myService')
print service.echo('one=1, two=3')
Result: [[u'one=1, two=3'], {}]
now if instead of:
def echo(*args, **kwargs):
return (args, kwargs)
I use:
def echo(**kwargs):
return kwargs
and send the same request, I get the following error:
TypeError: echo() takes exactly 0 arguments (1 given)
while at the same time:
>>> def f(**kwargs): return kwargs
...
>>> f(one=1, two=3)
{'two': 3, 'one': 1}
>>>
Question: Why is this happening? Please share insights
I'm using: python 2.5.2, cherrypy 3.1.2, pyamf 0.5.1
By default, WSGIGateway sets expose_request=True
which means that the WSGI environ dict is set as the first argument to any service method in that gateway.
This means that echo should be written as:
def echo(environ, *args):
return args
PyAMF provides a decorator which allows you to forcibly expose the request even if expose_request=False
, an example:
from pyamf.remoting.gateway import expose_request
from pyamf.remoting.gateway.wsgi import WSGIGateway
@expose_request
def some_service_method(request, *args):
return ['some', 'thing']
services = {
'a_service_method': some_service_method
}
gw = WSGIGateway(services, expose_request=False)
Hope that clarifies why you are getting the TypeError
in this case.
You correctly point out that you cannot supply **kwargs directly in a PyAMF client/server call but you can use default named parameters:
def update(obj, force=False):
pass
Then you can access the service:
from pyamf.remoting.client import RemotingService
path = 'http://localhost:8080/gateway/'
gw = RemotingService(path)
service = gw.getService('myService')
print service.update('foo', True)