This is what to do when creating a custom transfer.

All custom tranfer

All transfers is based on return a repository that can handle table data. To do this a getrepo is called to return an instance of the repository that will read, return and update data in a source. All data in DG3 transfer is looked at as table data, so if you read or write data to xml, JSON, SOAP or similar, you must create table data in the source and create from records in target.

# The getrepo definition you must use
def getrepo(ctx=None):
	return MyRepo(ctx=ctx)

Custom source

In the custom source you need to return a TableDef from gettdf, and return records from an iterator. You must also descend from RepoBase and SourceBase. This will make sure you have the base functionality needed for a no table based source. The custom source do not read any definitions from the filters. This must all be done in your code. The only thing that is sent from the server is the context (ctx) the transfer is run. This might be a page context, task context or any other place where a transfer can be used. You also have the possibility to use the "Test context" to send parameters to your transfer during a test run. This is done bey setting a string in query form like field=value&field2=value2 etc. This comes as the ctx as a dict where fields are keys and values are the dicts values.

from debdata import TableDef, FieldDef, Record, RepoBase, SourceBase, TargetBase, gettypefromtext

def getrepo(ctx=None):
    return SourceRepo(ctx=ctx)

class SourceRepo(RepoBase,SourceBase):
    def __init__(self,ctx = None):
        self.max = 100 # maximum records to return

    def gettdf(self,name):
        self.tdf = TableDef(name='MySource',type=TableDef.REPOTYPE.TABLE)
        flddef = FieldDef(name='Name',type=FieldDef.FIELDTYPE.TEXT)
        flddef = FieldDef(name='EMail',type=FieldDef.FIELDTYPE.TEXT)
        return self.tdf

    def getsource(self,tdf=None,filter=None):
        return self

    def __iter__(self):
        self.row = -1
        self.internaldata=[['My name',''],]
        return self

    def next(self):
        if len(self.internaldata)>self.row and self.row < self.max:
            rec = Record(self.row,self.tdf,fields)
            return rec
            raise StopIteration

    def cleanup(self):

The first part is to simulate a repository and return a TDF. You can add as many field as you intend to return in your record iterator by creating a TableDef and then add all the fields you need of the type you intend to return to your target. In this example we added two text fields, Name and EMail. Then you return the source object. This is the object you will iterate over when return records. In a custom source, this is usually it self as this is where you also will create the iterator. Then you create the iterator to return one record at the time. Each record returned should also hold the correct row number and be returned as a Record class.At last you need a cleanup method that closes down sources and clean up memory use.

That's it for a custom source. You can use whatever python library and code you need to extract the data from your source.

Custom target

The custom target must define an updaterecord.

Testing in external debugger

The python editor in DG3 is not much good for debugging your code yet. To do this, you are better of using an external debugger that is set up to run the DG3 environment. Make sure you add the paths to the DG3 runtime libraries before in your debugger. These can be found in path to DG3 executables + DE4Web (ex. "C:\Program Files (x86)\DG3\DE4Web")

Add this code to the end of your custom Source to read all data and write it to console:

if __name__ == '__main__':
    repo = getrepo()
    heading = []
    for field in repo.gettdf('GetData'):
    print heading
    for rec in repo:
        recarr = []
        for field in rec:
        print recarr

More to come