pydpm_xl 0.2.3__tar.gz → 0.2.4__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 (99) hide show
  1. {pydpm_xl-0.2.3/pydpm_xl.egg-info → pydpm_xl-0.2.4}/PKG-INFO +1 -1
  2. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/__init__.py +1 -1
  3. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm/instance.py +3 -3
  4. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/instance/instance.py +62 -23
  5. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4/pydpm_xl.egg-info}/PKG-INFO +1 -1
  6. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/pyproject.toml +2 -2
  7. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/LICENSE +0 -0
  8. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/README.md +0 -0
  9. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/__init__.py +0 -0
  10. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm/__init__.py +0 -0
  11. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm/data_dictionary.py +0 -0
  12. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm/explorer.py +0 -0
  13. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm/hierarchical_queries.py +0 -0
  14. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm/migration.py +0 -0
  15. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm_xl/__init__.py +0 -0
  16. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm_xl/ast_generator.py +0 -0
  17. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm_xl/complete_ast.py +0 -0
  18. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm_xl/operation_scopes.py +0 -0
  19. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm_xl/semantic.py +0 -0
  20. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/api/dpm_xl/syntax.py +0 -0
  21. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/cli/__init__.py +0 -0
  22. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/cli/commands/__init__.py +0 -0
  23. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/cli/main.py +0 -0
  24. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/__init__.py +0 -0
  25. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/migration.py +0 -0
  26. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/models.py +0 -0
  27. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/base.py +0 -0
  28. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/basic_objects.py +0 -0
  29. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/explorer_queries.py +0 -0
  30. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/filters.py +0 -0
  31. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/glossary.py +0 -0
  32. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/hierarchical_queries.py +0 -0
  33. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/queries/tables.py +0 -0
  34. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm/utils.py +0 -0
  35. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/__init__.py +0 -0
  36. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/__init__.py +0 -0
  37. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/constructor.py +0 -0
  38. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/ml_generation.py +0 -0
  39. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/module_analyzer.py +0 -0
  40. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/module_dependencies.py +0 -0
  41. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/nodes.py +0 -0
  42. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/operands.py +0 -0
  43. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/template.py +0 -0
  44. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/visitor.py +0 -0
  45. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/ast/where_clause.py +0 -0
  46. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/__init__.py +0 -0
  47. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/__init__.py +0 -0
  48. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlLexer.interp +0 -0
  49. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlLexer.py +0 -0
  50. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlLexer.tokens +0 -0
  51. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlParser.interp +0 -0
  52. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlParser.py +0 -0
  53. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlParser.tokens +0 -0
  54. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlParserListener.py +0 -0
  55. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/dpm_xlParserVisitor.py +0 -0
  56. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/grammar/generated/listeners.py +0 -0
  57. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/__init__.py +0 -0
  58. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/aggregate.py +0 -0
  59. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/arithmetic.py +0 -0
  60. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/base.py +0 -0
  61. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/boolean.py +0 -0
  62. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/clause.py +0 -0
  63. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/comparison.py +0 -0
  64. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/conditional.py +0 -0
  65. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/string.py +0 -0
  66. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/operators/time.py +0 -0
  67. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/semantic_analyzer.py +0 -0
  68. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/symbols.py +0 -0
  69. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/types/__init__.py +0 -0
  70. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/types/promotion.py +0 -0
  71. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/types/scalar.py +0 -0
  72. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/types/time.py +0 -0
  73. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/__init__.py +0 -0
  74. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/data_handlers.py +0 -0
  75. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/operands_mapping.py +0 -0
  76. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/operator_mapping.py +0 -0
  77. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/scopes_calculator.py +0 -0
  78. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/serialization.py +0 -0
  79. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/dpm_xl/utils/tokens.py +0 -0
  80. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/exceptions/__init__.py +0 -0
  81. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/exceptions/exceptions.py +0 -0
  82. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/exceptions/messages.py +0 -0
  83. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/py_dpm/instance/__init__.py +0 -0
  84. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/pydpm_xl.egg-info/SOURCES.txt +0 -0
  85. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/pydpm_xl.egg-info/dependency_links.txt +0 -0
  86. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/pydpm_xl.egg-info/entry_points.txt +0 -0
  87. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/pydpm_xl.egg-info/requires.txt +0 -0
  88. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/pydpm_xl.egg-info/top_level.txt +0 -0
  89. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/setup.cfg +0 -0
  90. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_cli_semantic.py +0 -0
  91. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_data_dictionary_releases.py +0 -0
  92. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_db_connection_handling.py +0 -0
  93. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_get_table_details.py +0 -0
  94. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_get_tables_date_filter.py +0 -0
  95. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_get_tables_release_code.py +0 -0
  96. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_hierarchical_query.py +0 -0
  97. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_query_refactor.py +0 -0
  98. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_release_filters_semantic.py +0 -0
  99. {pydpm_xl-0.2.3 → pydpm_xl-0.2.4}/tests/test_semantic_release.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydpm_xl
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Python library for DPM-XL data processing and analysis
5
5
  Author-email: "MeaningfulData S.L." <info@meaningfuldata.eu>
6
6
  License: GPL-3.0-or-later
@@ -41,7 +41,7 @@ Available packages:
41
41
  - pydpm.api: Main APIs for migration, syntax, and semantic analysis
42
42
  """
43
43
 
44
- __version__ = "0.2.3"
44
+ __version__ = "0.2.4"
45
45
  __author__ = "MeaningfulData S.L."
46
46
  __email__ = "info@meaningfuldata.eu"
47
47
  __license__ = "GPL-3.0-or-later"
@@ -31,7 +31,7 @@ class InstanceAPI:
31
31
  Args:
32
32
  instance_data: Dictionary with the instance configuration.
33
33
  Must contain: module_code, parameters (with refPeriod),
34
- and operands (list of facts)
34
+ and facts (list of facts)
35
35
  output_folder: Directory where the output ZIP file will be created
36
36
  file_prefix: Optional prefix for the output filename
37
37
 
@@ -49,7 +49,7 @@ class InstanceAPI:
49
49
  ... "parameters": {
50
50
  ... "refPeriod": "2024-12-31"
51
51
  ... },
52
- ... "operands": [
52
+ ... "facts": [
53
53
  ... {
54
54
  ... "table_code": "t001",
55
55
  ... "row_code": "r010",
@@ -78,7 +78,7 @@ class InstanceAPI:
78
78
  Args:
79
79
  json_file: Path to JSON file with instance configuration.
80
80
  Must contain: module_code, parameters (with refPeriod),
81
- and operands (list of facts)
81
+ and facts (list of facts)
82
82
  output_folder: Directory where the output ZIP file will be created
83
83
  file_prefix: Optional prefix for the output filename
84
84
 
@@ -25,8 +25,7 @@ class Fact:
25
25
  self.open_values = open_values
26
26
  self.value = value
27
27
  self.variable_id = None
28
-
29
- self.resolve_datapoint_id(date)
28
+ self._date = date
30
29
 
31
30
  def __str__(self):
32
31
  return f"Operand(table={self.table_code}, column={self.column_code}, row={self.row_code}, sheet={self.sheet_code}, open_values={self.open_values}, value={self.value})"
@@ -116,7 +115,7 @@ class Instance:
116
115
 
117
116
  @staticmethod
118
117
  def _validate_dict_structure(instance_json: dict):
119
- required_keys = {"module_code", "parameters", "operands"}
118
+ required_keys = {"module_code", "parameters", "facts"}
120
119
  if required_keys != set(instance_json.keys()):
121
120
  missing = required_keys - set(instance_json.keys())
122
121
  raise ValueError(f"Missing required keys: {missing}")
@@ -130,8 +129,8 @@ class Instance:
130
129
  if "refPeriod" not in instance_json["parameters"]:
131
130
  raise ValueError("parameters must contain 'refPeriod'")
132
131
 
133
- if not isinstance(instance_json["operands"], list):
134
- raise TypeError("operands must be a list")
132
+ if not isinstance(instance_json["facts"], list):
133
+ raise TypeError("facts must be a list")
135
134
 
136
135
  @classmethod
137
136
  def from_json_file(cls, json_file: Path):
@@ -144,21 +143,58 @@ class Instance:
144
143
  def from_dict(cls, instance_json: dict):
145
144
  cls._validate_dict_structure(instance_json)
146
145
 
147
- url = ExplorerQueryAPI().get_module_url(
148
- module_code=instance_json["module_code"],
149
- date=instance_json["parameters"]["refPeriod"],
150
- )
151
-
152
146
  parameters = cls.PARAMETERS_DEFAULT.copy()
153
147
  parameters.update(instance_json["parameters"])
154
148
 
155
- operands = {}
156
- for operand in instance_json["operands"]:
157
- operand["date"] = parameters["refPeriod"]
158
- operand = Fact.from_dict(operand)
159
- if operand.table_code not in operands:
160
- operands[operand.table_code] = []
161
- operands[operand.table_code].append(operand)
149
+ ref_period = parameters["refPeriod"]
150
+
151
+ with ExplorerQueryAPI() as explorer:
152
+ url = explorer.get_module_url(
153
+ module_code=instance_json["module_code"],
154
+ date=ref_period,
155
+ )
156
+
157
+ # Build Fact objects grouped by table without triggering DB lookups
158
+ operands = {}
159
+ for fact_data in instance_json["facts"]:
160
+ fact = Fact.from_dict(fact_data)
161
+ if fact.table_code not in operands:
162
+ operands[fact.table_code] = []
163
+ operands[fact.table_code].append(fact)
164
+
165
+ # Resolve datapoint IDs in batches per table
166
+ for table_code, facts in operands.items():
167
+ variables = explorer.get_variable_from_cell_address(
168
+ table_code=table_code,
169
+ row_code=None,
170
+ column_code=None,
171
+ sheet_code=None,
172
+ date=ref_period,
173
+ )
174
+
175
+ # Build mapping from (row, column, sheet) -> list of variable rows
176
+ variable_map = {}
177
+ for var in variables:
178
+ key = (
179
+ var.get("row_code"),
180
+ var.get("column_code"),
181
+ var.get("sheet_code"),
182
+ )
183
+ variable_map.setdefault(key, []).append(var)
184
+
185
+ # Assign variable_id to each fact, preserving previous error semantics
186
+ for fact in facts:
187
+ key = (fact.row_code, fact.column_code, fact.sheet_code)
188
+ candidates = variable_map.get(key, [])
189
+
190
+ if len(candidates) == 0:
191
+ raise ValueError(f"No mapping found for {fact.operand_code}")
192
+ if len(candidates) > 1:
193
+ raise ValueError(
194
+ f"Multiple mappings found for {fact.operand_code}"
195
+ )
196
+
197
+ fact.variable_id = candidates[0]["variable_id"]
162
198
 
163
199
  instance = cls(
164
200
  module_url=url,
@@ -212,12 +248,15 @@ class Instance:
212
248
 
213
249
  # FilingIndicators.csv
214
250
  filing_indicators_lines = ["templateID,reported"]
251
+ seen_templates = set()
215
252
  for table in self.operands.keys():
216
- if "." in table:
217
- table = table.split(".")
218
- table = table[0] + "." + table[1]
219
- if f"{table},true" not in filing_indicators_lines:
220
- filing_indicators_lines.append(f"{table},true")
253
+ normalized_table = table
254
+ if "." in normalized_table:
255
+ parts = normalized_table.split(".")
256
+ normalized_table = parts[0] + "." + parts[1]
257
+ if normalized_table not in seen_templates:
258
+ seen_templates.add(normalized_table)
259
+ filing_indicators_lines.append(f"{normalized_table},true")
221
260
 
222
261
  (reports_dir / "FilingIndicators.csv").write_text(
223
262
  "\n".join(filing_indicators_lines)
@@ -262,4 +301,4 @@ class Instance:
262
301
 
263
302
  print(f"Instance package written to: {output_path}")
264
303
 
265
- return output_path
304
+ return output_path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydpm_xl
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Python library for DPM-XL data processing and analysis
5
5
  Author-email: "MeaningfulData S.L." <info@meaningfuldata.eu>
6
6
  License: GPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pydpm_xl"
3
- version = "0.2.3"
3
+ version = "0.2.4"
4
4
  description = "Python library for DPM-XL data processing and analysis"
5
5
  authors = [
6
6
  {name = "MeaningfulData S.L.", email = "info@meaningfuldata.eu"}
@@ -52,7 +52,7 @@ exclude = []
52
52
 
53
53
  [tool.poetry]
54
54
  name = "pydpm_xl"
55
- version = "0.2.3"
55
+ version = "0.2.4"
56
56
  description = "Python library for DPM-XL data processing and analysis"
57
57
  authors = ["MeaningfulData S.L. <info@meaningfuldata.eu>"]
58
58
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes