duplicates of complex service types when serving as wsgiapp

Asked by Mads Find Madsen

I have been serving up my web services using apache (and ladon-ctl) up till now, and have had no problems.
Since I want to provide another interface for the same library of functions, implemented in pyramid, I wanted to move to make a wsgi app out of my ladonized functions and serve it together with the rest of the pyramid application using waitress.
This works, but changes the behaviour of ladon in a way that is not entirely intuitive to me:

My web services look something like this:
from ladon.ladonizer import ladonize
from ladon.types.ladontype import LadonType

class Result(LadonType):
        name = {
                'type': str
        }
        value = {
                'type': str
        }
 unit = {
  'type': str
 }

class DummyServices(object):

 @ladonize(int,rtype=Result)
 def dummyres(self,uid):
  r = Result()
  r.name= str('test')
  r.value = str(1.23)
  r.unit = str('m/s')
  return r

serving it up with:
ladon-ctl testserve dummyservices.py -p 6544
works just fine.

Now I want to include it in my pyramid application, so I modified my __init__.py file to look something like this:

from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from os.path import abspath,dirname
from pyramid.wsgi import wsgiapp
from ladon.server.wsgi import LadonWSGIApplication

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    application = LadonWSGIApplication(
        ['dummyservices'],
        [dirname(abspath(__file__))],
        catalog_name='My Ladon webservice catalog',
        catalog_desc='This is the root of my cool webservice catalog')
    ladonService = wsgiapp(application)

    config = Configurator(settings=settings)
    config.include('pyramid_chameleon')
    config.add_view(ladonService,name='dummyservices')
    config.scan()
    return config.make_wsgi_app()

and serve it up with pserve.

Suddenly there are two duplicate, identical instances of the Result type - but only in the overview page and the soap WSDLs; e.g.:
<wsdl:definitions name="DummyServices" targetNamespace="urn:DummyServices"><wsdl:types><xsd:schema targetNamespace="urn:DummyServices"><xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/"/><xsd:complexType name="Result"><xsd:sequence><xsd:element maxOccurs="1" minOccurs="1" name="name" type="xsd:string"/><xsd:element maxOccurs="1" minOccurs="1" name="unit" type="xsd:string"/><xsd:element maxOccurs="1" minOccurs="1" name="value" type="xsd:string"/></xsd:sequence></xsd:complexType><xsd:complexType name="Result"><xsd:sequence><xsd:element maxOccurs="1" minOccurs="1" name="name" type="xsd:string"/><xsd:element maxOccurs="1" minOccurs="1" name="unit" type="xsd:string"/><xsd:element maxOccurs="1" minOccurs="1" name="value" type="xsd:string"/></xsd:sequence></xsd:complexType></xsd:schema>
...
This doesn't play well with the c# application that I want to act as the client, unfortunately (suds just ignores the duplicate definition).

Interestingly in the JSON-WSP description, there is only one reference to the Result type.

{"version": "1.1", "url": "http://localhost:6543/dummyservices/jsonwsp", "servicename": "DummyServices", "type": "jsonwsp/description", "types": {"Result": {"value": {"type": "string"}, "name": {"type": "string"}, "unit": {"type": "string"}}}, "methods": {"dummyres": {"ret_info": {"doc_lines": [], "type": "Result"}, "doc_lines": [], "params": {"uid": {"def_order": 1, "doc_lines": [], "type": "number", "optional": false}}}}}

 I am still fairly new to python, and I am sure I am doing something wrong in the way I am creating the wsgi app, but I am at a loss as to what. Any help would be very much appreciated!

Question information

Language:
English Edit question
Status:
Expired
For:
ladon Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Mads Find Madsen (o-mads) said :
#1

Ok, a bit closer to solving the issue:
I put in some print statements to examine type_order in the soap11.py file in ladon to figure out what is happening when the wsdl is being generated.

So the types look like this:

{'attributes': [('name', <type 'str'>, {'type': <type 'str'>}), ('unit', <type 'str'>, {'type': <type 'str'>}), ('value', <type 'str'>, {'type': <type 'str'>})], 'parse_order': 0, 'name': 'Result', 'module': 'mo2server.dummyservices'}

 [<class 'mo2server.dummyservices.Result'>]

{'attributes': [('name', <type 'str'>, {'type': <type 'str'>}), ('unit', <type 'str'>, {'type': <type 'str'>}), ('value', <type 'str'>, {'type': <type 'str'>})], 'parse_order': 1, 'name': 'Result', 'module': 'dummyservices'}

[<class 'dummyservices.Result'>]

Exact duplicates of everything, identical except for the 'module'.
it looks like there are two instances of Result, because it has been imported twice. My (novice python) suggestion is that it happens once when the package is loaded initially, and once when and once when calling LadonWSGIApplication from inside the package. Hence the different relative names.

Still not sure what I should do to avoid loading the module twice - is there some way to keep python from loading a specific file in a package, so it will only be loaded when run by LadonWSGIApplication? (Actually I was naively thinking that it would be some sort of dark incantation keeping python from loading the same .py file twice... but goes to show how little I understand!).
Would it be better to try to modify the code so it simply checks not to write two types with the same name in the WSDL?

Revision history for this message
Mads Find Madsen (o-mads) said :
#2

Ok... problem solved.
Changed the LadonWSGIApplication call from

    application = LadonWSGIApplication(
        ['dummyservices'],
        [dirname(abspath(__file__))],
        catalog_name='My Ladon webservice catalog',
        catalog_desc='This is the root of my cool webservice catalog')

to

    application = LadonWSGIApplication(
        ['mo2server.dummyservices'],
        ['/hardcoded/path/one/step/up'],
        catalog_name='My Ladon webservice catalog',
        catalog_desc='This is the root of my cool webservice catalog')

Don't know if this constitutes a bug -- at least now my personal odyssey has been documented for the ages ;-)
To my defense jsonwsp seems to figure out that there should only be one element of each type, so that indicates that there is SOME uncertainty as to what constitutes the correct behaviour.

Revision history for this message
Launchpad Janitor (janitor) said :
#3

This question was expired because it remained in the 'Open' state without activity for the last 15 days.