Simple Types HOWTO ================== The easiest way to understand use of data types is look at and run the examples already written (in tests/, validate/ and bid/) , and to write your own clients, looking at the xml as it is sent (by setting SOAP.Config.debug=1). As far as the built-in types are concerned, SOAP.py will preserve type as expected. That is: python integer will be of type integer, and equivalently for string and float. To access more than just these types, there are classes in SOAP.py. These allow invoking a certain type by making an instance of the corresponding class. The SOAPBuilder in SOAP.py will automatically convert python lists to Arrays and python dictionaries to Structs- these are two of the most frequently used data types. CLIENT EXAMPLES --------------- ## CODE import SOAP server = SOAP.SOAPProxy("http://localhost:8080/") print server.echo("Hello world") ## /CODE This example (taken from quickstart.txt) sends an ordered parameter of type string. ## CODE import SOAP import time #SOAP.Config.debug = 1 test = time.gmtime (time.time ()) server = SOAP.SOAPProxy("http://localhost:8080/") print server.echoDate (inputDate = SOAP.DateTime(test)) ## /CODE This test calls echoDate with the named parameter inputDate, which is a TimeInstant. It prints the the result. **Note: The reason that it is a TimeInstant and not a DateTime is that SOAP.py uses the 1999 schema intead of the 2001 schema. To make it a DateTime, one would just use SOAP.dateTimeType() in place of SOAP.DateTime(). ** ## CODE import SOAP server = SOAP.SOAPProxy("http://localhost:8080/") test = [0, 1, -1, 3853] print server.echoIntegerArray (inputIntegerArray = test) ## /CODE This calls echoIntegerArray with the named parameter inputIntegerArray, which is a four-member array of type int. It prints the result. ## CODE import SOAP test = {'varFloat': 2.256, 'varInt': 474, 'varString': 'Utah'} server = SOAP.SOAPProxy("http://localhost:8080/") print server.echoStruct (inputStruct = test) ## /CODE This code calls the method echoStruct with the named parameter inputStruct, which is of type Struct. It then prints the result. ## CODE import SOAP item1 = SOAP.Struct( data = {"name":"widget","quantity":200,"price":SOAP.decimalType(45.99), "_typename":"LineItem"}) items = SOAP.Array ( data = [item1] ) items._ns = "http://www.soapinterop.org/Bid" server = SOAP.SOAPProxy("http://localhost:8080") server = server._sa ("http://www.soapinterop.org/Buy") server = server._ns ("http://www.soapinterop.org/Bid") po = SOAP.Struct( data = {"poID":"Order 1234", "createDate": SOAP.dateTimeType(), "items": items} ) print server.Buy(PurchaseOrder = po) ## /CODE A few new things here. -First, we are creating an Array, 'items', with components of (made up) type 'LineItem'. (Notice the use of "_typename" to specify type). -This code associates a namespace with the Array, rather than use the default. -SOAP.dateTimeType() is called directly to get a dateTime instead of SOAP.py's default, 'timeInstant'. -Note that when creating a Struct or Array, the data must be passed in as a named 'data' param (as the first param, by order, is 'name'). -The proxy is instantiated and then the values for its namespace (_ns) and soapaction (_sa) are assigned. -This call will work for a server expecting a parameter with the same components as those in the variable 'po' above. It will work whether the server has a named param 'PurchaseOrder' or has an unnamed param, but will not work if the server expects a named param with a name of anything but 'PurchaseOrder'. SERVER EXAMPLES --------------- ## CODE import SOAP def echo(s): return s + s # repeats a string twice server = SOAP.SOAPServer(("localhost", 8080)) server.registerFunction(echo) server.serve_forever() ## /CODE This server example, from quickstart.txt, echoes (as type string) the string that is passed in, s. ## CODE import SOAP def echoDate (inputDate): return SOAP.DateTime(inputDate) server = SOAP.SOAPServer(("localhost", 8080)) server.registerKWFunction(echoDate ) server.serve_forever() ## /CODE This code accepts an inputDate and returns the same date, ensuring that it is of type TimeInstant by returning an instance of DateTime instead of simply returning the value. ## CODE import SOAP def echoIntegerArray (inputIntegerArray): if type(inputIntegerArray) != type([]) or len(inputIntegerArray) != 4: for elem in inputIntegerArray: if type(elem) != type(1): raise TypeError, "expected 4-member Array of ints" return inputIntegerArray server = SOAP.SOAPServer(("localhost", 8080)) server.registerKWFunction(echoIntegerArray ) server.serve_forever() ## /CODE This server supports the method echoIntegerArray, requiring the named parameter inputIntegerArray, which must be a four-member array of type int. ## CODE import SOAP def echoStruct (inputStruct): myfloat = inputStruct["varFloat"] mystr = inputStruct["varString"] myint = inputStruct["varInt"] return inputStruct server = SOAP.SOAPServer(("localhost", 8080)) server.registerKWFunction(echoStruct ) server.serve_forever() ## /CODE This code creates a server with a method echoStruct, which requires that the incoming Struct have elements named varFloat, varString, and varInt. That is, the server will fault if the incoming Struct does not have any of those elements. **Note, this server code does NOT require that these be the only elements in the struct- just that they be present**. This method simply returns the Struct passed in. ## CODE import sys import SOAP serverstring = "SOAP.py (actzero.com) running "+sys.platform def Buy(**kw): try: PurchaseOrder = kw["PurchaseOrder"] except: PurchaseOrder = kw["PO"] POkeys = PurchaseOrder['_keyord'] POkeys.sort() POkeys_expected = ["items","poID","createDate"] POkeys_expected.sort() if POkeys != POkeys_expected: raise ValueError, "struct 'PurchaseOrder' needs %s, %s, and %s" % tuple(POkeys_expected) items = PurchaseOrder["items"].__dict__ data = items["data"] retstring = "" for item in data: itemdict = item["_asdict"] q = itemdict["quantity"] p = itemdict["price"] name = itemdict["name"] if retstring != "": retstring += ", " else: retstring = "bought " retstring += "%d %s(s) for %.2f" % (q,name,p) retstring += " from "+serverstring return retstring server = SOAP.SOAPServer(("localhost", 8080)) namespace = "http://www.soapinterop.org/Bid" server.registerKWFunction(Buy, namespace ) server.serve_forever() ## /CODE This example creates a server to implement 'Buy', which takes a parameter named either PurchaseOrder or PO. (Notice the use of **kw as the input parameter to the method for this functionality). The server gets the names of the Struct's members by using the '_keyord' key of the Struct-as-dictionary. It checks these names against what it expects from the client, and raises a fault if the two are not the same. By using the __dict__ attribute, the server gets the 'items' (an elemnent of the PurchaseOrder Struct) as a dictionary. Then it checks that 'items' is formatted as expected. Finally, it returns a confirmation of what was bought. $Id: simpleTypes.txt,v 1.2 2005/02/21 20:09:39 warnes Exp $