# Can you create a Metadata or Text node from a batch python script?

**URL:** <https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035>\
**Category:** Python\
**Tags:** batch\
**Created:** [June 8, 2022, 11:04pm UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035 "2022-06-08T23:04:37Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 8, 2022, 11:04pm UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/1 "2022-06-08T23:04:37Z")

</div>

I’m trying to figure out a way to take a clip and automatically create the slate info as an overlay node (either a text node or a Metadata node) from it but I can’t figure out from the API if there is a way to create such a node. Anybody know?

---

<div class="post-metadata">

**Author:** ![MikeV](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.logik.tv/mikev/32/399_2.png) [@MikeV](https://forum.logik.tv/u/MikeV)\
**Post date:** [June 9, 2022, 12:01am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/2 "2022-06-09T00:01:46Z")

</div>

Hey Elad!

It’s definitely possible. But not all through the API. The way I’ve done it in the past is to save out a metadata node setup to use as a template of what info you want in the slate and the positioning of it. Then using python create a copy of that template setup and insert whatever custom shot data you need into that template setup, then through the API load it into your metadata node. A similar process could be done with the text node. Although using the metadata node would probably be easier.

Mike

---

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 9, 2022, 5:09am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/3 "2022-06-09T05:09:46Z")

</div>

Thanks Mike! I figured that might need to be the way to go about it. Although I can’t even figure out which call would load the data into the node.

I guess the other end of the question is, is there a way to grab all the pertinent information from a clip? like the length, etc, or other information from the batch as well like the batch iteration etc? I’m having a hard time figuring all that out from the API documentation.

---

<div class="post-metadata">

**Author:** ![MikeV](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.logik.tv/mikev/32/399_2.png) [@MikeV](https://forum.logik.tv/u/MikeV)\
**Post date:** [June 9, 2022, 5:57am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/4 "2022-06-09T05:57:42Z")

</div>

Yea… the API doc’s are a struggle sometimes for sure.

To create a metadata node and load a setup you can do this:

metadata\_node = flame.batch.create\_node(‘burn-in metadata’)  
metadata\_node.load\_node\_setup(path\_to\_metadata\_setup)

To get the batch duration:

flame.batch.duration

To get the batch iteration:

flame.batch.current\_iteration.name

---

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 9, 2022, 2:13pm UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/5 "2022-06-09T14:13:02Z")

</div>

You the best Mike!

---

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 14, 2022, 1:46am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/6 "2022-06-14T01:46:55Z")

</div>

me again… apologies… I’ve collected out all the data I need but how do I access the files for the metadata node on the filesystem to revise the data? Any chance you’re willing to send me what you did as an example?

---

<div class="post-metadata">

**Author:** ![MikeV](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.logik.tv/mikev/32/399_2.png) [@MikeV](https://forum.logik.tv/u/MikeV)\
**Post date:** [June 14, 2022, 3:01am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/7 "2022-06-14T03:01:20Z")

</div>

Sure. The script is a couple years old and written for python 2.7. I would probably do a couple things differently if I was writing it now.

If you’re using Flame 2022 or newer just adding some parenthesis around the print statements should get it working.

What the script did was allow you to set off a render by right clicking in batch but while also updating the slate info in the metadata node(metadata node would have to be named ‘slate info’ for the right-click menu to appear). I would have a template metadata node setup in the default flame project burnmetadata node folder that the script would look for… this could be changed to be wherever though. The template would have everything setup with the way you want to have the slate look. Except in the fields where the things like the date, duration, version would go, I would put tokens that get replaced by the script. In this case %Version% and %Date%. So you could have a Custom Text layer with a line like this in the node:

Date: %Date%

and it would get changed to:

Date: 06/13/22

The replace\_tokens function is where the tokens the script looks for can be added/changed. After it looks for all the tokens, it writes out a temp file that then gets loaded back into the ‘slate\_info’ metadata node.

Hope it helps.

[burnmetadata\_template.burnmetadata\_node.zip](https://forum.logik.tv/uploads/short-url/mlgft7fSJOo1SJt943tUOvHGuR.zip) (1.2 KB)

```auto
def update_burnin_node():
    import datetime
    import flame
    import os

    def project_path():
        import re

        flame_prj_name = flame.project.current_project.project_name
        print 'flame_prj_name:', flame_prj_name

        with open('/opt/Autodesk/project/project.db', 'r') as project_db:
            for line in project_db:
                if ':' + flame_prj_name + '=' in line:
                    save_path = re.search('SetupDir="(.*)",Partition', line)
                    save_path = save_path.group(1)

        print 'save path:', save_path

        return save_path

    def edit_template():

        def replace_tokens():
            import re

            token_dict = {}

            token_dict['%Version%'] = batch_iteration
            token_dict['%Date%'] = date

            # Replace tokens in menu template

            for key, value in token_dict.items():
                for line in template_lines:
                    if key in line:
                        line_index = template_lines.index(line)
                        new_line = re.sub(key, value, line)
                        template_lines[line_index] = new_line

        # Read template

        burn_in_setup = open(template_path, 'r')
        template_lines = burn_in_setup.read().splitlines()

        # Replace tokens in template

        replace_tokens()

        # Write out temp node

        out_file = open(temp_burn_in_file, 'w')
        for line in template_lines:
            print >>out_file, line
        out_file.close()

    def load_burn_in_node():

        burn_in_node.load_node_setup(temp_burn_in_file)

    # Get current project path

    template_path = '%s/burnmetadata/flame/slate_info.burnmetadata_node' % project_path()
    print 'template_path:', template_path

    temp_burn_in_file = '/opt/Autodesk/shared/python/update_slate/temp.burnmetadata_node'

    batch_iteration = str(flame.batch.current_iteration.name)[1:-1]
    print 'batch_iteration:', batch_iteration

    now = datetime.datetime.now()
    date = now.strftime('%m/%d/%y')
    print 'date: ', date

    for node in flame.batch.nodes:
        if node.name == 'slate_info':
            burn_in_node = node

            edit_template()

            load_burn_in_node()

    os.remove(temp_burn_in_file)

def update_slate(selection):

    update_burnin_node()

    print '\n>>> slate updated <<<\n'

def update_slate_render(selection):
    import flame

    update_burnin_node()

    flame.batch.render()

    print '\n>>> slate updated <<<\n'

def update_slate_burn(selection):
    import flame

    update_burnin_node()

    flame.batch.render(render_option='Burn')

    print '\n>>> slate updated <<<\n'

def scope_slate_info(selection):
    import flame

    for n in flame.batch.nodes:
        if n.name == 'slate_info':
            return True
    return False

def get_batch_custom_ui_actions():

    return [
        {
            'name': 'Slate...',
            'actions': [
                {
                    'name': 'Update Slate',
                    'isVisible': scope_slate_info,
                    'execute': update_slate,
                    'minimumVersion': '2020'
                },
                {
                    'name': 'Update Slate and Render',
                    'isVisible': scope_slate_info,
                    'execute': update_slate_render,
                    'minimumVersion': '2020'
                },
                {
                    'name': 'Update Slate and Burn',
                    'isVisible': scope_slate_info,
                    'execute': update_slate_burn,
                    'minimumVersion': '2020'
                }
            ]
        }
    ]

```

---

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 14, 2022, 3:16am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/8 "2022-06-14T03:16:21Z")

</div>

Thanks so much Mike! I just needed an example to follow 😊.

> ![Image removed by sender.]()  
>   
> |   
>   
> [**MikeV**](https://forum.logik.tv/u/mikev) patron of Logik  
> June 14  
>   
> |
> 
> - | - |

Sure. The script is a couple years old and written for python 2.7. I would probably do a couple things differently if I was writing it now.

If you’re using Flame 2022 or newer just adding some parenthesis around the print statements should get it working.

What the script did was allow you to set off a render by right clicking in batch but while also updating the slate info in the metadata node(metadata node would have to be named ‘slate info’ for the right-click menu to appear). I would have a template metadata node setup in the default flame project burnmetadata node folder that the script would look for… this could be changed to be wherever though. The template would have everything setup with the way you want to have the slate look. Except in the fields where the things like the date, duration, version would go, I would put tokens that get replaced by the script. In this case %Version% and %Date%. So you could have a Custom Text layer with a line like this in the node:

Date: %Date%

and it would get changed to:

The replace\_tokens function is where the tokens the script looks for can be added/changed. After it looks for all the tokens, it writes out a temp file that then gets loaded back into the ‘slate\_info’ metadata node.

Hope it helps.

[**burnmetadata\_template.burnmetadata\_node.zip**](https://forum.logik.tv/uploads/short-url/mlgft7fSJOo1SJt943tUOvHGuR.zip) (1.2 KB)

```auto
def update_burnin_node():

```

```auto

```

```auto
    import datetime

```

```auto

```

```auto
    import flame

```

```auto

```

```auto
    import os

```

```auto

```

```auto

```

```auto

```

```auto
    def project_path():

```

```auto

```

```auto
        import re

```

```auto

```

```auto

```

```auto

```

```auto
        flame_prj_name = flame.project.current_project.project_name

```

```auto

```

```auto
        print 'flame_prj_name:', flame_prj_name

```

```auto

```

```auto

```

```auto

```

```auto
        with open('/opt/Autodesk/project/project.db', 'r') as project_db:

```

```auto

```

```auto
            for line in project_db:

```

```auto

```

```auto
                if ':' + flame_prj_name + '=' in line:

```

```auto

```

```auto
                    save_path = re.search('SetupDir="(.*)",Partition', line)

```

```auto

```

```auto
                    save_path = save_path.group(1)

```

```auto

```

```auto

```

```auto

```

```auto
        print 'save path:', save_path

```

```auto

```

```auto

```

```auto

```

```auto
        return save_path

```

```auto

```

```auto

```

```auto

```

```auto
    def edit_template():

```

```auto

```

```auto

```

```auto

```

```auto
        def replace_tokens():

```

```auto

```

```auto
            import re

```

```auto

```

```auto

```

```auto

```

```auto
            token_dict = {}

```

```auto

```

```auto

```

```auto

```

```auto
            token_dict['%Version%'] = batch_iteration

```

```auto

```

```auto
            token_dict['%Date%'] = date

```

```auto

```

```auto

```

```auto

```

```auto
            # Replace tokens in menu template

```

```auto

```

```auto

```

```auto

```

```auto
            for key, value in token_dict.items():

```

```auto

```

```auto
                for line in template_lines:

```

```auto

```

```auto
                    if key in line:

```

```auto

```

```auto
                        line_index = template_lines.index(line)

```

```auto

```

```auto
                        new_line = re.sub(key, value, line)

```

```auto

```

```auto
                        template_lines[line_index] = new_line

```

```auto

```

```auto

```

```auto

```

```auto
        # Read template

```

```auto

```

```auto

```

```auto

```

```auto
        burn_in_setup = open(template_path, 'r')

```

```auto

```

```auto
        template_lines = burn_in_setup.read().splitlines()

```

```auto

```

```auto

```

```auto

```

```auto
        # Replace tokens in template

```

```auto

```

```auto

```

```auto

```

```auto
        replace_tokens()

```

```auto

```

```auto

```

```auto

```

```auto
        # Write out temp node

```

```auto

```

```auto

```

```auto

```

```auto
        out_file = open(temp_burn_in_file, 'w')

```

```auto

```

```auto
        for line in template_lines:

```

```auto

```

```auto
            print >>out_file, line

```

```auto

```

```auto
        out_file.close()

```

```auto

```

```auto

```

```auto

```

```auto
    def load_burn_in_node():

```

```auto

```

```auto

```

```auto

```

```auto
        burn_in_node.load_node_setup(temp_burn_in_file)

```

```auto

```

```auto

```

```auto

```

```auto
    # Get current project path

```

```auto

```

```auto

```

```auto

```

```auto
    template_path = '%s/burnmetadata/flame/slate_info.burnmetadata_node' % project_path()

```

```auto

```

```auto
    print 'template_path:', template_path

```

```auto

```

```auto

```

```auto

```

```auto
    temp_burn_in_file = '/opt/Autodesk/shared/python/update_slate/temp.burnmetadata_node'

```

```auto

```

```auto

```

```auto

```

```auto
    batch_iteration = str(flame.batch.current_iteration.name)[1:-1]

```

```auto

```

```auto
    print 'batch_iteration:', batch_iteration

```

```auto

```

```auto

```

```auto

```

```auto
    now = datetime.datetime.now()

```

```auto

```

```auto
    date = now.strftime('%m/%d/%y')

```

```auto

```

```auto
    print 'date: ', date

```

```auto

```

```auto

```

```auto

```

```auto
    for node in flame.batch.nodes:

```

```auto

```

```auto
        if node.name == 'slate_info':

```

```auto

```

```auto
            burn_in_node = node

```

```auto

```

```auto

```

```auto

```

```auto
            edit_template()

```

```auto

```

```auto

```

```auto

```

```auto
            load_burn_in_node()

```

```auto

```

```auto

```

```auto

```

```auto
    os.remove(temp_burn_in_file)

```

```auto

```

```auto

```

```auto

```

```auto
def update_slate(selection):

```

```auto

```

```auto

```

```auto

```

```auto
    update_burnin_node()

```

```auto

```

```auto

```

```auto

```

```auto
    print '\n>>> slate updated <<<\n'

```

```auto

```

```auto

```

```auto

```

```auto
def update_slate_render(selection):

```

```auto

```

```auto
    import flame

```

```auto

```

```auto

```

```auto

```

```auto
    update_burnin_node()

```

```auto

```

```auto

```

```auto

```

```auto
    flame.batch.render()

```

```auto

```

```auto

```

```auto

```

```auto
    print '\n>>> slate updated <<<\n'

```

```auto

```

```auto

```

```auto

```

```auto
def update_slate_burn(selection):

```

```auto

```

```auto
    import flame

```

```auto

```

```auto

```

```auto

```

```auto
    update_burnin_node()

```

```auto

```

```auto

```

```auto

```

```auto
    flame.batch.render(render_option='Burn')

```

```auto

```

```auto

```

```auto

```

```auto
    print '\n>>> slate updated <<<\n'

```

```auto

```

```auto

```

```auto

```

```auto
def scope_slate_info(selection):

```

```auto

```

```auto
    import flame

```

```auto

```

```auto

```

```auto

```

```auto
    for n in flame.batch.nodes:

```

```auto

```

```auto
        if n.name == 'slate_info':

```

```auto

```

```auto
            return True

```

```auto

```

```auto
    return False

```

```auto

```

```auto

```

```auto

```

```auto
def get_batch_custom_ui_actions():

```

```auto

```

```auto

```

```auto

```

```auto
    return [

```

```auto

```

```auto
        {

```

```auto

```

```auto
            'name': 'Slate...',

```

```auto

```

```auto
            'actions': [

```

```auto

```

```auto
                {

```

```auto

```

```auto
                    'name': 'Update Slate',

```

```auto

```

```auto
                    'isVisible': scope_slate_info,

```

```auto

```

```auto
                    'execute': update_slate,

```

```auto

```

```auto
                    'minimumVersion': '2020'

```

```auto

```

```auto
                },

```

```auto

```

```auto
                {

```

```auto

```

```auto
                    'name': 'Update Slate and Render',

```

```auto

```

```auto
                    'isVisible': scope_slate_info,

```

```auto

```

```auto
                    'execute': update_slate_render,

```

```auto

```

```auto
                    'minimumVersion': '2020'

```

```auto

```

```auto
                },

```

```auto

```

```auto
                {

```

```auto

```

```auto
                    'name': 'Update Slate and Burn',

```

```auto

```

```auto
                    'isVisible': scope_slate_info,

```

```auto

```

```auto
                    'execute': update_slate_burn,

```

```auto

```

```auto
                    'minimumVersion': '2020'

```

```auto

```

```auto
                }

```

```auto

```

```auto
            ]

```

```auto

```

```auto
        }

```

```auto

```

```auto
    ]

```

```auto

```

```auto

```

```auto

```

---

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 28, 2022, 1:42am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/9 "2022-06-28T01:42:22Z")

</div>

That worked perfectly! I was able to revise it to make it work and it taught me some stuff!  
Another follow up question - is there a direct way to get the current batch iteration number or do I need to get the iteration list and grab the last one and get that one’s iteration number? do you know?  
Tell me to fuck off any time I get annoying with these question btw…

---

<div class="post-metadata">

**Author:** ![MikeV](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.logik.tv/mikev/32/399_2.png) [@MikeV](https://forum.logik.tv/u/MikeV)\
**Post date:** [June 28, 2022, 4:56am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/10 "2022-06-28T04:56:14Z")

</div>

Glad to hear it helped out. Doing something like this might get you what you’re looking for as far as the batch iterations on your currently open batch:

print(flame.batch.current\_iteration.name)  
print(flame.batch.batch\_iterations[-1].name)

current\_iteration and batch\_iterations can also be applied to any batch group selection.

---

<div class="post-metadata">

**Author:** ![balldee](https://avatars.discourse-cdn.com/v4/letter/b/cdc98d/32.png) [@balldee](https://forum.logik.tv/u/balldee)\
**Post date:** [June 28, 2022, 5:11am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/11 "2022-06-28T05:11:33Z")

</div>

The funny thing about that is that it gives the full name and I can even get the formatting text from token\_name but it doesn’t seem like there is a way to just get the iteration number other than as its place in the iterations list. Not hard to do but seems to me a little odd that it isn’t an exposed value.

---

<div class="post-metadata">

**Author:** ![PhilippeJ](https://avatars.discourse-cdn.com/v4/letter/p/a5b964/32.png) [@PhilippeJ](https://forum.logik.tv/u/PhilippeJ)\
**Post date:** [June 28, 2022, 11:16am UTC](https://forum.logik.tv/t/can-you-create-a-metadata-or-text-node-from-a-batch-python-script/6035/12 "2022-06-28T11:16:51Z")

</div>

You could get the iteration number in an indirect way via the WriteFile node attributes.

```auto
def get_current_iteration_number():
    import flame
    dummy_node = flame.batch.create_node("Write File")
    dummy_node.version_mode = "Follow Iteration"
    number = dummy_node.version_number.get_value()
    flame.delete(dummy_node)
    return number

```
