Examples

Reusing functions by dependencies

import siringa


@siringa.register
def mul(x, y):
    return x * y


@siringa.register
def mul2(x, mul: '!mul'):
    return mul(x, 2)


@siringa.register
def pow2(x):
    return x ** 2


@siringa.inject
def compute(x, pow: '!pow2', mul: '!mul2'):
    return pow(mul(x))


print('Result:', compute(2))  # => 16

Invoke function with automatic dependency injection

import siringa


@siringa.register
def mul2(x):
    return x * 2


# Note that the function was not instrumented yet!
def compute(x, mul: '!mul2'):
    return mul(x)


# Invoke function
print('Result:', siringa.invoke(compute, 2))

Create a custom dependency container

import siringa

# Create a custom dependency layer
layer = siringa.Layer('app')

# Then you can use the standard API
layer.register('print', print)


# Then you can use the standard API
@layer.inject
def mul2(x, print: '!'):
    print('Argument:', x)
    return x * 2


print('Result:', mul2(2))

Custom layer with parent inheritance

import siringa


# Create parent dependency layer
parent = siringa.Layer('parent')

# Create child dependency layer that inherits from parent
child = siringa.Layer('child', parent)


# Register a sample dependency within parent container
@parent.register
def mul2(x):
    return x * 2


# Verify that the dependency is injectable from child layer
print('Is injectable from parent:', parent.is_injectable('mul2'))
print('Is injectable from child:', child.is_injectable('mul2'))


@child.inject
def compute(x, mul: '!mul2'):
    return mul(x)


print('Result:', compute(2))

Injection flag based annotations

import siringa


@siringa.register
def foo():
    return 'foo'


# Use '!' flag for DRYer dependency injection
# Argument name expression will be used for dependency pattern matching
@siringa.inject
def bar(foo: '!'):
    return foo()


assert bar() == foo()
print('Succeeded!')

Mocking dependencies

import siringa


@siringa.register
class DB(object):
    def query(self, sql):
        return ['john', 'mike']


@siringa.mock('DB')
class DBMock(object):
    def query(self, sql):
        return ['foo', 'bar']


@siringa.inject
def run(sql, db: '!DB'):
    return db().query(sql)


# Test mock call
assert run('SELECT name FROM foo') == ['foo', 'bar']

# Once done, clear the mock
siringa.unregister_mock('DB')

# Or alternatively clear all the registed mocks within the container
siringa.clear_mocks()

# Test read call
assert run('SELECT name FROM foo') == ['john', 'mike']