I'm writing a slackbot using bolt_python which consists of writing functions that are called during events. Multiple of the events I want to respond to use the same data that I get from an external API. I'd like to avoid calling the API multiple times for the exact same data, so I'd like to cache it and share the cache.

I could make the cache use a global variable, but no one likes that.

Here's what the version using a global might look like.

dumb_global = {}

@app.command('\foo') 
def foo_command(command, logger, say):
    if len(dumb_global) < 1:
        dumb_global = do_lots_of_io_and_networky_stuff()
    say(something_useful(dumb_global))

@app.action('button-click')
def button_click(action, logger, say):
    if len(dumb_global) < 1:
        dumb_global = do_lots_of_io_and_networky_stuff()
    say(something_else_useful(dumb_global))

What's the best way to do this?

Thanks!

1 Reply 1

Well, you can use a class to handle state, its better than a raw global and you are wrapping your cache in a class which is explicit that is sharing state. So the data gets loaded on the first call and then it reused after that.

class BotCache:
    def __init__(self):
        self.data = None
    
    def get_data(self):
        if self.data is None:
            self.data = do_lots_of_io_and_networky_stuff()
        return self.data

cache = BotCache()

@app.command('\foo') 
def foo_command(command, logger, say):
    say(something_useful(cache.get_data()))

@app.action('button-click')
def button_click(action, logger, say):
    say(something_else_useful(cache.get_data()))

here you can add cache invalidation logic later without touching the events handlers. Also as a recomendation additional you can use functools.lru_cache for automatic expriation and the decorator handle that cache automatic. heres the code recomended

from functools import lru_cache
import time

@lru_cache(maxsize=1)
def get_data(cache_key):
    return do_lots_of_io_and_networky_stuff()

data = get_data(int(time.time()) // 300)  # here it does the refres at 5min

(FYI just change the cache key when you want to fresh data.)

I noticed into bold-python there is an issue tracker active, if you need addittional help, you can check directly with them if my answer didnt work.

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.