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 $
