question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Examples with multiple classes, instead of a big "flat file"

See original GitHub issue

The files in the examples directory are very helpful. Thank you for those!

Unfortunately (and please don’t take this the wrong) they aren’t very “Pythonic”. They all start by defining a global:

app = AsyncApp()   # or App()

and then proceed to use the @app.message, @app.event, etc. syntactic sugar to decorate the event handlers being demonstrated. This is definitely a great way to introduce the concepts of Bolt, and it makes the examples easy to follow.

But I’d like to see a more “real world” example (or maybe two, if App() and AsyncApp() are substantially different) which demonstrates “Bolt-approved best practices” on how to split (unrelated) sections of an app’s event processing across multiple files/classes, and not have to rely on an app global to decorate event handlers.

I’ve tried several approaches, but none of them feel very satisfying. Or perhaps I’m just missing something obvious? In any case, it would be great to see what the Bolt authors had in mind in terms of a “larger scale” app… even just a short example with some event handlers split across a couple files would be helpful. (Hopefully it wasn’t to just put everything in one flat namespace! 😄)

Thanks!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

5reactions
eddygcommented, Feb 10, 2021

This is what I came up with last night as a proof-of-concept. During dynamic loading of the plugins, I call in to a register method in each plugin to attach Bolt events:

class HelloPlugin(BasePlugin):
    def register(self, app: AsyncApp):
        app.message(re.compile(r"^h(i|ello)", re.I))(self.message_hello)
        app.action("click_me_button_clicked")(self.action_button_clicked)

    async def message_hello(self, message: Dict, say: Say, logger: Logger):
        logger.debug("Processing 'hello'")
        await say(
            blocks=[
                {
                    "type": "section",
                    "text": {"type": "mrkdwn", "text": f"Hey there <@{message['user']}>! :wave:"},
                    "accessory": {
                        "type": "button",
                        "text": {"type": "plain_text", "text": "Click Me"},
                        "action_id": "click_me_button_clicked"
                    }
                }
            ],
            text=f"Hey there <@{message['user']}>! :wave:"
        )

    async def action_button_clicked(self, body: Dict, ack: Ack, say: Say):
        # since this is an action, need to acknowledge it
        await ack()
        # reply to hello message in a thread
        message = body.get("message")
        thread_ts = message.get("thread_ts") or message["ts"]
        await say(text=f"<@{body['user']['id']}> clicked the button!", thread_ts=thread_ts)

Do you foresee any problems with this approach? Thanks again.

4reactions
capehartcommented, Feb 11, 2021

Thanks @eddyg for the issue and @seratch for the answers. I’m in pretty much the exact same place – trying to modernize an app built on top of https://github.com/slackapi/python-rtmbot and was struggling with how to keep the generation modular. I was very glad to have run across this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is a flat file and how does it work? - TechTarget
A flat-file database is a simple two-dimensional repository of like data. The data is arranged in rows -- or records -- across columns...
Read more >
Is it considered Pythonic to have multiple classes defined in ...
My interpretation is that it's fine as it would keep things simple and flat. Also, because class names and file names have different...
Read more >
Is it a bad practice to have multiple classes in the same file?
The best rule of thumb is to keep one class per file except when that starts to make things harder rather than easier....
Read more >
Multiple Flat Files Connection Manager - Microsoft Learn
A Multiple Flat Files connection manager enables a package to access data in multiple flat files. For example, a Flat File source can...
Read more >
FileHelpers - Library Examples
Example of how to read a Fixed Length layout file (eg COBOL output):; Write Fixed File ... Shows how to sort a big...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found