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)
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)
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()
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)