-
Notifications
You must be signed in to change notification settings - Fork 22
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
Decouple scripts from WorkContext #609
Conversation
95363d6
to
6f5fcfd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't check the tests. I will do this later.
I have a general remark I think we might need to discuss. I really dislike the documentation being duplicated between yapapi.script.command.X
and yapapi.script.Script.x
. This is hard to maintain: docs will be changing and it's hard to keep such things in sync. Also, I double-dislike duplicated logic, like in run
(I added a separate comment for this).
I think all those functions should look like this:
def run(self, *args, **kwargs):
'''Arguments are passed to command.Run(). Returns awaitable ...'''
return self.add(Run(*args, **kwargs))
This is clear. This is easy to maintain. If we have links in docs (as Filip suggested), this wouldn't even make it much harder to read.
Also: chapeau bas for finding a path through all of this stuff!
Co-authored-by: johny-b <[email protected]>
7dd990d
to
5378db3
Compare
While I agree on the part about not duplicating docstrings I'm not convinced about having these methods accept @johny-b What's your take on this? |
Are sure about this? Anyway, that's not really important because ...
... I think you're right. |
tests/script/test_script.py
Outdated
|
||
@pytest.fixture | ||
def work_context(self): | ||
return WorkContext(mock.MagicMock(), mock.MagicMock(), storage=mock.AsyncMock()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, I think this could be converted into a factoryboy factory so that it's reusable anywhere else where we'd like to have a mock WorkContext....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 53d23eb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally, looks good as far as I could tell... adding a few non-critical comments
tests/script/test_script.py
Outdated
@staticmethod | ||
def _assert_dst_path(script: Script, dst_path): | ||
batch = script._evaluate() | ||
# transfer_cmd = {'transfer': {'from': 'some/mock/path', 'to': 'container:expected/path'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leftover cruft?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually a helper comment to show what transfer_cmd
should look like. I see how it can be confusing, I'm going to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in 53d23eb
tests/script/test_script.py
Outdated
@staticmethod | ||
def _assert_src_path(script: Script, src_path): | ||
batch = script._evaluate() | ||
# transfer_cmd = {'transfer': {'from': 'container:expected/path', 'to': 'some/mock/path'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leftover cruft?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in 53d23eb
tests/test_ctx.py
Outdated
assert c.commands().pop()["transfer"]["to"] == f"container:{dst_path}" | ||
def _assert_dst_path(script: Script, dst_path): | ||
batch = script._evaluate() | ||
# transfer_cmd = {'transfer': {'from': 'some/mock/path', 'to': 'container:expected/path'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same leftover cruft...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not cruft!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed anyway in 53d23eb
tests/test_ctx.py
Outdated
assert c.commands().pop()["transfer"]["from"] == f"container:{src_path}" | ||
def _assert_src_path(script: Script, src_path): | ||
batch = script._evaluate() | ||
# transfer_cmd = {'transfer': {'from': 'container:expected/path', 'to': 'some/mock/path'} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same leftover cruft...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed in 53d23eb
yapapi/script/__init__.py
Outdated
"""Schedule a Terminate command on the provider.""" | ||
return self.add(Terminate()) | ||
|
||
def send_json(self, data: dict, dst_path: str) -> Awaitable[CommandExecuted]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be upload_json
to better correspond with download_json
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed in 4741009
yapapi/script/__init__.py
Outdated
""" | ||
return self.add(SendBytes(data, dst_path)) | ||
|
||
def send_file(self, src_path: str, dst_path: str) -> Awaitable[CommandExecuted]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be upload_file
to better correspond with download_file
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed in 4741009
steps = self._pending_steps | ||
self._pending_steps = [] | ||
return Steps(*steps, timeout=timeout) | ||
assert self.__script._commands, "commit called with no commands scheduled" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm.... maybe it's not a bad thing per se? ... I mean, maybe there should be a way to vary commands run within an exescript from 0 to n ? ... it would make it simpler to create scripts based on variable number of elements - the client code wouldn't have to vary here and just process_batches
would step over such a script without actually sending anything to the provider...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, though I'm thinking of potential debugging issues here (someone sending an empty script by mistake). Perhaps we should print a warning in process_batches
whenever an empty script is encountered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
printing a warning is perfect! thanks :)
Co-authored-by: shadeofblue <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job!
There's one more thing I don't understand, I left a commit suggestion.
Also: please take a look at
#641
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I like the result : )
Resolves #564, #261
Public API changes
script/__init__.py#Script
) which replaces direct command calls on theWorkContext
.WorkContext
have been marked as deprecated in version0.7.0
.WorkContext
now includes anew_script
method which returns an instance ofScript
bound to the givenWorkContext
instance.Script
(e.g.run
,send_json
or directadd
call) now returns an awaitable which, once the script is executed, will contain the event with the result of that particular command.Other changes
Script
is now used as the expectedyield
type from worker functions.CommandContainer
,Steps
andExecOptions
classes. Their former responsibilities are now fulfilled byScript
(i.e. storing commands, defining options for a batch and serializing a series of commands for transfer to the provider).Run
,SendJson
) have been moved toscript/command.py
. They have a new common base class (Command
) with a new interface (after
,before
,evaluate
).TODO (optional, perhaps as separate PRs)
Script
instances instead of calls toWorkContext
0.6.0
?