1

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?

3

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()
1

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())
  • 1
    Can you give some reasons to use this method instead of the one given by @slybloty? – John Go-Soco Jan 18 at 10:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.