<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://performiq.com/kb/index.php?action=history&amp;feed=atom&amp;title=Python_SOAP_Server</id>
	<title>Python SOAP Server - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://performiq.com/kb/index.php?action=history&amp;feed=atom&amp;title=Python_SOAP_Server"/>
	<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Python_SOAP_Server&amp;action=history"/>
	<updated>2026-05-18T11:36:22Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://performiq.com/kb/index.php?title=Python_SOAP_Server&amp;diff=2036&amp;oldid=prev</id>
		<title>PeterHarding: New page: =From Vivtek=  &lt;pre&gt; #!/usr/bin/env python  ################################################################################ # # The Python SOAP server is a really easy way to export workf...</title>
		<link rel="alternate" type="text/html" href="https://performiq.com/kb/index.php?title=Python_SOAP_Server&amp;diff=2036&amp;oldid=prev"/>
		<updated>2008-05-01T11:04:09Z</updated>

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