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

Allow ${{}} exprs to call methods from external python modules #324

Closed
wants to merge 27 commits into from

Conversation

zebralt
Copy link

@zebralt zebralt commented Oct 23, 2020

#301

This PR adds the evaluator RemoteMethodCallEvaluator, It extends CodeEvaluator by allowing a RMC expression <module>:≤python function call> to be inserted in ${{}} expressions, which so far only accepts pure Python code.

RMC expression

A RMC expr allows you to invoke a method/function from a given python module:

${{ std:response.ok }}

The right member of the expression must either be a a raw name as above or a typical Python call:

std:response.status_is(200)
std:response.status_is(code=300, detail='jon')

std

In addition to any module name, the left member also accepts two values: the empty string and std. Those two values means the module to import from is scanapi/std.py. std.py is meant to be a standard library of methods shipped with scanapi.

For now, std is only a module, but maybe it should become a package instead to avoid putting everything into a single file.

How modules are imported

Modules are imported at evaluation time. Path resolution works the same as a regular import , i.e to import a local module you'll need to have it in your current working directory.

How functions are called

The function is imported from its module, then

  • if args/kwargs were provided in the right member of the RMC expr, they are bound to the function using functools.partial;
  • the RMC evaluator attempts to feed vars to the function as efficiently as possible here, in the following order:
    • if the function's spec can be inspected, the evaluator tries to see which names the function expects and feeds it only these, e.g.
vars = {'response': ResponseObject(), 'ids': [...]}
def response_ok(response):
    return response.status == 200
call_against_vars(f, (), {}, vars)  # will only send vars['response'] to response_ok
  • if there is no key in the spec that can be correlated with vars's keys, an exception is raised.
  • if the spec cannot be inspected (such is the case of builtins), vars is fed as a single positional argument to the function.
  • if the spec has a vars argument, vars is fed as a keyword argument under that name.

#301 suggested that vars be fed implicitly to the function, but there may be a case for doing it explicitly instead; the right member is parsed using the ast module, and we could use it to parse name arguments as well; that wouldn't be too much of a stretch:

${{ std:response_ok(response) }}  # search for 'response' name in vars

@zebralt zebralt requested review from a team as code owners October 23, 2020 20:35
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for supporting ScanAPI, and congratulations on your first contribution! A project committer will shortly review your contribution.

In the mean time, if you haven't had a chance please skim over the First Pull Request Guide which all pull requests must adhere to.

We hope to see you around!

@github-actions github-actions bot added the First Contribution First contribution to the project. label Oct 23, 2020
@zebralt
Copy link
Author

zebralt commented Oct 27, 2020

Weird, my local black setup gives a completely different result ...

would reformat scanapi\scanapi\__main__.py
would reformat scanapi\scanapi\hide_utils.py
would reformat scanapi\scanapi\reporter.py
would reformat scanapi\scanapi\scan.py
would reformat scanapi\scanapi\settings.py
would reformat scanapi\scanapi\utils.py
would reformat scanapi\scanapi\tree\request_node.py

@hebertjulio
Copy link
Member

Hey @camilamaia

This month i will take a vacation, and after i can work at this PR if necessary.

@camilamaia
Copy link
Member

@hebertjulio perfect! It would help a lot. Have a great vacation!

Copy link
Member

@camilamaia camilamaia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zebralt Sorry for the HUGE delay with this PR. This is a complex issue that you made a great effort to tackle.

We are trying to bring it back now. I am solving the conflicts and the format issues. @jlugao will help us testing it. @zebralt let me know if you also want to keep working on it.

scanapi/evaluators/rmc_evaluator.py Outdated Show resolved Hide resolved
scanapi/evaluators/rmc_evaluator.py Outdated Show resolved Hide resolved
scanapi/evaluators/rmc_evaluator.py Outdated Show resolved Hide resolved
scanapi/evaluators/rmc_evaluator.py Outdated Show resolved Hide resolved
tests/unit/evaluators/test_rmc_evaluator.py Show resolved Hide resolved
tests/unit/evaluators/test_rmc_evaluator.py Outdated Show resolved Hide resolved
tests/unit/evaluators/test_rmc_evaluator.py Outdated Show resolved Hide resolved
tests/unit/evaluators/test_rmc_evaluator.py Outdated Show resolved Hide resolved
tests/unit/evaluators/test_rmc_evaluator.py Outdated Show resolved Hide resolved
tests/unit/evaluators/test_rmc_evaluator.py Outdated Show resolved Hide resolved
@camilamaia
Copy link
Member

@jlugao I solved all conflicts 👌 It is still failing in some static analysis (https://github.com/scanapi/scanapi/pull/324/checks?check_run_id=3433068011 and https://github.com/scanapi/scanapi/pull/324/checks?check_run_id=3433067531) but we can tackle them later, before merging the PR.

I believe it is all good now for you to test it. As a guide, I would suggest you:

Let me know how it goes! I can help with any blocker :) Also, feel free to join our discord server https://discord.scanapi.dev if you want some help via chat

@camilamaia
Copy link
Member

Sorry, closing this PR for now since there was no recent activity 🧹 If you want to update it, feel free to reopen it.

@camilamaia camilamaia closed this Feb 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
First Contribution First contribution to the project.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants