How to create a persistent Global Variable

Is there any way in pyRevit to set a variable within a script.py file that will still exist the next time the script.py file is run?

My bundle.yaml has the following:

engine:
  clean: false
  full_frame: false
  persistent: true

Keeping in mind this info… I’ve tried:

  • Writing to globals with globals[‘myvar’] = ‘value’
  • Writing to globals with globals[‘myvar’] = ‘value’
  • Writing a value onto objects in dir() or globals() with setattr(EXEC_PARAMS, ‘myvar’, ‘value’)
  • Using id(obj) to inspect which objects in dir() are new vs reused
  • A half dozen other weird and probably inadvisable approaches

None of these approaches results in being able to retrieve my variable on the next script.py execution.

The only object that seems to be writable and last between script.py executions for me is this:

from pyrevit.runtime.types import ScriptConsoleManager

# I can read and write from this list of objects and the changes exist during 
# the next run, but I'm 99% sure this is not a good practice because the list 
# is meant for storing output windows and nothing else.. 
ScriptConsoleManager.ActiveOutputWindows

So yeah… Is there any way/ any place to keep a variable within pyRevit where it won’t get cleaned up between executions of script.py?

I am not sure if there is a way to directly do this but you could export the variable to a pickle file and then read it in the next script.

Hi,
I’m sorry you had an hard time finding the solution.

I may suggest to take a look at the pyRevit’s userconfig module. I use it at document level to persist some variables even after a Revit restart. You can also use it globally instead of linked to a model.

You don’t need a persistent engine for this to work, as it just writes a file and stores the data there.

Thank you both for the responses; I may have described it poorly, but what I was hoping for was to keep the variable in memory, since the variable is actually a reference to a specific wpf window. Unfortunately afaik, its not possible to serialize that kind of “reference” variable (so its not possible to store to disk and reload).

The solution I ultimately found was to register the wpf window to Revit’s window, then re-acquire it during each run of the “script.py” file though. Appreciate the ideas though!

And how did you exactly do that? Could you share the code? :pinching_hand: :+1:

@thumDer
Its not possible to store a custom object between executions. There are some ways to store a simple variable, and some ways to pickle then unpickle things… Check out this page:
https://pyrevit.readthedocs.io/en/latest/pyrevit/script.html

Specifically the following functions:

  • Pickling and unpickling
    store_data()
    load_data()

  • To store very simple variables (string, int, float, etc):
    set_envvar
    get_envvar()
    dump_json()
    load_json()
    several others…

Unfortunately my particular need was to store a reference to an in-memory object (which is not serializable as far as I know), so I didn’t get too deep into the functions above/ cannot offer any sample reference code…