Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .flake8

This file was deleted.

12 changes: 7 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Place your settings in this file to overwrite default and user settings.
{
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.venvPath": "${workspaceFolder}/env",
"python.formatting.provider": "black",
"editor.formatOnSave": true,
"python.linting.enabled": true,
}
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit"
}
}
}
11 changes: 5 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Each contains a header warning:
# DO NOT EDIT THIS FILE
# 1) Modify slack_sdk/web/client.py
# 2) Run `python scripts/codegen.py`
# 3) Run `black slack_sdk/`
# 3) Run `ruff format slack_sdk/`
```

**How it works:**
Expand Down Expand Up @@ -215,8 +215,8 @@ Available scripts in the `scripts/` directory:

All tooling configuration is defined in the following files:

- **Formatter**: `black` — see `[tool.black]` in `pyproject.toml`
- **Linter**: `flake8` — see `.flake8`
- **Formatter**: `ruff format` — see `[tool.ruff]` in `pyproject.toml`
- **Linter**: `ruff check` — see `[tool.ruff.lint]` in `pyproject.toml`
- **Type checker**: `mypy` — see `[tool.mypy]` in `pyproject.toml`
- **Test runner**: `pytest` — see `[tool.pytest.ini_options]` in `pyproject.toml`
- **Coverage**: `pytest-cov` reporting to Codecov
Expand All @@ -226,7 +226,7 @@ All tooling configuration is defined in the following files:

- Testing: `requirements/testing.txt`
- Optional runtime: `requirements/optional.txt`
- Dev tools (black, flake8, mypy): `requirements/tools.txt`
- Dev tools (ruff, mypy): `requirements/tools.txt`

## CI Pipeline (GitHub Actions)

Expand All @@ -244,8 +244,7 @@ Defined in `.github/workflows/ci-build.yml`, runs on push to `main`, all PRs, an

**Configuration:**

- `pyproject.toml` — Project metadata, build config, tool settings (black, pytest, mypy)
- `.flake8` — Flake8 linter configuration
- `pyproject.toml` — Project metadata, build config, tool settings (ruff, pytest, mypy)
- `requirements/*.txt` — Dependency specifications

**Tooling:**
Expand Down
4 changes: 2 additions & 2 deletions integration_tests/rtm/test_issue_530.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_issue_530(self):
self.fail("Raising an error here was expected")
except Exception as e:
self.assertEqual(
"The request to the Slack API failed.\n" "The server responded with: {'ok': False, 'error': 'invalid_auth'}",
"The request to the Slack API failed.\nThe server responded with: {'ok': False, 'error': 'invalid_auth'}",
str(e),
)
finally:
Expand All @@ -42,7 +42,7 @@ async def test_issue_530_async(self):
self.fail("Raising an error here was expected")
except Exception as e:
self.assertEqual(
"The request to the Slack API failed.\n" "The server responded with: {'ok': False, 'error': 'invalid_auth'}",
"The request to the Slack API failed.\nThe server responded with: {'ok': False, 'error': 'invalid_auth'}",
str(e),
)
finally:
Expand Down
4 changes: 2 additions & 2 deletions integration_tests/samples/conversations/open_dm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
client = WebClient(token=os.environ["SLACK_API_TOKEN"])

all_users = client.users_list(limit=100)["members"]
joinable_only = (
lambda u: u["id"] != "USLACKBOT"
joinable_only = lambda u: (
u["id"] != "USLACKBOT"
and not u["is_bot"]
and not u["is_app_user"]
and not u["deleted"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ def setUp(self):
self.channel_id = client.conversations_create(
name=channel_name,
is_private=True,
)[
"channel"
]["id"]
)["channel"]["id"]

def tearDown(self):
pass
Expand Down
4 changes: 1 addition & 3 deletions integration_tests/web/test_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ def test_sync(self):
lambda u: not u["deleted"] and "bot_id" not in u,
client.users_list(limit=50)["members"],
)
)[
0
]["id"]
)[0]["id"]

new_call = client.calls_add(
external_unique_id=str(uuid.uuid4()),
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ optional-dependencies.optional = { file = ["requirements/optional.txt"] }
[tool.distutils.bdist_wheel]
universal = true

[tool.black]
[tool.ruff]
line-length = 125

[tool.ruff.lint]
select = ["E", "W", "F"]
ignore = ["E402"]

[tool.pytest.ini_options]
testpaths = ["tests"]
log_file = "logs/pytest.log"
Expand Down
7 changes: 2 additions & 5 deletions requirements/tools.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@
# mypy
mypy<=2.1.0

# flake8
flake8>=7.3.0,<8

# black
black==26.3.1
# ruff
ruff==0.16.4
2 changes: 1 addition & 1 deletion scripts/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"#\n"
"# 1) Modify slack_sdk/web/client.py\n"
"# 2) Run `python scripts/codegen.py`\n"
"# 3) Run `black slack_sdk/`\n"
"# 3) Run `ruff format slack_sdk/`\n"
"#\n"
"# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
"\n"
Expand Down
3 changes: 2 additions & 1 deletion scripts/format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ if [[ "$1" != "--no-install" ]]; then
pip install -U -r requirements/tools.txt
fi

black slack/ slack_sdk/ tests/ integration_tests/
ruff check --fix slack/ slack_sdk/
ruff format slack/ slack_sdk/ tests/ integration_tests/
4 changes: 2 additions & 2 deletions scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ if [[ "$1" != "--no-install" ]]; then
pip install -U -r requirements/tools.txt
fi

black --check slack/ slack_sdk/ tests/ integration_tests/
flake8 slack/ slack_sdk/
ruff format --check slack/ slack_sdk/ tests/ integration_tests/
ruff check slack/ slack_sdk/
2 changes: 1 addition & 1 deletion scripts/run_integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ cd ${script_dir}/..
./scripts/install.sh

echo "Generating code ..." && python scripts/codegen.py --path .
echo "Running black (code formatter) ..." && ./scripts/format.sh --no-install
echo "Running ruff (code formatter) ..." && ./scripts/format.sh --no-install

test_target="${1:-tests/integration_tests/}"
PYTHONPATH=$PWD:$PYTHONPATH pytest $test_target
2 changes: 1 addition & 1 deletion scripts/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ cd ${script_dir}/..
test_target="${1:-tests/}"

echo "Generating code ..." && python scripts/codegen.py --path .
echo "Running black (code formatter) ..." && ./scripts/format.sh --no-install
echo "Running ruff (code formatter) ..." && ./scripts/format.sh --no-install

echo "Running tests ..."
PYTHONPATH=$PWD:$PYTHONPATH pytest $test_target
2 changes: 1 addition & 1 deletion scripts/run_validation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ echo "Generating code ..." && python scripts/codegen.py --path .

# Run mypy type checking only on the latest supported Python version
if [[ "$current_py" == "$LATEST_SUPPORTED_PY" ]]; then
echo "Running black (code formatter) ..." && ./scripts/format.sh --no-install
echo "Running ruff (code formatter) ..." && ./scripts/format.sh --no-install
echo "Running linting checks ..." && ./scripts/lint.sh --no-install
echo "Running mypy type checking ..." && ./scripts/run_mypy.sh --no-install
else
Expand Down
12 changes: 6 additions & 6 deletions slack/web/classes/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ from slack.web.classes import dialogs

builder = (
dialogs.DialogBuilder()
.title("My Cool Dialog")
.callback_id("myCoolDialog")
.state({'value': 123, 'key': "something"})
.conversation_selector(name="target", label="Choose Target")
.text_area(name="message", label="Message", hint="Enter a message", max_length=500)
.text_field(name="signature", label="Signature", optional=True, max_length=50)
.title("My Cool Dialog")
.callback_id("myCoolDialog")
.state({"value": 123, "key": "something"})
.conversation_selector(name="target", label="Choose Target")
.text_area(name="message", label="Message", hint="Enter a message", max_length=500)
.text_field(name="signature", label="Signature", optional=True, max_length=50)
)

client = WebClient(token="abc")
Expand Down
2 changes: 1 addition & 1 deletion slack_sdk/audit_logs/v1/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ async def _perform_http_request(
):
if self.logger.level <= logging.DEBUG:
self.logger.info(
f"A retry handler found: {type(handler).__name__} " f"for {http_verb} {url} - {e}"
f"A retry handler found: {type(handler).__name__} for {http_verb} {url} - {e}"
)
await handler.prepare_for_next_attempt_async(
state=retry_state,
Expand Down
9 changes: 8 additions & 1 deletion slack_sdk/models/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ Choose the base class that matches the type you're adding.
def attributes(self) -> Set[str]:
return super().attributes.union({"text", "optional_field"})

def __init__(self, *, text: Union[str, dict, TextObject], optional_field: Optional[str] = None, block_id: Optional[str] = None, **others: dict):
def __init__(
self,
*,
text: Union[str, dict, TextObject],
optional_field: Optional[str] = None,
block_id: Optional[str] = None,
**others: dict,
):
super().__init__(type=self.type, block_id=block_id)
show_unknown_key_warning(self, others)
self.text = TextObject.parse(text, default_type=PlainTextObject.type)
Expand Down
2 changes: 1 addition & 1 deletion slack_sdk/models/basic_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ def wrapped_f(*args, **kwargs):

class EnumValidator(JsonValidator):
def __init__(self, attribute: str, enum: Iterable[str]):
super().__init__(f"{attribute} attribute must be one of the following values: " f"{', '.join(enum)}")
super().__init__(f"{attribute} attribute must be one of the following values: {', '.join(enum)}")
2 changes: 1 addition & 1 deletion slack_sdk/models/blocks/block_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -1916,7 +1916,7 @@ def __init__(
self.options = options
self.confirm = ConfirmObject.parse(confirm) # type: ignore[arg-type]

@JsonValidator(f"options attribute must have between {options_min_length} " f"and {options_max_length} items")
@JsonValidator(f"options attribute must have between {options_min_length} and {options_max_length} items")
def _validate_options_length(self) -> bool:
return self.options_min_length <= len(self.options) <= self.options_max_length

Expand Down
2 changes: 1 addition & 1 deletion slack_sdk/models/messages/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

skip_warn = os.environ.get("SLACKCLIENT_SKIP_DEPRECATION") # for unit tests etc.
if not skip_warn:
message = "This class is no longer actively maintained. " "Please use a dict object for building message data instead."
message = "This class is no longer actively maintained. Please use a dict object for building message data instead."
warnings.warn(message)


Expand Down
8 changes: 1 addition & 7 deletions slack_sdk/oauth/authorize_url_generator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,7 @@ def __init__(
def generate(self, state: str, team: Optional[str] = None) -> str:
scopes = ",".join(self.scopes) if self.scopes else ""
user_scopes = ",".join(self.user_scopes) if self.user_scopes else ""
url = (
f"{self.authorization_url}?"
f"state={state}&"
f"client_id={self.client_id}&"
f"scope={scopes}&"
f"user_scope={user_scopes}"
)
url = f"{self.authorization_url}?state={state}&client_id={self.client_id}&scope={scopes}&user_scope={user_scopes}"
if self.redirect_uri is not None:
url += f"&redirect_uri={self.redirect_uri}"
if team is not None:
Expand Down
4 changes: 2 additions & 2 deletions slack_sdk/oauth/state_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def __init__(
self.expiration_seconds = expiration_seconds

def build_set_cookie_for_new_state(self, state: str) -> str:
return f"{self.cookie_name}={state}; " "Secure; " "HttpOnly; " "Path=/; " f"Max-Age={self.expiration_seconds}"
return f"{self.cookie_name}={state}; Secure; HttpOnly; Path=/; Max-Age={self.expiration_seconds}"

def build_set_cookie_for_deletion(self) -> str:
return f"{self.cookie_name}=deleted; " "Secure; " "HttpOnly; " "Path=/; " "Expires=Thu, 01 Jan 1970 00:00:00 GMT"
return f"{self.cookie_name}=deleted; Secure; HttpOnly; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT"

def is_valid_browser(
self,
Expand Down
14 changes: 6 additions & 8 deletions slack_sdk/rtm_v2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def run_all_message_listeners(self, message: str):

def run_all_error_listeners(self, error: Exception):
self.logger.exception(
f"on_error invoked (session id: {self.session_id()}, " f"error: {type(error).__name__}, message: {error})"
f"on_error invoked (session id: {self.session_id()}, error: {type(error).__name__}, message: {error})"
)
for listener in self.on_error_listeners:
listener(error)
Expand All @@ -357,7 +357,7 @@ def run_all_close_listeners(self, code: int, reason: Optional[str] = None):
if self.logger.level <= logging.DEBUG:
self.logger.debug(f"on_close invoked (session id: {self.session_id()})")
if self.auto_reconnect_enabled:
self.logger.info("Received CLOSE event. Going to reconnect... " f"(session id: {self.session_id()})")
self.logger.info(f"Received CLOSE event. Going to reconnect... (session id: {self.session_id()})")
self.connect_to_new_endpoint()
for listener in self.on_close_listeners:
listener(code, reason)
Expand All @@ -366,14 +366,12 @@ def _run_current_session(self):
if self.current_session is not None and self.current_session.is_active():
session_id = self.session_id()
try:
self.logger.info("Starting to receive messages from a new connection" f" (session id: {session_id})")
self.logger.info(f"Starting to receive messages from a new connection (session id: {session_id})")
self.current_session_state.terminated = False
self.current_session.run_until_completion(self.current_session_state)
self.logger.info("Stopped receiving messages from a connection" f" (session id: {session_id})")
self.logger.info(f"Stopped receiving messages from a connection (session id: {session_id})")
except Exception as e:
self.logger.exception(
"Failed to start or stop the current session" f" (session id: {session_id}, error: {e})"
)
self.logger.exception(f"Failed to start or stop the current session (session id: {session_id}, error: {e})")

def _monitor_current_session(self):
if self.current_app_monitor_started:
Expand All @@ -382,7 +380,7 @@ def _monitor_current_session(self):

if self.auto_reconnect_enabled and (self.current_session is None or not self.current_session.is_active()):
self.logger.info(
"The session seems to be already closed. Going to reconnect... " f"(session id: {self.session_id()})"
f"The session seems to be already closed. Going to reconnect... (session id: {self.session_id()})"
)
self.connect_to_new_endpoint()
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion slack_sdk/scim/v1/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ async def _perform_http_request(
):
if self.logger.level <= logging.DEBUG:
self.logger.info(
f"A retry handler found: {type(handler).__name__} " f"for {http_verb} {url} - {e}"
f"A retry handler found: {type(handler).__name__} for {http_verb} {url} - {e}"
)
await handler.prepare_for_next_attempt_async(
state=retry_state,
Expand Down
4 changes: 1 addition & 3 deletions slack_sdk/socket_mode/aiohttp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,7 @@ async def send_message(self, message: str):
if await self.is_connected():
await self.current_session.send_str(message) # type: ignore[union-attr]
else:
self.logger.warning(
f"The current session ({session_id}) is no longer active. " "Failed to send a message"
)
self.logger.warning(f"The current session ({session_id}) is no longer active. Failed to send a message")
raise e
finally:
if self.connect_operation_lock.locked() is True:
Expand Down
5 changes: 1 addition & 4 deletions slack_sdk/socket_mode/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,5 @@ async def run_message_listeners(self, message: dict, raw_message: str) -> None:
finally:
if self.logger.level <= logging.DEBUG:
self.logger.debug(
f"Message processing completed ("
f"type: {type}, "
f"envelope_id: {envelope_id}, "
f"session: {session_id})"
f"Message processing completed (type: {type}, envelope_id: {envelope_id}, session: {session_id})"
)
Loading
Loading