1
1
from __future__ import annotations
2
- from dataclasses import dataclass , field
3
- from dataclasses_json .cfg import config
2
+ from typing import Optional
3
+
4
+ from attr import define , field
4
5
5
6
import cellengine as ce
6
- from cellengine .utils .dataclass_mixin import DataClassMixin , ReadOnly
7
+ from cellengine .utils import converter , readonly
8
+
7
9
10
+ try :
11
+ from typing import Literal
12
+ except ImportError :
13
+ from typing_extensions import Literal
8
14
9
- @dataclass
10
- class Attachment (DataClassMixin ):
15
+
16
+ @define
17
+ class Attachment :
11
18
"""A class representing a CellEngine attachment.
12
19
Attachments are non-data files that are stored in an experiment.
13
20
"""
14
21
22
+ _id : str = field (on_setattr = readonly )
15
23
filename : str
16
- _id : str = field (
17
- metadata = config (field_name = "_id" ), default = ReadOnly ()
18
- ) # type: ignore
19
- crc32c : str = field (repr = False , default = ReadOnly ()) # type: ignore
20
- experiment_id : str = field (repr = False , default = ReadOnly ()) # type: ignore
21
- md5 : str = field (repr = False , default = ReadOnly ()) # type: ignore
22
- size : int = field (repr = False , default = ReadOnly ()) # type: ignore
24
+ crc32c : str = field (on_setattr = readonly , repr = False )
25
+ experiment_id : str = field (on_setattr = readonly , repr = False )
26
+ md5 : str = field (on_setattr = readonly , repr = False )
27
+ size : int = field (on_setattr = readonly , repr = False )
28
+ grid_id : Optional [str ] = None
29
+ type : Optional [Literal ["textbox" , "image" ]] = None
30
+
31
+ @property
32
+ def client (self ):
33
+ return ce .APIClient ()
34
+
35
+ @property
36
+ def path (self ):
37
+ return f"experiments/{ self .experiment_id } /attachments/{ self ._id } " .rstrip (
38
+ "/None"
39
+ )
23
40
24
41
@classmethod
25
42
def get (cls , experiment_id : str , _id : str = None , name : str = None ) -> Attachment :
@@ -39,20 +56,20 @@ def upload(experiment_id: str, filepath: str, filename: str = None) -> Attachmen
39
56
return ce .APIClient ().upload_attachment (experiment_id , filepath , filename )
40
57
41
58
def update (self ):
42
- """Save changes to this Attachment to CellEngine.
59
+ """Save changes to this Attachment to CellEngine."""
60
+ res = self .client .update (self )
61
+ self .__setstate__ (res .__getstate__ ()) # type: ignore
43
62
44
- Returns:
45
- None: Updates the Attachment on CellEngine and synchronizes the
46
- local Attachment object properties with remote state.
47
- """
48
- res = ce .APIClient ().update_entity (
49
- self .experiment_id , self ._id , "attachments" , body = self .to_dict ()
50
- )
51
- self .__dict__ .update (Attachment .from_dict (res ).__dict__ )
63
+ @classmethod
64
+ def from_dict (cls , data : dict ):
65
+ return converter .structure (data , cls )
52
66
53
- def delete (self ):
54
- """Delete this attachment."""
55
- return ce .APIClient ().delete_entity (self .experiment_id , "attachments" , self ._id )
67
+ def to_dict (self ):
68
+ return converter .unstructure (self )
69
+
70
+ def asdict (self ):
71
+ """Force use of cattrs"""
72
+ return self .to_dict ()
56
73
57
74
def download (self , to_file : str = None ):
58
75
"""Download the attachment.
@@ -74,3 +91,6 @@ def download(self, to_file: str = None):
74
91
f .write (res )
75
92
else :
76
93
return res
94
+
95
+ def delete (self ):
96
+ return self .client .delete_entity (self .experiment_id , "attachments" , self ._id )
0 commit comments