[Spread-users] Python binding for Spread
Bradley McLean
brad at bradm.net
Thu Sep 27 11:39:08 EDT 2001
Attached is a python binding for spread. It does not
support the authentication work (because I didn't see
any documentation on it).
I'm willing to make extensions and donate this to the
project if folks are interested.
I started from a SWIG generated interface, and then
replaced almost all of it with hand coding for various
reasons.
-Brad
-------------- next part --------------
#include <stdlib.h>
#include "Python.h"
#include "sp.h"
#include "sp_func.h"
#ifdef __cplusplus
extern "C" {
#endif
static PyObject *_wrap_SP_version(PyObject *self, PyObject *args) {
int major;
int minor;
int rev;
int result;
result = (int) SP_version(&major,&minor,&rev);
// believe that result cannot come back as a useful value, so don't
// bother to return it up to the scripting layer.
return Py_BuildValue("iii",major,minor,rev);
}
/* FUTURE, when these are documented and I can figure out how to map
them to python:
static PyObject *_wrap_SP_set_auth_method(PyObject *self, PyObject *args) {
PyObject *resultobj;
char *arg0 ;
int (*arg1)(int ,void *) ;
void *arg2 ;
PyObject * argo1 =0 ;
PyObject * argo2 =0 ;
int result ;
// deal with the objects in here
if(!PyArg_ParseTuple(args,(char *)"sOO:SP_set_auth_method",&arg0,
&argo1,&argo2)) return NULL;
result = (int )SP_set_auth_method((char const *)arg0,arg1,arg2);
return = PyInt_FromLong((long)result);
}
static PyObject *_wrap_SP_set_auth_methods(PyObject *self, PyObject *args) {
PyObject *resultobj;
int arg0 ;
char **arg1 ;
int (**arg2)(int ,void *) ;
void **arg3 ;
PyObject * argo1 =0 ;
PyObject * argo2 =0 ;
PyObject * argo3 =0 ;
int result ;
if(!PyArg_ParseTuple(args,(char *)"iOOO:SP_set_auth_methods",&arg0,
&argo1,&argo2,&argo3)) return NULL;
// deal with the objects in here.
result = (int )SP_set_auth_methods(arg0,(char const *(*))arg1,arg2,arg3);
resultobj = PyInt_FromLong((long)result);
return resultobj;
}
*/
static PyObject *_wrap_SP_connect(PyObject *self, PyObject *args) {
char *spread_name;
char *private_name;
int priority;
int groupmsgs;
int handle ;
char private_group[MAX_PRIVATE_NAME] ;
int result ;
if(!PyArg_ParseTuple(args,(char *)"ssii:SP_connect",
&spread_name,&private_name,&priority,&groupmsgs)) return NULL;
result = (int )SP_connect((char const *)spread_name,
(char const *)private_name,
priority,groupmsgs,&handle,private_group);
return Py_BuildValue("iis",result,handle,private_group);
}
static PyObject *_wrap_SP_connect_timeout(PyObject *self, PyObject *args) {
char *spread_name ;
char *private_name ;
int priority ;
int groupmsgs ;
int handle ;
char private_group[MAX_PRIVATE_NAME];
sp_time timeout ;
int result ;
if(!PyArg_ParseTuple(args,(char *)"ssiill:SP_connect_timeout",
&spread_name,&private_name,&priority,&groupmsgs,
&timeout.sec,&timeout.usec)) return NULL;
result = (int )SP_connect_timeout((char const *)spread_name,
(char const *)private_name,priority,
groupmsgs,&handle,private_group,timeout);
return Py_BuildValue("iis",result,handle,private_group);
}
static PyObject *_wrap_SP_disconnect(PyObject *self, PyObject *args) {
int handle;
if(!PyArg_ParseTuple(args,(char *)"i:SP_disconnect",&handle)) return NULL;
return PyInt_FromLong((long)SP_disconnect(handle));
}
static PyObject *_wrap_SP_join(PyObject *self, PyObject *args) {
int handle;
char *groupname;
int result;
if(!PyArg_ParseTuple(args,(char *)"is:SP_join",&handle,&groupname))
return NULL;
result = (int )SP_join(handle,(char const *)groupname);
return PyInt_FromLong((long)result);
}
static PyObject *_wrap_SP_leave(PyObject *self, PyObject *args) {
int handle;
char *groupname;
int result;
if(!PyArg_ParseTuple(args,(char *)"is:SP_leave",&handle,&groupname))
return NULL;
result = (int )SP_leave(handle,(char const *)groupname);
return PyInt_FromLong((long)result);
}
static PyObject *_wrap_SP_multicast(PyObject *self, PyObject *args) {
int handle;
int svc;
int groupcnt;
char *groupname;
char (*grouplist)[MAX_GROUP_NAME] ;
short msgtype ;
int msglen ;
char *msg ;
PyObject * groups =0 ;
PyObject * str =0 ;
int i, result ;
if(!PyArg_ParseTuple(args,(char *)"iishis:SP_multicast",&handle,
&svc,&groupname,&msgtype,&msglen,&msg)) {
if(!PyArg_ParseTuple(args,(char *)"iiOhis:SP_multigroup_multicast",
&handle,&svc,&groups,&msgtype,
&msglen,&msg)) return NULL;
if ( !PySequence_Check(groups) ) return NULL;
grouplist = (char (*)[MAX_GROUP_NAME])calloc(PySequence_Length(groups),
MAX_GROUP_NAME);
if ( grouplist == NULL ) return NULL;
groupcnt=PySequence_Length(groups);
for ( i=0; i < groupcnt; i++ ) {
str = PySequence_GetItem(groups,i);
if ( !PyString_Check(str) ) return NULL;
strncpy(grouplist[i],PyString_AsString(str),MAX_GROUP_NAME);
}
result = (int )SP_multigroup_multicast(handle,svc,groupcnt,
(char const (*)[32])grouplist,
msgtype,msglen,
(char const *)msg);
free(grouplist);
} else { /* Single group form */
result = (int )SP_multicast(handle,svc,(char const *)groupname,
msgtype,msglen,(char const *)msg);
}
return PyInt_FromLong((long)result);
}
static PyObject *_wrap_SP_receive(PyObject *self, PyObject *args) {
PyObject *resultobj;
int hand;
int maxgrp;
int msglen;
service service_type;
char sender[MAX_GROUP_NAME];
int numgrp;
char (*grps)[MAX_GROUP_NAME];
int16 type;
int endian;
char *msg;
PyObject *grouplist;
int i, result ;
if(!PyArg_ParseTuple(args,(char *)"iii:SP_receive",&hand,&maxgrp,&msglen))
return NULL;
grps = (char (*)[MAX_GROUP_NAME])calloc(maxgrp,MAX_GROUP_NAME);
if ( grps == NULL ) return NULL;
msg = calloc(msglen,1);
if ( msg == NULL ) return NULL;
sender[0] = 0;
result = (int )SP_receive(hand,&service_type,sender,maxgrp,&numgrp,
grps,&type,&endian,msglen,msg);
if ( result <= 0 ) {
grouplist = PyInt_FromLong((long) numgrp);
} else {
grouplist = PyList_New(numgrp);
for ( i=0; i < numgrp; i++ ) {
PyList_SetItem(grouplist,i,PyString_FromString(grps[i]));
}
}
resultobj = Py_BuildValue("iisOhis",result,service_type,sender,
grouplist,type,endian,msg);
free(msg);
free(grps);
return resultobj;
}
static PyObject *_wrap_SP_poll(PyObject *self, PyObject *args) {
PyObject *resultobj;
int handle ;
int result ;
if(!PyArg_ParseTuple(args,(char *)"i:SP_poll",&handle)) return NULL;
result = (int )SP_poll(handle);
resultobj = PyInt_FromLong((long)result);
return resultobj;
}
/* Future? We don't actually ever decode these objects; we just export
the visible names.
static PyObject *_wrap_SP_equal_group_ids(PyObject *self, PyObject *args) {
PyObject *resultobj;
group_id *handle ;
group_id *arg1 ;
PyObject * argo0 =0 ;
PyObject * argo1 =0 ;
int result ;
if(!PyArg_ParseTuple(args,(char *)"OO:SP_equal_group_ids",&argo0,&argo1))
return NULL;
if ((SWIG_ConvertPtr(argo0,(void **) &handle,SWIGTYPE_p_group_id,1)) == -1)
return NULL;
if ((SWIG_ConvertPtr(argo1,(void **) &arg1,SWIGTYPE_p_group_id,1)) == -1)
return NULL;
result = (int )SP_equal_group_ids(*handle,*arg1);
resultobj = PyInt_FromLong((long)result);
return resultobj;
}
*/
static PyMethodDef spredMethods[] = {
{ (char *)"SP_version", _wrap_SP_version, METH_VARARGS },
// { (char *)"SP_set_auth_method", _wrap_SP_set_auth_method, METH_VARARGS },
// { (char *)"SP_set_auth_methods", _wrap_SP_set_auth_methods, METH_VARARGS },
{ (char *)"SP_connect", _wrap_SP_connect, METH_VARARGS },
{ (char *)"SP_connect_timeout", _wrap_SP_connect_timeout, METH_VARARGS },
{ (char *)"SP_disconnect", _wrap_SP_disconnect, METH_VARARGS },
{ (char *)"SP_join", _wrap_SP_join, METH_VARARGS },
{ (char *)"SP_leave", _wrap_SP_leave, METH_VARARGS },
{ (char *)"SP_multicast", _wrap_SP_multicast, METH_VARARGS },
{ (char *)"SP_receive", _wrap_SP_receive, METH_VARARGS },
{ (char *)"SP_poll", _wrap_SP_poll, METH_VARARGS },
// { (char *)"SP_equal_group_ids", _wrap_SP_equal_group_ids, METH_VARARGS },
{ NULL, NULL }
};
#ifdef __cplusplus
}
#endif
static struct { char *name; long lvalue; } const_table[] = {
{ (char*)"LOW_PRIORITY", (long) LOW_PRIORITY},
{ (char*)"MEDIUM_PRIORITY", (long) MEDIUM_PRIORITY},
{ (char*)"HIGH_PRIORITY", (long) HIGH_PRIORITY},
{ (char*)"DEFAULT_SPREAD_PORT", (long) DEFAULT_SPREAD_PORT},
{ (char*)"SPREAD_VERSION", (long) SPREAD_VERSION},
{ (char*)"MAX_GROUP_NAME", (long) MAX_GROUP_NAME},
{ (char*)"MAX_PRIVATE_NAME", (long) MAX_PRIVATE_NAME},
{ (char*)"MAX_PROC_NAME", (long) MAX_PROC_NAME},
{ (char*)"UNRELIABLE_MESS", (long) UNRELIABLE_MESS},
{ (char*)"RELIABLE_MESS", (long) RELIABLE_MESS},
{ (char*)"FIFO_MESS", (long) FIFO_MESS},
{ (char*)"CAUSAL_MESS", (long) CAUSAL_MESS},
{ (char*)"AGREED_MESS", (long) AGREED_MESS},
{ (char*)"SAFE_MESS", (long) SAFE_MESS},
{ (char*)"REGULAR_MESS", (long) REGULAR_MESS},
{ (char*)"SELF_DISCARD", (long) SELF_DISCARD},
{ (char*)"DROP_RECV", (long) DROP_RECV},
{ (char*)"REG_MEMB_MESS", (long) REG_MEMB_MESS},
{ (char*)"TRANSITION_MESS", (long) TRANSITION_MESS},
{ (char*)"CAUSED_BY_JOIN", (long) CAUSED_BY_JOIN},
{ (char*)"CAUSED_BY_LEAVE", (long) CAUSED_BY_LEAVE},
{ (char*)"CAUSED_BY_DISCONNECT", (long) CAUSED_BY_DISCONNECT},
{ (char*)"CAUSED_BY_NETWORK", (long) CAUSED_BY_NETWORK},
{ (char*)"MEMBERSHIP_MESS", (long) MEMBERSHIP_MESS},
{ (char*)"ENDIAN_RESERVED", (long) ENDIAN_RESERVED},
{ (char*)"RESERVED", (long) RESERVED},
{ (char*)"REJECT_MESS", (long) REJECT_MESS},
{ (char*)"ACCEPT_SESSION", (long) ACCEPT_SESSION},
{ (char*)"ILLEGAL_SPREAD", (long) ILLEGAL_SPREAD},
{ (char*)"COULD_NOT_CONNECT", (long) COULD_NOT_CONNECT},
{ (char*)"REJECT_QUOTA", (long) REJECT_QUOTA},
{ (char*)"REJECT_NO_NAME", (long) REJECT_NO_NAME},
{ (char*)"REJECT_ILLEGAL_NAME", (long) REJECT_ILLEGAL_NAME},
{ (char*)"REJECT_NOT_UNIQUE", (long) REJECT_NOT_UNIQUE},
{ (char*)"REJECT_VERSION", (long) REJECT_VERSION},
{ (char*)"CONNECTION_CLOSED", (long) CONNECTION_CLOSED},
{ (char*)"REJECT_AUTH", (long) REJECT_AUTH},
{ (char*)"ILLEGAL_SESSION", (long) ILLEGAL_SESSION},
{ (char*)"ILLEGAL_SERVICE", (long) ILLEGAL_SERVICE},
{ (char*)"ILLEGAL_MESSAGE", (long) ILLEGAL_MESSAGE},
{ (char*)"ILLEGAL_GROUP", (long) ILLEGAL_GROUP},
{ (char*)"BUFFER_TOO_SHORT", (long) BUFFER_TOO_SHORT},
{ (char*)"GROUPS_TOO_SHORT", (long) GROUPS_TOO_SHORT},
{ (char*)"MESSAGE_TOO_LONG", (long) MESSAGE_TOO_LONG},
{ (char*)"MAX_SCATTER_ELEMENTS", (long) MAX_SCATTER_ELEMENTS},
{0}};
#ifdef __cplusplus
extern "C"
#endif
void initspred(void) {
PyObject *m, *d, *val;
int i;
m = Py_InitModule((char*)"spred", spredMethods);
for ( i=0; const_table[i].name; i++ ) {
d = PyModule_GetDict(m);
val = PyInt_FromLong(const_table[i].lvalue);
PyDict_SetItemString(d,const_table[i].name,val);
Py_DECREF(val);
}
}
-------------- next part --------------
import spred
import string, types
version = spred.SP_version
class spread:
LOW_PRIORITY = spred.LOW_PRIORITY
MEDIUM_PRIORITY = spred.MEDIUM_PRIORITY
HIGH_PRIORITY = spred.HIGH_PRIORITY
DEFAULT_SPREAD_PORT = spred.DEFAULT_SPREAD_PORT
SPREAD_VERSION = spred.SPREAD_VERSION
MAX_GROUP_NAME = spred.MAX_GROUP_NAME
MAX_PRIVATE_NAME = spred.MAX_PRIVATE_NAME
MAX_PROC_NAME = spred.MAX_PROC_NAME
UNRELIABLE_MESS = spred.UNRELIABLE_MESS
RELIABLE_MESS = spred.RELIABLE_MESS
FIFO_MESS = spred.FIFO_MESS
CAUSAL_MESS = spred.CAUSAL_MESS
AGREED_MESS = spred.AGREED_MESS
SAFE_MESS = spred.SAFE_MESS
REGULAR_MESS = spred.REGULAR_MESS
SELF_DISCARD = spred.SELF_DISCARD
DROP_RECV = spred.DROP_RECV
REG_MEMB_MESS = spred.REG_MEMB_MESS
TRANSITION_MESS = spred.TRANSITION_MESS
CAUSED_BY_JOIN = spred.CAUSED_BY_JOIN
CAUSED_BY_LEAVE = spred.CAUSED_BY_LEAVE
CAUSED_BY_DISCONNECT = spred.CAUSED_BY_DISCONNECT
CAUSED_BY_NETWORK = spred.CAUSED_BY_NETWORK
MEMBERSHIP_MESS = spred.MEMBERSHIP_MESS
ENDIAN_RESERVED = spred.ENDIAN_RESERVED
RESERVED = spred.RESERVED
REJECT_MESS = spred.REJECT_MESS
error = { spred.LOW_PRIORITY : 'LOW_PRIORITY',
spred.MEDIUM_PRIORITY : 'MEDIUM_PRIORITY',
spred.HIGH_PRIORITY : 'HIGH_PRIORITY',
spred.DEFAULT_SPREAD_PORT : 'DEFAULT_SPREAD_PORT',
spred.SPREAD_VERSION : 'SPREAD_VERSION',
spred.DROP_RECV : 'DROP_RECV',
spred.REG_MEMB_MESS : 'REG_MEMB_MESS',
spred.TRANSITION_MESS : 'TRANSITION_MESS',
spred.CAUSED_BY_JOIN : 'CAUSED_BY_JOIN',
spred.CAUSED_BY_LEAVE : 'CAUSED_BY_LEAVE',
spred.CAUSED_BY_DISCONNECT : 'CAUSED_BY_DISCONNECT',
spred.CAUSED_BY_NETWORK : 'CAUSED_BY_NETWORK',
spred.MEMBERSHIP_MESS : 'MEMBERSHIP_MESS',
spred.ENDIAN_RESERVED : 'ENDIAN_RESERVED',
spred.RESERVED : 'RESERVED',
spred.REJECT_MESS : 'REJECT_MESS',
spred.ACCEPT_SESSION : 'ACCEPT_SESSION',
spred.ILLEGAL_SPREAD : 'ILLEGAL_SPREAD',
spred.COULD_NOT_CONNECT : 'COULD_NOT_CONNECT',
spred.REJECT_QUOTA : 'REJECT_QUOTA',
spred.REJECT_NO_NAME : 'REJECT_NO_NAME',
spred.REJECT_ILLEGAL_NAME : 'REJECT_ILLEGAL_NAME',
spred.REJECT_NOT_UNIQUE : 'REJECT_NOT_UNIQUE',
spred.REJECT_VERSION : 'REJECT_VERSION',
spred.CONNECTION_CLOSED : 'CONNECTION_CLOSED',
spred.REJECT_AUTH : 'REJECT_AUTH',
spred.ILLEGAL_SESSION : 'ILLEGAL_SESSION',
spred.ILLEGAL_SERVICE : 'ILLEGAL_SERVICE',
spred.ILLEGAL_MESSAGE : 'ILLEGAL_MESSAGE',
spred.ILLEGAL_GROUP : 'ILLEGAL_GROUP',
spred.BUFFER_TOO_SHORT : 'BUFFER_TOO_SHORT',
spred.GROUPS_TOO_SHORT : 'GROUPS_TOO_SHORT',
spred.MESSAGE_TOO_LONG : 'MESSAGE_TOO_LONG',
spred.MAX_SCATTER_ELEMENTS : 'MAX_SCATTER_ELEMENTS' }
def __init__(self,spreadname,privatename,priority = 0,group = 1):
(res,self.handle,self.privategroup) = spred.SP_connect(spreadname,privatename,priority,group)
if res != spred.ACCEPT_SESSION:
raise self.error[res]
self.groups = {}
def __del__(self):
res = spred.SP_disconnect(self.handle)
if res != 0:
raise self.error[res]
def join(self,group):
res = spred.SP_join(self.handle,group)
if res != 0:
raise self.error[res]
# Not needed, the membership message does it:
#self.groups[group] = (self.privategroup)
def leave(self,group):
res = spred.SP_leave(self.handle,group)
if res != 0:
raise self.error[res]
del self.groups[group]
def _membership(self,res,service,sender,groups,type,endian,msg):
self.groups[sender]=groups
def multicast(self,service,groups,msgtype,message):
res = spred.SP_multicast(self.handle,service,groups,msgtype,
len(message),message)
if res < 0:
raise self.error[res]
def receive(self,maxgroups=4,messagelen=1024):
while 1:
result = spred.SP_receive(self.handle,maxgroups,messagelen)
(res,service,sender,groups,type,endian,msg) = result
if res < 0:
if res == spred.GROUPS_TOO_SHORT:
maxgroups = -groups
elif res == spred.BUFFER_TOO_SHORT:
messagelen = -endian
else:
raise self.error[res]
if service & spred.MEMBERSHIP_MESS:
self._membership(res,service,sender,groups,type,endian,msg)
else:
return result
def poll(self):
return spred.SP_poll(self.handle)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: buildspred.sh
Type: application/x-sh
Size: 164 bytes
Desc: not available
Url : http://lists.spread.org/pipermail/spread-users/attachments/20010927/2b6cd98b/attachment.sh
-------------- next part --------------
from spread import spread
chan1 = spread('4803 at localhost','one')
chan1.join("g1")
chan1.multicast(spread.RELIABLE_MESS,"g1",0,'Welcome to Spread Test')
while 1:
res = chan1.receive()
print "Got> ",res
More information about the Spread-users
mailing list