Skip to content
Snippets Groups Projects
Commit 2fdda004 authored by Jonathan Lambrechts's avatar Jonathan Lambrechts
Browse files

add onelab python clients

parent 708a843e
No related branches found
No related tags found
No related merge requests found
...@@ -702,7 +702,7 @@ namespace onelab{ ...@@ -702,7 +702,7 @@ namespace onelab{
const std::string &client=""){ return _set(p, client, _functions); } const std::string &client=""){ return _set(p, client, _functions); }
bool get(std::vector<number> &ps, const std::string &name="", bool get(std::vector<number> &ps, const std::string &name="",
const std::string &client=""){ return _get(ps, name, client, _numbers); } const std::string &client=""){ return _get(ps, name, client, _numbers); }
bool get(std::vector<string> &ps, const std::string &name="", bool get(std::vector<onelab::string> &ps, const std::string &name="",
const std::string &client=""){ return _get(ps, name, client, _strings); } const std::string &client=""){ return _get(ps, name, client, _strings); }
bool get(std::vector<region> &ps, const std::string &name="", bool get(std::vector<region> &ps, const std::string &name="",
const std::string &client=""){ return _get(ps, name, client, _regions); } const std::string &client=""){ return _get(ps, name, client, _regions); }
...@@ -817,7 +817,7 @@ namespace onelab{ ...@@ -817,7 +817,7 @@ namespace onelab{
virtual bool set(const region &p) = 0; virtual bool set(const region &p) = 0;
virtual bool set(const function &p) = 0; virtual bool set(const function &p) = 0;
virtual bool get(std::vector<number> &ps, const std::string &name="") = 0; virtual bool get(std::vector<number> &ps, const std::string &name="") = 0;
virtual bool get(std::vector<string> &ps, const std::string &name="") = 0; virtual bool get(std::vector<onelab::string> &ps, const std::string &name="") = 0;
virtual bool get(std::vector<region> &ps, const std::string &name="") = 0; virtual bool get(std::vector<region> &ps, const std::string &name="") = 0;
virtual bool get(std::vector<function> &ps, const std::string &name="") = 0; virtual bool get(std::vector<function> &ps, const std::string &name="") = 0;
std::vector<std::string> toChar() std::vector<std::string> toChar()
...@@ -967,7 +967,7 @@ namespace onelab{ ...@@ -967,7 +967,7 @@ namespace onelab{
virtual bool set(const region &p){ return _set(p); } virtual bool set(const region &p){ return _set(p); }
virtual bool get(std::vector<number> &ps, virtual bool get(std::vector<number> &ps,
const std::string &name=""){ return _get(ps, name); } const std::string &name=""){ return _get(ps, name); }
virtual bool get(std::vector<string> &ps, virtual bool get(std::vector<onelab::string> &ps,
const std::string &name=""){ return _get(ps, name); } const std::string &name=""){ return _get(ps, name); }
virtual bool get(std::vector<function> &ps, virtual bool get(std::vector<function> &ps,
const std::string &name=""){ return _get(ps, name); } const std::string &name=""){ return _get(ps, name); }
...@@ -1005,8 +1005,10 @@ namespace onelab{ ...@@ -1005,8 +1005,10 @@ namespace onelab{
void setPid(int pid){ _pid = pid; } void setPid(int pid){ _pid = pid; }
GmshServer *getGmshServer(){ return _gmshServer; } GmshServer *getGmshServer(){ return _gmshServer; }
void setGmshServer(GmshServer *server){ _gmshServer = server; } void setGmshServer(GmshServer *server){ _gmshServer = server; }
#ifndef SWIG
virtual bool run(); virtual bool run();
virtual bool kill(); virtual bool kill();
#endif
}; };
// The remote part of a network client. // The remote part of a network client.
...@@ -1112,7 +1114,7 @@ namespace onelab{ ...@@ -1112,7 +1114,7 @@ namespace onelab{
virtual bool set(const region &p){ return _set(p); } virtual bool set(const region &p){ return _set(p); }
virtual bool get(std::vector<number> &ps, virtual bool get(std::vector<number> &ps,
const std::string &name=""){ return _get(ps, name); } const std::string &name=""){ return _get(ps, name); }
virtual bool get(std::vector<string> &ps, virtual bool get(std::vector<onelab::string> &ps,
const std::string &name=""){ return _get(ps, name); } const std::string &name=""){ return _get(ps, name); }
virtual bool get(std::vector<function> &ps, virtual bool get(std::vector<function> &ps,
const std::string &name=""){ return _get(ps, name); } const std::string &name=""){ return _get(ps, name); }
......
%module onelab
%{
#include "onelab.h"
onelab::server *onelab::server::_server = 0;
void modelName(const std::string &name, const std::string &wdir="");
int metamodel(const std::string &todo);
void setNumber(const std::string &name, const double value);
void setString(const std::string &name, const std::string &value);
double getNumber(const std::string &name);
std::string getString(const std::string &name);
%}
%include std_string.i
extern void modelName(const std::string &name, const std::string &wdir="");
extern int metamodel(const std::string &todo);
extern void setNumber(const std::string &name, const double value);
extern void setString(const std::string &name, const std::string &value);
extern double getNumber(const std::string &name);
extern std::string getString(const std::string &name);
import socket, struct, os, sys
_VERSION = '1.05'
class _parameter() :
_membersbase = [
('name', 'string'), ('label', 'string', ''), ('help', 'string', ''),
('neverChanged', 'int', 0), ('changed', 'int', 1), ('visible', 'int', 1),
('read_only', 'int', 0), ('attributes', ('dict', 'string', 'string'), {}),
('clients', ('list', 'string'), [])
]
_members = {
'string' : _membersbase + [
('value', 'string'), ('kind', 'string', 'generic'), ('choices', ('list', 'string'), [])
],
'number' : _membersbase + [
('value', 'float'), ('min', 'float', -sys.float_info.max), ('max', 'float', sys.float_info.max),
('step', 'float', 0.), ('index', 'int', -1), ('choices', ('list', 'float'), []),
('labels', ('dict', 'float', 'string'), {})
]
}
def __init__(self, type, **values) :
self.type = type
for i in _parameter._members[self.type] :
setattr(self, i[0], values[i[0]] if i[0] in values else i[2])
def tochar(self) :
def tocharitem(l, t, v) :
if t=='string' : l.append(v)
elif t =='int': l.append(str(v))
elif t=='float' : l.append('%.16g' % v)
elif t[0]=='list' :
l.append(str(len(v)))
for i in v : tocharitem(l, t[1], i)
elif t[0]=='dict' :
l.append(str(len(v)))
for i, j in v.items() :
tocharitem(l, t[1], i)
tocharitem(l, t[2], j)
msg = [_VERSION, self.type]
for i in _parameter._members[self.type] :
tocharitem(msg, i[1], getattr(self, i[0]))
return '\0'.join(msg)
def fromchar(self, msg) :
def fromcharitem(l, t) :
if t=='string' : return l.pop()
elif t =='int': return int(l.pop())
elif t=='float' : return float(l.pop())
elif t[0]=='list' : return [fromcharitem(l, t[1]) for i in range(int(l.pop()))]
elif t[0]=='dict' : return dict([(fromcharitem(l, t[1]),fromcharitem(l, t[2])) for i in range(int(l.pop()))])
l = msg.split('\0')
l.reverse()
if l.pop() != _VERSION :
print('onelab version mismatch')
if l.pop() != self.type :
print('onelab parameter type mismatch')
for p in _parameter._members[self.type]:
setattr(self, p[0], fromcharitem(l, p[1]))
class client :
_GMSH_START = 1
_GMSH_STOP = 2
_GMSH_INFO = 10
_GMSH_PARAMETER = 23
_GMSH_PARAMETER_QUERY = 24
def _receive(self) :
def buffered_receive(l) :
msg = b''
while len(msg) < l:
chunk = self.socket.recv(l - len(msg))
if not chunk :
RuntimeError('onelab socket closed')
msg += chunk
return msg
msg = buffered_receive(struct.calcsize('ii'))
t, l = struct.unpack('ii', msg)
msg = buffered_receive(l).decode('utf-8')
if t == self._GMSH_INFO :
print('onelab info : %s' % msg)
return t, msg
def _send(self, t, msg) :
m = msg.encode('utf-8')
if self.socket.send(struct.pack('ii%is' %len(m), t, len(m), m)) == 0 :
RuntimeError('onelab socket closed')
def _get_parameter(self, param) :
if not self.socket :
return
self._send(self._GMSH_PARAMETER_QUERY, param.tochar())
(t, msg) = self._receive()
if t == self._GMSH_PARAMETER :
param.fromchar(msg)
elif t == self._GMSH_INFO :
self._send(self._GMSH_PARAMETER, param.tochar())
def get_string(self, name, value, **param):
param = _parameter('string', name=name, value=value, **param)
self._get_parameter(param)
return param.value
def get_number(self, name, value, **param):
if "labels" in param :
param["choices"] = param["labels"].keys()
p = _parameter('number', name=name, value=value, **param)
self._get_parameter(p)
return p.value
def __init__(self):
self.socket = None
self.name = ""
for i, v in enumerate(sys.argv) :
if v == '-onelab':
self.name = sys.argv[i + 1]
addr = sys.argv[2]
if '/' in addr or '\\' in addr or ':' not in addr :
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
else :
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect(sys.argv[i + 2])
self._send(self._GMSH_START, str(os.getpid))
self.action = self.get_string(self.name + '/Action', 'compute')
if self.action == "initialize": exit(0)
def __del__(self) :
if self.socket :
self._send(self._GMSH_STOP, 'Goodbye!')
self.socket.close()
Native.register(native, ./test.py);
Native.run();
#!/usr/bin/env python
#coding=utf-8
import OnelabClient
oc = OnelabClient.client()
#name and default value are required
A = oc.get_number('A', 10)
#other attributes are optionals
B = oc.get_number('Group/B', 0, min = -10, max = 10, step = 1)
C = oc.get_number('Group/C', 2, choices = [0, 1, 2, 3], attributes={'Highlight':'Pink'})
D = oc.get_number('Group/D', 2, labels = {0:'zero', 1:'un', 2:'deux', 3:'trois'}, attributes={'Highlight':'Blue'})
#utf-8 are allowed everywhere (should be prefixed by 'u' in python 2, not required in python 3)
Omega = oc.get_string(u'Ω', u'∫(∂φ/∂α)³dx', help=u'ask someone@universe.org', choices = ['oui', 'non', u'peut-être'])
if oc.action != 'compute' :
exit(0)
#this is the solver code
print (A, B, C, str(Omega))
all: _onelab.so
GMSH_DIR=../../../../
COMMON_DIR=$(GMSH_DIR)/Common
CPPFLAGS+= $(shell python-config --includes) -I$(COMMON_DIR) -DONELAB_LOADER
onelab_wrap.cpp : onelab.i
swig -python -c++ ${CPPFLAGS} -o $@ $<
_onelab.so : onelab_wrap.cpp
$(CXX) -shared onelab_wrap.cpp -o $@ $(CPPFLAGS) -fPIC -DSWIG
.PRECIOUS: $(OBJDIR)/%.o
import onelab
import sys
class client :
def get_number(self, name, default, label = '', min = -sys.float_info.max, max = sys.float_info.max, step = 0, choices = [], labels = [], attributes = {}, help = "", visible = 1, read_only = 0) :
if not self.client :
return default
n = onelab.number(name, default)
n.setLabel(label)
n.setVisible(visible)
n.setReadOnly(read_only)
n.setMin(min)
n.setMax(max)
n.setStep(step)
n.setHelp(help)
n.setChoices(choices)
if labels :
n.setChoices([k for k in labels.keys()])
n.setChoiceLabels([v for v in labels.values()])
for k,v in attributes.items() :
n.setAttribute(k, v)
r = onelab.OnelabNumberVector()
self.client.get(r, n.getName())
if r :
return r[0].getValue()
else :
self.client.set(n)
return default
def get_string(self, name, default, choices = [], help ="", label = "", visible = 1, read_only = 0, kind = "generic", attributes = {}) :
if not self.client :
return default
n = onelab.string(name, default)
n.setChoices(choices)
n.setReadOnly(read_only)
n.setVisible(visible)
n.setLabel(label)
n.setHelp(help)
n.setKind(kind)
r = onelab.OnelabStringVector()
for k,v in attributes.items() :
n.setAttribute(k, v)
self.client.get(r, n.getName())
if r :
return r[0].getValue()
else :
self.client.set(n)
return default
def __init__(self):
self.client = None
for i, v in enumerate(sys.argv) :
if v == '-onelab':
self.name = sys.argv[i + 1]
self.client = onelab.remoteNetworkClient(self.name, sys.argv[i+2])
self.action = self.get_string(self.name + '/Action', 'compute')
if self.action == "initialize": exit(0)
%module onelab
%{
#include "onelab.h"
onelab::server *onelab::server::_server = 0;
%}
%include std_string.i
%include std_vector.i
%include std_map.i
%template(OnelabNumberVector) std::vector<onelab::number>;
%template(OnelabStringVector) std::vector<onelab::string>;
%template(DoubleVector) std::vector<double>;
%template(StringVector) std::vector<std::string>;
%template(DoubleStringMap) std::map<double, std::string>;
%include "onelab.h"
../test.ol
\ No newline at end of file
../test.py
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment