예제 #1
0
    def _load_schema(self, location, xml=None):
        """
        location -- location of schema, also used as a key
        xml -- optional string representation of schema
        """
        cachedir = self._cachedir
        # wsdl2py: deal with XML Schema
        if not os.path.isdir(cachedir): os.mkdir(cachedir)
    
        file = os.path.join(cachedir, '.cache')
        section = 'TYPES'
        cp = ConfigParser()
        try:
            cp.readfp(open(file, 'r'))
        except IOError:
            del cp;  cp = None
            
        option = location.replace(':', '-') # colons seem to screw up option
        if (cp is not None and cp.has_section(section) and 
            cp.has_option(section, option)):
            types = cp.get(section, option)
        else:
            # dont do anything to anames
            if not self._pyclass:
                containers.ContainerBase.func_aname = lambda instnc,n: str(n)
                
            from ZSI.wstools import XMLSchema
            reader = XMLSchema.SchemaReader(base_url=location)
            if xml is not None and isinstance(xml, basestring):
                schema = reader.loadFromString(xml)
            elif xml is not None:
                raise RuntimeError, 'Unsupported: XML must be string'
            elif not os.path.isfile(location):
                schema = reader.loadFromURL(location)
            else:
                schema = reader.reader.loadFromFile(location)
                
            # TODO: change this to keyword list
            class options:
                output_dir = cachedir
                schema = True
                simple_naming = False
                address = False
                lazy = self._lazy
                complexType = self._pyclass

            schema.location = location
            files = commands._wsdl2py(options, schema)
            if cp is None: cp = ConfigParser()
            if not cp.has_section(section): cp.add_section(section)
            types = filter(lambda f: f.endswith('_types.py'), files)[0]
            cp.set(section, option, types)
            cp.write(open(file, 'w'))
            
        if os.path.abspath(cachedir) not in sys.path:
            sys.path.append(os.path.abspath(cachedir))
            
        mod = os.path.split(types)[-1].rstrip('.py')
        return __import__(mod)
예제 #2
0
def wsdl2py(args=None):
    """Utility for automatically generating client/service interface code from
    a wsdl definition, and a set of classes representing element declarations 
    and type definitions.  By default invoking this script produces three files, 
    each named after the wsdl definition name, in the current working directory.
    
    Generated Modules Suffix:
        _client.py -- client locator, rpc proxy port, messages
        _types.py  -- typecodes representing 
        _server.py -- server-side bindings
        
    Parameters:
        args -- optional can provide arguments, rather than parsing 
            command-line.
            
    return:
        Default behavior is to return None, if args are provided then
        return names of the generated files.
                                                    
    """
    op = optparse.OptionParser(usage="USAGE: %wsdl2py [options] WSDL",
                 description=wsdl2py.__doc__)
    
    # Basic options
    op.add_option("-x", "--schema",
                  action="store_true", dest="schema", default=False,
                  help="process just the schema from an xsd file [no services]")

    op.add_option("-d", "--debug",
                  action="callback", callback=SetDebugCallback,
                  help="debug output")
                  
    # WS Options
    op.add_option("-a", "--address",
                  action="store_true", dest="address", default=False,
                  help="ws-addressing support, must include WS-Addressing schema.")
                  
    # pyclass Metaclass 
    op.add_option("-b", "--complexType",
                  action="callback", callback=SetPyclassMetaclass, 
                  callback_kwargs={'module':'ZSI.generate.pyclass', 
                      'metaclass':'pyclass_type'},
                  help="add convenience functions for complexTypes, including Getters, Setters, factory methods, and properties (via metaclass). *** DONT USE WITH --simple-naming ***")
    
    # Lazy Evaluation of Typecodes (done at serialization/parsing when needed).
    op.add_option("-l", "--lazy",
                  action="callback", callback=SetUpLazyEvaluation, 
                  callback_kwargs={},
                  help="EXPERIMENTAL: recursion error solution, lazy evalution of typecodes")
    
    # Use Twisted
    op.add_option("-w", "--twisted",
                  action="store_true", dest='twisted', default=False,
                  help="generate a twisted.web client/server, dependencies python>=2.4, Twisted>=2.0.0, TwistedWeb>=0.5.0")
    
    op.add_option("-o", "--output-dir",
                  action="store", dest="output_dir", default=".", type="string",
                  help="save files in directory")
    
    op.add_option("-s", "--simple-naming",
                  action="store_true", dest="simple_naming", default=False,
                  help="map element names directly to python attributes")
    
    op.add_option("-p", "--pydoc",
                  action="store_true", dest="pydoc", default=False,
                  help="top-level directory for pydoc documentation.")
    
    
    is_cmdline = args is None
    if is_cmdline:
        (options, args) = op.parse_args()
    else:
        (options, args) = op.parse_args(args)

    if len(args) != 1:
        print>>sys.stderr, 'Expecting a file/url as argument (WSDL).'
        sys.exit(os.EX_USAGE)
        
    location = args[0]
    if options.schema is True:
        reader = XMLSchema.SchemaReader(base_url=location)
    else:
        reader = WSDLTools.WSDLReader()

    load = reader.loadFromFile
    if not isfile(location):
        load = reader.loadFromURL

    try:
        wsdl = load(location)
    except Exception, e:
        print >> sys.stderr, "Error loading %s: \n\t%s" % (location, e)
        traceback.print_exc(sys.stderr)
        # exit code UNIX specific, Windows?
        if hasattr(os, 'EX_NOINPUT'): sys.exit(os.EX_NOINPUT)
        sys.exit("error loading %s" %location)
예제 #3
0
def wsdl2py(args=None):
    """
    A utility for automatically generating client interface code from a wsdl
    definition, and a set of classes representing element declarations and
    type definitions.  This will produce two files in the current working 
    directory named after the wsdl definition name.

    eg. <definition name='SampleService'>
        SampleService.py
        SampleService_types.py
    """
    
    op = optparse.OptionParser(usage="usage: %prog [options]",
                 description=wsdl2py.__doc__)
    
    # Basic options
    op.add_option("-f", "--file",
                  action="store", dest="file", default=None, type="string",
                  help="FILE to load wsdl from")
    op.add_option("-u", "--url",
                  action="store", dest="url", default=None, type="string",
                  help="URL to load wsdl from")
    op.add_option("-x", "--schema",
                  action="store_true", dest="schema", default=False,
                  help="process just the schema from an xsd file [no services]")
    op.add_option("-d", "--debug",
                  action="callback", callback=SetDebugCallback,
                  help="debug output")
                  
    # WS Options
    op.add_option("-a", "--address",
                  action="store_true", dest="address", default=False,
                  help="ws-addressing support, must include WS-Addressing schema.")
                  
    # pyclass Metaclass 
    op.add_option("-b", "--complexType",
                  action="callback", callback=SetPyclassMetaclass, 
                  callback_kwargs={'module':'ZSI.generate.pyclass', 
                      'metaclass':'pyclass_type'},
                  help="add convenience functions for complexTypes, including Getters, Setters, factory methods, and properties (via metaclass). *** DONT USE WITH --simple-naming ***")
    
    # Lazy Evaluation of Typecodes (done at serialization/parsing when needed).
    op.add_option("-l", "--lazy",
                  action="callback", callback=SetUpLazyEvaluation, 
                  callback_kwargs={},
                  help="EXPERIMENTAL: recursion error solution, lazy evalution of typecodes")
    
    # Use Twisted
    op.add_option("-w", "--twisted",
                  action="callback", callback=SetUpTwistedClient, 
                  callback_kwargs={'module':'ZSI.generate.pyclass', 
                      'metaclass':'pyclass_type'},
                  help="generate a twisted.web client, dependencies python>=2.4, Twisted>=2.0.0, TwistedWeb>=0.5.0")
    
    # Extended generation options
    op.add_option("-e", "--extended",
                  action="store_true", dest="extended", default=False,
                  help="Do Extended code generation.")    
    op.add_option("-z", "--aname",
                  action="store", dest="aname", default=None, type="string",
                  help="pass in a function for attribute name creation")
    op.add_option("-t", "--types",
                  action="store", dest="types", default=None, type="string",
                  help="file to load types from")
    op.add_option("-o", "--output-dir",
                  action="store", dest="output_dir", default=".", type="string",
                  help="Write generated files to OUTPUT_DIR")
    op.add_option("-s", "--simple-naming",
                  action="store_true", dest="simple_naming", default=False,
                  help="Simplify generated naming.")
    op.add_option("-c", "--clientClassSuffix",
                  action="store", dest="clientClassSuffix", default=None, type="string",
                  help="Suffix to use for service client class (default \"SOAP\")")
    op.add_option("-m", "--pyclassMapModule",
                  action="store", dest="pyclassMapModule", default=None, type="string",
                  help="Python file that maps external python classes to a schema type.  The classes are used as the \"pyclass\" for that type.  The module should contain a dict() called mapping in the format: mapping = {schemaTypeName:(moduleName.py,className) }")
                  
    if args is None:
        (options, args) = op.parse_args()
    else:
        (options, args) = op.parse_args(args)

    if not xor(options.file is None, options.url is None):
        print('Must specify either --file or --url option')
        sys.exit(os.EX_USAGE)
    
    location = options.file            
    if options.url is not None:
        location = options.url
    
    if options.schema is True:
        reader = XMLSchema.SchemaReader(base_url=location)
    else:
        reader = WSDLTools.WSDLReader()

    load = reader.loadFromFile
    if options.url is not None:
        load = reader.loadFromURL

    wsdl = None
    try:
        wsdl = load(location)
    except Exception as e:
        print("Error loading %s: \n\t%s" % (location, e))
        # exit code UNIX specific, Windows?
        sys.exit(os.EX_NOINPUT)

    if options.simple_naming:
        # Use a different client suffix
        WriteServiceModule.client_module_suffix = "_client"
        # Write messages definitions to a separate file.
        ServiceDescription.separate_messages = True
        # Use more simple type and element class names
        containers.SetTypeNameFunc( lambda n: '%s_' %(NC_to_CN(n)) )
        containers.SetElementNameFunc( lambda n: '%s' %(NC_to_CN(n)) )
        # Don't add "_" to the attribute name (remove when --aname works well)
        containers.ContainerBase.func_aname = lambda instnc,n: TextProtect(str(n))
        # write out the modules with their names rather than their number.
        utility.namespace_name = lambda cls, ns: utility.Namespace2ModuleName(ns)

    if options.clientClassSuffix:
        from ZSI.generate.containers import ServiceContainerBase
        ServiceContainerBase.clientClassSuffix = options.clientClassSuffix

    if options.schema is True:
        wsdl = formatSchemaObject(location, wsdl)

    if options.aname is not None:
        args = options.aname.rsplit('.',1)
        assert len(args) == 2, 'expecting module.function'
        # The following exec causes a syntax error.
        #exec('from %s import %s as FUNC' %(args[0],args[1]))
        assert isinstance(FUNC, collections.Callable),\
            '%s must be a callable method with one string parameter' %options.aname
        from ZSI.generate.containers import TypecodeContainerBase
        TypecodeContainerBase.func_aname = staticmethod(FUNC)

    if options.pyclassMapModule != None:
        mod = __import__(options.pyclassMapModule)
        components = options.pyclassMapModule.split('.')
        for comp in components[1:]:
            mod = getattr(mod, comp)
        extPyClasses = mod.mapping
    else:
        extPyClasses = None
        
    wsm = WriteServiceModule(wsdl, addressing=options.address, do_extended=options.extended, extPyClasses=extPyClasses)
    if options.types != None:
        wsm.setTypesModuleName(options.types)
    if options.schema is False:
         fd = open(os.path.join(options.output_dir, '%s.py' %wsm.getClientModuleName()), 'w+')
         # simple naming writes the messages to a separate file
         if not options.simple_naming:
             wsm.writeClient(fd)
         else: # provide a separate file to store messages to.
             msg_fd = open(os.path.join(options.output_dir, '%s.py' %wsm.getMessagesModuleName()), 'w+')
             wsm.writeClient(fd, msg_fd=msg_fd)
             msg_fd.close()
         fd.close()

    fd = open( os.path.join(options.output_dir, '%s.py' %wsm.getTypesModuleName()), 'w+')
    wsm.writeTypes(fd)
    fd.close()
예제 #4
0
def wsdl2py(args=None):
    """
    A utility for automatically generating client interface code from a wsdl
    definition, and a set of classes representing element declarations and
    type definitions.  This will produce two files in the current working 
    directory named after the wsdl definition name.

    eg. <definition name='SampleService'>
        SampleService.py
        SampleService_types.py
    """

    op = optparse.OptionParser(usage="usage: %prog [options]",
                               description=wsdl2py.__doc__)

    # Basic options
    op.add_option("-f",
                  "--file",
                  action="store",
                  dest="file",
                  default=None,
                  type="string",
                  help="FILE to load wsdl from")
    op.add_option("-u",
                  "--url",
                  action="store",
                  dest="url",
                  default=None,
                  type="string",
                  help="URL to load wsdl from")
    op.add_option(
        "-x",
        "--schema",
        action="store_true",
        dest="schema",
        default=False,
        help="process just the schema from an xsd file [no services]")
    op.add_option("-d",
                  "--debug",
                  action="callback",
                  callback=SetDebugCallback,
                  help="debug output")

    # WS Options
    op.add_option(
        "-a",
        "--address",
        action="store_true",
        dest="address",
        default=False,
        help="ws-addressing support, must include WS-Addressing schema.")

    # pyclass Metaclass
    op.add_option(
        "-b",
        "--complexType",
        action="callback",
        callback=SetPyclassMetaclass,
        callback_kwargs={
            'module': 'ZSI.generate.pyclass',
            'metaclass': 'pyclass_type'
        },
        help=
        "add convenience functions for complexTypes, including Getters, Setters, factory methods, and properties (via metaclass). *** DONT USE WITH --simple-naming ***"
    )

    # Lazy Evaluation of Typecodes (done at serialization/parsing when needed).
    op.add_option(
        "-l",
        "--lazy",
        action="callback",
        callback=SetUpLazyEvaluation,
        callback_kwargs={},
        help=
        "EXPERIMENTAL: recursion error solution, lazy evalution of typecodes")

    # Use Twisted
    op.add_option(
        "-w",
        "--twisted",
        action="callback",
        callback=SetUpTwistedClient,
        callback_kwargs={
            'module': 'ZSI.generate.pyclass',
            'metaclass': 'pyclass_type'
        },
        help=
        "generate a twisted.web client, dependencies python>=2.4, Twisted>=2.0.0, TwistedWeb>=0.5.0"
    )

    # Extended generation options
    op.add_option("-e",
                  "--extended",
                  action="store_true",
                  dest="extended",
                  default=False,
                  help="Do Extended code generation.")
    op.add_option("-z",
                  "--aname",
                  action="store",
                  dest="aname",
                  default=None,
                  type="string",
                  help="pass in a function for attribute name creation")
    op.add_option("-t",
                  "--types",
                  action="store",
                  dest="types",
                  default=None,
                  type="string",
                  help="file to load types from")
    op.add_option("-o",
                  "--output-dir",
                  action="store",
                  dest="output_dir",
                  default=".",
                  type="string",
                  help="Write generated files to OUTPUT_DIR")
    op.add_option("-s",
                  "--simple-naming",
                  action="store_true",
                  dest="simple_naming",
                  default=False,
                  help="Simplify generated naming.")
    op.add_option(
        "-c",
        "--clientClassSuffix",
        action="store",
        dest="clientClassSuffix",
        default=None,
        type="string",
        help="Suffix to use for service client class (default \"SOAP\")")
    op.add_option(
        "-m",
        "--pyclassMapModule",
        action="store",
        dest="pyclassMapModule",
        default=None,
        type="string",
        help=
        "Python file that maps external python classes to a schema type.  The classes are used as the \"pyclass\" for that type.  The module should contain a dict() called mapping in the format: mapping = {schemaTypeName:(moduleName.py,className) }"
    )

    if args is None:
        (options, args) = op.parse_args()
    else:
        (options, args) = op.parse_args(args)

    if not xor(options.file is None, options.url is None):
        print 'Must specify either --file or --url option'
        sys.exit(os.EX_USAGE)

    location = options.file
    if options.url is not None:
        location = options.url

    if options.schema is True:
        reader = XMLSchema.SchemaReader(base_url=location)
    else:
        reader = WSDLTools.WSDLReader()

    load = reader.loadFromFile
    if options.url is not None:
        load = reader.loadFromURL

    wsdl = None
    try:
        wsdl = load(location)
    except Exception, e:
        print "Error loading %s: \n\t%s" % (location, e)
        # exit code UNIX specific, Windows?
        sys.exit(os.EX_NOINPUT)