(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 $
$ python
>>> import spiroclient
>>> c = spiroclient.SpiroClient("fred")
>>>
Now, a namespace has been created for you on the server. You can look at it by:
>>> c.dir()
()
>>>
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.do("import java")
>>> c.dir()
('java',)
>>>
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'.
>>> java = c.java
>>> java
<java package java at 17705039>
>>>
That's right - we've got a local ref to a remote object, in this case, a module object.
>>> java.lang.Math.sqrt(25)
5.0
>>>
As you can see, we've called a remote function just as if the function existed locally.
>>> org = c.doimport("org")
>>> org
<java package org at 7607272>
>>>
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).
>>> 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"]
>>>
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.
>>> def mary():
... return "this is mary"
>>> c.mary = mary
will cause Really Bad Things to happen. The way around this is to set up a callback (see below).
>>> def myfunc():
... return "this is myfunc"
>>> c.myfunc = c.callback(myfunc)
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.