solvebio-python icon indicating copy to clipboard operation
solvebio-python copied to clipboard

Ability to compose a template via subclass

Open davecap opened this issue 5 years ago • 0 comments

Adds the ability to define templates as (very limited) classes rather than JSON. The main benefit is making it easier to create unit tests, and to write expressions with syntax highlighting.

Example of a template with pytest tests:

import solvebio as sb

sb.login(api_host="https://solvebio.api.solvebio.com")


class MyTemplate(sb.DatasetTemplate):
    # Define all field parameters in the decorator
    @sb.DatasetTemplate.field(is_transient=True)
    def hello(self, record):
        # NOTE: Use comments instead of docstrings, as docstrings are interpreted as expressions.
        # returns are optional, but can be helpful for unit testing
        return "hello"

    @sb.DatasetTemplate.field(depends_on=["hello"])
    def world(self, record):
        # Functions must be "one-liner" expressions, but can have line-breaks.
        return (
            record.hello +
            ' world'
        )

    # Functions must be one-liner expressions!
    # @sb.DatasetTemplate.field()
    # def invalid(self, record):
    #     if 1 + 1 == 2:
    #         return "this is an invalid expression"


def test_template_e2e():
    tpl = MyTemplate()

    assert len(tpl.fields) == 2

    ann = sb.Annotator(tpl.fields).annotate([{}])
    for row in ann:
        assert row.get('hello') is None
        assert row['world'] == 'hello world'


def test_hello():
    tpl = MyTemplate()

    assert tpl.hello(record={}) == 'hello'


def test_evaluate_fields():
    tpl = MyTemplate()
    assert tpl.hello.field.evaluate() == 'hello'
    # TODO: record support
    # assert tpl.world.field.evaluate(record={'hello': 'hello'}) == 'hello world'


if __name__ == "__main__":
    # TODO: get_or_create() does not work yet, coming soon!
    m = MyTemplate.get_or_create(
        name="My Template",
        version="1.0.0-beta.1"
    )
    print(m)

davecap avatar May 24 '20 14:05 davecap