Skip to content

Fix #1018 Add optional arguments in WebClient methods#1099

Merged
seratch merged 4 commits intoslackapi:mainfrom
seratch:issue-1018-optional-args
Aug 25, 2021
Merged

Fix #1018 Add optional arguments in WebClient methods#1099
seratch merged 4 commits intoslackapi:mainfrom
seratch:issue-1018-optional-args

Conversation

@seratch
Copy link
Copy Markdown
Contributor

@seratch seratch commented Aug 19, 2021

Summary

This pull request fixes #1018 by adding all the optional arguments in WebClient, AsyncWebClient, and LegacyWebClient.

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

  • slack_sdk.web.WebClient (sync/async) (Web API client)
  • slack_sdk.webhook.WebhookClient (sync/async) (Incoming Webhook, response_url sender)
  • slack_sdk.socket_mode (Socket Mode client)
  • slack_sdk.signature (Request Signature Verifier)
  • slack_sdk.oauth (OAuth Flow Utilities)
  • slack_sdk.models (UI component builders)
  • slack_sdk.scim (SCIM API client)
  • slack_sdk.audit_logs (Audit Logs API client)
  • slack_sdk.rtm_v2 (RTM client)
  • /docs-src (Documents, have you run ./docs.sh?)
  • /docs-src-v2 (Documents, have you run ./docs-v2.sh?)
  • /tutorial (PythOnBoardingBot tutorial)
  • tests/integration_tests (Automated tests for this library)

Requirements (place an x in each [ ])

  • 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 python3 -m venv .venv && source .venv/bin/activate && ./scripts/run_validation.sh after making the changes.

@seratch seratch added enhancement M-T: A feature request for new functionality web-client Version: 3x labels Aug 19, 2021
@seratch seratch added this to the 3.10.0 milestone Aug 19, 2021
):
return self
msg = "The request to the Slack API failed."
msg = f"The request to the Slack API failed. (url: {self.api_url})"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While running tests, I found that this error message does not have sufficient information.

@@ -77,12 +81,7 @@ def admin_analytics_getFile(
**kwargs,
) -> SlackResponse:
"""Retrieve analytics data for a given date, presented as a compressed JSON file

Args:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have all arguments, maintaining Args comment for 240+ API methods becomes more challenging. Instead, we can have a link to the API method document.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will also reduce risk of innacuracy or drift from updates made in one source vs. in the sdk.

"team_id": team_id,
}
)
return self.api_call("admin.apps.approve", params=kwargs)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As some endpoints do not support application/json request body, it's safer to use the form body for most APIs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, but all endpoints support form POSTs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@filmaj Yes, they do but interestingly some endpoints do not support application/json.

@@ -119,32 +114,114 @@ def admin_apps_approve(
"The app_id or request_id argument must be specified."
)

return self.api_call("admin.apps.approve", json=kwargs)
kwargs.update(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we use params (not json), None values will be removed in the api_call method (both async and sync)

kwargs.update({"channel": channel})
kwargs = _filter_none_values(kwargs)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For json=kwargs API calls, having None value in dict can result in null value in JSON data. The Slack API server-side often does not work with the data. Thus, we remove None values here. For params / data, we don't need to worry about it.

@codecov
Copy link
Copy Markdown

codecov bot commented Aug 19, 2021

Codecov Report

Merging #1099 (4541e44) into main (d679144) will increase coverage by 0.06%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1099      +/-   ##
==========================================
+ Coverage   86.20%   86.27%   +0.06%     
==========================================
  Files         110      110              
  Lines        9955    10413     +458     
==========================================
+ Hits         8582     8984     +402     
- Misses       1373     1429      +56     
Impacted Files Coverage Δ
slack_sdk/web/async_client.py 92.06% <ø> (-0.74%) ⬇️
slack_sdk/web/client.py 93.41% <ø> (-1.00%) ⬇️
slack_sdk/web/legacy_client.py 93.11% <ø> (-0.94%) ⬇️
slack_sdk/web/async_slack_response.py 90.47% <100.00%> (ø)
slack_sdk/web/internal_utils.py 94.26% <100.00%> (+0.09%) ⬆️
slack_sdk/web/slack_response.py 93.54% <100.00%> (ø)
slack_sdk/socket_mode/builtin/client.py 79.19% <0.00%> (-0.68%) ⬇️
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d679144...4541e44. Read the comment docs.

@seratch seratch force-pushed the issue-1018-optional-args branch from 01ca6f7 to 9664ec1 Compare August 21, 2021 05:05
@stasfilin
Copy link
Copy Markdown
Contributor

Wow, nice work,
Waiting when it will be release

Copy link
Copy Markdown
Contributor

@srajiang srajiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look really great! Since there are quite a few changes, it will be good to have a few more eyes pass over this for little things missed.

@@ -77,12 +81,7 @@ def admin_analytics_getFile(
**kwargs,
) -> SlackResponse:
"""Retrieve analytics data for a given date, presented as a compressed JSON file

Args:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will also reduce risk of innacuracy or drift from updates made in one source vs. in the sdk.

@@ -158,7 +250,9 @@ def admin_apps_uninstall(
team_ids: Optional[Union[str, Sequence[str]]] = None,
**kwargs,
) -> SlackResponse:
"""Uninstall an app from one or many workspaces, or an entire enterprise organization."""
"""Uninstall an app from one or many workspaces, or an entire enterprise organization.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could note here as we do above for admin.apps.restrict requirements, that with an org-level token, enterprise_id or team_ids is required.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srajiang Thanks. Updated.

org_channel: Optional[bool] = None,
target_team_ids: Optional[Union[str, Sequence[str]]] = None,
team_id: Optional[str] = None,
**kwargs,
) -> SlackResponse:
"""Set the workspaces in an Enterprise grid org that connect to a channel.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can modify to "that connect to a public or private channel"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Perhaps, the description was updated afterwards.

self,
*,
team_id: str,
discoverability: str, # open, invite_only, closed, or unlisted
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it would be better to remove this additional comment, in case in future the API supports other discoverability options and there is a difference between the SDK and the public docs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree wit this!

"""
kwargs.update({"team_id": team_id, "name": name})
return self.api_call("admin.teams.settings.setName", json=kwargs)
return self.api_call("admin.teams.settings.setName", params=kwargs)

def admin_usergroups_addChannels(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason the git UI is preventing me from inserting a comment right at line 1153.

Should we make this an Optional field?

team_id: Optional[str] = None,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right. Updated.

https://api.slack.com/methods/files.remote.remove
"""
kwargs.update({"external_id": external_id, "file": file})
return self.api_call("files.remote.remove", http_verb="POST", params=kwargs)

def files_remote_share(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could check for either file or external_id field here or raise a SlackRequestError

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

def groups_archive(self, *, channel: str, **kwargs) -> SlackResponse:
"""Archives a private channel.
# --------------------------
# Deprecated: groups.*
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as with channels.* comment on deprecation. Could point users to conversations.* mapped API methods.

Args:
channel (str): Direct message channel to close. e.g. 'D1234567890'
"""
def im_close(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is no longer publicly listed on our API docs, even as a deprecated method. Should we remove support for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove it in the near future but I didn't do so this time

Args:
channel (str): Multiparty Direct message channel to close. e.g. 'G1234567890'
"""
def mpim_close(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as im.close


def reminders_add(self, *, text: str, time: str, **kwargs) -> SlackResponse:
def reminders_add(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an unusual options field for recurrence which is not as well documented. Though from investigating it looks like it would accept a string. Did you omit on purpose for now?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I just missed the one. Added with optional str type

Copy link
Copy Markdown
Contributor

@filmaj filmaj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I appreciate the links to the methods in the function header.

Copy link
Copy Markdown
Contributor Author

@seratch seratch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srajiang @filmaj Thanks for helpful comments! I just fixed all of the issues detected here

"team_id": team_id,
}
)
return self.api_call("admin.apps.approve", params=kwargs)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@filmaj Yes, they do but interestingly some endpoints do not support application/json.

@@ -158,7 +250,9 @@ def admin_apps_uninstall(
team_ids: Optional[Union[str, Sequence[str]]] = None,
**kwargs,
) -> SlackResponse:
"""Uninstall an app from one or many workspaces, or an entire enterprise organization."""
"""Uninstall an app from one or many workspaces, or an entire enterprise organization.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srajiang Thanks. Updated.

org_channel: Optional[bool] = None,
target_team_ids: Optional[Union[str, Sequence[str]]] = None,
team_id: Optional[str] = None,
**kwargs,
) -> SlackResponse:
"""Set the workspaces in an Enterprise grid org that connect to a channel.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Perhaps, the description was updated afterwards.

self,
*,
team_id: str,
discoverability: str, # open, invite_only, closed, or unlisted
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree wit this!

"""
kwargs.update({"team_id": team_id, "name": name})
return self.api_call("admin.teams.settings.setName", json=kwargs)
return self.api_call("admin.teams.settings.setName", params=kwargs)

def admin_usergroups_addChannels(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right. Updated.

ts: str,
cursor: Optional[str] = None,
inclusive: Optional[bool] = None,
latest: Optional[str] = None,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srajiang we should not recommend using float values for ts, in general. See slackapi/node-slack-sdk#780 (comment)

external_url: str,
title: str,
filetype: Optional[str] = None,
indexable_file_contents: Optional[str] = None,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch - fixed!

https://api.slack.com/methods/files.remote.remove
"""
kwargs.update({"external_id": external_id, "file": file})
return self.api_call("files.remote.remove", http_verb="POST", params=kwargs)

def files_remote_share(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Args:
channel (str): Direct message channel to close. e.g. 'D1234567890'
"""
def im_close(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove it in the near future but I didn't do so this time


def reminders_add(self, *, text: str, time: str, **kwargs) -> SlackResponse:
def reminders_add(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I just missed the one. Added with optional str type

@seratch seratch merged commit fada5dc into slackapi:main Aug 25, 2021
@seratch seratch deleted the issue-1018-optional-args branch August 25, 2021 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement M-T: A feature request for new functionality Version: 3x web-client

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add optional arguments in WebClient methods

5 participants