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.
Files changed (56) hide show
  1. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/PKG-INFO +2 -2
  2. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/compiler.py +35 -15
  3. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/model.py +1 -0
  4. nsj_rest_lib2-0.0.34/nsj_rest_lib2/controller/dynamic_controller.py +413 -0
  5. nsj_rest_lib2-0.0.34/nsj_rest_lib2/dto/__init__.py +1 -0
  6. nsj_rest_lib2-0.0.34/nsj_rest_lib2/dto/escopo_dto.py +39 -0
  7. nsj_rest_lib2-0.0.34/nsj_rest_lib2/entity/escopo_entity.py +15 -0
  8. nsj_rest_lib2-0.0.34/nsj_rest_lib2/service/__init__.py +0 -0
  9. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/service/entity_config_writer.py +2 -0
  10. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/service/entity_loader.py +13 -0
  11. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/PKG-INFO +2 -2
  12. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/SOURCES.txt +8 -0
  13. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/requires.txt +1 -1
  14. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/setup.cfg +2 -2
  15. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/tests/test_function_handler_compilation.py +9 -2
  16. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/tests/test_migration_generation.py +11 -1
  17. nsj_rest_lib2-0.0.32/nsj_rest_lib2/controller/dynamic_controller.py +0 -528
  18. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/README.md +0 -0
  19. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/__init__.py +0 -0
  20. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/__init__.py +0 -0
  21. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/compiler_structures.py +0 -0
  22. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/dto_compiler.py +0 -0
  23. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/__init__.py +0 -0
  24. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py +0 -0
  25. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/api_model.py +0 -0
  26. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py +0 -0
  27. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/entity_model.py +0 -0
  28. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/entity_model_base.py +0 -0
  29. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/entity_model_root.py +0 -0
  30. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/index_model.py +0 -0
  31. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/primitives.py +0 -0
  32. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/property_meta_model.py +0 -0
  33. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/edl_model/repository_model.py +0 -0
  34. {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
  35. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/entity_compiler.py +0 -0
  36. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/function_get_delete_compiler.py +0 -0
  37. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/function_insert_update_compiler.py +0 -0
  38. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/function_model.py +0 -0
  39. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler.py +0 -0
  40. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler_alter_table.py +0 -0
  41. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler_create_table.py +0 -0
  42. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/migration_compiler_util.py +0 -0
  43. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/property_compiler.py +0 -0
  44. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/__init__.py +0 -0
  45. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/relation_ref.py +0 -0
  46. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/str_util.py +0 -0
  47. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/type_naming_util.py +0 -0
  48. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/compiler/util/type_util.py +0 -0
  49. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/controller/__init__.py +0 -0
  50. {nsj_rest_lib2-0.0.32/nsj_rest_lib2/service → nsj_rest_lib2-0.0.34/nsj_rest_lib2/entity}/__init__.py +0 -0
  51. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/exception.py +0 -0
  52. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/redis_config.py +0 -0
  53. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2/settings.py +0 -0
  54. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/dependency_links.txt +0 -0
  55. {nsj_rest_lib2-0.0.32 → nsj_rest_lib2-0.0.34}/nsj_rest_lib2.egg-info/top_level.txt +0 -0
  56. {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.32
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<6.0.0,>=5.1.3
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, entity_models: dict[str, EntityModel]
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
- compiler_result = self._compile_model(entity_model, entity_models)
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: str | None = None,
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 and (isinstance(entity_model, EntityModel)):
99
- escopo = entity_model.escopo
100
-
101
- if not escopo:
102
- raise Exception(f"Escopo não definido para a entidade: {entity_model.id}.")
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
- escopo,
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
- compiler_results = compiler.compile_models(entities)
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,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