Python SOAP Server
Jump to navigation
Jump to search
From Vivtek
#!/usr/bin/env python
################################################################################
#
# The Python SOAP server is a really easy way to export workflow functionality via SOAP.
# This is just the beginning; this is where we'll also be defining some WfMC interface stuff.
# More information at http://www.vivtek.com/wftk/doc/code/python
#
# Copyright (c) 2003, Vivtek, and released under the GPL, as follows:
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
################################################################################
import sys
import SOAPpy
from xmlapi import *
import repmgr
import re
#-------------------------------------------------------------------------------
if len(sys.argv) > 1:
repos = sys.argv[1]
else:
repos = 'system.defn'
try:
repository = xml_read (repos)
except:
print "Unable to read system definition file '%s'." % repos
sys.exit (1)
repmgr.open (repository, "SOAP server")
#-------------------------------------------------------------------------------
def get(list_id, key, mode='map', auth=None, task_key=None):
if mode == 'new':
key = None
if mode == 'edit' or mode == 'new' or mode == 'display':
return xml_stringcontent(repmgr.form(repository, list_id, key, mode))
if task_key==None:
defn = repmgr.defn(repository, list_id)
rec = repmgr.get(repository, list_id, key)
else:
defn = repmgr.defn(repository, "_tasks")
rec = repmgr.task_get(repository, list_id, key, task_key)
if mode == 'full':
return xml_string(rec)
if mode == 'tasks':
ret = []
tasklist = xml_create("list");
xml_set(tasklist, "id", "_tasks");
repmgr.tasks_direct(repository, rec, tasklist);
for t in xml_elements(tasklist):
rec = {}
rec['key'] = xml_attrval(t, 'id')
rec['id'] = xml_attrval(t, 'id')
rec['label'] = xml_attrval(t, 'label')
rec['user'] = xml_attrval(t, 'user')
rec['role'] = xml_attrval(t, 'role')
ret.append(rec)
return ret
# Default = 'map'
ret = {}
for f in xml_elements(rec):
if xml_is(f, 'field'):
ret[xml_attrval(f, 'id')] = xmlobj_get(rec, defn, xml_attrval(f, 'id'))
if task_key != None:
ret['key'] = xml_attrval(rec, 'key')
return ret
#-------------------------------------------------------------------------------
def list(list_id, mode='keys', auth=None):
keys = repmgr.list(repository, list_id)
#if mode ==
return keys
#-------------------------------------------------------------------------------
def build_obj(fields, fields_xml, loose_fields):
if fields_xml == None:
obj = xml_create("record")
else:
obj = xml_parse(fields_xml.decode("utf8"))
# TODO: Handle "fields"
for k in loose_fields.keys():
if re.match("^fld_", k):
name = k[4:]
xmlobj_set(obj, None, name, (loose_fields[k]).encode("latin"))
return obj
#-------------------------------------------------------------------------------
# The functions which use it are add, mod, and merge.
#-------------------------------------------------------------------------------
def add(list_id, fields=None, fields_xml=None, auth=None, **loose_fields):
obj = build_obj(fields, fields_xml, loose_fields)
repmgr.add(repository, list_id, obj)
return repmgr.getkey(repository, list_id, obj)
#-------------------------------------------------------------------------------
def mod(list_id, key, fields=None, fields_xml=None, auth=None, **loose_fields):
obj = build_obj(fields, fields_xml, loose_fields)
repmgr.merge(repository, list_id, obj, key)
return repmgr.getkey(repository, list_id, obj)
#-------------------------------------------------------------------------------
def merge(list_id, key, fields=None, fields_xml=None, auth=None, **loose_fields):
obj = build_obj(fields, fields_xml, loose_fields)
repmgr.merge(repository, list_id, obj, key)
return repmgr.getkey(repository, list_id, obj)
#-------------------------------------------------------------------------------
# From a technical standpoint, of course, deletion is rather dull.
def delete(list_id, key, auth=None):
ret = repmgr.delete(repository, list_id, key)
return ret
"""
And then we come to tasks and todo, each of which returns a list of objects, not just a simple list of keys. Those objects turn into a list of mappings on the client end.
"""
#-------------------------------------------------------------------------------
def tasks(auth=None):
ret = []
tasklist = xml_create("list");
xml_set(tasklist, "id", "_tasks");
repmgr.list(repository, tasklist);
for t in xml_elements(tasklist):
rec = {}
for f in xml_elements(t):
if xml_is(f, 'field'):
rec[xml_attrval(f, 'id')] = xmlobj_get(t, None, xml_attrval(f, 'id'))
ret.append(rec)
return ret
#-------------------------------------------------------------------------------
def todo(auth=None):
ret = []
tasklist = xml_create("list");
xml_set(tasklist, "id", "_todo");
repmgr.list(repository, tasklist);
for t in xml_elements(tasklist):
rec = {}
for f in xml_elements(t):
if xml_is(f, 'field'):
rec[xml_attrval(f, 'id')] = xmlobj_get(t, None, xml_attrval(f, 'id'))
ret.append(rec)
return ret
#-------------------------------------------------------------------------------
def auth(userid, password, mode='clear', auth=None):
return userid
#-------------------------------------------------------------------------------
# TODO: override server definitions on command line
server_url = xmlobj_getconf(repository, "config.soap.server", "localhost")
server_port = int(xmlobj_getconf(repository, "config.soap.port", "8000"))
SOAPpy.Config.debug=int(xmlobj_getconf(repository, "config.soap.debug", "0")) # Set to '1' to see everything that happens, and I mean everything.
server = SOAPpy.SOAPServer((server_url, server_port))
server.registerFunction(get)
server.registerFunction(list)
server.registerFunction(add)
server.registerFunction(mod)
server.registerFunction(merge)
server.registerFunction(delete)
server.registerFunction(tasks)
server.registerFunction(todo)
server.registerFunction(auth)
print "Listening on %s:%d for requests against %s" % (server_url, server_port, repos)
if SOAPpy.Config.debug == 1: print "Debug mode ON"
server.serve_forever() # TODO: maybe some error handling here.
#-------------------------------------------------------------------------------