diff --git a/xos/grpc/apihelper.py b/xos/grpc/apihelper.py
new file mode 100644
index 0000000..bf128c2
--- /dev/null
+++ b/xos/grpc/apihelper.py
@@ -0,0 +1,154 @@
+import base64
+import time
+from protos import xos_pb2
+from google.protobuf.empty_pb2 import Empty
+
+from django.contrib.auth import authenticate as django_authenticate
+from core.models import *
+from xos.exceptions import *
+
+class XOSAPIHelperMixin(object):
+    def getProtoClass(self, djangoClass):
+        pClass = getattr(xos_pb2, djangoClass.__name__)
+        return pClass
+
+    def getPluralProtoClass(self, djangoClass):
+        pClass = getattr(xos_pb2, djangoClass.__name__ + "s")
+        return pClass
+
+    def convertFloat(self, x):
+        if not x:
+            return 0
+        else:
+            return float(x)
+
+    def convertDateTime(self, x):
+        if not x:
+            return 0
+        else:
+            return time.mktime(x.timetuple())
+
+    def convertForeignKey(self, x):
+        if not x:
+            return 0
+        else:
+            return int(x.id)
+
+    def objToProto(self, obj):
+        p_obj = self.getProtoClass(obj.__class__)()
+        for field in obj._meta.fields:
+            if getattr(obj, field.name) == None:
+                continue
+
+            ftype = field.get_internal_type()
+            if (ftype == "CharField") or (ftype == "TextField") or (ftype == "SlugField"):
+                setattr(p_obj, field.name, str(getattr(obj, field.name)))
+            elif (ftype == "BooleanField"):
+                setattr(p_obj, field.name, getattr(obj, field.name))
+            elif (ftype == "AutoField"):
+                setattr(p_obj, field.name, int(getattr(obj, field.name)))
+            elif (ftype == "IntegerField") or (ftype == "PositiveIntegerField"):
+                setattr(p_obj, field.name, int(getattr(obj, field.name)))
+            elif (ftype == "ForeignKey"):
+                setattr(p_obj, field.name+"_id", self.convertForeignKey(getattr(obj, field.name)))
+            elif (ftype == "DateTimeField"):
+                setattr(p_obj, field.name, self.convertDateTime(getattr(obj, field.name)))
+            elif (ftype == "FloatField"):
+                setattr(p_obj, field.name, float(getattr(obj, field.name)))
+            elif (ftype == "GenericIPAddressField"):
+                setattr(p_obj, field.name, str(getattr(obj, field.name)))
+        return p_obj
+
+    def protoToArgs(self, djangoClass, message):
+        args={}
+        fmap={}
+        fset={}
+        for field in djangoClass._meta.fields:
+            fmap[field.name] = field
+            if field.get_internal_type() == "ForeignKey":
+               # foreign key can be represented as an id
+               fmap[field.name + "_id"] = field
+
+        for (fieldDesc, val) in message.ListFields():
+            name = fieldDesc.name
+            if name in fmap:
+                if (name=="id"):
+                    # don't let anyone set the id
+                    continue
+                ftype = fmap[name].get_internal_type()
+                if (ftype == "CharField") or (ftype == "TextField") or (ftype == "SlugField"):
+                    args[name] = val
+                elif (ftype == "BooleanField"):
+                    args[name] = val
+                elif (ftype == "AutoField"):
+                    args[name] = val
+                elif (ftype == "IntegerField") or (ftype == "PositiveIntegerField"):
+                    args[name] = val
+                elif (ftype == "ForeignKey"):
+                    args[name] = val # field name already has "_id" at the end
+                elif (ftype == "DateTimeField"):
+                    pass # do something special here
+                elif (ftype == "FloatField"):
+                    args[name] = val
+                elif (ftype == "GenericIPAddressField"):
+                    args[name] = val
+                fset[name] = True
+
+        return args
+
+    def querysetToProto(self, djangoClass, queryset):
+        objs = queryset
+        p_objs = self.getPluralProtoClass(djangoClass)()
+
+        for obj in objs:
+           new_obj = p_objs.items.add()
+           new_obj.CopyFrom(self.objToProto(obj))
+
+        return p_objs
+
+    def get(self, djangoClass, id):
+        obj = djangoClass.objects.get(id=id)
+        return self.objToProto(obj)
+
+    def create(self, djangoClass, user, request):
+        args = self.protoToArgs(djangoClass, request)
+        new_obj = djangoClass(**args)
+        new_obj.caller = user
+        if (not user) or (not new_obj.can_update(user)):
+            raise XOSPermissionDenied()
+        new_obj.save()
+        return self.objToProto(new_obj)
+
+    def update(self, djangoClass, user, id, message):
+        obj = djangoClass.objects.get(id=id)
+        obj.caller = user
+        if (not user) or (not obj.can_update(user)):
+            raise XOSPermissionDenied()
+        args = self.protoToArgs(djangoClass, message)
+        for (k,v) in args.iteritems():
+            setattr(obj, k, v)
+        obj.save()
+        return self.objToProto(obj)
+
+    def delete(self, djangoClass, user, id):
+      obj = djangoClass.objects.get(id=id)
+      if (not user) or (not obj.can_update(user)):
+          raise XOSPermissionDenied()
+      obj.delete()
+      return Empty()
+
+    def authenticate(self, context):
+        for (k, v) in context.invocation_metadata():
+            if (k.lower()=="authorization"):
+                (method, auth) = v.split(" ",1)
+                if (method.lower() == "basic"):
+                    auth = base64.b64decode(auth)
+                    (username, password) = auth.split(":")
+                    user = django_authenticate(username=username, password=password)
+                    if not user:
+                        raise Exception("failed to authenticate %s:%s" % (username, password))
+                    print "authenticated %s:%s as %s" % (username, password, user)
+                    return user
+
+        return None
+
diff --git a/xos/tools/apigen/grpc_api.template.py b/xos/tools/apigen/grpc_api.template.py
index ddd2b77..9e23db5 100644
--- a/xos/tools/apigen/grpc_api.template.py
+++ b/xos/tools/apigen/grpc_api.template.py
@@ -6,159 +6,15 @@
 from django.contrib.auth import authenticate as django_authenticate
 from core.models import *
 from xos.exceptions import *
+from apihelper import XOSAPIHelperMixin
 
-class XosService(xos_pb2.xosServicer):
+class XosService(xos_pb2.xosServicer, XOSAPIHelperMixin):
     def __init__(self, thread_pool):
         self.thread_pool = thread_pool
 
     def stop(self):
         pass
 
-    def getProtoClass(self, djangoClass):
-        pClass = getattr(xos_pb2, djangoClass.__name__)
-        return pClass
-
-    def getPluralProtoClass(self, djangoClass):
-        pClass = getattr(xos_pb2, djangoClass.__name__ + "s")
-        return pClass
-
-    def convertFloat(self, x):
-        if not x:
-            return 0
-        else:
-            return float(x)
-
-    def convertDateTime(self, x):
-        if not x:
-            return 0
-        else:
-            return time.mktime(x.timetuple())
-
-    def convertForeignKey(self, x):
-        if not x:
-            return 0
-        else:
-            return int(x.id)
-
-    def objToProto(self, obj):
-        p_obj = self.getProtoClass(obj.__class__)()
-        for field in obj._meta.fields:
-            if getattr(obj, field.name) == None:
-                continue
-
-            ftype = field.get_internal_type()
-            if (ftype == "CharField") or (ftype == "TextField") or (ftype == "SlugField"):
-                setattr(p_obj, field.name, str(getattr(obj, field.name)))
-            elif (ftype == "BooleanField"):
-                setattr(p_obj, field.name, getattr(obj, field.name))
-            elif (ftype == "AutoField"):
-                setattr(p_obj, field.name, int(getattr(obj, field.name)))
-            elif (ftype == "IntegerField") or (ftype == "PositiveIntegerField"):
-                setattr(p_obj, field.name, int(getattr(obj, field.name)))
-            elif (ftype == "ForeignKey"):
-                setattr(p_obj, field.name+"_id", self.convertForeignKey(getattr(obj, field.name)))
-            elif (ftype == "DateTimeField"):
-                setattr(p_obj, field.name, self.convertDateTime(getattr(obj, field.name)))
-            elif (ftype == "FloatField"):
-                setattr(p_obj, field.name, float(getattr(obj, field.name)))
-            elif (ftype == "GenericIPAddressField"):
-                setattr(p_obj, field.name, str(getattr(obj, field.name)))
-        return p_obj
-
-    def protoToArgs(self, djangoClass, message):
-        args={}
-        fmap={}
-        fset={}
-        for field in djangoClass._meta.fields:
-            fmap[field.name] = field
-            if field.get_internal_type() == "ForeignKey":
-               # foreign key can be represented as an id
-               fmap[field.name + "_id"] = field
-
-        for (fieldDesc, val) in message.ListFields():
-            name = fieldDesc.name
-            if name in fmap:
-                if (name=="id"):
-                    # don't let anyone set the id
-                    continue
-                ftype = fmap[name].get_internal_type()
-                if (ftype == "CharField") or (ftype == "TextField") or (ftype == "SlugField"):
-                    args[name] = val
-                elif (ftype == "BooleanField"):
-                    args[name] = val
-                elif (ftype == "AutoField"):
-                    args[name] = val
-                elif (ftype == "IntegerField") or (ftype == "PositiveIntegerField"):
-                    args[name] = val
-                elif (ftype == "ForeignKey"):
-                    args[name] = val # field name already has "_id" at the end
-                elif (ftype == "DateTimeField"):
-                    pass # do something special here
-                elif (ftype == "FloatField"):
-                    args[name] = val
-                elif (ftype == "GenericIPAddressField"):
-                    args[name] = val
-                fset[name] = True
-
-        return args
-
-    def querysetToProto(self, djangoClass, queryset):
-        objs = queryset
-        p_objs = self.getPluralProtoClass(djangoClass)()
-
-        for obj in objs:
-           new_obj = p_objs.items.add()
-           new_obj.CopyFrom(self.objToProto(obj))
-
-        return p_objs
-
-    def get(self, djangoClass, id):
-        obj = djangoClass.objects.get(id=id)
-        return self.objToProto(obj)
-
-    def create(self, djangoClass, user, request):
-        args = self.protoToArgs(djangoClass, request)
-        new_obj = djangoClass(**args)
-        new_obj.caller = user
-        if (not user) or (not new_obj.can_update(user)):
-            raise XOSPermissionDenied()
-        new_obj.save()
-        return self.objToProto(new_obj)
-
-    def update(self, djangoClass, user, id, message):
-        obj = djangoClass.objects.get(id=id)
-        obj.caller = user
-        if (not user) or (not obj.can_update(user)):
-            raise XOSPermissionDenied()
-        args = self.protoToArgs(djangoClass, message)
-        for (k,v) in args.iteritems():
-            setattr(obj, k, v)
-        obj.save()
-        return self.objToProto(obj)
-
-    def delete(self, djangoClass, user, id):
-      obj = djangoClass.objects.get(id=id)
-      if (not user) or (not obj.can_update(user)):
-          raise XOSPermissionDenied()
-      obj.delete()
-      return Empty()
-
-    def authenticate(self, context):
-        for (k, v) in context.invocation_metadata():
-            if (k.lower()=="authorization"):
-                (method, auth) = v.split(" ",1)
-                if (method.lower() == "basic"):
-                    auth = base64.b64decode(auth)
-                    (username, password) = auth.split(":")
-                    user = django_authenticate(username=username, password=password)
-                    if not user:
-                        raise Exception("failed to authenticate %s:%s" % (username, password))
-                    print "authenticated %s:%s as %s" % (username, password, user)
-                    return user
-
-        return None
-
-
 {% for object in generator.all() %}
     def List{{ object.camel() }}(self, request, context):
       user=self.authenticate(context)
