संदर्भ: (डौग Hellmann के लिए धन्यवाद) building soap service
Zolera साबुन infrastucture (ZSI), pywebsvcs परियोजना का एक हिस्सा है। यह SOAP के साथ काम करने के लिए पूर्ण सर्वर और क्लाइंट पुस्तकालय प्रदान करता है। इसका उपयोग करने के लिए, एक डेवलपर WSDL फ़ाइल (हाथ से या WSDL संपादक का उपयोग करके) लिखता है, और फिर सर्वर के लिए क्लाइंट और स्टब्स के लिए पाइथन स्रोत उत्पन्न करता है। WSDL फ़ाइल में परिभाषित डेटा संरचनाओं को पायथन कक्षाओं में परिवर्तित किया जाता है जिनका उपयोग क्लाइंट और सर्वर कोड दोनों में किया जा सकता है।
हमने एक साधारण गूंज सेवा लागू की जो क्लाइंट से इनपुट के रूप में जो भी हो, आउटपुट के रूप में लौटाता है। लिस्टिंग 1 में इस सेवा के जेएसआई संस्करण के लिए हस्तनिर्मित डब्लूएसडीएल इनपुट शामिल हैं।
लिस्टिंग 1
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:ZSI"
targetNamespace="urn:ZSI" >
<types>
<xsd:schema elementFormDefault="qualified"
targetNamespace="urn:ZSI">
<xsd:element name="Echo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="EchoRequest">
<part name="parameters" element="tns:Echo" />
</message>
<message name="EchoResponse">
<part name="parameters" element="tns:Echo"/>
</message>
<portType name="EchoServer">
<operation name="Echo">
<input message="tns:EchoRequest"/>
<output message="tns:EchoResponse"/>
</operation>
</portType>
<binding name="EchoServer" type="tns:EchoServer">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="Echo">
<soap:operation soapAction="Echo"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="EchoServer">
<port name="EchoServer" binding="tns:EchoServer">
<soap:address location="http://localhost:7000"/>
</port>
</service>
</definitions>
डबल्यूएसडीएल से क्लाइंट और सर्वर कोड उत्पन्न करने के लिए, wsdl2py कार्यक्रम (ZSI के साथ शामिल) में खाते हैं। जटिल प्रकारों के लिए समर्थन जोड़ने के लिए, -b विकल्प जोड़ें, लेकिन इस सरल उदाहरण के लिए इसकी आवश्यकता नहीं है। wsdl2py, जवाब में, तीन फ़ाइलों का उत्पादन करेगा:
लिस्टिंग 2
EchoServer_client.py कोड SimpleEcho वेब सेवा के लिए एक ग्राहक बनाने की जरूरत है।
##################################################
# file: EchoServer_client.py
#
# client stubs generated by
# "ZSI.generate.wsdl2python.WriteServiceModule"
#
##################################################
from EchoServer_types import *
import urlparse, types
from ZSI.TCcompound import ComplexType, Struct
from ZSI import client
from ZSI.schema import GED, GTD
import ZSI
from ZSI.generate.pyclass import pyclass_type
# Locator
class EchoServerLocator:
EchoServer_address = "http://localhost:7000"
def getEchoServerAddress(self):
return EchoServerLocator.EchoServer_address
def getEchoServer(self, url=None, **kw):
return EchoServerSOAP(
url or EchoServerLocator.EchoServer_address,
**kw)
# Methods
class EchoServerSOAP:
def __init__(self, url, **kw):
kw.setdefault("readerclass", None)
kw.setdefault("writerclass", None)
# no resource properties
self.binding = client.Binding(url=url, **kw)
# no ws-addressing
# op: Echo
def Echo(self, request, **kw):
if isinstance(request, EchoRequest) is False:
raise TypeError, "%s incorrect request type" % \
(request.__class__)
# no input wsaction
self.binding.Send(None, None, request, soapaction="Echo", **kw)
# no output wsaction
response = self.binding.Receive(EchoResponse.typecode)
return response
EchoRequest = GED("urn:ZSI", "Echo").pyclass
EchoResponse = GED("urn:ZSI", "Echo").pyclass
लिस्टिंग 3
EchoServer_server.py SimpleEcho वेब सेवा सर्वर बनाने की जरूरत कोड होता है।
##################################################
# file: EchoServer_server.py
#
# skeleton generated by
# "ZSI.generate.wsdl2dispatch.ServiceModuleWriter"
#
##################################################
from ZSI.schema import GED, GTD
from ZSI.TCcompound import ComplexType, Struct
from EchoServer_types import *
from ZSI.ServiceContainer import ServiceSOAPBinding
# Messages
EchoRequest = GED("urn:ZSI", "Echo").pyclass
EchoResponse = GED("urn:ZSI", "Echo").pyclass
# Service Skeletons
class EchoServer(ServiceSOAPBinding):
soapAction = {}
root = {}
def __init__(self, post='', **kw):
ServiceSOAPBinding.__init__(self, post)
def soap_Echo(self, ps, **kw):
request = ps.Parse(EchoRequest.typecode)
return request,EchoResponse()
soapAction['Echo'] = 'soap_Echo'
root[(EchoRequest.typecode.nspname,EchoRequest.typecode.pname)] = \
'soap_Echo'
लिस्टिंग 4
EchoServer_types.py दोनों क्लाइंट और सर्वर कोड द्वारा इस्तेमाल किया परिभाषाएँ टाइप है।
##################################################
# file: EchoServer_types.py
#
# schema types generated by
# "ZSI.generate.wsdl2python.WriteServiceModule"
#
##################################################
import ZSI
import ZSI.TCcompound
from ZSI.schema import (LocalElementDeclaration, ElementDeclaration,
TypeDefinition, GTD, GED)
from ZSI.generate.pyclass import pyclass_type
##############################
# targetNamespace
# urn:ZSI
##############################
class ns0:
targetNamespace = "urn:ZSI"
class Echo_Dec(ZSI.TCcompound.ComplexType, ElementDeclaration):
literal = "Echo"
schema = "urn:ZSI"
def __init__(self, **kw):
ns = ns0.Echo_Dec.schema
TClist = [ZSI.TC.AnyType(pname=(ns,"value"),
aname="_value", minOccurs=1, maxOccurs=1,
nillable=False, typed=False,
encoded=kw.get("encoded"))]
kw["pname"] = ("urn:ZSI","Echo")
kw["aname"] = "_Echo"
self.attribute_typecode_dict = {}
ZSI.TCcompound.ComplexType.__init__(self,None,TClist,
inorder=0,**kw)
class Holder:
__metaclass__ = pyclass_type
typecode = self
def __init__(self):
# pyclass
self._value = None
return
Holder.__name__ = "Echo_Holder"
self.pyclass = Holder
# end class ns0 (tns: urn:ZSI)
एक बार उत्पन्न, इन फ़ाइलों को संपादित करने के लिए नहीं होती हैं, क्योंकि वे एक निर्माण प्रक्रिया जब भी डबल्यूएसडीएल इनपुट परिवर्तन के भाग के रूप पुनर्जीवित किया जाएगा। फ़ाइलों में कोड अधिक प्रकार के रूप में बढ़ता है और सेवा परिभाषा में कॉल जोड़े जाते हैं।
सर्वर का कार्यान्वयन एक अलग फ़ाइल में जाता है जो जेनरेट कोड आयात करता है। उदाहरण में, वास्तविक सेवा लिस्टिंग 5 की पंक्तियों पर है। @soapmethod सजावट कॉल के लिए इनपुट (एक इकोआरक्वेट) और आउटपुट (एक इको रेस्पॉन्स) परिभाषित करता है। उदाहरण में, soap_Echo() का कार्यान्वयन अनुरोध मान के साथ प्रतिक्रिया मान में भर जाता है, और अनुरोध और प्रतिक्रिया दोनों देता है। वहां से, जेएसआई एसओएपी प्रतिक्रिया बनाने और इसे वापस ग्राहक को भेजने की देखभाल करता है।
लिस्टिंग 5
import os
import sys
from EchoServer_client import *
from ZSI.twisted.wsgi import (SOAPApplication,
soapmethod,
SOAPHandlerChainFactory)
class EchoService(SOAPApplication):
factory = SOAPHandlerChainFactory
wsdl_content = dict(name='Echo',
targetNamespace='urn:echo',
imports=(),
portType='',
)
def __call__(self, env, start_response):
self.env = env
return SOAPApplication.__call__(self, env, start_response)
@soapmethod(EchoRequest.typecode,
EchoResponse.typecode,
operation='Echo',
soapaction='Echo')
def soap_Echo(self, request, response, **kw):
# Just return what was sent
response.Value = request.Value
return request, response
def main():
from wsgiref.simple_server import make_server
from ZSI.twisted.wsgi import WSGIApplication
application = WSGIApplication()
httpd = make_server('', 7000, application)
application['echo'] = EchoService()
print "listening..."
httpd.serve_forever()
if __name__ == '__main__':
main()
लिस्टिंग 6 कैसे ग्राहक अंत से सर्वर तक पहुँचने के लिए ZSI क्लाइंट लाइब्रेरी का उपयोग करने का एक नमूना भी शामिल है। जो कुछ करने की ज़रूरत है वह है इकोसेवर वेब सेवा के लिए एक हैंडल बनाना, एक इकोआरक्वेट बनाना, इसे वेब सेवा पर भेजना, और प्रतिक्रिया पढ़ें।
from EchoServer_client import *
import sys, time
loc = EchoServerLocator()
port = loc.getEchoServer(url='http://localhost:7000/echo')
print "Echo: ",
msg = EchoRequest()
msg.Value = "Is there an echo in here?"
rsp = port.Echo(msg)
print rsp.Value