I have a python CLI tool that my department uses to process some excel file aided by a yaml. I tried to diagram a basic work flow here:
tool process flow: user interaction, tool execution, outputs
Step 1: User downloads a xlsx, puts it in a file, runs tool --preprocess
which takes some inputs A, B, C, and the file name. This step doesn't do anything, see my question below.
Step 2: User runs tool --start
where they give the same inputs. However this time it uses their inputs and the xlsx to generate a yaml.
Step 3: User finishes updating the yaml, and runs tool --build
which takes just a yaml and a xlsx, and converts it into a giant pdf.
One thing that i've noticed is that some of my users are going to great lengths to make some edits of the files because they are an edge case. For example: They might create some worksheets before using tool --start
.
Here's my question: How could I allow users to "hook" into each step, that is, allow them to write a custom python file/function that gets saved in a different file (I don't want to have to custom make everyone's functionality):
So instead of:
def preprocess():
# do stuff
if input == "A":
# user 1 code
if input == "B":
# user 2 code
# convert to expected form
Maybe they could push up a file like "A.py" which has def overload_preprocess()
and then the tool would import the file and run their function depending on their inputs?
2 Answers 2
You can dynamically import those files that users made and run the appropriate functions; maybe have a run()
function in each.
Have these files provided as input arguments when they run your tool
.
tool --userFiles A,B
Here's an example of such user file:
A.py
def run():
# Do something
return
Your tool
will then parse its arguments and call, let's say, preprocess
with the list of user file names.
userFiles = ['A', 'B'] # determined by your arg parser
preprocess(userFiles)
And your function will import those user files and execute them.
def preprocess(*args):
for a in args:
userFile = __import__(a)
userFile.run()
If a user gives a filename, you can do something like this to run arbitrary code:
exec(open(filename).read())
def preprocess(fileName=None):
# do stuff
if fileName != None:
exec(open(fileName).read())
-
1Can you give some reasons to use this method instead of the one given by @slybloty?John Go-Soco– John Go-Soco01/18/2019 10:09:53Commented Jan 18, 2019 at 10:09
Explore related questions
See similar questions with these tags.