(If targetting at windows, you can compile your python to a .EXE, build the SPIRO server-side to a self-contained .jar file, and toss in a java runtime environment, for a fully self-contained program distribution that doesn't require Joe Sixpack Windows User to install any third-party stuff at all).This brief manual should be (at least just) enough to get you up and running with SPIRO. You should try the examples herein, and get a hands-on feel for how things work. This will give you a quick grasp of SPIRO, and how it can help you.
$ python spiroclient.py connecting to Spiro server... Importing java package Grabbing java's sqrt() function... Representation of this function: <java function sqrt at 8225050> Executing sqrt(16) got 4.0 $
Now, a namespace has been created for you on the server. You can look at it by:$ python >>> import spiroclient >>> c = spiroclient.SpiroClient("fred") >>>
There are a couple of magic methods of server connection objects. .dir() is one of them, which lists out the names in the server-side namespace. As you can see in the above example, the namespace is currently empty.>>> c.dir() () >>>
Here we see another 'magic method' - .do(). This method causes arbitrary python statements to be executed within your namespace on the server. You'll also see that the namespace now contains a symbol called 'java'.>>> c.do("import java") >>> c.dir() ('java',) >>>
That's right - we've got a local ref to a remote object, in this case, a module object.>>> java = c.java >>> java <java package java at 17705039> >>>
As you can see, we've called a remote function just as if the function existed locally.>>> java.lang.Math.sqrt(25) 5.0 >>>
Note that this .doimport() method doesn't import the module into the server-side namespace, the module is instead returned directly to the client (or, more correctly, wrapped into a proxy object on the client).>>> org = c.doimport("org") >>> org <java package org at 7607272> >>>
Note in this example that the list object assigned to 'fred' in the server namespace actually resides on the namespace. That's because it's a mutable object.>>> c.dir() ('java',) >>> c.alice = 33 >>> print c.alice 33 >>> c.bob = "hello" "hello" >>> c.dir() ('java', 'alice', 'bob') >>> c.fred = ["one", "two"] >>> c.dir() ('java', 'alice', 'bob', 'fred') >>> c.fred ["one", "two"] >>> c.fred.append("three") >>> c.fred ["one", "two", "three"] >>>
will cause Really Bad Things to happen. The way around this is to set up a callback (see below).>>> def mary(): ... return "this is mary" >>> c.mary = mary
Then, objects on the server can call your client-side callables. This is particularly useful when you need to pass callables on the fly as callback args to java functions/methods.>>> def myfunc(): ... return "this is myfunc" >>> c.myfunc = c.callback(myfunc)