Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose loop param on asyncio-based AsyncSocketModeHandler #1216

Merged
merged 3 commits into from
Dec 5, 2024

Conversation

jantman
Copy link
Contributor

@jantman jantman commented Dec 4, 2024

This PR exposes the loop parameter (asyncio event loop) on AsyncSocketModeHandler, so that a socket mode handler can be created using an existing asyncio event loop.

This PR relies on slackapi/python-slack-sdk#1609 to also expose the loop parameter in the SDK.

Category (place an x in each of the [ ])

  • slack_bolt.App and/or its core components
  • slack_bolt.async_app.AsyncApp and/or its core components
  • Adapters in slack_bolt.adapter
  • Document pages under /docs
  • Others

Requirements (place an x in each [ ])

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

  • I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • I've read and agree to the Code of Conduct.
  • I've run ./scripts/install_all_and_run_tests.sh after making the changes.

@hello-ashleyintech
Copy link

Hi, @jantman! Thanks for submitting this and also for signing the CLA! 🙌

I am noticing at least two unit tests due to an unexpected key word, loop. I'm guessing this corresponds to the Python SDK change needing to be merged first, is that correct?

@hello-ashleyintech
Copy link

@seratch I'm unfamiliar with the benefits / potential downsides to exposing the loop param, if any - will default to you to determine if this is a good change to add both here and to the SDK

@seratch seratch self-assigned this Dec 5, 2024
@seratch seratch added this to the 1.x milestone Dec 5, 2024
@seratch
Copy link
Member

seratch commented Dec 5, 2024

@jantman Thanks for taking the time to make these pull requests! The changes look good to me, and we'll include them in the next release.

One thing I wanted to ask is how you plan to use this argument. As far as I know, most asyncio-based apps simply rely on asyncio.get_event_loop() (and asyncio.set_event_loop() if you want to set a new one) for configuring the underlying event loop. If you create a new loop using asyncio.new_event_loop() and pass it to the constructor, it might not work as expected (yes, asyncio can be a bit complicated!). So I wanted to better understand what challenges you're facing.

Copy link

codecov bot commented Dec 5, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.94%. Comparing base (15ad6ec) to head (aee630a).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1216   +/-   ##
=======================================
  Coverage   90.93%   90.94%           
=======================================
  Files         222      222           
  Lines        7505     7506    +1     
=======================================
+ Hits         6825     6826    +1     
  Misses        680      680           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jantman
Copy link
Contributor Author

jantman commented Dec 5, 2024

@seratch Thank you so much for the prompt attention on this. Apologies that I didn't respond sooner about the unit test failures, but I was unable to reply yesterday.

In my particular case, I have an existing Quart-based (the asyncio port of Flask) API that's being used to control some physical equipment via relays. We had a desire to also allow control via a Slack app/bot integration. While this would normally have been approached via a standalone application that acts as a gateway between Slack and this (internal) ReST API... since Quart is already an asyncio app, once the loop parameter was exposed, I was able to just run the Slack websocket client and the Quart app in the same event loop, and hence eliminate needing a separate process/application for the Slack integration.

The specific code, taken from here with some minor edits for clarity:

    loop: AbstractEventLoop = get_event_loop()
    app: Quart = create_app()  # this returns a Quart application instance
    token: str = os.environ.get("SLACK_APP_TOKEN", "").strip()
    if token:
        slack: SlackHandler = SlackHandler(app)
        handler = AsyncSocketModeHandler(
            slack.app, os.environ["SLACK_APP_TOKEN"], loop=loop
        )
        loop.create_task(handler.start_async())
    app.run(loop=loop, debug=args.debug, host="0.0.0.0", port=args.port)
    # we now have the Quart app and the Slack socket mode handler both running in the same loop

The desire for running both in the same event loop (as opposed to running the Slack handler in a separate loop in its own thread) was to allow mutual access to data structures previously only extant within the Quart app, which are not thread safe (since that was never a concern in this code base). The Quart app in question is hosted locally and not exposed on the Internet for safety reasons, hence the need for the socket mode client.

@seratch
Copy link
Member

seratch commented Dec 5, 2024

@jantman Thanks for sharing the details, and now I got the point 👍

@seratch seratch merged commit c4a802e into slackapi:main Dec 5, 2024
12 checks passed
@seratch seratch changed the title expose loop param on AsyncSocketModeHandler Expose loop param on asyncio-based AsyncSocketModeHandler Dec 5, 2024
@seratch seratch modified the milestones: 1.x, 1.21.3 Dec 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants