Store custom variable in the Flame project metadata

Hello Guys,
I am new to the forum (and Flame dev community). I was suggested on the Discord that this might be the correct place to ask.

For our Flame integration, I’m looking at how can I store custom variable content (json string) onto the Flame project.
I’ve followed this suggestion here Store persistent variable with flame project - Autodesk Community leveraging Nickname of the project XML metadata.

It works great but now I’m getting random crash report when I quit Flame application.
I tried switching WireTap Python SDK to WireTap command lines, slightly better but same results. I got a feeling Flame does not like me live-tweaking current project metadata.

Does it ring a bell to anyone ? Would you guys have another recommendation ?

Thanks a bunch !

why?

1 Like

I use the nickname of a project to store something that my python scripts need later. It’s the only way I know how to do this, and you can only do one variable.

There’s a similar feature request here:
https://feedback.autodesk.com/project/feedback/view.html?cap=5afe6c845cb3447ab36ccbd7f0688f84&uf=24186202a2814863b9acd3ae41bb976e#AddReply

Robin,

It’s a little unclear what you’re asking for. I’m guessing it’s either defining Global Variables for other scripts to use for the current Flame session OR it’s to define settings that persist and get loaded whenever you restart Flame.

If you just want Globals, I like to use a class that has class level fields (verses instance fields).

my_globals.py:

class my_globals:
    # Project Globals
    proj_config_dir_name = 'MW_PROJECT_CONFIG'
    proj_config_file_name = 'MW_PROJECT_CONFIG.json'
    proj_config_dir_path = ''  # set path later in app init
    proj_config_file_path = ''  # set path later in app init
    default_jobs_path = '/mnt/JOBS'

Then every script you want to use the globals class you just import my_globals.py. For global variables that need to be initialized after the app starts, you can do this:


from my_globals.py import my_globals
# ------------------------------------------
# Application Initialization Hook
# ------------------------------------------
def app_initialized(project_name):
    """
    Hook called when application is initialized (AFTER you select project and hit 'Start')
    """
    my_globals.proj_config_dir_path = "/mnt/JOBS/blah"

Using a class for globals is better in 2 ways… it defines a namespace for your scripts preventing conflicts with other 3rd party scripts (from Logik for instance) and you don’t have to specify “global -global variable-” inside the local function in order to modify the global.

In the case where you wanted a json config file to store persistence data between Flame sessions, you can just create a json file with the built in “open” function. But you probably want the file to live in the Flame Project folder that holds the batch setups, project config, etc.

There’s no flame api function that gives you the project setting folder path directly (not that I know of)…BUT there is a function that gives you the path to the export codec folder inside the project setting folder!

def get_presets_base_dir():
    """
    Returns the presets directory for the current project.

    Typically the presets directory is:
    ../flame/project/export/presets/flame
    """
    return os.path.abspath(flame.PyExporter.get_presets_base_dir(flame.PyExporter.Project))


def get_flame_project_dir():
    """
    Returns the project directory for the current project.
    """
    # there's no function to get project folder directly from flame, but we can go up 3 folder from presets folder.
    return os.path.abspath(os.path.join(get_presets_base_dir(), '../../..'))  # returns the project directory

Then you can write your config dict to the json file in the project setup folder:

def write_config():
    """
        Write the persistant configuration file
    """
    import json
    # Make config directory if it doesn't exist
    config_dir = get_flame_project_dir()
    if not os.path.exists(config_dir):
        os.makedirs(config_dir)
    # Make dict of globals we want to write to config file
    settings = {
        'jobs_path': my_globals.jobs_path,
        'otherdata': my_globals.otherdata,
    }
    with open(config_dir, 'w') as config:
        config.write(json.dumps(settings))

You can load the config file and parse the json file in the “app_initialized” hook.

2 Likes

@DannyYoon’s solution is quite elegant. We just get the current project and dump configs, variables, etc into /opt/Autodesk/project/currentproject/cfg and call it a day.

Anytime we need said variable you just pull it from there. If, however, it’s something that needs to be shared amongst other users, then it’ll be placed on the network within the job structure as, again, we know what project it is.

This, of course, means the project name in Flame has to follow your project name on the server (or be extracted from it) but as you’re talking pipeline, I can imagine it wouldn’t.

Thanks a lot @DannyYoon my use-case was indeed the persistent data you suggested.

I went with your approach in storing those via a side-car json file which works very well.
I wanted to ensure I was not missing any embedded feature, some other DCCs have metadata slot they let you use to that your data is directly stored in the project file, but it looks like I did the right thing.

Thanks again folks for your time.