Code Monkey home page Code Monkey logo

slackblocks's Introduction

slackblocks

Licence: MIT Licence: BSD-3-Clause Python Versions PyPI Downloads Build Status Docs

What is it?

slackblocks is a Python API for building messages in the fancy Slack Block Kit API

Documentation

Full documentation is provided here.

Requirements

slackblocks requires Python >= 3.8.

As of version 0.1.0 it has no dependencies outside the Python standard library.

Installation

pip install slackblocks

Basic Usage

from slackblocks import Message, SectionBlock


block = SectionBlock("Hello, world!")
message = Message(channel="#general", blocks=block)
message.json()

Will produce the following JSON string:

{
    "channel": "#general",
    "mrkdwn": true,
    "blocks": [
        {
            "type": "section",
            "block_id": "992ceb6b-9ad4-496b-b8e6-1bd8a632e8b3",
            "text": {
                "type": "mrkdwn",
                "text": "Hello, world!"
            }
        }
    ]
}

Which can be sent as payload to the Slack message API HTTP endpoints.

Of more practical uses is the ability to unpack the objects directly into the Python Slack Client in order to send messages:

from os import environ
from slack import WebClient
from slackblocks import Message, SectionBlock


client = WebClient(token=environ["SLACK_API_TOKEN"])
block = SectionBlock("Hello, world!")
message = Message(channel="#general", blocks=block)

response = client.chat_postMessage(**message)

Note the ** operator in front of the message object.

Can I use this in my project?

Yes, please do! The code is all open source and dual BSD-3.0 and MIT licensed (use what suits you best).

slackblocks's People

Contributors

andreweckart avatar bejocke avatar braewebb avatar confiq avatar dependabot[bot] avatar fedirz avatar foobic avatar k8skween avatar kennethtxytqw avatar kigsmtua avatar nicklambourne avatar palewire avatar rizenfrmtheashes avatar tho-can-code avatar white-hat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

slackblocks's Issues

Support acknowledgement responses to user interactions

When responding to interactions, it's necessary for the API server which receives the interaction to construct an acknowledgement response. The response payload can be a message, formatted in the usual way (i.e. {"blocks": [..]}, but this message doesn't require a channel property and can also include a replace_original: true attribute to replace the message which was interacted with.

Proposal is to make channel optional, or create a base class BaseMessage which is subclassed for regular messages and acknowledgement responses.

ExternalSelectMenu initial_option does not automatically serialize Option object

Problem:
When trying to resolve an ExternalSelectMenu inside of an Input block the initial_option accepts Option | OptionGroup, but does not serialize it to JSON before sending to slack.

Workaround:
-When creating the blocks pre-resolving the initial option via ._resolve()

Does not work:

  try:
    return InputBlock(
      label="example label",
      optional=True,
      block_id="deployable_apps_tag_select",
      element=ExternalSelectMenu(
        action_id="deployable_apps_select_tag",
        placeholder="example placeholder",
        min_query_length=0,
        initial_option=Option(text=Text(text="test_text", type_=TextType.PLAINTEXT), value="test_value")
      )
    )
  except Exception as e:
    logger.warning(f"Failed to create tag select block: {e})")
    raise e

Workaround:

  try:
    return InputBlock(
      label="example label",
      optional=True,
      block_id="deployable_apps_tag_select",
      element=ExternalSelectMenu(
        action_id="deployable_apps_select_tag",
        placeholder="example placeholder",
        min_query_length=0,
        initial_option=Option(text=Text(text="test_text", type_=TextType.PLAINTEXT), value="test_value")._resolve()
      )
    )
  except Exception as e:
    logger.warning(f"Failed to create tag select block: {e})")
    raise e

Possible solution:

Updating the _resolve() function here to automatically resolve the initial option

external_select_menu["initial_option"] = self.initial_option

Caveats and Questions:
-Being that this is not a MultiExternalSelectMenu, it may not accept multiple options as an initial value and the schema should be checked to see if the constructor for ExternalSelectMenu should only accept Option as opposed to Option | OptionGroup

-This issue seems to be isolated to just the ExternalSelectMenu as it is working correctly for MultiExternalSelectMenu

initial_option._resolve() for initial_option in self.initial_options

How to use Button Element?

Dear @nicklambourne

I have tried

SectionBlock(text="For Test Button",accessory=Button(action_id="1", text="Choose"))

But got error

The server responded with: {'ok': False, 'error': 'invalid_blocks', 'response_metadata': {'messages': ['[ERROR] must be a valid enum value ...

It worked fine without accessory

SectionBlock(text="For Test Button")

Would you please guide me how to generate button?
Thank you so much.

SectionBlock text doesn't allow null or none

I need to pass null value for text=None, but I am getting error that empty or null string are not allowed.
But in the code it is optional
SectionBlock( fields=[Text(text="version", type_=TextType.PLAINTEXT))

def init(
self,
text: Optional[TextLike] = None,
block_id: Optional[str] = None,
fields: Optional[List[Text]] = None,
accessory: Optional[Element] = None,
):

Version installed 0.9.6

Resolve function is called for every key

Hey,

I'm using the message class and I noticed that __get__ is implemented using resolve in order to get each value,
this means that when **message is used the message is resolved once for the keys method and then again for every key.

I found it better to just use **message._resolve() this way a dictionary is returned and _resolve is called once.

I think making resolve a public function can be a great option to solve this issue.

Inputblock missing

Cannot use input elements in slack blocks due to missing Input block in .blocks

StaticSelectMenu & StaticMultiSelectMenu do not support default Option TextType

Problem:
When using the default TextType created when using the Option constructor inside or appended to a StaticMultiSelectMenu or StaticSelectMenu a schema error is returned from slack due to these not supporting the markdown TextType.

Based on the documentation there seems to be a supported and unsupported category.

Supporting Slack documentation:
"Overflow, select, and multi-select menus can only use plain_text objects, while radio buttons and checkboxes can use mrkdwn text objects." - LINK

Testing:

Working:

modal = ModalView(
    title="Example_Modal",
    submit="Submit",
    close="Cancel",
    callback_id="example_callback_id",
    blocks=[
      SectionBlock(text="Select a branch to deploy"),
      InputBlock(
        label="Branch",
        element=StaticSelectMenu(
          placeholder="Select a branch",
          action_id="branch_select",
          options=[
            Option(text=Text(text="branch-a",type_=TextType.PLAINTEXT), value="branch-a"),
            Option(text=Text(text="branch-b",type_=TextType.PLAINTEXT), value="branch-b"),
            Option(text=Text(text="branch-c",type_=TextType.PLAINTEXT), value="branch-c"),
          ],
        ),
      ),
      SectionBlock(text="Select the environment(s) to deploy to"),
      InputBlock(
        label="Environments",
        element=StaticMultiSelectMenu(
          placeholder="Select environments",
          action_id="deploy_to_env",
          options=[
            Option(text=Text(text="dev",type_=TextType.PLAINTEXT), value="dev"),
            Option(text=Text(text="preprod",type_=TextType.PLAINTEXT), value="preprod"),
            Option(text=Text(text="prod",type_=TextType.PLAINTEXT), value="prod"),
          ],
        ),
      ),
    ],
  )

Not working:

modal = ModalView(
  title="Example_Modal",
  submit="Submit",
  close="Cancel",
  callback_id="example_callback_id",
  blocks=[
    SectionBlock(text="Select a branch to deploy"),
    InputBlock(
      label="Branch",
      element=StaticSelectMenu(
        placeholder="Select a branch",
        action_id="branch_select",
        options=[
          Option(text="branch-a", value="branch-a"),
          Option(text="branch-b", value="branch-b"),
          Option(text="branch-c", value="branch-c"),
        ],
      ),
    ),
    SectionBlock(text="Select the environment(s) to deploy to"),
    InputBlock(
      label="Environments",
      element=StaticMultiSelectMenu(
        placeholder="Select environments",
        action_id="deploy_to_env",
        options=[
          Option(text="dev", value="dev"),
          Option(text="preprod", value="preprod"),
          Option(text="prod", value="prod"),
        ],
      ),
    ),
  ],
)

Error:

Error opening modal: The request to the Slack API failed. (url: https://www.slack.com/api/views.open)
The server responded with: {'ok': False, 'error': 'invalid_arguments', 'response_metadata': {'messages': ['[ERROR] failed to match all allowed schemas [json-pointer:/view]', '[ERROR] failed to match all allowed schemas [json-pointer:/view/blocks/1/element/options/0/text]', '[ERROR] must be a valid enum value [json-pointer:/view/blocks/1/element/options/0/text/type]', '[ERROR] failed to match all allowed schemas [json-pointer:/view/blocks/1/element/options/1/text]', '[ERROR] must be a valid enum value [json-pointer:/view/blocks/1/element/options/1/text/type]', '[ERROR] failed to match all allowed schemas [json-pointer:/view/blocks/1/element/options/2/text]', '[ERROR] must be a valid enum value [json-pointer:/view/blocks/1/element/options/2/text/type]', '[ERROR] failed to match all allowed schemas [json-pointer:/view/blocks/3/element/options/0/text]', '[ERROR] must be a valid enum value [json-pointer:/view/blocks/3/element/options/0/text/type]', '[ERROR] failed to match all allowed schemas [json-pointer:/view/blocks/3/element/options/1/text]', '[ERROR] must be a valid enum value [json-pointer:/view/blocks/3/element/options/1/text/type]', '[ERROR] failed to match all allowed schemas [json-pointer:/view/blocks/3/element/options/2/text]', '[ERROR] must be a valid enum value [json-pointer:/view/blocks/3/element/options/2/text/type]']}}

Possible Resolution:
-Add a check to the constructors to error if the TextType of any of the options is mrkdwn

ModalView contains extra field submit_disabled, needs to be removed

SlackClientError("The request to the Slack API failed.\nThe server responded with: {'ok': False, 'error': 'invalid_arguments', 'response_metadata': {'messages': ['[ERROR] failed to match all allowed schemas [json-pointer:/view]', '[ERROR] invalid additional property: submit_disabled [json-pointer:/view]']}}")

Initial users appears to be broken on the UserMultiSelectMenu

    multi_select_user = UserMultiSelectMenu(
        action_id="multi_users_select",
        placeholder=Text("Select one or more users", type_=TextType.PLAINTEXT),
        initial_users=["U064B5H1309", "U063JR973UP"],
    )

Given the above piece of code, looks like the initial_users fails to render with the below error

    user_multi_select["initial_users"] = [
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <list_iterator object at 0x7fdaa37a6b00>

    user_multi_select["initial_users"] = [
>       initial_option._resolve() for initial_option in self.initial_users
    ]
E   AttributeError: 'str' object has no attribute '_resolve'

This looks to be a case of the initial_users being specified as a list of strings, but we try to call the _resolve method from all the elements in intial_users, which will of course fail.

I am happy to push a fix for this.

Cannot create a modal view without submit button

File "/Users/nikhilxavier/Documents/sa-backend/services/slackblock_services.py", line 214, in basic_message_modal
    view = ModalView(
           ^^^^^^^^^^
  File "/Users/nikhilxavier/Documents/sa-backend/venv/lib/python3.11/site-packages/slackblocks/views.py", line 80, in __init__
    self.submit = Text.to_text(submit, force_plaintext=True, max_length=24)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/nikhilxavier/Documents/sa-backend/venv/lib/python3.11/site-packages/slackblocks/objects.py", line 114, in to_text
    raise InvalidUsageError("This field cannot have the value None or ''")
slackblocks.errors.InvalidUsageError: This field cannot have the value None or ''

Tried using the modal view to create a basic modal popup with just a close button, but could not do so since modalview is expecting submit field by default although its default is None. I.e
image
basically converting to text is causing an issue since allow_none is set to false by default!

SectionBlock should maybe make the text input optional

I have been able to submit section blocks to the Slack API with only fields, and no text attribute. I don't think your class allows that. I propose making the input optional. If you agree, I'd be happy to submit a patch.

class SectionBlock(Block):
"""
A section is one of the most flexible blocks available -
it can be used as a simple text block, in combination with text fields,
or side-by-side with any of the available block elements.
"""
def __init__(self,
text: Union[str, Text],
block_id: Optional[str] = None,
fields: Optional[List[Text]] = None,
accessory: Optional[Element] = None):
super().__init__(type_=BlockType.SECTION,
block_id=block_id)
if type(text) is Text:
self.text = text
else:
self.text = Text(text)
self.fields = fields
self.accessory = accessory
def _resolve(self) -> Dict[str, Any]:
section = self._attributes()
section["text"] = self.text._resolve()
if self.fields:
section["fields"] = [field._resolve() for field in self.fields]
if self.accessory:
section["accessory"] = self.accessory._resolve()
return section

RIchTextList and nested RIchText issues

Hello, i am trying to create this block :

{ "blocks": [ { "type": "divider" }, { "type": "rich_text", "elements": [ { "type": "rich_text_section", "elements": [ { "type": "text", "text": "10:00 - Lorem ipsum blaba\n" } ] }, { "type": "rich_text_list", "style": "bullet", "indent": 0, "border": 0, "elements": [ { "type": "rich_text_section", "elements": [ { "type": "text", "text": "10:00 - Lorem ipsum two " }, { "type": "emoji", "name": "white_check_mark", "unicode": "2705" }, { "type": "text", "text": " " } ] }, { "type": "rich_text_section", "elements": [ { "type": "text", "text": "10:01 - lorem ipsum 3! " }, { "type": "emoji", "name": "white_check_mark", "unicode": "2705" }, { "type": "text", "text": " " } ] } ] } ] }, { "type": "divider" } ] }

I am trying like this:

status = RichTextSection([ RichText(text="10;00 - Lorem ipsum blaba\n", bold=True), RichTextList(style="bullet", elements=( RichTextSection([ RichText("10:00 - Lorem ipsum two \n"), RichText("10:01 - Lorem ipsum3!\n"), ]) )) ])

and i get the following error

} (<class 'slackblocks.rich_text.objects.RichTextList'>)) inconsistent with expected type (<class 'slackblocks.rich_text.elements.RichTextChannel'>, <class 'slackblocks.rich_text.elements.RichTextEmoji'>, <class 'slackblocks.rich_text.elements.RichTextLink'>, <class 'slackblocks.rich_text.elements.RichText'>, <class 'slackblocks.rich_text.elements.RichTextUser'>, <class 'slackblocks.rich_text.elements.RichTextUserGroup'>).

I have no idea how to fix this? Can anyone help me?

Thanks

Slack Client requires a dict for publishing views

Slack's official web client requires a dict[Unknown, Unknown] when publishing views, and would not work unless I am calling the private _resolve() method when using HomeTabView.

v = HomeTabView(...)
client.views_publish(..., view=v._resolve())

I have noticed that you have added a to_dict() method in #17 so I am wondering if it's okay to do the same for Views.

If that is okay with you, I'll be happy to submit a small PR to add it for Views.

DatePicker errors when not given optional inital_date on creation.

Problem:
DatePicker errors when calling _resolve is the optional variable initial_date is not given

Testing(This is nested inside a ModalView that renders perfectly when it is initialized with initial_date is provided):
I am just going to provide the part of the code that stands out

delete_after_block = InputBlock(
        label=Text("Delete After",type_=TextType.PLAINTEXT, emoji=True),
        element=DatePicker(
            action_id="datepicker-action",
            #set to current date plus 4 days as unix timestamp in second
            #initial_date = str(datetime.now().date() + timedelta(days=4)),
        ),
        block_id="delete_after_block"
    )

Error:

Failed to run listener function (error: 'DatePicker' object has no attribute 'initial_date')
Traceback (most recent call last):
 File "/opt/homebrew/lib/python3.11/site-packages/slack_bolt/listener/thread_runner.py", line 120, in run_ack_function_asynchronously
   listener.run_ack_function(request=request, response=response)
 File "/opt/homebrew/lib/python3.11/site-packages/slack_bolt/listener/custom_listener.py", line 50, in run_ack_function
   return self.ack_function(
          ^^^^^^^^^^^^^^^^^^
 File "/Users/victoriamann/Source/slack-workflow-server/platform-bot/src/main.py", line 49, in platform_bot_test
   view=modal_view.to_dict()
        ^^^^^^^^^^^^^^^^^^^^
 File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/views.py", line 54, in to_dict
   return self._resolve()
          ^^^^^^^^^^^^^^^
 File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/views.py", line 93, in _resolve
   modal_view = super()._resolve()
                ^^^^^^^^^^^^^^^^^^
 File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/views.py", line 44, in _resolve
   view["blocks"] = [block._resolve() for block in self.blocks]
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/views.py", line 44, in <listcomp>
   view["blocks"] = [block._resolve() for block in self.blocks]
                     ^^^^^^^^^^^^^^^^
 File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/blocks.py", line 269, in _resolve
   input_block["element"] = self.element._resolve()
                            ^^^^^^^^^^^^^^^^^^^^^^^
 File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/elements.py", line 180, in _resolve
   if self.initial_date:
      ^^^^^^^^^^^^^^^^^
AttributeError: 'DatePicker' object has no attribute 'initial_date'

When the line with the inital_date is uncommentated it works perfectly.

Relevant documentation

initial_date is an optional field in the constructor and for the Slack API.

Possible fix: Update the _resolve method to omit the field when it is set to its default value of None

ActionsBlock throws AttributeError: 'ActionsBlock' object has no attribute 'elements' in `Message.json()`

ActionsBlock throws AttributeError: 'ActionsBlock' object has no attribute 'elements' in Message.json().

Minimal reproducer:

from slackblocks import ActionsBlock, SectionBlock, ContextBlock, Button, Text, Message

username = "newuser"
text_section = SectionBlock(f"New signup from {username}")
approve_btn = Button("Approve", action_id="accept_user", value=username, style="primary")
reject_btn = Button("Reject", action_id="reject_user", value=username, style="danger")
actions = ActionsBlock([approve_btn, reject_btn])
msg = Message(channel='signups', blocks=[text_section, actions]).json()
print(msg)

Cannot create UserSelectMenu object with placeholder=None

UserSelectMenu requires only one positional argument: 'action_id' but when:
slackblocks.UserSelectMenu('action')
then
self.placeholder = Text.to_text(
^^^^^^^^^^^^^
raise InvalidUsageError("This field cannot have the value None or ''")
slackblocks.errors.InvalidUsageError: This field cannot have the value None or ''

Problem with SectionBlock and fields

I'm having code like this

from slackblocks import Message, SectionBlock, ContextBlock, Text, DividerBlock, TextType

foo = SectionBlock("Test:", fields=[Text(text='foo')])
message = Message(channel="#general", blocks=foo)
message.json()

But I'm getting the following:

❯ python test.py                                                                                                                                                                                                                   ─╯
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    message.json()
  File "/Users/confiq/work/infra-iac/venv/lib/python3.7/site-packages/slackblocks/messages.py", line 46, in json
    return dumps(self._resolve(), indent=4)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 201, in encode
    chunks = list(chunks)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 431, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 325, in _iterencode_list
    yield from chunks
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 405, in _iterencode_dict
    yield from chunks
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 325, in _iterencode_list
    yield from chunks
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 438, in _iterencode
    o = _default(o)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Text is not JSON serializable

It seems it's a bug so I wanted to confirm here if it's a bug or I misread the library.

This is the json that I expect to render: api-slack-block-builder

❯ python --version
Python 3.7.7

❯ pip freeze | grep slack
slackblocks==0.1.5

Are checkboxes supported?

Are checkboxes supported, if not is there any plan to add them?

I can't seem to find any check box classes so im assuming they're not implented

DateTimePicker not in ALLOWED_INPUT_ELEMENTS for InputBlock

Problem: DateTimePicker is now allowed inside of InputBlock

Testing:

Code:

InputBlock(label="Select Branch", element=DateTimePicker(action_id="datetimepicker-action",initial_datetime = 1628633820))

Error:

    print(InputBlock(label="Select Branch", element=DateTimePicker(action_id="datetimepicker-action",initial_datetime = 1628633820)))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/slackblocks/blocks.py", line 258, in __init__
    raise InvalidUsageError("")
slackblocks.errors.InvalidUsageError

Documentation: LINK
I tested this this in a slack block editor to make sure it works inside a InputBlock

Caveats: This is only available on Desktop and only in Modal or Messages

Possible Resolution: Add DateTimePicker to the constant HERE

StaticMultiSelectMenu not allowing initial_options due typing.

Heyh @nicklambourne!
Love your lib, but I have an issue using StaticMultiSelectMenu with initial_values.

InputBlock(
      "Ticket Tags",
      element = StaticMultiSelectMenu("ticket_tags",
                            options=[
                                  Option(Text("Label1", TextType.PLAINTEXT), value="1"),
                                  Option(Text("Label2", TextType.PLAINTEXT), value="2")
                              ],
                            initial_options=[
                                  Option(Text("Label1", TextType.PLAINTEXT), value="1")
                              ]
                          )
)

I got the following error,

  File "/[REDACTED]/venv/lib/python3.10/site-packages/slackblocks/elements.py", line 520, in __init__
    and not isinstance(self.initial_options, List[Option])
  File "/usr/lib/python3.10/typing.py", line 994, in __instancecheck__
    return self.__subclasscheck__(type(obj))
  File "/usr/lib/python3.10/typing.py", line 997, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
TypeError: Subscripted generics cannot be used with class and instance checks

As per my investigation, Python's runtime does not support checking for specific types within generics. In this case a generic (list) as a list of Options. If you use this code you'll see that it gets the same error.

from typing import List

class Option:
    pass

# Suppose you have an instance of some options
options = [Option(), Option()]

# And you try to check if 'options' is an instance of a list of Option objects
isinstance(options, List[Option])  # This will raise the error

If we check all objects in the initial_options are actually Option class it works.

if (
      options
      and self.initial_options
      and not all(isinstance(option, Option) for option in self.initial_options) # line 520
   ):

I modify it on my local machine and it works. What do you think?

list of block in blocks attribute

Hi,
I'm trying to use this module and adding many blocks on the blocks attribute:

    message = Message(channel="team-developments",
                      blocks=[header, divider, intro_section, org_section, divider, doc_section])

but when I try to send the message with the client I receive the following error

TypeError: chat_postMessage() argument after ** must be a mapping, not Message

do you have any hint on how to solve?

thanks

ContextBlock elements arg has the wrong type

In the ContextBlock init, the elements arg might have the wrong type.

I think it's currently elements: Optional[List[Union[Element, CompositionObjectType]]] = None,
but I think CompositionObjectType should be CompositionObject.

Because CompositionObjectType refers to the enum type, but the CompositionObject refers to the actual element/object.

Here's the typeerror being thrown, and Text should be subclassing CompositionObject

Screenshot 2024-04-23 at 10 23 28 AM
Screenshot 2024-04-23 at 10 23 42 AM

Question: Supported way to use slackblocks with WebhookClient

Hello!

We have a few slack apps that rely on app based incoming webhooks. We utilize the WebhookClient class in the SDK to interface with this. It doesn't require a few of the fields, like channel or text. Is there a supported way to pass the blocks in (aside from dropping them into a Message instance and grabbing the blocks from that?)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.