nsj-rest-lib2 0.0.9__tar.gz → 0.0.11__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 (39) hide show
  1. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/PKG-INFO +2 -2
  2. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/compiler.py +15 -13
  3. nsj_rest_lib2-0.0.11/nsj_rest_lib2/compiler/model.py +45 -0
  4. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/property_compiler.py +12 -0
  5. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/service/entity_loader.py +44 -5
  6. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2.egg-info/PKG-INFO +2 -2
  7. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2.egg-info/SOURCES.txt +2 -0
  8. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2.egg-info/requires.txt +1 -1
  9. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/setup.cfg +2 -2
  10. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/README.md +0 -0
  11. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/__init__.py +0 -0
  12. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/__init__.py +0 -0
  13. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/ai_compiler.py +0 -0
  14. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/compiler_structures.py +0 -0
  15. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/dto_compiler.py +0 -0
  16. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/__init__.py +0 -0
  17. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py +0 -0
  18. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/api_model.py +0 -0
  19. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/column_meta_model.py +0 -0
  20. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/entity_model.py +0 -0
  21. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/index_model.py +0 -0
  22. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/primitives.py +0 -0
  23. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/property_meta_model.py +0 -0
  24. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/repository_model.py +0 -0
  25. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py +0 -0
  26. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/entity_compiler.py +0 -0
  27. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/util/__init__.py +0 -0
  28. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/util/str_util.py +0 -0
  29. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/util/type_naming_util.py +0 -0
  30. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/compiler/util/type_util.py +0 -0
  31. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/controller/__init__.py +0 -0
  32. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/controller/dynamic_controller.py +0 -0
  33. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/exception.py +0 -0
  34. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/redis_config.py +0 -0
  35. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/service/__init__.py +0 -0
  36. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2/settings.py +0 -0
  37. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2.egg-info/dependency_links.txt +0 -0
  38. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/nsj_rest_lib2.egg-info/top_level.txt +0 -0
  39. {nsj_rest_lib2-0.0.9 → nsj_rest_lib2-0.0.11}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.9
3
+ Version: 0.0.11
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
@@ -17,7 +17,7 @@ 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
19
19
  Requires-Dist: black<26.0.0,>=25.1.0
20
- Requires-Dist: pyyaml>7.0.0,>=6.0.3
20
+ Requires-Dist: pyyaml<7.0.0,>=6.0.3
21
21
 
22
22
  # nsj_rest_lib2
23
23
 
@@ -1,4 +1,5 @@
1
1
  import re
2
+
2
3
  from typing import Any
3
4
 
4
5
  from nsj_rest_lib2.compiler.compiler_structures import (
@@ -7,8 +8,8 @@ from nsj_rest_lib2.compiler.compiler_structures import (
7
8
  )
8
9
  from nsj_rest_lib2.compiler.dto_compiler import DTOCompiler
9
10
  from nsj_rest_lib2.compiler.edl_model.primitives import REGEX_EXTERNAL_REF
10
- from nsj_rest_lib2.compiler.edl_model.repository_model import RepositoryModel
11
11
  from nsj_rest_lib2.compiler.entity_compiler import EntityCompiler
12
+ from nsj_rest_lib2.compiler.model import CompilerResult
12
13
  from nsj_rest_lib2.compiler.property_compiler import EDLPropertyCompiler
13
14
 
14
15
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
@@ -26,17 +27,6 @@ from nsj_rest_lib2.settings import get_logger
26
27
  # TODO Criar imagem docker base para as aplicações, usando venv (para poderem atualizar o pydantic)
27
28
 
28
29
 
29
- class CompilerResult:
30
- def __init__(self):
31
- self.dto_class_name: str | None = None
32
- self.dto_code: str | None = None
33
- self.entity_class_name: str | None = None
34
- self.entity_code: str | None = None
35
- self.api_expose: bool | None = None
36
- self.api_resource: str | None = None
37
- self.api_verbs: list[str] | None = None
38
-
39
-
40
30
  class EDLCompiler:
41
31
  def __init__(self) -> None:
42
32
  self._properties_compiler = EDLPropertyCompiler()
@@ -114,6 +104,7 @@ class EDLCompiler:
114
104
  props_pk,
115
105
  enum_classes,
116
106
  related_imports,
107
+ relations_dependencies,
117
108
  ) = self._properties_compiler.compile(
118
109
  properties_structure,
119
110
  map_unique_by_property,
@@ -142,6 +133,7 @@ class EDLCompiler:
142
133
  compiler_result.api_expose = entity_model.api.expose
143
134
  compiler_result.api_resource = entity_model.api.resource
144
135
  compiler_result.api_verbs = entity_model.api.verbs
136
+ compiler_result.relations_dependencies = relations_dependencies
145
137
 
146
138
  return compiler_result
147
139
 
@@ -244,10 +236,20 @@ class EDLCompiler:
244
236
  def _list_dependencies(self, entity_model: EntityModel) -> list[str]:
245
237
  entities: list[str] = []
246
238
 
239
+ # Adicionando dependências por traits
247
240
  if entity_model.trait_from:
248
241
  entities.append(entity_model.trait_from)
249
242
 
250
- # Populando com as dependências de propriedades de relacionamento 1_N
243
+ # Populando com as dependências de propriedades de relacionamento
244
+ relations = self._list_dependencies_relations(entity_model)
245
+ entities.extend(relations)
246
+
247
+ return entities
248
+
249
+ def _list_dependencies_relations(self, entity_model) -> list[str]:
250
+ entities = []
251
+
252
+ # Relacionamento 1_N
251
253
  for pkey in entity_model.properties:
252
254
  prop = entity_model.properties[pkey]
253
255
 
@@ -0,0 +1,45 @@
1
+ import uuid
2
+
3
+ from typing import Any
4
+
5
+
6
+ class RelationDependency:
7
+ def __init__(self):
8
+ self.tenant: int | None = None
9
+ self.grupo_empresarial: uuid.UUID | None = None
10
+ self.entity_resource: str | None = None
11
+ self.entity_scope: str | None = None
12
+
13
+ def to_dict(self) -> dict[str, Any]:
14
+ return {
15
+ "tenant": self.tenant,
16
+ "grupo_empresarial": (
17
+ str(self.grupo_empresarial) if self.grupo_empresarial else None
18
+ ),
19
+ "entity_resource": self.entity_resource,
20
+ "entity_scope": self.entity_scope,
21
+ }
22
+
23
+ def from_dict(self, data: dict[str, Any]) -> "RelationDependency":
24
+ self.tenant = data.get("tenant")
25
+ self.grupo_empresarial = (
26
+ uuid.UUID(data["grupo_empresarial"])
27
+ if data.get("grupo_empresarial")
28
+ else None
29
+ )
30
+ self.entity_resource = data.get("entity_resource")
31
+ self.entity_scope = data.get("entity_scope")
32
+
33
+ return self
34
+
35
+
36
+ class CompilerResult:
37
+ def __init__(self):
38
+ self.dto_class_name: str | None = None
39
+ self.dto_code: str | None = None
40
+ self.entity_class_name: str | None = None
41
+ self.entity_code: str | None = None
42
+ self.api_expose: bool | None = None
43
+ self.api_resource: str | None = None
44
+ self.api_verbs: list[str] | None = None
45
+ self.relations_dependencies: list[RelationDependency] | None = None
@@ -13,6 +13,7 @@ from nsj_rest_lib2.compiler.edl_model.primitives import (
13
13
  REGEX_INTERNAL_REF,
14
14
  )
15
15
  from nsj_rest_lib2.compiler.edl_model.property_meta_model import PropertyMetaModel
16
+ from nsj_rest_lib2.compiler.model import RelationDependency
16
17
  from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
17
18
  from nsj_rest_lib2.compiler.util.type_naming_util import (
18
19
  compile_dto_class_name,
@@ -40,6 +41,7 @@ class EDLPropertyCompiler:
40
41
  list[str],
41
42
  list[ast.stmt],
42
43
  list[tuple[str, str, str]],
44
+ list[RelationDependency],
43
45
  ]:
44
46
 
45
47
  # TODO Criar opção de campo calculado?
@@ -70,6 +72,7 @@ class EDLPropertyCompiler:
70
72
  props_pk = []
71
73
  enum_classes = []
72
74
  related_imports = []
75
+ relations_dependencies = []
73
76
 
74
77
  if properties_structure.properties is None:
75
78
  return (ast_dto_attributes, ast_entity_attributes, props_pk, enum_classes)
@@ -140,6 +143,14 @@ class EDLPropertyCompiler:
140
143
  )
141
144
  )
142
145
 
146
+ # Gravando a dependência de relacionamento
147
+ relation_dependency = RelationDependency()
148
+ relation_dependency.entity_resource = related_entity.api.resource
149
+ relation_dependency.entity_scope = related_entity.escopo
150
+ relation_dependency.tenant = tenant
151
+ relation_dependency.grupo_empresarial = grupo_empresarial
152
+ relations_dependencies.append(relation_dependency)
153
+
143
154
  # Instanciando o ast
144
155
  if prop.cardinality == CardinalityTypes.C1_N:
145
156
  # Para relacionamentos 1_N
@@ -214,6 +225,7 @@ class EDLPropertyCompiler:
214
225
  props_pk,
215
226
  enum_classes,
216
227
  related_imports,
228
+ relations_dependencies,
217
229
  )
218
230
 
219
231
  def compile_simple_property(
@@ -1,11 +1,14 @@
1
1
  import datetime
2
2
  import json
3
+ import re
3
4
  import sys
4
5
  import threading
5
6
  import types
6
7
 
7
8
  from nsj_rest_lib.settings import get_logger
8
9
 
10
+ from nsj_rest_lib2.compiler.edl_model.primitives import REGEX_EXTERNAL_REF
11
+ from nsj_rest_lib2.compiler.model import RelationDependency
9
12
  from nsj_rest_lib2.compiler.util.type_naming_util import compile_namespace_keys
10
13
  from nsj_rest_lib2.exception import MissingEntityConfigException
11
14
  from nsj_rest_lib2.redis_config import get_redis
@@ -21,14 +24,15 @@ class LoadedEntity:
21
24
  self.loaded_at: datetime.datetime = datetime.datetime.now()
22
25
  self.api_expose: bool = False
23
26
  self.api_verbs: list[str] = []
27
+ self.relations_dependencies: list[RelationDependency] = []
24
28
 
25
29
 
26
30
  class Namespace:
27
31
  def __init__(self):
28
32
  self.key: str = ""
29
33
  self.loaded_entities: dict[str, LoadedEntity] = {}
30
- self.entities_dict: dict = None
31
- self.module: types.ModuleType = None
34
+ self.entities_dict: dict = {}
35
+ self.module: types.ModuleType = types.ModuleType("empty")
32
36
 
33
37
 
34
38
  namespaces_dict: dict[str, Namespace] = {}
@@ -43,17 +47,18 @@ class EntityLoader:
43
47
  entity_resource: str,
44
48
  tenant: str | None,
45
49
  grupo_empresarial: str | None,
50
+ scope: str = ESCOPO_RESTLIB2,
46
51
  ) -> tuple[str, str, dict, bool, list[str]]:
47
52
  # Montando as chaves dos namespaces
48
53
  grupo_key, tenant_key, default_key = compile_namespace_keys(
49
54
  tenant, grupo_empresarial
50
55
  )
51
56
 
52
- result = self._load_entity_source_from_memory(
57
+ result = self._search_entity_namespace_in_memory(
53
58
  entity_resource, grupo_key, tenant_key, default_key
54
59
  )
55
60
 
56
- # Se conseguiu carregar da memória, verifica se houve alteração no hash, em relação ao redis
61
+ # Se conseguiu localizar na memória, verifica se houve alteração no hash, em relação ao redis
57
62
  if result is not None:
58
63
  # Desempacotando o result e recuperando informações do namespace
59
64
  (
@@ -67,6 +72,21 @@ class EntityLoader:
67
72
  entities_dict = namespace.entities_dict
68
73
  api_expose = loaded_entity.api_expose
69
74
  api_verbs = loaded_entity.api_verbs
75
+ relations_dependencies = loaded_entity.relations_dependencies
76
+
77
+ # Verificando se alguma de suas dependências precisariam ser recarregadas
78
+ for rd in relations_dependencies:
79
+ if rd.entity_resource is None or rd.entity_scope is None:
80
+ raise RuntimeError(
81
+ f"Erro: Dependência de entidade mal formada na entidade {entity_resource}."
82
+ )
83
+
84
+ self.load_entity_source(
85
+ rd.entity_resource,
86
+ str(rd.tenant),
87
+ str(rd.grupo_empresarial),
88
+ rd.entity_scope,
89
+ )
70
90
 
71
91
  # Se o tempo entre o carregamento e agora for maior do que MIN_TIME_SOURCE_REFRESH minutos,
72
92
  # verifica se precisa de refresh
@@ -215,6 +235,10 @@ class EntityLoader:
215
235
  api_expose = entity_config["api_expose"]
216
236
  # api_resource = entity_config["api_resource"]
217
237
  api_verbs = entity_config["api_verbs"]
238
+ relations_dependencies = [
239
+ RelationDependency().from_dict(rd)
240
+ for rd in entity_config.get("relations_dependencies", [])
241
+ ]
218
242
  except json.JSONDecodeError as e:
219
243
  if not check_refresh:
220
244
  raise RuntimeError(
@@ -226,6 +250,20 @@ class EntityLoader:
226
250
  )
227
251
  return None
228
252
 
253
+ # Verificando se alguma de suas dependências precisariam ser carregadas (ou recarregadas)
254
+ for rd in relations_dependencies:
255
+ if rd.entity_resource is None or rd.entity_scope is None:
256
+ raise RuntimeError(
257
+ f"Erro: Dependência de entidade mal formada na entidade {entity_resource}."
258
+ )
259
+
260
+ self.load_entity_source(
261
+ rd.entity_resource,
262
+ str(rd.tenant),
263
+ str(rd.grupo_empresarial),
264
+ rd.entity_scope,
265
+ )
266
+
229
267
  # Verificando se a entidade precisa ou não de refresh
230
268
  if check_refresh:
231
269
  loaded_namespace = namespaces_dict.get(entity_config_key)
@@ -283,6 +321,7 @@ class EntityLoader:
283
321
  loaded_entity.entity_hash = entity_hash
284
322
  loaded_entity.api_expose = api_expose
285
323
  loaded_entity.api_verbs = api_verbs
324
+ loaded_entity.relations_dependencies = relations_dependencies
286
325
 
287
326
  namespace.loaded_entities[entity_resource] = loaded_entity
288
327
 
@@ -334,7 +373,7 @@ class EntityLoader:
334
373
 
335
374
  return (entity_config_key, entity_config_str)
336
375
 
337
- def _load_entity_source_from_memory(
376
+ def _search_entity_namespace_in_memory(
338
377
  self,
339
378
  entity_resource: str,
340
379
  grupo_key: str,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.9
3
+ Version: 0.0.11
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
@@ -17,7 +17,7 @@ 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
19
19
  Requires-Dist: black<26.0.0,>=25.1.0
20
- Requires-Dist: pyyaml>7.0.0,>=6.0.3
20
+ Requires-Dist: pyyaml<7.0.0,>=6.0.3
21
21
 
22
22
  # nsj_rest_lib2
23
23
 
@@ -16,6 +16,7 @@ setup.cfg
16
16
  ./nsj_rest_lib2/compiler/compiler_structures.py
17
17
  ./nsj_rest_lib2/compiler/dto_compiler.py
18
18
  ./nsj_rest_lib2/compiler/entity_compiler.py
19
+ ./nsj_rest_lib2/compiler/model.py
19
20
  ./nsj_rest_lib2/compiler/property_compiler.py
20
21
  ./nsj_rest_lib2/compiler/edl_model/__init__.py
21
22
  ./nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py
@@ -50,6 +51,7 @@ nsj_rest_lib2/compiler/compiler.py
50
51
  nsj_rest_lib2/compiler/compiler_structures.py
51
52
  nsj_rest_lib2/compiler/dto_compiler.py
52
53
  nsj_rest_lib2/compiler/entity_compiler.py
54
+ nsj_rest_lib2/compiler/model.py
53
55
  nsj_rest_lib2/compiler/property_compiler.py
54
56
  nsj_rest_lib2/compiler/edl_model/__init__.py
55
57
  nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py
@@ -3,4 +3,4 @@ redis<7.0.0,>=6.4.0
3
3
  nsj-multi-database-lib<3.0.0,>=2.0.1
4
4
  pydantic<3.0.0,>=2.11.9
5
5
  black<26.0.0,>=25.1.0
6
- pyyaml>7.0.0,>=6.0.3
6
+ pyyaml<7.0.0,>=6.0.3
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = nsj_rest_lib2
3
- version = 0.0.9
3
+ version = 0.0.11
4
4
  author = Nasajon Sistemas
5
5
  author_email = contact.dev@nasajon.com.br
6
6
  description = Biblioteca para permitir a distribuição de rotas dinâmicas numa API, configuradas por meio de EDLs declarativos (em formato JSON).
@@ -26,7 +26,7 @@ install_requires =
26
26
  nsj-multi-database-lib>=2.0.1,<3.0.0
27
27
  pydantic>=2.11.9,<3.0.0
28
28
  black>=25.1.0,<26.0.0
29
- pyyaml>=6.0.3,>7.0.0
29
+ pyyaml>=6.0.3,<7.0.0
30
30
 
31
31
  [options.packages.find]
32
32
  where = ./
File without changes