170 likes | 302 Vues
Python Web/Grid Services. Presenter: Joshua Boverhof Lawrence Berkeley National Lab. Webpage: http://pywebsvcs.sourceforge.net/ http://dsd.lbl.gov/gtg/projects/download/download_info.html Demo: http://dsd.lbl.gov/~boverhof Email: JRBoverhof@lbl.gov Pywebsvcs-talk@lists.sourceforge.net.
E N D
Python Web/Grid Services Presenter: Joshua Boverhof Lawrence Berkeley National Lab.
Webpage: http://pywebsvcs.sourceforge.net/ http://dsd.lbl.gov/gtg/projects/download/download_info.html Demo: http://dsd.lbl.gov/~boverhof Email: JRBoverhof@lbl.gov Pywebsvcs-talk@lists.sourceforge.net Project links
Overview ZSI -- Zolera SOAP implementation • wsdl2python -- WSDL/XML Schema • Generate Client: Locators, Ports, Messages • Generate Service: ServiceSOAPBinding pyGridWare -- WS-Resource Framework • New Directions: Basic Profile, WS-Addressing, WS-Resource, XML Message Security
WSDL Info Items <service> <binding> <portType> <messsage> <types> <port> <operation> <operation> <input> <input> <output> <output>
WSDL to Python <service> <binding> <portType> <messsage> <types> <port> <operation> <operation> <part> <schema> Types Locator SOAPPort elements messages
TypeCodes: Describing the data • ZSI.TypeCode “aname”: specifies python attribute name TypeCode will access for element value when parsing and serializing. --wsdl2py convention specify aname as “_name” • Facets: minOccurs, maxOccurs, nillable --ZSI TypeCodes expects repeatable (maxOccurs>1) elements to be specified in sequences.
Elements, Types, and TypeCodes WSDL from http://soap.systinet.net/demos/FreeDB/wsdl <wsdl:message name='FreeDBService_searchByTrack_Response'> <wsdl:part name='response' element='ns0:ArrayOfCDInfo_Response'/> </wsdl:message> <xsd:element name="ArrayOfCDInfo_Response” nillable="true” type="xns4:ArrayOfCDInfo"/> <xsd:complexType name="ArrayOfCDInfo"> <xsd:sequence> <xsd:element maxOccurs="unbounded" minOccurs="0" name="CDInfo" nillable="true" type="tns:CDInfo"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="CDInfo"> <xsd:sequence> <xsd:element name="artist" nillable="true” type="xsd:string"/> <xsd:element name="category" nillable="true” type="xsd:string"/> <xsd:element name="discId" nillable="true” type="xsd:string"/> <xsd:element name="title" nillable="true” type="xsd:string"/> </xsd:sequence> </xsd:complexType>
Elements --> XML Instance <e:Envelope xmlns:e="http://schemas.xmlsoap.org/soap/envelope/" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:wn0="http://systinet.com/wsdl/com/systinet/demo/freedb/" xmlns:wn1="http://systinet.com/xsd/SchemaTypes/" xmlns:wn2="http://idoox.com/interface"> <e:Body> <wn1:ArrayOfCDInfo_Response i:type="wn0:ArrayOfCDInfo"> <wn0:CDInfo i:type="wn0:CDInfo"> <wn0:artist i:type="d:string">Deftones et Slipknot</wn0:artist> <wn0:category i:type="d:string">rock</wn0:category> <wn0:discId i:type="d:string">23110313</wn0:discId> <wn0:title i:type="d:string">Personnalisé</wn0:title> </wn0:CDInfo> … </e:Body> </e:Envelope>
Generated Client Modules _services.py _types.py Types elements Locator SOAPPort messages %wsdl2py -u http://soap.systinet.net/demos/FreeDB/wsdl %python >>>from com_systinet_demo_freedb_FreeDBService_services import * >>>loc = JavaServiceLocator() >>>port = loc.getFreeDBService() >>>msg = port.searchByArtist(’Slipknot') >>> msg <com_systinet_demo_freedb_FreeDBService_services_types.ArrayOfCDInfo_Response_Dec> >>> len(msg._CDInfo) 74 >>> msg._CDInfo[49]._title u'My Plague (New Abuse Mix)'
Generated Service Module _services_server.py _services.py _types.py Types elements ServiceSOAP Binding messages %wsdl2dispatch -u http://soap.systinet.net/demos/FreeDB/wsdl %python >>>from com_systinet_demo_freedb_FreeDBService_services_server import * >>>from ZSI.ServiceContainer import AsServer >>>AsServer(port=8080,services=(com_systinet_demo_freedb_FreeDBService(),))
Service Module class com_systinet_demo_freedb_FreeDBService(ServiceSOAPBinding): soapAction = { 'http://systinet.com/wsdl/com/systinet/demo/freedb/FreeDBService#getDetails#':'soap_getDetails', 'http://systinet.com/wsdl/com/systinet/demo/freedb/FreeDBService#search#':'soap_search', 'http://systinet.com/wsdl/com/systinet/demo/freedb/FreeDBService#searchByArtist#':'soap_searchByArtist', 'http://systinet.com/wsdl/com/systinet/demo/freedb/FreeDBService#searchByTitle#':'soap_searchByTitle', 'http://systinet.com/wsdl/com/systinet/demo/freedb/FreeDBService#searchByTrack#':'soap_searchByTrack', } def __init__(self, post='/FreeDB/', **kw): ServiceSOAPBinding.__init__(self, post) def soap_searchByArtist(self, ps): # input vals in request object args = ps.Parse( FreeDBService_searchByArtist_1_Request() ) # assign return values to response object response = FreeDBService_searchByArtist_Response() #User Adds some logic to do something if args == ‘Slipknot’: class Holder: pass response._CDInfo = [Holder()] response._CDInfo[0]._title = 'My Plague (New Abuse Mix) ' response._CDInfo[0]._artist = ’SLIPKNOT' return response
New Directions: pyGridWare • WS-Resource: Stateless web services paradigm, implied factory pattern. • WS-Address: Specify resource identity in SOAP Header. • Message-Level Security
Implied Resource Pattern Soap:Header Service client Body 1 Model State create 2 3 epr value response epr 5 epr epr 4 epr operation
$wsdl2py -f counter_service.wsdl -a Client for WS-Resource • Client generated in same way… Just specify WS-Addressing • Create operation -- receives an EndpointReference containing a resource ID. This is used to refer back to the stateful instance. • Drop EndpointReference into a new port. • New port refers to a stateful service
Create XML Instance <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Header xmlns:ns1="http://schemas.xmlsoap.org/ws/2003/03/addressing"> <ns1:MessageID id="567080">uuid:1087253160.24</ns1:MessageID> <ns1:Action id="54e808">http://counter.com/service/CounterPortType/createCounterRequest</ns1:Action> <ns1:To id="73338">http://bundy.localdomain:8080/wsrf/services/CounterService</ns1:To> </SOAP-ENV:Header> <SOAP-ENV:Body xmlns:ns1="http://counter.com"> <ns1:createCounter></ns1:createCounter> </SOAP-ENV:Body> </SOAP-ENV:Envelope> %python >>>import pyGridWare.generated.stubs.Counter_services as COUNTER >>>locator = COUNTER.CounterServiceLocator() >>>port = locator.getCounterPortType() >>>msg = port.createCounter(COUNTER.CreateCounterRequest())
Create Response XML Instance <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing"> <soapenv:Header> <wsa:MessageID soapenv:mustUnderstand="0">uuid:E77B0490-BE5B-11D8-92A0</wsa:MessageID> <wsa:To soapenv:mustUnderstand="0">http://schemas.xmlsoap.org/ws/2003/03/addressing/role/anonymous</wsa:To> <wsa:Action soapenv:mustUnderstand="0">http://counter.com/service/CounterPortType/createCounterResponse </wsa:Action> <wsa:From><wsa:Address>http://bundy.localdomain:8080/wsrf/services/CounterService</wsa:Address></wsa:From> <ns0:RelatesTo RelationshipType="wsa:Response" soapenv:mustUnderstand="0" xmlns:ns0="http://schemas.xmlsoap.org/ws/2003/03/addressing">uuid:1087255976.97</ns0:RelatesTo> </soapenv:Header> <soapenv:Body> <createCounterResponse xmlns="http://counter.com"> <wsa:EndpointReference> <wsa:Address>http://bundy.localdomain:8080/wsrf/services/CounterService</wsa:Address> <wsa:ReferenceProperties> <CounterKey>27378735</CounterKey> </wsa:ReferenceProperties> </wsa:EndpointReference> </createCounterResponse> </soapenv:Body> </soapenv:Envelope>
Add Operation <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ZSI="http://www.zolera.com/schemas/ZSI/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Header xmlns:ns1="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:ns2="http://counter.com"> <ns1:MessageID id="740980">uuid:1088447466.12</ns1:MessageID> <ns1:Action id="55b610">http://counter.com/service/CounterPortType/addRequest</ns1:Action> <ns1:To id="107a260">http://bundy.localdomain:8080/wsrf/services/CounterService</ns1:To> <ns2:CounterKey id="107a6b0">12399227</ns2:CounterKey> </SOAP-ENV:Header> <SOAP-ENV:Body xmlns:ns1="http://counter.com"> <ns1:add id="18085d0">11</ns1:add> </SOAP-ENV:Body> </SOAP-ENV:Envelope> >>>msg = port.createCounter(COUNTER.CreateCounterRequest()) >>>port = locator.getCounterPortType(endPointReference=msg._EndpointReference) >>>msg = port.add(11)