Extensions

agate’s core featureset is designed rely on as few dependencies as possible. However, in the real world you’re often going to want to interface agate with SQL, numpy or other data processing tools.

How extensions work

In order to support these use-cases, but not make things excessively complicated, agate support’s a simple extensibility pattern based on monkey patching. Libraries can be created that patch new methods onto Table and TableSet. For example, agate-sql adds the ability to read and write tables from a SQL database:

import agate
import agatesql

agatesql.patch()

# After calling patch the from_sql and to_sql methods are now part of the Table class
table = agate.Table.from_sql('postgresql:///database', 'input_table')
table.to_sql('postgresql:///database', 'output_table')

List of extensions

Here is a list of actively supported agate extensions:

Writing your own extensions

Writing your own extensions is straightforward. Create a class that acts as your “patch” and when you call Table.monkeypatch() it will dynamically be added as a base class of Table.

import agate

class ExamplePatch(object):
    def new_method(self):
        print('I do something to a Table when you call me.')

Then create a function that applies your patch:

def patch()
    agate.Table.monkeypatch(ExamplePatch)

The Table class will now have all the methods of ExamplePatch as though they were defined as part of it.

>>> import agate
>>> import myextension
>>> myextension.patch()
>>> table = agate.Table(rows, column_names, column_types)
>>> table.new_method()
'I do something to a Table when you call me.'

The same pattern also works for adding methods to TableSet.

Warning

Extensions are added as base classes of Table so you can not use them to override the implementation of an existing method. They are perfect for adding features, but if you need to actually modify how agate works, then you’ll need to use a subclass. Any shadowed method will be ignored.