logs-py 1.14__py3-none-any.whl → 2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of logs-py might be problematic. Click here for more details.

Files changed (90) hide show
  1. LOGS/Auxiliary/Constants.py +2 -2
  2. LOGS/Auxiliary/DateTimeConverter.py +1 -1
  3. LOGS/Auxiliary/Exceptions.py +1 -1
  4. LOGS/Auxiliary/MinimalModelGenerator.py +28 -6
  5. LOGS/Auxiliary/Tools.py +4 -0
  6. LOGS/Entities/AutoloadClientInfo.py +6 -8
  7. LOGS/Entities/AutoloadStatus.py +3 -3
  8. LOGS/Entities/{AutoloadSource.py → Bridge.py} +11 -10
  9. LOGS/Entities/BridgeMinimal.py +8 -0
  10. LOGS/Entities/BridgeRelations.py +23 -0
  11. LOGS/Entities/BridgeRequestParameter.py +19 -0
  12. LOGS/Entities/{AutoloadSourceType.py → BridgeType.py} +1 -1
  13. LOGS/Entities/Bridges.py +12 -0
  14. LOGS/Entities/{AutoloadConfiguration.py → DataSource.py} +97 -23
  15. LOGS/Entities/DataSourceMinimal.py +8 -0
  16. LOGS/Entities/DataSourceRelations.py +23 -0
  17. LOGS/Entities/DataSourceRequestParameter.py +44 -0
  18. LOGS/Entities/{AutoloadConfigurationStatus.py → DataSourceStatus.py} +1 -1
  19. LOGS/Entities/DataSources.py +12 -0
  20. LOGS/Entities/Dataset.py +83 -71
  21. LOGS/Entities/DatasetCreator.py +38 -18
  22. LOGS/Entities/DatasetMatchTypes.py +38 -6
  23. LOGS/Entities/DatasetRelations.py +13 -2
  24. LOGS/Entities/DatasetRequestParameter.py +19 -7
  25. LOGS/Entities/Datasets.py +1 -1
  26. LOGS/Entities/Document.py +2 -2
  27. LOGS/Entities/Experiment.py +9 -24
  28. LOGS/Entities/ExperimentRelations.py +23 -0
  29. LOGS/Entities/ExperimentRequestParameter.py +27 -2
  30. LOGS/Entities/Format.py +27 -61
  31. LOGS/Entities/FormatFormat.py +8 -6
  32. LOGS/Entities/FormatInstrument.py +2 -2
  33. LOGS/Entities/FormatMetaData.py +13 -5
  34. LOGS/Entities/FormatMethod.py +34 -3
  35. LOGS/Entities/FormatMinimal.py +11 -1
  36. LOGS/Entities/FormatRequestParameter.py +8 -3
  37. LOGS/Entities/FormatVendor.py +14 -1
  38. LOGS/Entities/FormatVendorRequestParameter.py +1 -0
  39. LOGS/Entities/ICustomSchemaRequest.py +7 -0
  40. LOGS/Entities/IRelatedEntityRequest.py +9 -0
  41. LOGS/Entities/Instrument.py +16 -2
  42. LOGS/Entities/InstrumentRelations.py +23 -0
  43. LOGS/Entities/InstrumentRequestParameter.py +34 -2
  44. LOGS/Entities/LabNotebookEntry.py +67 -7
  45. LOGS/Entities/LabNotebookEntryRelations.py +81 -0
  46. LOGS/Entities/LabNotebookEntryRequestParameter.py +57 -2
  47. LOGS/Entities/Method.py +24 -2
  48. LOGS/Entities/MethodRelations.py +35 -0
  49. LOGS/Entities/MethodRequestParameter.py +35 -1
  50. LOGS/Entities/Origin.py +2 -2
  51. LOGS/Entities/OriginRequestParameter.py +3 -3
  52. LOGS/Entities/Person.py +34 -3
  53. LOGS/Entities/PersonRelations.py +36 -3
  54. LOGS/Entities/PersonRequestParameter.py +50 -10
  55. LOGS/Entities/Project.py +15 -2
  56. LOGS/Entities/ProjectRelations.py +11 -0
  57. LOGS/Entities/ProjectRequestParameter.py +44 -3
  58. LOGS/Entities/Role.py +45 -16
  59. LOGS/Entities/RoleRelations.py +23 -0
  60. LOGS/Entities/RoleRequestParameter.py +28 -1
  61. LOGS/Entities/Sample.py +26 -32
  62. LOGS/Entities/SampleRelations.py +4 -2
  63. LOGS/Entities/SampleRequestParameter.py +5 -10
  64. LOGS/Entities/__init__.py +8 -7
  65. LOGS/Entity/Entity.py +30 -6
  66. LOGS/Entity/EntityRelations.py +3 -2
  67. LOGS/Entity/EntityRequestParameter.py +10 -5
  68. LOGS/Entity/EntityWithIntId.py +1 -1
  69. LOGS/Entity/SerializeableContent.py +10 -4
  70. LOGS/Interfaces/ICreationRecord.py +12 -3
  71. LOGS/Interfaces/IModificationRecord.py +10 -1
  72. LOGS/Interfaces/IProjectBased.py +30 -0
  73. LOGS/Interfaces/IRelatedEntity.py +34 -0
  74. LOGS/Interfaces/IRelationModel.py +6 -0
  75. LOGS/Interfaces/IRelationRequest.py +12 -0
  76. LOGS/Interfaces/ITypedEntity.py +28 -0
  77. LOGS/Interfaces/IUniqueEntity.py +2 -3
  78. LOGS/LOGS.py +128 -40
  79. LOGS/LOGSConnection.py +2 -1
  80. {logs_py-1.14.dist-info → logs_py-2.1.dist-info}/METADATA +1 -1
  81. {logs_py-1.14.dist-info → logs_py-2.1.dist-info}/RECORD +84 -70
  82. LOGS/Entities/AutoloadConfigurationMinimal.py +0 -8
  83. LOGS/Entities/AutoloadConfigurationRequestParameter.py +0 -17
  84. LOGS/Entities/AutoloadConfigurations.py +0 -16
  85. LOGS/Entities/AutoloadSourceMinimal.py +0 -8
  86. LOGS/Entities/AutoloadSourceRequestParameter.py +0 -13
  87. LOGS/Entities/AutoloadSources.py +0 -12
  88. /LOGS/Interfaces/{ICustomFields.py → ICustomField.py} +0 -0
  89. {logs_py-1.14.dist-info → logs_py-2.1.dist-info}/WHEEL +0 -0
  90. {logs_py-1.14.dist-info → logs_py-2.1.dist-info}/top_level.txt +0 -0
LOGS/Entities/Role.py CHANGED
@@ -1,19 +1,50 @@
1
- from typing import TYPE_CHECKING, List, Optional
1
+ from typing import TYPE_CHECKING, Optional
2
2
 
3
3
  from LOGS.Auxiliary.Decorators import Endpoint
4
- from LOGS.Auxiliary.MinimalModelGenerator import MinimalFromList
5
- from LOGS.Entity.EntityWithIntId import EntityWithIntId
4
+ from LOGS.Entities.RoleRelations import RoleRelations
5
+ from LOGS.Entity.EntityWithIntId import IEntityWithIntId
6
+ from LOGS.Interfaces.ICreationRecord import ICreationRecord
7
+ from LOGS.Interfaces.IModificationRecord import IModificationRecord
6
8
  from LOGS.Interfaces.INamedEntity import INamedEntity
7
- from LOGS.Interfaces.IUniqueEntity import IUniqueEntity
9
+ from LOGS.Interfaces.IRelatedEntity import IRelatedEntity
10
+ from LOGS.LOGSConnection import LOGSConnection
8
11
 
9
12
  if TYPE_CHECKING:
10
- from LOGS.Entities.PersonMinimal import PersonMinimal
13
+ pass
11
14
 
12
15
 
13
16
  @Endpoint("roles")
14
- class Role(INamedEntity, EntityWithIntId, IUniqueEntity):
17
+ class Role(
18
+ IEntityWithIntId,
19
+ INamedEntity,
20
+ ICreationRecord,
21
+ IModificationRecord,
22
+ IRelatedEntity[RoleRelations],
23
+ ):
24
+ _relationType = type(RoleRelations)
25
+
26
+ _roleId: Optional[str] = None
15
27
  _description: Optional[str] = None
16
- _users: Optional[List["PersonMinimal"]]
28
+ _isDefault: Optional[bool]
29
+
30
+ def __init__(
31
+ self,
32
+ ref=None,
33
+ id: Optional[int] = None,
34
+ connection: Optional[LOGSConnection] = None,
35
+ ):
36
+ if isinstance(ref, str):
37
+ ref = {"roleId": ref}
38
+
39
+ super().__init__(ref=ref, id=id, connection=connection)
40
+
41
+ @property
42
+ def roleId(self) -> Optional[str]:
43
+ return self._roleId
44
+
45
+ @roleId.setter
46
+ def roleId(self, value):
47
+ self._roleId = self.checkAndConvertNullable(value, str, "roleId")
17
48
 
18
49
  @property
19
50
  def description(self) -> Optional[str]:
@@ -21,14 +52,12 @@ class Role(INamedEntity, EntityWithIntId, IUniqueEntity):
21
52
 
22
53
  @description.setter
23
54
  def description(self, value):
24
- self._description = self.checkAndConvertNullable(value, str, "fullName")
55
+ self._description = self.checkAndConvertNullable(value, str, "description")
25
56
 
26
57
  @property
27
- def users(self) -> Optional[List["PersonMinimal"]]:
28
- return self._users
29
-
30
- @users.setter
31
- def users(self, value):
32
- self._users = MinimalFromList(
33
- value, "PersonMinimal", "users", connection=self.connection
34
- )
58
+ def isDefault(self) -> Optional[bool]:
59
+ return self._isDefault
60
+
61
+ @isDefault.setter
62
+ def isDefault(self, value):
63
+ self._isDefault = self.checkAndConvertNullable(value, bool, "isDefault")
@@ -0,0 +1,23 @@
1
+ from typing import TYPE_CHECKING, Optional
2
+
3
+ from LOGS.Entity.EntityRelation import EntityRelation
4
+ from LOGS.Entity.EntityRelations import EntityRelations
5
+
6
+ if TYPE_CHECKING:
7
+ from LOGS.Entities.Person import Person
8
+
9
+
10
+ class RoleRelations(EntityRelations):
11
+ """Relations of a Role with other entities"""
12
+
13
+ _persons: Optional[EntityRelation["Person"]] = None
14
+
15
+ @property
16
+ def persons(self) -> Optional[EntityRelation["Person"]]:
17
+ return self._persons
18
+
19
+ @persons.setter
20
+ def persons(self, value):
21
+ from LOGS.Entities.Persons import Persons
22
+
23
+ self._persons = self._entityConverter(value, Persons)
@@ -1,9 +1,36 @@
1
1
  from dataclasses import dataclass
2
+ from enum import Enum
2
3
  from typing import Optional
3
4
 
5
+ from LOGS.Entities.IRelatedEntityRequest import IRelatedEntityRequest
4
6
  from LOGS.Entity.EntityRequestParameter import EntityRequestParameter
7
+ from LOGS.Interfaces.ICreationRecord import ICreationRecordRequest
8
+ from LOGS.Interfaces.IModificationRecord import IModificationRecordRequest
9
+
10
+
11
+ class RoleOrder(Enum):
12
+ ID_ASC = "ID_ASC"
13
+ ID_DESC = "ID_DESC"
14
+ NAME_ASC = "NAME_ASC"
15
+ NAME_DESC = "NAME_DESC"
16
+ IS_INTERNAL_ASC = "IS_INTERNAL_ASC"
17
+ IS_INTERNAL_DESC = "IS_INTERNAL_DESC"
18
+ CREATED_ON_ASC = "CREATED_ON_ASC"
19
+ CREATED_ON_DESC = "CREATED_ON_DESC"
20
+ CREATED_BY_ASC = "CREATED_BY_ASC"
21
+ CREATED_BY_DESC = "CREATED_BY_DESC"
22
+ MODIFIED_ON_ASC = "MODIFIED_ON_ASC"
23
+ MODIFIED_ON_DESC = "MODIFIED_ON_DESC"
24
+ MODIFIED_BY_ASC = "MODIFIED_BY_ASC"
25
+ MODIFIED_BY_DESC = "MODIFIED_BY_DESC"
5
26
 
6
27
 
7
28
  @dataclass
8
- class RoleRequestParameter(EntityRequestParameter):
29
+ class RoleRequestParameter(
30
+ EntityRequestParameter[RoleOrder],
31
+ IRelatedEntityRequest,
32
+ ICreationRecordRequest,
33
+ IModificationRecordRequest,
34
+ ):
9
35
  name: Optional[str] = None
36
+ roleId: Optional[str] = None
LOGS/Entities/Sample.py CHANGED
@@ -8,11 +8,13 @@ from LOGS.Auxiliary.MinimalModelGenerator import (
8
8
  )
9
9
  from LOGS.Entities.SampleRelations import SampleRelations
10
10
  from LOGS.Entities.SampleTypeMinimal import SampleTypeMinimal
11
- from LOGS.Entity.EntityWithIntId import EntityWithIntId
12
- from LOGS.Interfaces.ICustomFields import ICustomFields
11
+ from LOGS.Entity.EntityWithIntId import IEntityWithIntId
13
12
  from LOGS.Interfaces.INamedEntity import INamedEntity
14
13
  from LOGS.Interfaces.IOwnedEntity import IOwnedEntity
14
+ from LOGS.Interfaces.IProjectBased import IProjectBased
15
+ from LOGS.Interfaces.IRelatedEntity import IRelatedEntity
15
16
  from LOGS.Interfaces.ISoftDeletable import ISoftDeletable
17
+ from LOGS.Interfaces.ITypedEntity import ITypedEntity
16
18
  from LOGS.Interfaces.IUniqueEntity import IUniqueEntity
17
19
  from LOGS.LOGSConnection import LOGSConnection
18
20
 
@@ -24,24 +26,26 @@ if TYPE_CHECKING:
24
26
 
25
27
  @Endpoint("samples")
26
28
  class Sample(
27
- INamedEntity,
28
- EntityWithIntId,
29
+ IProjectBased,
30
+ IEntityWithIntId,
31
+ IRelatedEntity[SampleRelations],
32
+ ITypedEntity,
29
33
  IUniqueEntity,
30
34
  IOwnedEntity,
31
- ICustomFields,
32
35
  ISoftDeletable,
36
+ INamedEntity,
33
37
  ):
38
+ _relationType = type(SampleRelations)
39
+
34
40
  _type: Optional[SampleTypeMinimal]
35
41
  _fullName: Optional[str] = None
36
42
  _createdAt: Optional[datetime]
37
43
  _preparedAt: Optional[datetime]
38
44
  _discardedAt: Optional[datetime]
39
- _projects: Optional[List["ProjectMinimal"]]
40
45
  _preparedBy: Optional[List["PersonMinimal"]]
41
46
  _discardedBy: Optional[List["PersonMinimal"]]
42
47
  _other: Optional[str]
43
48
  _notes: Optional[str]
44
- _relations: Optional[SampleRelations]
45
49
  _tags: Optional[Dict[str, Union[str, int, float]]]
46
50
 
47
51
  def __init__(
@@ -148,15 +152,15 @@ class Sample(
148
152
  # def discarders(self, value):
149
153
  # self._discarders = self.checkAndConvertNullable(value, List, "discarders")
150
154
 
151
- @property
152
- def projects(self) -> Optional[List["ProjectMinimal"]]:
153
- return self._projects
155
+ # @property
156
+ # def projects(self) -> Optional[List["ProjectMinimal"]]:
157
+ # return self._projects
154
158
 
155
- @projects.setter
156
- def projects(self, value):
157
- self._projects = MinimalFromList(
158
- value, "ProjectMinimal", "projects", connection=self.connection
159
- )
159
+ # @projects.setter
160
+ # def projects(self, value):
161
+ # self._projects = MinimalFromList(
162
+ # value, "ProjectMinimal", "projects", connection=self.connection
163
+ # )
160
164
 
161
165
  # @property
162
166
  # def documents(self) -> List[Document]:
@@ -194,16 +198,6 @@ class Sample(
194
198
  def notes(self, value):
195
199
  self._notes = self.checkAndConvertNullable(value, str, "notes")
196
200
 
197
- @property
198
- def relations(self) -> Optional[SampleRelations]:
199
- return self._relations
200
-
201
- @relations.setter
202
- def relations(self, value):
203
- self._relations = self.checkAndConvertNullable(
204
- value, SampleRelations, "relations"
205
- )
206
-
207
201
  @property
208
202
  def tags(self) -> Optional[Dict[str, Union[str, int, float]]]:
209
203
  return self._tags
@@ -211,11 +205,11 @@ class Sample(
211
205
  @tags.setter
212
206
  def tags(self, value):
213
207
  self._tags = self.checkAndConvertNullable(value, dict, "tags")
214
- self._tags = {
215
- str(k): v
216
- for k, v in self._tags.items()
217
- if v is not None and k != "Name" and isinstance(v, (str, int, float))
218
- }
219
-
220
- if not self._tags:
208
+ if self._tags:
209
+ self._tags = {
210
+ str(k): v
211
+ for k, v in self._tags.items()
212
+ if v is not None and k != "Name" and isinstance(v, (str, int, float))
213
+ }
214
+ else:
221
215
  self._tags = None
@@ -1,7 +1,5 @@
1
1
  from typing import TYPE_CHECKING, Optional
2
2
 
3
- from LOGS.Entities.Datasets import Datasets
4
- from LOGS.Entities.Documents import Documents
5
3
  from LOGS.Entity.EntityRelation import EntityRelation
6
4
  from LOGS.Entity.EntityRelations import EntityRelations
7
5
 
@@ -23,6 +21,8 @@ class SampleRelations(EntityRelations):
23
21
 
24
22
  @documents.setter
25
23
  def documents(self, value):
24
+ from LOGS.Entities.Documents import Documents
25
+
26
26
  self._documents = self._entityConverter(value, Documents)
27
27
 
28
28
  @property
@@ -31,6 +31,8 @@ class SampleRelations(EntityRelations):
31
31
 
32
32
  @datasets.setter
33
33
  def datasets(self, value):
34
+ from LOGS.Entities.Datasets import Datasets
35
+
34
36
  self._datasets = self._entityConverter(value, Datasets)
35
37
 
36
38
  @property
@@ -4,11 +4,11 @@ from enum import Enum
4
4
  from typing import List, Optional
5
5
 
6
6
  from LOGS.Entity.EntityRequestParameter import EntityRequestParameter
7
- from LOGS.Interfaces.ICustomFields import ICustomFieldsRequest
8
7
  from LOGS.Interfaces.INamedEntity import INamedEntityRequest
9
8
  from LOGS.Interfaces.IOwnedEntity import IOwnedEntityRequest
10
9
  from LOGS.Interfaces.IPaginationRequest import IPaginationRequest
11
10
  from LOGS.Interfaces.ISoftDeletable import ISoftDeletableRequest
11
+ from LOGS.Interfaces.ITypedEntity import ITypedEntityRequest
12
12
 
13
13
 
14
14
  class SampleOrder(Enum):
@@ -20,23 +20,19 @@ class SampleOrder(Enum):
20
20
  PREPARATION_DATE_DESC = "PREPARATION_DATE_DESC"
21
21
  NAME_ASC = "NAME_ASC"
22
22
  NAME_DESC = "NAME_DESC"
23
- SAMPLE_TYPE_ASC = "SAMPLE_TYPE_ASC"
24
- SAMPLE_TYPE_DESC = "SAMPLE_TYPE_DESC"
23
+ TYPE_ASC = "TYPE_ASC"
24
+ TYPE_DESC = "TYPE_DESC"
25
25
 
26
26
 
27
27
  @dataclass
28
28
  class SampleRequestParameter(
29
- EntityRequestParameter,
29
+ EntityRequestParameter[SampleOrder],
30
30
  IPaginationRequest,
31
31
  IOwnedEntityRequest,
32
- ICustomFieldsRequest,
32
+ ITypedEntityRequest,
33
33
  INamedEntityRequest,
34
34
  ISoftDeletableRequest,
35
35
  ):
36
- includePermissions: Optional[bool] = None
37
- includeRelationLink: Optional[bool] = None
38
- includeRelationCount: Optional[bool] = None
39
-
40
36
  projectIds: Optional[List[int]] = None
41
37
  organizationIds: Optional[List[int]] = None
42
38
  preparedByIds: Optional[List[int]] = None
@@ -48,4 +44,3 @@ class SampleRequestParameter(
48
44
  preparedAtFrom: Optional[datetime] = None
49
45
  preparedAtTo: Optional[datetime] = None
50
46
  includeTags: Optional[bool] = None
51
- orderBy: Optional[SampleOrder] = None
LOGS/Entities/__init__.py CHANGED
@@ -7,15 +7,13 @@
7
7
  Permission to use this libraray and all of its contents is
8
8
  strictly permitted to the Signals Company.
9
9
  """
10
+
10
11
  from .AutoloadClientInfo import *
11
- from .AutoloadConfiguration import *
12
- from .AutoloadConfigurationMinimal import *
13
- from .AutoloadConfigurationRequestParameter import *
14
- from .AutoloadSource import *
15
- from .AutoloadSourceMinimal import *
16
- from .AutoloadSourceRequestParameter import *
17
- from .AutoloadSourceType import *
18
12
  from .AxisNaming import *
13
+ from .Bridge import *
14
+ from .BridgeMinimal import *
15
+ from .BridgeRequestParameter import *
16
+ from .BridgeType import *
19
17
  from .CustomSchema import *
20
18
  from .Dataset import *
21
19
  from .DatasetCreator import *
@@ -29,6 +27,9 @@ from .Datasets import *
29
27
  from .DatasetType import *
30
28
  from .DatasetTypeMinimal import *
31
29
  from .DatasetUploadParameter import *
30
+ from .DataSource import *
31
+ from .DataSourceMinimal import *
32
+ from .DataSourceRequestParameter import *
32
33
  from .Datatrack import *
33
34
  from .DatatrackNumericArray import *
34
35
  from .Document import *
LOGS/Entity/Entity.py CHANGED
@@ -91,6 +91,28 @@ class Entity(ConnectedEntity):
91
91
  def fetch(self):
92
92
  self._fetchEntity(self._getConnection())
93
93
 
94
+ def _restoreEntity(self, connection: LOGSConnection):
95
+ if not self._endpoint:
96
+ raise NotImplementedError(
97
+ "Updating of entity type %a is not implemented."
98
+ % (
99
+ type(self).__name__
100
+ if type(self).__name__ != Entity.__name__
101
+ else "unknown"
102
+ )
103
+ )
104
+
105
+ if not self.id:
106
+ raise EntityNotFoundException(self)
107
+
108
+ data, errors = connection.postEndpoint(
109
+ self._endpoint + ["restore", self.id], data=self.toDict()
110
+ )
111
+ if errors:
112
+ raise EntityUpdatingException(entity=self, errors=errors)
113
+
114
+ self.override(data)
115
+
94
116
  def _updateEntity(self, connection: LOGSConnection):
95
117
  if not self._endpoint:
96
118
  raise NotImplementedError(
@@ -130,6 +152,9 @@ class Entity(ConnectedEntity):
130
152
  _, error = connection.deleteEndpoint(
131
153
  self._endpoint + [self.id], parameters={"deletePermanently": permanently}
132
154
  )
155
+ if hasattr(self, "isDeleted"):
156
+ self.isDeleted = True
157
+
133
158
  if permanently:
134
159
  self.connection = None
135
160
 
@@ -148,6 +173,9 @@ class Entity(ConnectedEntity):
148
173
  def update(self):
149
174
  self._updateEntity(self._getConnection())
150
175
 
176
+ def restore(self):
177
+ self._restoreEntity(self._getConnection())
178
+
151
179
  def delete(self, permanently: bool = False):
152
180
  self._deleteEntity(self._getConnection(), permanently=permanently)
153
181
 
@@ -158,17 +186,13 @@ class Entity(ConnectedEntity):
158
186
 
159
187
  @property
160
188
  def identifier(self):
161
- name = self.name
189
+ name = f"'{getattr(self, 'name')}'" if hasattr(self, "name") else None
162
190
  return "%s(id:%s)%s" % (
163
191
  type(self).__name__,
164
192
  str(self.id),
165
- "'" + name + "'" if name else "",
193
+ name,
166
194
  )
167
195
 
168
- @property
169
- def name(self):
170
- return getattr(self, "_name") if hasattr(self, "_name") else None
171
-
172
196
  @property
173
197
  def id(self):
174
198
  return self._id
@@ -3,15 +3,16 @@ from typing import Any, Optional, Type, cast
3
3
  from LOGS.Entity.ConnectedEntity import ConnectedEntity
4
4
  from LOGS.Entity.EntityConnector import EntityConnector
5
5
  from LOGS.Entity.EntityRelation import EntityRelation
6
+ from LOGS.Interfaces.IRelationModel import IRelationModel
6
7
  from LOGS.LOGSConnection import LOGSConnection
7
8
 
8
9
 
9
- class EntityRelations(ConnectedEntity):
10
+ class EntityRelations(ConnectedEntity, IRelationModel):
10
11
  def _entityConverter(self, ref: Any, entityConnector: Type[EntityConnector]):
11
12
  result = self.checkAndConvertNullable(
12
13
  ref, EntityRelation, fieldName=type(entityConnector).__name__.lower()
13
14
  )
14
- result._entities = entityConnector(connection=self._connection)
15
+ result._entities = cast(Any, entityConnector(connection=self._connection))
15
16
  result._entities._firstUrl = result.link
16
17
  return result
17
18
 
@@ -1,22 +1,27 @@
1
1
  from dataclasses import dataclass
2
2
  from enum import Enum
3
- from typing import Any, List, Optional, Union
3
+ from typing import Generic, List, Optional, TypeVar, Union
4
4
 
5
5
  from LOGS.Entity.SerializeableContent import SerializeableClass
6
6
  from LOGS.Interfaces.IPaginationRequest import IPaginationRequest
7
7
 
8
8
 
9
9
  class DefaultOrder(Enum):
10
- id: Any = "id"
11
- name: Any = "name"
10
+ ID_ASC = "ID_ASC"
11
+ ID_DESC = "ID_DESC"
12
+ NAME_ASC = "NAME_ASC"
13
+ NAME_DESC = "NAME_DESC"
14
+
15
+
16
+ _Sorting = TypeVar("_Sorting", bound=Enum)
12
17
 
13
18
 
14
19
  @dataclass
15
- class EntityRequestParameter(SerializeableClass, IPaginationRequest):
20
+ class EntityRequestParameter(Generic[_Sorting], SerializeableClass, IPaginationRequest):
16
21
  _noSerialize = ["asString"]
17
22
  excludeIds: Optional[Union[List[int], List[str]]] = None
18
23
  searchTerm: Optional[str] = None
19
24
  ids: Optional[Union[List[int], List[str]]] = None
20
25
  includeCount: Optional[bool] = None
21
26
  includeRelations: Optional[bool] = True
22
- orderby: Any = None
27
+ orderby: Optional[_Sorting] = None
@@ -5,7 +5,7 @@ from LOGS.Entity.Entity import Entity
5
5
  from LOGS.LOGSConnection import LOGSConnection
6
6
 
7
7
 
8
- class EntityWithIntId(Entity):
8
+ class IEntityWithIntId(Entity):
9
9
  _id: int = 0
10
10
 
11
11
  def __init__(
@@ -72,7 +72,7 @@ class SerializeableContent:
72
72
  )
73
73
  else:
74
74
  self.checkFieldAndConvert(
75
- ref, fieldName=k, fieldType=t, allowNone=True
75
+ elements=ref, fieldName=k, fieldType=t, allowNone=True
76
76
  )
77
77
 
78
78
  if fromDict:
@@ -116,13 +116,19 @@ class SerializeableContent:
116
116
  # print("ref", type(self).__name__)
117
117
 
118
118
  for k in dir(self):
119
- # _k = "_" + k
119
+ # print(
120
+ # f"[{type(self).__name__}] Attribute",
121
+ # k,
122
+ # k in ref and hasattr(self, k) and not callable(getattr(self, k)),
123
+ # "->",
124
+ # ref[k] if k in ref else "NULL",
125
+ # )
120
126
  if k in ref and hasattr(self, k) and not callable(getattr(self, k)):
121
127
  try:
122
128
  # print(" ", k, "->", ref[k])
123
129
  setattr(self, k, ref[k])
124
- except AttributeError:
125
- # print("ERROR:", k, "->", ref[k])
130
+ except AttributeError as e:
131
+ # print(f"[{type(self).__name__}] ERROR:", k, "->", ref[k], e)
126
132
  pass
127
133
 
128
134
  # This is the old way to check if settable: checks if a private attr exists and sets this
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from datetime import datetime
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING, List, Optional
4
4
 
5
5
  from LOGS.Auxiliary import Tools
6
6
  from LOGS.Auxiliary.MinimalModelGenerator import PersonMinimalFromDict
@@ -10,8 +10,17 @@ if TYPE_CHECKING:
10
10
  from LOGS.Entities.PersonMinimal import PersonMinimal
11
11
 
12
12
 
13
+ class ICreatedOnRequest:
14
+ createdFrom: Optional[datetime] = None
15
+ createdTo: Optional[datetime] = None
16
+
17
+
18
+ class ICreatedByRequest:
19
+ createdByIds: Optional[List[int]]
20
+
21
+
13
22
  @dataclass
14
- class ICreationRecordRequest:
23
+ class ICreationRecordRequest(ICreatedOnRequest, ICreatedByRequest):
15
24
  pass
16
25
 
17
26
 
@@ -39,7 +48,7 @@ class ICreatedBy(IEntityInterface):
39
48
  @createdBy.setter
40
49
  def createdBy(self, value):
41
50
  self._createdBy = PersonMinimalFromDict(
42
- value, "_createdBy", self._getEntityConnection()
51
+ value, "createdBy", self._getEntityConnection()
43
52
  )
44
53
 
45
54
 
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from datetime import datetime
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING, List, Optional
4
4
 
5
5
  from LOGS.Auxiliary import Tools
6
6
  from LOGS.Auxiliary.MinimalModelGenerator import PersonMinimalFromDict
@@ -15,6 +15,15 @@ class IModificationRecordRequest:
15
15
  pass
16
16
 
17
17
 
18
+ class IModifiedOnRequest:
19
+ modifiedFrom: Optional[datetime] = None
20
+ modifiedTo: Optional[datetime] = None
21
+
22
+
23
+ class IModifiedByRequest:
24
+ modifiedByIds: Optional[List[int]]
25
+
26
+
18
27
  class IModifiedOn(IEntityInterface):
19
28
  _modifiedOn: Optional[datetime] = None
20
29
 
@@ -0,0 +1,30 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, List, Optional
3
+
4
+ from LOGS.Auxiliary.MinimalModelGenerator import MinimalFromList
5
+ from LOGS.Interfaces.IEntityInterface import IEntityInterface
6
+
7
+ if TYPE_CHECKING:
8
+ from LOGS.Entities.ProjectMinimal import ProjectMinimal
9
+
10
+
11
+ @dataclass
12
+ class IProjectBasedRequest:
13
+ projects: Optional[List[str]] = None
14
+
15
+
16
+ class IProjectBased(IEntityInterface):
17
+ _projects: Optional[List["ProjectMinimal"]] = None
18
+
19
+ @property
20
+ def projects(self) -> Optional[List["ProjectMinimal"]]:
21
+ return self._projects
22
+
23
+ @projects.setter
24
+ def projects(self, value):
25
+ connection = (
26
+ getattr(self, "connection") if hasattr(self, "connection") else None
27
+ )
28
+ self._projects = MinimalFromList(
29
+ value, "ProjectMinimal", "projects", connection=connection
30
+ )
@@ -0,0 +1,34 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Generic, Optional, Type, TypeVar
3
+
4
+ from LOGS.Auxiliary import Tools
5
+ from LOGS.Interfaces.IEntityInterface import IEntityInterface
6
+ from LOGS.Interfaces.IRelationModel import IRelationModel
7
+
8
+ if TYPE_CHECKING:
9
+ pass
10
+
11
+
12
+ _Relations = TypeVar("_Relations", bound=IRelationModel)
13
+
14
+
15
+ @dataclass
16
+ class IRelatedEntity(Generic[_Relations], IEntityInterface):
17
+ _relationType: Optional[Type[_Relations]] = None
18
+ _relations: Optional[_Relations] = None
19
+
20
+ @property
21
+ def relations(self) -> Optional[_Relations]:
22
+ return self._relations
23
+
24
+ @relations.setter
25
+ def relations(self, value):
26
+ if not self._relationType:
27
+ raise NotImplementedError(
28
+ "Relation class definition (_relationType) for of entity type %a is missing."
29
+ % (type(self).__name__)
30
+ )
31
+
32
+ self._createdOn = Tools.checkAndConvert(
33
+ value, self._relationType, "relations", allowNone=True
34
+ )
@@ -0,0 +1,6 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class IRelationModel:
6
+ pass
@@ -0,0 +1,12 @@
1
+ from dataclasses import dataclass
2
+ from typing import TYPE_CHECKING, Optional
3
+
4
+ if TYPE_CHECKING:
5
+ pass
6
+
7
+
8
+ @dataclass
9
+ class IRelationRequest:
10
+ includePermissions: Optional[bool] = None
11
+ includeRelationLink: Optional[bool] = None
12
+ includeRelationCount: Optional[bool] = None