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

Add documention for injected 'args' param option #835

Merged
merged 1 commit into from
Feb 23, 2023
Merged

Conversation

YSaxon
Copy link
Contributor

@YSaxon YSaxon commented Feb 23, 2023

(Describe the goal of this PR. Mention any related Issue numbers)

Category

  • 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

This pull request adds to the docstrings of the Args class the fact that you can use a parameter named 'args' to receive an instance of the Args class (linking to all the other arguments), as an alternative to naming each of the requested arguments one at a time.

This functionality is already implemented in line 97 of the build_required_kwargs method in both sync and async but is not presently documented anywhere I could find. The docs themselves just link to this docstring for more info on possible injectable params, and the docstring only mentions injecting its children but not itself.

@CLAassistant
Copy link

CLAassistant commented Feb 23, 2023

CLA assistant check
All committers have signed the CLA.

@YSaxon YSaxon marked this pull request as draft February 23, 2023 19:01
@eddyg
Copy link
Contributor

eddyg commented Feb 23, 2023

Is the lack of documentation intentional?

kwarg injection allows the best practice of YAGNI so that you can choose exactly which arguments are needed in each use case rather than always having a bunch of args that are (potentially; often) never used.

Similarly, a function that calls out its arguments is more clear and follows the Python zen that Explicit is better than implicit as well as Readability counts.

I'm just not sure the documentation should "promote" a less "zen" type of usage, which is why I wondered if the omission was intentional.

@hello-ashleyintech
Copy link

Hi, @YSaxon! Thanks so much for your PR! Also thank you @eddyg for posing that question - on seeing this PR, I was wondering the same thing. Since I lack the context about whether this is an intentional omission of the documentation or not, I will surface this internally to my team and then update as soon as I hear back!

@YSaxon YSaxon marked this pull request as ready for review February 23, 2023 20:07
@YSaxon
Copy link
Contributor Author

YSaxon commented Feb 23, 2023

(I just added a couple of commits to fix the functionality itself, after realizing it was hitting a subtle error)

@YSaxon
Copy link
Contributor Author

YSaxon commented Feb 23, 2023

I would just note that this functionality is clearly already deliberately in the code so it might as well be documented.

As to whether it's good or bad:

  • It isn't making the code any less efficient, as all the arguments are already being gathered into the all_available_args dict regardless of whether that is passed or not.
  • It can be quite useful, most notably in cases where you want to delegate the handling of a request to different methods which might require different arguments to allow more complicated request handling logic. Presently you need to do something like
def handler_1(ack, body, **unused_kwargs): 
  ack()
  #handling logic

def handler_2(ack, action, context, **unused_kwargs): 
  ack()
  #handling logic

@app.action(re.compile("dynamic_handler_.*"))
def delegate_to_handler(ack,body,action,client,say,respond,context):
  selected_handler=complex_logic_to_decide_which_handler_to_use(action, context)
  selected_handler(ack=ack,body=body,action=action,client=client,say=say,
                   respond=respond,context=context)

There also isn't any good way to specify a valid handler if you have some method to register them dynamically and if you forget to add the **unused_kwargs parameter to one of them, it will receive extra parameters and die.

Whereas if you use the args approach, you can do this:

def handler_1(args:Args): 
  args.ack()
  #handling logic

def handler_2(args:Args): 
  args.ack()
  #handling logic


@app.action(re.compile("dynamic_handler_.*"))
def delegate_to_handler(args:Args):
  selected_handler=complex_logic_to_decide_which_handler_to_use(args.action, args.context)
  selected_handler(args)

And then to specify a legal handler is very simple, it's just a Callable[[Args],...]

@eddyg
Copy link
Contributor

eddyg commented Feb 23, 2023

Thanks for providing the example use case! 👍

This definitely makes it more clear why knowing that this functionality is available would be a useful addition to the docs.

@seratch seratch self-assigned this Feb 23, 2023
@seratch seratch added the docs Improvements or additions to documentation label Feb 23, 2023
@seratch seratch added this to the 1.16.3 milestone Feb 23, 2023
@seratch
Copy link
Member

seratch commented Feb 23, 2023

@YSaxon The pull request alreay looks great to me. Can you check @CLAassistant's mesage above? It seems that you're not using the email adress associated with your GitHub user account for the commits. git configure user.email (your email here), git reset HEAD~3, git add ., git commit -m"your comment", and then git push your-fork main -f should resolve the issue. If you have never signed the CLA, you can sign in with your GItHub account.

@seratch
Copy link
Member

seratch commented Feb 23, 2023

The CI build failure with codecov is not caused by this PR. I will look into it.

@YSaxon
Copy link
Contributor Author

YSaxon commented Feb 23, 2023

Thanks for the precise instructions on how to fix the username issue

@seratch seratch changed the title add documention for injected 'args' param option Add documention for injected 'args' param option Feb 23, 2023
@seratch seratch merged commit a747f28 into slackapi:main Feb 23, 2023
@YSaxon
Copy link
Contributor Author

YSaxon commented Feb 23, 2023

By the way, while I have you devs here, there's another issue that's been bothering me forever which I would love to submit a pull request for, but it's in the closed-source backend code, so maybe you can do it for me.

I wrote it up in some detail here
Essentially there is a problem with the text field returned with command or message events. It is inherently not a good representation of the plaintext of what a user saw when they hit enter. And whereas in message events, at least you could parse out the true plaintext from the blocks field, the blocks field is omitted entirely from a command payload (where if anything it is needed more), making it impossible to perfectly recover the plaintext.

Some suggested fixes:

  • Fix the text so it correctly reflects the true plaintext.
  • Add a true_plaintext field, if you are concerned about breaking existing programs
  • Just put the blocks field into the command payload, and I'll parse the true plaintext out myself

@YSaxon
Copy link
Contributor Author

YSaxon commented Feb 23, 2023

@seratch ^

@seratch
Copy link
Member

seratch commented Feb 23, 2023

@YSaxon Thanks for sharing this! I hear you and actually we've received similar feedback many times in the past. I can escalate you feedback this time, however, I don't anticipate the backend engineering teams can prioritize this kind of enhancements at least in the short term, due to priorities and other circumstances. So sorry for the inconvenience.

@YSaxon
Copy link
Contributor Author

YSaxon commented Feb 23, 2023

Ok, but please do pass to them my third suggestion in particular, putting the blocks field into the command payload, as I very strongly suspect that this can be done in seven characters on a single line of code somewhere (adding blocks, to the list of fields being sent) with no side effects anywhere else.

WilliamBergamin added a commit to WilliamBergamin/bolt-python that referenced this pull request Mar 2, 2023
* Fix perform_bot_token_rotation call in AsyncInstallationStoreAuthorize (slackapi#825)

* Fix perform_bot_token_rotation call of AsyncTokenRotator
* Fix pytype inconsistency in [Async]Listener

* version 1.16.2

* Add config.yml for GitHub issues

* Rename GH issue type title

* Update GH issue type titles

* Added redirect url to readme (slackapi#831)

* Add documention for injected 'args' param option (slackapi#835)

* Fix codecov failure starting in Feb, 2023 (slackapi#836)

---------

Co-authored-by: Cristian Caruceru <90720255+ccaruceru@users.noreply.github.com>
Co-authored-by: Kazuhiro Sera <seratch@gmail.com>
Co-authored-by: Kazuhiro Sera <ksera@slack-corp.com>
Co-authored-by: Smyja <akposlive59@gmail.com>
Co-authored-by: Yaakov Saxon <YSaxon@users.noreply.github.com>
@seratch
Copy link
Member

seratch commented Apr 26, 2023

Hi @YSaxon, we apologize for the inconvenience, but we kindly ask that you sign our new CLA: https://cla.salesforce.com/status/slackapi/bolt-python/pull/893

As it is not fully compatible with the previous agreement you signed for this PR, we need your signature once again. Your cooperation and prompt response would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants