Skip to content

Commit bfe8ff8

Browse files
fix: move away from deprecated datetime utilities
1 parent 978dd56 commit bfe8ff8

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

slack_sdk/oauth/installation_store/models/bot.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import datetime
1+
from datetime import datetime, timezone
22
from time import time
33
from typing import Optional, Union, Dict, Any, Sequence
44

@@ -100,10 +100,12 @@ def _to_standard_value_dict(self) -> Dict[str, Any]:
100100
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
101101
"bot_refresh_token": self.bot_refresh_token,
102102
"bot_token_expires_at": (
103-
datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
103+
datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
104+
if self.bot_token_expires_at is not None
105+
else None
104106
),
105107
"is_enterprise_install": self.is_enterprise_install,
106-
"installed_at": datetime.utcfromtimestamp(self.installed_at),
108+
"installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
107109
}
108110

109111
def to_dict_for_copying(self) -> Dict[str, Any]:

slack_sdk/oauth/installation_store/models/installation.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import datetime
1+
from datetime import datetime, timezone
22
from time import time
33
from typing import Optional, Union, Dict, Any, Sequence
44

@@ -173,22 +173,26 @@ def _to_standard_value_dict(self) -> Dict[str, Any]:
173173
"bot_scopes": ",".join(self.bot_scopes) if self.bot_scopes else None,
174174
"bot_refresh_token": self.bot_refresh_token,
175175
"bot_token_expires_at": (
176-
datetime.utcfromtimestamp(self.bot_token_expires_at) if self.bot_token_expires_at is not None else None
176+
datetime.fromtimestamp(self.bot_token_expires_at, tz=timezone.utc)
177+
if self.bot_token_expires_at is not None
178+
else None
177179
),
178180
"user_id": self.user_id,
179181
"user_token": self.user_token,
180182
"user_scopes": ",".join(self.user_scopes) if self.user_scopes else None,
181183
"user_refresh_token": self.user_refresh_token,
182184
"user_token_expires_at": (
183-
datetime.utcfromtimestamp(self.user_token_expires_at) if self.user_token_expires_at is not None else None
185+
datetime.fromtimestamp(self.user_token_expires_at, tz=timezone.utc)
186+
if self.user_token_expires_at is not None
187+
else None
184188
),
185189
"incoming_webhook_url": self.incoming_webhook_url,
186190
"incoming_webhook_channel": self.incoming_webhook_channel,
187191
"incoming_webhook_channel_id": self.incoming_webhook_channel_id,
188192
"incoming_webhook_configuration_url": self.incoming_webhook_configuration_url,
189193
"is_enterprise_install": self.is_enterprise_install,
190194
"token_type": self.token_type,
191-
"installed_at": datetime.utcfromtimestamp(self.installed_at),
195+
"installed_at": datetime.fromtimestamp(self.installed_at, tz=timezone.utc),
192196
}
193197

194198
def to_dict_for_copying(self) -> Dict[str, Any]:

slack_sdk/oauth/state_store/sqlalchemy/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import time
3-
from datetime import datetime
3+
from datetime import datetime, timezone
44
from logging import Logger
55
from uuid import uuid4
66

@@ -55,7 +55,7 @@ def logger(self) -> Logger:
5555

5656
def issue(self, *args, **kwargs) -> str:
5757
state: str = str(uuid4())
58-
now = datetime.utcfromtimestamp(time.time() + self.expiration_seconds)
58+
now = datetime.fromtimestamp(time.time() + self.expiration_seconds, tz=timezone.utc)
5959
with self.engine.begin() as conn:
6060
conn.execute(
6161
self.oauth_states.insert(),
@@ -67,7 +67,7 @@ def consume(self, state: str) -> bool:
6767
try:
6868
with self.engine.begin() as conn:
6969
c = self.oauth_states.c
70-
query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.utcnow()))
70+
query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.now(tz=timezone.utc)))
7171
result = conn.execute(query)
7272
for row in result.mappings():
7373
self.logger.debug(f"consume's query result: {row}")
@@ -124,7 +124,7 @@ def logger(self) -> Logger:
124124

125125
async def async_issue(self, *args, **kwargs) -> str:
126126
state: str = str(uuid4())
127-
now = datetime.utcfromtimestamp(time.time() + self.expiration_seconds)
127+
now = datetime.fromtimestamp(time.time() + self.expiration_seconds, tz=timezone.utc)
128128
async with self.engine.begin() as conn:
129129
await conn.execute(
130130
self.oauth_states.insert(),
@@ -136,7 +136,7 @@ async def async_consume(self, state: str) -> bool:
136136
try:
137137
async with self.engine.begin() as conn:
138138
c = self.oauth_states.c
139-
query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.utcnow()))
139+
query = self.oauth_states.select().where(and_(c.state == state, c.expire_at > datetime.now(tz=timezone.utc)))
140140
result = await conn.execute(query)
141141
for row in result.mappings():
142142
self.logger.debug(f"consume's query result: {row}")

tests/slack_sdk/oauth/installation_store/test_models.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import time
2+
from datetime import datetime, timezone
23
import unittest
34

45
from slack_sdk.oauth.installation_store import Installation, FileInstallationStore, Bot
@@ -36,6 +37,22 @@ def test_bot_custom_fields(self):
3637
self.assertEqual(bot.to_dict().get("service_user_id"), "XYZ123")
3738
self.assertEqual(bot.to_dict_for_copying().get("custom_values").get("service_user_id"), "XYZ123")
3839

40+
def test_bot_datetime_manipulation(self):
41+
expected_timestamp = datetime.now(tz=timezone.utc)
42+
bot = Bot(
43+
bot_token="xoxb-",
44+
bot_id="B111",
45+
bot_user_id="U111",
46+
bot_token_expires_at=expected_timestamp,
47+
installed_at=expected_timestamp,
48+
)
49+
bot_dict = bot.to_dict()
50+
self.assertIsNotNone(bot_dict)
51+
self.assertEqual(
52+
bot_dict.get("bot_token_expires_at").isoformat(), expected_timestamp.strftime("%Y-%m-%dT%H:%M:%S+00:00")
53+
)
54+
self.assertEqual(bot_dict.get("installed_at"), expected_timestamp)
55+
3956
def test_installation(self):
4057
installation = Installation(
4158
app_id="A111",
@@ -84,3 +101,29 @@ def test_installation_custom_fields(self):
84101
self.assertEqual(bot.to_dict().get("app_id"), "A111")
85102
self.assertEqual(bot.to_dict().get("service_user_id"), "XYZ123")
86103
self.assertEqual(bot.to_dict_for_copying().get("custom_values").get("app_id"), "A222")
104+
105+
def test_installation_datetime_manipulation(self):
106+
expected_timestamp = datetime.now(tz=timezone.utc)
107+
installation = Installation(
108+
app_id="A111",
109+
enterprise_id="E111",
110+
team_id="T111",
111+
user_id="U111",
112+
bot_id="B111",
113+
bot_token="xoxb-111",
114+
bot_scopes=["chat:write"],
115+
bot_user_id="U222",
116+
bot_token_expires_at=expected_timestamp,
117+
user_token_expires_at=expected_timestamp,
118+
installed_at=expected_timestamp,
119+
)
120+
installation_dict = installation.to_dict()
121+
self.assertIsNotNone(installation_dict)
122+
self.assertEqual(
123+
installation_dict.get("bot_token_expires_at").isoformat(), expected_timestamp.strftime("%Y-%m-%dT%H:%M:%S+00:00")
124+
)
125+
self.assertEqual(
126+
installation_dict.get("user_token_expires_at").isoformat(),
127+
expected_timestamp.strftime("%Y-%m-%dT%H:%M:%S+00:00"),
128+
)
129+
self.assertEqual(installation_dict.get("installed_at"), expected_timestamp)

0 commit comments

Comments
 (0)