Skip to content

Commit cc8daad

Browse files
committed
pinnwand: use aware datetime objects
Deprecation warnings are being emitted about using `datetime.utcnow` and to replace those with `datetime.now(timezone.utc)`. This creates a timezone aware datetime object hence we now need to get datetime aware objects from the database as well. This seems to a bit annoying in (for example SQLite) for the backend. We use a 3rd-party package to provide us with an `UtcDateTime` type for SQLAlchemy to fix this. Signed-off-by: Simon de Vlieger <[email protected]>
1 parent 5f0e526 commit cc8daad

File tree

10 files changed

+671
-548
lines changed

10 files changed

+671
-548
lines changed

CHANGELOG.rst

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ v1.6.1 (unreleased)
1010
languages again. Opened a public discussion about this behavior.
1111
* Conditionally discover e2e testcases only when playwright is available in
1212
the environment. Closes #284.
13+
* Switched to timezone-aware objects in the databse to squash deprecation
14+
warnings.
1315

1416
v1.6.0 (20241101)
1517
*******************

pdm.lock

+336-267
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dependencies = [
1515
"token-bucket>=0.3.0",
1616
"tomli>=2.0.1",
1717
"python-dotenv>=1.0.1",
18+
"sqlalchemy-utc>=0.14.0",
1819
]
1920
requires-python = ">=3.8"
2021
readme = "README.md"

requirements.txt

+304-254
Large diffs are not rendered by default.

src/pinnwand/database/models.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import datetime
2-
from datetime import timedelta
2+
from datetime import timedelta, timezone
33
from typing import Optional
44

55
import pygments.lexers
66
from pygments_better_html import BetterHtmlFormatter
77
from sqlalchemy import (
88
Column,
9-
DateTime,
109
ForeignKey,
1110
Integer,
1211
String,
@@ -18,6 +17,8 @@
1817
relationship,
1918
)
2019

20+
from sqlalchemy_utc import UtcDateTime
21+
2122
from pinnwand import defensive, error, logger, utility
2223
from pinnwand.configuration import Configuration, ConfigurationProvider
2324

@@ -42,15 +43,15 @@ def __tablename__(cls) -> str: # pylint: disable=no-self-argument
4243
class Paste(Base): # type: ignore
4344
"""The Paste model represents a single Paste."""
4445

45-
pub_date = Column(DateTime)
46-
chg_date = Column(DateTime)
46+
pub_date = Column(UtcDateTime)
47+
chg_date = Column(UtcDateTime)
4748

4849
slug = Column(String(250), unique=True)
4950
removal = Column(String(250), unique=True)
5051

5152
src = Column(String(250))
5253

53-
exp_date = Column(DateTime)
54+
exp_date = Column(UtcDateTime)
5455

5556
files = relationship("File", cascade="all,delete", backref="paste")
5657

@@ -66,8 +67,8 @@ def __init__(
6667
self.slug = slug
6768
self.removal = utility.slug_create(auto_scale=False)
6869

69-
self.pub_date = datetime.datetime.utcnow()
70-
self.chg_date = datetime.datetime.utcnow()
70+
self.pub_date = datetime.datetime.now(timezone.utc)
71+
self.chg_date = datetime.datetime.now(timezone.utc)
7172

7273
self.src = src
7374

@@ -82,8 +83,8 @@ class File(Base): # type: ignore
8283
paste_id = Column(ForeignKey("paste.id"))
8384
slug = Column(String(255), unique=True)
8485

85-
pub_date = Column(DateTime)
86-
chg_date = Column(DateTime)
86+
pub_date = Column(UtcDateTime)
87+
chg_date = Column(UtcDateTime)
8788

8889
lexer = Column(String(250))
8990

@@ -110,8 +111,8 @@ def __init__(
110111
f"Text exceeds size limit {configuration.paste_size//1024} (kB)"
111112
)
112113

113-
self.pub_date = datetime.datetime.utcnow()
114-
self.chg_date = datetime.datetime.utcnow()
114+
self.pub_date = datetime.datetime.now(timezone.utc)
115+
self.chg_date = datetime.datetime.now(timezone.utc)
115116

116117
self.raw = raw
117118

src/pinnwand/handler/api_deprecated.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from datetime import datetime, timedelta
2+
from datetime import datetime, timedelta, timezone
33
from typing import Any
44
from urllib.parse import urljoin
55

@@ -87,7 +87,7 @@ async def get(self, slug: str) -> None: # type: ignore
8787
if not paste:
8888
raise tornado.web.HTTPError(404)
8989

90-
if paste.exp_date < datetime.utcnow():
90+
if paste.exp_date < datetime.now(timezone.utc):
9191
session.delete(paste)
9292
session.commit()
9393

src/pinnwand/handler/api_v1.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from datetime import datetime, timedelta
2+
from datetime import datetime, timedelta, timezone
33
from typing import Any
44
from urllib.parse import urljoin
55

@@ -136,7 +136,7 @@ async def get(self, slug: str) -> None:
136136
if not paste:
137137
raise tornado.web.HTTPError(404)
138138

139-
if paste.exp_date < datetime.utcnow():
139+
if paste.exp_date < datetime.now(timezone.utc):
140140
session.delete(paste)
141141
session.commit()
142142

src/pinnwand/handler/website.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import binascii
22
import io
33
import zipfile
4-
from datetime import datetime
4+
from datetime import datetime, timezone
55
from typing import Any
66

77
import docutils.core
@@ -307,7 +307,7 @@ async def get(self, slug: str) -> None: # type: ignore
307307
if not paste:
308308
raise tornado.web.HTTPError(404)
309309

310-
if paste.exp_date < datetime.utcnow():
310+
if paste.exp_date < datetime.now(timezone.utc):
311311
session.delete(paste)
312312
session.commit()
313313

@@ -344,7 +344,7 @@ async def get(self, slug: str) -> None: # type: ignore
344344
if not paste:
345345
raise tornado.web.HTTPError(404)
346346

347-
if paste.exp_date < datetime.utcnow():
347+
if paste.exp_date < datetime.now(timezone.utc):
348348
session.delete(paste)
349349
session.commit()
350350

@@ -374,7 +374,7 @@ async def get(self, file_id: str) -> None: # type: ignore
374374
if not file:
375375
raise tornado.web.HTTPError(404)
376376

377-
if file.paste.exp_date < datetime.utcnow():
377+
if file.paste.exp_date < datetime.now(timezone.utc):
378378
session.delete(file.paste)
379379
session.commit()
380380

@@ -405,7 +405,7 @@ async def get(self, file_id: str) -> None: # type: ignore
405405
if not file:
406406
raise tornado.web.HTTPError(404)
407407

408-
if file.paste.exp_date < datetime.utcnow():
408+
if file.paste.exp_date < datetime.now(timezone.utc):
409409
session.delete(file.paste)
410410
session.commit()
411411

@@ -436,7 +436,7 @@ async def get(self, paste_id: str) -> None: # type: ignore
436436
if not paste:
437437
raise tornado.web.HTTPError(404)
438438

439-
if paste.exp_date < datetime.utcnow():
439+
if paste.exp_date < datetime.now(timezone.utc):
440440
session.delete(paste)
441441
session.commit()
442442

@@ -483,7 +483,7 @@ async def get(self, file_id: str) -> None: # type: ignore
483483
if not file:
484484
raise tornado.web.HTTPError(404)
485485

486-
if file.paste.exp_date < datetime.utcnow():
486+
if file.paste.exp_date < datetime.now(timezone.utc):
487487
session.delete(file.paste)
488488
session.commit()
489489

@@ -527,7 +527,7 @@ async def get(self, removal: str) -> None: # type: ignore
527527
log.info("RemovePaste.get: someone visited with invalid id")
528528
raise tornado.web.HTTPError(404)
529529

530-
if paste.exp_date < datetime.utcnow():
530+
if paste.exp_date < datetime.now(timezone.utc):
531531
session.delete(paste)
532532
session.commit()
533533

src/pinnwand/utility.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import math
22
import re
33
from base64 import b32encode
4-
from datetime import datetime
4+
from datetime import datetime, timezone
55
from os import urandom
66
from typing import Any, Dict, List, Optional
77

@@ -192,7 +192,7 @@ def reap() -> None:
192192
with manager.DatabaseManager.get_session() as session:
193193
pastes = (
194194
session.query(models.Paste)
195-
.filter(models.Paste.exp_date < datetime.utcnow())
195+
.filter(models.Paste.exp_date < datetime.now(timezone.utc))
196196
.all()
197197
)
198198

test/e2e/pinnwand.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
database_uri = "sqlite:///C:\\Users\\shtlrs\\AppData\\Local\\Temp\\tmpvb8tgs72"
2-
reaping_periodicity = 2000 # in milliseconds
1+
database_uri = "sqlite:////tmp/tmp5r3kq5tn"
2+
reaping_periodicity = 2000
33

44
[ratelimit.read]
55
capacity = 200

0 commit comments

Comments
 (0)