Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
flamenco-worker-python
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
blender
flamenco-worker-python
Commits
4cea32d8
Commit
4cea32d8
authored
6 years ago
by
Sybren A. Stüvel
Browse files
Options
Downloads
Patches
Plain Diff
Stricter type declarations in `commands.py`
parent
45cd62b5
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
flamenco_worker/commands.py
+33
-26
33 additions, 26 deletions
flamenco_worker/commands.py
with
33 additions
and
26 deletions
flamenco_worker/commands.py
+
33
−
26
View file @
4cea32d8
...
@@ -22,6 +22,12 @@ from . import worker
...
@@ -22,6 +22,12 @@ from . import worker
command_handlers
=
{}
# type: typing.Mapping[str, typing.Type['AbstractCommand']]
command_handlers
=
{}
# type: typing.Mapping[str, typing.Type['AbstractCommand']]
# Some type declarations.
Settings
=
typing
.
MutableMapping
[
str
,
typing
.
Any
]
# This is the type of the 2nd arg for instanceof(a, b)
InstanceOfType
=
typing
.
Union
[
type
,
typing
.
Tuple
[
typing
.
Union
[
type
,
typing
.
Tuple
[
typing
.
Any
,
...]],
...]]
# Timeout of subprocess.stdout.readline() call.
# Timeout of subprocess.stdout.readline() call.
SUBPROC_READLINE_TIMEOUT
=
3600
# seconds
SUBPROC_READLINE_TIMEOUT
=
3600
# seconds
...
@@ -94,7 +100,7 @@ class AbstractCommand(metaclass=abc.ABCMeta):
...
@@ -94,7 +100,7 @@ class AbstractCommand(metaclass=abc.ABCMeta):
self
.
command_idx
)
self
.
command_idx
)
self
.
_log
=
log
.
getChild
(
self
.
identifier
)
self
.
_log
=
log
.
getChild
(
self
.
identifier
)
async
def
run
(
self
,
settings
:
dict
)
->
bool
:
async
def
run
(
self
,
settings
:
Settings
)
->
bool
:
"""
Runs the command, parsing output and sending it back to the worker.
"""
Runs the command, parsing output and sending it back to the worker.
Returns True when the command was succesful, and False otherwise.
Returns True when the command was succesful, and False otherwise.
...
@@ -159,13 +165,13 @@ class AbstractCommand(metaclass=abc.ABCMeta):
...
@@ -159,13 +165,13 @@ class AbstractCommand(metaclass=abc.ABCMeta):
)
)
@abc.abstractmethod
@abc.abstractmethod
async
def
execute
(
self
,
settings
:
dict
)
:
async
def
execute
(
self
,
settings
:
Settings
)
->
None
:
"""
Executes the command.
"""
Executes the command.
An error should be indicated by an exception.
An error should be indicated by an exception.
"""
"""
def
validate
(
self
,
settings
:
dict
)
:
def
validate
(
self
,
settings
:
Settings
)
->
typing
.
Optional
[
str
]
:
"""
Validates the settings for this command.
"""
Validates the settings for this command.
If there is an error, a description of the error is returned.
If there is an error, a description of the error is returned.
...
@@ -176,7 +182,8 @@ class AbstractCommand(metaclass=abc.ABCMeta):
...
@@ -176,7 +182,8 @@ class AbstractCommand(metaclass=abc.ABCMeta):
return
None
return
None
def
_setting
(
self
,
settings
:
dict
,
key
:
str
,
is_required
:
bool
,
valtype
:
typing
.
Type
=
str
)
\
def
_setting
(
self
,
settings
:
Settings
,
key
:
str
,
is_required
:
bool
,
valtype
:
InstanceOfType
=
str
)
\
->
typing
.
Tuple
[
typing
.
Any
,
typing
.
Optional
[
str
]]:
->
typing
.
Tuple
[
typing
.
Any
,
typing
.
Optional
[
str
]]:
"""
Parses a setting, returns either (value, None) or (None, errormsg)
"""
"""
Parses a setting, returns either (value, None) or (None, errormsg)
"""
...
@@ -198,7 +205,7 @@ class AbstractCommand(metaclass=abc.ABCMeta):
...
@@ -198,7 +205,7 @@ class AbstractCommand(metaclass=abc.ABCMeta):
@command_executor
(
'
echo
'
)
@command_executor
(
'
echo
'
)
class
EchoCommand
(
AbstractCommand
):
class
EchoCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
try
:
try
:
msg
=
settings
[
'
message
'
]
msg
=
settings
[
'
message
'
]
except
KeyError
:
except
KeyError
:
...
@@ -207,20 +214,20 @@ class EchoCommand(AbstractCommand):
...
@@ -207,20 +214,20 @@ class EchoCommand(AbstractCommand):
if
not
isinstance
(
msg
,
str
):
if
not
isinstance
(
msg
,
str
):
return
'
Message must be a string
'
return
'
Message must be a string
'
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
await
self
.
worker
.
register_log
(
settings
[
'
message
'
])
await
self
.
worker
.
register_log
(
settings
[
'
message
'
])
@command_executor
(
'
log_a_lot
'
)
@command_executor
(
'
log_a_lot
'
)
class
LogALotCommand
(
AbstractCommand
):
class
LogALotCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
lines
=
settings
.
get
(
'
lines
'
,
20000
)
lines
=
settings
.
get
(
'
lines
'
,
20000
)
if
isinstance
(
lines
,
float
):
if
isinstance
(
lines
,
float
):
lines
=
int
(
lines
)
lines
=
int
(
lines
)
if
not
isinstance
(
lines
,
int
):
if
not
isinstance
(
lines
,
int
):
return
'"
lines
"
setting must be an integer, not %s
'
%
type
(
lines
)
return
'"
lines
"
setting must be an integer, not %s
'
%
type
(
lines
)
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
lines
=
settings
.
get
(
'
lines
'
,
20000
)
lines
=
settings
.
get
(
'
lines
'
,
20000
)
await
self
.
worker
.
register_task_update
(
activity
=
'
logging %d lines
'
%
lines
)
await
self
.
worker
.
register_task_update
(
activity
=
'
logging %d lines
'
%
lines
)
...
@@ -230,7 +237,7 @@ class LogALotCommand(AbstractCommand):
...
@@ -230,7 +237,7 @@ class LogALotCommand(AbstractCommand):
@command_executor
(
'
sleep
'
)
@command_executor
(
'
sleep
'
)
class
SleepCommand
(
AbstractCommand
):
class
SleepCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
try
:
try
:
sleeptime
=
settings
[
'
time_in_seconds
'
]
sleeptime
=
settings
[
'
time_in_seconds
'
]
except
KeyError
:
except
KeyError
:
...
@@ -239,7 +246,7 @@ class SleepCommand(AbstractCommand):
...
@@ -239,7 +246,7 @@ class SleepCommand(AbstractCommand):
if
not
isinstance
(
sleeptime
,
(
int
,
float
)):
if
not
isinstance
(
sleeptime
,
(
int
,
float
)):
return
'
time_in_seconds must be an int or float
'
return
'
time_in_seconds must be an int or float
'
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
time_in_seconds
=
settings
[
'
time_in_seconds
'
]
time_in_seconds
=
settings
[
'
time_in_seconds
'
]
await
self
.
worker
.
register_log
(
'
Sleeping for %s seconds
'
%
time_in_seconds
)
await
self
.
worker
.
register_log
(
'
Sleeping for %s seconds
'
%
time_in_seconds
)
await
asyncio
.
sleep
(
time_in_seconds
)
await
asyncio
.
sleep
(
time_in_seconds
)
...
@@ -285,7 +292,7 @@ def _unique_path(path: Path) -> Path:
...
@@ -285,7 +292,7 @@ def _unique_path(path: Path) -> Path:
@command_executor
(
'
move_out_of_way
'
)
@command_executor
(
'
move_out_of_way
'
)
class
MoveOutOfWayCommand
(
AbstractCommand
):
class
MoveOutOfWayCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
try
:
try
:
src
=
settings
[
'
src
'
]
src
=
settings
[
'
src
'
]
except
KeyError
:
except
KeyError
:
...
@@ -294,7 +301,7 @@ class MoveOutOfWayCommand(AbstractCommand):
...
@@ -294,7 +301,7 @@ class MoveOutOfWayCommand(AbstractCommand):
if
not
isinstance
(
src
,
str
):
if
not
isinstance
(
src
,
str
):
return
'
src must be a string
'
return
'
src must be a string
'
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
src
=
Path
(
settings
[
'
src
'
])
src
=
Path
(
settings
[
'
src
'
])
if
not
src
.
exists
():
if
not
src
.
exists
():
self
.
_log
.
info
(
'
Render output path %s does not exist, not moving out of way
'
,
src
)
self
.
_log
.
info
(
'
Render output path %s does not exist, not moving out of way
'
,
src
)
...
@@ -315,12 +322,12 @@ class MoveOutOfWayCommand(AbstractCommand):
...
@@ -315,12 +322,12 @@ class MoveOutOfWayCommand(AbstractCommand):
@command_executor
(
'
move_to_final
'
)
@command_executor
(
'
move_to_final
'
)
class
MoveToFinalCommand
(
AbstractCommand
):
class
MoveToFinalCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
_
,
err1
=
self
.
_setting
(
settings
,
'
src
'
,
True
)
_
,
err1
=
self
.
_setting
(
settings
,
'
src
'
,
True
)
_
,
err2
=
self
.
_setting
(
settings
,
'
dest
'
,
True
)
_
,
err2
=
self
.
_setting
(
settings
,
'
dest
'
,
True
)
return
err1
or
err2
return
err1
or
err2
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
src
=
Path
(
settings
[
'
src
'
])
src
=
Path
(
settings
[
'
src
'
])
if
not
src
.
exists
():
if
not
src
.
exists
():
msg
=
'
Path %s does not exist, not moving
'
%
src
msg
=
'
Path %s does not exist, not moving
'
%
src
...
@@ -349,7 +356,7 @@ class MoveToFinalCommand(AbstractCommand):
...
@@ -349,7 +356,7 @@ class MoveToFinalCommand(AbstractCommand):
@command_executor
(
'
copy_file
'
)
@command_executor
(
'
copy_file
'
)
class
CopyFileCommand
(
AbstractCommand
):
class
CopyFileCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
src
,
err
=
self
.
_setting
(
settings
,
'
src
'
,
True
)
src
,
err
=
self
.
_setting
(
settings
,
'
src
'
,
True
)
if
err
:
if
err
:
return
err
return
err
...
@@ -361,7 +368,7 @@ class CopyFileCommand(AbstractCommand):
...
@@ -361,7 +368,7 @@ class CopyFileCommand(AbstractCommand):
if
not
dest
:
if
not
dest
:
return
'
dest may not be empty
'
return
'
dest may not be empty
'
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
src
=
Path
(
settings
[
'
src
'
])
src
=
Path
(
settings
[
'
src
'
])
if
not
src
.
exists
():
if
not
src
.
exists
():
raise
CommandExecutionError
(
'
Path %s does not exist, unable to copy
'
%
src
)
raise
CommandExecutionError
(
'
Path %s does not exist, unable to copy
'
%
src
)
...
@@ -386,14 +393,14 @@ class CopyFileCommand(AbstractCommand):
...
@@ -386,14 +393,14 @@ class CopyFileCommand(AbstractCommand):
@command_executor
(
'
remove_tree
'
)
@command_executor
(
'
remove_tree
'
)
class
RemoveTreeCommand
(
AbstractCommand
):
class
RemoveTreeCommand
(
AbstractCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
path
,
err
=
self
.
_setting
(
settings
,
'
path
'
,
True
)
path
,
err
=
self
.
_setting
(
settings
,
'
path
'
,
True
)
if
err
:
if
err
:
return
err
return
err
if
not
path
:
if
not
path
:
return
"'
path
'
may not be empty
"
return
"'
path
'
may not be empty
"
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
path
=
Path
(
settings
[
'
path
'
])
path
=
Path
(
settings
[
'
path
'
])
if
not
path
.
exists
():
if
not
path
.
exists
():
msg
=
'
Path %s does not exist, so not removing.
'
%
path
msg
=
'
Path %s does not exist, so not removing.
'
%
path
...
@@ -424,7 +431,7 @@ class AbstractSubprocessCommand(AbstractCommand, abc.ABC):
...
@@ -424,7 +431,7 @@ class AbstractSubprocessCommand(AbstractCommand, abc.ABC):
return
None
return
None
return
pathlib
.
Path
(
subprocess_pid_file
)
return
pathlib
.
Path
(
subprocess_pid_file
)
def
validate
(
self
,
settings
:
dict
)
->
typing
.
Optional
[
str
]:
def
validate
(
self
,
settings
:
Settings
)
->
typing
.
Optional
[
str
]:
supererr
=
super
().
validate
(
settings
)
supererr
=
super
().
validate
(
settings
)
if
supererr
:
if
supererr
:
return
supererr
return
supererr
...
@@ -578,7 +585,7 @@ class AbstractSubprocessCommand(AbstractCommand, abc.ABC):
...
@@ -578,7 +585,7 @@ class AbstractSubprocessCommand(AbstractCommand, abc.ABC):
@command_executor
(
'
exec
'
)
@command_executor
(
'
exec
'
)
class
ExecCommand
(
AbstractSubprocessCommand
):
class
ExecCommand
(
AbstractSubprocessCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
try
:
try
:
cmd
=
settings
[
'
cmd
'
]
cmd
=
settings
[
'
cmd
'
]
except
KeyError
:
except
KeyError
:
...
@@ -590,7 +597,7 @@ class ExecCommand(AbstractSubprocessCommand):
...
@@ -590,7 +597,7 @@ class ExecCommand(AbstractSubprocessCommand):
return
'"
cmd
"
may not be empty
'
return
'"
cmd
"
may not be empty
'
return
super
().
validate
(
settings
)
return
super
().
validate
(
settings
)
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
await
self
.
subprocess
(
shlex
.
split
(
settings
[
'
cmd
'
]))
await
self
.
subprocess
(
shlex
.
split
(
settings
[
'
cmd
'
]))
...
@@ -628,7 +635,7 @@ class BlenderRenderCommand(AbstractSubprocessCommand):
...
@@ -628,7 +635,7 @@ class BlenderRenderCommand(AbstractSubprocessCommand):
self
.
_last_activity_time
=
0.0
self
.
_last_activity_time
=
0.0
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
blender_cmd
,
err
=
self
.
_setting
(
settings
,
'
blender_cmd
'
,
True
)
blender_cmd
,
err
=
self
.
_setting
(
settings
,
'
blender_cmd
'
,
True
)
if
err
:
if
err
:
return
err
return
err
...
@@ -668,7 +675,7 @@ class BlenderRenderCommand(AbstractSubprocessCommand):
...
@@ -668,7 +675,7 @@ class BlenderRenderCommand(AbstractSubprocessCommand):
return
super
().
validate
(
settings
)
return
super
().
validate
(
settings
)
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
cmd
=
self
.
_build_blender_cmd
(
settings
)
cmd
=
self
.
_build_blender_cmd
(
settings
)
await
self
.
worker
.
register_task_update
(
activity
=
'
Starting Blender
'
)
await
self
.
worker
.
register_task_update
(
activity
=
'
Starting Blender
'
)
...
@@ -770,7 +777,7 @@ class BlenderRenderCommand(AbstractSubprocessCommand):
...
@@ -770,7 +777,7 @@ class BlenderRenderCommand(AbstractSubprocessCommand):
@command_executor
(
'
blender_render_progressive
'
)
@command_executor
(
'
blender_render_progressive
'
)
class
BlenderRenderProgressiveCommand
(
BlenderRenderCommand
):
class
BlenderRenderProgressiveCommand
(
BlenderRenderCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
err
=
super
().
validate
(
settings
)
err
=
super
().
validate
(
settings
)
if
err
:
return
err
if
err
:
return
err
...
@@ -796,7 +803,7 @@ class BlenderRenderProgressiveCommand(BlenderRenderCommand):
...
@@ -796,7 +803,7 @@ class BlenderRenderProgressiveCommand(BlenderRenderCommand):
@command_executor
(
'
merge_progressive_renders
'
)
@command_executor
(
'
merge_progressive_renders
'
)
class
MergeProgressiveRendersCommand
(
AbstractSubprocessCommand
):
class
MergeProgressiveRendersCommand
(
AbstractSubprocessCommand
):
def
validate
(
self
,
settings
:
dict
):
def
validate
(
self
,
settings
:
Settings
):
blender_cmd
,
err
=
self
.
_setting
(
settings
,
'
blender_cmd
'
,
True
)
blender_cmd
,
err
=
self
.
_setting
(
settings
,
'
blender_cmd
'
,
True
)
if
err
:
if
err
:
return
err
return
err
...
@@ -831,7 +838,7 @@ class MergeProgressiveRendersCommand(AbstractSubprocessCommand):
...
@@ -831,7 +838,7 @@ class MergeProgressiveRendersCommand(AbstractSubprocessCommand):
return
super
().
validate
(
settings
)
return
super
().
validate
(
settings
)
async
def
execute
(
self
,
settings
:
dict
):
async
def
execute
(
self
,
settings
:
Settings
):
blendpath
=
Path
(
__file__
).
with_name
(
'
merge-exr.blend
'
)
blendpath
=
Path
(
__file__
).
with_name
(
'
merge-exr.blend
'
)
cmd
=
settings
[
'
blender_cmd
'
][:]
cmd
=
settings
[
'
blender_cmd
'
][:]
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment