nsj-rest-lib2 0.0.26__py3-none-any.whl → 0.0.29__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.
- nsj_rest_lib2/compiler/compiler.py +81 -0
- nsj_rest_lib2/compiler/dto_compiler.py +1 -1
- nsj_rest_lib2/compiler/edl_model/api_model.py +95 -2
- nsj_rest_lib2/compiler/function_compiler.py +550 -0
- nsj_rest_lib2/compiler/function_model.py +70 -0
- nsj_rest_lib2/compiler/model.py +4 -0
- nsj_rest_lib2/compiler/property_compiler.py +111 -0
- nsj_rest_lib2/compiler/util/type_naming_util.py +22 -0
- nsj_rest_lib2/controller/dynamic_controller.py +26 -0
- nsj_rest_lib2/service/entity_config_writer.py +134 -0
- nsj_rest_lib2/service/entity_loader.py +56 -6
- {nsj_rest_lib2-0.0.26.dist-info → nsj_rest_lib2-0.0.29.dist-info}/METADATA +2 -2
- {nsj_rest_lib2-0.0.26.dist-info → nsj_rest_lib2-0.0.29.dist-info}/RECORD +15 -12
- {nsj_rest_lib2-0.0.26.dist-info → nsj_rest_lib2-0.0.29.dist-info}/WHEEL +0 -0
- {nsj_rest_lib2-0.0.26.dist-info → nsj_rest_lib2-0.0.29.dist-info}/top_level.txt +0 -0
|
@@ -18,6 +18,7 @@ from nsj_rest_lib2.compiler.edl_model.primitives import (
|
|
|
18
18
|
STR_BASED_TYPES,
|
|
19
19
|
)
|
|
20
20
|
from nsj_rest_lib2.compiler.edl_model.property_meta_model import PropertyMetaModel
|
|
21
|
+
from nsj_rest_lib2.compiler.function_model import FunctionBindingConfig
|
|
21
22
|
from nsj_rest_lib2.compiler.edl_model.trait_property_meta_model import (
|
|
22
23
|
TraitPropertyMetaModel,
|
|
23
24
|
)
|
|
@@ -41,6 +42,7 @@ class EDLPropertyCompiler:
|
|
|
41
42
|
entity_model: EntityModelBase,
|
|
42
43
|
entity_models: dict[str, EntityModel],
|
|
43
44
|
prefx_class_name: str,
|
|
45
|
+
function_bindings: FunctionBindingConfig | None = None,
|
|
44
46
|
) -> tuple[
|
|
45
47
|
list[ast.stmt],
|
|
46
48
|
list[ast.stmt],
|
|
@@ -76,6 +78,9 @@ class EDLPropertyCompiler:
|
|
|
76
78
|
|
|
77
79
|
# pk_key = pk_keys[0]
|
|
78
80
|
|
|
81
|
+
function_bindings = function_bindings or FunctionBindingConfig()
|
|
82
|
+
self._function_bindings = function_bindings
|
|
83
|
+
|
|
79
84
|
# Instanciando as listas de retorno
|
|
80
85
|
ast_dto_attributes = []
|
|
81
86
|
ast_entity_attributes = []
|
|
@@ -433,6 +438,50 @@ class EDLPropertyCompiler:
|
|
|
433
438
|
),
|
|
434
439
|
]
|
|
435
440
|
|
|
441
|
+
insert_binding = self._function_bindings.insert_relations.get(pkey)
|
|
442
|
+
if insert_binding:
|
|
443
|
+
if (
|
|
444
|
+
insert_binding.field_name
|
|
445
|
+
and insert_binding.field_name != CompilerStrUtil.to_snake_case(pkey)
|
|
446
|
+
):
|
|
447
|
+
keywords.append(
|
|
448
|
+
ast.keyword(
|
|
449
|
+
arg="insert_function_field",
|
|
450
|
+
value=ast.Constant(value=insert_binding.field_name),
|
|
451
|
+
)
|
|
452
|
+
)
|
|
453
|
+
if insert_binding.function_type_class:
|
|
454
|
+
keywords.append(
|
|
455
|
+
ast.keyword(
|
|
456
|
+
arg="insert_function_type",
|
|
457
|
+
value=ast.Name(
|
|
458
|
+
id=insert_binding.function_type_class, ctx=ast.Load()
|
|
459
|
+
),
|
|
460
|
+
)
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
update_binding = self._function_bindings.update_relations.get(pkey)
|
|
464
|
+
if update_binding:
|
|
465
|
+
if (
|
|
466
|
+
update_binding.field_name
|
|
467
|
+
and update_binding.field_name != CompilerStrUtil.to_snake_case(pkey)
|
|
468
|
+
):
|
|
469
|
+
keywords.append(
|
|
470
|
+
ast.keyword(
|
|
471
|
+
arg="update_function_field",
|
|
472
|
+
value=ast.Constant(value=update_binding.field_name),
|
|
473
|
+
)
|
|
474
|
+
)
|
|
475
|
+
if update_binding.function_type_class:
|
|
476
|
+
keywords.append(
|
|
477
|
+
ast.keyword(
|
|
478
|
+
arg="update_function_type",
|
|
479
|
+
value=ast.Name(
|
|
480
|
+
id=update_binding.function_type_class, ctx=ast.Load()
|
|
481
|
+
),
|
|
482
|
+
)
|
|
483
|
+
)
|
|
484
|
+
|
|
436
485
|
# Tratando das opções básicas do descritor de propriedade
|
|
437
486
|
if properties_structure.required and pkey in properties_structure.required:
|
|
438
487
|
keywords.append(ast.keyword(arg="not_null", value=ast.Constant(True)))
|
|
@@ -518,6 +567,50 @@ class EDLPropertyCompiler:
|
|
|
518
567
|
),
|
|
519
568
|
]
|
|
520
569
|
|
|
570
|
+
insert_binding = self._function_bindings.insert_relations.get(pkey)
|
|
571
|
+
if insert_binding:
|
|
572
|
+
if (
|
|
573
|
+
insert_binding.field_name
|
|
574
|
+
and insert_binding.field_name != CompilerStrUtil.to_snake_case(pkey)
|
|
575
|
+
):
|
|
576
|
+
keywords.append(
|
|
577
|
+
ast.keyword(
|
|
578
|
+
arg="insert_function_field",
|
|
579
|
+
value=ast.Constant(value=insert_binding.field_name),
|
|
580
|
+
)
|
|
581
|
+
)
|
|
582
|
+
if insert_binding.function_type_class:
|
|
583
|
+
keywords.append(
|
|
584
|
+
ast.keyword(
|
|
585
|
+
arg="insert_function_type",
|
|
586
|
+
value=ast.Name(
|
|
587
|
+
id=insert_binding.function_type_class, ctx=ast.Load()
|
|
588
|
+
),
|
|
589
|
+
)
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
update_binding = self._function_bindings.update_relations.get(pkey)
|
|
593
|
+
if update_binding:
|
|
594
|
+
if (
|
|
595
|
+
update_binding.field_name
|
|
596
|
+
and update_binding.field_name != CompilerStrUtil.to_snake_case(pkey)
|
|
597
|
+
):
|
|
598
|
+
keywords.append(
|
|
599
|
+
ast.keyword(
|
|
600
|
+
arg="update_function_field",
|
|
601
|
+
value=ast.Constant(value=update_binding.field_name),
|
|
602
|
+
)
|
|
603
|
+
)
|
|
604
|
+
if update_binding.function_type_class:
|
|
605
|
+
keywords.append(
|
|
606
|
+
ast.keyword(
|
|
607
|
+
arg="update_function_type",
|
|
608
|
+
value=ast.Name(
|
|
609
|
+
id=update_binding.function_type_class, ctx=ast.Load()
|
|
610
|
+
),
|
|
611
|
+
)
|
|
612
|
+
)
|
|
613
|
+
|
|
521
614
|
# Tratando das opções básicas do descritor de propriedade
|
|
522
615
|
if properties_structure.required and pkey in properties_structure.required:
|
|
523
616
|
keywords.append(ast.keyword(arg="not_null", value=ast.Constant(True)))
|
|
@@ -861,6 +954,24 @@ class EDLPropertyCompiler:
|
|
|
861
954
|
)
|
|
862
955
|
)
|
|
863
956
|
|
|
957
|
+
insert_binding = self._function_bindings.insert_fields.get(pkey)
|
|
958
|
+
if insert_binding:
|
|
959
|
+
keywords.append(
|
|
960
|
+
ast.keyword(
|
|
961
|
+
arg="insert_function_field",
|
|
962
|
+
value=ast.Constant(value=insert_binding),
|
|
963
|
+
)
|
|
964
|
+
)
|
|
965
|
+
|
|
966
|
+
update_binding = self._function_bindings.update_fields.get(pkey)
|
|
967
|
+
if update_binding:
|
|
968
|
+
keywords.append(
|
|
969
|
+
ast.keyword(
|
|
970
|
+
arg="update_function_field",
|
|
971
|
+
value=ast.Constant(value=update_binding),
|
|
972
|
+
)
|
|
973
|
+
)
|
|
974
|
+
|
|
864
975
|
# Resolvendo o nome da propriedade no Entity
|
|
865
976
|
if (
|
|
866
977
|
properties_structure.entity_properties
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import uuid
|
|
2
|
+
from typing import Iterable
|
|
2
3
|
|
|
3
4
|
from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
|
|
4
5
|
|
|
@@ -19,3 +20,24 @@ def compile_dto_class_name(entity_id: str, prefx_class_name: str = "") -> str:
|
|
|
19
20
|
|
|
20
21
|
def compile_entity_class_name(entity_id: str, prefx_class_name: str = "") -> str:
|
|
21
22
|
return f"{CompilerStrUtil.to_pascal_case(prefx_class_name)}{CompilerStrUtil.to_pascal_case(entity_id)}Entity"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def compile_function_class_name(
|
|
26
|
+
entity_id: str,
|
|
27
|
+
prefx_class_name: str,
|
|
28
|
+
path_parts: Iterable[str],
|
|
29
|
+
operation: str,
|
|
30
|
+
) -> str:
|
|
31
|
+
"""
|
|
32
|
+
Gera o nome da classe para FunctionTypes (insert/update),
|
|
33
|
+
incorporando o caminho dos relacionamentos (quando houver).
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
suffix = "InsertType" if operation == "insert" else "UpdateType"
|
|
37
|
+
path_suffix = "".join(CompilerStrUtil.to_pascal_case(part) for part in path_parts)
|
|
38
|
+
return (
|
|
39
|
+
f"{CompilerStrUtil.to_pascal_case(prefx_class_name)}"
|
|
40
|
+
f"{CompilerStrUtil.to_pascal_case(entity_id)}"
|
|
41
|
+
f"{path_suffix}"
|
|
42
|
+
f"{suffix}"
|
|
43
|
+
)
|
|
@@ -94,6 +94,8 @@ def setup_dynamic_routes(
|
|
|
94
94
|
etities_dict,
|
|
95
95
|
api_expose,
|
|
96
96
|
api_verbs,
|
|
97
|
+
_insert_function_class_name,
|
|
98
|
+
_update_function_class_name,
|
|
97
99
|
) = entity_loader.load_entity_source(
|
|
98
100
|
entity_resource,
|
|
99
101
|
tenant,
|
|
@@ -148,6 +150,8 @@ def setup_dynamic_routes(
|
|
|
148
150
|
etities_dict,
|
|
149
151
|
api_expose,
|
|
150
152
|
api_verbs,
|
|
153
|
+
_insert_function_class_name,
|
|
154
|
+
_update_function_class_name,
|
|
151
155
|
) = entity_loader.load_entity_source(
|
|
152
156
|
entity_resource,
|
|
153
157
|
tenant,
|
|
@@ -201,6 +205,8 @@ def setup_dynamic_routes(
|
|
|
201
205
|
etities_dict,
|
|
202
206
|
api_expose,
|
|
203
207
|
api_verbs,
|
|
208
|
+
insert_function_class_name,
|
|
209
|
+
_update_function_class_name,
|
|
204
210
|
) = entity_loader.load_entity_source(
|
|
205
211
|
entity_resource,
|
|
206
212
|
tenant,
|
|
@@ -214,12 +220,19 @@ def setup_dynamic_routes(
|
|
|
214
220
|
return ("", 405, {})
|
|
215
221
|
|
|
216
222
|
# Executando o list pelo RestLib
|
|
223
|
+
insert_function_type_class = (
|
|
224
|
+
etities_dict.get(insert_function_class_name)
|
|
225
|
+
if insert_function_class_name
|
|
226
|
+
else None
|
|
227
|
+
)
|
|
228
|
+
|
|
217
229
|
route = PostRoute(
|
|
218
230
|
url=COLLECTION_DYNAMIC_ROUTE,
|
|
219
231
|
http_method="POST",
|
|
220
232
|
dto_class=etities_dict[dto_class_name],
|
|
221
233
|
entity_class=etities_dict[entity_class_name],
|
|
222
234
|
injector_factory=injector_factory,
|
|
235
|
+
insert_function_type_class=insert_function_type_class,
|
|
223
236
|
)
|
|
224
237
|
|
|
225
238
|
return route.handle_request(*args, **kwargs)
|
|
@@ -254,6 +267,8 @@ def setup_dynamic_routes(
|
|
|
254
267
|
etities_dict,
|
|
255
268
|
api_expose,
|
|
256
269
|
api_verbs,
|
|
270
|
+
_insert_function_class_name,
|
|
271
|
+
update_function_class_name,
|
|
257
272
|
) = entity_loader.load_entity_source(
|
|
258
273
|
entity_resource,
|
|
259
274
|
tenant,
|
|
@@ -267,12 +282,19 @@ def setup_dynamic_routes(
|
|
|
267
282
|
return ("", 405, {})
|
|
268
283
|
|
|
269
284
|
# Executando o list pelo RestLib
|
|
285
|
+
update_function_type_class = (
|
|
286
|
+
etities_dict.get(update_function_class_name)
|
|
287
|
+
if update_function_class_name
|
|
288
|
+
else None
|
|
289
|
+
)
|
|
290
|
+
|
|
270
291
|
route = PutRoute(
|
|
271
292
|
url=ONE_DYNAMIC_ROUTE,
|
|
272
293
|
http_method="PUT",
|
|
273
294
|
dto_class=etities_dict[dto_class_name],
|
|
274
295
|
entity_class=etities_dict[entity_class_name],
|
|
275
296
|
injector_factory=injector_factory,
|
|
297
|
+
update_function_type_class=update_function_type_class,
|
|
276
298
|
)
|
|
277
299
|
|
|
278
300
|
return route.handle_request(*args, **kwargs)
|
|
@@ -307,6 +329,8 @@ def setup_dynamic_routes(
|
|
|
307
329
|
etities_dict,
|
|
308
330
|
api_expose,
|
|
309
331
|
api_verbs,
|
|
332
|
+
_insert_function_class_name,
|
|
333
|
+
_update_function_class_name,
|
|
310
334
|
) = entity_loader.load_entity_source(
|
|
311
335
|
entity_resource,
|
|
312
336
|
tenant,
|
|
@@ -360,6 +384,8 @@ def setup_dynamic_routes(
|
|
|
360
384
|
etities_dict,
|
|
361
385
|
api_expose,
|
|
362
386
|
api_verbs,
|
|
387
|
+
_insert_function_class_name,
|
|
388
|
+
_update_function_class_name,
|
|
363
389
|
) = entity_loader.load_entity_source(
|
|
364
390
|
entity_resource,
|
|
365
391
|
tenant,
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
from typing import Any, Dict, Iterator, Optional
|
|
6
|
+
|
|
7
|
+
from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
|
|
8
|
+
from nsj_rest_lib2.compiler.edl_model.entity_model_base import EntityModelBase
|
|
9
|
+
from nsj_rest_lib2.compiler.model import CompilerResult
|
|
10
|
+
from nsj_rest_lib2.compiler.util.type_naming_util import compile_namespace_keys
|
|
11
|
+
from nsj_rest_lib2.redis_config import set_redis
|
|
12
|
+
from nsj_rest_lib2.settings import ESCOPO_RESTLIB2
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class EntityConfigWriter:
|
|
16
|
+
"""
|
|
17
|
+
Serializa o resultado da compilação e publica no Redis usando o mesmo
|
|
18
|
+
layout consumido pelo EntityLoader.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, escopo: str = ESCOPO_RESTLIB2) -> None:
|
|
22
|
+
self._escopo = escopo or ESCOPO_RESTLIB2
|
|
23
|
+
|
|
24
|
+
def publish(
|
|
25
|
+
self,
|
|
26
|
+
entity_model: EntityModelBase,
|
|
27
|
+
compiler_result: CompilerResult,
|
|
28
|
+
*,
|
|
29
|
+
entity_hash: str | None = None,
|
|
30
|
+
) -> Dict[str, Any]:
|
|
31
|
+
"""
|
|
32
|
+
Serializa e grava o resultado da compilação no Redis.
|
|
33
|
+
|
|
34
|
+
:return: Payload serializado (útil para inspeção/testes).
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
payload = self.build_payload(
|
|
38
|
+
entity_model, compiler_result, entity_hash=entity_hash
|
|
39
|
+
)
|
|
40
|
+
namespace_key = self._resolve_namespace_key(entity_model)
|
|
41
|
+
resource = self._resolve_resource(entity_model)
|
|
42
|
+
|
|
43
|
+
set_redis(
|
|
44
|
+
"entity_config",
|
|
45
|
+
self._escopo,
|
|
46
|
+
namespace_key,
|
|
47
|
+
resource,
|
|
48
|
+
json.dumps(payload, ensure_ascii=False),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return payload
|
|
52
|
+
|
|
53
|
+
def build_payload(
|
|
54
|
+
self,
|
|
55
|
+
entity_model: EntityModelBase,
|
|
56
|
+
compiler_result: CompilerResult,
|
|
57
|
+
*,
|
|
58
|
+
entity_hash: str | None = None,
|
|
59
|
+
) -> Dict[str, Any]:
|
|
60
|
+
"""
|
|
61
|
+
Constrói o dicionário serializável que representa a entidade compilada.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
resource = self._resolve_resource(entity_model)
|
|
65
|
+
relations = [
|
|
66
|
+
rd.to_dict()
|
|
67
|
+
for rd in (compiler_result.relations_dependencies or [])
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
"dto_class_name": compiler_result.dto_class_name,
|
|
72
|
+
"entity_class_name": compiler_result.entity_class_name,
|
|
73
|
+
"insert_function_class_name": compiler_result.insert_function_class_name,
|
|
74
|
+
"source_insert_function": compiler_result.source_insert_function,
|
|
75
|
+
"update_function_class_name": compiler_result.update_function_class_name,
|
|
76
|
+
"source_update_function": compiler_result.source_update_function,
|
|
77
|
+
"source_dto": compiler_result.dto_code,
|
|
78
|
+
"source_entity": compiler_result.entity_code,
|
|
79
|
+
"entity_hash": entity_hash
|
|
80
|
+
if entity_hash is not None
|
|
81
|
+
else self._build_entity_hash(compiler_result),
|
|
82
|
+
"api_expose": compiler_result.api_expose,
|
|
83
|
+
"api_resource": resource,
|
|
84
|
+
"api_verbs": compiler_result.api_verbs or [],
|
|
85
|
+
"relations_dependencies": relations,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
def _resolve_namespace_key(self, entity_model: EntityModelBase) -> str:
|
|
89
|
+
tenant = getattr(entity_model, "tenant", None)
|
|
90
|
+
grupo_empresarial = getattr(entity_model, "grupo_empresarial", None)
|
|
91
|
+
|
|
92
|
+
grupo_key, tenant_key, default_key = compile_namespace_keys(
|
|
93
|
+
tenant,
|
|
94
|
+
grupo_empresarial,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
if (
|
|
98
|
+
tenant
|
|
99
|
+
and tenant != 0
|
|
100
|
+
and grupo_empresarial
|
|
101
|
+
and str(grupo_empresarial) != "00000000-0000-0000-0000-000000000000"
|
|
102
|
+
):
|
|
103
|
+
return grupo_key
|
|
104
|
+
if tenant and tenant != 0:
|
|
105
|
+
return tenant_key
|
|
106
|
+
return default_key
|
|
107
|
+
|
|
108
|
+
def _resolve_resource(self, entity_model: EntityModelBase) -> str:
|
|
109
|
+
if not isinstance(entity_model, EntityModel) or not entity_model.api:
|
|
110
|
+
raise ValueError(
|
|
111
|
+
"EntityModel precisa possuir bloco de API para publicação no Redis."
|
|
112
|
+
)
|
|
113
|
+
if not entity_model.api.resource:
|
|
114
|
+
raise ValueError("api.resource é obrigatório para publicação no Redis.")
|
|
115
|
+
return entity_model.api.resource
|
|
116
|
+
|
|
117
|
+
def _build_entity_hash(self, compiler_result: CompilerResult) -> str:
|
|
118
|
+
hasher = hashlib.sha256()
|
|
119
|
+
|
|
120
|
+
for content in self._iter_hash_chunks(
|
|
121
|
+
compiler_result.dto_code,
|
|
122
|
+
compiler_result.entity_code,
|
|
123
|
+
compiler_result.source_insert_function,
|
|
124
|
+
compiler_result.source_update_function,
|
|
125
|
+
):
|
|
126
|
+
hasher.update(content)
|
|
127
|
+
|
|
128
|
+
return hasher.hexdigest()
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def _iter_hash_chunks(*chunks: Optional[str]) -> Iterator[bytes]:
|
|
132
|
+
for chunk in chunks:
|
|
133
|
+
if chunk:
|
|
134
|
+
yield chunk.encode("utf-8")
|
|
@@ -24,6 +24,8 @@ class LoadedEntity:
|
|
|
24
24
|
self.api_expose: bool = False
|
|
25
25
|
self.api_verbs: list[str] = []
|
|
26
26
|
self.relations_dependencies: list[RelationDependency] = []
|
|
27
|
+
self.insert_function_class_name: str | None = None
|
|
28
|
+
self.update_function_class_name: str | None = None
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class Namespace:
|
|
@@ -48,7 +50,7 @@ class EntityLoader:
|
|
|
48
50
|
grupo_empresarial: str | None,
|
|
49
51
|
escopo: str = ESCOPO_RESTLIB2,
|
|
50
52
|
force_reload: bool = False,
|
|
51
|
-
) -> tuple[str, str, dict, bool, list[str]]:
|
|
53
|
+
) -> tuple[str, str, dict, bool, list[str], str | None, str | None]:
|
|
52
54
|
# Assumind o escopo default se necessário
|
|
53
55
|
if not escopo:
|
|
54
56
|
escopo = ESCOPO_RESTLIB2
|
|
@@ -77,6 +79,8 @@ class EntityLoader:
|
|
|
77
79
|
api_expose = loaded_entity.api_expose
|
|
78
80
|
api_verbs = loaded_entity.api_verbs
|
|
79
81
|
relations_dependencies = loaded_entity.relations_dependencies
|
|
82
|
+
insert_function_class_name = loaded_entity.insert_function_class_name
|
|
83
|
+
update_function_class_name = loaded_entity.update_function_class_name
|
|
80
84
|
|
|
81
85
|
# Verificando se alguma de suas dependências precisariam ser recarregadas
|
|
82
86
|
for rd in relations_dependencies:
|
|
@@ -122,6 +126,8 @@ class EntityLoader:
|
|
|
122
126
|
entities_dict,
|
|
123
127
|
api_expose,
|
|
124
128
|
api_verbs,
|
|
129
|
+
insert_function_class_name,
|
|
130
|
+
update_function_class_name,
|
|
125
131
|
)
|
|
126
132
|
|
|
127
133
|
# Desempacotando resultado
|
|
@@ -143,6 +149,8 @@ class EntityLoader:
|
|
|
143
149
|
entities_dict,
|
|
144
150
|
api_expose,
|
|
145
151
|
api_verbs,
|
|
152
|
+
insert_function_class_name,
|
|
153
|
+
update_function_class_name,
|
|
146
154
|
)
|
|
147
155
|
else:
|
|
148
156
|
(
|
|
@@ -167,6 +175,8 @@ class EntityLoader:
|
|
|
167
175
|
entities_dict,
|
|
168
176
|
api_expose,
|
|
169
177
|
api_verbs,
|
|
178
|
+
insert_function_class_name,
|
|
179
|
+
update_function_class_name,
|
|
170
180
|
)
|
|
171
181
|
|
|
172
182
|
# Se não conseguir recuperar a entidade, procura no redis:
|
|
@@ -195,9 +205,15 @@ class EntityLoader:
|
|
|
195
205
|
raise RuntimeError(
|
|
196
206
|
f"Erro desconhecido carregando entidade: {entity_resource}"
|
|
197
207
|
)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
208
|
+
(
|
|
209
|
+
dto_class_name,
|
|
210
|
+
entity_class_name,
|
|
211
|
+
namespace,
|
|
212
|
+
api_expose,
|
|
213
|
+
api_verbs,
|
|
214
|
+
insert_function_class_name,
|
|
215
|
+
update_function_class_name,
|
|
216
|
+
) = result_execute
|
|
201
217
|
|
|
202
218
|
return (
|
|
203
219
|
dto_class_name,
|
|
@@ -205,6 +221,8 @@ class EntityLoader:
|
|
|
205
221
|
namespace.entities_dict,
|
|
206
222
|
api_expose,
|
|
207
223
|
api_verbs,
|
|
224
|
+
insert_function_class_name,
|
|
225
|
+
update_function_class_name,
|
|
208
226
|
)
|
|
209
227
|
|
|
210
228
|
def clear_namespaces(self):
|
|
@@ -235,7 +253,7 @@ class EntityLoader:
|
|
|
235
253
|
entity_config_key: str,
|
|
236
254
|
entity_resource: str,
|
|
237
255
|
check_refresh: bool = False,
|
|
238
|
-
) -> tuple[str, str, Namespace, bool, list[str]] | None:
|
|
256
|
+
) -> tuple[str, str, Namespace, bool, list[str], str | None, str | None] | None:
|
|
239
257
|
# Interpretando o json de configuração da entidade
|
|
240
258
|
try:
|
|
241
259
|
entity_config = json.loads(entity_config_str)
|
|
@@ -249,6 +267,14 @@ class EntityLoader:
|
|
|
249
267
|
api_expose = entity_config["api_expose"]
|
|
250
268
|
# api_resource = entity_config["api_resource"]
|
|
251
269
|
api_verbs = entity_config["api_verbs"]
|
|
270
|
+
insert_function_class_name = entity_config.get(
|
|
271
|
+
"insert_function_class_name"
|
|
272
|
+
)
|
|
273
|
+
insert_function_code = entity_config.get("source_insert_function")
|
|
274
|
+
update_function_class_name = entity_config.get(
|
|
275
|
+
"update_function_class_name"
|
|
276
|
+
)
|
|
277
|
+
update_function_code = entity_config.get("source_update_function")
|
|
252
278
|
relations_dependencies = [
|
|
253
279
|
RelationDependency().from_dict(rd)
|
|
254
280
|
for rd in entity_config.get("relations_dependencies", [])
|
|
@@ -331,6 +357,20 @@ class EntityLoader:
|
|
|
331
357
|
get_logger().debug(f"Entity source:\n{source_entity}")
|
|
332
358
|
get_logger().debug(f"DTO source:\n{source_dto}")
|
|
333
359
|
|
|
360
|
+
if insert_function_code:
|
|
361
|
+
self._safe_exec(
|
|
362
|
+
insert_function_code,
|
|
363
|
+
namespace.entities_dict,
|
|
364
|
+
"Insert Function source",
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
if update_function_code:
|
|
368
|
+
self._safe_exec(
|
|
369
|
+
update_function_code,
|
|
370
|
+
namespace.entities_dict,
|
|
371
|
+
"Update Function source",
|
|
372
|
+
)
|
|
373
|
+
|
|
334
374
|
self._safe_exec(source_entity, namespace.entities_dict, "Entity source")
|
|
335
375
|
self._safe_exec(source_dto, namespace.entities_dict, "DTO source")
|
|
336
376
|
|
|
@@ -342,10 +382,20 @@ class EntityLoader:
|
|
|
342
382
|
loaded_entity.api_expose = api_expose
|
|
343
383
|
loaded_entity.api_verbs = api_verbs
|
|
344
384
|
loaded_entity.relations_dependencies = relations_dependencies
|
|
385
|
+
loaded_entity.insert_function_class_name = insert_function_class_name
|
|
386
|
+
loaded_entity.update_function_class_name = update_function_class_name
|
|
345
387
|
|
|
346
388
|
namespace.loaded_entities[entity_resource] = loaded_entity
|
|
347
389
|
|
|
348
|
-
return (
|
|
390
|
+
return (
|
|
391
|
+
dto_class_name,
|
|
392
|
+
entity_class_name,
|
|
393
|
+
namespace,
|
|
394
|
+
api_expose,
|
|
395
|
+
api_verbs,
|
|
396
|
+
insert_function_class_name,
|
|
397
|
+
update_function_class_name,
|
|
398
|
+
)
|
|
349
399
|
|
|
350
400
|
def _safe_exec(self, source_code, context, description):
|
|
351
401
|
try:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nsj_rest_lib2
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.29
|
|
4
4
|
Summary: Biblioteca para permitir a distribuição de rotas dinâmicas numa API, configuradas por meio de EDLs declarativos (em formato JSON).
|
|
5
5
|
Home-page: https://github.com/Nasajon/nsj_rest_lib2
|
|
6
6
|
Author: Nasajon Sistemas
|
|
@@ -12,7 +12,7 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Requires-Python: >=3.4
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
-
Requires-Dist: nsj-rest-lib<
|
|
15
|
+
Requires-Dist: nsj-rest-lib<6.0.0,>=5.1.3
|
|
16
16
|
Requires-Dist: redis<7.0.0,>=6.4.0
|
|
17
17
|
Requires-Dist: nsj-multi-database-lib<3.0.0,>=2.0.1
|
|
18
18
|
Requires-Dist: pydantic<3.0.0,>=2.11.9
|
|
@@ -4,15 +4,17 @@ nsj_rest_lib2/redis_config.py,sha256=4KLcvYS3nJO7PMQgF6F9_j6r-TyqcS7TBbd3LEQuKDU
|
|
|
4
4
|
nsj_rest_lib2/settings.py,sha256=Hn_o1HZmievnYb8D1kNT2Nq-OEjxbyNjOiOpbnFsMwE,367
|
|
5
5
|
nsj_rest_lib2/compiler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
nsj_rest_lib2/compiler/ai_compiler.py,sha256=shAtN4T0ai_52qh15L3mK1QbeC6glHOR6C3J3gj14II,9029
|
|
7
|
-
nsj_rest_lib2/compiler/compiler.py,sha256=
|
|
7
|
+
nsj_rest_lib2/compiler/compiler.py,sha256=8avORndGTPOlQO3-s8PkC3fsfCLsUzBW4Qfq-UaueEE,30403
|
|
8
8
|
nsj_rest_lib2/compiler/compiler_structures.py,sha256=a_DF_nU4VgCt0sWJI03Ky6fPHvoIM0cjMkwQb_dYv6Q,1437
|
|
9
|
-
nsj_rest_lib2/compiler/dto_compiler.py,sha256=
|
|
9
|
+
nsj_rest_lib2/compiler/dto_compiler.py,sha256=ksZ2eYd_urrs6HBNK1m5_LhQhhq7i60GfSzD-AaF0fU,6743
|
|
10
10
|
nsj_rest_lib2/compiler/entity_compiler.py,sha256=-mDA1-dHKYp0umQi1A4GbA0F1hlaC-gQRqj69vkADC4,6536
|
|
11
|
-
nsj_rest_lib2/compiler/
|
|
12
|
-
nsj_rest_lib2/compiler/
|
|
11
|
+
nsj_rest_lib2/compiler/function_compiler.py,sha256=t5e_NoDB0IckiIEuYLsvk2lPSwrcrjL91s4LTQkpRqA,18085
|
|
12
|
+
nsj_rest_lib2/compiler/function_model.py,sha256=iSKMlCSZDWlP_aTdlcbYQhsEAIMH-XbSJUU0-KNtLCs,2066
|
|
13
|
+
nsj_rest_lib2/compiler/model.py,sha256=8UxzTvcNgZQdLwC592o8ZMVPhG3AloBCg5q2V72Up8U,1688
|
|
14
|
+
nsj_rest_lib2/compiler/property_compiler.py,sha256=7cShFGtbZwSamyS9frSd_CebdmTmWLxpFDsq6vUqj80,47894
|
|
13
15
|
nsj_rest_lib2/compiler/edl_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
16
|
nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py,sha256=664QBDcOgVnyfwtUOXO1W7AKaZhueBG335x5DuogruY,7644
|
|
15
|
-
nsj_rest_lib2/compiler/edl_model/api_model.py,sha256=
|
|
17
|
+
nsj_rest_lib2/compiler/edl_model/api_model.py,sha256=7RpZkUGROZmTBh2psgTG_b3e4xxjc3uBr1EYb-wiAkc,3810
|
|
16
18
|
nsj_rest_lib2/compiler/edl_model/column_meta_model.py,sha256=s0sEVkoW1hV2_hto1mws4XhzKGH_b4NzhaOiwFH25Ks,694
|
|
17
19
|
nsj_rest_lib2/compiler/edl_model/entity_model.py,sha256=Yc6wvjsiwacmz796mZIU-i9hxzNV9yuLPdULGKYHNbM,854
|
|
18
20
|
nsj_rest_lib2/compiler/edl_model/entity_model_base.py,sha256=eRn0pirIPHvniqGpT0xE-mmgqz5RIVtqghxcnfxKNdQ,4345
|
|
@@ -24,13 +26,14 @@ nsj_rest_lib2/compiler/edl_model/repository_model.py,sha256=OmtUzSq2LKmM76VXefGr
|
|
|
24
26
|
nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py,sha256=NtMVZeOPu3LJwXI-8tCOLVuQiGua_0t7kL1h9gL7HuM,657
|
|
25
27
|
nsj_rest_lib2/compiler/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
28
|
nsj_rest_lib2/compiler/util/str_util.py,sha256=0ReIQ2Vy4zAmVMvGv0FcUehRQw15hlz0e7yDsF89ghk,1178
|
|
27
|
-
nsj_rest_lib2/compiler/util/type_naming_util.py,sha256=
|
|
29
|
+
nsj_rest_lib2/compiler/util/type_naming_util.py,sha256=fPyzsEsbG9sgzaUJghamijcmZ6Odh_rIv3zk-lcP5pQ,1419
|
|
28
30
|
nsj_rest_lib2/compiler/util/type_util.py,sha256=HTKOH4uRTOY0YgoM8oUv_6cEcReE_bgKYXFBsQCb-3A,357
|
|
29
31
|
nsj_rest_lib2/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
-
nsj_rest_lib2/controller/dynamic_controller.py,sha256=
|
|
32
|
+
nsj_rest_lib2/controller/dynamic_controller.py,sha256=UJtlr0_A6bGJ1gD24oj3481tCbJUgshLFuBRIU-eDEs,18878
|
|
31
33
|
nsj_rest_lib2/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
nsj_rest_lib2/service/
|
|
33
|
-
nsj_rest_lib2
|
|
34
|
-
nsj_rest_lib2-0.0.
|
|
35
|
-
nsj_rest_lib2-0.0.
|
|
36
|
-
nsj_rest_lib2-0.0.
|
|
34
|
+
nsj_rest_lib2/service/entity_config_writer.py,sha256=DC8M4BYKfaOkNty1YFmAmWiNvENjvmiUqDKgsAV3eNc,4688
|
|
35
|
+
nsj_rest_lib2/service/entity_loader.py,sha256=I8Ua2CPCxxUovHJn8SSRz0bYfmdFqfWj-JQfNTBBypc,17842
|
|
36
|
+
nsj_rest_lib2-0.0.29.dist-info/METADATA,sha256=n4ENC9nHnSZETVqLpUKWLDM8qpf6U_nzpWpG9z1Af9w,1094
|
|
37
|
+
nsj_rest_lib2-0.0.29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
38
|
+
nsj_rest_lib2-0.0.29.dist-info/top_level.txt,sha256=L6zh0EfH8_rur7OJ8_V-El-XEMf4qg3bkF8ADgqLVIA,14
|
|
39
|
+
nsj_rest_lib2-0.0.29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|