hello,

while briefly trying to update to the spyne codebase, i am encountering an AssertionError due to spyne enforcing a 1-to-1 mapping between MethodDescriptor and the function it wraps:

  File "/path/to/spyne/interface/_base.py", line 224, in populate_interface
    assert not s.get_method_id(method) in self.method_id_map
AssertionError

... the problem is that i am currently building the MethodDescriptors dynamically, and mapping to a single _proxy function; this SOAP service is really proxying/exposing another JSON service (no JSON support in rpclib/spyne during development).

service definition (disregard custom json functions, unrelated):

-----------------------------------------------
from rpclib import MethodDescriptor
from rpclib.interface.wsdl import Wsdl11
from rpclib.service import ServiceBase
from requests import request
import json

from awesome import models


API_VERISION_JSON = 1
API_VERISION_SOAP = 1


METHODS = [('method_one', 'put', 'some method two'),
           ('method_two', 'post', 'some method two')]


def _bind(udp):
    m, verb, doc = udp
    def f(*args, **kwds):
        name = kwds['_default_function_name']
        in_message = getattr(models, m)
        out_message = getattr(models, m+'Response', None)
        if out_message is None:
            out_message = getattr(models, m+'_response')
        desc = MethodDescriptor(function=_proxy,
                                in_message=in_message,
                                out_message=out_message,
                                doc=doc,
                                is_callback=False,
                                is_async=False,
                                mtom=False,
                                in_header=None,
                                out_header=None,
                                faults=None,
                                port_type=None,
                                no_ctx=False,
                                udp=udp,
                                class_key=name)
        return desc
    f.__doc__ = doc
    f._is_rpc = True
    return f


def _proxy(ctx, req):
    res = None
    ret = None
    method, verb, doc = ctx.descriptor.udp
    host = 'http://%(SERVER_NAME)s:%(SERVER_PORT)s' % \
        ctx.transport.req_env
    endpoint = '%s/api/v%s/%s/' % (host, API_VERISION_JSON, method)
    headers = {'content-type': 'application/json'}
    try:
        res = request(verb, endpoint, headers=headers,
                      data=json.dumps(req.json(req)))
        res_json = json.loads(res.text)
    except Exception, e:
        import traceback
        if res:
            print res.text
        traceback.print_exc()
        raise e
    out_message = ctx.descriptor.out_message
    if len(out_message._type_info) == 1:
        out_message = out_message._type_info[0]
    return out_message.json(res_json)


MyService = type('MyService', (ServiceBase,),
    dict([(udp[0], _bind(udp)) for udp in METHODS]))
-----------------------------------------------

... thats's the complete -- working -- service definition, with only the method list truncated and some names changed to protect the innocent. in short: i store the method name, HTTP verb, and __doc__ in udp, then use that and the transport context to rebuild the real request.

i haven't spent much time investigating, but why is this restriction necessary? the solution ATM means needlessly wrapping _proxy for each method with a module level function, since lambdas probably wouldn't work either (albeit, i didn't try :-)

how can i solve this cleanly, or better, patch spyne to not care what callable actually implements the method (since the pattern was working rather nicely)?

thanks!

--

C Anthony


-----------------------------------------
CONFIDENTIALITY: The information contained in this communication may be 
confidential and is intended only for the use of the intended recipient(s). If 
the reader of this message is not the intended recipient(s), you are hereby 
notified that
any dissemination, distribution, or copying of this communication, or any of 
its contents, is strictly prohibited. If you have received this communication 
in error, please return it to the sender immediately and delete any copy of it 
from your computer system.
_______________________________________________
Soap mailing list
[email protected]
http://mail.python.org/mailman/listinfo/soap

Reply via email to