nsj-rest-lib2 0.0.32__tar.gz → 0.0.34__tar.gz
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-0.0.32 → nsj_rest_lib2-0.0.34}/PKG-INFO +2 -2
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/compiler.py +35 -15
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/model.py +1 -0
- nsj_rest_lib2-0.0.34/nsj_rest_lib2/controller/dynamic_controller.py +413 -0
- nsj_rest_lib2-0.0.34/nsj_rest_lib2/dto/__init__.py +1 -0
- nsj_rest_lib2-0.0.34/nsj_rest_lib2/dto/escopo_dto.py +39 -0
- nsj_rest_lib2-0.0.34/nsj_rest_lib2/entity/escopo_entity.py +15 -0
- nsj_rest_lib2-0.0.34/nsj_rest_lib2/service/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/service/entity_config_writer.py +2 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/service/entity_loader.py +13 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/PKG-INFO +2 -2
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/SOURCES.txt +8 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/requires.txt +1 -1
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/setup.cfg +2 -2
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/tests/test_function_handler_compilation.py +9 -2
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/tests/test_migration_generation.py +11 -1
- nsj_rest_lib2-0.0.32/nsj_rest_lib2/controller/dynamic_controller.py +0 -528
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/README.md +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/compiler_structures.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/dto_compiler.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/api_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/entity_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/entity_model_base.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/entity_model_root.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/index_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/primitives.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/property_meta_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/repository_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/entity_compiler.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/function_get_delete_compiler.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/function_insert_update_compiler.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/function_model.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler_alter_table.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler_create_table.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler_util.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/property_compiler.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/relation_ref.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/str_util.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/type_naming_util.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/type_util.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/controller/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32/nsj_rest_lib2/service → nsj_rest_lib2-0.0.34/nsj_rest_lib2/entity}/__init__.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/exception.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/redis_config.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/settings.py +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/dependency_links.txt +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/top_level.txt +0 -0
- {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nsj_rest_lib2
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
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<7.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
|
|
@@ -33,6 +33,7 @@ from nsj_rest_lib2.compiler.util.relation_ref import RelationRefParser
|
|
|
33
33
|
from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
|
|
34
34
|
|
|
35
35
|
from nsj_rest_lib2.settings import get_logger
|
|
36
|
+
from nsj_rest_lib2.dto.escopo_dto import EscopoDTO
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
class EDLCompiler:
|
|
@@ -44,13 +45,24 @@ class EDLCompiler:
|
|
|
44
45
|
self._function_get_delete_compiler = FunctionGetDeleteCompiler()
|
|
45
46
|
|
|
46
47
|
def compile_models(
|
|
47
|
-
self,
|
|
48
|
+
self,
|
|
49
|
+
entity_models: dict[str, EntityModel],
|
|
50
|
+
escopos: dict[str, EscopoDTO],
|
|
48
51
|
) -> list[CompilerResult]:
|
|
49
52
|
|
|
50
53
|
compiler_results = []
|
|
51
54
|
for entity_model_id in entity_models:
|
|
52
55
|
entity_model = entity_models[entity_model_id]
|
|
53
|
-
|
|
56
|
+
escopo_dto = escopos.get(entity_model.escopo)
|
|
57
|
+
if escopo_dto is None:
|
|
58
|
+
raise Exception(
|
|
59
|
+
f"EscopoDTO não informado para o escopo: {entity_model.escopo}."
|
|
60
|
+
)
|
|
61
|
+
compiler_result = self._compile_model(
|
|
62
|
+
entity_model,
|
|
63
|
+
entity_models,
|
|
64
|
+
escopo=escopo_dto,
|
|
65
|
+
)
|
|
54
66
|
if compiler_result:
|
|
55
67
|
compiler_results.append(compiler_result)
|
|
56
68
|
|
|
@@ -60,6 +72,7 @@ class EDLCompiler:
|
|
|
60
72
|
self,
|
|
61
73
|
edl_json: dict[str, Any],
|
|
62
74
|
dependencies_edls: list[dict[str, Any]],
|
|
75
|
+
escopo: EscopoDTO,
|
|
63
76
|
) -> CompilerResult | None:
|
|
64
77
|
entity_model = EntityModel(**edl_json)
|
|
65
78
|
|
|
@@ -71,35 +84,36 @@ class EDLCompiler:
|
|
|
71
84
|
dependency_entity_model = EntityModel(**dependency_edl)
|
|
72
85
|
entity_models.append(dependency_entity_model)
|
|
73
86
|
|
|
74
|
-
return self.compile_model(entity_model, entity_models)
|
|
87
|
+
return self.compile_model(entity_model, entity_models, escopo=escopo)
|
|
75
88
|
|
|
76
89
|
def compile_model(
|
|
77
90
|
self,
|
|
78
91
|
entity_model: EntityModelBase,
|
|
79
92
|
dependencies_models: list[tuple[str, EntityModelBase]],
|
|
93
|
+
escopo: EscopoDTO,
|
|
80
94
|
) -> CompilerResult | None:
|
|
81
95
|
entity_models = {}
|
|
82
96
|
for dependency_entity_model in dependencies_models:
|
|
83
97
|
complete_entity_id = dependency_entity_model[0]
|
|
84
98
|
entity_models[complete_entity_id] = dependency_entity_model[1]
|
|
85
99
|
|
|
86
|
-
return self._compile_model(entity_model, entity_models)
|
|
100
|
+
return self._compile_model(entity_model, entity_models, escopo=escopo)
|
|
87
101
|
|
|
88
102
|
def _compile_model(
|
|
89
103
|
self,
|
|
90
104
|
entity_model: EntityModelBase,
|
|
91
105
|
entity_models: dict[str, EntityModel],
|
|
92
|
-
escopo:
|
|
106
|
+
escopo: EscopoDTO | None,
|
|
93
107
|
prefx_class_name: str = "",
|
|
94
108
|
) -> CompilerResult | None:
|
|
95
109
|
if entity_model.mixin:
|
|
96
110
|
return None
|
|
97
111
|
|
|
98
|
-
if escopo is None
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
112
|
+
if escopo is None:
|
|
113
|
+
raise Exception(
|
|
114
|
+
f"EscopoDTO não informado para a entidade: {getattr(entity_model, 'id', '<unknown>')}."
|
|
115
|
+
)
|
|
116
|
+
escopo_codigo = escopo.codigo
|
|
103
117
|
|
|
104
118
|
# Tratando dos dados base para a extensão parcial
|
|
105
119
|
partial_metadata: dict[str, str] | None = None
|
|
@@ -250,7 +264,7 @@ class EDLCompiler:
|
|
|
250
264
|
) = self._properties_compiler.compile(
|
|
251
265
|
properties_structure,
|
|
252
266
|
map_unique_by_property,
|
|
253
|
-
|
|
267
|
+
escopo_codigo,
|
|
254
268
|
entity_model,
|
|
255
269
|
entity_models,
|
|
256
270
|
prefx_class_name,
|
|
@@ -371,9 +385,7 @@ class EDLCompiler:
|
|
|
371
385
|
compiler_result.list_function_type_class_name = list_function_type_class
|
|
372
386
|
compiler_result.delete_function_type_class_name = delete_function_type_class
|
|
373
387
|
compiler_result.source_get_function_type = get_function_code.strip() or None
|
|
374
|
-
compiler_result.source_list_function_type = (
|
|
375
|
-
list_function_code.strip() or None
|
|
376
|
-
)
|
|
388
|
+
compiler_result.source_list_function_type = list_function_code.strip() or None
|
|
377
389
|
compiler_result.source_delete_function_type = (
|
|
378
390
|
delete_function_code.strip() or None
|
|
379
391
|
)
|
|
@@ -392,6 +404,7 @@ class EDLCompiler:
|
|
|
392
404
|
compiler_result.api_expose = entity_model.api.expose
|
|
393
405
|
compiler_result.api_resource = entity_model.api.resource
|
|
394
406
|
compiler_result.api_verbs = entity_model.api.verbs
|
|
407
|
+
compiler_result.service_account = escopo.service_account
|
|
395
408
|
|
|
396
409
|
get_logger().debug(f"código gerado para a entidade: {entity_model.id}")
|
|
397
410
|
get_logger().debug("DTO Code:")
|
|
@@ -848,7 +861,14 @@ if __name__ == "__main__":
|
|
|
848
861
|
entities[complete_entity_id] = entity_model
|
|
849
862
|
|
|
850
863
|
compiler = EDLCompiler()
|
|
851
|
-
|
|
864
|
+
escopos = {}
|
|
865
|
+
for entity_model in entities.values():
|
|
866
|
+
if entity_model.escopo not in escopos:
|
|
867
|
+
escopos[entity_model.escopo] = EscopoDTO(
|
|
868
|
+
codigo=entity_model.escopo,
|
|
869
|
+
service_account=None,
|
|
870
|
+
)
|
|
871
|
+
compiler_results = compiler.compile_models(entities, escopos)
|
|
852
872
|
|
|
853
873
|
with open("output_compilacao_local.py", "w") as f:
|
|
854
874
|
for compiler_result in compiler_results:
|
|
@@ -42,6 +42,7 @@ class CompilerResult:
|
|
|
42
42
|
self.api_expose: bool | None = None
|
|
43
43
|
self.api_resource: str | None = None
|
|
44
44
|
self.api_verbs: list[str] | None = None
|
|
45
|
+
self.service_account: str | None = None
|
|
45
46
|
self.relations_dependencies: list[RelationDependency] | None = None
|
|
46
47
|
self.insert_function_class_name: str | None = None
|
|
47
48
|
self.insert_function_name: str | None = None
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
|
|
5
|
+
from flask import Flask, request
|
|
6
|
+
|
|
7
|
+
from nsj_rest_lib.settings import APP_NAME
|
|
8
|
+
|
|
9
|
+
from nsj_gcf_utils.rest_error_util import format_json_error
|
|
10
|
+
|
|
11
|
+
from nsj_multi_database_lib.decorator.multi_database import multi_database
|
|
12
|
+
|
|
13
|
+
from nsj_rest_lib.controller.controller_util import DEFAULT_RESP_HEADERS
|
|
14
|
+
from nsj_rest_lib.controller.list_route import ListRoute
|
|
15
|
+
from nsj_rest_lib.controller.get_route import GetRoute
|
|
16
|
+
from nsj_rest_lib.controller.post_route import PostRoute
|
|
17
|
+
from nsj_rest_lib.controller.put_route import PutRoute
|
|
18
|
+
from nsj_rest_lib.controller.patch_route import PatchRoute
|
|
19
|
+
from nsj_rest_lib.controller.delete_route import DeleteRoute
|
|
20
|
+
|
|
21
|
+
from nsj_rest_lib2.exception import MissingEntityConfigException
|
|
22
|
+
from nsj_rest_lib2.service.entity_loader import EntityLoader
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _get_query_args() -> tuple[str, str, bool]:
|
|
26
|
+
# Tentando ler do query args
|
|
27
|
+
query_args = request.args
|
|
28
|
+
tenant = query_args.get("tenant")
|
|
29
|
+
grupo_empresarial = query_args.get("grupo_empresarial")
|
|
30
|
+
force_reload = query_args.get("force_reload", "false").lower() == "true"
|
|
31
|
+
|
|
32
|
+
# Tentando ler do corpo da requisição
|
|
33
|
+
try:
|
|
34
|
+
body_str = request.data.decode("utf-8")
|
|
35
|
+
body_json = json.loads(body_str)
|
|
36
|
+
|
|
37
|
+
if not tenant:
|
|
38
|
+
tenant = body_json.get("tenant")
|
|
39
|
+
if not grupo_empresarial:
|
|
40
|
+
grupo_empresarial = body_json.get("grupo_empresarial")
|
|
41
|
+
except:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
return (str(tenant), str(grupo_empresarial), force_reload)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _endpoint_name(func: Any, multidb: bool, root: str) -> str:
|
|
48
|
+
suffix = "_mb" if multidb else ""
|
|
49
|
+
return f"{root}_{func.__name__}{suffix}"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def setup_dynamic_routes(
|
|
53
|
+
flask_app: Flask,
|
|
54
|
+
multidb: bool = True,
|
|
55
|
+
dynamic_root_path: str = "edl1",
|
|
56
|
+
injector_factory: Any = None,
|
|
57
|
+
escopo_in_url: bool = False,
|
|
58
|
+
) -> None:
|
|
59
|
+
|
|
60
|
+
if not escopo_in_url:
|
|
61
|
+
COLLECTION_DYNAMIC_ROUTE = f"/{APP_NAME}/{dynamic_root_path}/<entity_resource>"
|
|
62
|
+
ONE_DYNAMIC_ROUTE = f"/{APP_NAME}/{dynamic_root_path}/<entity_resource>/<id>"
|
|
63
|
+
else:
|
|
64
|
+
COLLECTION_DYNAMIC_ROUTE = (
|
|
65
|
+
f"/{APP_NAME}/{dynamic_root_path}/<entity_escopo>/<entity_resource>"
|
|
66
|
+
)
|
|
67
|
+
ONE_DYNAMIC_ROUTE = (
|
|
68
|
+
f"/{APP_NAME}/{dynamic_root_path}/<entity_escopo>/<entity_resource>/<id>"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def _dynamic_route_wrapper(
|
|
72
|
+
route_builder: Callable[[tuple[Any, ...]], Callable[..., Any]],
|
|
73
|
+
endpoint_suffix: str | None = None,
|
|
74
|
+
) -> Callable[..., Any]:
|
|
75
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
76
|
+
if "entity_resource" not in kwargs:
|
|
77
|
+
msg = "Faltando parâmetro identificador da entidade na URL."
|
|
78
|
+
return (format_json_error(msg), 400, {**DEFAULT_RESP_HEADERS})
|
|
79
|
+
entity_resource = kwargs.pop("entity_resource")
|
|
80
|
+
|
|
81
|
+
entity_escopo = kwargs.pop("entity_escopo", "")
|
|
82
|
+
|
|
83
|
+
tenant, grupo_empresarial, force_reload = _get_query_args()
|
|
84
|
+
|
|
85
|
+
try:
|
|
86
|
+
entity_loader = EntityLoader()
|
|
87
|
+
entity_config = entity_loader.load_entity_source(
|
|
88
|
+
entity_resource,
|
|
89
|
+
tenant,
|
|
90
|
+
grupo_empresarial,
|
|
91
|
+
escopo=entity_escopo,
|
|
92
|
+
force_reload=force_reload,
|
|
93
|
+
)
|
|
94
|
+
except MissingEntityConfigException:
|
|
95
|
+
msg = f"Entity configuration for {entity_resource} not found."
|
|
96
|
+
return (format_json_error(msg), 412, {**DEFAULT_RESP_HEADERS})
|
|
97
|
+
|
|
98
|
+
(
|
|
99
|
+
_,
|
|
100
|
+
_,
|
|
101
|
+
_,
|
|
102
|
+
_,
|
|
103
|
+
_,
|
|
104
|
+
service_account,
|
|
105
|
+
*rest,
|
|
106
|
+
) = entity_config
|
|
107
|
+
|
|
108
|
+
route_handler = route_builder(entity_config)
|
|
109
|
+
|
|
110
|
+
if multidb:
|
|
111
|
+
route_handler = multi_database(service_account)(route_handler)
|
|
112
|
+
|
|
113
|
+
return route_handler(*args, **kwargs)
|
|
114
|
+
|
|
115
|
+
wrapper.__name__ = endpoint_suffix or f"{route_builder.__name__}_wrapper"
|
|
116
|
+
return wrapper
|
|
117
|
+
|
|
118
|
+
def list_dynamic_builder(entity_config: tuple[Any, ...]) -> Callable[..., Any]:
|
|
119
|
+
(
|
|
120
|
+
dto_class_name,
|
|
121
|
+
entity_class_name,
|
|
122
|
+
etities_dict,
|
|
123
|
+
api_expose,
|
|
124
|
+
api_verbs,
|
|
125
|
+
_service_account,
|
|
126
|
+
_insert_function_class_name,
|
|
127
|
+
_update_function_class_name,
|
|
128
|
+
_insert_function_name,
|
|
129
|
+
_update_function_name,
|
|
130
|
+
_get_function_name,
|
|
131
|
+
list_function_name,
|
|
132
|
+
_delete_function_name,
|
|
133
|
+
_get_function_type_class_name,
|
|
134
|
+
list_function_type_class_name,
|
|
135
|
+
_delete_function_type_class_name,
|
|
136
|
+
) = entity_config
|
|
137
|
+
|
|
138
|
+
def list_dynamic(*args: Any, **kwargs: Any) -> Any:
|
|
139
|
+
if not api_expose or "GET" not in api_verbs:
|
|
140
|
+
return ("", 405, {})
|
|
141
|
+
|
|
142
|
+
route = ListRoute(
|
|
143
|
+
url=COLLECTION_DYNAMIC_ROUTE,
|
|
144
|
+
http_method="GET",
|
|
145
|
+
dto_class=etities_dict[dto_class_name],
|
|
146
|
+
entity_class=etities_dict[entity_class_name],
|
|
147
|
+
injector_factory=injector_factory,
|
|
148
|
+
list_function_name=list_function_name,
|
|
149
|
+
list_function_type_class=etities_dict.get(
|
|
150
|
+
list_function_type_class_name
|
|
151
|
+
),
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
return route.handle_request(*args, **kwargs)
|
|
155
|
+
|
|
156
|
+
return list_dynamic
|
|
157
|
+
|
|
158
|
+
def get_dynamic_builder(entity_config: tuple[Any, ...]) -> Callable[..., Any]:
|
|
159
|
+
(
|
|
160
|
+
dto_class_name,
|
|
161
|
+
entity_class_name,
|
|
162
|
+
etities_dict,
|
|
163
|
+
api_expose,
|
|
164
|
+
api_verbs,
|
|
165
|
+
_service_account,
|
|
166
|
+
_insert_function_class_name,
|
|
167
|
+
_update_function_class_name,
|
|
168
|
+
_insert_function_name,
|
|
169
|
+
_update_function_name,
|
|
170
|
+
get_function_name,
|
|
171
|
+
_list_function_name,
|
|
172
|
+
_delete_function_name,
|
|
173
|
+
get_function_type_class_name,
|
|
174
|
+
_list_function_type_class_name,
|
|
175
|
+
_delete_function_type_class_name,
|
|
176
|
+
) = entity_config
|
|
177
|
+
|
|
178
|
+
def get_dynamic(*args: Any, **kwargs: Any) -> Any:
|
|
179
|
+
if not api_expose or "GET" not in api_verbs:
|
|
180
|
+
return ("", 405, {})
|
|
181
|
+
|
|
182
|
+
route = GetRoute(
|
|
183
|
+
url=ONE_DYNAMIC_ROUTE,
|
|
184
|
+
http_method="GET",
|
|
185
|
+
dto_class=etities_dict[dto_class_name],
|
|
186
|
+
entity_class=etities_dict[entity_class_name],
|
|
187
|
+
injector_factory=injector_factory,
|
|
188
|
+
get_function_name=get_function_name,
|
|
189
|
+
get_function_type_class=etities_dict.get(get_function_type_class_name),
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
return route.handle_request(*args, **kwargs)
|
|
193
|
+
|
|
194
|
+
return get_dynamic
|
|
195
|
+
|
|
196
|
+
def post_dynamic_builder(entity_config: tuple[Any, ...]) -> Callable[..., Any]:
|
|
197
|
+
(
|
|
198
|
+
dto_class_name,
|
|
199
|
+
entity_class_name,
|
|
200
|
+
etities_dict,
|
|
201
|
+
api_expose,
|
|
202
|
+
api_verbs,
|
|
203
|
+
_service_account,
|
|
204
|
+
insert_function_class_name,
|
|
205
|
+
_update_function_class_name,
|
|
206
|
+
insert_function_name,
|
|
207
|
+
_update_function_name,
|
|
208
|
+
_get_function_name,
|
|
209
|
+
_list_function_name,
|
|
210
|
+
_delete_function_name,
|
|
211
|
+
_get_function_type_class_name,
|
|
212
|
+
_list_function_type_class_name,
|
|
213
|
+
_delete_function_type_class_name,
|
|
214
|
+
) = entity_config
|
|
215
|
+
|
|
216
|
+
def post_dynamic(*args: Any, **kwargs: Any) -> Any:
|
|
217
|
+
if not api_expose or "POST" not in api_verbs:
|
|
218
|
+
return ("", 405, {})
|
|
219
|
+
|
|
220
|
+
insert_function_type_class = (
|
|
221
|
+
etities_dict.get(insert_function_class_name)
|
|
222
|
+
if insert_function_class_name
|
|
223
|
+
else None
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
route = PostRoute(
|
|
227
|
+
url=COLLECTION_DYNAMIC_ROUTE,
|
|
228
|
+
http_method="POST",
|
|
229
|
+
dto_class=etities_dict[dto_class_name],
|
|
230
|
+
entity_class=etities_dict[entity_class_name],
|
|
231
|
+
injector_factory=injector_factory,
|
|
232
|
+
insert_function_type_class=insert_function_type_class,
|
|
233
|
+
insert_function_name=insert_function_name,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
return route.handle_request(*args, **kwargs)
|
|
237
|
+
|
|
238
|
+
return post_dynamic
|
|
239
|
+
|
|
240
|
+
def put_dynamic_builder(entity_config: tuple[Any, ...]) -> Callable[..., Any]:
|
|
241
|
+
(
|
|
242
|
+
dto_class_name,
|
|
243
|
+
entity_class_name,
|
|
244
|
+
etities_dict,
|
|
245
|
+
api_expose,
|
|
246
|
+
api_verbs,
|
|
247
|
+
_service_account,
|
|
248
|
+
_insert_function_class_name,
|
|
249
|
+
update_function_class_name,
|
|
250
|
+
_insert_function_name,
|
|
251
|
+
update_function_name,
|
|
252
|
+
_get_function_name,
|
|
253
|
+
_list_function_name,
|
|
254
|
+
_delete_function_name,
|
|
255
|
+
_get_function_type_class_name,
|
|
256
|
+
_list_function_type_class_name,
|
|
257
|
+
_delete_function_type_class_name,
|
|
258
|
+
) = entity_config
|
|
259
|
+
|
|
260
|
+
def put_dynamic(*args: Any, **kwargs: Any) -> Any:
|
|
261
|
+
if not api_expose or "PUT" not in api_verbs:
|
|
262
|
+
return ("", 405, {})
|
|
263
|
+
|
|
264
|
+
update_function_type_class = (
|
|
265
|
+
etities_dict.get(update_function_class_name)
|
|
266
|
+
if update_function_class_name
|
|
267
|
+
else None
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
route = PutRoute(
|
|
271
|
+
url=ONE_DYNAMIC_ROUTE,
|
|
272
|
+
http_method="PUT",
|
|
273
|
+
dto_class=etities_dict[dto_class_name],
|
|
274
|
+
entity_class=etities_dict[entity_class_name],
|
|
275
|
+
injector_factory=injector_factory,
|
|
276
|
+
update_function_type_class=update_function_type_class,
|
|
277
|
+
update_function_name=update_function_name,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
return route.handle_request(*args, **kwargs)
|
|
281
|
+
|
|
282
|
+
return put_dynamic
|
|
283
|
+
|
|
284
|
+
def patch_dynamic_builder(entity_config: tuple[Any, ...]) -> Callable[..., Any]:
|
|
285
|
+
(
|
|
286
|
+
dto_class_name,
|
|
287
|
+
entity_class_name,
|
|
288
|
+
etities_dict,
|
|
289
|
+
api_expose,
|
|
290
|
+
api_verbs,
|
|
291
|
+
_service_account,
|
|
292
|
+
_insert_function_class_name,
|
|
293
|
+
_update_function_class_name,
|
|
294
|
+
_insert_function_name,
|
|
295
|
+
_update_function_name,
|
|
296
|
+
_get_function_name,
|
|
297
|
+
_list_function_name,
|
|
298
|
+
_delete_function_name,
|
|
299
|
+
*_,
|
|
300
|
+
) = entity_config
|
|
301
|
+
|
|
302
|
+
def patch_dynamic(*args: Any, **kwargs: Any) -> Any:
|
|
303
|
+
if not api_expose or "PATCH" not in api_verbs:
|
|
304
|
+
return ("", 405, {})
|
|
305
|
+
|
|
306
|
+
route = PatchRoute(
|
|
307
|
+
url=ONE_DYNAMIC_ROUTE,
|
|
308
|
+
http_method="PATCH",
|
|
309
|
+
dto_class=etities_dict[dto_class_name],
|
|
310
|
+
entity_class=etities_dict[entity_class_name],
|
|
311
|
+
injector_factory=injector_factory,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
return route.handle_request(*args, **kwargs)
|
|
315
|
+
|
|
316
|
+
return patch_dynamic
|
|
317
|
+
|
|
318
|
+
def delete_dynamic_builder(entity_config: tuple[Any, ...]) -> Callable[..., Any]:
|
|
319
|
+
(
|
|
320
|
+
dto_class_name,
|
|
321
|
+
entity_class_name,
|
|
322
|
+
etities_dict,
|
|
323
|
+
api_expose,
|
|
324
|
+
api_verbs,
|
|
325
|
+
_service_account,
|
|
326
|
+
_insert_function_class_name,
|
|
327
|
+
_update_function_class_name,
|
|
328
|
+
_insert_function_name,
|
|
329
|
+
_update_function_name,
|
|
330
|
+
_get_function_name,
|
|
331
|
+
_list_function_name,
|
|
332
|
+
delete_function_name,
|
|
333
|
+
_get_function_type_class_name,
|
|
334
|
+
_list_function_type_class_name,
|
|
335
|
+
delete_function_type_class_name,
|
|
336
|
+
) = entity_config
|
|
337
|
+
|
|
338
|
+
def delete_dynamic(*args: Any, **kwargs: Any) -> Any:
|
|
339
|
+
if not api_expose or "DELETE" not in api_verbs:
|
|
340
|
+
return ("", 405, {})
|
|
341
|
+
|
|
342
|
+
route = DeleteRoute(
|
|
343
|
+
url=ONE_DYNAMIC_ROUTE,
|
|
344
|
+
http_method="DELETE",
|
|
345
|
+
dto_class=etities_dict[dto_class_name],
|
|
346
|
+
entity_class=etities_dict[entity_class_name],
|
|
347
|
+
injector_factory=injector_factory,
|
|
348
|
+
delete_function_name=delete_function_name,
|
|
349
|
+
delete_function_type_class=etities_dict.get(
|
|
350
|
+
delete_function_type_class_name
|
|
351
|
+
),
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
return route.handle_request(*args, **kwargs)
|
|
355
|
+
|
|
356
|
+
return delete_dynamic
|
|
357
|
+
|
|
358
|
+
list_dynamic = _dynamic_route_wrapper(
|
|
359
|
+
list_dynamic_builder, endpoint_suffix="list_dynamic"
|
|
360
|
+
)
|
|
361
|
+
get_dynamic = _dynamic_route_wrapper(
|
|
362
|
+
get_dynamic_builder, endpoint_suffix="get_dynamic"
|
|
363
|
+
)
|
|
364
|
+
post_dynamic = _dynamic_route_wrapper(
|
|
365
|
+
post_dynamic_builder, endpoint_suffix="post_dynamic"
|
|
366
|
+
)
|
|
367
|
+
put_dynamic = _dynamic_route_wrapper(
|
|
368
|
+
put_dynamic_builder, endpoint_suffix="put_dynamic"
|
|
369
|
+
)
|
|
370
|
+
patch_dynamic = _dynamic_route_wrapper(
|
|
371
|
+
patch_dynamic_builder, endpoint_suffix="patch_dynamic"
|
|
372
|
+
)
|
|
373
|
+
delete_dynamic = _dynamic_route_wrapper(
|
|
374
|
+
delete_dynamic_builder, endpoint_suffix="delete_dynamic"
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
# Registrando as rotas no flask
|
|
378
|
+
flask_app.add_url_rule(
|
|
379
|
+
COLLECTION_DYNAMIC_ROUTE,
|
|
380
|
+
endpoint=_endpoint_name(list_dynamic, multidb, dynamic_root_path),
|
|
381
|
+
view_func=list_dynamic,
|
|
382
|
+
methods=["GET"],
|
|
383
|
+
)
|
|
384
|
+
flask_app.add_url_rule(
|
|
385
|
+
ONE_DYNAMIC_ROUTE,
|
|
386
|
+
endpoint=_endpoint_name(get_dynamic, multidb, dynamic_root_path),
|
|
387
|
+
view_func=get_dynamic,
|
|
388
|
+
methods=["GET"],
|
|
389
|
+
)
|
|
390
|
+
flask_app.add_url_rule(
|
|
391
|
+
COLLECTION_DYNAMIC_ROUTE,
|
|
392
|
+
endpoint=_endpoint_name(post_dynamic, multidb, dynamic_root_path),
|
|
393
|
+
view_func=post_dynamic,
|
|
394
|
+
methods=["POST"],
|
|
395
|
+
)
|
|
396
|
+
flask_app.add_url_rule(
|
|
397
|
+
ONE_DYNAMIC_ROUTE,
|
|
398
|
+
endpoint=_endpoint_name(put_dynamic, multidb, dynamic_root_path),
|
|
399
|
+
view_func=put_dynamic,
|
|
400
|
+
methods=["PUT"],
|
|
401
|
+
)
|
|
402
|
+
flask_app.add_url_rule(
|
|
403
|
+
ONE_DYNAMIC_ROUTE,
|
|
404
|
+
endpoint=_endpoint_name(patch_dynamic, multidb, dynamic_root_path),
|
|
405
|
+
view_func=patch_dynamic,
|
|
406
|
+
methods=["PATCH"],
|
|
407
|
+
)
|
|
408
|
+
flask_app.add_url_rule(
|
|
409
|
+
ONE_DYNAMIC_ROUTE,
|
|
410
|
+
endpoint=_endpoint_name(delete_dynamic, multidb, dynamic_root_path),
|
|
411
|
+
view_func=delete_dynamic,
|
|
412
|
+
methods=["DELETE"],
|
|
413
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from nsj_rest_lib.decorator.dto import DTO
|
|
4
|
+
from nsj_rest_lib.descriptor.dto_field import DTOField
|
|
5
|
+
from nsj_rest_lib.descriptor.dto_field_validators import DTOFieldValidators
|
|
6
|
+
from nsj_rest_lib.dto.dto_base import DTOBase
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@DTO()
|
|
10
|
+
class EscopoDTO(DTOBase):
|
|
11
|
+
|
|
12
|
+
id: uuid.UUID = DTOField(
|
|
13
|
+
pk=True,
|
|
14
|
+
resume=True,
|
|
15
|
+
not_null=True,
|
|
16
|
+
default_value=uuid.uuid4,
|
|
17
|
+
strip=True,
|
|
18
|
+
min=36,
|
|
19
|
+
max=36,
|
|
20
|
+
validator=DTOFieldValidators().validate_uuid,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
codigo: str = DTOField(
|
|
24
|
+
resume=True,
|
|
25
|
+
not_null=True,
|
|
26
|
+
strip=True,
|
|
27
|
+
min=1,
|
|
28
|
+
max=100,
|
|
29
|
+
unique="escopo_codigo",
|
|
30
|
+
candidate_key=True,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
service_account: str = DTOField(
|
|
34
|
+
resume=True,
|
|
35
|
+
strip=True,
|
|
36
|
+
min=5,
|
|
37
|
+
max=320,
|
|
38
|
+
validator=DTOFieldValidators().validate_email,
|
|
39
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from nsj_rest_lib.entity.entity_base import EntityBase
|
|
4
|
+
from nsj_rest_lib.decorator.entity import Entity
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@Entity(
|
|
8
|
+
table_name="restlib2.escopo",
|
|
9
|
+
pk_field="id",
|
|
10
|
+
default_order_fields=["codigo", "id"],
|
|
11
|
+
)
|
|
12
|
+
class EscopoEntity(EntityBase):
|
|
13
|
+
id: uuid.UUID = None
|
|
14
|
+
codigo: str = None
|
|
15
|
+
service_account: str = None
|
|
File without changes
|
|
@@ -70,6 +70,7 @@ class EntityConfigWriter:
|
|
|
70
70
|
return {
|
|
71
71
|
"dto_class_name": compiler_result.dto_class_name,
|
|
72
72
|
"entity_class_name": compiler_result.entity_class_name,
|
|
73
|
+
"service_account": compiler_result.service_account,
|
|
73
74
|
"insert_function_class_name": compiler_result.insert_function_class_name,
|
|
74
75
|
"insert_function_name": compiler_result.insert_function_name,
|
|
75
76
|
"source_insert_function": compiler_result.source_insert_function,
|
|
@@ -141,6 +142,7 @@ class EntityConfigWriter:
|
|
|
141
142
|
compiler_result.source_get_function_type,
|
|
142
143
|
compiler_result.source_list_function_type,
|
|
143
144
|
compiler_result.source_delete_function_type,
|
|
145
|
+
compiler_result.service_account,
|
|
144
146
|
):
|
|
145
147
|
hasher.update(content)
|
|
146
148
|
|