Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block decorator #5

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Conversation

elbasti
Copy link

@elbasti elbasti commented May 8, 2015

I added a decorator function to the module. This function should help avoid boilerplate code.
Imagine that a user has a function:

def foo(bar):
    return bar

They can now copy that directly into blockspring by simply using the decorator:

@blockspring.decorate
def foo(bar):
    return bar
blockspring.define(foo)

No need to change the function name, arguments or add blockspring boilerplate code!
The decorator will find the names of the arguments and transform foo into:

def foo(request, response):
    bar = request.params['bar']
    output = foo(bar)
    response.addOutput('output', output)

Sebastian Villarreal and others added 3 commits May 5, 2015 19:23
@jtokoph
Copy link
Member

jtokoph commented May 8, 2015

First: This is awesome:exclamation:

Second: One bug I noticed is that response.end should be response.end() at this line

Third: This works perfectly for a function that has one return value. I wonder how we could extend this for functions that have multiple outputs. Here is a basic example:

test-math.py

import blockspring

def mathstuff(request, response):
    x = request.params['x']
    y = request.params['y']

    response.addOutput('sum', x + y)
    response.addOutput('difference', x - y)
    response.addOutput('product', x * y)
    response.addOutput('quotient', x / y)

    response.end()

blockspring.define(mathstuff)

Sample output

$ echo '{ "x": 10, "y": 5 }' | python test-math.py | json_pp
{
   "_blockspring_spec" : true,
   "product" : 50,
   "sum" : 15,
   "difference" : 5,
   "_errors" : [],
   "quotient" : 2
}

One idea is to allow the decorator to include name arguments where the names map to items in a returned list:

import blockspring

@blockspring.decorate("sum", "difference", "product", "quotient")
def mathstuff(x, y):
    return [x + y, x - y, x * y, x / y]

blockspring.define(mathstuff)

Another option might be detecting dict returns and adding the corresponding outputs:

import blockspring

@blockspring.decorate
def mathstuff(x, y):
    return { "sum": x + y, "difference": x - y, "product": x * y, "quotient": x / y }

blockspring.define(mathstuff)

@elbasti
Copy link
Author

elbasti commented May 8, 2015

I think multiple returns is a lesser concern, since they aren't allowed in a typical python function anyway.
I'm thinking a possible solution is to always serialize the output into json before returning it (ie, always return json).

This would work because json.dumps('foo'), json.dumps(['foo','bar']) and json.dumps[{'foo':'bar'}] are all valid.

We're checking for json.loads when we receive arguments anyway.

Sebastian Villarreal added 3 commits May 8, 2015 16:53
@elbasti
Copy link
Author

elbasti commented May 9, 2015

I added tests to test against multiple outputs--it worked without having to make a single change, because you're serializing output in Response.end().

Try it!

@pkpp1233
Copy link
Contributor

This is a great idea. Removing this barrier to creating a blockspring function is amazing. Ok let me list out all the things the library does now, so we make sure we know what we still enable here / are losing:

  • Can it support a caching flag?
  • Do multiple inputs work?
  • Do we lose the ability to output errors? (response.addErrorOutput)
  • What about outputting files? (response.addFileOutput)
  • Any way to pass an API key?

... i think that's it!

@elbasti
Copy link
Author

elbasti commented May 12, 2015

Ok, that sounds like the beginnings of a (very necessary) test suite.

I'll start that suite and pull-request it in a separate request. That way we can all rebase our pull requests and make sure tests pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants