everysk-lib 1.10.2__cp312-cp312-win_amd64.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.
- everysk/__init__.py +30 -0
- everysk/_version.py +683 -0
- everysk/api/__init__.py +61 -0
- everysk/api/api_requestor.py +167 -0
- everysk/api/api_resources/__init__.py +23 -0
- everysk/api/api_resources/api_resource.py +371 -0
- everysk/api/api_resources/calculation.py +779 -0
- everysk/api/api_resources/custom_index.py +42 -0
- everysk/api/api_resources/datastore.py +81 -0
- everysk/api/api_resources/file.py +42 -0
- everysk/api/api_resources/market_data.py +223 -0
- everysk/api/api_resources/parser.py +66 -0
- everysk/api/api_resources/portfolio.py +43 -0
- everysk/api/api_resources/private_security.py +42 -0
- everysk/api/api_resources/report.py +65 -0
- everysk/api/api_resources/report_template.py +39 -0
- everysk/api/api_resources/tests.py +115 -0
- everysk/api/api_resources/worker_execution.py +64 -0
- everysk/api/api_resources/workflow.py +65 -0
- everysk/api/api_resources/workflow_execution.py +93 -0
- everysk/api/api_resources/workspace.py +42 -0
- everysk/api/http_client.py +63 -0
- everysk/api/tests.py +32 -0
- everysk/api/utils.py +262 -0
- everysk/config.py +451 -0
- everysk/core/_tests/serialize/test_json.py +336 -0
- everysk/core/_tests/serialize/test_orjson.py +295 -0
- everysk/core/_tests/serialize/test_pickle.py +48 -0
- everysk/core/cloud_function/main.py +78 -0
- everysk/core/cloud_function/tests.py +86 -0
- everysk/core/compress.py +245 -0
- everysk/core/datetime/__init__.py +12 -0
- everysk/core/datetime/calendar.py +144 -0
- everysk/core/datetime/date.py +424 -0
- everysk/core/datetime/date_expression.py +299 -0
- everysk/core/datetime/date_mixin.py +1475 -0
- everysk/core/datetime/date_settings.py +30 -0
- everysk/core/datetime/datetime.py +713 -0
- everysk/core/exceptions.py +435 -0
- everysk/core/fields.py +1176 -0
- everysk/core/firestore.py +555 -0
- everysk/core/fixtures/_settings.py +29 -0
- everysk/core/fixtures/other/_settings.py +18 -0
- everysk/core/fixtures/user_agents.json +88 -0
- everysk/core/http.py +691 -0
- everysk/core/lists.py +92 -0
- everysk/core/log.py +709 -0
- everysk/core/number.py +37 -0
- everysk/core/object.py +1469 -0
- everysk/core/redis.py +1021 -0
- everysk/core/retry.py +51 -0
- everysk/core/serialize.py +674 -0
- everysk/core/sftp.py +414 -0
- everysk/core/signing.py +53 -0
- everysk/core/slack.py +127 -0
- everysk/core/string.py +199 -0
- everysk/core/tests.py +240 -0
- everysk/core/threads.py +199 -0
- everysk/core/undefined.py +70 -0
- everysk/core/unittests.py +73 -0
- everysk/core/workers.py +241 -0
- everysk/sdk/__init__.py +23 -0
- everysk/sdk/base.py +98 -0
- everysk/sdk/brutils/cnpj.py +391 -0
- everysk/sdk/brutils/cnpj_pd.py +129 -0
- everysk/sdk/engines/__init__.py +26 -0
- everysk/sdk/engines/cache.py +185 -0
- everysk/sdk/engines/compliance.py +37 -0
- everysk/sdk/engines/cryptography.py +69 -0
- everysk/sdk/engines/expression.cp312-win_amd64.pyd +0 -0
- everysk/sdk/engines/expression.pyi +55 -0
- everysk/sdk/engines/helpers.cp312-win_amd64.pyd +0 -0
- everysk/sdk/engines/helpers.pyi +26 -0
- everysk/sdk/engines/lock.py +120 -0
- everysk/sdk/engines/market_data.py +244 -0
- everysk/sdk/engines/settings.py +19 -0
- everysk/sdk/entities/__init__.py +23 -0
- everysk/sdk/entities/base.py +784 -0
- everysk/sdk/entities/base_list.py +131 -0
- everysk/sdk/entities/custom_index/base.py +209 -0
- everysk/sdk/entities/custom_index/settings.py +29 -0
- everysk/sdk/entities/datastore/base.py +160 -0
- everysk/sdk/entities/datastore/settings.py +17 -0
- everysk/sdk/entities/fields.py +375 -0
- everysk/sdk/entities/file/base.py +215 -0
- everysk/sdk/entities/file/settings.py +63 -0
- everysk/sdk/entities/portfolio/base.py +248 -0
- everysk/sdk/entities/portfolio/securities.py +241 -0
- everysk/sdk/entities/portfolio/security.py +580 -0
- everysk/sdk/entities/portfolio/settings.py +97 -0
- everysk/sdk/entities/private_security/base.py +226 -0
- everysk/sdk/entities/private_security/settings.py +17 -0
- everysk/sdk/entities/query.py +603 -0
- everysk/sdk/entities/report/base.py +214 -0
- everysk/sdk/entities/report/settings.py +23 -0
- everysk/sdk/entities/script.py +310 -0
- everysk/sdk/entities/secrets/base.py +128 -0
- everysk/sdk/entities/secrets/script.py +119 -0
- everysk/sdk/entities/secrets/settings.py +17 -0
- everysk/sdk/entities/settings.py +48 -0
- everysk/sdk/entities/tags.py +174 -0
- everysk/sdk/entities/worker_execution/base.py +307 -0
- everysk/sdk/entities/worker_execution/settings.py +63 -0
- everysk/sdk/entities/workflow_execution/base.py +113 -0
- everysk/sdk/entities/workflow_execution/settings.py +32 -0
- everysk/sdk/entities/workspace/base.py +99 -0
- everysk/sdk/entities/workspace/settings.py +27 -0
- everysk/sdk/settings.py +67 -0
- everysk/sdk/tests.py +105 -0
- everysk/sdk/worker_base.py +47 -0
- everysk/server/__init__.py +9 -0
- everysk/server/applications.py +63 -0
- everysk/server/endpoints.py +516 -0
- everysk/server/example_api.py +69 -0
- everysk/server/middlewares.py +80 -0
- everysk/server/requests.py +62 -0
- everysk/server/responses.py +119 -0
- everysk/server/routing.py +64 -0
- everysk/server/settings.py +36 -0
- everysk/server/tests.py +36 -0
- everysk/settings.py +98 -0
- everysk/sql/__init__.py +9 -0
- everysk/sql/connection.py +232 -0
- everysk/sql/model.py +376 -0
- everysk/sql/query.py +417 -0
- everysk/sql/row_factory.py +63 -0
- everysk/sql/settings.py +49 -0
- everysk/sql/utils.py +129 -0
- everysk/tests.py +23 -0
- everysk/utils.py +81 -0
- everysk/version.py +15 -0
- everysk_lib-1.10.2.dist-info/.gitignore +5 -0
- everysk_lib-1.10.2.dist-info/METADATA +326 -0
- everysk_lib-1.10.2.dist-info/RECORD +137 -0
- everysk_lib-1.10.2.dist-info/WHEEL +5 -0
- everysk_lib-1.10.2.dist-info/licenses/LICENSE.txt +9 -0
- everysk_lib-1.10.2.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
# -*- coding: utf_8 -*-
|
|
2
|
+
###############################################################################
|
|
3
|
+
#
|
|
4
|
+
# (C) Copyright 2023 EVERYSK TECHNOLOGIES
|
|
5
|
+
#
|
|
6
|
+
# This is an unpublished work containing confidential and proprietary
|
|
7
|
+
# information of EVERYSK TECHNOLOGIES. Disclosure, use, or reproduction
|
|
8
|
+
# without authorization of EVERYSK TECHNOLOGIES is prohibited.
|
|
9
|
+
#
|
|
10
|
+
###############################################################################
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from everysk.config import settings
|
|
14
|
+
from everysk.core.datetime import DateTime
|
|
15
|
+
from everysk.core.fields import ChoiceField, DateTimeField, ListField, StrField, _min_max_validate
|
|
16
|
+
from everysk.core.log import Logger
|
|
17
|
+
from everysk.sdk.engines.market_data import MarketDataPublic
|
|
18
|
+
from everysk.sdk.entities.tags import Tags
|
|
19
|
+
|
|
20
|
+
log = Logger(name=__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
###############################################################################
|
|
24
|
+
# CurrencyField Class Implementation
|
|
25
|
+
###############################################################################
|
|
26
|
+
class CurrencyField(ChoiceField):
|
|
27
|
+
"""
|
|
28
|
+
A field for currency codes with validation capabilities.
|
|
29
|
+
|
|
30
|
+
This class extends the standard ChoiceField and adds validation for the values
|
|
31
|
+
added or inserted into it.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
_choices: list[str] = None
|
|
35
|
+
_market_data: MarketDataPublic = MarketDataPublic()
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
default: str = None,
|
|
40
|
+
choices: list = None,
|
|
41
|
+
readonly: bool = False,
|
|
42
|
+
required: bool = False,
|
|
43
|
+
required_lazy: bool = True,
|
|
44
|
+
empty_is_none: bool = False,
|
|
45
|
+
**kwargs,
|
|
46
|
+
) -> None:
|
|
47
|
+
super().__init__(
|
|
48
|
+
default=default,
|
|
49
|
+
choices=choices,
|
|
50
|
+
readonly=readonly,
|
|
51
|
+
required=required,
|
|
52
|
+
required_lazy=required_lazy,
|
|
53
|
+
empty_is_none=empty_is_none,
|
|
54
|
+
**kwargs,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def _get_choices(self) -> set():
|
|
58
|
+
"""
|
|
59
|
+
Get all available currencies.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
A list of all available currencies.
|
|
63
|
+
"""
|
|
64
|
+
if not self._choices:
|
|
65
|
+
try:
|
|
66
|
+
self._choices = {
|
|
67
|
+
item['code'] for item in self._market_data.get_currencies(fields='code', status__eq='active')
|
|
68
|
+
}
|
|
69
|
+
except Exception as error:
|
|
70
|
+
log.error('Failed to get currencies from public Market Data: %s', error)
|
|
71
|
+
|
|
72
|
+
# If we don't have a list of currencies we set to the one in the settings
|
|
73
|
+
if not self._choices:
|
|
74
|
+
self._choices = set(settings.ENTITY_BASE_CURRENCY_DEFAULT_LIST)
|
|
75
|
+
|
|
76
|
+
return self._choices
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
###############################################################################
|
|
80
|
+
# EntityNameField Class Implementation
|
|
81
|
+
###############################################################################
|
|
82
|
+
class EntityNameField(StrField):
|
|
83
|
+
"""
|
|
84
|
+
This class is a subclass of StrField and provides specific validation for name, including
|
|
85
|
+
size limits and pattern matching.
|
|
86
|
+
|
|
87
|
+
Attributes:
|
|
88
|
+
min_size (int): The minimum allowed size for the list (default is the value from settings).
|
|
89
|
+
max_size (int): The maximum allowed size for the list (default is the value from settings).
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
attr_type = str
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
default: Any = None,
|
|
97
|
+
regex: str = None,
|
|
98
|
+
min_size: int = settings.ENTITY_NAME_MIN_LENGTH,
|
|
99
|
+
max_size: int = settings.ENTITY_NAME_MAX_LENGTH,
|
|
100
|
+
readonly: bool = False,
|
|
101
|
+
required: bool = False,
|
|
102
|
+
required_lazy: bool = True,
|
|
103
|
+
empty_is_none: bool = True,
|
|
104
|
+
**kwargs,
|
|
105
|
+
) -> None:
|
|
106
|
+
super().__init__(
|
|
107
|
+
default=default,
|
|
108
|
+
regex=regex,
|
|
109
|
+
min_size=min_size,
|
|
110
|
+
max_size=max_size,
|
|
111
|
+
readonly=readonly,
|
|
112
|
+
required=required,
|
|
113
|
+
required_lazy=required_lazy,
|
|
114
|
+
empty_is_none=empty_is_none,
|
|
115
|
+
**kwargs,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
###############################################################################
|
|
120
|
+
# EntityDescriptionField Class Implementation
|
|
121
|
+
###############################################################################
|
|
122
|
+
class EntityDescriptionField(StrField):
|
|
123
|
+
"""
|
|
124
|
+
This class is a subclass of StrField and provides specific validation for description, including
|
|
125
|
+
size limits and pattern matching.
|
|
126
|
+
|
|
127
|
+
Attributes:
|
|
128
|
+
min_size (int): The minimum allowed size for the list (default is the value from settings).
|
|
129
|
+
max_size (int): The maximum allowed size for the list (default is the value from settings).
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
attr_type = str
|
|
133
|
+
|
|
134
|
+
def __init__(
|
|
135
|
+
self,
|
|
136
|
+
default: Any = None,
|
|
137
|
+
regex: str = None,
|
|
138
|
+
min_size: int = settings.ENTITY_DESCRIPTION_MIN_LEN,
|
|
139
|
+
max_size: int = settings.ENTITY_DESCRIPTION_MAX_LEN,
|
|
140
|
+
readonly: bool = False,
|
|
141
|
+
required: bool = False,
|
|
142
|
+
required_lazy: bool = False,
|
|
143
|
+
empty_is_none: bool = False,
|
|
144
|
+
**kwargs,
|
|
145
|
+
) -> None:
|
|
146
|
+
super().__init__(
|
|
147
|
+
default=default,
|
|
148
|
+
regex=regex,
|
|
149
|
+
min_size=min_size,
|
|
150
|
+
max_size=max_size,
|
|
151
|
+
readonly=readonly,
|
|
152
|
+
required=required,
|
|
153
|
+
required_lazy=required_lazy,
|
|
154
|
+
empty_is_none=empty_is_none,
|
|
155
|
+
**kwargs,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
###############################################################################
|
|
160
|
+
# EntityLinkUIDField Class Implementation
|
|
161
|
+
###############################################################################
|
|
162
|
+
class EntityLinkUIDField(StrField):
|
|
163
|
+
"""
|
|
164
|
+
This class is a subclass of StrField and provides specific validation for link uid, including
|
|
165
|
+
size limits and pattern matching.
|
|
166
|
+
|
|
167
|
+
Attributes:
|
|
168
|
+
min_size (int): The minimum allowed size for the list (default is the value from settings).
|
|
169
|
+
max_size (int): The maximum allowed size for the list (default is the value from settings).
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
attr_type = str
|
|
173
|
+
|
|
174
|
+
def __init__(
|
|
175
|
+
self,
|
|
176
|
+
default: Any = None,
|
|
177
|
+
regex: str = None,
|
|
178
|
+
min_size: int = settings.ENTITY_LINK_UID_MIN_LENGTH,
|
|
179
|
+
max_size: int = settings.ENTITY_LINK_UID_MAX_LENGTH,
|
|
180
|
+
readonly: bool = False,
|
|
181
|
+
required: bool = False,
|
|
182
|
+
required_lazy: bool = False,
|
|
183
|
+
empty_is_none: bool = True,
|
|
184
|
+
**kwargs,
|
|
185
|
+
) -> None:
|
|
186
|
+
super().__init__(
|
|
187
|
+
default=default,
|
|
188
|
+
regex=regex,
|
|
189
|
+
min_size=min_size,
|
|
190
|
+
max_size=max_size,
|
|
191
|
+
readonly=readonly,
|
|
192
|
+
required=required,
|
|
193
|
+
required_lazy=required_lazy,
|
|
194
|
+
empty_is_none=empty_is_none,
|
|
195
|
+
**kwargs,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
###############################################################################
|
|
200
|
+
# EntityWorkspaceField Class Implementation
|
|
201
|
+
###############################################################################
|
|
202
|
+
class EntityWorkspaceField(StrField):
|
|
203
|
+
"""
|
|
204
|
+
This class is a subclass of StrField and provides specific validation for workspace, including
|
|
205
|
+
size limits and pattern matching.
|
|
206
|
+
|
|
207
|
+
Attributes:
|
|
208
|
+
min_size (int): The minimum allowed size for the list (default is the value from settings).
|
|
209
|
+
max_size (int): The maximum allowed size for the list (default is the value from settings).
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
attr_type = str
|
|
213
|
+
|
|
214
|
+
def __init__(
|
|
215
|
+
self,
|
|
216
|
+
default: Any = None,
|
|
217
|
+
regex: str = settings.ENTITY_WORKSPACE_REGEX,
|
|
218
|
+
min_size: int = settings.ENTITY_WORKSPACE_MIN_LENGTH,
|
|
219
|
+
max_size: int = settings.ENTITY_WORKSPACE_MAX_LENGTH,
|
|
220
|
+
readonly: bool = False,
|
|
221
|
+
required: bool = False,
|
|
222
|
+
required_lazy: bool = True,
|
|
223
|
+
empty_is_none: bool = True,
|
|
224
|
+
**kwargs,
|
|
225
|
+
) -> None:
|
|
226
|
+
super().__init__(
|
|
227
|
+
default=default,
|
|
228
|
+
regex=regex,
|
|
229
|
+
min_size=min_size,
|
|
230
|
+
max_size=max_size,
|
|
231
|
+
readonly=readonly,
|
|
232
|
+
required=required,
|
|
233
|
+
required_lazy=required_lazy,
|
|
234
|
+
empty_is_none=empty_is_none,
|
|
235
|
+
**kwargs,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
###############################################################################
|
|
240
|
+
# EntityDateTimeField Class Implementation
|
|
241
|
+
###############################################################################
|
|
242
|
+
class EntityDateTimeField(DateTimeField):
|
|
243
|
+
"""
|
|
244
|
+
This class is a subclass of StrField and provides specific validation for date, including
|
|
245
|
+
size limits and pattern matching.
|
|
246
|
+
|
|
247
|
+
Attributes:
|
|
248
|
+
min_size (int): The minimum allowed size for the list (default is the value from DateTime market start).
|
|
249
|
+
max_size (int): The maximum allowed size for the list (default is one day delta from now).
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
attr_type = DateTime
|
|
253
|
+
|
|
254
|
+
def __init__(
|
|
255
|
+
self,
|
|
256
|
+
default: Any = None,
|
|
257
|
+
min_date: DateTime = None,
|
|
258
|
+
max_date: DateTime = None,
|
|
259
|
+
force_time: str = 'MIDDAY',
|
|
260
|
+
required: bool = False,
|
|
261
|
+
readonly: bool = False,
|
|
262
|
+
required_lazy: bool = True,
|
|
263
|
+
empty_is_none: bool = True,
|
|
264
|
+
**kwargs,
|
|
265
|
+
) -> None:
|
|
266
|
+
super().__init__(
|
|
267
|
+
default,
|
|
268
|
+
min_date=min_date,
|
|
269
|
+
max_date=max_date,
|
|
270
|
+
force_time=force_time,
|
|
271
|
+
required=required,
|
|
272
|
+
readonly=readonly,
|
|
273
|
+
required_lazy=required_lazy,
|
|
274
|
+
empty_is_none=empty_is_none,
|
|
275
|
+
**kwargs,
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def validate(self, attr_name: str, value: Any, attr_type: type = None) -> None:
|
|
279
|
+
"""
|
|
280
|
+
Checks if value is greater than min and lower than max including both values.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
attr_name (str): The name of the attribute being validated.
|
|
284
|
+
value (Any): The value to validate.
|
|
285
|
+
attr_type (type): The type of the attribute being validated.
|
|
286
|
+
|
|
287
|
+
Raises:
|
|
288
|
+
FieldValueError: If the value is not within the specified range.
|
|
289
|
+
|
|
290
|
+
Example:
|
|
291
|
+
>>> from everysk.sdk.entities.fields import EntityDateTimeField
|
|
292
|
+
>>> from everysk.core.datetime.datetime import DateTime
|
|
293
|
+
>>> field = EntityDateTimeField(min_date=DateTime(2023-01-01), max_date=DateTime(2023-12-31))
|
|
294
|
+
>>> try:
|
|
295
|
+
>>> ... field.validate("test_field", DateTime(2023, 6, 15))
|
|
296
|
+
>>> ... print("Valid Date")
|
|
297
|
+
>>> except Exception as e:
|
|
298
|
+
>>> ... print(f"Validation error: {e}")
|
|
299
|
+
>>> Valid Date
|
|
300
|
+
"""
|
|
301
|
+
min_date = self.min_date if self.min_date is not None else DateTime.market_start()
|
|
302
|
+
max_date = (
|
|
303
|
+
self.max_date if self.max_date is not None else DateTime.now().delta(1, 'D').force_time('LAST_MINUTE')
|
|
304
|
+
)
|
|
305
|
+
_min_max_validate(min_date, max_date, value, attr_name)
|
|
306
|
+
return super().validate(attr_name, value, attr_type)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
###############################################################################
|
|
310
|
+
# EntityTagsField Class Implementation
|
|
311
|
+
###############################################################################
|
|
312
|
+
class EntityTagsField(ListField):
|
|
313
|
+
"""
|
|
314
|
+
This class is a subclass of ListField and provides specific validation for tags, including
|
|
315
|
+
size limits and pattern matching.
|
|
316
|
+
|
|
317
|
+
Attributes:
|
|
318
|
+
min_size (int): The minimum allowed size for the list (default is the value from settings).
|
|
319
|
+
max_size (int): The maximum allowed size for the list (default is the value from settings).
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
attr_type = Tags
|
|
323
|
+
|
|
324
|
+
def __init__(
|
|
325
|
+
self,
|
|
326
|
+
default: Any = None,
|
|
327
|
+
min_size: int = settings.ENTITY_MIN_TAG_SIZE,
|
|
328
|
+
max_size: int = settings.ENTITY_MAX_TAG_SIZE,
|
|
329
|
+
readonly: bool = False,
|
|
330
|
+
required: bool = False,
|
|
331
|
+
required_lazy: bool = False,
|
|
332
|
+
empty_is_none: bool = False,
|
|
333
|
+
**kwargs,
|
|
334
|
+
) -> None:
|
|
335
|
+
if default is not None and not isinstance(default, Tags):
|
|
336
|
+
default = Tags(default)
|
|
337
|
+
super().__init__(
|
|
338
|
+
default=default,
|
|
339
|
+
min_size=min_size,
|
|
340
|
+
max_size=max_size,
|
|
341
|
+
readonly=readonly,
|
|
342
|
+
required=required,
|
|
343
|
+
required_lazy=required_lazy,
|
|
344
|
+
empty_is_none=empty_is_none,
|
|
345
|
+
**kwargs,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
def clean_value(self, value: Any) -> Any:
|
|
349
|
+
"""
|
|
350
|
+
This method ensures that the provided value is in the expected format before assigning it to an attribute.
|
|
351
|
+
If the value is None, it is replaced with an empty TagsList. If it is not already a TagsList instance,
|
|
352
|
+
it is converted into one.
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
value (Any): The value to clean, None, A TagsList instance, or any other value.
|
|
356
|
+
|
|
357
|
+
Example:
|
|
358
|
+
>>> from everysk.sdk.entities.tags import Tags
|
|
359
|
+
>>> from everysk.sdk.entities.fields import EntityTagsField
|
|
360
|
+
>>> field = EntityTagsField()
|
|
361
|
+
|
|
362
|
+
>>> cleaned_value_none = field.clean_value(None)
|
|
363
|
+
>>> print(cleaned_value_none)
|
|
364
|
+
>>> []
|
|
365
|
+
|
|
366
|
+
>>> cleaned_non_empty_tags = field.clean_value(Tags(['tag1', 'tag2']))
|
|
367
|
+
>>> print(cleaned_non_empty_tags)
|
|
368
|
+
>>> ['tag1', 'tag2']
|
|
369
|
+
"""
|
|
370
|
+
value = super().clean_value(value)
|
|
371
|
+
if value is None:
|
|
372
|
+
value = Tags()
|
|
373
|
+
elif not isinstance(value, Tags):
|
|
374
|
+
value = Tags(value)
|
|
375
|
+
return value
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# (C) Copyright 2023 EVERYSK TECHNOLOGIES
|
|
4
|
+
#
|
|
5
|
+
# This is an unpublished work containing confidential and proprietary
|
|
6
|
+
# information of EVERYSK TECHNOLOGIES. Disclosure, use, or reproduction
|
|
7
|
+
# without authorization of EVERYSK TECHNOLOGIES is prohibited.
|
|
8
|
+
#
|
|
9
|
+
###############################################################################
|
|
10
|
+
from typing import Self
|
|
11
|
+
|
|
12
|
+
from everysk.config import settings
|
|
13
|
+
from everysk.core.exceptions import SDKValueError
|
|
14
|
+
from everysk.core.fields import ListField, StrField, ChoiceField
|
|
15
|
+
from everysk.sdk.engines.cryptography import generate_unique_id
|
|
16
|
+
from everysk.sdk.entities.base import BaseEntity, ScriptMetaClass
|
|
17
|
+
from everysk.sdk.entities.fields import EntityNameField, EntityDescriptionField, EntityLinkUIDField, EntityWorkspaceField, EntityDateTimeField, EntityTagsField
|
|
18
|
+
from everysk.sdk.entities.query import Query
|
|
19
|
+
from everysk.sdk.entities.script import Script
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
###############################################################################
|
|
23
|
+
# File Class Implementation
|
|
24
|
+
###############################################################################
|
|
25
|
+
class File(BaseEntity, metaclass=ScriptMetaClass):
|
|
26
|
+
"""
|
|
27
|
+
This class represents a file entity object and provides methods to validate and manage the entity's data.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
script (Script): The script object associated with the file.
|
|
31
|
+
id (StrField): The unique identifier of the file.
|
|
32
|
+
workspace (EntityWorkspaceField): The workspace of the file.
|
|
33
|
+
name (EntityNameField): The name of the file.
|
|
34
|
+
tags (EntityTagsField): The tags of the file.
|
|
35
|
+
description (EntityDescriptionField): The description of the file.
|
|
36
|
+
link_uid (EntityLinkUIDField): The link UID of the file.
|
|
37
|
+
date (EntityDateTimeField): The date associated with the file.
|
|
38
|
+
data (StrField): The file data in base64 format.
|
|
39
|
+
url (StrField): The URL of the file.
|
|
40
|
+
content_type (ChoiceField): The content type of the file.
|
|
41
|
+
|
|
42
|
+
version (StrField): The version of the datastore.
|
|
43
|
+
created_on (DateTimeField): The created on date of the datastore.
|
|
44
|
+
updated_on (DateTimeField): The updated on date of the datastore.
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
>>> from everysk.sdk.entities.file.base import File
|
|
48
|
+
>>> file = File()
|
|
49
|
+
>>> file.script = 'my_script'
|
|
50
|
+
>>> file.id = 'file_12345678'
|
|
51
|
+
>>> file.name = 'My File'
|
|
52
|
+
>>> file.tags = ['tag1', 'tag2']
|
|
53
|
+
>>> file.description = 'This is a sample file.'
|
|
54
|
+
>>> file.workspace = 'my_workspace'
|
|
55
|
+
>>> file.date = DateTime.fromisoformat('20220101')
|
|
56
|
+
>>> file.data = 'base64_encoded_data_here'
|
|
57
|
+
>>> file.content_type = 'application/pdf'
|
|
58
|
+
>>> file.url = '/1234567891011211234567890'
|
|
59
|
+
>>> file.create()
|
|
60
|
+
>>> print(file)
|
|
61
|
+
{
|
|
62
|
+
'id': 'file_12345678',
|
|
63
|
+
'script': 'my_script',
|
|
64
|
+
'name': 'My File',
|
|
65
|
+
'description': 'This is a sample file.',
|
|
66
|
+
'tags': ['tag1', 'tag2'],
|
|
67
|
+
'link_uid': None,
|
|
68
|
+
'workspace': 'my_workspace',
|
|
69
|
+
'date': '20220101',
|
|
70
|
+
'data': 'base64_encoded_data_here',
|
|
71
|
+
'content_type': 'application/pdf',
|
|
72
|
+
'url': '/1234567891011211234567890'
|
|
73
|
+
'created': '2021-01-01T00:00:00.000000Z',
|
|
74
|
+
'updated': '2021-01-01T00:00:00.000000Z',
|
|
75
|
+
}
|
|
76
|
+
"""
|
|
77
|
+
script: Script
|
|
78
|
+
_orderable_attributes = ListField(default=['date', 'created_on', 'updated_on', 'name'], readonly=True)
|
|
79
|
+
_allowed_query_attributes_for_all_operators = ListField(default=settings.ENTITY_ALLOWED_QUERY_ATTRIBUTES_FOR_ALL_OPERATORS + ['content_type'], readonly=True)
|
|
80
|
+
|
|
81
|
+
id = StrField(regex=settings.FILE_ID_REGEX, max_size=settings.FILE_ID_MAX_SIZE, required_lazy=True, empty_is_none=True)
|
|
82
|
+
|
|
83
|
+
name = EntityNameField()
|
|
84
|
+
description = EntityDescriptionField()
|
|
85
|
+
tags = EntityTagsField()
|
|
86
|
+
link_uid = EntityLinkUIDField()
|
|
87
|
+
workspace = EntityWorkspaceField()
|
|
88
|
+
|
|
89
|
+
date = EntityDateTimeField()
|
|
90
|
+
|
|
91
|
+
hash = StrField(default=None, max_size=settings.FILE_HASH_LENGTH, required_lazy=True)
|
|
92
|
+
data = StrField(default=None, max_size=settings.FILE_DATA_MAX_SIZE_IN_BASE64, required_lazy=True)
|
|
93
|
+
content_type = ChoiceField(default=None, choices=settings.FILE_CONTENT_TYPES, required_lazy=True)
|
|
94
|
+
url = StrField(required_lazy=True)
|
|
95
|
+
|
|
96
|
+
def validate(self) -> bool:
|
|
97
|
+
"""
|
|
98
|
+
This method validates the entity object and raises an exception if it is not
|
|
99
|
+
valid. The validation is performed by calling the `validate` method of each field
|
|
100
|
+
of the entity.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
self (Self): The entity object to be validated.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
FieldValueError: If the entity object is not valid.
|
|
107
|
+
RequiredFieldError: If a required field is missing.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
bool: True if the entity object is valid, False otherwise.
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
>>> file = File()
|
|
114
|
+
>>> file.validate()
|
|
115
|
+
True
|
|
116
|
+
"""
|
|
117
|
+
return self.get_response(self_obj=self)
|
|
118
|
+
|
|
119
|
+
@classmethod
|
|
120
|
+
def validate_transient(cls, entity_dict: dict) -> Self:
|
|
121
|
+
"""
|
|
122
|
+
Validate the entity properties.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
entity_dict (dict): The entity properties.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
BaseEntity: The entity object.
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
>>> entity_dict = {'name': 'My Entity'}
|
|
132
|
+
>>> BaseEntity.validate_transient(entity_dict)
|
|
133
|
+
"""
|
|
134
|
+
return cls.get_response(params={'entity_dict': entity_dict})
|
|
135
|
+
|
|
136
|
+
def _check_entity_to_query(self) -> bool:
|
|
137
|
+
"""
|
|
138
|
+
Check the entity object to query.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
bool: True if the entity object is valid.
|
|
142
|
+
"""
|
|
143
|
+
super()._check_entity_to_query()
|
|
144
|
+
if self.url and (self.name or self.tags or self.link_uid):
|
|
145
|
+
raise SDKValueError("Can't filter by URL and Name, Tags or Link UID at the same time")
|
|
146
|
+
|
|
147
|
+
return True
|
|
148
|
+
|
|
149
|
+
def _mount_query(self, query: Query) -> Query:
|
|
150
|
+
"""
|
|
151
|
+
Mount the query object.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
query (Query): The query object.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Query: The query object.
|
|
158
|
+
"""
|
|
159
|
+
query = super()._mount_query(query)
|
|
160
|
+
|
|
161
|
+
if self.url is not None:
|
|
162
|
+
query = query.where('url', self.url)
|
|
163
|
+
|
|
164
|
+
return query
|
|
165
|
+
|
|
166
|
+
@staticmethod
|
|
167
|
+
def get_id_prefix() -> str:
|
|
168
|
+
"""
|
|
169
|
+
Returns the prefix of the file id field value.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
str: The prefix of the file id field value.
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
>>> File.get_id_prefix()
|
|
176
|
+
'file_'
|
|
177
|
+
"""
|
|
178
|
+
return settings.FILE_ID_PREFIX
|
|
179
|
+
|
|
180
|
+
@staticmethod
|
|
181
|
+
def generate_url() -> str:
|
|
182
|
+
"""
|
|
183
|
+
Generate a unique url for the file.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
str: A unique url for the file.
|
|
187
|
+
|
|
188
|
+
Example:
|
|
189
|
+
>>> File.generate_url()
|
|
190
|
+
'/1234567891011211234567890'
|
|
191
|
+
"""
|
|
192
|
+
return f'/{generate_unique_id()}'
|
|
193
|
+
|
|
194
|
+
def to_dict(self, add_class_path: bool = False, recursion: bool = False) -> dict:
|
|
195
|
+
"""
|
|
196
|
+
Convert the entity to a JSON-serializable dictionary.
|
|
197
|
+
This method converts the entity object into a dictionary that can be easily
|
|
198
|
+
serialized to JSON.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
self (Self): The entity instance to convert.
|
|
202
|
+
with_internals (bool, optional): Whether to include internal parameters. Defaults to True.
|
|
203
|
+
recursion (bool, optional): Whether to include nested entities. Defaults to False.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
dict: A dictionary representation of the File entity.
|
|
207
|
+
Raises:
|
|
208
|
+
NotImplementedError: This method should be implemented in subclasses.
|
|
209
|
+
"""
|
|
210
|
+
dct: dict = super().to_dict(add_class_path=add_class_path, recursion=recursion)
|
|
211
|
+
|
|
212
|
+
if add_class_path is False:
|
|
213
|
+
dct['url'] = f"{settings.FILE_URL_PATH}{self.url}" if self.url else None
|
|
214
|
+
|
|
215
|
+
return dct
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
###############################################################################
|
|
2
|
+
#
|
|
3
|
+
# (C) Copyright 2023 EVERYSK TECHNOLOGIES
|
|
4
|
+
#
|
|
5
|
+
# This is an unpublished work containing confidential and proprietary
|
|
6
|
+
# information of EVERYSK TECHNOLOGIES. Disclosure, use, or reproduction
|
|
7
|
+
# without authorization of EVERYSK TECHNOLOGIES is prohibited.
|
|
8
|
+
#
|
|
9
|
+
###############################################################################
|
|
10
|
+
from everysk.core.fields import IntField, ListField, RegexField, StrField
|
|
11
|
+
|
|
12
|
+
FILE_URL_PATH = StrField(default='/file', readonly=True)
|
|
13
|
+
FILE_URL_LENGTH = IntField(default=32, readonly=True)
|
|
14
|
+
FILE_HASH_LENGTH = IntField(default=40, readonly=True)
|
|
15
|
+
|
|
16
|
+
FILE_ID_REGEX = RegexField(default=r'^file_[a-zA-Z0-9]', readonly=True)
|
|
17
|
+
FILE_ID_MAX_SIZE = IntField(default=30, readonly=True)
|
|
18
|
+
FILE_ID_PREFIX = StrField(default='file_', readonly=True)
|
|
19
|
+
|
|
20
|
+
FILE_DATA_MAX_SIZE_IN_RAW = IntField(default=(100 * 1024 * 1024), readonly=True)
|
|
21
|
+
FILE_DATA_MAX_SIZE_IN_BASE64 = IntField(
|
|
22
|
+
default=139810133, readonly=True
|
|
23
|
+
) # int(FILE_DATA_MAX_SIZE_IN_RAW / 3 * 4) # 13.33MB in BASE64 ~= 10MB in RAW
|
|
24
|
+
|
|
25
|
+
FILE_CONTENT_TYPES = ListField(
|
|
26
|
+
default=[
|
|
27
|
+
None,
|
|
28
|
+
'application/csv',
|
|
29
|
+
'application/javascript',
|
|
30
|
+
'application/json',
|
|
31
|
+
'application/x-python',
|
|
32
|
+
'application/x-python-code',
|
|
33
|
+
'application/x-python-script',
|
|
34
|
+
'text/x-python',
|
|
35
|
+
'text/x-python-code',
|
|
36
|
+
'text/x-python-script',
|
|
37
|
+
'application/msword',
|
|
38
|
+
'application/octet-stream',
|
|
39
|
+
'application/pdf',
|
|
40
|
+
'application/vnd.ms-excel',
|
|
41
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
42
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
43
|
+
'application/x-zip-compressed',
|
|
44
|
+
'application/xml',
|
|
45
|
+
'application/zip',
|
|
46
|
+
'image/bmp',
|
|
47
|
+
'image/gif',
|
|
48
|
+
'image/jpeg',
|
|
49
|
+
'image/png',
|
|
50
|
+
'image/svg+xml',
|
|
51
|
+
'image/webp',
|
|
52
|
+
'text/comma-separated-values',
|
|
53
|
+
'text/csv',
|
|
54
|
+
'text/html',
|
|
55
|
+
'text/plain',
|
|
56
|
+
'text/markdown',
|
|
57
|
+
'text/x-comma-separated-values',
|
|
58
|
+
'text/xml',
|
|
59
|
+
'audio/mpeg',
|
|
60
|
+
'audio/wav',
|
|
61
|
+
],
|
|
62
|
+
readonly=True,
|
|
63
|
+
)
|