diff --git a/docs/reference/oauth/installation_store/index.html b/docs/reference/oauth/installation_store/index.html
index 4f90fb1c5..8d95802d0 100644
--- a/docs/reference/oauth/installation_store/index.html
+++ b/docs/reference/oauth/installation_store/index.html
@@ -193,10 +193,12 @@
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
"bot_refresh_token": self.bot_refresh_token,
"bot_token_expires_at": (
- datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
+ datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
+ if self.bot_token_expires_at is not None
+ else None
),
"is_enterprise_install": self.is_enterprise_install,
- "installed_at": datetime.utcfromtimestamp(self.installed_at),
+ "installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
}
def to_dict_for_copying(self) -> Dict[str, Any]:
@@ -850,14 +852,18 @@ Inherited members
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
"bot_refresh_token": self.bot_refresh_token,
"bot_token_expires_at": (
- datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
+ datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
+ if self.bot_token_expires_at is not None
+ else None
),
"user_id": self.user_id,
"user_token": self.user_token,
"user_scopes": ",".join(self.user_scopes) if self.user_scopes else None,
"user_refresh_token": self.user_refresh_token,
"user_token_expires_at": (
- datetime.utcfromtimestamp(self.user_token_expires_at) if self.user_token_expires_at is not None else None
+ datetime.fromtimestamp(self.user_token_expires_at, tz=timezone.utc)
+ if self.user_token_expires_at is not None
+ else None
),
"incoming_webhook_url": self.incoming_webhook_url,
"incoming_webhook_channel": self.incoming_webhook_channel,
@@ -865,7 +871,7 @@ Inherited members
"incoming_webhook_configuration_url": self.incoming_webhook_configuration_url,
"is_enterprise_install": self.is_enterprise_install,
"token_type": self.token_type,
- "installed_at": datetime.utcfromtimestamp(self.installed_at),
+ "installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
}
def to_dict_for_copying(self) -> Dict[str, Any]:
diff --git a/docs/reference/oauth/installation_store/models/bot.html b/docs/reference/oauth/installation_store/models/bot.html
index bb6182df2..b27abfc7d 100644
--- a/docs/reference/oauth/installation_store/models/bot.html
+++ b/docs/reference/oauth/installation_store/models/bot.html
@@ -150,10 +150,12 @@
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
"bot_refresh_token": self.bot_refresh_token,
"bot_token_expires_at": (
- datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
+ datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
+ if self.bot_token_expires_at is not None
+ else None
),
"is_enterprise_install": self.is_enterprise_install,
- "installed_at": datetime.utcfromtimestamp(self.installed_at),
+ "installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
}
def to_dict_for_copying(self) -> Dict[str, Any]:
diff --git a/docs/reference/oauth/installation_store/models/index.html b/docs/reference/oauth/installation_store/models/index.html
index b96d16179..69e08affe 100644
--- a/docs/reference/oauth/installation_store/models/index.html
+++ b/docs/reference/oauth/installation_store/models/index.html
@@ -161,10 +161,12 @@
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
"bot_refresh_token": self.bot_refresh_token,
"bot_token_expires_at": (
- datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
+ datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
+ if self.bot_token_expires_at is not None
+ else None
),
"is_enterprise_install": self.is_enterprise_install,
- "installed_at": datetime.utcfromtimestamp(self.installed_at),
+ "installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
}
def to_dict_for_copying(self) -> Dict[str, Any]:
@@ -469,14 +471,18 @@ Methods
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
"bot_refresh_token": self.bot_refresh_token,
"bot_token_expires_at": (
- datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
+ datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
+ if self.bot_token_expires_at is not None
+ else None
),
"user_id": self.user_id,
"user_token": self.user_token,
"user_scopes": ",".join(self.user_scopes) if self.user_scopes else None,
"user_refresh_token": self.user_refresh_token,
"user_token_expires_at": (
- datetime.utcfromtimestamp(self.user_token_expires_at) if self.user_token_expires_at is not None else None
+ datetime.fromtimestamp(self.user_token_expires_at, tz=timezone.utc)
+ if self.user_token_expires_at is not None
+ else None
),
"incoming_webhook_url": self.incoming_webhook_url,
"incoming_webhook_channel": self.incoming_webhook_channel,
@@ -484,7 +490,7 @@ Methods
"incoming_webhook_configuration_url": self.incoming_webhook_configuration_url,
"is_enterprise_install": self.is_enterprise_install,
"token_type": self.token_type,
- "installed_at": datetime.utcfromtimestamp(self.installed_at),
+ "installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
}
def to_dict_for_copying(self) -> Dict[str, Any]:
diff --git a/docs/reference/oauth/installation_store/models/installation.html b/docs/reference/oauth/installation_store/models/installation.html
index c0de92807..3f47d901a 100644
--- a/docs/reference/oauth/installation_store/models/installation.html
+++ b/docs/reference/oauth/installation_store/models/installation.html
@@ -222,14 +222,18 @@
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
"bot_refresh_token": self.bot_refresh_token,
"bot_token_expires_at": (
- datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
+ datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
+ if self.bot_token_expires_at is not None
+ else None
),
"user_id": self.user_id,
"user_token": self.user_token,
"user_scopes": ",".join(self.user_scopes) if self.user_scopes else None,
"user_refresh_token": self.user_refresh_token,
"user_token_expires_at": (
- datetime.utcfromtimestamp(self.user_token_expires_at) if self.user_token_expires_at is not None else None
+ datetime.fromtimestamp(self.user_token_expires_at, tz=timezone.utc)
+ if self.user_token_expires_at is not None
+ else None
),
"incoming_webhook_url": self.incoming_webhook_url,
"incoming_webhook_channel": self.incoming_webhook_channel,
@@ -237,7 +241,7 @@
"incoming_webhook_configuration_url": self.incoming_webhook_configuration_url,
"is_enterprise_install": self.is_enterprise_install,
"token_type": self.token_type,
- "installed_at": datetime.utcfromtimestamp(self.installed_at),
+ "installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
}
def to_dict_for_copying(self) -> Dict[str, Any]:
diff --git a/docs/reference/oauth/state_store/sqlalchemy/index.html b/docs/reference/oauth/state_store/sqlalchemy/index.html
index 29fe36884..a35fa3171 100644
--- a/docs/reference/oauth/state_store/sqlalchemy/index.html
+++ b/docs/reference/oauth/state_store/sqlalchemy/index.html
@@ -99,7 +99,7 @@
async def async_issue(self, *args, **kwargs) -> str:
state: str = str(uuid4())
- now = datetime.utcfromtimestamp(time.time() + self.expiration_seconds)
+ now = datetime.fromtimestamp(time.time() + self.expiration_seconds, tz=timezone.utc)
async with self.engine.begin() as conn:
await conn.execute(
self.oauth_states.insert(),
@@ -111,7 +111,7 @@
try:
async with self.engine.begin() as conn:
c = self.oauth_states.c
- query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.utcnow()))
+ query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.now(tz=timezone.utc)))
result = await conn.execute(query)
for row in result.mappings():
self.logger.debug(f"consume's query result: {row}")
@@ -191,7 +191,7 @@ Methods
try:
async with self.engine.begin() as conn:
c = self.oauth_states.c
- query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.utcnow()))
+ query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.now(tz=timezone.utc)))
result = await conn.execute(query)
for row in result.mappings():
self.logger.debug(f"consume's query result: {row}")
@@ -215,7 +215,7 @@ Methods
async def async_issue(self, *args, **kwargs) -> str:
state: str = str(uuid4())
- now = datetime.utcfromtimestamp(time.time() + self.expiration_seconds)
+ now = datetime.fromtimestamp(time.time() + self.expiration_seconds, tz=timezone.utc)
async with self.engine.begin() as conn:
await conn.execute(
self.oauth_states.insert(),
@@ -293,7 +293,7 @@ Methods
def issue(self, *args, **kwargs) -> str:
state: str = str(uuid4())
- now = datetime.utcfromtimestamp(time.time() + self.expiration_seconds)
+ now = datetime.fromtimestamp(time.time() + self.expiration_seconds, tz=timezone.utc)
with self.engine.begin() as conn:
conn.execute(
self.oauth_states.insert(),
@@ -305,7 +305,7 @@ Methods
try:
with self.engine.begin() as conn:
c = self.oauth_states.c
- query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.utcnow()))
+ query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.now(tz=timezone.utc)))
result = conn.execute(query)
for row in result.mappings():
self.logger.debug(f"consume's query result: {row}")
@@ -385,7 +385,7 @@ Methods
try:
with self.engine.begin() as conn:
c = self.oauth_states.c
- query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.utcnow()))
+ query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.now(tz=timezone.utc)))
result = conn.execute(query)
for row in result.mappings():
self.logger.debug(f"consume's query result: {row}")
@@ -422,7 +422,7 @@ Methods
def issue(self, *args, **kwargs) -> str:
state: str = str(uuid4())
- now = datetime.utcfromtimestamp(time.time() + self.expiration_seconds)
+ now = datetime.fromtimestamp(time.time() + self.expiration_seconds, tz=timezone.utc)
with self.engine.begin() as conn:
conn.execute(
self.oauth_states.insert(),
diff --git a/docs/reference/web/async_chat_stream.html b/docs/reference/web/async_chat_stream.html
index ca7bf2506..d8e4f5bfe 100644
--- a/docs/reference/web/async_chat_stream.html
+++ b/docs/reference/web/async_chat_stream.html
@@ -48,7 +48,7 @@
class AsyncChatStream
-(client: AsyncWebClient,
*,
channel: str,
logger: logging.Logger,
thread_ts: str,
buffer_size: int,
recipient_team_id: str | None = None,
recipient_user_id: str | None = None,
**kwargs)
+(client: AsyncWebClient,
*,
channel: str,
logger: logging.Logger,
thread_ts: str,
buffer_size: int,
recipient_team_id: str | None = None,
recipient_user_id: str | None = None,
task_display_mode: str | None = None,
**kwargs)
-
@@ -72,6 +72,7 @@
buffer_size: int,
recipient_team_id: Optional[str] = None,
recipient_user_id: Optional[str] = None,
+ task_display_mode: Optional[str] = None,
**kwargs,
):
"""Initialize a new ChatStream instance.
@@ -87,6 +88,8 @@
recipient_team_id: The encoded ID of the team the user receiving the streaming text belongs to. Required when
streaming to channels.
recipient_user_id: The encoded ID of the user to receive the streaming text. Required when streaming to channels.
+ task_display_mode: Specifies how tasks are displayed in the message. A "timeline" displays individual tasks
+ with text and "plan" displays all tasks together.
buffer_size: The length of markdown_text to buffer in-memory before calling a method. Increasing this value
decreases the number of method calls made for the same amount of text, which is useful to avoid rate limits.
**kwargs: Additional arguments passed to the underlying API calls.
@@ -99,6 +102,7 @@
"thread_ts": thread_ts,
"recipient_team_id": recipient_team_id,
"recipient_user_id": recipient_user_id,
+ "task_display_mode": task_display_mode,
**kwargs,
}
self._buffer = ""
@@ -109,7 +113,8 @@
async def append(
self,
*,
- markdown_text: str,
+ markdown_text: Optional[str] = None,
+ chunks: Optional[Sequence[Union[Dict, Chunk]]] = None,
**kwargs,
) -> Optional[AsyncSlackResponse]:
"""Append to the stream.
@@ -118,6 +123,7 @@
is stopped this method cannot be called.
Args:
+ chunks: An array of streaming chunks. Chunks can be markdown text, plan, or task update chunks.
markdown_text: Accepts message text formatted in markdown. Limit this field to 12,000 characters. This text is
what will be appended to the message received so far.
**kwargs: Additional arguments passed to the underlying API calls.
@@ -145,9 +151,10 @@
raise e.SlackRequestError(f"Cannot append to stream: stream state is {self._state}")
if kwargs.get("token"):
self._token = kwargs.pop("token")
- self._buffer += markdown_text
- if len(self._buffer) >= self._buffer_size:
- return await self._flush_buffer(**kwargs)
+ if markdown_text is not None:
+ self._buffer += markdown_text
+ if len(self._buffer) >= self._buffer_size or chunks is not None:
+ return await self._flush_buffer(chunks=chunks, **kwargs)
details = {
"buffer_length": len(self._buffer),
"buffer_size": self._buffer_size,
@@ -163,6 +170,7 @@
self,
*,
markdown_text: Optional[str] = None,
+ chunks: Optional[Sequence[Union[Dict, Chunk]]] = None,
blocks: Optional[Union[str, Sequence[Union[Dict, Block]]]] = None,
metadata: Optional[Union[Dict, Metadata]] = None,
**kwargs,
@@ -171,6 +179,7 @@
Args:
blocks: A list of blocks that will be rendered at the bottom of the finalized message.
+ chunks: An array of streaming chunks. Chunks can be markdown text, plan, or task update chunks.
markdown_text: Accepts message text formatted in markdown. Limit this field to 12,000 characters. This text is
what will be appended to the message received so far.
metadata: JSON object with event_type and event_payload fields, presented as a URL-encoded string. Metadata you
@@ -211,26 +220,36 @@
raise e.SlackRequestError("Failed to stop stream: stream not started")
self._stream_ts = str(response["ts"])
self._state = "in_progress"
+ flushings: List[Union[Dict, Chunk]] = []
+ if len(self._buffer) != 0:
+ flushings.append(MarkdownTextChunk(text=self._buffer))
+ if chunks is not None:
+ flushings.extend(chunks)
response = await self._client.chat_stopStream(
token=self._token,
channel=self._stream_args["channel"],
ts=self._stream_ts,
blocks=blocks,
- markdown_text=self._buffer,
+ chunks=flushings,
metadata=metadata,
**kwargs,
)
self._state = "completed"
return response
- async def _flush_buffer(self, **kwargs) -> AsyncSlackResponse:
- """Flush the internal buffer by making appropriate API calls."""
+ async def _flush_buffer(self, chunks: Optional[Sequence[Union[Dict, Chunk]]] = None, **kwargs) -> AsyncSlackResponse:
+ """Flush the internal buffer with chunks by making appropriate API calls."""
+ chunks_to_flush: List[Union[Dict, Chunk]] = []
+ if len(self._buffer) != 0:
+ chunks_to_flush.append(MarkdownTextChunk(text=self._buffer))
+ if chunks is not None:
+ chunks_to_flush.extend(chunks)
if not self._stream_ts:
response = await self._client.chat_startStream(
**self._stream_args,
token=self._token,
**kwargs,
- markdown_text=self._buffer,
+ chunks=chunks_to_flush,
)
self._stream_ts = response.get("ts")
self._state = "in_progress"
@@ -240,7 +259,7 @@
channel=self._stream_args["channel"],
ts=self._stream_ts,
**kwargs,
- markdown_text=self._buffer,
+ chunks=chunks_to_flush,
)
self._buffer = ""
return response
@@ -266,6 +285,9 @@ Args
streaming to channels.