diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..4a08579c2 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,12 @@ +# Salesforce Open Source project configuration +# Learn more: https://github.com/salesforce/oss-template +#ECCN:Open Source +#GUSINFO:Open Source,Open Source Workflow + +# @slackapi/slack-platform-python +# are code reviewers for all changes in this repo. +* @slackapi/slack-platform-python + +# @slackapi/developer-education +# are code reviewers for changes in the `/docs` directory. +/docs/ @slackapi/developer-education diff --git a/.github/dependabot.yml b/.github/dependabot.yml index dc523d227..ac86badc1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,6 +8,8 @@ updates: schedule: interval: "monthly" open-pull-requests-limit: 5 + ignore: + - dependency-name: "black" - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/maintainers_guide.md b/.github/maintainers_guide.md index 57ad6b689..ccda1607f 100644 --- a/.github/maintainers_guide.md +++ b/.github/maintainers_guide.md @@ -10,20 +10,20 @@ this project. If you use this package within your own software as is but don't p We recommend using [pyenv](https://github.com/pyenv/pyenv) for Python runtime management. If you use macOS, follow the following steps: -```bash -$ brew update -$ brew install pyenv +```sh +brew update +brew install pyenv ``` You can hook `pyenv` into your shell automatically by running `pyenv init` and following the instructions. Install necessary Python runtimes for development/testing. It is not necessary to install all the various Python versions we test in [continuous integration on -GitHub Actions](https://github.com/slackapi/python-slack-sdk/blob/main/.github/workflows/ci-build.yml), +GitHub Actions](https://github.com/slackapi/python-slack-sdk/blob/main/.github/workflows/tests.yml), but make sure you are running at least one version that we execute our tests in locally so that you can run the tests yourself. -```bash +```sh $ pyenv install -l | grep -v "-e[conda|stackless|pypy]" $ pyenv install 3.9.6 # select the latest patch version @@ -40,9 +40,9 @@ $ pyenv rehash Then, you can create a new [Virtual Environment](https://docs.python.org/3/tutorial/venv.html) specific to the Python version you just installed by running: -```bash -$ python -m venv env_3.9.6 -$ source env_3.9.6/bin/activate +```sh +python -m venv env_3.9.6 +source env_3.9.6/bin/activate ``` At this point you have a clean, Python-version-specific environment "activated" for @@ -55,8 +55,8 @@ run `source env_3.9.6/bin/activate` again. The last step is to install this project's dependencies and run all unit tests; to do so, you can run -```bash -$ ./scripts/run_validation.sh +```sh +./scripts/run_validation.sh ``` Also check out [how @@ -65,28 +65,36 @@ our continuous integration](https://github.com/slackapi/python-slack-sdk/blob/v3 ## Tasks +### Formatting + +This project uses code formatting tools to maintain consistent style. You can format the codebase by running: + +```sh +./scripts/format.sh +``` + ### Testing #### Unit Tests When you make changes to this SDK, please write unit tests verifying if the changes work as you expected. You can easily run all the tests and formatting/linter with the below scripts. -Run all the unit tests, code formatter, and code analyzer: +Run all the unit tests, code linter, and code analyzer: -```bash -$ ./scripts/run_validation.sh +```sh +./scripts/run_validation.sh ``` -Run all the unit tests (no formatter nor code analyzer): +Run all the unit tests (no linter nor code analyzer): -```bash -$ ./scripts/run_unit_tests.sh +```sh +./scripts/run_unit_tests.sh ``` Run a specific unit test: -```bash -$ ./scripts/run_unit_tests.sh tests/web/test_web_client.py +```sh +./scripts/run_unit_tests.sh tests/web/test_web_client.py ``` You can rely on GitHub Actions builds for running the tests on a variety of Python runtimes. @@ -97,14 +105,14 @@ This project also has integration tests that verify the SDK works with the Slack Run all integration tests: -```bash -$ ./scripts/run_integration_tests.sh +```sh +./scripts/run_integration_tests.sh ``` Run a specific integration test: -```bash -$ ./scripts/run_integration_tests.sh integration_tests/web/test_async_web_client.py +```sh +./scripts/run_integration_tests.sh integration_tests/web/test_async_web_client.py ``` #### Develop Locally @@ -113,14 +121,14 @@ If you want to test the package locally you can. 1. Build the package locally - Run - ```bash + ```sh scripts/build_pypi_package.sh ``` - This will create a `.whl` file in the `./dist` folder 2. Use the built package - Example `/dist/slack_sdk-1.2.3-py2.py3-none-any.whl` was created - From anywhere on your machine you can install this package to a project with - ```bash + ```sh pip install /dist/slack_sdk-1.2.3-py2.py3-none-any.whl ``` - It is also possible to include `slack_sdk @ file:////dist/slack_sdk-1.2.3-py2.py3-none-any.whl` in a [requirements.txt](https://pip.pypa.io/en/stable/user_guide/#requirements-files) file @@ -131,75 +139,113 @@ See [`/docs/README`](https://github.com/slackapi/python-slack-sdk/blob/main/docs The API reference is generated from a script. You can generate and preview the **API _reference_ documents for `slack_sdk` package modules** by running: -```bash -$ ./scripts/generate_api_docs.sh +```sh +./scripts/generate_api_docs.sh ``` ### Releasing -1. Create the commit for the release: - - - Bump the version number in adherence to [Semantic Versioning](http://semver.org/) in `slack_sdk/version.py`. - - Build the reference docs with `./scripts/generate_api_docs.sh`. - - Create a branch for the release with `git checkout -b v2.5.0` - - Make a commit that includes the new version number: `git commit -a -m 'version 2.5.0'`. - - Open a PR and merge after receiving at least one approval from other maintainers. - -2. Distribute the release - - - Use the latest stable Python runtime - - `python -m venv env` - - `./scripts/deploy_to_prod_pypi_org.sh` - - Create a new GitHub Release from the [Releases page](https://github.com/slackapi/python-slack-sdk/releases) by clicking the "Draft a new release" button. - - Enter the new version number updated from the commit (e.g. `v2.5.0`) into the "Choose a tag" input. - - Ensure the tag `Target` branch is `main` (e.g `Target:main`). - - Click the "Create a new tag: x.x.x on publish" button. This won't create your tag immediately. - - Name the release after the version number updated from the commit (e.g. `version 2.5.0`) - - Auto-generate the release notes by clicking the "Auto-generate release - notes" button. This will pull in changes that will be included in your - release. - - Edit the resulting notes to ensure they have decent messaging that are - understandable by non-contributors, but each commit should still have it's - own line. - - Ensure that this version adheres to [semantic versioning][semver]. See - [Versioning](#versioning-and-tags) for correct version format. Version tags - should match the following pattern: `v2.5.0`. +#### test.pypi.org deployment - ```markdown - Refer to [v{version} milestone](https://github.com/slackapi/python-slack-sdk/milestone/{TODO}?closed=1) to know the complete list of the issues resolved by this release. +[TestPyPI](https://test.pypi.org/) is a separate instance of the Python Package +Index that allows you to try distribution tools and processes without affecting +the real index. This is particularly useful when making changes related to the +package configuration itself, for example, modifications to the `pyproject.toml` file. - **Updates** +You can deploy this project to TestPyPI using GitHub Actions. - 1. [WebClient] #111 Make an awesome change - Thanks @SlackHQ - 2. [RTMClient] #222 Make an awesome change - Thanks @SlackAPI +To deploy using GitHub Actions: - **All Changes** +1. Push your changes to a branch or tag +2. Navigate to +3. Click on "Run workflow" +4. Select your branch or tag from the dropdown +5. Click "Run workflow" to build and deploy your branch to TestPyPI - * All issues/pull requests: https://github.com/slackapi/python-slack-sdk/milestone/{milestone for the release} - * All changes: https://github.com/slackapi/python-slack-sdk/compare/{the previous release version tag}...{the release version tag} - ``` +Alternatively, you can deploy from your local machine with: - - Close the milestone relating to the Release - - Create the next patch version Milestone. To be used by the following release. - -3. (Slack Internal) Communicate the release internally - - - Include a link to the GitHub release - -4. Make announcements - - - #slack-api in dev4slack.slack.com - - #lang-python in community.slack.com - -5. (Slack Internal) Tweet by @SlackAPI +```sh +./scripts/deploy_to_test_pypi.sh +``` - - Not necessary for patch updates, might be needed for minor updates, definitely needed for major updates. Include a link to the GitHub release +#### Development Deployment + +Deploying a new version of this library to PyPI is triggered by publishing a GitHub Release. +Before creating a new release, ensure that everything on a stable branch has +landed, then [run the tests](#unit-tests). + +1. Create the commit for the release + 1. Use the latest supported Python version. Using a [virtual environment](#python-and-friends) is recommended. + 2. In `slack_sdk/version.py` bump the version number in adherence to [Semantic Versioning](http://semver.org/) and [Developmental Release](https://peps.python.org/pep-0440/#developmental-releases). + - Example: if the current version is `1.2.3`, a proper development bump would be `1.2.4.dev0` + - `.dev` will indicate to pip that this is a [Development Release](https://peps.python.org/pep-0440/#developmental-releases) + - Note that the `dev` version can be bumped in development releases: `1.2.4.dev0` -> `1.2.4.dev1` + 3. Build the docs with `./scripts/generate_api_docs.sh`. + 4. Commit with a message including the new version number. For example `1.2.4.dev0` & push the commit to a branch where the development release will live (create it if it does not exist) + 1. `git checkout -b future-release` + 2. `git add --all` (review files with `git status` before committing) + 3. `git commit -m 'chore(release): version 1.2.4.dev0'` + 4. `git push -u origin future-release` +2. Create a new GitHub Release + 1. Navigate to the [Releases page](https://github.com/slackapi/python-slack-sdk/releases). + 2. Click the "Draft a new release" button. + 3. Set the "Target" to the feature branch with the development changes. + 4. Click "Tag: Select tag" + 5. Input a new tag name manually. The tag name must match the version in `slack_sdk/version.py` prefixed with "v" (e.g., if version is `1.2.4.dev0`, enter `v1.2.4.dev0`) + 6. Click the "Create a new tag" button. This won't create your tag immediately. + 7. Click the "Generate release notes" button. + 8. The release name should match the tag name! + 9. Edit the resulting notes to ensure they have decent messaging that is understandable by non-contributors, but each commit should still have its own line. + 10. Set this release as a pre-release. + 11. Publish the release by clicking the "Publish release" button! +3. Navigate to the [release workflow run](https://github.com/slackapi/python-slack-sdk/actions/workflows/pypi-release.yml). You will need to approve the deployment! +4. After a few minutes, the corresponding version will be available on . +5. (Slack Internal) Communicate the release internally + +#### Production Deployment + +Deploying a new version of this library to PyPI is triggered by publishing a GitHub Release. +Before creating a new release, ensure that everything on the `main` branch since +the last tag is in a releasable state! At a minimum, [run the tests](#unit-tests). + +1. Create the commit for the release + 1. Use the latest supported Python version. Using a [virtual environment](#python-and-friends) is recommended. + 2. In `slack_sdk/version.py` bump the version number in adherence to [Semantic Versioning](http://semver.org/) and the [Versioning](#versioning-and-tags) section. + 3. Build the docs with `./scripts/generate_api_docs.sh`. + 4. Commit with a message including the new version number. For example `1.2.3` & push the commit to a branch and create a PR to sanity check. + 1. `git checkout -b 1.2.3-release` + 2. `git add --all` (review files with `git status` before committing) + 3. `git commit -m 'chore(release): version 1.2.3'` + 4. `git push -u origin 1.2.3-release` + 5. Add relevant labels to the PR and add the PR to a GitHub Milestone. + 6. Merge in release PR after getting an approval from at least one maintainer. +2. Create a new GitHub Release + 1. Navigate to the [Releases page](https://github.com/slackapi/python-slack-sdk/releases). + 2. Click the "Draft a new release" button. + 3. Set the "Target" to the `main` branch. + 4. Click "Tag: Select tag" + 5. Input a new tag name manually. The tag name must match the version in `slack_sdk/version.py` prefixed with "v" (e.g., if version is `1.2.3`, enter `v1.2.3`) + 6. Click the "Create a new tag" button. This won't create your tag immediately. + 7. Click the "Generate release notes" button. + 8. The release name should match the tag name! + 9. Edit the resulting notes to ensure they have decent messaging that is understandable by non-contributors, but each commit should still have its own line. + 10. Include a link to the current GitHub Milestone. + 11. Ensure the "latest release" checkbox is checked to mark this as the latest stable release. + 12. Publish the release by clicking the "Publish release" button! +3. Navigate to the [release workflow run](https://github.com/slackapi/python-slack-sdk/actions/workflows/pypi-release.yml). You will need to approve the deployment! +4. After a few minutes, the corresponding version will be available on . +5. Close the current GitHub Milestone and create one for the next patch version. +6. (Slack Internal) Communicate the release internally + - Include a link to the GitHub release +7. (Slack Internal) Tweet by @SlackAPI + - Not necessary for patch updates, might be needed for minor updates, + definitely needed for major updates. Include a link to the GitHub release ## Workflow ### Versioning and Tags -This project uses semantic versioning, expressed through the numbering scheme of +This project uses [Semantic Versioning](http://semver.org/), expressed through the numbering scheme of [PEP-0440](https://www.python.org/dev/peps/pep-0440/). ### Branches diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 000000000..b2574b7cc --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,24 @@ +# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes#configuring-automatically-generated-release-notes +changelog: + categories: + - title: 🚀 Enhancements + labels: + - enhancement + - title: 🐛 Bug Fixes + labels: + - bug + - title: 📚 Documentation + labels: + - docs + - title: 🤖 Build + labels: + - build + - title: 🧪 Testing/Code Health + labels: + - code health + - title: 🔒 Security + labels: + - security + - title: 📦 Other changes + labels: + - "*" diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml deleted file mode 100644 index fa5087fd1..000000000 --- a/.github/workflows/mypy.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: mypy validation - -on: - push: - branches: - - main - pull_request: - -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 5 - strategy: - matrix: - python-version: ["3.13"] - permissions: - contents: read - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - with: - persist-credentials: false - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 - with: - python-version: ${{ matrix.python-version }} - - name: Run mypy verification - run: | - ./scripts/run_mypy.sh diff --git a/.github/workflows/pypi-release.yml b/.github/workflows/pypi-release.yml new file mode 100644 index 000000000..21b472247 --- /dev/null +++ b/.github/workflows/pypi-release.yml @@ -0,0 +1,87 @@ +name: Upload A Release to pypi.org or test.pypi.org + +on: + release: + types: + - published + workflow_dispatch: + inputs: + dry_run: + description: "Dry run (build only, do not publish)" + required: false + type: boolean + +jobs: + release-build: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + ref: ${{ github.event.release.tag_name || github.ref }} + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: "3.x" + + - name: Build release distributions + run: | + scripts/build_pypi_package.sh + + - name: Persist dist folder + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: release-dist + path: dist/ + + test-pypi-publish: + runs-on: ubuntu-latest + needs: + - release-build + # Run this job for workflow_dispatch events when dry_run input is not 'true' + # Note: The comparison is against a string value 'true' since GitHub Actions inputs are strings + if: github.event_name == 'workflow_dispatch' && github.event.inputs.dry_run != 'true' + environment: + name: testpypi + permissions: + id-token: write + + steps: + - name: Retrieve dist folder + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + with: + name: release-dist + path: dist/ + + - name: Publish release distributions to test.pypi.org + # Using OIDC for PyPI publishing (no API tokens needed) + # See: https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-pypi + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + with: + repository-url: https://test.pypi.org/legacy/ + + pypi-publish: + runs-on: ubuntu-latest + needs: + - release-build + if: github.event_name == 'release' + environment: + name: pypi + permissions: + id-token: write + + steps: + - name: Retrieve dist folder + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 + with: + name: release-dist + path: dist/ + + - name: Publish release distributions to pypi.org + # Using OIDC for PyPI publishing (no API tokens needed) + # See: https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-pypi + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 diff --git a/.github/workflows/ci-build.yml b/.github/workflows/tests.yml similarity index 57% rename from .github/workflows/ci-build.yml rename to .github/workflows/tests.yml index 841cb37ed..92ed007c8 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/tests.yml @@ -1,20 +1,45 @@ # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions -name: CI Build +name: Test on: push: branches: - main pull_request: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: jobs: - build: + typecheck: + name: Typechecks + runs-on: ubuntu-latest + timeout-minutes: 5 + strategy: + matrix: + python-version: ["3.14"] + permissions: + contents: read + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ matrix.python-version }} + - name: Run mypy verification + run: | + ./scripts/run_mypy.sh + unittest: + name: Unit tests runs-on: ubuntu-22.04 timeout-minutes: 15 strategy: fail-fast: false matrix: python-version: + - "3.14" - "3.13" - "3.12" - "3.11" @@ -55,16 +80,38 @@ jobs: PYTHONPATH=$PWD:$PYTHONPATH pytest tests/slack_sdk/oauth/state_store/test_sqlalchemy.py - name: Upload test results to Codecov if: ${{ !cancelled() }} - uses: codecov/test-results-action@47f89e9acb64b76debcd5ea40642d25a4adced9f # v1.1.1 + uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 with: directory: ./reports/ + fail_ci_if_error: true flags: ${{ matrix.python-version }} + report_type: test_results token: ${{ secrets.CODECOV_TOKEN }} verbose: true - name: Upload test coverage to Codecov (only with latest supported version) - if: startsWith(matrix.python-version, '3.13') + if: startsWith(matrix.python-version, '3.14') uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 with: - token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true # Run validation generates the coverage file files: ./coverage.xml + report_type: coverage + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + notifications: + name: Regression notifications + runs-on: ubuntu-latest + needs: + - typecheck + - unittest + if: ${{ !success() && github.ref == 'refs/heads/main' && github.event_name != 'workflow_dispatch' }} + steps: + - name: Send notifications of failing tests + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + with: + errors: true + webhook: ${{ secrets.SLACK_REGRESSION_FAILURES_WEBHOOK_URL }} + webhook-type: webhook-trigger + payload: | + action_url: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + repository: "${{ github.repository }}" diff --git a/.github/workflows/triage-issues.yml b/.github/workflows/triage-issues.yml index 5cb75bf93..85ccb72aa 100644 --- a/.github/workflows/triage-issues.yml +++ b/.github/workflows/triage-issues.yml @@ -16,7 +16,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0 + - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0 with: days-before-issue-stale: 30 days-before-issue-close: 10 diff --git a/README.md b/README.md index ec57ebfdc..568efbea2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

Python Slack SDK

- - CI Build + + Tests Codecov @@ -302,3 +302,4 @@ helpful and collaborative way. [slack-community]: https://slackcommunity.com/ [files_upload_v2]: https://github.com/slackapi/python-slack-sdk/releases/tag/v3.19.0 [aiohttp]: https://aiohttp.readthedocs.io/ + diff --git a/docs/english/index.md b/docs/english/index.md index 7e5a47fb7..7fdbcd6e4 100644 --- a/docs/english/index.md +++ b/docs/english/index.md @@ -18,7 +18,7 @@ The Slack platform offers several APIs to build apps. Each Slack API delivers pa | Request Signature Verification | Verify incoming requests from the Slack API servers. | `slack_sdk.signature` | | UI Builders | Construct UI components using easy-to-use builders. | `slack_sdk.models` | -You can also view the [Python module documents](https://docs.slack.dev/python-slack-sdk/reference)! +You can also view the [Python module documents](https://docs.slack.dev/tools/python-slack-sdk/reference)! ## Getting help {#getting-help} diff --git a/docs/reference/http_retry/async_handler.html b/docs/reference/http_retry/async_handler.html index 169110894..4f3889fcc 100644 --- a/docs/reference/http_retry/async_handler.html +++ b/docs/reference/http_retry/async_handler.html @@ -193,7 +193,7 @@

Static methods

class HttpResponse -(*,
status_code: str | int,
headers: Dict[str, str | List[str]],
body: Dict[str, Any] | None = None,
data: bytes | None = None)
+(*,
status_code: int | str,
headers: Dict[str, str | List[str]],
body: Dict[str, Any] | None = None,
data: bytes | None = None)
diff --git a/docs/reference/http_retry/index.html b/docs/reference/http_retry/index.html index 7e2294404..501a62c9e 100644 --- a/docs/reference/http_retry/index.html +++ b/docs/reference/http_retry/index.html @@ -388,7 +388,7 @@

Static methods

class HttpResponse -(*,
status_code: str | int,
headers: Dict[str, str | List[str]],
body: Dict[str, Any] | None = None,
data: bytes | None = None)
+(*,
status_code: int | str,
headers: Dict[str, str | List[str]],
body: Dict[str, Any] | None = None,
data: bytes | None = None)
diff --git a/docs/reference/http_retry/response.html b/docs/reference/http_retry/response.html index d9c82b4d8..4a786ab78 100644 --- a/docs/reference/http_retry/response.html +++ b/docs/reference/http_retry/response.html @@ -48,7 +48,7 @@

Classes

class HttpResponse -(*,
status_code: str | int,
headers: Dict[str, str | List[str]],
body: Dict[str, Any] | None = None,
data: bytes | None = None)
+(*,
status_code: int | str,
headers: Dict[str, str | List[str]],
body: Dict[str, Any] | None = None,
data: bytes | None = None)
diff --git a/docs/reference/index.html b/docs/reference/index.html index 282903146..7cc7723c1 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -2894,7 +2894,7 @@

Classes

link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -3123,6 +3123,7 @@

Classes

source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -3139,6 +3140,7 @@

Classes

"source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3770,6 +3772,30 @@

Classes

kwargs.update({"include_categories": include_categories}) return self.api_call("emoji.list", http_verb="GET", params=kwargs) + def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> SlackResponse: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return self.api_call("entity.presentDetails", json=kwargs) + def files_comments_delete( self, *, @@ -5024,6 +5050,249 @@

Classes

) return self.api_call("search.messages", http_verb="GET", params=kwargs) + def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.delete", json=kwargs) + + def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.set", json=kwargs) + + def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.create", json=kwargs) + + def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> SlackResponse: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.get", json=kwargs) + + def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.start", json=kwargs) + + def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> SlackResponse: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.create", json=kwargs) + + def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> SlackResponse: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.delete", json=kwargs) + + def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> SlackResponse: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.info", json=kwargs) + + def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.list", json=kwargs) + + def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> SlackResponse: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.update", json=kwargs) + + def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.update", json=kwargs) + def stars_add( self, *, @@ -10170,7 +10439,7 @@

Methods

https://docs.slack.dev/reference/methods/chat.postEphemeral

-def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
+def chat_postMessage(self,
*,
channel: str,
text: str | None = None,
as_user: bool | None = None,
attachments: str | Sequence[Dict | Attachment] | None = None,
blocks: str | Sequence[Dict | Block] | None = None,
thread_ts: str | None = None,
reply_broadcast: bool | None = None,
unfurl_links: bool | None = None,
unfurl_media: bool | None = None,
container_id: str | None = None,
icon_emoji: str | None = None,
icon_url: str | None = None,
mrkdwn: bool | None = None,
link_names: bool | None = None,
username: str | None = None,
parse: str | None = None,
metadata: Dict | Metadata | EventAndEntityMetadata | None = None,
markdown_text: str | None = None,
**kwargs) ‑> SlackResponse
@@ -10196,7 +10465,7 @@

Methods

link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -10518,7 +10787,7 @@

Example

-def chat_unfurl(self,
*,
channel: str | None = None,
ts: str | None = None,
source: str | None = None,
unfurl_id: str | None = None,
unfurls: Dict[str, Dict] | None = None,
user_auth_blocks: str | Sequence[Dict | Block] | None = None,
user_auth_message: str | None = None,
user_auth_required: bool | None = None,
user_auth_url: str | None = None,
**kwargs) ‑> SlackResponse
+def chat_unfurl(self,
*,
channel: str | None = None,
ts: str | None = None,
source: str | None = None,
unfurl_id: str | None = None,
unfurls: Dict[str, Dict] | None = None,
metadata: Dict | EventAndEntityMetadata | None = None,
user_auth_blocks: str | Sequence[Dict | Block] | None = None,
user_auth_message: str | None = None,
user_auth_required: bool | None = None,
user_auth_url: str | None = None,
**kwargs) ‑> SlackResponse
@@ -10533,6 +10802,7 @@

Example

source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -10549,6 +10819,7 @@

Example

"source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -11580,6 +11851,41 @@

Example

+
+def entity_presentDetails(self,
trigger_id: str,
metadata: Dict | EntityMetadata | None = None,
user_auth_required: bool | None = None,
user_auth_url: str | None = None,
error: Dict[str, Any] | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def entity_presentDetails(
+    self,
+    trigger_id: str,
+    metadata: Optional[Union[Dict, EntityMetadata]] = None,
+    user_auth_required: Optional[bool] = None,
+    user_auth_url: Optional[str] = None,
+    error: Optional[Dict[str, Any]] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Provides entity details for the flexpane.
+    https://docs.slack.dev/reference/methods/entity.presentDetails/
+    """
+    kwargs.update({"trigger_id": trigger_id})
+    if metadata is not None:
+        kwargs.update({"metadata": metadata})
+    if user_auth_required is not None:
+        kwargs.update({"user_auth_required": user_auth_required})
+    if user_auth_url is not None:
+        kwargs.update({"user_auth_url": user_auth_url})
+    if error is not None:
+        kwargs.update({"error": error})
+    _parse_web_class_objects(kwargs)
+    return self.api_call("entity.presentDetails", json=kwargs)
+
+

Provides entity details for the flexpane. +https://docs.slack.dev/reference/methods/entity.presentDetails/

+
def files_comments_delete(self, *, file: str, id: str, **kwargs) ‑> SlackResponse
@@ -13555,6 +13861,381 @@

Example

Searches for messages matching a query. https://docs.slack.dev/reference/methods/search.messages

+
+def slackLists_access_delete(self,
*,
list_id: str,
channel_ids: List[str] | None = None,
user_ids: List[str] | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def slackLists_access_delete(
+    self,
+    *,
+    list_id: str,
+    channel_ids: Optional[List[str]] = None,
+    user_ids: Optional[List[str]] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Revoke access to a List for specified entities.
+    https://docs.slack.dev/reference/methods/slackLists.access.delete
+    """
+    kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids})
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.access.delete", json=kwargs)
+
+

Revoke access to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.delete

+
+
+def slackLists_access_set(self,
*,
list_id: str,
access_level: str,
channel_ids: List[str] | None = None,
user_ids: List[str] | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def slackLists_access_set(
+    self,
+    *,
+    list_id: str,
+    access_level: str,
+    channel_ids: Optional[List[str]] = None,
+    user_ids: Optional[List[str]] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Set the access level to a List for specified entities.
+    https://docs.slack.dev/reference/methods/slackLists.access.set
+    """
+    kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids})
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.access.set", json=kwargs)
+
+

Set the access level to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.set

+
+
+def slackLists_create(self,
*,
name: str,
description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
schema: List[Dict[str, Any]] | None = None,
copy_from_list_id: str | None = None,
include_copied_list_records: bool | None = None,
todo_mode: bool | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def slackLists_create(
+    self,
+    *,
+    name: str,
+    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
+    schema: Optional[List[Dict[str, Any]]] = None,
+    copy_from_list_id: Optional[str] = None,
+    include_copied_list_records: Optional[bool] = None,
+    todo_mode: Optional[bool] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Creates a List.
+    https://docs.slack.dev/reference/methods/slackLists.create
+    """
+    kwargs.update(
+        {
+            "name": name,
+            "description_blocks": description_blocks,
+            "schema": schema,
+            "copy_from_list_id": copy_from_list_id,
+            "include_copied_list_records": include_copied_list_records,
+            "todo_mode": todo_mode,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.create", json=kwargs)
+
+ +
+
+def slackLists_download_get(self, *, list_id: str, job_id: str, **kwargs) ‑> SlackResponse +
+
+
+ +Expand source code + +
def slackLists_download_get(
+    self,
+    *,
+    list_id: str,
+    job_id: str,
+    **kwargs,
+) -> SlackResponse:
+    """Retrieve List download URL from an export job to download List contents.
+    https://docs.slack.dev/reference/methods/slackLists.download.get
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "job_id": job_id,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.download.get", json=kwargs)
+
+

Retrieve List download URL from an export job to download List contents. +https://docs.slack.dev/reference/methods/slackLists.download.get

+
+
+def slackLists_download_start(self, *, list_id: str, include_archived: bool | None = None, **kwargs) ‑> SlackResponse +
+
+
+ +Expand source code + +
def slackLists_download_start(
+    self,
+    *,
+    list_id: str,
+    include_archived: Optional[bool] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Initiate a job to export List contents.
+    https://docs.slack.dev/reference/methods/slackLists.download.start
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "include_archived": include_archived,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.download.start", json=kwargs)
+
+ +
+
+def slackLists_items_create(self,
*,
list_id: str,
duplicated_item_id: str | None = None,
parent_item_id: str | None = None,
initial_fields: List[Dict[str, Any]] | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def slackLists_items_create(
+    self,
+    *,
+    list_id: str,
+    duplicated_item_id: Optional[str] = None,
+    parent_item_id: Optional[str] = None,
+    initial_fields: Optional[List[Dict[str, Any]]] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Add a new item to an existing List.
+    https://docs.slack.dev/reference/methods/slackLists.items.create
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "duplicated_item_id": duplicated_item_id,
+            "parent_item_id": parent_item_id,
+            "initial_fields": initial_fields,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.items.create", json=kwargs)
+
+ +
+
+def slackLists_items_delete(self, *, list_id: str, id: str, **kwargs) ‑> SlackResponse +
+
+
+ +Expand source code + +
def slackLists_items_delete(
+    self,
+    *,
+    list_id: str,
+    id: str,
+    **kwargs,
+) -> SlackResponse:
+    """Deletes an item from an existing List.
+    https://docs.slack.dev/reference/methods/slackLists.items.delete
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "id": id,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.items.delete", json=kwargs)
+
+ +
+
+def slackLists_items_deleteMultiple(self, *, list_id: str, ids: List[str], **kwargs) ‑> SlackResponse +
+
+
+ +Expand source code + +
def slackLists_items_deleteMultiple(
+    self,
+    *,
+    list_id: str,
+    ids: List[str],
+    **kwargs,
+) -> SlackResponse:
+    """Deletes multiple items from an existing List.
+    https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "ids": ids,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.items.deleteMultiple", json=kwargs)
+
+ +
+
+def slackLists_items_info(self, *, list_id: str, id: str, include_is_subscribed: bool | None = None, **kwargs) ‑> SlackResponse +
+
+
+ +Expand source code + +
def slackLists_items_info(
+    self,
+    *,
+    list_id: str,
+    id: str,
+    include_is_subscribed: Optional[bool] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Get a row from a List.
+    https://docs.slack.dev/reference/methods/slackLists.items.info
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "id": id,
+            "include_is_subscribed": include_is_subscribed,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.items.info", json=kwargs)
+
+ +
+
+def slackLists_items_list(self,
*,
list_id: str,
limit: int | None = None,
cursor: str | None = None,
archived: bool | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def slackLists_items_list(
+    self,
+    *,
+    list_id: str,
+    limit: Optional[int] = None,
+    cursor: Optional[str] = None,
+    archived: Optional[bool] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Get records from a List.
+    https://docs.slack.dev/reference/methods/slackLists.items.list
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "limit": limit,
+            "cursor": cursor,
+            "archived": archived,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.items.list", json=kwargs)
+
+ +
+
+def slackLists_items_update(self, *, list_id: str, cells: List[Dict[str, Any]], **kwargs) ‑> SlackResponse +
+
+
+ +Expand source code + +
def slackLists_items_update(
+    self,
+    *,
+    list_id: str,
+    cells: List[Dict[str, Any]],
+    **kwargs,
+) -> SlackResponse:
+    """Updates cells in a List.
+    https://docs.slack.dev/reference/methods/slackLists.items.update
+    """
+    kwargs.update(
+        {
+            "list_id": list_id,
+            "cells": cells,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.items.update", json=kwargs)
+
+ +
+
+def slackLists_update(self,
*,
id: str,
name: str | None = None,
description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
todo_mode: bool | None = None,
**kwargs) ‑> SlackResponse
+
+
+
+ +Expand source code + +
def slackLists_update(
+    self,
+    *,
+    id: str,
+    name: Optional[str] = None,
+    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
+    todo_mode: Optional[bool] = None,
+    **kwargs,
+) -> SlackResponse:
+    """Update a List.
+    https://docs.slack.dev/reference/methods/slackLists.update
+    """
+    kwargs.update(
+        {
+            "id": id,
+            "name": name,
+            "description_blocks": description_blocks,
+            "todo_mode": todo_mode,
+        }
+    )
+    kwargs = _remove_none_values(kwargs)
+    return self.api_call("slackLists.update", json=kwargs)
+
+ +
def stars_add(self,
*,
channel: str | None = None,
file: str | None = None,
file_comment: str | None = None,
timestamp: str | None = None,
**kwargs) ‑> SlackResponse
@@ -15532,6 +16213,7 @@

WebClientdnd_setSnooze
  • dnd_teamInfo
  • emoji_list
  • +
  • entity_presentDetails
  • files_comments_delete
  • files_completeUploadExternal
  • files_delete
  • @@ -15601,6 +16283,18 @@

    WebClientsearch_all
  • search_files
  • search_messages
  • +
  • slackLists_access_delete
  • +
  • slackLists_access_set
  • +
  • slackLists_create
  • +
  • slackLists_download_get
  • +
  • slackLists_download_start
  • +
  • slackLists_items_create
  • +
  • slackLists_items_delete
  • +
  • slackLists_items_deleteMultiple
  • +
  • slackLists_items_info
  • +
  • slackLists_items_list
  • +
  • slackLists_items_update
  • +
  • slackLists_update
  • stars_add
  • stars_list
  • stars_remove
  • diff --git a/docs/reference/models/basic_objects.html b/docs/reference/models/basic_objects.html index 972273cc9..193200f84 100644 --- a/docs/reference/models/basic_objects.html +++ b/docs/reference/models/basic_objects.html @@ -119,6 +119,9 @@

    Ancestors

    if callable(method) and hasattr(method, "validator"): method() + def get_object_attribute(self, key: str): + return getattr(self, key, None) + def get_non_null_attributes(self) -> dict: """ Construct a dictionary out of non-null keys (from attributes property) @@ -136,7 +139,7 @@

    Ancestors

    return value def is_not_empty(self, key: str) -> bool: - value = getattr(self, key, None) + value = self.get_object_attribute(key) if value is None: return False @@ -154,7 +157,9 @@

    Ancestors

    return value is not None return { - key: to_dict_compatible(getattr(self, key, None)) for key in sorted(self.attributes) if is_not_empty(self, key) + key: to_dict_compatible(value=self.get_object_attribute(key)) + for key in sorted(self.attributes) + if is_not_empty(self, key) } def to_dict(self, *args) -> dict: @@ -208,7 +213,40 @@

    Subclasses

  • DialogBuilder
  • DialogTextComponent
  • Message
  • +
  • ContentItemEntityFields
  • +
  • EntityActionButton
  • +
  • EntityActionProcessingState
  • +
  • EntityActions
  • +
  • EntityArrayItemField
  • +
  • EntityAttributes
  • +
  • EntityBooleanCheckboxField
  • +
  • EntityBooleanTextField
  • +
  • EntityCustomField
  • +
  • EntityEditNumberConfig
  • +
  • EntityEditSelectConfig
  • +
  • EntityEditSupport
  • +
  • EntityEditTextConfig
  • +
  • EntityFullSizePreview
  • +
  • EntityFullSizePreviewError
  • +
  • EntityIconField
  • +
  • EntityIconSlackFile
  • +
  • EntityImageField
  • +
  • EntityMetadata
  • +
  • EntityPayload
  • +
  • EntityRefField
  • +
  • EntityStringField
  • +
  • EntityTimestampField
  • +
  • EntityTitle
  • +
  • EntityTypedField
  • +
  • EntityUserField
  • +
  • EntityUserIDField
  • +
  • EventAndEntityMetadata
  • +
  • ExternalRef
  • +
  • FileEntityFields
  • +
  • FileEntitySlackFile
  • +
  • IncidentEntityFields
  • Metadata
  • +
  • TaskEntityFields
  • View
  • ViewState
  • ViewStateValue
  • @@ -257,7 +295,7 @@

    Methods

    return value def is_not_empty(self, key: str) -> bool: - value = getattr(self, key, None) + value = self.get_object_attribute(key) if value is None: return False @@ -275,12 +313,27 @@

    Methods

    return value is not None return { - key: to_dict_compatible(getattr(self, key, None)) for key in sorted(self.attributes) if is_not_empty(self, key) + key: to_dict_compatible(value=self.get_object_attribute(key)) + for key in sorted(self.attributes) + if is_not_empty(self, key) }

    Construct a dictionary out of non-null keys (from attributes property) present on this object

    +
    +def get_object_attribute(self, key: str) +
    +
    +
    + +Expand source code + +
    def get_object_attribute(self, key: str):
    +    return getattr(self, key, None)
    +
    +
    +
    def to_dict(self, *args) ‑> dict
    @@ -401,6 +454,7 @@

  • attributes
  • get_non_null_attributes
  • +
  • get_object_attribute
  • to_dict
  • validate_json
  • diff --git a/docs/reference/models/blocks/basic_components.html b/docs/reference/models/blocks/basic_components.html index 8a48c9a6a..2821b6a4b 100644 --- a/docs/reference/models/blocks/basic_components.html +++ b/docs/reference/models/blocks/basic_components.html @@ -378,6 +378,7 @@

    Inherited members

    ): """ A feedback button element object for either positive or negative feedback. + https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element#button-object-fields Args: text (required): An object containing some text. Maximum length for this field is 75 characters. @@ -410,7 +411,8 @@

    Inherited members

    return json

    The base class for JSON serializable class objects

    -

    A feedback button element object for either positive or negative feedback.

    +

    A feedback button element object for either positive or negative feedback. +https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element#button-object-fields

    Args

    text : required
    @@ -1246,6 +1248,130 @@

    Inherited members

    +
    +class RawTextObject +(*, text: str) +
    +
    +
    + +Expand source code + +
    class RawTextObject(TextObject):
    +    """raw_text typed text object"""
    +
    +    type = "raw_text"
    +
    +    @property
    +    def attributes(self) -> Set[str]:  # type: ignore[override]
    +        return {"text", "type"}
    +
    +    def __init__(self, *, text: str):
    +        """A raw text object used in table block cells.
    +        https://docs.slack.dev/reference/block-kit/composition-objects/text-object/
    +        https://docs.slack.dev/reference/block-kit/blocks/table-block
    +
    +        Args:
    +            text (required): The text content for the table block cell.
    +        """
    +        super().__init__(text=text, type=self.type)
    +
    +    @staticmethod
    +    def from_str(text: str) -> "RawTextObject":
    +        """Transforms a string into a RawTextObject"""
    +        return RawTextObject(text=text)
    +
    +    @staticmethod
    +    def direct_from_string(text: str) -> Dict[str, Any]:
    +        """Transforms a string into the required object shape to act as a RawTextObject"""
    +        return RawTextObject.from_str(text).to_dict()
    +
    +    @JsonValidator("text attribute must have at least 1 character")
    +    def _validate_text_min_length(self):
    +        return len(self.text) >= 1
    +
    +

    raw_text typed text object

    +

    A raw text object used in table block cells. +https://docs.slack.dev/reference/block-kit/composition-objects/text-object/ +https://docs.slack.dev/reference/block-kit/blocks/table-block

    +

    Args

    +
    +
    text : required
    +
    The text content for the table block cell.
    +
    +

    Ancestors

    + +

    Class variables

    +
    +
    var type
    +
    +

    The type of the None singleton.

    +
    +
    +

    Static methods

    +
    +
    +def direct_from_string(text: str) ‑> Dict[str, Any] +
    +
    +
    + +Expand source code + +
    @staticmethod
    +def direct_from_string(text: str) -> Dict[str, Any]:
    +    """Transforms a string into the required object shape to act as a RawTextObject"""
    +    return RawTextObject.from_str(text).to_dict()
    +
    +

    Transforms a string into the required object shape to act as a RawTextObject

    +
    +
    +def from_str(text: str) ‑> RawTextObject +
    +
    +
    + +Expand source code + +
    @staticmethod
    +def from_str(text: str) -> "RawTextObject":
    +    """Transforms a string into a RawTextObject"""
    +    return RawTextObject(text=text)
    +
    +

    Transforms a string into a RawTextObject

    +
    +
    +

    Instance variables

    +
    +
    prop attributes : Set[str]
    +
    +
    + +Expand source code + +
    @property
    +def attributes(self) -> Set[str]:  # type: ignore[override]
    +    return {"text", "type"}
    +
    +

    Build an unordered collection of unique elements.

    +
    +
    +

    Inherited members

    + +
    class SlackFile (*, id: str | None = None, url: str | None = None) @@ -1394,6 +1520,7 @@

    Subclasses

    Class variables

    @@ -1631,6 +1758,15 @@

  • +

    RawTextObject

    + +
  • +
  • SlackFile

    • attributes
    • diff --git a/docs/reference/models/blocks/block_elements.html b/docs/reference/models/blocks/block_elements.html index ac23c73a1..375ee07ce 100644 --- a/docs/reference/models/blocks/block_elements.html +++ b/docs/reference/models/blocks/block_elements.html @@ -1868,6 +1868,7 @@

      Inherited members

      **others: dict, ): """Buttons to indicate positive or negative feedback. + https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element Args: action_id (required): An identifier for this action. @@ -1885,7 +1886,8 @@

      Inherited members

      Block Elements are things that exists inside of your Blocks. https://docs.slack.dev/reference/block-kit/block-elements/

      -

      Buttons to indicate positive or negative feedback.

      +

      Buttons to indicate positive or negative feedback. +https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element

      Args

      action_id : required
      @@ -2074,6 +2076,7 @@

      Inherited members

      **others: dict, ): """An icon button to perform actions. + https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element Args: action_id: An identifier for this action. @@ -2103,7 +2106,8 @@

      Inherited members

      Block Elements are things that exists inside of your Blocks. https://docs.slack.dev/reference/block-kit/block-elements/

      -

      An icon button to perform actions.

      +

      An icon button to perform actions. +https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element

      Args

      action_id
      @@ -3225,11 +3229,13 @@

      Inherited members

      italic: Optional[bool] = None, strike: Optional[bool] = None, code: Optional[bool] = None, + underline: Optional[bool] = None, ): self.bold = bold self.italic = italic self.strike = strike self.code = code + self.underline = underline def to_dict(self, *args) -> dict: result = { @@ -3237,6 +3243,7 @@

      Inherited members

      "italic": self.italic, "strike": self.strike, "code": self.code, + "underline": self.underline, } return {k: v for k, v in result.items() if v is not None} diff --git a/docs/reference/models/blocks/blocks.html b/docs/reference/models/blocks/blocks.html index e01a02436..722d12164 100644 --- a/docs/reference/models/blocks/blocks.html +++ b/docs/reference/models/blocks/blocks.html @@ -236,6 +236,8 @@

      Inherited members

      return VideoBlock(**block) elif type == RichTextBlock.type: return RichTextBlock(**block) + elif type == TableBlock.type: + return TableBlock(**block) else: cls.logger.warning(f"Unknown block detected and skipped ({block})") return None @@ -269,6 +271,7 @@

      Subclasses

    • MarkdownBlock
    • RichTextBlock
    • SectionBlock
    • +
    • TableBlock
    • VideoBlock

    Class variables

    @@ -433,6 +436,7 @@

    Inherited members

    **others: dict, ): """Displays actions as contextual info, which can include both feedback buttons and icon buttons. + https://docs.slack.dev/reference/block-kit/blocks/context-actions-block Args: elements (required): An array of feedback_buttons or icon_button block elements. Maximum number of items is 5. @@ -457,7 +461,8 @@

    Inherited members

    Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://docs.slack.dev/reference/block-kit/blocks

    -

    Displays actions as contextual info, which can include both feedback buttons and icon buttons.

    +

    Displays actions as contextual info, which can include both feedback buttons and icon buttons. +https://docs.slack.dev/reference/block-kit/blocks/context-actions-block

    Args

    elements : required
    @@ -1578,6 +1583,123 @@

    Inherited members

  • +
    +class TableBlock +(*,
    rows: Sequence[Sequence[Dict[str, Any]]],
    column_settings: Sequence[Dict[str, Any] | None] | None = None,
    block_id: str | None = None,
    **others: dict)
    +
    +
    +
    + +Expand source code + +
    class TableBlock(Block):
    +    type = "table"
    +
    +    @property
    +    def attributes(self) -> Set[str]:  # type: ignore[override]
    +        return super().attributes.union({"rows", "column_settings"})
    +
    +    def __init__(
    +        self,
    +        *,
    +        rows: Sequence[Sequence[Dict[str, Any]]],
    +        column_settings: Optional[Sequence[Optional[Dict[str, Any]]]] = None,
    +        block_id: Optional[str] = None,
    +        **others: dict,
    +    ):
    +        """Displays structured information in a table.
    +        https://docs.slack.dev/reference/block-kit/blocks/table-block
    +
    +        Args:
    +            rows (required): An array consisting of table rows. Maximum 100 rows.
    +                Each row object is an array with a max of 20 table cells.
    +                Table cells can have a type of raw_text or rich_text.
    +            column_settings: An array describing column behavior. If there are fewer items in the column_settings array
    +                than there are columns in the table, then the items in the the column_settings array will describe
    +                the same number of columns in the table as there are in the array itself.
    +                Any additional columns will have the default behavior. Maximum 20 items.
    +                See below for column settings schema.
    +            block_id: A unique identifier for a block. If not specified, a block_id will be generated.
    +                You can use this block_id when you receive an interaction payload to identify the source of the action.
    +                Maximum length for this field is 255 characters.
    +                block_id should be unique for each message and each iteration of a message.
    +                If a message is updated, use a new block_id.
    +        """
    +        super().__init__(type=self.type, block_id=block_id)
    +        show_unknown_key_warning(self, others)
    +
    +        self.rows = rows
    +        self.column_settings = column_settings
    +
    +    @JsonValidator("rows attribute must be specified")
    +    def _validate_rows(self):
    +        return self.rows is not None and len(self.rows) > 0
    +
    +

    Blocks are a series of components that can be combined +to create visually rich and compellingly interactive messages. +https://docs.slack.dev/reference/block-kit/blocks

    +

    Displays structured information in a table. +https://docs.slack.dev/reference/block-kit/blocks/table-block

    +

    Args

    +
    +
    rows : required
    +
    An array consisting of table rows. Maximum 100 rows. +Each row object is an array with a max of 20 table cells. +Table cells can have a type of raw_text or rich_text.
    +
    column_settings
    +
    An array describing column behavior. If there are fewer items in the column_settings array +than there are columns in the table, then the items in the the column_settings array will describe +the same number of columns in the table as there are in the array itself. +Any additional columns will have the default behavior. Maximum 20 items. +See below for column settings schema.
    +
    block_id
    +
    A unique identifier for a block. If not specified, a block_id will be generated. +You can use this block_id when you receive an interaction payload to identify the source of the action. +Maximum length for this field is 255 characters. +block_id should be unique for each message and each iteration of a message. +If a message is updated, use a new block_id.
    +
    +

    Ancestors

    + +

    Class variables

    +
    +
    var type
    +
    +

    The type of the None singleton.

    +
    +
    +

    Instance variables

    +
    +
    prop attributes : Set[str]
    +
    +
    + +Expand source code + +
    @property
    +def attributes(self) -> Set[str]:  # type: ignore[override]
    +    return super().attributes.union({"rows", "column_settings"})
    +
    +

    Build an unordered collection of unique elements.

    +
    +
    +

    Inherited members

    + +
    class VideoBlock (*,
    block_id: str | None = None,
    alt_text: str | None = None,
    video_url: str | None = None,
    thumbnail_url: str | None = None,
    title: str | dict | PlainTextObject | None = None,
    title_url: str | None = None,
    description: str | dict | PlainTextObject | None = None,
    provider_icon_url: str | None = None,
    provider_name: str | None = None,
    author_name: str | None = None,
    **others: dict)
    @@ -1902,6 +2024,13 @@

    TableBlock

    + + +
  • VideoBlock

    • attributes
    • diff --git a/docs/reference/models/blocks/index.html b/docs/reference/models/blocks/index.html index ad0c7b088..0d2047c12 100644 --- a/docs/reference/models/blocks/index.html +++ b/docs/reference/models/blocks/index.html @@ -258,6 +258,8 @@

      Inherited members

      return VideoBlock(**block) elif type == RichTextBlock.type: return RichTextBlock(**block) + elif type == TableBlock.type: + return TableBlock(**block) else: cls.logger.warning(f"Unknown block detected and skipped ({block})") return None @@ -291,6 +293,7 @@

      Subclasses

    • MarkdownBlock
    • RichTextBlock
    • SectionBlock
    • +
    • TableBlock
    • VideoBlock

    Class variables

    @@ -1369,6 +1372,7 @@

    Inherited members

    **others: dict, ): """Displays actions as contextual info, which can include both feedback buttons and icon buttons. + https://docs.slack.dev/reference/block-kit/blocks/context-actions-block Args: elements (required): An array of feedback_buttons or icon_button block elements. Maximum number of items is 5. @@ -1393,7 +1397,8 @@

    Inherited members

    Blocks are a series of components that can be combined to create visually rich and compellingly interactive messages. https://docs.slack.dev/reference/block-kit/blocks

    -

    Displays actions as contextual info, which can include both feedback buttons and icon buttons.

    +

    Displays actions as contextual info, which can include both feedback buttons and icon buttons. +https://docs.slack.dev/reference/block-kit/blocks/context-actions-block

    Args

    elements : required
    @@ -2762,6 +2767,7 @@

    Inherited members

    ): """ A feedback button element object for either positive or negative feedback. + https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element#button-object-fields Args: text (required): An object containing some text. Maximum length for this field is 75 characters. @@ -2794,7 +2800,8 @@

    Inherited members

    return json

    The base class for JSON serializable class objects

    -

    A feedback button element object for either positive or negative feedback.

    +

    A feedback button element object for either positive or negative feedback. +https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element#button-object-fields

    Args

    text : required
    @@ -2901,6 +2908,7 @@

    Inherited members

    **others: dict, ): """Buttons to indicate positive or negative feedback. + https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element Args: action_id (required): An identifier for this action. @@ -2918,7 +2926,8 @@

    Inherited members

    Block Elements are things that exists inside of your Blocks. https://docs.slack.dev/reference/block-kit/block-elements/

    -

    Buttons to indicate positive or negative feedback.

    +

    Buttons to indicate positive or negative feedback. +https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element

    Args

    action_id : required
    @@ -3196,6 +3205,7 @@

    Inherited members

    **others: dict, ): """An icon button to perform actions. + https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element Args: action_id: An identifier for this action. @@ -3225,7 +3235,8 @@

    Inherited members

    Block Elements are things that exists inside of your Blocks. https://docs.slack.dev/reference/block-kit/block-elements/

    -

    An icon button to perform actions.

    +

    An icon button to perform actions. +https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element

    Args

    action_id
    @@ -5454,6 +5465,130 @@

    Inherited members

  • +
    +class RawTextObject +(*, text: str) +
    +
    +
    + +Expand source code + +
    class RawTextObject(TextObject):
    +    """raw_text typed text object"""
    +
    +    type = "raw_text"
    +
    +    @property
    +    def attributes(self) -> Set[str]:  # type: ignore[override]
    +        return {"text", "type"}
    +
    +    def __init__(self, *, text: str):
    +        """A raw text object used in table block cells.
    +        https://docs.slack.dev/reference/block-kit/composition-objects/text-object/
    +        https://docs.slack.dev/reference/block-kit/blocks/table-block
    +
    +        Args:
    +            text (required): The text content for the table block cell.
    +        """
    +        super().__init__(text=text, type=self.type)
    +
    +    @staticmethod
    +    def from_str(text: str) -> "RawTextObject":
    +        """Transforms a string into a RawTextObject"""
    +        return RawTextObject(text=text)
    +
    +    @staticmethod
    +    def direct_from_string(text: str) -> Dict[str, Any]:
    +        """Transforms a string into the required object shape to act as a RawTextObject"""
    +        return RawTextObject.from_str(text).to_dict()
    +
    +    @JsonValidator("text attribute must have at least 1 character")
    +    def _validate_text_min_length(self):
    +        return len(self.text) >= 1
    +
    +

    raw_text typed text object

    +

    A raw text object used in table block cells. +https://docs.slack.dev/reference/block-kit/composition-objects/text-object/ +https://docs.slack.dev/reference/block-kit/blocks/table-block

    +

    Args

    +
    +
    text : required
    +
    The text content for the table block cell.
    +
    +

    Ancestors

    + +

    Class variables

    +
    +
    var type
    +
    +

    The type of the None singleton.

    +
    +
    +

    Static methods

    +
    +
    +def direct_from_string(text: str) ‑> Dict[str, Any] +
    +
    +
    + +Expand source code + +
    @staticmethod
    +def direct_from_string(text: str) -> Dict[str, Any]:
    +    """Transforms a string into the required object shape to act as a RawTextObject"""
    +    return RawTextObject.from_str(text).to_dict()
    +
    +

    Transforms a string into the required object shape to act as a RawTextObject

    +
    +
    +def from_str(text: str) ‑> RawTextObject +
    +
    +
    + +Expand source code + +
    @staticmethod
    +def from_str(text: str) -> "RawTextObject":
    +    """Transforms a string into a RawTextObject"""
    +    return RawTextObject(text=text)
    +
    +

    Transforms a string into a RawTextObject

    +
    +
    +

    Instance variables

    +
    +
    prop attributes : Set[str]
    +
    +
    + +Expand source code + +
    @property
    +def attributes(self) -> Set[str]:  # type: ignore[override]
    +    return {"text", "type"}
    +
    +

    Build an unordered collection of unique elements.

    +
    +
    +

    Inherited members

    + +
    class RichTextBlock (*,
    elements: Sequence[dict | RichTextElement],
    block_id: str | None = None,
    **others: dict)
    @@ -5617,11 +5752,13 @@

    Inherited members

    italic: Optional[bool] = None, strike: Optional[bool] = None, code: Optional[bool] = None, + underline: Optional[bool] = None, ): self.bold = bold self.italic = italic self.strike = strike self.code = code + self.underline = underline def to_dict(self, *args) -> dict: result = { @@ -5629,6 +5766,7 @@

    Inherited members

    "italic": self.italic, "strike": self.strike, "code": self.code, + "underline": self.underline, } return {k: v for k, v in result.items() if v is not None} @@ -6941,6 +7079,123 @@

    Inherited members

    +
    +class TableBlock +(*,
    rows: Sequence[Sequence[Dict[str, Any]]],
    column_settings: Sequence[Dict[str, Any] | None] | None = None,
    block_id: str | None = None,
    **others: dict)
    +
    +
    +
    + +Expand source code + +
    class TableBlock(Block):
    +    type = "table"
    +
    +    @property
    +    def attributes(self) -> Set[str]:  # type: ignore[override]
    +        return super().attributes.union({"rows", "column_settings"})
    +
    +    def __init__(
    +        self,
    +        *,
    +        rows: Sequence[Sequence[Dict[str, Any]]],
    +        column_settings: Optional[Sequence[Optional[Dict[str, Any]]]] = None,
    +        block_id: Optional[str] = None,
    +        **others: dict,
    +    ):
    +        """Displays structured information in a table.
    +        https://docs.slack.dev/reference/block-kit/blocks/table-block
    +
    +        Args:
    +            rows (required): An array consisting of table rows. Maximum 100 rows.
    +                Each row object is an array with a max of 20 table cells.
    +                Table cells can have a type of raw_text or rich_text.
    +            column_settings: An array describing column behavior. If there are fewer items in the column_settings array
    +                than there are columns in the table, then the items in the the column_settings array will describe
    +                the same number of columns in the table as there are in the array itself.
    +                Any additional columns will have the default behavior. Maximum 20 items.
    +                See below for column settings schema.
    +            block_id: A unique identifier for a block. If not specified, a block_id will be generated.
    +                You can use this block_id when you receive an interaction payload to identify the source of the action.
    +                Maximum length for this field is 255 characters.
    +                block_id should be unique for each message and each iteration of a message.
    +                If a message is updated, use a new block_id.
    +        """
    +        super().__init__(type=self.type, block_id=block_id)
    +        show_unknown_key_warning(self, others)
    +
    +        self.rows = rows
    +        self.column_settings = column_settings
    +
    +    @JsonValidator("rows attribute must be specified")
    +    def _validate_rows(self):
    +        return self.rows is not None and len(self.rows) > 0
    +
    +

    Blocks are a series of components that can be combined +to create visually rich and compellingly interactive messages. +https://docs.slack.dev/reference/block-kit/blocks

    +

    Displays structured information in a table. +https://docs.slack.dev/reference/block-kit/blocks/table-block

    +

    Args

    +
    +
    rows : required
    +
    An array consisting of table rows. Maximum 100 rows. +Each row object is an array with a max of 20 table cells. +Table cells can have a type of raw_text or rich_text.
    +
    column_settings
    +
    An array describing column behavior. If there are fewer items in the column_settings array +than there are columns in the table, then the items in the the column_settings array will describe +the same number of columns in the table as there are in the array itself. +Any additional columns will have the default behavior. Maximum 20 items. +See below for column settings schema.
    +
    block_id
    +
    A unique identifier for a block. If not specified, a block_id will be generated. +You can use this block_id when you receive an interaction payload to identify the source of the action. +Maximum length for this field is 255 characters. +block_id should be unique for each message and each iteration of a message. +If a message is updated, use a new block_id.
    +
    +

    Ancestors

    + +

    Class variables

    +
    +
    var type
    +
    +

    The type of the None singleton.

    +
    +
    +

    Instance variables

    +
    +
    prop attributes : Set[str]
    +
    +
    + +Expand source code + +
    @property
    +def attributes(self) -> Set[str]:  # type: ignore[override]
    +    return super().attributes.union({"rows", "column_settings"})
    +
    +

    Build an unordered collection of unique elements.

    +
    +
    +

    Inherited members

    + +
    class TextObject (text: str,
    type: str | None = None,
    subtype: str | None = None,
    emoji: bool | None = None,
    **kwargs)
    @@ -7019,6 +7274,7 @@

    Subclasses

    Class variables

    @@ -8140,6 +8396,15 @@

    RawTextObject

    + + +
  • RichTextBlock

    • attributes
    • @@ -8237,6 +8502,13 @@

      TableBlock

      + + +
    • TextObject

      diff --git a/docs/reference/models/metadata/index.html b/docs/reference/models/metadata/index.html index 14663e790..1c4d7a69c 100644 --- a/docs/reference/models/metadata/index.html +++ b/docs/reference/models/metadata/index.html @@ -40,12 +40,2270 @@

      Module slack_sdk.models.metadata

      +

      Global variables

      +
      +
      var EntityType
      +
      +

      Custom field types

      +
      +

      Classes

      +
      +class ContentItemEntityFields +(preview: Dict[str, Any] | EntityImageField | None = None,
      description: Dict[str, Any] | EntityStringField | None = None,
      created_by: Dict[str, Any] | EntityTypedField | None = None,
      date_created: Dict[str, Any] | EntityTimestampField | None = None,
      date_updated: Dict[str, Any] | EntityTimestampField | None = None,
      last_modified_by: Dict[str, Any] | EntityTypedField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class ContentItemEntityFields(JsonObject):
      +    """Fields specific to content item entities"""
      +
      +    attributes = {
      +        "preview",
      +        "description",
      +        "created_by",
      +        "date_created",
      +        "date_updated",
      +        "last_modified_by",
      +    }
      +
      +    def __init__(
      +        self,
      +        preview: Optional[Union[Dict[str, Any], EntityImageField]] = None,
      +        description: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
      +        date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
      +        date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
      +        last_modified_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
      +        **kwargs,
      +    ):
      +        self.preview = preview
      +        self.description = description
      +        self.created_by = created_by
      +        self.date_created = date_created
      +        self.date_updated = date_updated
      +        self.last_modified_by = last_modified_by
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Fields specific to content item entities

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityActionButton +(text: str,
      action_id: str,
      value: str | None = None,
      style: str | None = None,
      url: str | None = None,
      accessibility_label: str | None = None,
      processing_state: Dict[str, Any] | EntityActionProcessingState | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityActionButton(JsonObject):
      +    """Action button for entity"""
      +
      +    attributes = {
      +        "text",
      +        "action_id",
      +        "value",
      +        "style",
      +        "url",
      +        "accessibility_label",
      +        "processing_state",
      +    }
      +
      +    def __init__(
      +        self,
      +        text: str,
      +        action_id: str,
      +        value: Optional[str] = None,
      +        style: Optional[str] = None,
      +        url: Optional[str] = None,
      +        accessibility_label: Optional[str] = None,
      +        processing_state: Optional[Union[Dict[str, Any], EntityActionProcessingState]] = None,
      +        **kwargs,
      +    ):
      +        self.text = text
      +        self.action_id = action_id
      +        self.value = value
      +        self.style = style
      +        self.url = url
      +        self.accessibility_label = accessibility_label
      +        self.processing_state = processing_state
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Action button for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityActionProcessingState +(enabled: bool, interstitial_text: str | None = None, **kwargs) +
      +
      +
      + +Expand source code + +
      class EntityActionProcessingState(JsonObject):
      +    """Processing state configuration for entity action button"""
      +
      +    attributes = {
      +        "enabled",
      +        "interstitial_text",
      +    }
      +
      +    def __init__(
      +        self,
      +        enabled: bool,
      +        interstitial_text: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.enabled = enabled
      +        self.interstitial_text = interstitial_text
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Processing state configuration for entity action button

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityActions +(primary_actions: List[Dict[str, Any] | EntityActionButton] | None = None,
      overflow_actions: List[Dict[str, Any] | EntityActionButton] | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityActions(JsonObject):
      +    """Actions configuration for entity"""
      +
      +    attributes = {
      +        "primary_actions",
      +        "overflow_actions",
      +    }
      +
      +    def __init__(
      +        self,
      +        primary_actions: Optional[List[Union[Dict[str, Any], EntityActionButton]]] = None,
      +        overflow_actions: Optional[List[Union[Dict[str, Any], EntityActionButton]]] = None,
      +        **kwargs,
      +    ):
      +        self.primary_actions = primary_actions
      +        self.overflow_actions = overflow_actions
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Actions configuration for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityArrayItemField +(type: str | None = None,
      label: str | None = None,
      value: str | int | None = None,
      link: str | None = None,
      icon: Dict[str, Any] | EntityIconField | None = None,
      long: bool | None = None,
      format: str | None = None,
      image_url: str | None = None,
      slack_file: Dict[str, Any] | None = None,
      alt_text: str | None = None,
      edit: Dict[str, Any] | EntityEditSupport | None = None,
      tag_color: str | None = None,
      user: Dict[str, Any] | EntityUserIDField | EntityUserField | None = None,
      entity_ref: Dict[str, Any] | EntityRefField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityArrayItemField(JsonObject):
      +    """Array item field for entity (similar to EntityTypedField but with optional type)"""
      +
      +    attributes = {
      +        "type",
      +        "label",
      +        "value",
      +        "link",
      +        "icon",
      +        "long",
      +        "format",
      +        "image_url",
      +        "slack_file",
      +        "alt_text",
      +        "edit",
      +        "tag_color",
      +        "user",
      +        "entity_ref",
      +    }
      +
      +    def __init__(
      +        self,
      +        type: Optional[str] = None,
      +        label: Optional[str] = None,
      +        value: Optional[Union[str, int]] = None,
      +        link: Optional[str] = None,
      +        icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        long: Optional[bool] = None,
      +        format: Optional[str] = None,
      +        image_url: Optional[str] = None,
      +        slack_file: Optional[Dict[str, Any]] = None,
      +        alt_text: Optional[str] = None,
      +        edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None,
      +        tag_color: Optional[str] = None,
      +        user: Optional[Union[Dict[str, Any], EntityUserIDField, EntityUserField]] = None,
      +        entity_ref: Optional[Union[Dict[str, Any], EntityRefField]] = None,
      +        **kwargs,
      +    ):
      +        self.type = type
      +        self.label = label
      +        self.value = value
      +        self.link = link
      +        self.icon = icon
      +        self.long = long
      +        self.format = format
      +        self.image_url = image_url
      +        self.slack_file = slack_file
      +        self.alt_text = alt_text
      +        self.edit = edit
      +        self.tag_color = tag_color
      +        self.user = user
      +        self.entity_ref = entity_ref
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Array item field for entity (similar to EntityTypedField but with optional type)

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityAttributes +(title: Dict[str, Any] | EntityTitle,
      display_type: str | None = None,
      display_id: str | None = None,
      product_icon: Dict[str, Any] | EntityIconField | None = None,
      product_name: str | None = None,
      locale: str | None = None,
      full_size_preview: Dict[str, Any] | EntityFullSizePreview | None = None,
      metadata_last_modified: int | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityAttributes(JsonObject):
      +    """Attributes for an entity"""
      +
      +    attributes = {
      +        "title",
      +        "display_type",
      +        "display_id",
      +        "product_icon",
      +        "product_name",
      +        "locale",
      +        "full_size_preview",
      +        "metadata_last_modified",
      +    }
      +
      +    def __init__(
      +        self,
      +        title: Union[Dict[str, Any], EntityTitle],
      +        display_type: Optional[str] = None,
      +        display_id: Optional[str] = None,
      +        product_icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        product_name: Optional[str] = None,
      +        locale: Optional[str] = None,
      +        full_size_preview: Optional[Union[Dict[str, Any], EntityFullSizePreview]] = None,
      +        metadata_last_modified: Optional[int] = None,
      +        **kwargs,
      +    ):
      +        self.title = title
      +        self.display_type = display_type
      +        self.display_id = display_id
      +        self.product_icon = product_icon
      +        self.product_name = product_name
      +        self.locale = locale
      +        self.full_size_preview = full_size_preview
      +        self.metadata_last_modified = metadata_last_modified
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Attributes for an entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityBooleanCheckboxField +(type: str, text: str, description: str | None, **kwargs) +
      +
      +
      + +Expand source code + +
      class EntityBooleanCheckboxField(JsonObject):
      +    """Boolean checkbox properties"""
      +
      +    attributes = {"type", "text", "description"}
      +
      +    def __init__(
      +        self,
      +        type: str,
      +        text: str,
      +        description: Optional[str],
      +        **kwargs,
      +    ):
      +        self.type = type
      +        self.text = text
      +        self.description = description
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Boolean checkbox properties

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityBooleanTextField +(type: str,
      true_text: str,
      false_text: str,
      true_description: str | None,
      false_description: str | None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityBooleanTextField(JsonObject):
      +    """Boolean text properties"""
      +
      +    attributes = {"type", "true_text", "false_text", "true_description", "false_description"}
      +
      +    def __init__(
      +        self,
      +        type: str,
      +        true_text: str,
      +        false_text: str,
      +        true_description: Optional[str],
      +        false_description: Optional[str],
      +        **kwargs,
      +    ):
      +        self.type = type
      +        self.true_text = (true_text,)
      +        self.false_text = (false_text,)
      +        self.true_description = (true_description,)
      +        self.false_description = (false_description,)
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Boolean text properties

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityCustomField +(label: str,
      key: str,
      type: str,
      value: str | int | List[Dict[str, Any] | EntityArrayItemField] | None = None,
      link: str | None = None,
      icon: Dict[str, Any] | EntityIconField | None = None,
      long: bool | None = None,
      format: str | None = None,
      image_url: str | None = None,
      slack_file: Dict[str, Any] | None = None,
      alt_text: str | None = None,
      tag_color: str | None = None,
      edit: Dict[str, Any] | EntityEditSupport | None = None,
      item_type: str | None = None,
      user: Dict[str, Any] | EntityUserIDField | EntityUserField | None = None,
      entity_ref: Dict[str, Any] | EntityRefField | None = None,
      boolean: Dict[str, Any] | EntityBooleanCheckboxField | EntityBooleanTextField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityCustomField(JsonObject):
      +    """Custom field for entity with flexible types"""
      +
      +    attributes = {
      +        "label",
      +        "key",
      +        "type",
      +        "value",
      +        "link",
      +        "icon",
      +        "long",
      +        "format",
      +        "image_url",
      +        "slack_file",
      +        "alt_text",
      +        "tag_color",
      +        "edit",
      +        "item_type",
      +        "user",
      +        "entity_ref",
      +        "boolean",
      +    }
      +
      +    def __init__(
      +        self,
      +        label: str,
      +        key: str,
      +        type: str,
      +        value: Optional[Union[str, int, List[Union[Dict[str, Any], EntityArrayItemField]]]] = None,
      +        link: Optional[str] = None,
      +        icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        long: Optional[bool] = None,
      +        format: Optional[str] = None,
      +        image_url: Optional[str] = None,
      +        slack_file: Optional[Dict[str, Any]] = None,
      +        alt_text: Optional[str] = None,
      +        tag_color: Optional[str] = None,
      +        edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None,
      +        item_type: Optional[str] = None,
      +        user: Optional[Union[Dict[str, Any], EntityUserIDField, EntityUserField]] = None,
      +        entity_ref: Optional[Union[Dict[str, Any], EntityRefField]] = None,
      +        boolean: Optional[Union[Dict[str, Any], EntityBooleanCheckboxField, EntityBooleanTextField]] = None,
      +        **kwargs,
      +    ):
      +        self.label = label
      +        self.key = key
      +        self.type = type
      +        self.value = value
      +        self.link = link
      +        self.icon = icon
      +        self.long = long
      +        self.format = format
      +        self.image_url = image_url
      +        self.slack_file = slack_file
      +        self.alt_text = alt_text
      +        self.tag_color = tag_color
      +        self.edit = edit
      +        self.item_type = item_type
      +        self.user = user
      +        self.entity_ref = entity_ref
      +        self.boolean = boolean
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +    @EnumValidator("type", CustomFieldType)
      +    def type_valid(self):
      +        return self.type is None or self.type in CustomFieldType
      +
      +

      Custom field for entity with flexible types

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Methods

      +
      +
      +def type_valid(self) +
      +
      +
      + +Expand source code + +
      @EnumValidator("type", CustomFieldType)
      +def type_valid(self):
      +    return self.type is None or self.type in CustomFieldType
      +
      +
      +
      +
      +

      Inherited members

      + +
      +
      +class EntityEditNumberConfig +(is_decimal_allowed: bool | None = None,
      min_value: int | float | None = None,
      max_value: int | float | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityEditNumberConfig(JsonObject):
      +    """Number configuration for entity edit support"""
      +
      +    attributes = {
      +        "is_decimal_allowed",
      +        "min_value",
      +        "max_value",
      +    }
      +
      +    def __init__(
      +        self,
      +        is_decimal_allowed: Optional[bool] = None,
      +        min_value: Optional[Union[int, float]] = None,
      +        max_value: Optional[Union[int, float]] = None,
      +        **kwargs,
      +    ):
      +        self.is_decimal_allowed = is_decimal_allowed
      +        self.min_value = min_value
      +        self.max_value = max_value
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Number configuration for entity edit support

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityEditSelectConfig +(current_value: str | None = None,
      current_values: List[str] | None = None,
      static_options: List[Dict[str, Any]] | None = None,
      fetch_options_dynamically: bool | None = None,
      min_query_length: int | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityEditSelectConfig(JsonObject):
      +    """Select configuration for entity edit support"""
      +
      +    attributes = {
      +        "current_value",
      +        "current_values",
      +        "static_options",
      +        "fetch_options_dynamically",
      +        "min_query_length",
      +    }
      +
      +    def __init__(
      +        self,
      +        current_value: Optional[str] = None,
      +        current_values: Optional[List[str]] = None,
      +        static_options: Optional[List[Dict[str, Any]]] = None,  # Option[]
      +        fetch_options_dynamically: Optional[bool] = None,
      +        min_query_length: Optional[int] = None,
      +        **kwargs,
      +    ):
      +        self.current_value = current_value
      +        self.current_values = current_values
      +        self.static_options = static_options
      +        self.fetch_options_dynamically = fetch_options_dynamically
      +        self.min_query_length = min_query_length
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Select configuration for entity edit support

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityEditSupport +(enabled: bool,
      placeholder: Dict[str, Any] | None = None,
      hint: Dict[str, Any] | None = None,
      optional: bool | None = None,
      select: Dict[str, Any] | EntityEditSelectConfig | None = None,
      number: Dict[str, Any] | EntityEditNumberConfig | None = None,
      text: Dict[str, Any] | EntityEditTextConfig | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityEditSupport(JsonObject):
      +    """Edit support configuration for entity fields"""
      +
      +    attributes = {
      +        "enabled",
      +        "placeholder",
      +        "hint",
      +        "optional",
      +        "select",
      +        "number",
      +        "text",
      +    }
      +
      +    def __init__(
      +        self,
      +        enabled: bool,
      +        placeholder: Optional[Dict[str, Any]] = None,  # PlainTextElement
      +        hint: Optional[Dict[str, Any]] = None,  # PlainTextElement
      +        optional: Optional[bool] = None,
      +        select: Optional[Union[Dict[str, Any], EntityEditSelectConfig]] = None,
      +        number: Optional[Union[Dict[str, Any], EntityEditNumberConfig]] = None,
      +        text: Optional[Union[Dict[str, Any], EntityEditTextConfig]] = None,
      +        **kwargs,
      +    ):
      +        self.enabled = enabled
      +        self.placeholder = placeholder
      +        self.hint = hint
      +        self.optional = optional
      +        self.select = select
      +        self.number = number
      +        self.text = text
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Edit support configuration for entity fields

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityEditTextConfig +(min_length: int | None = None, max_length: int | None = None, **kwargs) +
      +
      +
      + +Expand source code + +
      class EntityEditTextConfig(JsonObject):
      +    """Text configuration for entity edit support"""
      +
      +    attributes = {
      +        "min_length",
      +        "max_length",
      +    }
      +
      +    def __init__(
      +        self,
      +        min_length: Optional[int] = None,
      +        max_length: Optional[int] = None,
      +        **kwargs,
      +    ):
      +        self.min_length = min_length
      +        self.max_length = max_length
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Text configuration for entity edit support

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityFullSizePreview +(is_supported: bool,
      preview_url: str | None = None,
      mime_type: str | None = None,
      error: Dict[str, Any] | EntityFullSizePreviewError | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityFullSizePreview(JsonObject):
      +    """Full-size preview configuration for entity"""
      +
      +    attributes = {
      +        "is_supported",
      +        "preview_url",
      +        "mime_type",
      +        "error",
      +    }
      +
      +    def __init__(
      +        self,
      +        is_supported: bool,
      +        preview_url: Optional[str] = None,
      +        mime_type: Optional[str] = None,
      +        error: Optional[Union[Dict[str, Any], EntityFullSizePreviewError]] = None,
      +        **kwargs,
      +    ):
      +        self.is_supported = is_supported
      +        self.preview_url = preview_url
      +        self.mime_type = mime_type
      +        self.error = error
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Full-size preview configuration for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityFullSizePreviewError +(code: str, message: str | None = None, **kwargs) +
      +
      +
      + +Expand source code + +
      class EntityFullSizePreviewError(JsonObject):
      +    """Error information for full-size preview"""
      +
      +    attributes = {
      +        "code",
      +        "message",
      +    }
      +
      +    def __init__(
      +        self,
      +        code: str,
      +        message: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.code = code
      +        self.message = message
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Error information for full-size preview

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityIconField +(alt_text: str,
      url: str | None = None,
      slack_file: Dict[str, Any] | EntityIconSlackFile | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityIconField(JsonObject):
      +    """Icon field for entity attributes"""
      +
      +    attributes = {
      +        "alt_text",
      +        "url",
      +        "slack_file",
      +    }
      +
      +    def __init__(
      +        self,
      +        alt_text: str,
      +        url: Optional[str] = None,
      +        slack_file: Optional[Union[Dict[str, Any], EntityIconSlackFile]] = None,
      +        **kwargs,
      +    ):
      +        self.alt_text = alt_text
      +        self.url = url
      +        self.slack_file = slack_file
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Icon field for entity attributes

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityIconSlackFile +(id: str | None = None, url: str | None = None, **kwargs) +
      +
      +
      + +Expand source code + +
      class EntityIconSlackFile(JsonObject):
      +    """Slack file reference for entity icon"""
      +
      +    attributes = {
      +        "id",
      +        "url",
      +    }
      +
      +    def __init__(
      +        self,
      +        id: Optional[str] = None,
      +        url: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.id = id
      +        self.url = url
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Slack file reference for entity icon

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityImageField +(alt_text: str,
      label: str | None = None,
      image_url: str | None = None,
      slack_file: Dict[str, Any] | None = None,
      title: str | None = None,
      type: str | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityImageField(JsonObject):
      +    """Image field for entity"""
      +
      +    attributes = {
      +        "alt_text",
      +        "label",
      +        "image_url",
      +        "slack_file",
      +        "title",
      +        "type",
      +    }
      +
      +    def __init__(
      +        self,
      +        alt_text: str,
      +        label: Optional[str] = None,
      +        image_url: Optional[str] = None,
      +        slack_file: Optional[Dict[str, Any]] = None,
      +        title: Optional[str] = None,
      +        type: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.alt_text = alt_text
      +        self.label = label
      +        self.image_url = image_url
      +        self.slack_file = slack_file
      +        self.title = title
      +        self.type = type
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Image field for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityMetadata +(entity_type: str,
      entity_payload: Dict[str, Any] | EntityPayload,
      external_ref: Dict[str, Any] | ExternalRef,
      url: str,
      app_unfurl_url: str | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityMetadata(JsonObject):
      +    """Work object entity metadata
      +
      +    https://docs.slack.dev/messaging/work-objects/
      +    """
      +
      +    attributes = {
      +        "entity_type",
      +        "entity_payload",
      +        "external_ref",
      +        "url",
      +        "app_unfurl_url",
      +    }
      +
      +    def __init__(
      +        self,
      +        entity_type: str,
      +        entity_payload: Union[Dict[str, Any], EntityPayload],
      +        external_ref: Union[Dict[str, Any], ExternalRef],
      +        url: str,
      +        app_unfurl_url: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.entity_type = entity_type
      +        self.entity_payload = entity_payload
      +        self.external_ref = external_ref
      +        self.url = url
      +        self.app_unfurl_url = app_unfurl_url
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +    @EnumValidator("entity_type", EntityType)
      +    def entity_type_valid(self):
      +        return self.entity_type is None or self.entity_type in EntityType
      +
      + +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Methods

      +
      +
      +def entity_type_valid(self) +
      +
      +
      + +Expand source code + +
      @EnumValidator("entity_type", EntityType)
      +def entity_type_valid(self):
      +    return self.entity_type is None or self.entity_type in EntityType
      +
      +
      +
      +
      +

      Inherited members

      + +
      +
      +class EntityPayload +(attributes: Dict[str, Any] | EntityAttributes,
      fields: Dict[str, Any] | ContentItemEntityFields | FileEntityFields | IncidentEntityFields | TaskEntityFields | None = None,
      custom_fields: List[Dict[str, Any] | EntityCustomField] | None = None,
      slack_file: Dict[str, Any] | FileEntitySlackFile | None = None,
      display_order: List[str] | None = None,
      actions: Dict[str, Any] | EntityActions | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityPayload(JsonObject):
      +    """Payload schema for an entity"""
      +
      +    attributes = {
      +        "attributes",
      +        "fields",
      +        "custom_fields",
      +        "slack_file",
      +        "display_order",
      +        "actions",
      +    }
      +
      +    def __init__(
      +        self,
      +        attributes: Union[Dict[str, Any], EntityAttributes],
      +        fields: Optional[
      +            Union[Dict[str, Any], ContentItemEntityFields, FileEntityFields, IncidentEntityFields, TaskEntityFields]
      +        ] = None,
      +        custom_fields: Optional[List[Union[Dict[str, Any], EntityCustomField]]] = None,
      +        slack_file: Optional[Union[Dict[str, Any], FileEntitySlackFile]] = None,
      +        display_order: Optional[List[str]] = None,
      +        actions: Optional[Union[Dict[str, Any], EntityActions]] = None,
      +        **kwargs,
      +    ):
      +        # Store entity attributes data with a different internal name to avoid
      +        # shadowing the class-level 'attributes' set used for JSON serialization
      +        self._entity_attributes = attributes
      +        self.fields = fields
      +        self.custom_fields = custom_fields
      +        self.slack_file = slack_file
      +        self.display_order = display_order
      +        self.actions = actions
      +        self.additional_attributes = kwargs
      +
      +    @property
      +    def entity_attributes(self) -> Union[Dict[str, Any], EntityAttributes]:
      +        """Get the entity attributes data.
      +
      +        Note: Use this property to access the attributes data. The class-level
      +        'attributes' is reserved for the JSON serialization schema.
      +        """
      +        return self._entity_attributes
      +
      +    @entity_attributes.setter
      +    def entity_attributes(self, value: Union[Dict[str, Any], EntityAttributes]):
      +        """Set the entity attributes data."""
      +        self._entity_attributes = value
      +
      +    def get_object_attribute(self, key: str):
      +        if key == "attributes":
      +            return self._entity_attributes
      +        else:
      +            return getattr(self, key, None)
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Payload schema for an entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Instance variables

      +
      +
      prop entity_attributes : Dict[str, Any] | EntityAttributes
      +
      +
      + +Expand source code + +
      @property
      +def entity_attributes(self) -> Union[Dict[str, Any], EntityAttributes]:
      +    """Get the entity attributes data.
      +
      +    Note: Use this property to access the attributes data. The class-level
      +    'attributes' is reserved for the JSON serialization schema.
      +    """
      +    return self._entity_attributes
      +
      +

      Get the entity attributes data.

      +

      Note: Use this property to access the attributes data. The class-level +'attributes' is reserved for the JSON serialization schema.

      +
      +
      +

      Methods

      +
      +
      +def get_object_attribute(self, key: str) +
      +
      +
      + +Expand source code + +
      def get_object_attribute(self, key: str):
      +    if key == "attributes":
      +        return self._entity_attributes
      +    else:
      +        return getattr(self, key, None)
      +
      +
      +
      +
      +

      Inherited members

      + +
      +
      +class EntityRefField +(entity_url: str,
      external_ref: Dict[str, Any] | ExternalRef,
      title: str,
      display_type: str | None = None,
      icon: Dict[str, Any] | EntityIconField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityRefField(JsonObject):
      +    """Entity reference field"""
      +
      +    attributes = {
      +        "entity_url",
      +        "external_ref",
      +        "title",
      +        "display_type",
      +        "icon",
      +    }
      +
      +    def __init__(
      +        self,
      +        entity_url: str,
      +        external_ref: Union[Dict[str, Any], ExternalRef],
      +        title: str,
      +        display_type: Optional[str] = None,
      +        icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        **kwargs,
      +    ):
      +        self.entity_url = entity_url
      +        self.external_ref = external_ref
      +        self.title = title
      +        self.display_type = display_type
      +        self.icon = icon
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Entity reference field

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityStringField +(value: str,
      label: str | None = None,
      format: str | None = None,
      link: str | None = None,
      icon: Dict[str, Any] | EntityIconField | None = None,
      long: bool | None = None,
      type: str | None = None,
      tag_color: str | None = None,
      edit: Dict[str, Any] | EntityEditSupport | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityStringField(JsonObject):
      +    """String field for entity"""
      +
      +    attributes = {
      +        "value",
      +        "label",
      +        "format",
      +        "link",
      +        "icon",
      +        "long",
      +        "type",
      +        "tag_color",
      +        "edit",
      +    }
      +
      +    def __init__(
      +        self,
      +        value: str,
      +        label: Optional[str] = None,
      +        format: Optional[str] = None,
      +        link: Optional[str] = None,
      +        icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        long: Optional[bool] = None,
      +        type: Optional[str] = None,
      +        tag_color: Optional[str] = None,
      +        edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None,
      +        **kwargs,
      +    ):
      +        self.value = value
      +        self.label = label
      +        self.format = format
      +        self.link = link
      +        self.icon = icon
      +        self.long = long
      +        self.type = type
      +        self.tag_color = tag_color
      +        self.edit = edit
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      String field for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityTimestampField +(value: int,
      label: str | None = None,
      type: str | None = None,
      edit: Dict[str, Any] | EntityEditSupport | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityTimestampField(JsonObject):
      +    """Timestamp field for entity"""
      +
      +    attributes = {
      +        "value",
      +        "label",
      +        "type",
      +        "edit",
      +    }
      +
      +    def __init__(
      +        self,
      +        value: int,
      +        label: Optional[str] = None,
      +        type: Optional[str] = None,
      +        edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None,
      +        **kwargs,
      +    ):
      +        self.value = value
      +        self.label = label
      +        self.type = type
      +        self.edit = edit
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Timestamp field for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityTitle +(text: str,
      edit: Dict[str, Any] | EntityEditSupport | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityTitle(JsonObject):
      +    """Title for entity attributes"""
      +
      +    attributes = {
      +        "text",
      +        "edit",
      +    }
      +
      +    def __init__(
      +        self,
      +        text: str,
      +        edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None,
      +        **kwargs,
      +    ):
      +        self.text = text
      +        self.edit = edit
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Title for entity attributes

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityTypedField +(type: str,
      label: str | None = None,
      value: str | int | None = None,
      link: str | None = None,
      icon: Dict[str, Any] | EntityIconField | None = None,
      long: bool | None = None,
      format: str | None = None,
      image_url: str | None = None,
      slack_file: Dict[str, Any] | None = None,
      alt_text: str | None = None,
      edit: Dict[str, Any] | EntityEditSupport | None = None,
      tag_color: str | None = None,
      user: Dict[str, Any] | EntityUserIDField | EntityUserField | None = None,
      entity_ref: Dict[str, Any] | EntityRefField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityTypedField(JsonObject):
      +    """Typed field for entity with various display options"""
      +
      +    attributes = {
      +        "type",
      +        "label",
      +        "value",
      +        "link",
      +        "icon",
      +        "long",
      +        "format",
      +        "image_url",
      +        "slack_file",
      +        "alt_text",
      +        "edit",
      +        "tag_color",
      +        "user",
      +        "entity_ref",
      +    }
      +
      +    def __init__(
      +        self,
      +        type: str,
      +        label: Optional[str] = None,
      +        value: Optional[Union[str, int]] = None,
      +        link: Optional[str] = None,
      +        icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        long: Optional[bool] = None,
      +        format: Optional[str] = None,
      +        image_url: Optional[str] = None,
      +        slack_file: Optional[Dict[str, Any]] = None,
      +        alt_text: Optional[str] = None,
      +        edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None,
      +        tag_color: Optional[str] = None,
      +        user: Optional[Union[Dict[str, Any], EntityUserIDField, EntityUserField]] = None,
      +        entity_ref: Optional[Union[Dict[str, Any], EntityRefField]] = None,
      +        **kwargs,
      +    ):
      +        self.type = type
      +        self.label = label
      +        self.value = value
      +        self.link = link
      +        self.icon = icon
      +        self.long = long
      +        self.format = format
      +        self.image_url = image_url
      +        self.slack_file = slack_file
      +        self.alt_text = alt_text
      +        self.edit = edit
      +        self.tag_color = tag_color
      +        self.user = user
      +        self.entity_ref = entity_ref
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Typed field for entity with various display options

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityUserField +(text: str,
      url: str | None = None,
      email: str | None = None,
      icon: Dict[str, Any] | EntityIconField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EntityUserField(JsonObject):
      +    """User field for entity"""
      +
      +    attributes = {
      +        "text",
      +        "url",
      +        "email",
      +        "icon",
      +    }
      +
      +    def __init__(
      +        self,
      +        text: str,
      +        url: Optional[str] = None,
      +        email: Optional[str] = None,
      +        icon: Optional[Union[Dict[str, Any], EntityIconField]] = None,
      +        **kwargs,
      +    ):
      +        self.text = text
      +        self.url = url
      +        self.email = email
      +        self.icon = icon
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      User field for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EntityUserIDField +(user_id: str, **kwargs) +
      +
      +
      + +Expand source code + +
      class EntityUserIDField(JsonObject):
      +    """User ID field for entity"""
      +
      +    attributes = {
      +        "user_id",
      +    }
      +
      +    def __init__(
      +        self,
      +        user_id: str,
      +        **kwargs,
      +    ):
      +        self.user_id = user_id
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      User ID field for entity

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class EventAndEntityMetadata +(event_type: str | None = None,
      event_payload: Dict[str, Any] | None = None,
      entities: List[Dict[str, Any] | EntityMetadata] | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class EventAndEntityMetadata(JsonObject):
      +    """Message metadata with entities
      +
      +    https://docs.slack.dev/messaging/message-metadata/
      +    https://docs.slack.dev/messaging/work-objects/
      +    """
      +
      +    attributes = {"event_type", "event_payload", "entities"}
      +
      +    def __init__(
      +        self,
      +        event_type: Optional[str] = None,
      +        event_payload: Optional[Dict[str, Any]] = None,
      +        entities: Optional[List[Union[Dict[str, Any], EntityMetadata]]] = None,
      +        **kwargs,
      +    ):
      +        self.event_type = event_type
      +        self.event_payload = event_payload
      +        self.entities = entities
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      + +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class ExternalRef +(id: str, type: str | None = None, **kwargs) +
      +
      +
      + +Expand source code + +
      class ExternalRef(JsonObject):
      +    """Reference (and optional type) used to identify an entity within the developer's system"""
      +
      +    attributes = {
      +        "id",
      +        "type",
      +    }
      +
      +    def __init__(
      +        self,
      +        id: str,
      +        type: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.id = id
      +        self.type = type
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Reference (and optional type) used to identify an entity within the developer's system

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class FileEntityFields +(preview: Dict[str, Any] | EntityImageField | None = None,
      created_by: Dict[str, Any] | EntityTypedField | None = None,
      date_created: Dict[str, Any] | EntityTimestampField | None = None,
      date_updated: Dict[str, Any] | EntityTimestampField | None = None,
      last_modified_by: Dict[str, Any] | EntityTypedField | None = None,
      file_size: Dict[str, Any] | EntityStringField | None = None,
      mime_type: Dict[str, Any] | EntityStringField | None = None,
      full_size_preview: Dict[str, Any] | EntityFullSizePreview | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class FileEntityFields(JsonObject):
      +    """Fields specific to file entities"""
      +
      +    attributes = {
      +        "preview",
      +        "created_by",
      +        "date_created",
      +        "date_updated",
      +        "last_modified_by",
      +        "file_size",
      +        "mime_type",
      +        "full_size_preview",
      +    }
      +
      +    def __init__(
      +        self,
      +        preview: Optional[Union[Dict[str, Any], EntityImageField]] = None,
      +        created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
      +        date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
      +        date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
      +        last_modified_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
      +        file_size: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        mime_type: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        full_size_preview: Optional[Union[Dict[str, Any], EntityFullSizePreview]] = None,
      +        **kwargs,
      +    ):
      +        self.preview = preview
      +        self.created_by = created_by
      +        self.date_created = date_created
      +        self.date_updated = date_updated
      +        self.last_modified_by = last_modified_by
      +        self.file_size = file_size
      +        self.mime_type = mime_type
      +        self.full_size_preview = full_size_preview
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Fields specific to file entities

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class FileEntitySlackFile +(id: str, type: str | None = None, **kwargs) +
      +
      +
      + +Expand source code + +
      class FileEntitySlackFile(JsonObject):
      +    """Slack file reference for file entities"""
      +
      +    attributes = {
      +        "id",
      +        "type",
      +    }
      +
      +    def __init__(
      +        self,
      +        id: str,
      +        type: Optional[str] = None,
      +        **kwargs,
      +    ):
      +        self.id = id
      +        self.type = type
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Slack file reference for file entities

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      +
      +class IncidentEntityFields +(status: Dict[str, Any] | EntityStringField | None = None,
      priority: Dict[str, Any] | EntityStringField | None = None,
      urgency: Dict[str, Any] | EntityStringField | None = None,
      created_by: Dict[str, Any] | EntityTypedField | None = None,
      assigned_to: Dict[str, Any] | EntityTypedField | None = None,
      date_created: Dict[str, Any] | EntityTimestampField | None = None,
      date_updated: Dict[str, Any] | EntityTimestampField | None = None,
      description: Dict[str, Any] | EntityStringField | None = None,
      service: Dict[str, Any] | EntityStringField | None = None,
      **kwargs)
      +
      +
      +
      + +Expand source code + +
      class IncidentEntityFields(JsonObject):
      +    """Fields specific to incident entities"""
      +
      +    attributes = {
      +        "status",
      +        "priority",
      +        "urgency",
      +        "created_by",
      +        "assigned_to",
      +        "date_created",
      +        "date_updated",
      +        "description",
      +        "service",
      +    }
      +
      +    def __init__(
      +        self,
      +        status: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        priority: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        urgency: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
      +        assigned_to: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
      +        date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
      +        date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
      +        description: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        service: Optional[Union[Dict[str, Any], EntityStringField]] = None,
      +        **kwargs,
      +    ):
      +        self.status = status
      +        self.priority = priority
      +        self.urgency = urgency
      +        self.created_by = created_by
      +        self.assigned_to = assigned_to
      +        self.date_created = date_created
      +        self.date_updated = date_updated
      +        self.description = description
      +        self.service = service
      +        self.additional_attributes = kwargs
      +
      +    def __str__(self):
      +        return str(self.get_non_null_attributes())
      +
      +    def __repr__(self):
      +        return self.__str__()
      +
      +

      Fields specific to incident entities

      +

      Ancestors

      + +

      Class variables

      +
      +
      var attributes
      +
      +

      The type of the None singleton.

      +
      +
      +

      Inherited members

      + +
      class Metadata (event_type: str, event_payload: Dict[str, Any], **kwargs) @@ -107,6 +2365,81 @@

      Inherited members

    +
    +class TaskEntityFields +(description: Dict[str, Any] | EntityStringField | None = None,
    created_by: Dict[str, Any] | EntityTypedField | None = None,
    date_created: Dict[str, Any] | EntityTimestampField | None = None,
    date_updated: Dict[str, Any] | EntityTimestampField | None = None,
    assignee: Dict[str, Any] | EntityTypedField | None = None,
    status: Dict[str, Any] | EntityStringField | None = None,
    due_date: Dict[str, Any] | EntityTypedField | None = None,
    priority: Dict[str, Any] | EntityStringField | None = None,
    **kwargs)
    +
    +
    +
    + +Expand source code + +
    class TaskEntityFields(JsonObject):
    +    """Fields specific to task entities"""
    +
    +    attributes = {
    +        "description",
    +        "created_by",
    +        "date_created",
    +        "date_updated",
    +        "assignee",
    +        "status",
    +        "due_date",
    +        "priority",
    +    }
    +
    +    def __init__(
    +        self,
    +        description: Optional[Union[Dict[str, Any], EntityStringField]] = None,
    +        created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
    +        date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
    +        date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None,
    +        assignee: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
    +        status: Optional[Union[Dict[str, Any], EntityStringField]] = None,
    +        due_date: Optional[Union[Dict[str, Any], EntityTypedField]] = None,
    +        priority: Optional[Union[Dict[str, Any], EntityStringField]] = None,
    +        **kwargs,
    +    ):
    +        self.description = description
    +        self.created_by = created_by
    +        self.date_created = date_created
    +        self.date_updated = date_updated
    +        self.assignee = assignee
    +        self.status = status
    +        self.due_date = due_date
    +        self.priority = priority
    +        self.additional_attributes = kwargs
    +
    +    def __str__(self):
    +        return str(self.get_non_null_attributes())
    +
    +    def __repr__(self):
    +        return self.__str__()
    +
    +

    Fields specific to task entities

    +

    Ancestors

    + +

    Class variables

    +
    +
    var attributes
    +
    +

    The type of the None singleton.

    +
    +
    +

    Inherited members

    + +
  • @@ -120,14 +2453,221 @@

    Inherited members

  • slack_sdk.models
  • +
  • Global variables

    + +
  • Classes

  • diff --git a/docs/reference/oauth/installation_store/file/index.html b/docs/reference/oauth/installation_store/file/index.html index 7658ddd96..db77a087c 100644 --- a/docs/reference/oauth/installation_store/file/index.html +++ b/docs/reference/oauth/installation_store/file/index.html @@ -48,7 +48,7 @@

    Classes

    class FileInstallationStore -(*,
    base_dir: str = '/Users/eden.zimbelman/.bolt-app-installation',
    historical_data_enabled: bool = True,
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
    +(*,
    base_dir: str = '$HOME/.bolt-app-installation',
    historical_data_enabled: bool = True,
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
    diff --git a/docs/reference/oauth/installation_store/index.html b/docs/reference/oauth/installation_store/index.html index 5865522cf..4f90fb1c5 100644 --- a/docs/reference/oauth/installation_store/index.html +++ b/docs/reference/oauth/installation_store/index.html @@ -327,7 +327,7 @@

    Methods

    class FileInstallationStore -(*,
    base_dir: str = '/Users/eden.zimbelman/.bolt-app-installation',
    historical_data_enabled: bool = True,
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
    +(*,
    base_dir: str = '$HOME/.bolt-app-installation',
    historical_data_enabled: bool = True,
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.installation_store.file (WARNING)>)
    diff --git a/docs/reference/oauth/state_store/file/index.html b/docs/reference/oauth/state_store/file/index.html index 33ac16d82..62e7be40e 100644 --- a/docs/reference/oauth/state_store/file/index.html +++ b/docs/reference/oauth/state_store/file/index.html @@ -48,7 +48,7 @@

    Classes

    class FileOAuthStateStore -(*,
    expiration_seconds: int,
    base_dir: str = '/Users/eden.zimbelman/.bolt-app-oauth-state',
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
    +(*,
    expiration_seconds: int,
    base_dir: str = '$HOME/.bolt-app-oauth-state',
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
    diff --git a/docs/reference/oauth/state_store/index.html b/docs/reference/oauth/state_store/index.html index 3f0c18327..38a016b32 100644 --- a/docs/reference/oauth/state_store/index.html +++ b/docs/reference/oauth/state_store/index.html @@ -77,7 +77,7 @@

    Classes

    class FileOAuthStateStore -(*,
    expiration_seconds: int,
    base_dir: str = '/Users/eden.zimbelman/.bolt-app-oauth-state',
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
    +(*,
    expiration_seconds: int,
    base_dir: str = '$HOME/.bolt-app-oauth-state',
    client_id: str | None = None,
    logger: logging.Logger = <Logger slack_sdk.oauth.state_store.file (WARNING)>)
    diff --git a/docs/reference/scim/async_client.html b/docs/reference/scim/async_client.html index 426ca9299..c91441c29 100644 --- a/docs/reference/scim/async_client.html +++ b/docs/reference/scim/async_client.html @@ -163,9 +163,9 @@

    Classes

    await self.api_call( http_verb="PATCH", path=f"Users/{quote(id)}", - body_params=partial_user.to_dict() - if isinstance(partial_user, User) - else _to_dict_without_not_given(partial_user), + body_params=( + partial_user.to_dict() if isinstance(partial_user, User) else _to_dict_without_not_given(partial_user) + ), ) ) @@ -228,9 +228,11 @@

    Classes

    await self.api_call( http_verb="PATCH", path=f"Groups/{quote(id)}", - body_params=partial_group.to_dict() - if isinstance(partial_group, Group) - else _to_dict_without_not_given(partial_group), + body_params=( + partial_group.to_dict() + if isinstance(partial_group, Group) + else _to_dict_without_not_given(partial_group) + ), ) ) @@ -620,9 +622,11 @@

    Methods

    await self.api_call( http_verb="PATCH", path=f"Groups/{quote(id)}", - body_params=partial_group.to_dict() - if isinstance(partial_group, Group) - else _to_dict_without_not_given(partial_group), + body_params=( + partial_group.to_dict() + if isinstance(partial_group, Group) + else _to_dict_without_not_given(partial_group) + ), ) )
    @@ -641,9 +645,9 @@

    Methods

    await self.api_call( http_verb="PATCH", path=f"Users/{quote(id)}", - body_params=partial_user.to_dict() - if isinstance(partial_user, User) - else _to_dict_without_not_given(partial_user), + body_params=( + partial_user.to_dict() if isinstance(partial_user, User) else _to_dict_without_not_given(partial_user) + ), ) )
    diff --git a/docs/reference/scim/v1/async_client.html b/docs/reference/scim/v1/async_client.html index 59fb723f3..6a971bb80 100644 --- a/docs/reference/scim/v1/async_client.html +++ b/docs/reference/scim/v1/async_client.html @@ -163,9 +163,9 @@

    Classes

    await self.api_call( http_verb="PATCH", path=f"Users/{quote(id)}", - body_params=partial_user.to_dict() - if isinstance(partial_user, User) - else _to_dict_without_not_given(partial_user), + body_params=( + partial_user.to_dict() if isinstance(partial_user, User) else _to_dict_without_not_given(partial_user) + ), ) ) @@ -228,9 +228,11 @@

    Classes

    await self.api_call( http_verb="PATCH", path=f"Groups/{quote(id)}", - body_params=partial_group.to_dict() - if isinstance(partial_group, Group) - else _to_dict_without_not_given(partial_group), + body_params=( + partial_group.to_dict() + if isinstance(partial_group, Group) + else _to_dict_without_not_given(partial_group) + ), ) ) @@ -620,9 +622,11 @@

    Methods

    await self.api_call( http_verb="PATCH", path=f"Groups/{quote(id)}", - body_params=partial_group.to_dict() - if isinstance(partial_group, Group) - else _to_dict_without_not_given(partial_group), + body_params=( + partial_group.to_dict() + if isinstance(partial_group, Group) + else _to_dict_without_not_given(partial_group) + ), ) )
    @@ -641,9 +645,9 @@

    Methods

    await self.api_call( http_verb="PATCH", path=f"Users/{quote(id)}", - body_params=partial_user.to_dict() - if isinstance(partial_user, User) - else _to_dict_without_not_given(partial_user), + body_params=( + partial_user.to_dict() if isinstance(partial_user, User) else _to_dict_without_not_given(partial_user) + ), ) )
    diff --git a/docs/reference/socket_mode/websocket_client/index.html b/docs/reference/socket_mode/websocket_client/index.html index fe43e29b1..b90aa9137 100644 --- a/docs/reference/socket_mode/websocket_client/index.html +++ b/docs/reference/socket_mode/websocket_client/index.html @@ -213,10 +213,10 @@

    Classes

    self.current_session = websocket.WebSocketApp( self.wss_uri, - on_open=on_open, # type: ignore[arg-type] - on_message=on_message, # type: ignore[arg-type] - on_error=on_error, # type: ignore[arg-type] - on_close=on_close, # type: ignore[arg-type] + on_open=on_open, + on_message=on_message, + on_error=on_error, + on_close=on_close, ) self.auto_reconnect_enabled = self.default_auto_reconnect_enabled @@ -441,10 +441,10 @@

    Methods

    self.current_session = websocket.WebSocketApp( self.wss_uri, - on_open=on_open, # type: ignore[arg-type] - on_message=on_message, # type: ignore[arg-type] - on_error=on_error, # type: ignore[arg-type] - on_close=on_close, # type: ignore[arg-type] + on_open=on_open, + on_message=on_message, + on_error=on_error, + on_close=on_close, ) self.auto_reconnect_enabled = self.default_auto_reconnect_enabled diff --git a/docs/reference/web/async_client.html b/docs/reference/web/async_client.html index 6e9c712fe..2ec1ba84a 100644 --- a/docs/reference/web/async_client.html +++ b/docs/reference/web/async_client.html @@ -2790,7 +2790,7 @@

    Classes

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> AsyncSlackResponse: @@ -3019,6 +3019,7 @@

    Classes

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -3035,6 +3036,7 @@

    Classes

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3666,6 +3668,30 @@

    Classes

    kwargs.update({"include_categories": include_categories}) return await self.api_call("emoji.list", http_verb="GET", params=kwargs) + async def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return await self.api_call("entity.presentDetails", json=kwargs) + async def files_comments_delete( self, *, @@ -4920,6 +4946,249 @@

    Classes

    ) return await self.api_call("search.messages", http_verb="GET", params=kwargs) + async def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.access.delete", json=kwargs) + + async def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.access.set", json=kwargs) + + async def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.create", json=kwargs) + + async def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> AsyncSlackResponse: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.download.get", json=kwargs) + + async def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.download.start", json=kwargs) + + async def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.create", json=kwargs) + + async def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> AsyncSlackResponse: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.delete", json=kwargs) + + async def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> AsyncSlackResponse: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + async def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.info", json=kwargs) + + async def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.list", json=kwargs) + + async def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> AsyncSlackResponse: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.update", json=kwargs) + + async def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.update", json=kwargs) + async def stars_add( self, *, @@ -10066,7 +10335,7 @@

    Methods

    https://docs.slack.dev/reference/methods/chat.postEphemeral

    -async def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +async def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | EventAndEntityMetadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> AsyncSlackResponse
    @@ -10092,7 +10361,7 @@

    Methods

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> AsyncSlackResponse: @@ -10414,7 +10683,7 @@

    Example

    -async def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +async def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    metadata: Dict | EventAndEntityMetadata | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> AsyncSlackResponse
    @@ -10429,6 +10698,7 @@

    Example

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -10445,6 +10715,7 @@

    Example

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -11476,6 +11747,41 @@

    Example

    +
    +async def entity_presentDetails(self,
    trigger_id: str,
    metadata: Dict | EntityMetadata | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    error: Dict[str, Any] | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def entity_presentDetails(
    +    self,
    +    trigger_id: str,
    +    metadata: Optional[Union[Dict, EntityMetadata]] = None,
    +    user_auth_required: Optional[bool] = None,
    +    user_auth_url: Optional[str] = None,
    +    error: Optional[Dict[str, Any]] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Provides entity details for the flexpane.
    +    https://docs.slack.dev/reference/methods/entity.presentDetails/
    +    """
    +    kwargs.update({"trigger_id": trigger_id})
    +    if metadata is not None:
    +        kwargs.update({"metadata": metadata})
    +    if user_auth_required is not None:
    +        kwargs.update({"user_auth_required": user_auth_required})
    +    if user_auth_url is not None:
    +        kwargs.update({"user_auth_url": user_auth_url})
    +    if error is not None:
    +        kwargs.update({"error": error})
    +    _parse_web_class_objects(kwargs)
    +    return await self.api_call("entity.presentDetails", json=kwargs)
    +
    +

    Provides entity details for the flexpane. +https://docs.slack.dev/reference/methods/entity.presentDetails/

    +
    async def files_comments_delete(self, *, file: str, id: str, **kwargs) ‑> AsyncSlackResponse
    @@ -13451,6 +13757,381 @@

    Example

    Searches for messages matching a query. https://docs.slack.dev/reference/methods/search.messages

    +
    +async def slackLists_access_delete(self,
    *,
    list_id: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def slackLists_access_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Revoke access to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.delete
    +    """
    +    kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.access.delete", json=kwargs)
    +
    +

    Revoke access to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.delete

    +
    +
    +async def slackLists_access_set(self,
    *,
    list_id: str,
    access_level: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def slackLists_access_set(
    +    self,
    +    *,
    +    list_id: str,
    +    access_level: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Set the access level to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.set
    +    """
    +    kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.access.set", json=kwargs)
    +
    +

    Set the access level to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.set

    +
    +
    +async def slackLists_create(self,
    *,
    name: str,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    schema: List[Dict[str, Any]] | None = None,
    copy_from_list_id: str | None = None,
    include_copied_list_records: bool | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def slackLists_create(
    +    self,
    +    *,
    +    name: str,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    schema: Optional[List[Dict[str, Any]]] = None,
    +    copy_from_list_id: Optional[str] = None,
    +    include_copied_list_records: Optional[bool] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Creates a List.
    +    https://docs.slack.dev/reference/methods/slackLists.create
    +    """
    +    kwargs.update(
    +        {
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "schema": schema,
    +            "copy_from_list_id": copy_from_list_id,
    +            "include_copied_list_records": include_copied_list_records,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.create", json=kwargs)
    +
    + +
    +
    +async def slackLists_download_get(self, *, list_id: str, job_id: str, **kwargs) ‑> AsyncSlackResponse +
    +
    +
    + +Expand source code + +
    async def slackLists_download_get(
    +    self,
    +    *,
    +    list_id: str,
    +    job_id: str,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Retrieve List download URL from an export job to download List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.get
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "job_id": job_id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.download.get", json=kwargs)
    +
    +

    Retrieve List download URL from an export job to download List contents. +https://docs.slack.dev/reference/methods/slackLists.download.get

    +
    +
    +async def slackLists_download_start(self, *, list_id: str, include_archived: bool | None = None, **kwargs) ‑> AsyncSlackResponse +
    +
    +
    + +Expand source code + +
    async def slackLists_download_start(
    +    self,
    +    *,
    +    list_id: str,
    +    include_archived: Optional[bool] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Initiate a job to export List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.start
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "include_archived": include_archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.download.start", json=kwargs)
    +
    + +
    +
    +async def slackLists_items_create(self,
    *,
    list_id: str,
    duplicated_item_id: str | None = None,
    parent_item_id: str | None = None,
    initial_fields: List[Dict[str, Any]] | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def slackLists_items_create(
    +    self,
    +    *,
    +    list_id: str,
    +    duplicated_item_id: Optional[str] = None,
    +    parent_item_id: Optional[str] = None,
    +    initial_fields: Optional[List[Dict[str, Any]]] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Add a new item to an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.create
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "duplicated_item_id": duplicated_item_id,
    +            "parent_item_id": parent_item_id,
    +            "initial_fields": initial_fields,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.items.create", json=kwargs)
    +
    + +
    +
    +async def slackLists_items_delete(self, *, list_id: str, id: str, **kwargs) ‑> AsyncSlackResponse +
    +
    +
    + +Expand source code + +
    async def slackLists_items_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Deletes an item from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.delete
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.items.delete", json=kwargs)
    +
    + +
    +
    +async def slackLists_items_deleteMultiple(self, *, list_id: str, ids: List[str], **kwargs) ‑> AsyncSlackResponse +
    +
    +
    + +Expand source code + +
    async def slackLists_items_deleteMultiple(
    +    self,
    +    *,
    +    list_id: str,
    +    ids: List[str],
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Deletes multiple items from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "ids": ids,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.items.deleteMultiple", json=kwargs)
    +
    + +
    +
    +async def slackLists_items_info(self, *, list_id: str, id: str, include_is_subscribed: bool | None = None, **kwargs) ‑> AsyncSlackResponse +
    +
    +
    + +Expand source code + +
    async def slackLists_items_info(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    include_is_subscribed: Optional[bool] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Get a row from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.info
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +            "include_is_subscribed": include_is_subscribed,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.items.info", json=kwargs)
    +
    + +
    +
    +async def slackLists_items_list(self,
    *,
    list_id: str,
    limit: int | None = None,
    cursor: str | None = None,
    archived: bool | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def slackLists_items_list(
    +    self,
    +    *,
    +    list_id: str,
    +    limit: Optional[int] = None,
    +    cursor: Optional[str] = None,
    +    archived: Optional[bool] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Get records from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.list
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "limit": limit,
    +            "cursor": cursor,
    +            "archived": archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.items.list", json=kwargs)
    +
    + +
    +
    +async def slackLists_items_update(self, *, list_id: str, cells: List[Dict[str, Any]], **kwargs) ‑> AsyncSlackResponse +
    +
    +
    + +Expand source code + +
    async def slackLists_items_update(
    +    self,
    +    *,
    +    list_id: str,
    +    cells: List[Dict[str, Any]],
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Updates cells in a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.update
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "cells": cells,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.items.update", json=kwargs)
    +
    + +
    +
    +async def slackLists_update(self,
    *,
    id: str,
    name: str | None = None,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> AsyncSlackResponse
    +
    +
    +
    + +Expand source code + +
    async def slackLists_update(
    +    self,
    +    *,
    +    id: str,
    +    name: Optional[str] = None,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> AsyncSlackResponse:
    +    """Update a List.
    +    https://docs.slack.dev/reference/methods/slackLists.update
    +    """
    +    kwargs.update(
    +        {
    +            "id": id,
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return await self.api_call("slackLists.update", json=kwargs)
    +
    + +
    async def stars_add(self,
    *,
    channel: str | None = None,
    file: str | None = None,
    file_comment: str | None = None,
    timestamp: str | None = None,
    **kwargs) ‑> AsyncSlackResponse
    @@ -14968,6 +15649,7 @@

    dnd_setSnooze
  • dnd_teamInfo
  • emoji_list
  • +
  • entity_presentDetails
  • files_comments_delete
  • files_completeUploadExternal
  • files_delete
  • @@ -15037,6 +15719,18 @@

    search_all
  • search_files
  • search_messages
  • +
  • slackLists_access_delete
  • +
  • slackLists_access_set
  • +
  • slackLists_create
  • +
  • slackLists_download_get
  • +
  • slackLists_download_start
  • +
  • slackLists_items_create
  • +
  • slackLists_items_delete
  • +
  • slackLists_items_deleteMultiple
  • +
  • slackLists_items_info
  • +
  • slackLists_items_list
  • +
  • slackLists_items_update
  • +
  • slackLists_update
  • stars_add
  • stars_list
  • stars_remove
  • diff --git a/docs/reference/web/client.html b/docs/reference/web/client.html index 6be773f23..6fded11e1 100644 --- a/docs/reference/web/client.html +++ b/docs/reference/web/client.html @@ -2790,7 +2790,7 @@

    Classes

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -3019,6 +3019,7 @@

    Classes

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -3035,6 +3036,7 @@

    Classes

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3666,6 +3668,30 @@

    Classes

    kwargs.update({"include_categories": include_categories}) return self.api_call("emoji.list", http_verb="GET", params=kwargs) + def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> SlackResponse: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return self.api_call("entity.presentDetails", json=kwargs) + def files_comments_delete( self, *, @@ -4920,6 +4946,249 @@

    Classes

    ) return self.api_call("search.messages", http_verb="GET", params=kwargs) + def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.delete", json=kwargs) + + def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.set", json=kwargs) + + def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.create", json=kwargs) + + def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> SlackResponse: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.get", json=kwargs) + + def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.start", json=kwargs) + + def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> SlackResponse: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.create", json=kwargs) + + def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> SlackResponse: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.delete", json=kwargs) + + def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> SlackResponse: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.info", json=kwargs) + + def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.list", json=kwargs) + + def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> SlackResponse: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.update", json=kwargs) + + def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.update", json=kwargs) + def stars_add( self, *, @@ -10066,7 +10335,7 @@

    Methods

    https://docs.slack.dev/reference/methods/chat.postEphemeral

    -def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> SlackResponse
    +def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | EventAndEntityMetadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> SlackResponse
    @@ -10092,7 +10361,7 @@

    Methods

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -10414,7 +10683,7 @@

    Example

    -def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> SlackResponse
    +def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    metadata: Dict | EventAndEntityMetadata | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> SlackResponse
    @@ -10429,6 +10698,7 @@

    Example

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -10445,6 +10715,7 @@

    Example

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -11476,6 +11747,41 @@

    Example

    +
    +def entity_presentDetails(self,
    trigger_id: str,
    metadata: Dict | EntityMetadata | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    error: Dict[str, Any] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def entity_presentDetails(
    +    self,
    +    trigger_id: str,
    +    metadata: Optional[Union[Dict, EntityMetadata]] = None,
    +    user_auth_required: Optional[bool] = None,
    +    user_auth_url: Optional[str] = None,
    +    error: Optional[Dict[str, Any]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Provides entity details for the flexpane.
    +    https://docs.slack.dev/reference/methods/entity.presentDetails/
    +    """
    +    kwargs.update({"trigger_id": trigger_id})
    +    if metadata is not None:
    +        kwargs.update({"metadata": metadata})
    +    if user_auth_required is not None:
    +        kwargs.update({"user_auth_required": user_auth_required})
    +    if user_auth_url is not None:
    +        kwargs.update({"user_auth_url": user_auth_url})
    +    if error is not None:
    +        kwargs.update({"error": error})
    +    _parse_web_class_objects(kwargs)
    +    return self.api_call("entity.presentDetails", json=kwargs)
    +
    +

    Provides entity details for the flexpane. +https://docs.slack.dev/reference/methods/entity.presentDetails/

    +
    def files_comments_delete(self, *, file: str, id: str, **kwargs) ‑> SlackResponse
    @@ -13451,6 +13757,381 @@

    Example

    Searches for messages matching a query. https://docs.slack.dev/reference/methods/search.messages

    +
    +def slackLists_access_delete(self,
    *,
    list_id: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_access_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Revoke access to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.delete
    +    """
    +    kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.access.delete", json=kwargs)
    +
    +

    Revoke access to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.delete

    +
    +
    +def slackLists_access_set(self,
    *,
    list_id: str,
    access_level: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_access_set(
    +    self,
    +    *,
    +    list_id: str,
    +    access_level: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Set the access level to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.set
    +    """
    +    kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.access.set", json=kwargs)
    +
    +

    Set the access level to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.set

    +
    +
    +def slackLists_create(self,
    *,
    name: str,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    schema: List[Dict[str, Any]] | None = None,
    copy_from_list_id: str | None = None,
    include_copied_list_records: bool | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_create(
    +    self,
    +    *,
    +    name: str,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    schema: Optional[List[Dict[str, Any]]] = None,
    +    copy_from_list_id: Optional[str] = None,
    +    include_copied_list_records: Optional[bool] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Creates a List.
    +    https://docs.slack.dev/reference/methods/slackLists.create
    +    """
    +    kwargs.update(
    +        {
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "schema": schema,
    +            "copy_from_list_id": copy_from_list_id,
    +            "include_copied_list_records": include_copied_list_records,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.create", json=kwargs)
    +
    + +
    +
    +def slackLists_download_get(self, *, list_id: str, job_id: str, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_download_get(
    +    self,
    +    *,
    +    list_id: str,
    +    job_id: str,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Retrieve List download URL from an export job to download List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.get
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "job_id": job_id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.download.get", json=kwargs)
    +
    +

    Retrieve List download URL from an export job to download List contents. +https://docs.slack.dev/reference/methods/slackLists.download.get

    +
    +
    +def slackLists_download_start(self, *, list_id: str, include_archived: bool | None = None, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_download_start(
    +    self,
    +    *,
    +    list_id: str,
    +    include_archived: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Initiate a job to export List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.start
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "include_archived": include_archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.download.start", json=kwargs)
    +
    + +
    +
    +def slackLists_items_create(self,
    *,
    list_id: str,
    duplicated_item_id: str | None = None,
    parent_item_id: str | None = None,
    initial_fields: List[Dict[str, Any]] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_items_create(
    +    self,
    +    *,
    +    list_id: str,
    +    duplicated_item_id: Optional[str] = None,
    +    parent_item_id: Optional[str] = None,
    +    initial_fields: Optional[List[Dict[str, Any]]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Add a new item to an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.create
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "duplicated_item_id": duplicated_item_id,
    +            "parent_item_id": parent_item_id,
    +            "initial_fields": initial_fields,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.create", json=kwargs)
    +
    + +
    +
    +def slackLists_items_delete(self, *, list_id: str, id: str, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Deletes an item from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.delete
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.delete", json=kwargs)
    +
    + +
    +
    +def slackLists_items_deleteMultiple(self, *, list_id: str, ids: List[str], **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_deleteMultiple(
    +    self,
    +    *,
    +    list_id: str,
    +    ids: List[str],
    +    **kwargs,
    +) -> SlackResponse:
    +    """Deletes multiple items from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "ids": ids,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.deleteMultiple", json=kwargs)
    +
    + +
    +
    +def slackLists_items_info(self, *, list_id: str, id: str, include_is_subscribed: bool | None = None, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_info(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    include_is_subscribed: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Get a row from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.info
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +            "include_is_subscribed": include_is_subscribed,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.info", json=kwargs)
    +
    + +
    +
    +def slackLists_items_list(self,
    *,
    list_id: str,
    limit: int | None = None,
    cursor: str | None = None,
    archived: bool | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_items_list(
    +    self,
    +    *,
    +    list_id: str,
    +    limit: Optional[int] = None,
    +    cursor: Optional[str] = None,
    +    archived: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Get records from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.list
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "limit": limit,
    +            "cursor": cursor,
    +            "archived": archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.list", json=kwargs)
    +
    + +
    +
    +def slackLists_items_update(self, *, list_id: str, cells: List[Dict[str, Any]], **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_update(
    +    self,
    +    *,
    +    list_id: str,
    +    cells: List[Dict[str, Any]],
    +    **kwargs,
    +) -> SlackResponse:
    +    """Updates cells in a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.update
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "cells": cells,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.update", json=kwargs)
    +
    + +
    +
    +def slackLists_update(self,
    *,
    id: str,
    name: str | None = None,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_update(
    +    self,
    +    *,
    +    id: str,
    +    name: Optional[str] = None,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Update a List.
    +    https://docs.slack.dev/reference/methods/slackLists.update
    +    """
    +    kwargs.update(
    +        {
    +            "id": id,
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.update", json=kwargs)
    +
    + +
    def stars_add(self,
    *,
    channel: str | None = None,
    file: str | None = None,
    file_comment: str | None = None,
    timestamp: str | None = None,
    **kwargs) ‑> SlackResponse
    @@ -14967,6 +15648,7 @@

    dnd_setSnooze
  • dnd_teamInfo
  • emoji_list
  • +
  • entity_presentDetails
  • files_comments_delete
  • files_completeUploadExternal
  • files_delete
  • @@ -15036,6 +15718,18 @@

    search_all
  • search_files
  • search_messages
  • +
  • slackLists_access_delete
  • +
  • slackLists_access_set
  • +
  • slackLists_create
  • +
  • slackLists_download_get
  • +
  • slackLists_download_start
  • +
  • slackLists_items_create
  • +
  • slackLists_items_delete
  • +
  • slackLists_items_deleteMultiple
  • +
  • slackLists_items_info
  • +
  • slackLists_items_list
  • +
  • slackLists_items_update
  • +
  • slackLists_update
  • stars_add
  • stars_list
  • stars_remove
  • diff --git a/docs/reference/web/index.html b/docs/reference/web/index.html index f4f7e2f2b..611a26b3b 100644 --- a/docs/reference/web/index.html +++ b/docs/reference/web/index.html @@ -3159,7 +3159,7 @@

    Raises

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -3388,6 +3388,7 @@

    Raises

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -3404,6 +3405,7 @@

    Raises

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -4035,6 +4037,30 @@

    Raises

    kwargs.update({"include_categories": include_categories}) return self.api_call("emoji.list", http_verb="GET", params=kwargs) + def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> SlackResponse: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return self.api_call("entity.presentDetails", json=kwargs) + def files_comments_delete( self, *, @@ -5289,6 +5315,249 @@

    Raises

    ) return self.api_call("search.messages", http_verb="GET", params=kwargs) + def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.delete", json=kwargs) + + def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.set", json=kwargs) + + def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.create", json=kwargs) + + def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> SlackResponse: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.get", json=kwargs) + + def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.start", json=kwargs) + + def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> SlackResponse: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.create", json=kwargs) + + def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> SlackResponse: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.delete", json=kwargs) + + def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> SlackResponse: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.info", json=kwargs) + + def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.list", json=kwargs) + + def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> SlackResponse: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.update", json=kwargs) + + def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.update", json=kwargs) + def stars_add( self, *, @@ -10435,7 +10704,7 @@

    Methods

    https://docs.slack.dev/reference/methods/chat.postEphemeral

    -def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> SlackResponse
    +def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | EventAndEntityMetadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> SlackResponse
    @@ -10461,7 +10730,7 @@

    Methods

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -10783,7 +11052,7 @@

    Example

    -def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> SlackResponse
    +def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    metadata: Dict | EventAndEntityMetadata | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> SlackResponse
    @@ -10798,6 +11067,7 @@

    Example

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -10814,6 +11084,7 @@

    Example

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -11845,6 +12116,41 @@

    Example

    +
    +def entity_presentDetails(self,
    trigger_id: str,
    metadata: Dict | EntityMetadata | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    error: Dict[str, Any] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def entity_presentDetails(
    +    self,
    +    trigger_id: str,
    +    metadata: Optional[Union[Dict, EntityMetadata]] = None,
    +    user_auth_required: Optional[bool] = None,
    +    user_auth_url: Optional[str] = None,
    +    error: Optional[Dict[str, Any]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Provides entity details for the flexpane.
    +    https://docs.slack.dev/reference/methods/entity.presentDetails/
    +    """
    +    kwargs.update({"trigger_id": trigger_id})
    +    if metadata is not None:
    +        kwargs.update({"metadata": metadata})
    +    if user_auth_required is not None:
    +        kwargs.update({"user_auth_required": user_auth_required})
    +    if user_auth_url is not None:
    +        kwargs.update({"user_auth_url": user_auth_url})
    +    if error is not None:
    +        kwargs.update({"error": error})
    +    _parse_web_class_objects(kwargs)
    +    return self.api_call("entity.presentDetails", json=kwargs)
    +
    +

    Provides entity details for the flexpane. +https://docs.slack.dev/reference/methods/entity.presentDetails/

    +
    def files_comments_delete(self, *, file: str, id: str, **kwargs) ‑> SlackResponse
    @@ -13820,6 +14126,381 @@

    Example

    Searches for messages matching a query. https://docs.slack.dev/reference/methods/search.messages

    +
    +def slackLists_access_delete(self,
    *,
    list_id: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_access_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Revoke access to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.delete
    +    """
    +    kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.access.delete", json=kwargs)
    +
    +

    Revoke access to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.delete

    +
    +
    +def slackLists_access_set(self,
    *,
    list_id: str,
    access_level: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_access_set(
    +    self,
    +    *,
    +    list_id: str,
    +    access_level: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Set the access level to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.set
    +    """
    +    kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.access.set", json=kwargs)
    +
    +

    Set the access level to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.set

    +
    +
    +def slackLists_create(self,
    *,
    name: str,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    schema: List[Dict[str, Any]] | None = None,
    copy_from_list_id: str | None = None,
    include_copied_list_records: bool | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_create(
    +    self,
    +    *,
    +    name: str,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    schema: Optional[List[Dict[str, Any]]] = None,
    +    copy_from_list_id: Optional[str] = None,
    +    include_copied_list_records: Optional[bool] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Creates a List.
    +    https://docs.slack.dev/reference/methods/slackLists.create
    +    """
    +    kwargs.update(
    +        {
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "schema": schema,
    +            "copy_from_list_id": copy_from_list_id,
    +            "include_copied_list_records": include_copied_list_records,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.create", json=kwargs)
    +
    + +
    +
    +def slackLists_download_get(self, *, list_id: str, job_id: str, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_download_get(
    +    self,
    +    *,
    +    list_id: str,
    +    job_id: str,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Retrieve List download URL from an export job to download List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.get
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "job_id": job_id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.download.get", json=kwargs)
    +
    +

    Retrieve List download URL from an export job to download List contents. +https://docs.slack.dev/reference/methods/slackLists.download.get

    +
    +
    +def slackLists_download_start(self, *, list_id: str, include_archived: bool | None = None, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_download_start(
    +    self,
    +    *,
    +    list_id: str,
    +    include_archived: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Initiate a job to export List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.start
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "include_archived": include_archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.download.start", json=kwargs)
    +
    + +
    +
    +def slackLists_items_create(self,
    *,
    list_id: str,
    duplicated_item_id: str | None = None,
    parent_item_id: str | None = None,
    initial_fields: List[Dict[str, Any]] | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_items_create(
    +    self,
    +    *,
    +    list_id: str,
    +    duplicated_item_id: Optional[str] = None,
    +    parent_item_id: Optional[str] = None,
    +    initial_fields: Optional[List[Dict[str, Any]]] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Add a new item to an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.create
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "duplicated_item_id": duplicated_item_id,
    +            "parent_item_id": parent_item_id,
    +            "initial_fields": initial_fields,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.create", json=kwargs)
    +
    + +
    +
    +def slackLists_items_delete(self, *, list_id: str, id: str, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Deletes an item from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.delete
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.delete", json=kwargs)
    +
    + +
    +
    +def slackLists_items_deleteMultiple(self, *, list_id: str, ids: List[str], **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_deleteMultiple(
    +    self,
    +    *,
    +    list_id: str,
    +    ids: List[str],
    +    **kwargs,
    +) -> SlackResponse:
    +    """Deletes multiple items from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "ids": ids,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.deleteMultiple", json=kwargs)
    +
    + +
    +
    +def slackLists_items_info(self, *, list_id: str, id: str, include_is_subscribed: bool | None = None, **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_info(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    include_is_subscribed: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Get a row from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.info
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +            "include_is_subscribed": include_is_subscribed,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.info", json=kwargs)
    +
    + +
    +
    +def slackLists_items_list(self,
    *,
    list_id: str,
    limit: int | None = None,
    cursor: str | None = None,
    archived: bool | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_items_list(
    +    self,
    +    *,
    +    list_id: str,
    +    limit: Optional[int] = None,
    +    cursor: Optional[str] = None,
    +    archived: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Get records from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.list
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "limit": limit,
    +            "cursor": cursor,
    +            "archived": archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.list", json=kwargs)
    +
    + +
    +
    +def slackLists_items_update(self, *, list_id: str, cells: List[Dict[str, Any]], **kwargs) ‑> SlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_update(
    +    self,
    +    *,
    +    list_id: str,
    +    cells: List[Dict[str, Any]],
    +    **kwargs,
    +) -> SlackResponse:
    +    """Updates cells in a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.update
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "cells": cells,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.update", json=kwargs)
    +
    + +
    +
    +def slackLists_update(self,
    *,
    id: str,
    name: str | None = None,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> SlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_update(
    +    self,
    +    *,
    +    id: str,
    +    name: Optional[str] = None,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> SlackResponse:
    +    """Update a List.
    +    https://docs.slack.dev/reference/methods/slackLists.update
    +    """
    +    kwargs.update(
    +        {
    +            "id": id,
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.update", json=kwargs)
    +
    + +
    def stars_add(self,
    *,
    channel: str | None = None,
    file: str | None = None,
    file_comment: str | None = None,
    timestamp: str | None = None,
    **kwargs) ‑> SlackResponse
    @@ -15362,6 +16043,7 @@

    Web
  • dnd_setSnooze
  • dnd_teamInfo
  • emoji_list
  • +
  • entity_presentDetails
  • files_comments_delete
  • files_completeUploadExternal
  • files_delete
  • @@ -15431,6 +16113,18 @@

    Web
  • search_all
  • search_files
  • search_messages
  • +
  • slackLists_access_delete
  • +
  • slackLists_access_set
  • +
  • slackLists_create
  • +
  • slackLists_download_get
  • +
  • slackLists_download_start
  • +
  • slackLists_items_create
  • +
  • slackLists_items_delete
  • +
  • slackLists_items_deleteMultiple
  • +
  • slackLists_items_info
  • +
  • slackLists_items_list
  • +
  • slackLists_items_update
  • +
  • slackLists_update
  • stars_add
  • stars_list
  • stars_remove
  • diff --git a/docs/reference/web/legacy_client.html b/docs/reference/web/legacy_client.html index 70cc6988d..d100178dc 100644 --- a/docs/reference/web/legacy_client.html +++ b/docs/reference/web/legacy_client.html @@ -2789,7 +2789,7 @@

    Classes

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> Union[Future, SlackResponse]: @@ -2955,6 +2955,7 @@

    Classes

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -2971,6 +2972,7 @@

    Classes

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3602,6 +3604,30 @@

    Classes

    kwargs.update({"include_categories": include_categories}) return self.api_call("emoji.list", http_verb="GET", params=kwargs) + def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return self.api_call("entity.presentDetails", json=kwargs) + def files_comments_delete( self, *, @@ -4856,6 +4882,249 @@

    Classes

    ) return self.api_call("search.messages", http_verb="GET", params=kwargs) + def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.delete", json=kwargs) + + def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.set", json=kwargs) + + def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.create", json=kwargs) + + def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.get", json=kwargs) + + def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.start", json=kwargs) + + def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.create", json=kwargs) + + def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.delete", json=kwargs) + + def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> Union[Future, SlackResponse]: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.info", json=kwargs) + + def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.list", json=kwargs) + + def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> Union[Future, SlackResponse]: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.update", json=kwargs) + + def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.update", json=kwargs) + def stars_add( self, *, @@ -10002,7 +10271,7 @@

    Methods

    https://docs.slack.dev/reference/methods/chat.postEphemeral

    -def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +def chat_postMessage(self,
    *,
    channel: str,
    text: str | None = None,
    as_user: bool | None = None,
    attachments: str | Sequence[Dict | Attachment] | None = None,
    blocks: str | Sequence[Dict | Block] | None = None,
    thread_ts: str | None = None,
    reply_broadcast: bool | None = None,
    unfurl_links: bool | None = None,
    unfurl_media: bool | None = None,
    container_id: str | None = None,
    icon_emoji: str | None = None,
    icon_url: str | None = None,
    mrkdwn: bool | None = None,
    link_names: bool | None = None,
    username: str | None = None,
    parse: str | None = None,
    metadata: Dict | Metadata | EventAndEntityMetadata | None = None,
    markdown_text: str | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    @@ -10028,7 +10297,7 @@

    Methods

    link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> Union[Future, SlackResponse]: @@ -10234,7 +10503,7 @@

    Methods

    https://docs.slack.dev/reference/methods/chat.stopStream

    -def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +def chat_unfurl(self,
    *,
    channel: str | None = None,
    ts: str | None = None,
    source: str | None = None,
    unfurl_id: str | None = None,
    unfurls: Dict[str, Dict] | None = None,
    metadata: Dict | EventAndEntityMetadata | None = None,
    user_auth_blocks: str | Sequence[Dict | Block] | None = None,
    user_auth_message: str | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    @@ -10249,6 +10518,7 @@

    Methods

    source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -10265,6 +10535,7 @@

    Methods

    "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -11296,6 +11567,41 @@

    Methods

    +
    +def entity_presentDetails(self,
    trigger_id: str,
    metadata: Dict | EntityMetadata | None = None,
    user_auth_required: bool | None = None,
    user_auth_url: str | None = None,
    error: Dict[str, Any] | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def entity_presentDetails(
    +    self,
    +    trigger_id: str,
    +    metadata: Optional[Union[Dict, EntityMetadata]] = None,
    +    user_auth_required: Optional[bool] = None,
    +    user_auth_url: Optional[str] = None,
    +    error: Optional[Dict[str, Any]] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Provides entity details for the flexpane.
    +    https://docs.slack.dev/reference/methods/entity.presentDetails/
    +    """
    +    kwargs.update({"trigger_id": trigger_id})
    +    if metadata is not None:
    +        kwargs.update({"metadata": metadata})
    +    if user_auth_required is not None:
    +        kwargs.update({"user_auth_required": user_auth_required})
    +    if user_auth_url is not None:
    +        kwargs.update({"user_auth_url": user_auth_url})
    +    if error is not None:
    +        kwargs.update({"error": error})
    +    _parse_web_class_objects(kwargs)
    +    return self.api_call("entity.presentDetails", json=kwargs)
    +
    +

    Provides entity details for the flexpane. +https://docs.slack.dev/reference/methods/entity.presentDetails/

    +
    def files_comments_delete(self, *, file: str, id: str, **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    @@ -13271,6 +13577,381 @@

    Methods

    Searches for messages matching a query. https://docs.slack.dev/reference/methods/search.messages

    +
    +def slackLists_access_delete(self,
    *,
    list_id: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_access_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Revoke access to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.delete
    +    """
    +    kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.access.delete", json=kwargs)
    +
    +

    Revoke access to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.delete

    +
    +
    +def slackLists_access_set(self,
    *,
    list_id: str,
    access_level: str,
    channel_ids: List[str] | None = None,
    user_ids: List[str] | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_access_set(
    +    self,
    +    *,
    +    list_id: str,
    +    access_level: str,
    +    channel_ids: Optional[List[str]] = None,
    +    user_ids: Optional[List[str]] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Set the access level to a List for specified entities.
    +    https://docs.slack.dev/reference/methods/slackLists.access.set
    +    """
    +    kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids})
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.access.set", json=kwargs)
    +
    +

    Set the access level to a List for specified entities. +https://docs.slack.dev/reference/methods/slackLists.access.set

    +
    +
    +def slackLists_create(self,
    *,
    name: str,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    schema: List[Dict[str, Any]] | None = None,
    copy_from_list_id: str | None = None,
    include_copied_list_records: bool | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_create(
    +    self,
    +    *,
    +    name: str,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    schema: Optional[List[Dict[str, Any]]] = None,
    +    copy_from_list_id: Optional[str] = None,
    +    include_copied_list_records: Optional[bool] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Creates a List.
    +    https://docs.slack.dev/reference/methods/slackLists.create
    +    """
    +    kwargs.update(
    +        {
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "schema": schema,
    +            "copy_from_list_id": copy_from_list_id,
    +            "include_copied_list_records": include_copied_list_records,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.create", json=kwargs)
    +
    + +
    +
    +def slackLists_download_get(self, *, list_id: str, job_id: str, **kwargs) ‑> _asyncio.Future | LegacySlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_download_get(
    +    self,
    +    *,
    +    list_id: str,
    +    job_id: str,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Retrieve List download URL from an export job to download List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.get
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "job_id": job_id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.download.get", json=kwargs)
    +
    +

    Retrieve List download URL from an export job to download List contents. +https://docs.slack.dev/reference/methods/slackLists.download.get

    +
    +
    +def slackLists_download_start(self, *, list_id: str, include_archived: bool | None = None, **kwargs) ‑> _asyncio.Future | LegacySlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_download_start(
    +    self,
    +    *,
    +    list_id: str,
    +    include_archived: Optional[bool] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Initiate a job to export List contents.
    +    https://docs.slack.dev/reference/methods/slackLists.download.start
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "include_archived": include_archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.download.start", json=kwargs)
    +
    + +
    +
    +def slackLists_items_create(self,
    *,
    list_id: str,
    duplicated_item_id: str | None = None,
    parent_item_id: str | None = None,
    initial_fields: List[Dict[str, Any]] | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_items_create(
    +    self,
    +    *,
    +    list_id: str,
    +    duplicated_item_id: Optional[str] = None,
    +    parent_item_id: Optional[str] = None,
    +    initial_fields: Optional[List[Dict[str, Any]]] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Add a new item to an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.create
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "duplicated_item_id": duplicated_item_id,
    +            "parent_item_id": parent_item_id,
    +            "initial_fields": initial_fields,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.create", json=kwargs)
    +
    + +
    +
    +def slackLists_items_delete(self, *, list_id: str, id: str, **kwargs) ‑> _asyncio.Future | LegacySlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_delete(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Deletes an item from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.delete
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.delete", json=kwargs)
    +
    + +
    +
    +def slackLists_items_deleteMultiple(self, *, list_id: str, ids: List[str], **kwargs) ‑> _asyncio.Future | LegacySlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_deleteMultiple(
    +    self,
    +    *,
    +    list_id: str,
    +    ids: List[str],
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Deletes multiple items from an existing List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "ids": ids,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.deleteMultiple", json=kwargs)
    +
    + +
    +
    +def slackLists_items_info(self, *, list_id: str, id: str, include_is_subscribed: bool | None = None, **kwargs) ‑> _asyncio.Future | LegacySlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_info(
    +    self,
    +    *,
    +    list_id: str,
    +    id: str,
    +    include_is_subscribed: Optional[bool] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Get a row from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.info
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "id": id,
    +            "include_is_subscribed": include_is_subscribed,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.info", json=kwargs)
    +
    + +
    +
    +def slackLists_items_list(self,
    *,
    list_id: str,
    limit: int | None = None,
    cursor: str | None = None,
    archived: bool | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_items_list(
    +    self,
    +    *,
    +    list_id: str,
    +    limit: Optional[int] = None,
    +    cursor: Optional[str] = None,
    +    archived: Optional[bool] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Get records from a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.list
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "limit": limit,
    +            "cursor": cursor,
    +            "archived": archived,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.list", json=kwargs)
    +
    + +
    +
    +def slackLists_items_update(self, *, list_id: str, cells: List[Dict[str, Any]], **kwargs) ‑> _asyncio.Future | LegacySlackResponse +
    +
    +
    + +Expand source code + +
    def slackLists_items_update(
    +    self,
    +    *,
    +    list_id: str,
    +    cells: List[Dict[str, Any]],
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Updates cells in a List.
    +    https://docs.slack.dev/reference/methods/slackLists.items.update
    +    """
    +    kwargs.update(
    +        {
    +            "list_id": list_id,
    +            "cells": cells,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.items.update", json=kwargs)
    +
    + +
    +
    +def slackLists_update(self,
    *,
    id: str,
    name: str | None = None,
    description_blocks: str | Sequence[Dict | RichTextBlock] | None = None,
    todo_mode: bool | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    +
    +
    +
    + +Expand source code + +
    def slackLists_update(
    +    self,
    +    *,
    +    id: str,
    +    name: Optional[str] = None,
    +    description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None,
    +    todo_mode: Optional[bool] = None,
    +    **kwargs,
    +) -> Union[Future, SlackResponse]:
    +    """Update a List.
    +    https://docs.slack.dev/reference/methods/slackLists.update
    +    """
    +    kwargs.update(
    +        {
    +            "id": id,
    +            "name": name,
    +            "description_blocks": description_blocks,
    +            "todo_mode": todo_mode,
    +        }
    +    )
    +    kwargs = _remove_none_values(kwargs)
    +    return self.api_call("slackLists.update", json=kwargs)
    +
    + +
    def stars_add(self,
    *,
    channel: str | None = None,
    file: str | None = None,
    file_comment: str | None = None,
    timestamp: str | None = None,
    **kwargs) ‑> _asyncio.Future | LegacySlackResponse
    @@ -14785,6 +15466,7 @@

    dnd_setSnooze
  • dnd_teamInfo
  • emoji_list
  • +
  • entity_presentDetails
  • files_comments_delete
  • files_completeUploadExternal
  • files_delete
  • @@ -14854,6 +15536,18 @@

    search_all
  • search_files
  • search_messages
  • +
  • slackLists_access_delete
  • +
  • slackLists_access_set
  • +
  • slackLists_create
  • +
  • slackLists_download_get
  • +
  • slackLists_download_start
  • +
  • slackLists_items_create
  • +
  • slackLists_items_delete
  • +
  • slackLists_items_deleteMultiple
  • +
  • slackLists_items_info
  • +
  • slackLists_items_list
  • +
  • slackLists_items_update
  • +
  • slackLists_update
  • stars_add
  • stars_list
  • stars_remove
  • diff --git a/integration_tests/web/test_admin_conversations_restrictAccess.py b/integration_tests/web/test_admin_conversations_restrictAccess.py index 54ee4e6c9..97915abe5 100644 --- a/integration_tests/web/test_admin_conversations_restrictAccess.py +++ b/integration_tests/web/test_admin_conversations_restrictAccess.py @@ -40,7 +40,10 @@ def setUp(self): if self.channel_id is None: millis = int(round(time.time() * 1000)) channel_name = f"private-test-channel-{millis}" - self.channel_id = client.conversations_create(name=channel_name, is_private=True,)[ + self.channel_id = client.conversations_create( + name=channel_name, + is_private=True, + )[ "channel" ]["id"] diff --git a/integration_tests/web/test_calls.py b/integration_tests/web/test_calls.py index 7f5979378..d285c03f0 100644 --- a/integration_tests/web/test_calls.py +++ b/integration_tests/web/test_calls.py @@ -24,7 +24,12 @@ def tearDown(self): def test_sync(self): client = self.sync_client - user_id = list(filter(lambda u: not u["deleted"] and "bot_id" not in u, client.users_list(limit=50)["members"],))[ + user_id = list( + filter( + lambda u: not u["deleted"] and "bot_id" not in u, + client.users_list(limit=50)["members"], + ) + )[ 0 ]["id"] diff --git a/integration_tests/web/test_message_metadata.py b/integration_tests/web/test_message_metadata.py index bb3a4de7b..dc2626d27 100644 --- a/integration_tests/web/test_message_metadata.py +++ b/integration_tests/web/test_message_metadata.py @@ -2,9 +2,32 @@ import os import time import unittest +import json from integration_tests.env_variable_names import SLACK_SDK_TEST_BOT_TOKEN -from slack_sdk.models.metadata import Metadata +from slack_sdk.models.metadata import ( + Metadata, + EventAndEntityMetadata, + EntityMetadata, + ExternalRef, + EntityPayload, + EntityAttributes, + EntityTitle, + TaskEntityFields, + EntityStringField, + EntityTitle, + EntityAttributes, + EntityFullSizePreview, + TaskEntityFields, + EntityTypedField, + EntityStringField, + EntityTimestampField, + EntityEditSupport, + EntityEditTextConfig, + EntityCustomField, + EntityUserIDField, + ExternalRef, +) from slack_sdk.web import WebClient @@ -125,3 +148,97 @@ def test_publishing_message_metadata_using_models(self): ) self.assertIsNone(scheduled.get("error")) self.assertIsNotNone(scheduled.get("message").get("metadata")) + + def test_publishing_entity_metadata(self): + client: WebClient = WebClient(token=self.bot_token) + new_message = client.chat_postMessage( + channel="C014KLZN9M0", + text="Message with entity metadata", + metadata={ + "entities": [ + { + "entity_type": "slack#/entities/task", + "url": "https://abc.com/123", + "external_ref": {"id": "123"}, + "entity_payload": { + "attributes": {"title": {"text": "My task"}, "product_name": "We reference only"}, + "fields": { + "due_date": {"value": "2026-06-06", "type": "slack#/types/date", "edit": {"enabled": True}}, + "created_by": {"type": "slack#/types/user", "user": {"user_id": "U014KLZE350"}}, + "date_created": {"value": 1760629278}, + }, + "custom_fields": [ + { + "label": "img", + "key": "img", + "type": "slack#/types/image", + "image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/korel-1YjNtFtJlMTaC26A/o.jpg", + } + ], + }, + } + ] + }, + ) + + self.assertIsNone(new_message.get("error")) + self.assertIsNone(new_message.get("warning")) + + def test_publishing_entity_metadata_using_models(self): + # Build the metadata + + title = EntityTitle(text="My title") + full_size_preview = EntityFullSizePreview( + is_supported=True, + preview_url="https://s3-media3.fl.yelpcdn.com/bphoto/c7ed05m9lC2EmA3Aruue7A/o.jpg", + mime_type="image/jpeg", + ) + attributes = EntityAttributes(title=title, product_name="My Product", full_size_preview=full_size_preview) + description = EntityStringField( + value="Description of the task.", + long=True, + edit=EntityEditSupport(enabled=True, text=EntityEditTextConfig(min_length=5, max_length=100)), + ) + due_date = EntityTypedField(value="2026-06-06", type="slack#/types/date", edit=EntityEditSupport(enabled=True)) + created_by = EntityTypedField( + type="slack#/types/user", + user=EntityUserIDField(user_id="USLACKBOT"), + ) + date_created = EntityTimestampField(value=1762450663, type="slack#/types/timestamp") + date_updated = EntityTimestampField(value=1762450663, type="slack#/types/timestamp") + fields = TaskEntityFields( + description=description, + due_date=due_date, + created_by=created_by, + date_created=date_created, + date_updated=date_updated, + ) + custom_fields = [] + custom_fields.append( + EntityCustomField( + label="My Image", + key="my-image", + type="slack#/types/image", + image_url="https://s3-media3.fl.yelpcdn.com/bphoto/c7ed05m9lC2EmA3Aruue7A/o.jpg", + ) + ) + entity = EntityPayload(attributes=attributes, fields=fields, custom_fields=custom_fields) + + client: WebClient = WebClient(token=self.bot_token) + new_message = client.chat_postMessage( + channel="#random", + text="Message with entity metadata", + metadata=EventAndEntityMetadata( + entities=[ + EntityMetadata( + entity_type="slack#/entities/task", + external_ref=ExternalRef(id="abc123"), + url="https://myappdomain.com", + entity_payload=entity, + ) + ] + ), + ) + + self.assertIsNone(new_message.get("error")) + self.assertIsNone(new_message.get("warning")) diff --git a/integration_tests/web/test_slack_lists.py b/integration_tests/web/test_slack_lists.py new file mode 100644 index 000000000..6d813bffe --- /dev/null +++ b/integration_tests/web/test_slack_lists.py @@ -0,0 +1,88 @@ +import logging +import os +import unittest + +from integration_tests.env_variable_names import ( + SLACK_SDK_TEST_BOT_TOKEN, +) +from integration_tests.helpers import async_test +from slack_sdk.web import WebClient +from slack_sdk.web.async_client import AsyncWebClient +from slack_sdk.models.blocks import RichTextBlock +from slack_sdk.models.blocks.block_elements import RichTextSection, RichTextText + + +class TestSlackLists(unittest.TestCase): + """Runs integration tests with real Slack API testing the slackLists.* APIs""" + + def setUp(self): + if not hasattr(self, "logger"): + self.logger = logging.getLogger(__name__) + self.bot_token = os.environ[SLACK_SDK_TEST_BOT_TOKEN] + self.async_client: AsyncWebClient = AsyncWebClient(token=self.bot_token) + self.sync_client: WebClient = WebClient(token=self.bot_token) + + def tearDown(self): + pass + + def test_create_list_with_dicts(self): + """Test creating a list with description_blocks as dicts""" + client = self.sync_client + + create_response = client.slackLists_create( + name="Test Sales Pipeline", + description_blocks=[ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [{"type": "text", "text": "This is a test list for integration testing"}], + } + ], + } + ], + schema=[ + {"key": "deal_name", "name": "Deal Name", "type": "text", "is_primary_column": True}, + {"key": "amount", "name": "Amount", "type": "number", "options": {"format": "currency", "precision": 2}}, + ], + ) + + self.assertIsNotNone(create_response) + self.assertTrue(create_response["ok"]) + self.assertIn("list", create_response) + list_id = create_response["list"]["id"] + self.logger.info(f"✓ Created list with ID: {list_id}") + + def test_create_list_with_rich_text_blocks(self): + """Test creating a list with RichTextBlock objects""" + client = self.sync_client + + create_response = client.slackLists_create( + name="Test List with Rich Text Blocks", + description_blocks=[ + RichTextBlock( + elements=[RichTextSection(elements=[RichTextText(text="Created with RichTextBlock objects!")])] + ) + ], + schema=[{"key": "task_name", "name": "Task", "type": "text", "is_primary_column": True}], + ) + + self.assertIsNotNone(create_response) + self.assertTrue(create_response["ok"]) + list_id = create_response["list"]["id"] + self.logger.info(f"✓ Created list with RichTextBlocks, ID: {list_id}") + + @async_test + async def test_create_list_async(self): + """Test creating a list with async client""" + client = self.async_client + + create_response = await client.slackLists_create( + name="Async Test List", schema=[{"key": "item_name", "name": "Item", "type": "text", "is_primary_column": True}] + ) + + self.assertIsNotNone(create_response) + self.assertTrue(create_response["ok"]) + list_id = create_response["list"]["id"] + self.logger.info(f"✓ Created list asynchronously, ID: {list_id}") diff --git a/pyproject.toml b/pyproject.toml index 1a1c5761b..37c6f3546 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", ] diff --git a/requirements/testing.txt b/requirements/testing.txt index 3c9e941e5..9b702718c 100644 --- a/requirements/testing.txt +++ b/requirements/testing.txt @@ -3,19 +3,13 @@ aiohttp<4 # used for a WebSocket server mock pytest>=7.0.1,<9 pytest-asyncio<2 # for async pytest-cov>=2,<8 -# while flake8 5.x have issues with Python 3.12, flake8 6.x requires Python >= 3.8.1, -# so 5.x should be kept in order to stay compatible with Python 3.7/3.8 -flake8>=5.0.4,<8 -# Don't change this version without running CI builds; -# The latest version may not be available for older Python runtime -black==22.10.0; click==8.0.4 # black is affected by https://github.com/pallets/click/issues/2225 psutil>=6.0.0,<8 # used only under slack_sdk/*_store boto3<=2 # For AWS tests moto>=4.0.13,<6 -mypy<=1.18.2 # For AsyncSQLAlchemy tests greenlet<=4 -aiosqlite<=1 \ No newline at end of file +aiosqlite<=1 +-r tools.txt diff --git a/requirements/tools.txt b/requirements/tools.txt new file mode 100644 index 000000000..0a646dc12 --- /dev/null +++ b/requirements/tools.txt @@ -0,0 +1,7 @@ +mypy<=1.18.2 +# while flake8 5.x have issues with Python 3.12, flake8 6.x requires Python >= 3.8.1, +# so 5.x should be kept in order to stay compatible with Python 3.7/3.8 +flake8>=5.0.4,<8 +# Don't change this version without running CI builds; +# The latest version may not be available for older Python runtime +black==23.3.0; diff --git a/scripts/deploy_to_prod_pypi_org.sh b/scripts/deploy_to_prod_pypi_org.sh deleted file mode 100755 index b96cdef62..000000000 --- a/scripts/deploy_to_prod_pypi_org.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -script_dir=`dirname $0` -cd ${script_dir}/.. -rm -rf ./slack_sdk.egg-info - -pip install -U pip && \ - pip install -U twine build && \ - rm -rf dist/ build/ slack_sdk.egg-info/ && \ - python -m build --sdist --wheel && \ - twine check dist/* && \ - twine upload dist/* diff --git a/scripts/deploy_to_test_pypi_org.sh b/scripts/deploy_to_test_pypi.sh similarity index 100% rename from scripts/deploy_to_test_pypi_org.sh rename to scripts/deploy_to_test_pypi.sh diff --git a/scripts/format.sh b/scripts/format.sh new file mode 100755 index 000000000..d4236258f --- /dev/null +++ b/scripts/format.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# ./scripts/format.sh + +script_dir=`dirname $0` +cd ${script_dir}/.. + +pip install -U pip +pip install -U -r requirements/tools.txt + +black slack/ slack_sdk/ tests/ integration_tests/ diff --git a/scripts/generate_api_docs.sh b/scripts/generate_api_docs.sh index 8f1281141..c2bb260ab 100755 --- a/scripts/generate_api_docs.sh +++ b/scripts/generate_api_docs.sh @@ -9,7 +9,7 @@ pip install -U -r requirements/optional.txt rm -rf docs/reference -pdoc slack_sdk --html -o docs/reference +HOME="\$HOME" pdoc slack_sdk --html -o docs/reference cp -R docs/reference/slack_sdk/* docs/reference/ rm -rf docs/reference/slack_sdk diff --git a/slack_sdk/__init__.py b/slack_sdk/__init__.py index 3adab865a..b5204e3e3 100644 --- a/slack_sdk/__init__.py +++ b/slack_sdk/__init__.py @@ -37,6 +37,7 @@ * `slack_sdk.scim.v1.async_client` """ + import logging from logging import NullHandler diff --git a/slack_sdk/aiohttp_version_checker.py b/slack_sdk/aiohttp_version_checker.py index 9f4d70fc3..1eff14efa 100644 --- a/slack_sdk/aiohttp_version_checker.py +++ b/slack_sdk/aiohttp_version_checker.py @@ -1,4 +1,5 @@ """Internal module for checking aiohttp compatibility of async modules""" + import logging from typing import Callable diff --git a/slack_sdk/audit_logs/__init__.py b/slack_sdk/audit_logs/__init__.py index 26a3b30d6..f8a7a2a91 100644 --- a/slack_sdk/audit_logs/__init__.py +++ b/slack_sdk/audit_logs/__init__.py @@ -2,6 +2,7 @@ Refer to https://docs.slack.dev/tools/python-slack-sdk/audit-logs for details. """ + from .v1.client import AuditLogsClient from .v1.response import AuditLogsResponse diff --git a/slack_sdk/models/basic_objects.py b/slack_sdk/models/basic_objects.py index 339358790..4feefe3f6 100644 --- a/slack_sdk/models/basic_objects.py +++ b/slack_sdk/models/basic_objects.py @@ -40,6 +40,9 @@ def validate_json(self) -> None: if callable(method) and hasattr(method, "validator"): method() + def get_object_attribute(self, key: str): + return getattr(self, key, None) + def get_non_null_attributes(self) -> dict: """ Construct a dictionary out of non-null keys (from attributes property) @@ -57,7 +60,7 @@ def to_dict_compatible(value: Union[dict, list, object, tuple]) -> Union[dict, l return value def is_not_empty(self, key: str) -> bool: - value = getattr(self, key, None) + value = self.get_object_attribute(key) if value is None: return False @@ -75,7 +78,9 @@ def is_not_empty(self, key: str) -> bool: return value is not None return { - key: to_dict_compatible(getattr(self, key, None)) for key in sorted(self.attributes) if is_not_empty(self, key) + key: to_dict_compatible(value=self.get_object_attribute(key)) + for key in sorted(self.attributes) + if is_not_empty(self, key) } def to_dict(self, *args) -> dict: diff --git a/slack_sdk/models/blocks/__init__.py b/slack_sdk/models/blocks/__init__.py index 334f55c40..d2776a9dc 100644 --- a/slack_sdk/models/blocks/__init__.py +++ b/slack_sdk/models/blocks/__init__.py @@ -16,6 +16,7 @@ Option, OptionGroup, PlainTextObject, + RawTextObject, TextObject, ) from .block_elements import ( @@ -71,6 +72,7 @@ MarkdownBlock, RichTextBlock, SectionBlock, + TableBlock, VideoBlock, ) @@ -83,6 +85,7 @@ "Option", "OptionGroup", "PlainTextObject", + "RawTextObject", "TextObject", "BlockElement", "ButtonElement", @@ -133,6 +136,7 @@ "InputBlock", "MarkdownBlock", "SectionBlock", + "TableBlock", "VideoBlock", "RichTextBlock", ] diff --git a/slack_sdk/models/blocks/basic_components.py b/slack_sdk/models/blocks/basic_components.py index f118c5a7f..b6e71683a 100644 --- a/slack_sdk/models/blocks/basic_components.py +++ b/slack_sdk/models/blocks/basic_components.py @@ -157,6 +157,40 @@ def direct_from_link(link: Link, title: str = "") -> Dict[str, Any]: return MarkdownTextObject.from_link(link, title).to_dict() +class RawTextObject(TextObject): + """raw_text typed text object""" + + type = "raw_text" + + @property + def attributes(self) -> Set[str]: # type: ignore[override] + return {"text", "type"} + + def __init__(self, *, text: str): + """A raw text object used in table block cells. + https://docs.slack.dev/reference/block-kit/composition-objects/text-object/ + https://docs.slack.dev/reference/block-kit/blocks/table-block + + Args: + text (required): The text content for the table block cell. + """ + super().__init__(text=text, type=self.type) + + @staticmethod + def from_str(text: str) -> "RawTextObject": + """Transforms a string into a RawTextObject""" + return RawTextObject(text=text) + + @staticmethod + def direct_from_string(text: str) -> Dict[str, Any]: + """Transforms a string into the required object shape to act as a RawTextObject""" + return RawTextObject.from_str(text).to_dict() + + @JsonValidator("text attribute must have at least 1 character") + def _validate_text_min_length(self): + return len(self.text) >= 1 + + class Option(JsonObject): """Option object used in dialogs, legacy message actions (interactivity in attachments), and blocks. JSON must be retrieved with an explicit option_type - the Slack API has @@ -551,6 +585,7 @@ def __init__( ): """ A feedback button element object for either positive or negative feedback. + https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element#button-object-fields Args: text (required): An object containing some text. Maximum length for this field is 75 characters. diff --git a/slack_sdk/models/blocks/block_elements.py b/slack_sdk/models/blocks/block_elements.py index b38cf21e0..89f0a7994 100644 --- a/slack_sdk/models/blocks/block_elements.py +++ b/slack_sdk/models/blocks/block_elements.py @@ -561,6 +561,7 @@ def __init__( **others: dict, ): """Buttons to indicate positive or negative feedback. + https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element Args: action_id (required): An identifier for this action. @@ -650,6 +651,7 @@ def __init__( **others: dict, ): """An icon button to perform actions. + https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element Args: action_id: An identifier for this action. @@ -2032,11 +2034,13 @@ def __init__( italic: Optional[bool] = None, strike: Optional[bool] = None, code: Optional[bool] = None, + underline: Optional[bool] = None, ): self.bold = bold self.italic = italic self.strike = strike self.code = code + self.underline = underline def to_dict(self, *args) -> dict: result = { @@ -2044,6 +2048,7 @@ def to_dict(self, *args) -> dict: "italic": self.italic, "strike": self.strike, "code": self.code, + "underline": self.underline, } return {k: v for k, v in result.items() if v is not None} diff --git a/slack_sdk/models/blocks/blocks.py b/slack_sdk/models/blocks/blocks.py index 69200be25..cac463c99 100644 --- a/slack_sdk/models/blocks/blocks.py +++ b/slack_sdk/models/blocks/blocks.py @@ -95,6 +95,8 @@ def parse(cls, block: Union[dict, "Block"]) -> Optional["Block"]: return VideoBlock(**block) elif type == RichTextBlock.type: return RichTextBlock(**block) + elif type == TableBlock.type: + return TableBlock(**block) else: cls.logger.warning(f"Unknown block detected and skipped ({block})") return None @@ -375,6 +377,7 @@ def __init__( **others: dict, ): """Displays actions as contextual info, which can include both feedback buttons and icon buttons. + https://docs.slack.dev/reference/block-kit/blocks/context-actions-block Args: elements (required): An array of feedback_buttons or icon_button block elements. Maximum number of items is 5. @@ -730,3 +733,47 @@ def __init__( show_unknown_key_warning(self, others) self.elements = BlockElement.parse_all(elements) + + +class TableBlock(Block): + type = "table" + + @property + def attributes(self) -> Set[str]: # type: ignore[override] + return super().attributes.union({"rows", "column_settings"}) + + def __init__( + self, + *, + rows: Sequence[Sequence[Dict[str, Any]]], + column_settings: Optional[Sequence[Optional[Dict[str, Any]]]] = None, + block_id: Optional[str] = None, + **others: dict, + ): + """Displays structured information in a table. + https://docs.slack.dev/reference/block-kit/blocks/table-block + + Args: + rows (required): An array consisting of table rows. Maximum 100 rows. + Each row object is an array with a max of 20 table cells. + Table cells can have a type of raw_text or rich_text. + column_settings: An array describing column behavior. If there are fewer items in the column_settings array + than there are columns in the table, then the items in the the column_settings array will describe + the same number of columns in the table as there are in the array itself. + Any additional columns will have the default behavior. Maximum 20 items. + See below for column settings schema. + block_id: A unique identifier for a block. If not specified, a block_id will be generated. + You can use this block_id when you receive an interaction payload to identify the source of the action. + Maximum length for this field is 255 characters. + block_id should be unique for each message and each iteration of a message. + If a message is updated, use a new block_id. + """ + super().__init__(type=self.type, block_id=block_id) + show_unknown_key_warning(self, others) + + self.rows = rows + self.column_settings = column_settings + + @JsonValidator("rows attribute must be specified") + def _validate_rows(self): + return self.rows is not None and len(self.rows) > 0 diff --git a/slack_sdk/models/metadata/__init__.py b/slack_sdk/models/metadata/__init__.py index ddf24f1ae..7e4918401 100644 --- a/slack_sdk/models/metadata/__init__.py +++ b/slack_sdk/models/metadata/__init__.py @@ -1,5 +1,5 @@ -from typing import Dict, Any -from slack_sdk.models.basic_objects import JsonObject +from typing import Dict, Any, Union, Optional, List +from slack_sdk.models.basic_objects import JsonObject, EnumValidator class Metadata(JsonObject): @@ -28,3 +28,1228 @@ def __str__(self): def __repr__(self): return self.__str__() + + +# +# Work object entity metadata +# https://docs.slack.dev/messaging/work-objects/ +# + + +"""Entity types""" +EntityType = { + "slack#/entities/task", + "slack#/entities/file", + "slack#/entities/item", + "slack#/entities/incident", + "slack#/entities/content_item", +} + + +"""Custom field types""" +CustomFieldType = { + "integer", + "string", + "array", + "boolean", + "slack#/types/date", + "slack#/types/timestamp", + "slack#/types/image", + "slack#/types/channel_id", + "slack#/types/user", + "slack#/types/entity_ref", + "slack#/types/link", + "slack#/types/email", +} + + +class ExternalRef(JsonObject): + """Reference (and optional type) used to identify an entity within the developer's system""" + + attributes = { + "id", + "type", + } + + def __init__( + self, + id: str, + type: Optional[str] = None, + **kwargs, + ): + self.id = id + self.type = type + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class FileEntitySlackFile(JsonObject): + """Slack file reference for file entities""" + + attributes = { + "id", + "type", + } + + def __init__( + self, + id: str, + type: Optional[str] = None, + **kwargs, + ): + self.id = id + self.type = type + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityIconSlackFile(JsonObject): + """Slack file reference for entity icon""" + + attributes = { + "id", + "url", + } + + def __init__( + self, + id: Optional[str] = None, + url: Optional[str] = None, + **kwargs, + ): + self.id = id + self.url = url + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityIconField(JsonObject): + """Icon field for entity attributes""" + + attributes = { + "alt_text", + "url", + "slack_file", + } + + def __init__( + self, + alt_text: str, + url: Optional[str] = None, + slack_file: Optional[Union[Dict[str, Any], EntityIconSlackFile]] = None, + **kwargs, + ): + self.alt_text = alt_text + self.url = url + self.slack_file = slack_file + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityEditSelectConfig(JsonObject): + """Select configuration for entity edit support""" + + attributes = { + "current_value", + "current_values", + "static_options", + "fetch_options_dynamically", + "min_query_length", + } + + def __init__( + self, + current_value: Optional[str] = None, + current_values: Optional[List[str]] = None, + static_options: Optional[List[Dict[str, Any]]] = None, # Option[] + fetch_options_dynamically: Optional[bool] = None, + min_query_length: Optional[int] = None, + **kwargs, + ): + self.current_value = current_value + self.current_values = current_values + self.static_options = static_options + self.fetch_options_dynamically = fetch_options_dynamically + self.min_query_length = min_query_length + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityEditNumberConfig(JsonObject): + """Number configuration for entity edit support""" + + attributes = { + "is_decimal_allowed", + "min_value", + "max_value", + } + + def __init__( + self, + is_decimal_allowed: Optional[bool] = None, + min_value: Optional[Union[int, float]] = None, + max_value: Optional[Union[int, float]] = None, + **kwargs, + ): + self.is_decimal_allowed = is_decimal_allowed + self.min_value = min_value + self.max_value = max_value + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityEditTextConfig(JsonObject): + """Text configuration for entity edit support""" + + attributes = { + "min_length", + "max_length", + } + + def __init__( + self, + min_length: Optional[int] = None, + max_length: Optional[int] = None, + **kwargs, + ): + self.min_length = min_length + self.max_length = max_length + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityEditSupport(JsonObject): + """Edit support configuration for entity fields""" + + attributes = { + "enabled", + "placeholder", + "hint", + "optional", + "select", + "number", + "text", + } + + def __init__( + self, + enabled: bool, + placeholder: Optional[Dict[str, Any]] = None, # PlainTextElement + hint: Optional[Dict[str, Any]] = None, # PlainTextElement + optional: Optional[bool] = None, + select: Optional[Union[Dict[str, Any], EntityEditSelectConfig]] = None, + number: Optional[Union[Dict[str, Any], EntityEditNumberConfig]] = None, + text: Optional[Union[Dict[str, Any], EntityEditTextConfig]] = None, + **kwargs, + ): + self.enabled = enabled + self.placeholder = placeholder + self.hint = hint + self.optional = optional + self.select = select + self.number = number + self.text = text + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityFullSizePreviewError(JsonObject): + """Error information for full-size preview""" + + attributes = { + "code", + "message", + } + + def __init__( + self, + code: str, + message: Optional[str] = None, + **kwargs, + ): + self.code = code + self.message = message + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityFullSizePreview(JsonObject): + """Full-size preview configuration for entity""" + + attributes = { + "is_supported", + "preview_url", + "mime_type", + "error", + } + + def __init__( + self, + is_supported: bool, + preview_url: Optional[str] = None, + mime_type: Optional[str] = None, + error: Optional[Union[Dict[str, Any], EntityFullSizePreviewError]] = None, + **kwargs, + ): + self.is_supported = is_supported + self.preview_url = preview_url + self.mime_type = mime_type + self.error = error + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityUserIDField(JsonObject): + """User ID field for entity""" + + attributes = { + "user_id", + } + + def __init__( + self, + user_id: str, + **kwargs, + ): + self.user_id = user_id + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityUserField(JsonObject): + """User field for entity""" + + attributes = { + "text", + "url", + "email", + "icon", + } + + def __init__( + self, + text: str, + url: Optional[str] = None, + email: Optional[str] = None, + icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + **kwargs, + ): + self.text = text + self.url = url + self.email = email + self.icon = icon + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityRefField(JsonObject): + """Entity reference field""" + + attributes = { + "entity_url", + "external_ref", + "title", + "display_type", + "icon", + } + + def __init__( + self, + entity_url: str, + external_ref: Union[Dict[str, Any], ExternalRef], + title: str, + display_type: Optional[str] = None, + icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + **kwargs, + ): + self.entity_url = entity_url + self.external_ref = external_ref + self.title = title + self.display_type = display_type + self.icon = icon + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityTypedField(JsonObject): + """Typed field for entity with various display options""" + + attributes = { + "type", + "label", + "value", + "link", + "icon", + "long", + "format", + "image_url", + "slack_file", + "alt_text", + "edit", + "tag_color", + "user", + "entity_ref", + } + + def __init__( + self, + type: str, + label: Optional[str] = None, + value: Optional[Union[str, int]] = None, + link: Optional[str] = None, + icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + long: Optional[bool] = None, + format: Optional[str] = None, + image_url: Optional[str] = None, + slack_file: Optional[Dict[str, Any]] = None, + alt_text: Optional[str] = None, + edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None, + tag_color: Optional[str] = None, + user: Optional[Union[Dict[str, Any], EntityUserIDField, EntityUserField]] = None, + entity_ref: Optional[Union[Dict[str, Any], EntityRefField]] = None, + **kwargs, + ): + self.type = type + self.label = label + self.value = value + self.link = link + self.icon = icon + self.long = long + self.format = format + self.image_url = image_url + self.slack_file = slack_file + self.alt_text = alt_text + self.edit = edit + self.tag_color = tag_color + self.user = user + self.entity_ref = entity_ref + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityStringField(JsonObject): + """String field for entity""" + + attributes = { + "value", + "label", + "format", + "link", + "icon", + "long", + "type", + "tag_color", + "edit", + } + + def __init__( + self, + value: str, + label: Optional[str] = None, + format: Optional[str] = None, + link: Optional[str] = None, + icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + long: Optional[bool] = None, + type: Optional[str] = None, + tag_color: Optional[str] = None, + edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None, + **kwargs, + ): + self.value = value + self.label = label + self.format = format + self.link = link + self.icon = icon + self.long = long + self.type = type + self.tag_color = tag_color + self.edit = edit + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityTimestampField(JsonObject): + """Timestamp field for entity""" + + attributes = { + "value", + "label", + "type", + "edit", + } + + def __init__( + self, + value: int, + label: Optional[str] = None, + type: Optional[str] = None, + edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None, + **kwargs, + ): + self.value = value + self.label = label + self.type = type + self.edit = edit + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityImageField(JsonObject): + """Image field for entity""" + + attributes = { + "alt_text", + "label", + "image_url", + "slack_file", + "title", + "type", + } + + def __init__( + self, + alt_text: str, + label: Optional[str] = None, + image_url: Optional[str] = None, + slack_file: Optional[Dict[str, Any]] = None, + title: Optional[str] = None, + type: Optional[str] = None, + **kwargs, + ): + self.alt_text = alt_text + self.label = label + self.image_url = image_url + self.slack_file = slack_file + self.title = title + self.type = type + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityBooleanCheckboxField(JsonObject): + """Boolean checkbox properties""" + + attributes = {"type", "text", "description"} + + def __init__( + self, + type: str, + text: str, + description: Optional[str], + **kwargs, + ): + self.type = type + self.text = text + self.description = description + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityBooleanTextField(JsonObject): + """Boolean text properties""" + + attributes = {"type", "true_text", "false_text", "true_description", "false_description"} + + def __init__( + self, + type: str, + true_text: str, + false_text: str, + true_description: Optional[str], + false_description: Optional[str], + **kwargs, + ): + self.type = type + self.true_text = (true_text,) + self.false_text = (false_text,) + self.true_description = (true_description,) + self.false_description = (false_description,) + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityArrayItemField(JsonObject): + """Array item field for entity (similar to EntityTypedField but with optional type)""" + + attributes = { + "type", + "label", + "value", + "link", + "icon", + "long", + "format", + "image_url", + "slack_file", + "alt_text", + "edit", + "tag_color", + "user", + "entity_ref", + } + + def __init__( + self, + type: Optional[str] = None, + label: Optional[str] = None, + value: Optional[Union[str, int]] = None, + link: Optional[str] = None, + icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + long: Optional[bool] = None, + format: Optional[str] = None, + image_url: Optional[str] = None, + slack_file: Optional[Dict[str, Any]] = None, + alt_text: Optional[str] = None, + edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None, + tag_color: Optional[str] = None, + user: Optional[Union[Dict[str, Any], EntityUserIDField, EntityUserField]] = None, + entity_ref: Optional[Union[Dict[str, Any], EntityRefField]] = None, + **kwargs, + ): + self.type = type + self.label = label + self.value = value + self.link = link + self.icon = icon + self.long = long + self.format = format + self.image_url = image_url + self.slack_file = slack_file + self.alt_text = alt_text + self.edit = edit + self.tag_color = tag_color + self.user = user + self.entity_ref = entity_ref + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityCustomField(JsonObject): + """Custom field for entity with flexible types""" + + attributes = { + "label", + "key", + "type", + "value", + "link", + "icon", + "long", + "format", + "image_url", + "slack_file", + "alt_text", + "tag_color", + "edit", + "item_type", + "user", + "entity_ref", + "boolean", + } + + def __init__( + self, + label: str, + key: str, + type: str, + value: Optional[Union[str, int, List[Union[Dict[str, Any], EntityArrayItemField]]]] = None, + link: Optional[str] = None, + icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + long: Optional[bool] = None, + format: Optional[str] = None, + image_url: Optional[str] = None, + slack_file: Optional[Dict[str, Any]] = None, + alt_text: Optional[str] = None, + tag_color: Optional[str] = None, + edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None, + item_type: Optional[str] = None, + user: Optional[Union[Dict[str, Any], EntityUserIDField, EntityUserField]] = None, + entity_ref: Optional[Union[Dict[str, Any], EntityRefField]] = None, + boolean: Optional[Union[Dict[str, Any], EntityBooleanCheckboxField, EntityBooleanTextField]] = None, + **kwargs, + ): + self.label = label + self.key = key + self.type = type + self.value = value + self.link = link + self.icon = icon + self.long = long + self.format = format + self.image_url = image_url + self.slack_file = slack_file + self.alt_text = alt_text + self.tag_color = tag_color + self.edit = edit + self.item_type = item_type + self.user = user + self.entity_ref = entity_ref + self.boolean = boolean + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + @EnumValidator("type", CustomFieldType) + def type_valid(self): + return self.type is None or self.type in CustomFieldType + + +class FileEntityFields(JsonObject): + """Fields specific to file entities""" + + attributes = { + "preview", + "created_by", + "date_created", + "date_updated", + "last_modified_by", + "file_size", + "mime_type", + "full_size_preview", + } + + def __init__( + self, + preview: Optional[Union[Dict[str, Any], EntityImageField]] = None, + created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + last_modified_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + file_size: Optional[Union[Dict[str, Any], EntityStringField]] = None, + mime_type: Optional[Union[Dict[str, Any], EntityStringField]] = None, + full_size_preview: Optional[Union[Dict[str, Any], EntityFullSizePreview]] = None, + **kwargs, + ): + self.preview = preview + self.created_by = created_by + self.date_created = date_created + self.date_updated = date_updated + self.last_modified_by = last_modified_by + self.file_size = file_size + self.mime_type = mime_type + self.full_size_preview = full_size_preview + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class TaskEntityFields(JsonObject): + """Fields specific to task entities""" + + attributes = { + "description", + "created_by", + "date_created", + "date_updated", + "assignee", + "status", + "due_date", + "priority", + } + + def __init__( + self, + description: Optional[Union[Dict[str, Any], EntityStringField]] = None, + created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + assignee: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + status: Optional[Union[Dict[str, Any], EntityStringField]] = None, + due_date: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + priority: Optional[Union[Dict[str, Any], EntityStringField]] = None, + **kwargs, + ): + self.description = description + self.created_by = created_by + self.date_created = date_created + self.date_updated = date_updated + self.assignee = assignee + self.status = status + self.due_date = due_date + self.priority = priority + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class IncidentEntityFields(JsonObject): + """Fields specific to incident entities""" + + attributes = { + "status", + "priority", + "urgency", + "created_by", + "assigned_to", + "date_created", + "date_updated", + "description", + "service", + } + + def __init__( + self, + status: Optional[Union[Dict[str, Any], EntityStringField]] = None, + priority: Optional[Union[Dict[str, Any], EntityStringField]] = None, + urgency: Optional[Union[Dict[str, Any], EntityStringField]] = None, + created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + assigned_to: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + description: Optional[Union[Dict[str, Any], EntityStringField]] = None, + service: Optional[Union[Dict[str, Any], EntityStringField]] = None, + **kwargs, + ): + self.status = status + self.priority = priority + self.urgency = urgency + self.created_by = created_by + self.assigned_to = assigned_to + self.date_created = date_created + self.date_updated = date_updated + self.description = description + self.service = service + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class ContentItemEntityFields(JsonObject): + """Fields specific to content item entities""" + + attributes = { + "preview", + "description", + "created_by", + "date_created", + "date_updated", + "last_modified_by", + } + + def __init__( + self, + preview: Optional[Union[Dict[str, Any], EntityImageField]] = None, + description: Optional[Union[Dict[str, Any], EntityStringField]] = None, + created_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + date_created: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + date_updated: Optional[Union[Dict[str, Any], EntityTimestampField]] = None, + last_modified_by: Optional[Union[Dict[str, Any], EntityTypedField]] = None, + **kwargs, + ): + self.preview = preview + self.description = description + self.created_by = created_by + self.date_created = date_created + self.date_updated = date_updated + self.last_modified_by = last_modified_by + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityActionProcessingState(JsonObject): + """Processing state configuration for entity action button""" + + attributes = { + "enabled", + "interstitial_text", + } + + def __init__( + self, + enabled: bool, + interstitial_text: Optional[str] = None, + **kwargs, + ): + self.enabled = enabled + self.interstitial_text = interstitial_text + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityActionButton(JsonObject): + """Action button for entity""" + + attributes = { + "text", + "action_id", + "value", + "style", + "url", + "accessibility_label", + "processing_state", + } + + def __init__( + self, + text: str, + action_id: str, + value: Optional[str] = None, + style: Optional[str] = None, + url: Optional[str] = None, + accessibility_label: Optional[str] = None, + processing_state: Optional[Union[Dict[str, Any], EntityActionProcessingState]] = None, + **kwargs, + ): + self.text = text + self.action_id = action_id + self.value = value + self.style = style + self.url = url + self.accessibility_label = accessibility_label + self.processing_state = processing_state + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityTitle(JsonObject): + """Title for entity attributes""" + + attributes = { + "text", + "edit", + } + + def __init__( + self, + text: str, + edit: Optional[Union[Dict[str, Any], EntityEditSupport]] = None, + **kwargs, + ): + self.text = text + self.edit = edit + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityAttributes(JsonObject): + """Attributes for an entity""" + + attributes = { + "title", + "display_type", + "display_id", + "product_icon", + "product_name", + "locale", + "full_size_preview", + "metadata_last_modified", + } + + def __init__( + self, + title: Union[Dict[str, Any], EntityTitle], + display_type: Optional[str] = None, + display_id: Optional[str] = None, + product_icon: Optional[Union[Dict[str, Any], EntityIconField]] = None, + product_name: Optional[str] = None, + locale: Optional[str] = None, + full_size_preview: Optional[Union[Dict[str, Any], EntityFullSizePreview]] = None, + metadata_last_modified: Optional[int] = None, + **kwargs, + ): + self.title = title + self.display_type = display_type + self.display_id = display_id + self.product_icon = product_icon + self.product_name = product_name + self.locale = locale + self.full_size_preview = full_size_preview + self.metadata_last_modified = metadata_last_modified + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityActions(JsonObject): + """Actions configuration for entity""" + + attributes = { + "primary_actions", + "overflow_actions", + } + + def __init__( + self, + primary_actions: Optional[List[Union[Dict[str, Any], EntityActionButton]]] = None, + overflow_actions: Optional[List[Union[Dict[str, Any], EntityActionButton]]] = None, + **kwargs, + ): + self.primary_actions = primary_actions + self.overflow_actions = overflow_actions + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityPayload(JsonObject): + """Payload schema for an entity""" + + attributes = { + "attributes", + "fields", + "custom_fields", + "slack_file", + "display_order", + "actions", + } + + def __init__( + self, + attributes: Union[Dict[str, Any], EntityAttributes], + fields: Optional[ + Union[Dict[str, Any], ContentItemEntityFields, FileEntityFields, IncidentEntityFields, TaskEntityFields] + ] = None, + custom_fields: Optional[List[Union[Dict[str, Any], EntityCustomField]]] = None, + slack_file: Optional[Union[Dict[str, Any], FileEntitySlackFile]] = None, + display_order: Optional[List[str]] = None, + actions: Optional[Union[Dict[str, Any], EntityActions]] = None, + **kwargs, + ): + # Store entity attributes data with a different internal name to avoid + # shadowing the class-level 'attributes' set used for JSON serialization + self._entity_attributes = attributes + self.fields = fields + self.custom_fields = custom_fields + self.slack_file = slack_file + self.display_order = display_order + self.actions = actions + self.additional_attributes = kwargs + + @property + def entity_attributes(self) -> Union[Dict[str, Any], EntityAttributes]: + """Get the entity attributes data. + + Note: Use this property to access the attributes data. The class-level + 'attributes' is reserved for the JSON serialization schema. + """ + return self._entity_attributes + + @entity_attributes.setter + def entity_attributes(self, value: Union[Dict[str, Any], EntityAttributes]): + """Set the entity attributes data.""" + self._entity_attributes = value + + def get_object_attribute(self, key: str): + if key == "attributes": + return self._entity_attributes + else: + return getattr(self, key, None) + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + +class EntityMetadata(JsonObject): + """Work object entity metadata + + https://docs.slack.dev/messaging/work-objects/ + """ + + attributes = { + "entity_type", + "entity_payload", + "external_ref", + "url", + "app_unfurl_url", + } + + def __init__( + self, + entity_type: str, + entity_payload: Union[Dict[str, Any], EntityPayload], + external_ref: Union[Dict[str, Any], ExternalRef], + url: str, + app_unfurl_url: Optional[str] = None, + **kwargs, + ): + self.entity_type = entity_type + self.entity_payload = entity_payload + self.external_ref = external_ref + self.url = url + self.app_unfurl_url = app_unfurl_url + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() + + @EnumValidator("entity_type", EntityType) + def entity_type_valid(self): + return self.entity_type is None or self.entity_type in EntityType + + +class EventAndEntityMetadata(JsonObject): + """Message metadata with entities + + https://docs.slack.dev/messaging/message-metadata/ + https://docs.slack.dev/messaging/work-objects/ + """ + + attributes = {"event_type", "event_payload", "entities"} + + def __init__( + self, + event_type: Optional[str] = None, + event_payload: Optional[Dict[str, Any]] = None, + entities: Optional[List[Union[Dict[str, Any], EntityMetadata]]] = None, + **kwargs, + ): + self.event_type = event_type + self.event_payload = event_payload + self.entities = entities + self.additional_attributes = kwargs + + def __str__(self): + return str(self.get_non_null_attributes()) + + def __repr__(self): + return self.__str__() diff --git a/slack_sdk/oauth/__init__.py b/slack_sdk/oauth/__init__.py index 286b87aa1..a27b606b0 100644 --- a/slack_sdk/oauth/__init__.py +++ b/slack_sdk/oauth/__init__.py @@ -2,6 +2,7 @@ https://docs.slack.dev/tools/python-slack-sdk/oauth """ + from .authorize_url_generator import AuthorizeUrlGenerator from .authorize_url_generator import OpenIDConnectAuthorizeUrlGenerator from .installation_store import InstallationStore diff --git a/slack_sdk/oauth/installation_store/installation_store.py b/slack_sdk/oauth/installation_store/installation_store.py index f01503408..8143d2fb7 100644 --- a/slack_sdk/oauth/installation_store/installation_store.py +++ b/slack_sdk/oauth/installation_store/installation_store.py @@ -2,6 +2,7 @@ Refer to https://docs.slack.dev/tools/python-slack-sdk/oauth for details. """ + from logging import Logger from typing import Optional diff --git a/slack_sdk/oauth/state_store/__init__.py b/slack_sdk/oauth/state_store/__init__.py index 18eddaff6..15491fd1d 100644 --- a/slack_sdk/oauth/state_store/__init__.py +++ b/slack_sdk/oauth/state_store/__init__.py @@ -2,6 +2,7 @@ Refer to https://docs.slack.dev/tools/python-slack-sdk/oauth for details. """ + # from .amazon_s3_state_store import AmazonS3OAuthStateStore from .file import FileOAuthStateStore from .state_store import OAuthStateStore diff --git a/slack_sdk/proxy_env_variable_loader.py b/slack_sdk/proxy_env_variable_loader.py index 848436905..7df080b9b 100644 --- a/slack_sdk/proxy_env_variable_loader.py +++ b/slack_sdk/proxy_env_variable_loader.py @@ -1,4 +1,5 @@ """Internal module for loading proxy-related env variables""" + import logging import os from typing import Optional diff --git a/slack_sdk/rtm_v2/__init__.py b/slack_sdk/rtm_v2/__init__.py index 21f96e347..be059303d 100644 --- a/slack_sdk/rtm_v2/__init__.py +++ b/slack_sdk/rtm_v2/__init__.py @@ -1,4 +1,5 @@ """A Python module for interacting with Slack's RTM API.""" + import inspect import json import logging diff --git a/slack_sdk/scim/__init__.py b/slack_sdk/scim/__init__.py index 901782a1c..25ad76109 100644 --- a/slack_sdk/scim/__init__.py +++ b/slack_sdk/scim/__init__.py @@ -4,6 +4,7 @@ Refer to https://docs.slack.dev/tools/python-slack-sdk/scim for details. """ + from .v1.client import SCIMClient from .v1.response import SCIMResponse from .v1.response import SearchUsersResponse, ReadUserResponse diff --git a/slack_sdk/scim/v1/async_client.py b/slack_sdk/scim/v1/async_client.py index 87f836a74..ad92ac49f 100644 --- a/slack_sdk/scim/v1/async_client.py +++ b/slack_sdk/scim/v1/async_client.py @@ -149,9 +149,9 @@ async def patch_user(self, id: str, partial_user: Union[Dict[str, Any], User]) - await self.api_call( http_verb="PATCH", path=f"Users/{quote(id)}", - body_params=partial_user.to_dict() - if isinstance(partial_user, User) - else _to_dict_without_not_given(partial_user), + body_params=( + partial_user.to_dict() if isinstance(partial_user, User) else _to_dict_without_not_given(partial_user) + ), ) ) @@ -214,9 +214,11 @@ async def patch_group(self, id: str, partial_group: Union[Dict[str, Any], Group] await self.api_call( http_verb="PATCH", path=f"Groups/{quote(id)}", - body_params=partial_group.to_dict() - if isinstance(partial_group, Group) - else _to_dict_without_not_given(partial_group), + body_params=( + partial_group.to_dict() + if isinstance(partial_group, Group) + else _to_dict_without_not_given(partial_group) + ), ) ) diff --git a/slack_sdk/socket_mode/__init__.py b/slack_sdk/socket_mode/__init__.py index 6cdee82cb..b8e1883c1 100644 --- a/slack_sdk/socket_mode/__init__.py +++ b/slack_sdk/socket_mode/__init__.py @@ -4,6 +4,7 @@ https://docs.slack.dev/apis/events-api/using-socket-mode/ """ + from .builtin import SocketModeClient __all__ = [ diff --git a/slack_sdk/socket_mode/websocket_client/__init__.py b/slack_sdk/socket_mode/websocket_client/__init__.py index e3e050196..ae7df4420 100644 --- a/slack_sdk/socket_mode/websocket_client/__init__.py +++ b/slack_sdk/socket_mode/websocket_client/__init__.py @@ -11,7 +11,7 @@ from logging import Logger from queue import Queue from threading import Lock -from typing import Union, Optional, List, Callable, Tuple +from typing import Callable, List, Optional, Tuple, Union import websocket from websocket import WebSocketApp, WebSocketException @@ -180,10 +180,10 @@ def on_close( self.current_session = websocket.WebSocketApp( self.wss_uri, - on_open=on_open, # type: ignore[arg-type] - on_message=on_message, # type: ignore[arg-type] - on_error=on_error, # type: ignore[arg-type] - on_close=on_close, # type: ignore[arg-type] + on_open=on_open, + on_message=on_message, + on_error=on_error, + on_close=on_close, ) self.auto_reconnect_enabled = self.default_auto_reconnect_enabled diff --git a/slack_sdk/version.py b/slack_sdk/version.py index a23f01f83..fb572e0ba 100644 --- a/slack_sdk/version.py +++ b/slack_sdk/version.py @@ -1,3 +1,3 @@ """Check the latest version at https://pypi.org/project/slack-sdk/""" -__version__ = "3.37.0" +__version__ = "3.39.0" diff --git a/slack_sdk/web/__init__.py b/slack_sdk/web/__init__.py index a3d5ef286..41f3b5a77 100644 --- a/slack_sdk/web/__init__.py +++ b/slack_sdk/web/__init__.py @@ -1,5 +1,6 @@ """The Slack Web API allows you to build applications that interact with Slack in more complex ways than the integrations we provide out of the box.""" + from .client import WebClient from .slack_response import SlackResponse diff --git a/slack_sdk/web/async_client.py b/slack_sdk/web/async_client.py index 7b82a0923..ca163da98 100644 --- a/slack_sdk/web/async_client.py +++ b/slack_sdk/web/async_client.py @@ -21,8 +21,8 @@ from slack_sdk.web.async_chat_stream import AsyncChatStream from ..models.attachments import Attachment -from ..models.blocks import Block -from ..models.metadata import Metadata +from ..models.blocks import Block, RichTextBlock +from ..models.metadata import Metadata, EntityMetadata, EventAndEntityMetadata from .async_base_client import AsyncBaseClient, AsyncSlackResponse from .internal_utils import ( _parse_web_class_objects, @@ -2769,7 +2769,7 @@ async def chat_postMessage( link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> AsyncSlackResponse: @@ -2998,6 +2998,7 @@ async def chat_unfurl( source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -3014,6 +3015,7 @@ async def chat_unfurl( "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3645,6 +3647,30 @@ async def emoji_list( kwargs.update({"include_categories": include_categories}) return await self.api_call("emoji.list", http_verb="GET", params=kwargs) + async def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return await self.api_call("entity.presentDetails", json=kwargs) + async def files_comments_delete( self, *, @@ -4899,6 +4925,249 @@ async def search_messages( ) return await self.api_call("search.messages", http_verb="GET", params=kwargs) + async def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.access.delete", json=kwargs) + + async def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.access.set", json=kwargs) + + async def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.create", json=kwargs) + + async def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> AsyncSlackResponse: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.download.get", json=kwargs) + + async def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.download.start", json=kwargs) + + async def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.create", json=kwargs) + + async def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> AsyncSlackResponse: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.delete", json=kwargs) + + async def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> AsyncSlackResponse: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + async def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.info", json=kwargs) + + async def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.list", json=kwargs) + + async def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> AsyncSlackResponse: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.items.update", json=kwargs) + + async def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> AsyncSlackResponse: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return await self.api_call("slackLists.update", json=kwargs) + async def stars_add( self, *, diff --git a/slack_sdk/web/client.py b/slack_sdk/web/client.py index 8410ffee2..dfa771832 100644 --- a/slack_sdk/web/client.py +++ b/slack_sdk/web/client.py @@ -11,8 +11,8 @@ from slack_sdk.web.chat_stream import ChatStream from ..models.attachments import Attachment -from ..models.blocks import Block -from ..models.metadata import Metadata +from ..models.blocks import Block, RichTextBlock +from ..models.metadata import Metadata, EntityMetadata, EventAndEntityMetadata from .base_client import BaseClient, SlackResponse from .internal_utils import ( _parse_web_class_objects, @@ -2759,7 +2759,7 @@ def chat_postMessage( link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> SlackResponse: @@ -2988,6 +2988,7 @@ def chat_unfurl( source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -3004,6 +3005,7 @@ def chat_unfurl( "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3635,6 +3637,30 @@ def emoji_list( kwargs.update({"include_categories": include_categories}) return self.api_call("emoji.list", http_verb="GET", params=kwargs) + def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> SlackResponse: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return self.api_call("entity.presentDetails", json=kwargs) + def files_comments_delete( self, *, @@ -4889,6 +4915,249 @@ def search_messages( ) return self.api_call("search.messages", http_verb="GET", params=kwargs) + def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.delete", json=kwargs) + + def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> SlackResponse: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.set", json=kwargs) + + def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.create", json=kwargs) + + def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> SlackResponse: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.get", json=kwargs) + + def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.start", json=kwargs) + + def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> SlackResponse: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.create", json=kwargs) + + def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> SlackResponse: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.delete", json=kwargs) + + def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> SlackResponse: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.info", json=kwargs) + + def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.list", json=kwargs) + + def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> SlackResponse: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.update", json=kwargs) + + def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> SlackResponse: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.update", json=kwargs) + def stars_add( self, *, diff --git a/slack_sdk/web/internal_utils.py b/slack_sdk/web/internal_utils.py index 3b5e01c62..87139559c 100644 --- a/slack_sdk/web/internal_utils.py +++ b/slack_sdk/web/internal_utils.py @@ -17,7 +17,7 @@ from slack_sdk.errors import SlackRequestError from slack_sdk.models.attachments import Attachment from slack_sdk.models.blocks import Block -from slack_sdk.models.metadata import Metadata +from slack_sdk.models.metadata import Metadata, EventAndEntityMetadata, EntityMetadata def convert_bool_to_0_or_1(params: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]: @@ -187,13 +187,17 @@ def _build_req_args( def _parse_web_class_objects(kwargs) -> None: - def to_dict(obj: Union[Dict, Block, Attachment, Metadata]): + def to_dict(obj: Union[Dict, Block, Attachment, Metadata, EventAndEntityMetadata, EntityMetadata]): if isinstance(obj, Block): return obj.to_dict() if isinstance(obj, Attachment): return obj.to_dict() if isinstance(obj, Metadata): return obj.to_dict() + if isinstance(obj, EventAndEntityMetadata): + return obj.to_dict() + if isinstance(obj, EntityMetadata): + return obj.to_dict() return obj for blocks_name in ["blocks", "user_auth_blocks"]: @@ -208,7 +212,11 @@ def to_dict(obj: Union[Dict, Block, Attachment, Metadata]): kwargs.update({"attachments": dict_attachments}) metadata = kwargs.get("metadata", None) - if metadata is not None and isinstance(metadata, Metadata): + if metadata is not None and ( + isinstance(metadata, Metadata) + or isinstance(metadata, EntityMetadata) + or isinstance(metadata, EventAndEntityMetadata) + ): kwargs.update({"metadata": to_dict(metadata)}) @@ -345,11 +353,11 @@ def _to_v2_file_upload_item(upload_file: Dict[str, Any]) -> Dict[str, Optional[A if filename is None: # use the local filename if filename is missing if isinstance(file, (str, os.PathLike)): - filename = os.fspath(file).split(os.path.sep)[-1] + filename = os.path.basename(os.fspath(file)) else: filename = "Uploaded file" - title = upload_file.get("title", "Uploaded file") + title = upload_file.get("title") if data is None: raise SlackRequestError(f"File content not found for filename: {filename}, title: {title}") diff --git a/slack_sdk/web/legacy_client.py b/slack_sdk/web/legacy_client.py index 88c0fcf1a..df2bcc370 100644 --- a/slack_sdk/web/legacy_client.py +++ b/slack_sdk/web/legacy_client.py @@ -22,8 +22,8 @@ from slack_sdk.models.views import View from ..models.attachments import Attachment -from ..models.blocks import Block -from ..models.metadata import Metadata +from ..models.blocks import Block, RichTextBlock +from ..models.metadata import Metadata, EntityMetadata, EventAndEntityMetadata from .legacy_base_client import LegacyBaseClient, SlackResponse from .internal_utils import ( _parse_web_class_objects, @@ -2770,7 +2770,7 @@ def chat_postMessage( link_names: Optional[bool] = None, username: Optional[str] = None, parse: Optional[str] = None, # none, full - metadata: Optional[Union[Dict, Metadata]] = None, + metadata: Optional[Union[Dict, Metadata, EventAndEntityMetadata]] = None, markdown_text: Optional[str] = None, **kwargs, ) -> Union[Future, SlackResponse]: @@ -2936,6 +2936,7 @@ def chat_unfurl( source: Optional[str] = None, unfurl_id: Optional[str] = None, unfurls: Optional[Dict[str, Dict]] = None, # or user_auth_* + metadata: Optional[Union[Dict, EventAndEntityMetadata]] = None, user_auth_blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None, user_auth_message: Optional[str] = None, user_auth_required: Optional[bool] = None, @@ -2952,6 +2953,7 @@ def chat_unfurl( "source": source, "unfurl_id": unfurl_id, "unfurls": unfurls, + "metadata": metadata, "user_auth_blocks": user_auth_blocks, "user_auth_message": user_auth_message, "user_auth_required": user_auth_required, @@ -3583,6 +3585,30 @@ def emoji_list( kwargs.update({"include_categories": include_categories}) return self.api_call("emoji.list", http_verb="GET", params=kwargs) + def entity_presentDetails( + self, + trigger_id: str, + metadata: Optional[Union[Dict, EntityMetadata]] = None, + user_auth_required: Optional[bool] = None, + user_auth_url: Optional[str] = None, + error: Optional[Dict[str, Any]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Provides entity details for the flexpane. + https://docs.slack.dev/reference/methods/entity.presentDetails/ + """ + kwargs.update({"trigger_id": trigger_id}) + if metadata is not None: + kwargs.update({"metadata": metadata}) + if user_auth_required is not None: + kwargs.update({"user_auth_required": user_auth_required}) + if user_auth_url is not None: + kwargs.update({"user_auth_url": user_auth_url}) + if error is not None: + kwargs.update({"error": error}) + _parse_web_class_objects(kwargs) + return self.api_call("entity.presentDetails", json=kwargs) + def files_comments_delete( self, *, @@ -4837,6 +4863,249 @@ def search_messages( ) return self.api_call("search.messages", http_verb="GET", params=kwargs) + def slackLists_access_delete( + self, + *, + list_id: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Revoke access to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.delete + """ + kwargs.update({"list_id": list_id, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.delete", json=kwargs) + + def slackLists_access_set( + self, + *, + list_id: str, + access_level: str, + channel_ids: Optional[List[str]] = None, + user_ids: Optional[List[str]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Set the access level to a List for specified entities. + https://docs.slack.dev/reference/methods/slackLists.access.set + """ + kwargs.update({"list_id": list_id, "access_level": access_level, "channel_ids": channel_ids, "user_ids": user_ids}) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.access.set", json=kwargs) + + def slackLists_create( + self, + *, + name: str, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + schema: Optional[List[Dict[str, Any]]] = None, + copy_from_list_id: Optional[str] = None, + include_copied_list_records: Optional[bool] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Creates a List. + https://docs.slack.dev/reference/methods/slackLists.create + """ + kwargs.update( + { + "name": name, + "description_blocks": description_blocks, + "schema": schema, + "copy_from_list_id": copy_from_list_id, + "include_copied_list_records": include_copied_list_records, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.create", json=kwargs) + + def slackLists_download_get( + self, + *, + list_id: str, + job_id: str, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Retrieve List download URL from an export job to download List contents. + https://docs.slack.dev/reference/methods/slackLists.download.get + """ + kwargs.update( + { + "list_id": list_id, + "job_id": job_id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.get", json=kwargs) + + def slackLists_download_start( + self, + *, + list_id: str, + include_archived: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Initiate a job to export List contents. + https://docs.slack.dev/reference/methods/slackLists.download.start + """ + kwargs.update( + { + "list_id": list_id, + "include_archived": include_archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.download.start", json=kwargs) + + def slackLists_items_create( + self, + *, + list_id: str, + duplicated_item_id: Optional[str] = None, + parent_item_id: Optional[str] = None, + initial_fields: Optional[List[Dict[str, Any]]] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Add a new item to an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.create + """ + kwargs.update( + { + "list_id": list_id, + "duplicated_item_id": duplicated_item_id, + "parent_item_id": parent_item_id, + "initial_fields": initial_fields, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.create", json=kwargs) + + def slackLists_items_delete( + self, + *, + list_id: str, + id: str, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Deletes an item from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.delete + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.delete", json=kwargs) + + def slackLists_items_deleteMultiple( + self, + *, + list_id: str, + ids: List[str], + **kwargs, + ) -> Union[Future, SlackResponse]: + """Deletes multiple items from an existing List. + https://docs.slack.dev/reference/methods/slackLists.items.deleteMultiple + """ + kwargs.update( + { + "list_id": list_id, + "ids": ids, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.deleteMultiple", json=kwargs) + + def slackLists_items_info( + self, + *, + list_id: str, + id: str, + include_is_subscribed: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Get a row from a List. + https://docs.slack.dev/reference/methods/slackLists.items.info + """ + kwargs.update( + { + "list_id": list_id, + "id": id, + "include_is_subscribed": include_is_subscribed, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.info", json=kwargs) + + def slackLists_items_list( + self, + *, + list_id: str, + limit: Optional[int] = None, + cursor: Optional[str] = None, + archived: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Get records from a List. + https://docs.slack.dev/reference/methods/slackLists.items.list + """ + kwargs.update( + { + "list_id": list_id, + "limit": limit, + "cursor": cursor, + "archived": archived, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.list", json=kwargs) + + def slackLists_items_update( + self, + *, + list_id: str, + cells: List[Dict[str, Any]], + **kwargs, + ) -> Union[Future, SlackResponse]: + """Updates cells in a List. + https://docs.slack.dev/reference/methods/slackLists.items.update + """ + kwargs.update( + { + "list_id": list_id, + "cells": cells, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.items.update", json=kwargs) + + def slackLists_update( + self, + *, + id: str, + name: Optional[str] = None, + description_blocks: Optional[Union[str, Sequence[Union[Dict, RichTextBlock]]]] = None, + todo_mode: Optional[bool] = None, + **kwargs, + ) -> Union[Future, SlackResponse]: + """Update a List. + https://docs.slack.dev/reference/methods/slackLists.update + """ + kwargs.update( + { + "id": id, + "name": name, + "description_blocks": description_blocks, + "todo_mode": todo_mode, + } + ) + kwargs = _remove_none_values(kwargs) + return self.api_call("slackLists.update", json=kwargs) + def stars_add( self, *, diff --git a/slack_sdk/webhook/__init__.py b/slack_sdk/webhook/__init__.py index ea52f6bf1..09e2292ab 100644 --- a/slack_sdk/webhook/__init__.py +++ b/slack_sdk/webhook/__init__.py @@ -1,6 +1,7 @@ """You can use slack_sdk.webhook.WebhookClient for Incoming Webhooks and message responses using response_url in payloads. """ + # from .async_client import AsyncWebhookClient from .client import WebhookClient from .webhook_response import WebhookResponse diff --git a/tests/slack_sdk/models/test_blocks.py b/tests/slack_sdk/models/test_blocks.py index adacf1427..6f3b9f141 100644 --- a/tests/slack_sdk/models/test_blocks.py +++ b/tests/slack_sdk/models/test_blocks.py @@ -21,6 +21,7 @@ Option, OverflowMenuElement, PlainTextObject, + RawTextObject, RichTextBlock, RichTextElementParts, RichTextListElement, @@ -29,6 +30,7 @@ RichTextSectionElement, SectionBlock, StaticSelectElement, + TableBlock, VideoBlock, ) from slack_sdk.models.blocks.basic_components import FeedbackButtonObject, SlackFile @@ -1037,6 +1039,8 @@ def test_complex(self): {"type": "text", "text": "block", "style": {"code": True}}, {"type": "text", "text": " "}, {"type": "text", "text": "test", "style": {"italic": True}}, + {"type": "text", "text": " "}, + {"type": "text", "text": "links", "style": {"underline": True}}, {"type": "link", "url": "https://slack.com", "text": "Slack website!"}, ], }, @@ -1138,6 +1142,8 @@ def test_complex(self): _.Text(text="block", style=_.TextStyle(code=True)), _.Text(text=" "), _.Text(text="test", style=_.TextStyle(italic=True)), + _.Text(text=" "), + _.Text(text="links", style=_.TextStyle(underline=True)), _.Link(text="Slack website!", url="https://slack.com"), ] ), @@ -1263,3 +1269,203 @@ def test_parsing_empty_block_elements(self): self.assertIsNotNone(block_dict["elements"][1].get("elements")) self.assertIsNotNone(block_dict["elements"][2].get("elements")) self.assertIsNotNone(block_dict["elements"][3].get("elements")) + + +# ---------------------------------------------- +# RawTextObject +# ---------------------------------------------- + + +class RawTextObjectTests(unittest.TestCase): + def test_basic_creation(self): + """Test basic RawTextObject creation""" + obj = RawTextObject(text="Hello") + expected = {"type": "raw_text", "text": "Hello"} + self.assertDictEqual(expected, obj.to_dict()) + + def test_from_str(self): + """Test RawTextObject.from_str() helper""" + obj = RawTextObject.from_str("Test text") + expected = {"type": "raw_text", "text": "Test text"} + self.assertDictEqual(expected, obj.to_dict()) + + def test_direct_from_string(self): + """Test RawTextObject.direct_from_string() helper""" + result = RawTextObject.direct_from_string("Direct text") + expected = {"type": "raw_text", "text": "Direct text"} + self.assertDictEqual(expected, result) + + def test_text_length_validation_min(self): + """Test that empty text fails validation""" + with self.assertRaises(SlackObjectFormationError): + RawTextObject(text="").to_dict() + + def test_text_length_validation_at_min(self): + """Test that text with 1 character passes validation""" + obj = RawTextObject(text="a") + obj.to_dict() # Should not raise + + def test_attributes(self): + """Test that RawTextObject only has text and type attributes""" + obj = RawTextObject(text="Test") + self.assertEqual(obj.attributes, {"text", "type"}) + # Should not have emoji attribute like PlainTextObject + self.assertNotIn("emoji", obj.to_dict()) + + +# ---------------------------------------------- +# Table +# ---------------------------------------------- + + +class TableBlockTests(unittest.TestCase): + def test_document(self): + """Test basic table block from Slack documentation example""" + input = { + "type": "table", + "column_settings": [{"is_wrapped": True}, {"align": "right"}], + "rows": [ + [{"type": "raw_text", "text": "Header A"}, {"type": "raw_text", "text": "Header B"}], + [{"type": "raw_text", "text": "Data 1A"}, {"type": "raw_text", "text": "Data 1B"}], + [{"type": "raw_text", "text": "Data 2A"}, {"type": "raw_text", "text": "Data 2B"}], + ], + } + self.assertDictEqual(input, TableBlock(**input).to_dict()) + self.assertDictEqual(input, Block.parse(input).to_dict()) + + def test_with_rich_text(self): + """Test table block with rich_text cells""" + input = { + "type": "table", + "column_settings": [{"is_wrapped": True}, {"align": "right"}], + "rows": [ + [{"type": "raw_text", "text": "Header A"}, {"type": "raw_text", "text": "Header B"}], + [ + {"type": "raw_text", "text": "Data 1A"}, + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [{"text": "Data 1B", "type": "link", "url": "https://slack.com"}], + } + ], + }, + ], + ], + } + self.assertDictEqual(input, TableBlock(**input).to_dict()) + self.assertDictEqual(input, Block.parse(input).to_dict()) + + def test_minimal_table(self): + """Test table with only required fields""" + input = { + "type": "table", + "rows": [[{"type": "raw_text", "text": "Cell"}]], + } + self.assertDictEqual(input, TableBlock(**input).to_dict()) + + def test_with_block_id(self): + """Test table block with block_id""" + input = { + "type": "table", + "block_id": "table-123", + "rows": [ + [{"type": "raw_text", "text": "A"}, {"type": "raw_text", "text": "B"}], + [{"type": "raw_text", "text": "1"}, {"type": "raw_text", "text": "2"}], + ], + } + self.assertDictEqual(input, TableBlock(**input).to_dict()) + + def test_column_settings_variations(self): + """Test various column_settings configurations""" + # Left align + input1 = { + "type": "table", + "column_settings": [{"align": "left"}], + "rows": [[{"type": "raw_text", "text": "Left"}]], + } + self.assertDictEqual(input1, TableBlock(**input1).to_dict()) + + # Center align + input2 = { + "type": "table", + "column_settings": [{"align": "center"}], + "rows": [[{"type": "raw_text", "text": "Center"}]], + } + self.assertDictEqual(input2, TableBlock(**input2).to_dict()) + + # With wrapping + input3 = { + "type": "table", + "column_settings": [{"is_wrapped": False}], + "rows": [[{"type": "raw_text", "text": "No wrap"}]], + } + self.assertDictEqual(input3, TableBlock(**input3).to_dict()) + + # Combined settings + input4 = { + "type": "table", + "column_settings": [{"align": "center", "is_wrapped": True}], + "rows": [[{"type": "raw_text", "text": "Both"}]], + } + self.assertDictEqual(input4, TableBlock(**input4).to_dict()) + + def test_column_settings_with_none(self): + """Test column_settings with None to skip columns""" + input = { + "type": "table", + "column_settings": [{"align": "left"}, None, {"align": "right"}], + "rows": [ + [ + {"type": "raw_text", "text": "Left"}, + {"type": "raw_text", "text": "Default"}, + {"type": "raw_text", "text": "Right"}, + ] + ], + } + self.assertDictEqual(input, TableBlock(**input).to_dict()) + + def test_rows_validation(self): + """Test that rows validation works correctly""" + # Empty rows should fail validation + with self.assertRaises(SlackObjectFormationError): + TableBlock(rows=[]).to_dict() + + def test_multi_row_table(self): + """Test table with multiple rows""" + input = { + "type": "table", + "rows": [ + [{"type": "raw_text", "text": "Name"}, {"type": "raw_text", "text": "Age"}], + [{"type": "raw_text", "text": "Alice"}, {"type": "raw_text", "text": "30"}], + [{"type": "raw_text", "text": "Bob"}, {"type": "raw_text", "text": "25"}], + [{"type": "raw_text", "text": "Charlie"}, {"type": "raw_text", "text": "35"}], + ], + } + block = TableBlock(**input) + self.assertEqual(len(block.rows), 4) + self.assertDictEqual(input, block.to_dict()) + + def test_with_raw_text_object_helper(self): + """Test table using RawTextObject helper class""" + # Create table using RawTextObject helper + block = TableBlock( + rows=[ + [RawTextObject(text="Product").to_dict(), RawTextObject(text="Price").to_dict()], + [RawTextObject(text="Widget").to_dict(), RawTextObject(text="$10").to_dict()], + [RawTextObject(text="Gadget").to_dict(), RawTextObject(text="$20").to_dict()], + ], + column_settings=[{"is_wrapped": True}, {"align": "right"}], + ) + + expected = { + "type": "table", + "column_settings": [{"is_wrapped": True}, {"align": "right"}], + "rows": [ + [{"type": "raw_text", "text": "Product"}, {"type": "raw_text", "text": "Price"}], + [{"type": "raw_text", "text": "Widget"}, {"type": "raw_text", "text": "$10"}], + [{"type": "raw_text", "text": "Gadget"}, {"type": "raw_text", "text": "$20"}], + ], + } + self.assertDictEqual(expected, block.to_dict()) diff --git a/tests/slack_sdk/models/test_metadata.py b/tests/slack_sdk/models/test_metadata.py new file mode 100644 index 000000000..14635c661 --- /dev/null +++ b/tests/slack_sdk/models/test_metadata.py @@ -0,0 +1,307 @@ +import unittest + +from slack_sdk.models.metadata import ( + EventAndEntityMetadata, + EntityMetadata, + ExternalRef, + FileEntitySlackFile, + EntityIconField, + EntityEditTextConfig, + EntityEditSupport, + EntityFullSizePreviewError, + EntityFullSizePreview, + EntityUserIDField, + EntityUserField, + EntityTypedField, + EntityStringField, + EntityTimestampField, + EntityImageField, + EntityCustomField, + FileEntityFields, + TaskEntityFields, + EntityActionButton, + EntityTitle, + EntityAttributes, + EntityActions, + EntityPayload, +) + + +class EntityMetadataTests(unittest.TestCase): + maxDiff = None + + # ============================================================================ + # Entity JSON + # ============================================================================ + + task_entity_json = { + "app_unfurl_url": "https://myappdomain.com/123?myquery=param", + "entity_type": "slack#/entities/task", + "url": "https://myappdomain.com/123", + "external_ref": {"id": "123"}, + "entity_payload": { + "attributes": { + "title": {"text": "My Title"}, + "display_type": "Incident", + "display_id": "123", + "product_name": "My Product", + }, + "fields": { + "date_created": {"value": 1741164235}, + "status": {"value": "In Progress"}, + "description": { + "value": "My Description", + "long": True, + "edit": {"enabled": True, "text": {"min_length": 5, "max_length": 100}}, + }, + "due_date": {"value": "2026-06-06", "type": "slack#/types/date"}, + "created_by": {"type": "slack#/types/user", "user": {"user_id": "USLACKBOT"}}, + }, + "custom_fields": [ + { + "label": "My Users", + "key": "my-users", + "type": "array", + "item_type": "slack#/types/user", + "value": [ + {"type": "slack#/types/user", "user": {"user_id": "USLACKBOT"}}, + { + "type": "slack#/types/user", + "user": { + "text": "John Smith", + "email": "j@example.com", + "icon": {"alt_text": "Avatar", "url": "https://my-hosted-icon.com"}, + }, + }, + ], + } + ], + }, + } + + file_entity_json = { + "app_unfurl_url": "https://myappdomain.com/file/456?view=preview", + "entity_type": "slack#/entities/file", + "url": "https://myappdomain.com/file/456", + "external_ref": {"id": "456", "type": "DOC"}, + "entity_payload": { + "attributes": { + "title": {"text": "Q4 Product Roadmap"}, + "display_type": "PDF Document", + "display_id": "DOC-456", + "product_icon": {"alt_text": "Product Logo", "url": "https://myappdomain.com/icons/logo.png"}, + "product_name": "FileVault Pro", + "locale": "en-US", + "full_size_preview": { + "is_supported": True, + "preview_url": "https://myappdomain.com/previews/456/full.png", + "mime_type": "image/png", + }, + }, + "fields": { + "preview": { + "alt_text": "Document preview thumbnail", + "label": "Preview", + "image_url": "https://myappdomain.com/previews/456/thumb.png", + "type": "slack#/types/image", + }, + "date_created": {"value": 1709554321, "type": "slack#/types/timestamp"}, + "mime_type": {"value": "application/pdf"}, + }, + "slack_file": {"id": "F123ABC456", "type": "pdf"}, + "display_order": ["date_created", "mime_type", "preview"], + "actions": { + "primary_actions": [ + { + "text": "Open", + "action_id": "open_file", + "value": "456", + "style": "primary", + "url": "https://myappdomain.com/file/456/view", + } + ], + "overflow_actions": [{"text": "Delete", "action_id": "delete_file", "value": "456", "style": "danger"}], + }, + }, + } + + # ============================================================================ + # Methods returning re-usable metadata components + # ============================================================================ + + def attributes(self): + return EntityAttributes( + title=EntityTitle(text="My Title"), + product_name="My Product", + display_type="Incident", + display_id="123", + ) + + def sample_file_attributes(self): + return EntityAttributes( + title=EntityTitle(text="Q4 Product Roadmap"), + display_type="PDF Document", + display_id="DOC-456", + product_icon=EntityIconField(alt_text="Product Logo", url="https://myappdomain.com/icons/logo.png"), + product_name="FileVault Pro", + locale="en-US", + full_size_preview=EntityFullSizePreview( + is_supported=True, preview_url="https://myappdomain.com/previews/456/full.png", mime_type="image/png" + ), + ) + + def user_array_custom_field(self): + return EntityCustomField( + label="My Users", + key="my-users", + type="array", + item_type="slack#/types/user", + value=[ + EntityTypedField(type="slack#/types/user", user=EntityUserIDField(user_id="USLACKBOT")), + EntityTypedField( + type="slack#/types/user", + user=EntityUserField( + text="John Smith", + email="j@example.com", + icon=EntityIconField(alt_text="Avatar", url="https://my-hosted-icon.com"), + ), + ), + ], + ) + + def task_fields(self): + return TaskEntityFields( + date_created=EntityTimestampField(value=1741164235), + status=EntityStringField(value="In Progress"), + description=EntityStringField( + value="My Description", + long=True, + edit=EntityEditSupport(enabled=True, text=EntityEditTextConfig(min_length=5, max_length=100)), + ), + due_date=EntityTypedField(value="2026-06-06", type="slack#/types/date"), + created_by=EntityTypedField( + type="slack#/types/user", + user=EntityUserIDField(user_id="USLACKBOT"), + ), + ) + + def file_fields(self): + return FileEntityFields( + preview=EntityImageField( + type="slack#/types/image", + alt_text="Document preview thumbnail", + label="Preview", + image_url="https://myappdomain.com/previews/456/thumb.png", + ), + date_created=EntityTimestampField(value=1709554321, type="slack#/types/timestamp"), + mime_type=EntityStringField(value="application/pdf"), + ) + + def supported_full_size_preview(self): + return EntityFullSizePreview( + is_supported=True, preview_url="https://example.com/preview.jpg", mime_type="image/jpeg" + ) + + def sample_file_actions(self): + return EntityActions( + primary_actions=[ + EntityActionButton( + text="Open", + action_id="open_file", + value="456", + style="primary", + url="https://myappdomain.com/file/456/view", + ) + ], + overflow_actions=[EntityActionButton(text="Delete", action_id="delete_file", value="456", style="danger")], + ) + + # ============================================================================ + # Tests + # ============================================================================ + + def test_entity_full_size_preview_error(self): + error = EntityFullSizePreviewError(code="not_found", message="File not found") + self.assertDictEqual(error.to_dict(), {"code": "not_found", "message": "File not found"}) + + def test_entity_full_size_preview_with_error(self): + preview = EntityFullSizePreview( + is_supported=False, error=EntityFullSizePreviewError(code="invalid_format", message="File not found") + ) + result = preview.to_dict() + self.assertFalse(result["is_supported"]) + self.assertIn("error", result) + + def test_attributes(self): + self.assertDictEqual( + self.attributes().to_dict(), + self.task_entity_json["entity_payload"]["attributes"], + ) + + def test_sample_file_attributes(self): + self.assertDictEqual( + self.sample_file_attributes().to_dict(), + self.file_entity_json["entity_payload"]["attributes"], + ) + + def test_array_custom_field(self): + self.assertDictEqual( + self.user_array_custom_field().to_dict(), + self.task_entity_json["entity_payload"]["custom_fields"][0], + ) + + def test_task_fields(self): + self.assertDictEqual( + self.task_fields().to_dict(), + self.task_entity_json["entity_payload"]["fields"], + ) + + def test_file_fields(self): + self.assertDictEqual( + self.file_fields().to_dict(), + self.file_entity_json["entity_payload"]["fields"], + ) + + def test_sample_file_actions(self): + self.assertDictEqual( + self.sample_file_actions().to_dict(), + self.file_entity_json["entity_payload"]["actions"], + ) + + def test_complete_task_entity_metadata(self): + entity_metadata = EventAndEntityMetadata( + entities=[ + EntityMetadata( + entity_type="slack#/entities/task", + external_ref=ExternalRef(id="123"), + url="https://myappdomain.com/123", + app_unfurl_url="https://myappdomain.com/123?myquery=param", + entity_payload=EntityPayload( + attributes=self.attributes(), + fields=self.task_fields(), + custom_fields=[self.user_array_custom_field()], + ), + ) + ] + ) + self.assertDictEqual(entity_metadata.to_dict(), {"entities": [self.task_entity_json]}) + + def test_complete_file_entity_metadata(self): + entity_metadata = EventAndEntityMetadata( + entities=[ + EntityMetadata( + entity_type="slack#/entities/file", + external_ref=ExternalRef(id="456", type="DOC"), + url="https://myappdomain.com/file/456", + app_unfurl_url="https://myappdomain.com/file/456?view=preview", + entity_payload=EntityPayload( + attributes=self.sample_file_attributes(), + fields=self.file_fields(), + slack_file=FileEntitySlackFile(id="F123ABC456", type="pdf"), + display_order=["date_created", "mime_type", "preview"], + actions=self.sample_file_actions(), + ), + ) + ] + ) + self.assertDictEqual(entity_metadata.to_dict(), {"entities": [self.file_entity_json]}) diff --git a/tests/slack_sdk_async/web/test_web_client_coverage.py b/tests/slack_sdk_async/web/test_web_client_coverage.py index af6d92236..0a3c1687b 100644 --- a/tests/slack_sdk_async/web/test_web_client_coverage.py +++ b/tests/slack_sdk_async/web/test_web_client_coverage.py @@ -15,7 +15,7 @@ class TestWebClientCoverage(unittest.TestCase): # 295 endpoints as of September 17, 2025 # Can be fetched by running `var methodNames = [].slice.call(document.getElementsByClassName('apiReferenceFilterableList__listItemLink')).map(e => e.href.replace("https://api.slack.com/methods/", ""));console.log(methodNames.toString());console.log(methodNames.length);` on https://api.slack.com/methods - all_api_methods = "admin.analytics.getFile,admin.apps.activities.list,admin.apps.approve,admin.apps.clearResolution,admin.apps.restrict,admin.apps.uninstall,admin.apps.approved.list,admin.apps.config.lookup,admin.apps.config.set,admin.apps.requests.cancel,admin.apps.requests.list,admin.apps.restricted.list,admin.audit.anomaly.allow.getItem,admin.audit.anomaly.allow.updateItem,admin.auth.policy.assignEntities,admin.auth.policy.getEntities,admin.auth.policy.removeEntities,admin.barriers.create,admin.barriers.delete,admin.barriers.list,admin.barriers.update,admin.conversations.archive,admin.conversations.bulkArchive,admin.conversations.bulkDelete,admin.conversations.bulkMove,admin.conversations.convertToPrivate,admin.conversations.convertToPublic,admin.conversations.create,admin.conversations.createForObjects,admin.conversations.delete,admin.conversations.disconnectShared,admin.conversations.getConversationPrefs,admin.conversations.getCustomRetention,admin.conversations.getTeams,admin.conversations.invite,admin.conversations.linkObjects,admin.conversations.lookup,admin.conversations.removeCustomRetention,admin.conversations.rename,admin.conversations.search,admin.conversations.setConversationPrefs,admin.conversations.setCustomRetention,admin.conversations.setTeams,admin.conversations.unarchive,admin.conversations.unlinkObjects,admin.conversations.ekm.listOriginalConnectedChannelInfo,admin.conversations.restrictAccess.addGroup,admin.conversations.restrictAccess.listGroups,admin.conversations.restrictAccess.removeGroup,admin.emoji.add,admin.emoji.addAlias,admin.emoji.list,admin.emoji.remove,admin.emoji.rename,admin.functions.list,admin.functions.permissions.lookup,admin.functions.permissions.set,admin.inviteRequests.approve,admin.inviteRequests.deny,admin.inviteRequests.list,admin.inviteRequests.approved.list,admin.inviteRequests.denied.list,admin.roles.addAssignments,admin.roles.listAssignments,admin.roles.removeAssignments,admin.teams.admins.list,admin.teams.create,admin.teams.list,admin.teams.owners.list,admin.teams.settings.info,admin.teams.settings.setDefaultChannels,admin.teams.settings.setDescription,admin.teams.settings.setDiscoverability,admin.teams.settings.setIcon,admin.teams.settings.setName,admin.usergroups.addChannels,admin.usergroups.addTeams,admin.usergroups.listChannels,admin.usergroups.removeChannels,admin.users.assign,admin.users.invite,admin.users.list,admin.users.remove,admin.users.setAdmin,admin.users.setExpiration,admin.users.setOwner,admin.users.setRegular,admin.users.session.clearSettings,admin.users.session.getSettings,admin.users.session.invalidate,admin.users.session.list,admin.users.session.reset,admin.users.session.resetBulk,admin.users.session.setSettings,admin.users.unsupportedVersions.export,admin.workflows.collaborators.add,admin.workflows.collaborators.remove,admin.workflows.permissions.lookup,admin.workflows.search,admin.workflows.unpublish,admin.workflows.triggers.types.permissions.lookup,admin.workflows.triggers.types.permissions.set,api.test,apps.activities.list,apps.auth.external.delete,apps.auth.external.get,apps.connections.open,apps.uninstall,apps.datastore.bulkDelete,apps.datastore.bulkGet,apps.datastore.bulkPut,apps.datastore.count,apps.datastore.delete,apps.datastore.get,apps.datastore.put,apps.datastore.query,apps.datastore.update,apps.event.authorizations.list,apps.manifest.create,apps.manifest.delete,apps.manifest.export,apps.manifest.update,apps.manifest.validate,assistant.search.context,assistant.threads.setStatus,assistant.threads.setSuggestedPrompts,assistant.threads.setTitle,auth.revoke,auth.test,auth.teams.list,bookmarks.add,bookmarks.edit,bookmarks.list,bookmarks.remove,bots.info,calls.add,calls.end,calls.info,calls.update,calls.participants.add,calls.participants.remove,canvases.access.delete,canvases.access.set,canvases.create,canvases.delete,canvases.edit,canvases.sections.lookup,channels.mark,chat.appendStream,chat.delete,chat.deleteScheduledMessage,chat.getPermalink,chat.meMessage,chat.postEphemeral,chat.postMessage,chat.scheduleMessage,chat.scheduledMessages.list,chat.startStream,chat.stopStream,chat.unfurl,chat.update,conversations.acceptSharedInvite,conversations.approveSharedInvite,conversations.archive,conversations.close,conversations.create,conversations.declineSharedInvite,conversations.history,conversations.info,conversations.invite,conversations.inviteShared,conversations.join,conversations.kick,conversations.leave,conversations.list,conversations.listConnectInvites,conversations.mark,conversations.members,conversations.open,conversations.rename,conversations.replies,conversations.setPurpose,conversations.setTopic,conversations.unarchive,conversations.canvases.create,conversations.externalInvitePermissions.set,conversations.requestSharedInvite.approve,conversations.requestSharedInvite.deny,conversations.requestSharedInvite.list,dialog.open,dnd.endDnd,dnd.endSnooze,dnd.info,dnd.setSnooze,dnd.teamInfo,emoji.list,files.completeUploadExternal,files.delete,files.getUploadURLExternal,files.info,files.list,files.revokePublicURL,files.sharedPublicURL,files.upload,files.comments.delete,files.remote.add,files.remote.info,files.remote.list,files.remote.remove,files.remote.share,files.remote.update,functions.completeError,functions.completeSuccess,functions.distributions.permissions.add,functions.distributions.permissions.list,functions.distributions.permissions.remove,functions.distributions.permissions.set,functions.workflows.steps.list,functions.workflows.steps.responses.export,groups.mark,migration.exchange,oauth.access,oauth.v2.access,oauth.v2.exchange,openid.connect.token,openid.connect.userInfo,pins.add,pins.list,pins.remove,reactions.add,reactions.get,reactions.list,reactions.remove,reminders.add,reminders.complete,reminders.delete,reminders.info,reminders.list,rtm.connect,rtm.start,search.all,search.files,search.messages,stars.add,stars.list,stars.remove,team.accessLogs,team.billableInfo,team.info,team.integrationLogs,team.billing.info,team.externalTeams.disconnect,team.externalTeams.list,team.preferences.list,team.profile.get,tooling.tokens.rotate,usergroups.create,usergroups.disable,usergroups.enable,usergroups.list,usergroups.update,usergroups.users.list,usergroups.users.update,users.conversations,users.deletePhoto,users.getPresence,users.identity,users.info,users.list,users.lookupByEmail,users.setActive,users.setPhoto,users.setPresence,users.discoverableContacts.lookup,users.profile.get,users.profile.set,views.open,views.publish,views.push,views.update,workflows.featured.add,workflows.featured.list,workflows.featured.remove,workflows.featured.set,workflows.stepCompleted,workflows.stepFailed,workflows.updateStep,workflows.triggers.permissions.add,workflows.triggers.permissions.list,workflows.triggers.permissions.remove,workflows.triggers.permissions.set,im.list,im.mark,mpim.list,mpim.mark".split( + all_api_methods = "admin.analytics.getFile,admin.apps.activities.list,admin.apps.approve,admin.apps.clearResolution,admin.apps.restrict,admin.apps.uninstall,admin.apps.approved.list,admin.apps.config.lookup,admin.apps.config.set,admin.apps.requests.cancel,admin.apps.requests.list,admin.apps.restricted.list,admin.audit.anomaly.allow.getItem,admin.audit.anomaly.allow.updateItem,admin.auth.policy.assignEntities,admin.auth.policy.getEntities,admin.auth.policy.removeEntities,admin.barriers.create,admin.barriers.delete,admin.barriers.list,admin.barriers.update,admin.conversations.archive,admin.conversations.bulkArchive,admin.conversations.bulkDelete,admin.conversations.bulkMove,admin.conversations.convertToPrivate,admin.conversations.convertToPublic,admin.conversations.create,admin.conversations.createForObjects,admin.conversations.delete,admin.conversations.disconnectShared,admin.conversations.getConversationPrefs,admin.conversations.getCustomRetention,admin.conversations.getTeams,admin.conversations.invite,admin.conversations.linkObjects,admin.conversations.lookup,admin.conversations.removeCustomRetention,admin.conversations.rename,admin.conversations.search,admin.conversations.setConversationPrefs,admin.conversations.setCustomRetention,admin.conversations.setTeams,admin.conversations.unarchive,admin.conversations.unlinkObjects,admin.conversations.ekm.listOriginalConnectedChannelInfo,admin.conversations.restrictAccess.addGroup,admin.conversations.restrictAccess.listGroups,admin.conversations.restrictAccess.removeGroup,admin.emoji.add,admin.emoji.addAlias,admin.emoji.list,admin.emoji.remove,admin.emoji.rename,admin.functions.list,admin.functions.permissions.lookup,admin.functions.permissions.set,admin.inviteRequests.approve,admin.inviteRequests.deny,admin.inviteRequests.list,admin.inviteRequests.approved.list,admin.inviteRequests.denied.list,admin.roles.addAssignments,admin.roles.listAssignments,admin.roles.removeAssignments,admin.teams.admins.list,admin.teams.create,admin.teams.list,admin.teams.owners.list,admin.teams.settings.info,admin.teams.settings.setDefaultChannels,admin.teams.settings.setDescription,admin.teams.settings.setDiscoverability,admin.teams.settings.setIcon,admin.teams.settings.setName,admin.usergroups.addChannels,admin.usergroups.addTeams,admin.usergroups.listChannels,admin.usergroups.removeChannels,admin.users.assign,admin.users.invite,admin.users.list,admin.users.remove,admin.users.setAdmin,admin.users.setExpiration,admin.users.setOwner,admin.users.setRegular,admin.users.session.clearSettings,admin.users.session.getSettings,admin.users.session.invalidate,admin.users.session.list,admin.users.session.reset,admin.users.session.resetBulk,admin.users.session.setSettings,admin.users.unsupportedVersions.export,admin.workflows.collaborators.add,admin.workflows.collaborators.remove,admin.workflows.permissions.lookup,admin.workflows.search,admin.workflows.unpublish,admin.workflows.triggers.types.permissions.lookup,admin.workflows.triggers.types.permissions.set,api.test,apps.activities.list,apps.auth.external.delete,apps.auth.external.get,apps.connections.open,apps.uninstall,apps.datastore.bulkDelete,apps.datastore.bulkGet,apps.datastore.bulkPut,apps.datastore.count,apps.datastore.delete,apps.datastore.get,apps.datastore.put,apps.datastore.query,apps.datastore.update,apps.event.authorizations.list,apps.manifest.create,apps.manifest.delete,apps.manifest.export,apps.manifest.update,apps.manifest.validate,assistant.search.context,assistant.threads.setStatus,assistant.threads.setSuggestedPrompts,assistant.threads.setTitle,auth.revoke,auth.test,auth.teams.list,bookmarks.add,bookmarks.edit,bookmarks.list,bookmarks.remove,bots.info,calls.add,calls.end,calls.info,calls.update,calls.participants.add,calls.participants.remove,canvases.access.delete,canvases.access.set,canvases.create,canvases.delete,canvases.edit,canvases.sections.lookup,channels.mark,chat.appendStream,chat.delete,chat.deleteScheduledMessage,chat.getPermalink,chat.meMessage,chat.postEphemeral,chat.postMessage,chat.scheduleMessage,chat.scheduledMessages.list,chat.startStream,chat.stopStream,chat.unfurl,chat.update,conversations.acceptSharedInvite,conversations.approveSharedInvite,conversations.archive,conversations.close,conversations.create,conversations.declineSharedInvite,conversations.history,conversations.info,conversations.invite,conversations.inviteShared,conversations.join,conversations.kick,conversations.leave,conversations.list,conversations.listConnectInvites,conversations.mark,conversations.members,conversations.open,conversations.rename,conversations.replies,conversations.setPurpose,conversations.setTopic,conversations.unarchive,conversations.canvases.create,conversations.externalInvitePermissions.set,conversations.requestSharedInvite.approve,conversations.requestSharedInvite.deny,conversations.requestSharedInvite.list,dialog.open,dnd.endDnd,dnd.endSnooze,dnd.info,dnd.setSnooze,dnd.teamInfo,emoji.list,files.completeUploadExternal,files.delete,files.getUploadURLExternal,files.info,files.list,files.revokePublicURL,files.sharedPublicURL,files.upload,files.comments.delete,files.remote.add,files.remote.info,files.remote.list,files.remote.remove,files.remote.share,files.remote.update,functions.completeError,functions.completeSuccess,functions.distributions.permissions.add,functions.distributions.permissions.list,functions.distributions.permissions.remove,functions.distributions.permissions.set,functions.workflows.steps.list,functions.workflows.steps.responses.export,groups.mark,migration.exchange,oauth.access,oauth.v2.access,oauth.v2.exchange,openid.connect.token,openid.connect.userInfo,pins.add,pins.list,pins.remove,reactions.add,reactions.get,reactions.list,reactions.remove,reminders.add,reminders.complete,reminders.delete,reminders.info,reminders.list,rtm.connect,rtm.start,search.all,search.files,search.messages,slackLists.access.delete,slackLists.access.set,slackLists.create,slackLists.download.get,slackLists.download.start,slackLists.items.create,slackLists.items.delete,slackLists.items.delete,slackLists.items.deleteMultiple,slackLists.items.info,slackLists.items.list,slackLists.items.update,slackLists.update,stars.add,stars.list,stars.remove,team.accessLogs,team.billableInfo,team.info,team.integrationLogs,team.billing.info,team.externalTeams.disconnect,team.externalTeams.list,team.preferences.list,team.profile.get,tooling.tokens.rotate,usergroups.create,usergroups.disable,usergroups.enable,usergroups.list,usergroups.update,usergroups.users.list,usergroups.users.update,users.conversations,users.deletePhoto,users.getPresence,users.identity,users.info,users.list,users.lookupByEmail,users.setActive,users.setPhoto,users.setPresence,users.discoverableContacts.lookup,users.profile.get,users.profile.set,views.open,views.publish,views.push,views.update,workflows.featured.add,workflows.featured.list,workflows.featured.remove,workflows.featured.set,workflows.stepCompleted,workflows.stepFailed,workflows.updateStep,workflows.triggers.permissions.add,workflows.triggers.permissions.list,workflows.triggers.permissions.remove,workflows.triggers.permissions.set,im.list,im.mark,mpim.list,mpim.mark".split( "," ) @@ -802,6 +802,44 @@ async def run_method(self, method_name, method, async_method): elif method_name == "search_messages": self.api_methods_to_call.remove(method(query="Slack")["method"]) await async_method(query="Slack") + elif method_name == "slackLists_access_delete": + self.api_methods_to_call.remove(method(list_id="123")["method"]) + await async_method(list_id="123") + elif method_name == "slackLists_access_set": + self.api_methods_to_call.remove(method(list_id="123", access_level="private")["method"]) + await async_method(list_id="123", access_level="private") + elif method_name == "slackLists_create": + self.api_methods_to_call.remove(method(name="Backlog")["method"]) + await async_method(name="Backlog") + elif method_name == "slackLists_download_get": + self.api_methods_to_call.remove(method(list_id="123", job_id="123")["method"]) + await async_method(list_id="123", job_id="123") + elif method_name == "slackLists_download_start": + self.api_methods_to_call.remove(method(list_id="123")["method"]) + await async_method(list_id="123") + elif method_name == "slackLists_items_create": + self.api_methods_to_call.remove(method(list_id="123")["method"]) + await async_method(list_id="123") + elif method_name == "slackLists_items_delete": + self.api_methods_to_call.remove(method(list_id="123", id="123")["method"]) + await async_method(list_id="123", id="123") + elif method_name == "slackLists_items_deleteMultiple": + self.api_methods_to_call.remove(method(list_id="123", ids=["123", "456"])["method"]) + await async_method(list_id="123", ids=["123", "456"]) + elif method_name == "slackLists_items_info": + self.api_methods_to_call.remove(method(list_id="123", id="123")["method"]) + await async_method(list_id="123", id="123") + elif method_name == "slackLists_items_list": + self.api_methods_to_call.remove(method(list_id="123")["method"]) + await async_method(list_id="123") + elif method_name == "slackLists_items_update": + self.api_methods_to_call.remove( + method(list_id="123", cells=[{"column_id": "col123"}, {"row_id": "row123"}])["method"] + ) + await async_method(list_id="123", cells=[{"column_id": "col123"}, {"row_id": "row123"}]) + elif method_name == "slackLists_update": + self.api_methods_to_call.remove(method(id="123")["method"]) + await async_method(id="123") elif method_name == "team_externalTeams_disconnect": self.api_methods_to_call.remove(method(target_team="T111")["method"]) await async_method(target_team="T111")