From 7d4673e21d227819d2b86dab37b5201cf31067e5 Mon Sep 17 00:00:00 2001 From: Trygve Aaberge Date: Sat, 14 Jan 2023 13:25:49 +0100 Subject: Add type for users.info --- mock_data/slack_users_info_bot.json | 53 +++++++++++++++++++ mock_data/slack_users_info_person.json | 49 ++++++++++++++++++ scripts/update_mocks.sh | 3 ++ slack/slack_api.py | 3 +- slack/slack_user.py | 3 ++ typings/slack_api/slack_users_info.pyi | 94 ++++++++++++++++++++++++++++++++++ 6 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 mock_data/slack_users_info_bot.json create mode 100644 mock_data/slack_users_info_person.json create mode 100644 typings/slack_api/slack_users_info.pyi diff --git a/mock_data/slack_users_info_bot.json b/mock_data/slack_users_info_bot.json new file mode 100644 index 0000000..2439dc9 --- /dev/null +++ b/mock_data/slack_users_info_bot.json @@ -0,0 +1,53 @@ +{ + "ok": true, + "user": { + "id": "UU6635U31", + "team_id": "T0FC8BFQR", + "name": "polly", + "deleted": false, + "color": "e0a729", + "real_name": "Polly", + "tz": "America/Los_Angeles", + "tz_label": "Pacific Standard Time", + "tz_offset": -28800, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "Polly", + "real_name_normalized": "Polly", + "display_name": "", + "display_name_normalized": "", + "fields": {}, + "status_text": "", + "status_emoji": "", + "status_emoji_display_info": [], + "status_expiration": 0, + "avatar_hash": "ec326dfe553b", + "api_app_id": "A04E6JX41", + "always_active": true, + "image_original": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_original.png", + "is_custom_image": true, + "bot_id": "BTU6APY9F", + "image_24": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_24.png", + "image_32": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_32.png", + "image_48": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_48.png", + "image_72": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_72.png", + "image_192": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_192.png", + "image_512": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_512.png", + "image_1024": "https://avatars.slack-edge.com/2020-11-19/1515013890914_ec326dfe553bb6b94d09_1024.png", + "status_text_canonical": "", + "team": "T0FC8BFQR" + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": true, + "is_app_user": false, + "updated": 1664912039, + "is_email_confirmed": false, + "who_can_share_contact_card": "EVERYONE" + } +} diff --git a/mock_data/slack_users_info_person.json b/mock_data/slack_users_info_person.json new file mode 100644 index 0000000..14e80f8 --- /dev/null +++ b/mock_data/slack_users_info_person.json @@ -0,0 +1,49 @@ +{ + "ok": true, + "user": { + "id": "U017V7T2D40", + "team_id": "T0FC8BFQR", + "name": "trygveaa_wee-slack-te", + "deleted": false, + "color": "684b6c", + "real_name": "Test 1", + "tz": "Europe/Amsterdam", + "tz_label": "Central European Time", + "tz_offset": 3600, + "profile": { + "title": "", + "phone": "", + "skype": "", + "real_name": "Test 1", + "real_name_normalized": "Test 1", + "display_name": "Test 1", + "display_name_normalized": "Test 1", + "fields": {}, + "status_text": "", + "status_emoji": "", + "status_emoji_display_info": [], + "status_expiration": 0, + "avatar_hash": "g57ba37781eb", + "email": "trygveaa+wee-slack-test.1@gmail.com", + "image_24": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-24.png", + "image_32": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-32.png", + "image_48": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-48.png", + "image_72": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-72.png", + "image_192": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-192.png", + "image_512": "https://secure.gravatar.com/avatar/57ba37781ebc7fcdf8cc9812dce9c407.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-512.png", + "status_text_canonical": "", + "team": "T0FC8BFQR" + }, + "is_admin": false, + "is_owner": false, + "is_primary_owner": false, + "is_restricted": false, + "is_ultra_restricted": false, + "is_bot": false, + "is_app_user": false, + "updated": 1664912039, + "is_email_confirmed": true, + "has_2fa": false, + "who_can_share_contact_card": "EVERYONE" + } +} diff --git a/scripts/update_mocks.sh b/scripts/update_mocks.sh index 5348796..7c029fb 100755 --- a/scripts/update_mocks.sh +++ b/scripts/update_mocks.sh @@ -20,3 +20,6 @@ curl_slack "$api_base/conversations.info?channel=GNLENA84B" | jq . > mock_data/s curl_slack "$api_base/conversations.info?channel=C042VL9076F" | jq . > mock_data/slack_info_mpim_channel.json curl_slack "$api_base/conversations.info?channel=GKHEJUM1N" | jq . > mock_data/slack_info_mpim_group.json curl_slack "$api_base/conversations.info?channel=D9N2KD0V6" | jq . > mock_data/slack_info_im.json + +curl_slack "$api_base/users.info?user=U017V7T2D40" | jq . > mock_data/slack_users_info_person.json +curl_slack "$api_base/users.info?user=UU6635U31" | jq . > mock_data/slack_users_info_bot.json diff --git a/slack/slack_api.py b/slack/slack_api.py index aeaf6be..ef522d0 100644 --- a/slack/slack_api.py +++ b/slack/slack_api.py @@ -10,6 +10,7 @@ from slack.shared import shared if TYPE_CHECKING: from slack_api.slack_conversations_info import SlackConversationsInfoResponse from slack_api.slack_users_conversations import SlackUsersConversationsResponse + from slack_api.slack_users_info import SlackUsersInfoResponse from slack.slack_conversation import SlackConversation from slack.slack_user import SlackUser @@ -78,5 +79,5 @@ class SlackApi: pages, ) - async def fetch_users_info(self, user: SlackUser) -> Any: + async def fetch_users_info(self, user: SlackUser) -> SlackUsersInfoResponse: return await self._fetch("users.info", {"user": user.id}) diff --git a/slack/slack_user.py b/slack/slack_user.py index 18c897f..6cb3897 100644 --- a/slack/slack_user.py +++ b/slack/slack_user.py @@ -18,4 +18,7 @@ class SlackUser: async def init(self): info = await self.api.fetch_users_info(self) + if info["ok"] is False: + # TODO: Handle error + return self.name = info["user"]["name"] diff --git a/typings/slack_api/slack_users_info.pyi b/typings/slack_api/slack_users_info.pyi new file mode 100644 index 0000000..433255e --- /dev/null +++ b/typings/slack_api/slack_users_info.pyi @@ -0,0 +1,94 @@ +from __future__ import annotations + +from typing import Dict, Generic, List, Literal, TypedDict, TypeVar, final + +T = TypeVar("T") + +class SlackProfileCommon(TypedDict): + title: str + phone: str + skype: str + real_name: str + real_name_normalized: str + display_name: str + display_name_normalized: str + fields: Dict # pyright: ignore [reportMissingTypeArgument] + status_text: str + status_emoji: str + status_emoji_display_info: List # pyright: ignore [reportMissingTypeArgument] + status_expiration: int + avatar_hash: str + image_24: str + image_32: str + image_48: str + image_72: str + image_192: str + image_512: str + status_text_canonical: str + team: str + +@final +class SlackProfilePerson(SlackProfileCommon): + email: str + +@final +class SlackProfileBot(SlackProfileCommon): + api_app_id: str + always_active: bool + image_original: str + is_custom_image: bool + bot_id: str + image_1024: str + +class SlackUsersInfoCommon(TypedDict): + id: str + team_id: str + name: str + deleted: bool + color: str + real_name: str + tz: str + tz_label: str + tz_offset: int + is_admin: bool + is_owner: bool + is_primary_owner: bool + is_restricted: bool + is_ultra_restricted: bool + is_app_user: bool + updated: int + is_email_confirmed: bool + who_can_share_contact_card: str + +@final +class SlackUsersInfoPerson(SlackUsersInfoCommon): + profile: SlackProfilePerson + is_bot: Literal[False] + has_2fa: bool + +@final +class SlackUsersInfoBot(SlackUsersInfoCommon): + profile: SlackProfileBot + is_bot: Literal[True] + +SlackUsersInfo = SlackUsersInfoPerson | SlackUsersInfoBot + +@final +class SlackUsersInfoErrorResponse(TypedDict): + ok: Literal[False] + error: str + +@final +class SlackUsersInfoSuccessResponse(TypedDict, Generic[T]): + ok: Literal[True] + user: T + +SlackUsersInfoPersonResponse = ( + SlackUsersInfoSuccessResponse[SlackUsersInfoPerson] | SlackUsersInfoErrorResponse +) +SlackUsersInfoBotResponse = ( + SlackUsersInfoSuccessResponse[SlackUsersInfoBot] | SlackUsersInfoErrorResponse +) +SlackUsersInfoResponse = ( + SlackUsersInfoSuccessResponse[SlackUsersInfo] | SlackUsersInfoErrorResponse +) -- cgit