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

Calculator api #45

Open
James-Crean opened this issue Apr 25, 2018 · 4 comments
Open

Calculator api #45

James-Crean opened this issue Apr 25, 2018 · 4 comments

Comments

@James-Crean
Copy link
Contributor

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:

  • While the common example is u + v, users need to be able to specify constants as well: u + 100
  • This needs to work both ways: 100 + u
  • The input should be sanitized by the backend before it is executed: u + print "should not print"
  • How will the new value be stored? For example: clt2 = clt + 100
  • vCDAT has an undo/redo feature, will this api be stateless?
    • If not, how do we make sure that the vCDAT frontend handles this fact gracefully?
  • Similar to the last question, what if a user renames a variable? clt = clt + 100. Suppose the following:
    1. The user loads and plots clt
    2. The user calculates clt = clt + 100
    3. The user plots the new versions of clt
    4. The user does not like the change and presses 'Undo' to revert the calculation
    5. The user plots clt again. Will the user see the original clt, or the modified version?

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

@scottwittenburg
Copy link
Collaborator

@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
Copy link
Contributor Author

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
Copy link
Contributor

@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
Copy link
Contributor Author

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?

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

No branches or pull requests

3 participants