How to persist a class instance across multiple function calls in a VIKTOR app?

Hi Support Team,

In my VIKTOR app, I’m using a custom class RodPattern that generates rod layouts based on user input. I want to avoid re-initializing the class on every function call, so I tried caching the instance like this:

_rp_cache = {}

def get_RP(params):
    key = id(params)
    if key not in _rp_cache:
        config_dic = get_config_dic(params)
        RP = RodPattern(config_dic)
        RP.Get_configuration_dict()
        _rp_cache[key] = RP
    return _rp_cache[key]

def Get_Pattern(params, **kwargs):
    RP = get_RP(params)
    RP.Generate_RodPattern()
    return RP.EF_dic_temp

def get_EF_options(params, **kwargs):
    RP = get_RP(params)
    EF_dic = RP.EF_dic_temp
    if EF_dic is None:
        return []
    return EF_dic.keys()

In the UI, I have this field:

Pattern_correction = vkt.Tab("Pattern Correction", visible=show_d2_view)
Pattern_correction.EF_choice = vkt.OptionField(
    "Choose EF", options=get_EF_options, visible=show_d2_view, flex=FLEX_DEFAULT
)

The issue:

When all parameters are filled in and the Pattern Correction tab becomes visible, the “Choose EF” field shows the following message in the Editor:

“There is a problem with Choose EF”

And the dropdown is empty — even though at that point RodPattern.Generate_RodPattern() has already been called (in theory).


What I need help with:

  • How can I ensure that Generate_RodPattern() is always called before get_EF_options()?
  • Is there a proper way to persist a computed object like RodPattern throughout a VIKTOR interaction?
  • Can I use params or another VIKTOR-native way to manage state or computed objects across function calls?

Any suggestions, workarounds, or best practices would be greatly appreciated. Thanks!

— Jules

Hi Jules

I think this article can you help you a lot in understanding how this works and how to adjust your code. it highlights a few options to persist state (memoize and storage).

hope this helps!

1 Like