pydpm_xl 0.1.39rc32__tar.gz → 0.2.0__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 (140) hide show
  1. pydpm_xl-0.2.0/PKG-INFO +278 -0
  2. pydpm_xl-0.2.0/README.md +245 -0
  3. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/py_dpm/__init__.py +1 -1
  4. pydpm_xl-0.2.0/py_dpm/api/__init__.py +78 -0
  5. pydpm_xl-0.2.0/py_dpm/api/dpm/__init__.py +20 -0
  6. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm}/data_dictionary.py +903 -984
  7. pydpm_xl-0.2.0/py_dpm/api/dpm/explorer.py +236 -0
  8. pydpm_xl-0.2.0/py_dpm/api/dpm/hierarchical_queries.py +142 -0
  9. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm}/migration.py +16 -19
  10. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm}/operation_scopes.py +319 -267
  11. pydpm_xl-0.2.0/py_dpm/api/dpm_xl/__init__.py +25 -0
  12. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm_xl}/ast_generator.py +3 -3
  13. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm_xl}/complete_ast.py +191 -167
  14. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm_xl}/semantic.py +31 -9
  15. {pydpm_xl-0.1.39rc32/py_dpm/api → pydpm_xl-0.2.0/py_dpm/api/dpm_xl}/syntax.py +6 -5
  16. pydpm_xl-0.2.0/py_dpm/api/explorer.py +4 -0
  17. pydpm_xl-0.2.0/py_dpm/api/semantic.py +56 -0
  18. pydpm_xl-0.2.0/py_dpm/cli/__init__.py +9 -0
  19. pydpm_xl-0.1.39rc32/py_dpm/client.py → pydpm_xl-0.2.0/py_dpm/cli/main.py +8 -8
  20. pydpm_xl-0.2.0/py_dpm/dpm/__init__.py +11 -0
  21. {pydpm_xl-0.1.39rc32/py_dpm → pydpm_xl-0.2.0/py_dpm/dpm}/models.py +112 -88
  22. pydpm_xl-0.2.0/py_dpm/dpm/queries/base.py +100 -0
  23. pydpm_xl-0.2.0/py_dpm/dpm/queries/basic_objects.py +33 -0
  24. pydpm_xl-0.2.0/py_dpm/dpm/queries/explorer_queries.py +352 -0
  25. pydpm_xl-0.2.0/py_dpm/dpm/queries/filters.py +139 -0
  26. pydpm_xl-0.2.0/py_dpm/dpm/queries/glossary.py +45 -0
  27. pydpm_xl-0.2.0/py_dpm/dpm/queries/hierarchical_queries.py +838 -0
  28. pydpm_xl-0.2.0/py_dpm/dpm/queries/tables.py +133 -0
  29. pydpm_xl-0.2.0/py_dpm/dpm/utils.py +356 -0
  30. pydpm_xl-0.2.0/py_dpm/dpm_xl/__init__.py +8 -0
  31. pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/__init__.py +14 -0
  32. pydpm_xl-0.1.39rc32/py_dpm/AST/ASTConstructor.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/constructor.py +6 -6
  33. pydpm_xl-0.1.39rc32/py_dpm/AST/MLGeneration.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/ml_generation.py +137 -87
  34. pydpm_xl-0.1.39rc32/py_dpm/AST/ModuleAnalyzer.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/module_analyzer.py +7 -7
  35. pydpm_xl-0.1.39rc32/py_dpm/AST/ModuleDependencies.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/module_dependencies.py +56 -41
  36. pydpm_xl-0.1.39rc32/py_dpm/AST/ASTObjects.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/nodes.py +1 -1
  37. pydpm_xl-0.1.39rc32/py_dpm/AST/check_operands.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/operands.py +16 -13
  38. pydpm_xl-0.1.39rc32/py_dpm/AST/ASTTemplate.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/template.py +2 -2
  39. pydpm_xl-0.1.39rc32/py_dpm/AST/WhereClauseChecker.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/where_clause.py +2 -2
  40. pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/__init__.py +18 -0
  41. pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/__init__.py +19 -0
  42. pydpm_xl-0.1.39rc32/py_dpm/Operators/AggregateOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/aggregate.py +7 -7
  43. pydpm_xl-0.1.39rc32/py_dpm/Operators/NumericOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/arithmetic.py +6 -6
  44. pydpm_xl-0.1.39rc32/py_dpm/Operators/Operator.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/base.py +5 -5
  45. pydpm_xl-0.1.39rc32/py_dpm/Operators/BooleanOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/boolean.py +5 -5
  46. pydpm_xl-0.1.39rc32/py_dpm/Operators/ClauseOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/clause.py +8 -8
  47. pydpm_xl-0.1.39rc32/py_dpm/Operators/ComparisonOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/comparison.py +5 -5
  48. pydpm_xl-0.1.39rc32/py_dpm/Operators/ConditionalOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/conditional.py +7 -7
  49. pydpm_xl-0.1.39rc32/py_dpm/Operators/StringOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/string.py +5 -5
  50. pydpm_xl-0.1.39rc32/py_dpm/Operators/TimeOperators.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/operators/time.py +6 -6
  51. pydpm_xl-0.1.39rc32/py_dpm/semantics/SemanticAnalyzer.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/semantic_analyzer.py +168 -68
  52. pydpm_xl-0.1.39rc32/py_dpm/semantics/Symbols.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/symbols.py +3 -3
  53. pydpm_xl-0.2.0/py_dpm/dpm_xl/types/__init__.py +13 -0
  54. pydpm_xl-0.1.39rc32/py_dpm/DataTypes/TypePromotion.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/types/promotion.py +2 -2
  55. pydpm_xl-0.1.39rc32/py_dpm/DataTypes/ScalarTypes.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/types/scalar.py +2 -2
  56. pydpm_xl-0.2.0/py_dpm/dpm_xl/utils/__init__.py +14 -0
  57. {pydpm_xl-0.1.39rc32/py_dpm → pydpm_xl-0.2.0/py_dpm/dpm_xl/utils}/data_handlers.py +2 -2
  58. {pydpm_xl-0.1.39rc32/py_dpm/Utils → pydpm_xl-0.2.0/py_dpm/dpm_xl/utils}/operands_mapping.py +1 -1
  59. {pydpm_xl-0.1.39rc32/py_dpm/Utils → pydpm_xl-0.2.0/py_dpm/dpm_xl/utils}/operator_mapping.py +8 -8
  60. pydpm_xl-0.1.39rc32/py_dpm/OperationScopes/OperationScopeService.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/utils/scopes_calculator.py +148 -58
  61. pydpm_xl-0.1.39rc32/py_dpm/Utils/ast_serialization.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/utils/serialization.py +2 -2
  62. pydpm_xl-0.2.0/py_dpm/dpm_xl/validation/__init__.py +12 -0
  63. pydpm_xl-0.1.39rc32/py_dpm/Utils/ValidationsGenerationUtils.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/validation/generation_utils.py +2 -3
  64. pydpm_xl-0.1.39rc32/py_dpm/ValidationsGeneration/PropertiesConstraintsProcessor.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/validation/property_constraints.py +56 -21
  65. pydpm_xl-0.1.39rc32/py_dpm/ValidationsGeneration/auxiliary_functions.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/validation/utils.py +2 -2
  66. pydpm_xl-0.1.39rc32/py_dpm/ValidationsGeneration/VariantsProcessor.py → pydpm_xl-0.2.0/py_dpm/dpm_xl/validation/variants.py +149 -55
  67. pydpm_xl-0.2.0/py_dpm/exceptions/__init__.py +23 -0
  68. {pydpm_xl-0.1.39rc32/py_dpm/Exceptions → pydpm_xl-0.2.0/py_dpm/exceptions}/exceptions.py +7 -2
  69. pydpm_xl-0.2.0/pydpm_xl.egg-info/PKG-INFO +278 -0
  70. pydpm_xl-0.2.0/pydpm_xl.egg-info/SOURCES.txt +100 -0
  71. pydpm_xl-0.2.0/pydpm_xl.egg-info/entry_points.txt +2 -0
  72. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/pyproject.toml +6 -25
  73. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/tests/test_cli_semantic.py +8 -8
  74. pydpm_xl-0.2.0/tests/test_data_dictionary_releases.py +112 -0
  75. pydpm_xl-0.2.0/tests/test_db_connection_handling.py +27 -0
  76. pydpm_xl-0.2.0/tests/test_get_table_details.py +343 -0
  77. pydpm_xl-0.2.0/tests/test_get_tables_date_filter.py +126 -0
  78. pydpm_xl-0.2.0/tests/test_get_tables_release_code.py +62 -0
  79. pydpm_xl-0.2.0/tests/test_hierarchical_query.py +124 -0
  80. pydpm_xl-0.2.0/tests/test_query_refactor.py +77 -0
  81. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/tests/test_semantic_release.py +145 -22
  82. pydpm_xl-0.1.39rc32/PKG-INFO +0 -53
  83. pydpm_xl-0.1.39rc32/README.md +0 -20
  84. pydpm_xl-0.1.39rc32/py_dpm/Exceptions/__init__.py +0 -0
  85. pydpm_xl-0.1.39rc32/py_dpm/OperationScopes/__init__.py +0 -0
  86. pydpm_xl-0.1.39rc32/py_dpm/Operators/__init__.py +0 -0
  87. pydpm_xl-0.1.39rc32/py_dpm/Utils/__init__.py +0 -0
  88. pydpm_xl-0.1.39rc32/py_dpm/Utils/utils.py +0 -2
  89. pydpm_xl-0.1.39rc32/py_dpm/ValidationsGeneration/Utils.py +0 -364
  90. pydpm_xl-0.1.39rc32/py_dpm/ValidationsGeneration/__init__.py +0 -0
  91. pydpm_xl-0.1.39rc32/py_dpm/api/__init__.py +0 -209
  92. pydpm_xl-0.1.39rc32/py_dpm/api/data_dictionary_validation.py +0 -614
  93. pydpm_xl-0.1.39rc32/py_dpm/db_utils.py +0 -221
  94. pydpm_xl-0.1.39rc32/py_dpm/grammar/__init__.py +0 -0
  95. pydpm_xl-0.1.39rc32/py_dpm/grammar/dist/__init__.py +0 -0
  96. pydpm_xl-0.1.39rc32/py_dpm/grammar/dpm_xlLexer.g4 +0 -437
  97. pydpm_xl-0.1.39rc32/py_dpm/grammar/dpm_xlParser.g4 +0 -263
  98. pydpm_xl-0.1.39rc32/py_dpm/semantics/DAG/DAGAnalyzer.py +0 -158
  99. pydpm_xl-0.1.39rc32/py_dpm/semantics/DAG/__init__.py +0 -0
  100. pydpm_xl-0.1.39rc32/py_dpm/semantics/__init__.py +0 -0
  101. pydpm_xl-0.1.39rc32/py_dpm/views/data_types.sql +0 -12
  102. pydpm_xl-0.1.39rc32/py_dpm/views/datapoints.sql +0 -65
  103. pydpm_xl-0.1.39rc32/py_dpm/views/hierarchy_operand_reference.sql +0 -11
  104. pydpm_xl-0.1.39rc32/py_dpm/views/hierarchy_preconditions.sql +0 -13
  105. pydpm_xl-0.1.39rc32/py_dpm/views/hierarchy_variables.sql +0 -26
  106. pydpm_xl-0.1.39rc32/py_dpm/views/hierarchy_variables_context.sql +0 -14
  107. pydpm_xl-0.1.39rc32/py_dpm/views/key_components.sql +0 -18
  108. pydpm_xl-0.1.39rc32/py_dpm/views/module_from_table.sql +0 -11
  109. pydpm_xl-0.1.39rc32/py_dpm/views/open_keys.sql +0 -13
  110. pydpm_xl-0.1.39rc32/py_dpm/views/operation_info.sql +0 -27
  111. pydpm_xl-0.1.39rc32/py_dpm/views/operation_list.sql +0 -18
  112. pydpm_xl-0.1.39rc32/py_dpm/views/operations_versions_from_module_version.sql +0 -30
  113. pydpm_xl-0.1.39rc32/py_dpm/views/precondition_info.sql +0 -17
  114. pydpm_xl-0.1.39rc32/py_dpm/views/report_type_operand_reference_info.sql +0 -18
  115. pydpm_xl-0.1.39rc32/py_dpm/views/subcategory_info.sql +0 -17
  116. pydpm_xl-0.1.39rc32/py_dpm/views/table_info.sql +0 -19
  117. pydpm_xl-0.1.39rc32/pydpm_xl.egg-info/PKG-INFO +0 -53
  118. pydpm_xl-0.1.39rc32/pydpm_xl.egg-info/SOURCES.txt +0 -101
  119. pydpm_xl-0.1.39rc32/pydpm_xl.egg-info/entry_points.txt +0 -2
  120. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/LICENSE +0 -0
  121. {pydpm_xl-0.1.39rc32/py_dpm/AST → pydpm_xl-0.2.0/py_dpm/cli/commands}/__init__.py +0 -0
  122. {pydpm_xl-0.1.39rc32/py_dpm → pydpm_xl-0.2.0/py_dpm/dpm}/migration.py +0 -0
  123. /pydpm_xl-0.1.39rc32/py_dpm/AST/ASTVisitor.py → /pydpm_xl-0.2.0/py_dpm/dpm_xl/ast/visitor.py +0 -0
  124. {pydpm_xl-0.1.39rc32/py_dpm/DataTypes → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/__init__.py +0 -0
  125. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlLexer.interp +0 -0
  126. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlLexer.py +0 -0
  127. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlLexer.tokens +0 -0
  128. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlParser.interp +0 -0
  129. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlParser.py +0 -0
  130. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlParser.tokens +0 -0
  131. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlParserListener.py +0 -0
  132. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/dpm_xlParserVisitor.py +0 -0
  133. {pydpm_xl-0.1.39rc32/py_dpm/grammar/dist → pydpm_xl-0.2.0/py_dpm/dpm_xl/grammar/generated}/listeners.py +0 -0
  134. /pydpm_xl-0.1.39rc32/py_dpm/DataTypes/TimeClasses.py → /pydpm_xl-0.2.0/py_dpm/dpm_xl/types/time.py +0 -0
  135. {pydpm_xl-0.1.39rc32/py_dpm/Utils → pydpm_xl-0.2.0/py_dpm/dpm_xl/utils}/tokens.py +0 -0
  136. {pydpm_xl-0.1.39rc32/py_dpm/Exceptions → pydpm_xl-0.2.0/py_dpm/exceptions}/messages.py +0 -0
  137. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/pydpm_xl.egg-info/dependency_links.txt +0 -0
  138. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/pydpm_xl.egg-info/requires.txt +0 -0
  139. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/pydpm_xl.egg-info/top_level.txt +0 -0
  140. {pydpm_xl-0.1.39rc32 → pydpm_xl-0.2.0}/setup.cfg +0 -0
@@ -0,0 +1,278 @@
1
+ Metadata-Version: 2.4
2
+ Name: pydpm_xl
3
+ Version: 0.2.0
4
+ Summary: Python library for DPM-XL data processing and analysis
5
+ Author-email: "MeaningfulData S.L." <info@meaningfuldata.eu>
6
+ License: GPL-3.0-or-later
7
+ Keywords: dpm,dpm-xl,data-processing,migration,analysis
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Database
17
+ Classifier: Topic :: Scientific/Engineering
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: rich<13.8.0,>=13.7.1
22
+ Requires-Dist: sqlalchemy<1.5.0,>=1.4.50
23
+ Requires-Dist: pandas>=2.1.4
24
+ Requires-Dist: antlr4-python3-runtime<4.9.3,>=4.9.2
25
+ Requires-Dist: pyodbc<5.2.0,>=5.1.0
26
+ Requires-Dist: click<8.2.0,>=8.1.6
27
+ Requires-Dist: python-dotenv<1.1.0,>=1.0.1
28
+ Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0
29
+ Provides-Extra: test
30
+ Requires-Dist: pytest<8.0.0,>=7.4.0; extra == "test"
31
+ Requires-Dist: pytest-cov<5.0.0,>=4.1.0; extra == "test"
32
+ Dynamic: license-file
33
+
34
+ # pyDPM
35
+
36
+ A Python library for processing DPM (Data Point Model) expressions and working with regulatory reporting data.
37
+
38
+ ## Overview
39
+
40
+ pyDPM provides two main areas of functionality:
41
+
42
+ - **DPM-XL Processing**: Parse, validate, and generate ASTs for DPM-XL expressions
43
+ - **DPM Utilities**: Work with DPM databases, explore data dictionaries, and manage operation scopes
44
+
45
+ ## Installation
46
+
47
+ ### Using Poetry (Recommended)
48
+
49
+ ```bash
50
+ poetry install
51
+ ```
52
+
53
+ ### Using pip
54
+
55
+ ```bash
56
+ pip install .
57
+ ```
58
+
59
+ ## Architecture
60
+
61
+ ```
62
+ py_dpm/
63
+ ├── api/ # Public APIs
64
+ │ ├── dpm_xl/ # DPM-XL expression APIs
65
+ │ └── dpm/ # General DPM APIs
66
+ ├── dpm_xl/ # DPM-XL Processing Engine
67
+ │ ├── grammar/ # ANTLR grammar
68
+ │ ├── ast/ # AST generation
69
+ │ ├── operators/ # Expression operators
70
+ │ ├── types/ # Type system
71
+ │ ├── validation/ # Validation logic
72
+ │ └── utils/ # DPM-XL utilities
73
+ ├── dpm/ # General DPM Core
74
+ │ ├── db/ # Database models & views
75
+ │ ├── scopes/ # Operation scopes
76
+ │ └── explorer/ # Data dictionary explorer
77
+ ├── cli/ # Command-line interface
78
+ ├── exceptions/ # Custom exceptions
79
+ └── utils/ # Shared utilities
80
+ ```
81
+
82
+ ## Database Configuration
83
+
84
+ pyDPM supports multiple database backends. It selects the connection method based on the following hierarchy of preference:
85
+
86
+ 1. **Explicit Argument**: Passing a connection URL or path directly in Python code overrides all configuration.
87
+ 2. **Unified RDBMS Configuration**: If `PYDPM_RDBMS` and the `PYDPM_DB_*` variables are set, it connects to the configured server database.
88
+ 3. **Legacy PostgreSQL**: If `USE_POSTGRES=true` in `.env`, it connects to the configured Postgres server.
89
+ 4. **SQLite**: If `USE_SQLITE=true` (default), it connects to a local SQLite file.
90
+ 5. **SQL Server**: Legacy fallback if no other option is selected.
91
+
92
+ ### Environment Variables (.env)
93
+
94
+ Configure your database connection in the `.env` file:
95
+
96
+ ```ini
97
+ # --- Option 1: SQLite (Default) ---
98
+ USE_SQLITE=true
99
+ SQLITE_DB_PATH=database.db
100
+
101
+ # --- Option 2: Unified server database (recommended) ---
102
+ # PYDPM_RDBMS=postgres # or "sqlserver"
103
+ # PYDPM_DB_HOST=localhost
104
+ # PYDPM_DB_PORT=5432 # defaults: 5432 for postgres, 1433 for sqlserver
105
+ # PYDPM_DB_NAME=dpm_db
106
+ # PYDPM_DB_USER=myuser
107
+ # PYDPM_DB_PASSWORD=mypassword
108
+
109
+ # --- Option 3: Legacy PostgreSQL (backward compatible) ---
110
+ # USE_POSTGRES=true
111
+ # POSTGRES_HOST=localhost
112
+ # POSTGRES_PORT=5432
113
+ # POSTGRES_DB=dpm_db
114
+ # POSTGRES_USER=myuser
115
+ # POSTGRES_PASS=mypassword
116
+ ```
117
+
118
+ ## Usage
119
+
120
+ ### Command Line Interface
121
+
122
+ #### Migrate Access Database
123
+ ```bash
124
+ poetry run pydpm migrate-access ./path-to-release.accdb
125
+ ```
126
+
127
+ #### Syntax Validation
128
+ ```bash
129
+ poetry run pydpm syntax "{tT_01.00, r0010, c0010}"
130
+ ```
131
+
132
+ #### Semantic Validation
133
+ ```bash
134
+ poetry run pydpm semantic "{tT_01.00, r0010, c0010}"
135
+ ```
136
+
137
+ ### Python API
138
+
139
+ #### DPM-XL Expression Processing
140
+
141
+ ```python
142
+ from py_dpm.api import SyntaxAPI, SemanticAPI, ASTGenerator
143
+
144
+ # Syntax validation
145
+ syntax_api = SyntaxAPI()
146
+ is_valid = syntax_api.is_valid_syntax("{tT_01.00, r0010, c0010}")
147
+ print(f"Valid syntax: {is_valid}")
148
+
149
+ # Get detailed syntax errors
150
+ errors = syntax_api.validate_syntax("invalid expression")
151
+ for error in errors:
152
+ print(f"Line {error.line}, Col {error.column}: {error.message}")
153
+
154
+ # Generate AST
155
+ ast_gen = ASTGenerator()
156
+ ast = ast_gen.generate("{tT_01.00, r0010, c0010}")
157
+ print(f"AST: {ast}")
158
+
159
+ # Semantic validation (requires database)
160
+ semantic_api = SemanticAPI()
161
+ result = semantic_api.validate("{tT_01.00, r0010, c0010}", release_id=123)
162
+ if result.is_valid:
163
+ print("Semantically valid!")
164
+ else:
165
+ for error in result.errors:
166
+ print(f"Error: {error.message}")
167
+ ```
168
+
169
+ #### Working with DPM Database
170
+
171
+ ```python
172
+ from py_dpm.api import DataDictionaryAPI, DPMExplorer
173
+
174
+ # Query data dictionary
175
+ dd_api = DataDictionaryAPI()
176
+
177
+ # Get all tables
178
+ tables = dd_api.get_all_tables(release_id=123)
179
+ for table in tables:
180
+ print(f"Table: {table.code} - {table.name}")
181
+
182
+ # Get table details
183
+ table = dd_api.get_table_by_code("T_01.00", release_id=123)
184
+ print(f"Table headers: {len(table.headers)}")
185
+
186
+ # Explore database structure
187
+ explorer = DPMExplorer()
188
+ modules = explorer.get_modules(release_id=123)
189
+ for module in modules:
190
+ print(f"Module: {module.code}")
191
+ ```
192
+
193
+ #### Operation Scopes
194
+
195
+ ```python
196
+ from py_dpm.api import OperationScopesAPI, calculate_scopes_from_expression
197
+
198
+ # Calculate scopes for an expression
199
+ scopes_api = OperationScopesAPI()
200
+ result = calculate_scopes_from_expression(
201
+ expression="{tT_01.00, r0010, c0010}",
202
+ release_id=123
203
+ )
204
+
205
+ if result.success:
206
+ for scope in result.scopes:
207
+ print(f"Table: {scope.table_code}")
208
+ print(f"Headers: {[h.header_code for h in scope.headers]}")
209
+ else:
210
+ print(f"Error: {result.error}")
211
+ ```
212
+
213
+ #### Complete AST Generation
214
+
215
+ ```python
216
+ from py_dpm.api import generate_complete_ast, generate_enriched_ast
217
+
218
+ # Generate complete AST with data fields
219
+ result = generate_complete_ast("{tT_01.00, r0010, c0010}", release_id=123)
220
+ if result.success:
221
+ print(f"AST: {result.ast}")
222
+ print(f"Data fields: {result.data_fields}")
223
+ else:
224
+ print(f"Errors: {result.errors}")
225
+
226
+ # Generate enriched AST (ready for execution engine)
227
+ enriched = generate_enriched_ast("{tT_01.00, r0010, c0010}", release_id=123)
228
+ print(f"Enriched AST: {enriched}")
229
+ ```
230
+
231
+ #### Migration
232
+
233
+ ```python
234
+ from py_dpm.api import MigrationAPI
235
+
236
+ # Migrate Access database to SQLAlchemy
237
+ migration_api = MigrationAPI()
238
+ migration_api.migrate_from_access(
239
+ access_db_path="./release.accdb",
240
+ release_id=123
241
+ )
242
+ ```
243
+
244
+ ## Development
245
+
246
+ ### Running Tests
247
+
248
+ ```bash
249
+ poetry run pytest
250
+ ```
251
+
252
+ ### Code Structure
253
+
254
+ - See [API_DOCUMENTATION.md](API_DOCUMENTATION.md) for detailed API reference
255
+ - See [REORGANIZATION_SUMMARY.md](REORGANIZATION_SUMMARY.md) for reorganization details
256
+
257
+ ## Important Notes
258
+
259
+ ### ANTLR Version
260
+ This project uses **ANTLR 4.9.2**. Always run Python scripts using Poetry to ensure the correct runtime version:
261
+
262
+ ```bash
263
+ poetry run python your_script.py # ✅ Correct
264
+ python your_script.py # ❌ May use wrong ANTLR version
265
+ ```
266
+
267
+ ### Database Sessions
268
+ When using database APIs without explicit connection configuration, pyDPM uses global session management. For concurrent usage or testing, pass explicit database paths or connection URLs:
269
+
270
+ ```python
271
+ api = DataDictionaryAPI(database_path="./test.db")
272
+ # or
273
+ api = DataDictionaryAPI(connection_url="postgresql://user:pass@localhost/db")
274
+ ```
275
+
276
+ ## License
277
+
278
+ [Add your license information here]
@@ -0,0 +1,245 @@
1
+ # pyDPM
2
+
3
+ A Python library for processing DPM (Data Point Model) expressions and working with regulatory reporting data.
4
+
5
+ ## Overview
6
+
7
+ pyDPM provides two main areas of functionality:
8
+
9
+ - **DPM-XL Processing**: Parse, validate, and generate ASTs for DPM-XL expressions
10
+ - **DPM Utilities**: Work with DPM databases, explore data dictionaries, and manage operation scopes
11
+
12
+ ## Installation
13
+
14
+ ### Using Poetry (Recommended)
15
+
16
+ ```bash
17
+ poetry install
18
+ ```
19
+
20
+ ### Using pip
21
+
22
+ ```bash
23
+ pip install .
24
+ ```
25
+
26
+ ## Architecture
27
+
28
+ ```
29
+ py_dpm/
30
+ ├── api/ # Public APIs
31
+ │ ├── dpm_xl/ # DPM-XL expression APIs
32
+ │ └── dpm/ # General DPM APIs
33
+ ├── dpm_xl/ # DPM-XL Processing Engine
34
+ │ ├── grammar/ # ANTLR grammar
35
+ │ ├── ast/ # AST generation
36
+ │ ├── operators/ # Expression operators
37
+ │ ├── types/ # Type system
38
+ │ ├── validation/ # Validation logic
39
+ │ └── utils/ # DPM-XL utilities
40
+ ├── dpm/ # General DPM Core
41
+ │ ├── db/ # Database models & views
42
+ │ ├── scopes/ # Operation scopes
43
+ │ └── explorer/ # Data dictionary explorer
44
+ ├── cli/ # Command-line interface
45
+ ├── exceptions/ # Custom exceptions
46
+ └── utils/ # Shared utilities
47
+ ```
48
+
49
+ ## Database Configuration
50
+
51
+ pyDPM supports multiple database backends. It selects the connection method based on the following hierarchy of preference:
52
+
53
+ 1. **Explicit Argument**: Passing a connection URL or path directly in Python code overrides all configuration.
54
+ 2. **Unified RDBMS Configuration**: If `PYDPM_RDBMS` and the `PYDPM_DB_*` variables are set, it connects to the configured server database.
55
+ 3. **Legacy PostgreSQL**: If `USE_POSTGRES=true` in `.env`, it connects to the configured Postgres server.
56
+ 4. **SQLite**: If `USE_SQLITE=true` (default), it connects to a local SQLite file.
57
+ 5. **SQL Server**: Legacy fallback if no other option is selected.
58
+
59
+ ### Environment Variables (.env)
60
+
61
+ Configure your database connection in the `.env` file:
62
+
63
+ ```ini
64
+ # --- Option 1: SQLite (Default) ---
65
+ USE_SQLITE=true
66
+ SQLITE_DB_PATH=database.db
67
+
68
+ # --- Option 2: Unified server database (recommended) ---
69
+ # PYDPM_RDBMS=postgres # or "sqlserver"
70
+ # PYDPM_DB_HOST=localhost
71
+ # PYDPM_DB_PORT=5432 # defaults: 5432 for postgres, 1433 for sqlserver
72
+ # PYDPM_DB_NAME=dpm_db
73
+ # PYDPM_DB_USER=myuser
74
+ # PYDPM_DB_PASSWORD=mypassword
75
+
76
+ # --- Option 3: Legacy PostgreSQL (backward compatible) ---
77
+ # USE_POSTGRES=true
78
+ # POSTGRES_HOST=localhost
79
+ # POSTGRES_PORT=5432
80
+ # POSTGRES_DB=dpm_db
81
+ # POSTGRES_USER=myuser
82
+ # POSTGRES_PASS=mypassword
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ ### Command Line Interface
88
+
89
+ #### Migrate Access Database
90
+ ```bash
91
+ poetry run pydpm migrate-access ./path-to-release.accdb
92
+ ```
93
+
94
+ #### Syntax Validation
95
+ ```bash
96
+ poetry run pydpm syntax "{tT_01.00, r0010, c0010}"
97
+ ```
98
+
99
+ #### Semantic Validation
100
+ ```bash
101
+ poetry run pydpm semantic "{tT_01.00, r0010, c0010}"
102
+ ```
103
+
104
+ ### Python API
105
+
106
+ #### DPM-XL Expression Processing
107
+
108
+ ```python
109
+ from py_dpm.api import SyntaxAPI, SemanticAPI, ASTGenerator
110
+
111
+ # Syntax validation
112
+ syntax_api = SyntaxAPI()
113
+ is_valid = syntax_api.is_valid_syntax("{tT_01.00, r0010, c0010}")
114
+ print(f"Valid syntax: {is_valid}")
115
+
116
+ # Get detailed syntax errors
117
+ errors = syntax_api.validate_syntax("invalid expression")
118
+ for error in errors:
119
+ print(f"Line {error.line}, Col {error.column}: {error.message}")
120
+
121
+ # Generate AST
122
+ ast_gen = ASTGenerator()
123
+ ast = ast_gen.generate("{tT_01.00, r0010, c0010}")
124
+ print(f"AST: {ast}")
125
+
126
+ # Semantic validation (requires database)
127
+ semantic_api = SemanticAPI()
128
+ result = semantic_api.validate("{tT_01.00, r0010, c0010}", release_id=123)
129
+ if result.is_valid:
130
+ print("Semantically valid!")
131
+ else:
132
+ for error in result.errors:
133
+ print(f"Error: {error.message}")
134
+ ```
135
+
136
+ #### Working with DPM Database
137
+
138
+ ```python
139
+ from py_dpm.api import DataDictionaryAPI, DPMExplorer
140
+
141
+ # Query data dictionary
142
+ dd_api = DataDictionaryAPI()
143
+
144
+ # Get all tables
145
+ tables = dd_api.get_all_tables(release_id=123)
146
+ for table in tables:
147
+ print(f"Table: {table.code} - {table.name}")
148
+
149
+ # Get table details
150
+ table = dd_api.get_table_by_code("T_01.00", release_id=123)
151
+ print(f"Table headers: {len(table.headers)}")
152
+
153
+ # Explore database structure
154
+ explorer = DPMExplorer()
155
+ modules = explorer.get_modules(release_id=123)
156
+ for module in modules:
157
+ print(f"Module: {module.code}")
158
+ ```
159
+
160
+ #### Operation Scopes
161
+
162
+ ```python
163
+ from py_dpm.api import OperationScopesAPI, calculate_scopes_from_expression
164
+
165
+ # Calculate scopes for an expression
166
+ scopes_api = OperationScopesAPI()
167
+ result = calculate_scopes_from_expression(
168
+ expression="{tT_01.00, r0010, c0010}",
169
+ release_id=123
170
+ )
171
+
172
+ if result.success:
173
+ for scope in result.scopes:
174
+ print(f"Table: {scope.table_code}")
175
+ print(f"Headers: {[h.header_code for h in scope.headers]}")
176
+ else:
177
+ print(f"Error: {result.error}")
178
+ ```
179
+
180
+ #### Complete AST Generation
181
+
182
+ ```python
183
+ from py_dpm.api import generate_complete_ast, generate_enriched_ast
184
+
185
+ # Generate complete AST with data fields
186
+ result = generate_complete_ast("{tT_01.00, r0010, c0010}", release_id=123)
187
+ if result.success:
188
+ print(f"AST: {result.ast}")
189
+ print(f"Data fields: {result.data_fields}")
190
+ else:
191
+ print(f"Errors: {result.errors}")
192
+
193
+ # Generate enriched AST (ready for execution engine)
194
+ enriched = generate_enriched_ast("{tT_01.00, r0010, c0010}", release_id=123)
195
+ print(f"Enriched AST: {enriched}")
196
+ ```
197
+
198
+ #### Migration
199
+
200
+ ```python
201
+ from py_dpm.api import MigrationAPI
202
+
203
+ # Migrate Access database to SQLAlchemy
204
+ migration_api = MigrationAPI()
205
+ migration_api.migrate_from_access(
206
+ access_db_path="./release.accdb",
207
+ release_id=123
208
+ )
209
+ ```
210
+
211
+ ## Development
212
+
213
+ ### Running Tests
214
+
215
+ ```bash
216
+ poetry run pytest
217
+ ```
218
+
219
+ ### Code Structure
220
+
221
+ - See [API_DOCUMENTATION.md](API_DOCUMENTATION.md) for detailed API reference
222
+ - See [REORGANIZATION_SUMMARY.md](REORGANIZATION_SUMMARY.md) for reorganization details
223
+
224
+ ## Important Notes
225
+
226
+ ### ANTLR Version
227
+ This project uses **ANTLR 4.9.2**. Always run Python scripts using Poetry to ensure the correct runtime version:
228
+
229
+ ```bash
230
+ poetry run python your_script.py # ✅ Correct
231
+ python your_script.py # ❌ May use wrong ANTLR version
232
+ ```
233
+
234
+ ### Database Sessions
235
+ When using database APIs without explicit connection configuration, pyDPM uses global session management. For concurrent usage or testing, pass explicit database paths or connection URLs:
236
+
237
+ ```python
238
+ api = DataDictionaryAPI(database_path="./test.db")
239
+ # or
240
+ api = DataDictionaryAPI(connection_url="postgresql://user:pass@localhost/db")
241
+ ```
242
+
243
+ ## License
244
+
245
+ [Add your license information here]
@@ -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.1.39rc32"
44
+ __version__ = "0.2.0"
45
45
  __author__ = "MeaningfulData S.L."
46
46
  __email__ = "info@meaningfuldata.eu"
47
47
  __license__ = "GPL-3.0-or-later"
@@ -0,0 +1,78 @@
1
+ """
2
+ PyDPM Public API
3
+
4
+ Main entry point for the PyDPM library.
5
+ Provides both DPM-XL specific and general DPM functionality.
6
+ """
7
+
8
+ # Import from DPM-XL API
9
+ from py_dpm.api.dpm_xl import (
10
+ SyntaxAPI,
11
+ SemanticAPI,
12
+ ASTGenerator,
13
+ )
14
+
15
+ # Import from general DPM API
16
+ from py_dpm.api.dpm import (
17
+ DataDictionaryAPI,
18
+ ExplorerQueryAPI,
19
+ OperationScopesAPI,
20
+ MigrationAPI,
21
+ HierarchicalQueryAPI,
22
+ )
23
+
24
+ # Import convenience functions and types from DPM API
25
+ from py_dpm.api.dpm.operation_scopes import (
26
+ calculate_scopes_from_expression,
27
+ get_existing_scopes,
28
+ OperationScopeDetailedInfo,
29
+ OperationScopeResult,
30
+ )
31
+
32
+
33
+ # Import AST generator convenience functions
34
+ from py_dpm.api.dpm_xl.ast_generator import (
35
+ parse_expression,
36
+ validate_expression,
37
+ parse_batch,
38
+ )
39
+
40
+ # Import complete AST functions
41
+ from py_dpm.api.dpm_xl.complete_ast import (
42
+ generate_complete_ast,
43
+ generate_complete_batch,
44
+ generate_enriched_ast,
45
+ enrich_ast_with_metadata,
46
+ )
47
+
48
+
49
+ # Export the main API classes
50
+ __all__ = [
51
+ # Complete AST API (recommended - includes data fields)
52
+ "generate_complete_ast",
53
+ "generate_complete_batch",
54
+ # Enriched AST API (engine-ready with framework structure)
55
+ "generate_enriched_ast",
56
+ "enrich_ast_with_metadata",
57
+ # Simple AST API
58
+ "ASTGenerator",
59
+ "parse_expression",
60
+ "validate_expression",
61
+ "parse_batch",
62
+ # Advanced APIs
63
+ "MigrationAPI",
64
+ "SyntaxAPI",
65
+ "SemanticAPI",
66
+ "DataDictionaryAPI",
67
+ "OperationScopesAPI",
68
+ "ExplorerQueryAPI",
69
+ # Operation Scopes Convenience Functions
70
+ "calculate_scopes_from_expression",
71
+ "get_existing_scopes",
72
+ # Operation Scopes Data Classes
73
+ "ModuleVersionInfo",
74
+ "TableVersionInfo",
75
+ "HeaderVersionInfo",
76
+ "OperationScopeDetailedInfo",
77
+ "OperationScopeResult",
78
+ ]
@@ -0,0 +1,20 @@
1
+ """
2
+ DPM API
3
+
4
+ Public APIs for general DPM functionality (database, exploration, scopes).
5
+ """
6
+
7
+ from py_dpm.api.dpm.data_dictionary import DataDictionaryAPI
8
+ from py_dpm.api.dpm.explorer import ExplorerQueryAPI
9
+ from py_dpm.api.dpm.operation_scopes import OperationScopesAPI
10
+ from py_dpm.api.dpm.migration import MigrationAPI
11
+ from py_dpm.api.dpm.hierarchical_queries import HierarchicalQueryAPI
12
+
13
+
14
+ __all__ = [
15
+ "DataDictionaryAPI",
16
+ "ExplorerQueryAPI",
17
+ "OperationScopesAPI",
18
+ "MigrationAPI",
19
+ "HierarchicalQueryAPI",
20
+ ]