CDAT / vcs-js

3 stars 3 forks source link

Calculator api #45

Open James-Crean opened 6 years ago

James-Crean commented 6 years ago

We need an api for calculations on variables. To start out we are looking to support '+', '-', '*', '/', 'power', and 'regrid'.

From vCDAT's perspective, the user will be able to select a variable/value, an operation, and another variable/value. They also have the ability to specify a variable name to store the result in.

Here are a few issues I can think of off the top of my head:

@scottwittenburg and @doutriaux1 let me know your thoughts and ideas.

scottwittenburg commented 6 years ago

@James-Crean I'm not clear on this issue if you're waiting for me to take some action, or if you have it under control for the time being. Last time we chatted, I thought this was going to end up being mostly a pass-through functionality in vcs-js. Specifically, I think you were going to generate calculator expressions in the client and we would just let vcs and friends evaluate them.

Let me know if this is not the case, or you think we need to discuss a bit more.

ping @danlipsa @aashish24 @doutriaux1

James-Crean commented 6 years ago

At the end of our last meeting it was undecided if we should use Sam's compute graph or if we should send python strings. Once a solution is agreed upon we can begin to work toward designing the API.

You are correct in thinking that vcs-js will be doing most of the work. The core idea is that the frontend should only be storing a set of actions/operations. These actions should be sent with a plot request, and vcs-js will execute these actions and manipulate the data before plotting.

The reason we need the series of commands to be executed on the fly is so that the undo/redo functionality works, as well as allowing users the convenience of saving and loading what they are doing.

danlipsa commented 6 years ago

@James-Crean you mentioned that we should parse the expression before we eval it for security reasons. I think this is a valid concern and we should do it. Not sure what parser we should use for that.

Do you need parsing for anything else in the front-end? What do you need to do for an undo operation? I assume you need to remove the temporary variable created. Anything else?

James-Crean commented 6 years ago

The undo/redo library on the frontend is not very flexible. Neither redux nor the undo library provide hooks/events to allow me to run code before/after the undo action is resolved. The general idea is that these state changes should be "pure" (Without side effects). Because of this, an undo action is very simple. We keep an array of previous states. When an action that would change the current state is dispatched, a copy of the state is made. The old copy is saved in the "previous" array and the new copy is mutated in a pure manner. The frontend then renders the current state again.

I am still wary of eval'ing python strings. My understanding was that allowing any sort of web service that would run arbitrary python code from users would be almost impossible to get approved by security. It would also defeat the purpose of having a "calculator" since we could just provide a pseudo python interpreter.

A cursory glance at stack overflow yields: https://stackoverflow.com/questions/3513292/python-make-eval-safe?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

From what I can tell, there are alternatives and workarounds, but it gets into parsing grammars and abstract syntax trees. There is a function ast.literal_eval, but It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing

Is there a better/simpler method of making it secure that I don't know about?