Skip to content

Commit dfecaaa

Browse files
committed
[PNE-7009] Expose locked metadata.
1 parent 67cc0d1 commit dfecaaa

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/citrine/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.21.0"
1+
__version__ = "3.22.0"

src/citrine/informatics/design_spaces/design_space.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ class DesignSpace(PolymorphicSerializable['DesignSpace'], AsynchronousObject):
2626
name = properties.String('data.name')
2727
description = properties.Optional(properties.String(), 'data.description')
2828

29+
locked_by = properties.Optional(properties.UUID, 'metadata.locked.user',
30+
serializable=False)
31+
""":Optional[UUID]: id of the user whose action cause the design space to
32+
be locked, if it is locked"""
33+
lock_time = properties.Optional(properties.Datetime, 'metadata.locked.time',
34+
serializable=False)
35+
""":Optional[datetime]: date and time at which the resource was locked,
36+
if it is locked"""
37+
2938
@staticmethod
3039
def wrap_instance(subspace_data: dict) -> dict:
3140
"""Insert a serialized embedded design space into an entity envelope.
@@ -65,6 +74,11 @@ def get_type(cls, data) -> Type[Serializable]:
6574
'HierarchicalDesignSpace': HierarchicalDesignSpace
6675
}[data['data']['instance']['type']]
6776

77+
@property
78+
def is_locked(self) -> bool:
79+
"""If is_locked is true, edits to the design space will be rejected."""
80+
return self.locked_by is not None
81+
6882
@property
6983
def sample_design_space_executions(self):
7084
"""Start a Sample Design Space Execution using the current Design Space."""

tests/resources/test_design_space.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import random
12
import uuid
23
from copy import deepcopy
3-
import random
4+
from datetime import datetime, timezone
45

56
import mock
67
import pytest
@@ -534,3 +535,31 @@ def test_carrying_settings_from_get(valid_product_design_space):
534535

535536
assert session.num_calls == 3
536537
assert session.calls[1] == expected_call
538+
539+
540+
def test_locked(valid_product_design_space_data):
541+
session = FakeSession()
542+
collection = DesignSpaceCollection(project_id=uuid.uuid4(), session=session)
543+
544+
session.set_response(deepcopy(valid_product_design_space_data))
545+
546+
ds = collection.get(uuid.uuid4())
547+
548+
assert not ds.is_locked
549+
assert ds.locked_by is None
550+
assert ds.lock_time is None
551+
552+
lock_user = uuid.uuid4()
553+
lock_time = datetime(2020, 4, 23, 15, 46, 23, tzinfo=timezone.utc)
554+
lock_timestamp = int(lock_time.timestamp()) * 1000
555+
556+
response_data = deepcopy(valid_product_design_space_data)
557+
response_data['metadata']['locked'] = {'user': str(lock_user), 'time': lock_timestamp}
558+
559+
session.set_response(response_data)
560+
561+
ds = collection.get(uuid.uuid4())
562+
563+
assert ds.is_locked
564+
assert ds.locked_by == lock_user
565+
assert ds.lock_time == lock_time

0 commit comments

Comments
 (0)