Running Multiple .docbuilder Scripts with Different Arguments in Python to Generate a Document

Hello everyone!

I’m developing an app using the Python library for document building, which generates documents based on various “components” that users can select. Each component is defined in a .docbuilder file and comes with different arguments.

My approach involves combining the Python document builder library with .docbuilder scripts to create the documents. For example, I can specify that I want a document with a header component, a paragraph section, an image, and another paragraph section. I then pass the information using the --argument option in builder.SetProperty("--argument", "arguments dictionary") and execute builder.Run(Path-to-script).

Initially, I tried to use the .SetProperty method for each builder.Run with the appropriate arguments for each .docbuilder script. However, I discovered that this method only works for the first script run. While I can pass all arguments to the builder in one go, having multiple instances of the same component causes the key arguments to overwrite each other.

Sample of my generateFile function:

def generateFile(docName, docType, positionArray, objectsDict):

    filename = docName + "." + docType
    dstPath = './filestore/' + filename
    builder = docbuilder.CDocBuilder()
    builder.CreateFile(docType)

    for position in positionArray:
        builder.SetProperty("--argument", str(objectsDict[position]['params']).replace('\'','\"'))
        builder.Run(f'./templates/{position}.docbuilder')

    builder.SaveFile(docType, dstPath)
    builder.CloseFile()

    return filename

Sample from a docbuilder that writes a paragraph section:

var oDocument = Api.GetDocument();
var sArray   = Argument["array"];

var oParagraph = Api.CreateParagraph();
oParagraph.AddText("Vamos escrever um array de paragrafos :)");
oDocument.Push(oParagraph);

sArray.forEach(function(item, i, Array) {
    var oParagraph = Api.CreateParagraph();
    oParagraph.AddText(item);
    oDocument.Push(oParagraph);
});

Has anyone faced a similar issue or has suggestions on how to handle multiple components with the same arguments without them conflicting? Any insights would be greatly appreciated!

Hello @mrmikept

I believe there is some kind of misunderstanding of how arguments work. Generally, one argument represent one particular object, kind of what is provided in this article about usage of arguments from command line:

So instead of defining what ‘component’ should be invoked, arguments allow you to simply put data to the place in your .docbuilder script from outside per se. From that perspective, it’s expected that if the same argument passes different values, then the last value will be placed into the final document.

Can you please provide more details about the scenario you’d like to achieve?

This is not quite explaining what are these components and how they work in your design with arguments.

Hi @Constantine,

Sorry for not clarifying my view on what “components” are.

My interpretation of “components” is pieces of .docbuilder that insert a predefined structure into the document. For example, a component could be a generateImageAndText.docbuilder file that generates an image and a predefined text with some placeholders (e.g., explaining the image). This component needs information for the image (URL, width, and height) and the values to place in the text, like so:

builder.SetProperty("--argument", "{"imageURL" : "image.com", "witdh" : 100, "height" : 100, "textValue1" : "something", "textValue2" : "else" }")

Similarly, I have another component, generateParagraphs.docbuilder, that generates some paragraphs with the provided document builder, with arguments like:

builder.SetProperty("--argument", "{"array" : ["Paragraph1","Paragraph2"] }")

Now, I want to create a document using these components, for example: Image and Text, paragraphs, and another Image and Text. In this case, the argument names for the first and last Image and Text will be the same (because these components are generic), so I can’t call only one builder.SetProperty(“–argument”, (…)) with all the arguments values. Soo i tried to generate the document like this:

def generateFile(docName, docType, dstPath):

    builder = docbuilder.CDocBuilder()
    builder.CreateFile(docType)

    builder.SetProperty("--argument", {"imageInfo" : [Array with the image info], "textValue1" : "something", "textValue2" : "else"})
    builder.Run('generateImageAndText.docbuilder')

    builder.SetProperty("--argument", {"array" : ["paragraph1", "paragraph2"]})
    builder.Run('generateParagraphs.docbuilder')    

    builder.SetProperty("--argument", {"imageInfo" : [Array with another image info], "textValue1" : "nothing", "textValue2" : "else2"})
    builder.Run('generateImageAndText.docbuilder')

    builder.SaveFile(docType, dstPath)
    builder.CloseFile()

However, the problem is that only the first .docbuilder script received its arguments; the others appear as “undefined” or are not generated at all.

The only solution I found to use this method is to save the file and open it again after running each .docbuilder. But I find this solution inelegant because of the constant reading and writing of the files.

Keep in mind that no .docbuilder creates or saves the file; that part is handled by the Python code, and only one document is generated. I also know this is not the standard way of using this library!

You try using arguments as such:

builder.CreateFile('docx')

builder.ExecuteCommand('Argument = {key1: "value1", key2: "value2"}')
builder.Run('script1.docbuilder')

builder.ExecuteCommand('Argument = {key1: "value3", key2: "value4"}')
builder.Run('script2.docbuilder')

By the way, I was informed that SetProperty('--argument', '...') is executed once during execution of first script - so it is confirmed now.

Hi @Constantine,

Thank you so much! The solution you provided works perfectly!

Yes, this seemed to be the case during my testing as well.

Thanks again for your help! :blush:

1 Like

Thank you for the feedback. I am glad to know that it helped.

1 Like