Skip to content

Commit fd0a92f

Browse files
Panaetiusjsam
authored andcommitted
hotfix: datasetfile dates (#673)
* Changes datasetfile's added date to get parsed as datetime with timezone * Puts datetime logic into utils and make Project dates load as datetime * test: added migration support and test
1 parent 44183e6 commit fd0a92f

File tree

4 files changed

+53
-13
lines changed

4 files changed

+53
-13
lines changed

renku/models/datasets.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525

2626
import attr
2727
from attr.validators import instance_of
28-
from dateutil.parser import parse as parse_date
2928

3029
from renku import errors
3130
from renku._compat import Path
3231
from renku.models.provenance.entities import Entity
32+
from renku.utils.datetime8601 import parse_date
3333
from renku.utils.doi import is_doi
3434

3535
from . import _jsonld as jsonld
@@ -193,7 +193,9 @@ class DatasetFile(Entity, CreatorsMixin):
193193
context='schema:creator'
194194
)
195195

196-
added = jsonld.ib(context='schema:dateCreated', kw_only=True)
196+
added = jsonld.ib(
197+
converter=parse_date, context='schema:dateCreated', kw_only=True
198+
)
197199

198200
checksum = attr.ib(default=None, kw_only=True)
199201

@@ -241,13 +243,6 @@ def __attrs_post_init__(self):
241243
self.name = self.filename
242244

243245

244-
def _parse_date(value):
245-
"""Convert date to datetime."""
246-
if isinstance(value, datetime.datetime):
247-
return value
248-
return parse_date(value)
249-
250-
251246
def _convert_dataset_files(value):
252247
"""Convert dataset files."""
253248
coll = value
@@ -357,7 +352,7 @@ class Dataset(Entity, CreatorsMixin):
357352
version = jsonld.ib(default=None, context='schema:version', kw_only=True)
358353

359354
created = jsonld.ib(
360-
converter=_parse_date, context='schema:dateCreated', kw_only=True
355+
converter=parse_date, context='schema:dateCreated', kw_only=True
361356
)
362357

363358
files = jsonld.container.list(

renku/models/projects.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
import datetime
2121

22+
import pytz
23+
24+
from renku.utils.datetime8601 import parse_date
25+
2226
from . import _jsonld as jsonld
2327
from ._datastructures import Collection
2428

@@ -38,8 +42,14 @@ class Project(object):
3842
"""Represent a project."""
3943

4044
name = jsonld.ib(default=None, context='foaf:name')
41-
created = jsonld.ib(context='http://schema.org/dateCreated', )
42-
updated = jsonld.ib(context='http://schema.org/dateUpdated', )
45+
created = jsonld.ib(
46+
converter=parse_date,
47+
context='http://schema.org/dateCreated',
48+
)
49+
updated = jsonld.ib(
50+
converter=parse_date,
51+
context='http://schema.org/dateUpdated',
52+
)
4353
version = jsonld.ib(
4454
converter=str,
4555
default='1',
@@ -52,6 +62,14 @@ def _now(self):
5262
"""Define default value for datetime fields."""
5363
return datetime.datetime.now(datetime.timezone.utc)
5464

65+
def __attrs_post_init__(self):
66+
"""Initialize computed attributes."""
67+
if self.created and self.created.tzinfo is None:
68+
self.created = pytz.utc.localize(self.created)
69+
70+
if self.updated and self.updated.tzinfo is None:
71+
self.updated = pytz.utc.localize(self.updated)
72+
5573

5674
class ProjectCollection(Collection):
5775
"""Represent projects on the server.

renku/utils/datetime8601.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818
"""Renku datetime utilities."""
19+
import datetime
1920
import re
2021

22+
from dateutil.parser import parse as dateutil_parse_date
23+
2124
regex = (
2225
r'^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12]['
2326
r'0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|['
@@ -34,3 +37,16 @@ def validate_iso8601(str_val):
3437
except re.error:
3538
pass
3639
return False
40+
41+
42+
def parse_date(value):
43+
"""Convert date to datetime."""
44+
if isinstance(value, datetime.datetime):
45+
return value
46+
date = dateutil_parse_date(value)
47+
if not date.tzinfo:
48+
# set timezone to local timezone
49+
tz = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
50+
date = date.replace(tzinfo=tz)
51+
52+
return date

tests/test_projects.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# limitations under the License.
1818
"""Test projects API."""
1919

20-
from datetime import timezone
20+
from datetime import datetime, timezone
2121

2222
import yaml
2323
from freezegun import freeze_time
@@ -68,3 +68,14 @@ def test_project_metadata_compatibility():
6868

6969
assert project.name == 'demo'
7070
assert project.version == '1'
71+
72+
73+
def test_project_datetime_loading():
74+
"""Check that datetime is correctly loaded."""
75+
project = Project.from_jsonld(yaml.safe_load(PROJECT_V1))
76+
77+
assert isinstance(project.updated, datetime)
78+
assert isinstance(project.created, datetime)
79+
80+
assert project.updated.tzinfo is not None
81+
assert project.created.tzinfo is not None

0 commit comments

Comments
 (0)