pylegend 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

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 (124) hide show
  1. pylegend/__init__.py +16 -6
  2. pylegend/core/{databse → database}/sql_to_string/__init__.py +3 -3
  3. pylegend/core/{databse → database}/sql_to_string/db_extension.py +14 -5
  4. pylegend/core/{databse → database}/sql_to_string/generator.py +2 -2
  5. pylegend/core/language/__init__.py +12 -10
  6. pylegend/core/language/legacy_api/__init__.py +13 -0
  7. pylegend/core/language/{aggregate_specification.py → legacy_api/aggregate_specification.py} +10 -10
  8. pylegend/core/language/legacy_api/legacy_api_tds_row.py +32 -0
  9. pylegend/core/language/legendql_api/__init__.py +13 -0
  10. pylegend/core/language/legendql_api/legendql_api_custom_expressions.py +541 -0
  11. pylegend/core/language/legendql_api/legendql_api_tds_row.py +292 -0
  12. pylegend/core/language/shared/__init__.py +13 -0
  13. pylegend/core/language/{column_expressions.py → shared/column_expressions.py} +32 -31
  14. pylegend/core/language/{expression.py → shared/expression.py} +8 -0
  15. pylegend/core/language/{functions.py → shared/functions.py} +12 -3
  16. pylegend/core/language/shared/helpers.py +75 -0
  17. pylegend/core/language/{literal_expressions.py → shared/literal_expressions.py} +39 -1
  18. pylegend/core/language/{operations → shared/operations}/binary_expression.py +34 -2
  19. pylegend/core/language/{operations → shared/operations}/boolean_operation_expressions.py +34 -6
  20. pylegend/core/language/{operations → shared/operations}/collection_operation_expressions.py +146 -26
  21. pylegend/core/language/{operations → shared/operations}/date_operation_expressions.py +288 -24
  22. pylegend/core/language/{operations → shared/operations}/float_operation_expressions.py +53 -8
  23. pylegend/core/language/{operations → shared/operations}/integer_operation_expressions.py +62 -9
  24. pylegend/core/language/{operations → shared/operations}/nullary_expression.py +9 -2
  25. pylegend/core/language/{operations → shared/operations}/number_operation_expressions.py +211 -30
  26. pylegend/core/language/shared/operations/primitive_operation_expressions.py +155 -0
  27. pylegend/core/language/{operations → shared/operations}/string_operation_expressions.py +194 -21
  28. pylegend/core/language/{operations → shared/operations}/unary_expression.py +10 -2
  29. pylegend/core/language/{primitive_collection.py → shared/primitive_collection.py} +2 -2
  30. pylegend/core/language/{primitives → shared/primitives}/__init__.py +9 -9
  31. pylegend/core/language/{primitives → shared/primitives}/boolean.py +9 -5
  32. pylegend/core/language/{primitives → shared/primitives}/date.py +60 -15
  33. pylegend/core/language/{primitives → shared/primitives}/datetime.py +4 -5
  34. pylegend/core/language/{primitives → shared/primitives}/float.py +6 -6
  35. pylegend/core/language/{primitives → shared/primitives}/integer.py +6 -6
  36. pylegend/core/language/{primitives → shared/primitives}/number.py +16 -13
  37. pylegend/core/language/{primitives → shared/primitives}/primitive.py +41 -5
  38. pylegend/core/language/{primitives → shared/primitives}/strictdate.py +4 -5
  39. pylegend/core/language/{primitives → shared/primitives}/string.py +18 -19
  40. pylegend/core/language/{tds_row.py → shared/tds_row.py} +46 -16
  41. pylegend/core/request/__init__.py +7 -1
  42. pylegend/core/request/auth.py +55 -1
  43. pylegend/core/request/legend_client.py +32 -0
  44. pylegend/core/sql/metamodel_extension.py +28 -0
  45. pylegend/core/tds/abstract/__init__.py +13 -0
  46. pylegend/core/tds/abstract/frames/__init__.py +13 -0
  47. pylegend/core/tds/{legend_api/frames/legend_api_applied_function_tds_frame.py → abstract/frames/applied_function_tds_frame.py} +19 -13
  48. pylegend/core/tds/abstract/frames/base_tds_frame.py +125 -0
  49. pylegend/core/tds/{legend_api/frames/legend_api_input_tds_frame.py → abstract/frames/input_tds_frame.py} +9 -12
  50. pylegend/core/tds/{legend_api/frames/functions → abstract}/function_helpers.py +1 -1
  51. pylegend/core/tds/{legend_api/frames/functions/concatenate_function.py → legacy_api/frames/functions/legacy_api_concatenate_function.py} +25 -13
  52. pylegend/core/tds/{legend_api/frames/functions/distinct_function.py → legacy_api/frames/functions/legacy_api_distinct_function.py} +13 -8
  53. pylegend/core/tds/{legend_api/frames/functions/drop_function.py → legacy_api/frames/functions/legacy_api_drop_function.py} +13 -8
  54. pylegend/core/tds/{legend_api/frames/functions/extend_function.py → legacy_api/frames/functions/legacy_api_extend_function.py} +36 -16
  55. pylegend/core/tds/{legend_api/frames/functions/filter_function.py → legacy_api/frames/functions/legacy_api_filter_function.py} +25 -13
  56. pylegend/core/tds/{legend_api/frames/functions/group_by_function.py → legacy_api/frames/functions/legacy_api_group_by_function.py} +44 -17
  57. pylegend/core/tds/{legend_api/frames/functions/head_function.py → legacy_api/frames/functions/legacy_api_head_function.py} +13 -8
  58. pylegend/core/tds/{legend_api/frames/functions/join_by_columns_function.py → legacy_api/frames/functions/legacy_api_join_by_columns_function.py} +40 -13
  59. pylegend/core/tds/{legend_api/frames/functions/join_function.py → legacy_api/frames/functions/legacy_api_join_function.py} +44 -20
  60. pylegend/core/tds/{legend_api/frames/functions/rename_columns_function.py → legacy_api/frames/functions/legacy_api_rename_columns_function.py} +20 -8
  61. pylegend/core/tds/{legend_api/frames/functions/restrict_function.py → legacy_api/frames/functions/legacy_api_restrict_function.py} +17 -8
  62. pylegend/core/tds/{legend_api/frames/functions/slice_function.py → legacy_api/frames/functions/legacy_api_slice_function.py} +13 -8
  63. pylegend/core/tds/{legend_api/frames/functions/sort_function.py → legacy_api/frames/functions/legacy_api_sort_function.py} +19 -8
  64. pylegend/core/tds/legacy_api/frames/legacy_api_applied_function_tds_frame.py +37 -0
  65. pylegend/core/tds/legacy_api/frames/legacy_api_base_tds_frame.py +204 -0
  66. pylegend/core/tds/legacy_api/frames/legacy_api_input_tds_frame.py +51 -0
  67. pylegend/core/tds/{legend_api/frames/legend_api_tds_frame.py → legacy_api/frames/legacy_api_tds_frame.py} +28 -28
  68. pylegend/core/tds/legendql_api/__init__.py +13 -0
  69. pylegend/core/tds/legendql_api/frames/__init__.py +13 -0
  70. pylegend/core/tds/legendql_api/frames/functions/__init__.py +13 -0
  71. pylegend/core/tds/legendql_api/frames/functions/legendql_api_asofjoin_function.py +156 -0
  72. pylegend/core/tds/legendql_api/frames/functions/legendql_api_concatenate_function.py +139 -0
  73. pylegend/core/tds/legendql_api/frames/functions/legendql_api_distinct_function.py +69 -0
  74. pylegend/core/tds/legendql_api/frames/functions/legendql_api_drop_function.py +74 -0
  75. pylegend/core/tds/legendql_api/frames/functions/legendql_api_extend_function.py +256 -0
  76. pylegend/core/tds/legendql_api/frames/functions/legendql_api_filter_function.py +121 -0
  77. pylegend/core/tds/legendql_api/frames/functions/legendql_api_function_helpers.py +137 -0
  78. pylegend/core/tds/legendql_api/frames/functions/legendql_api_groupby_function.py +256 -0
  79. pylegend/core/tds/legendql_api/frames/functions/legendql_api_head_function.py +74 -0
  80. pylegend/core/tds/legendql_api/frames/functions/legendql_api_join_function.py +214 -0
  81. pylegend/core/tds/legendql_api/frames/functions/legendql_api_project_function.py +169 -0
  82. pylegend/core/tds/legendql_api/frames/functions/legendql_api_rename_function.py +189 -0
  83. pylegend/core/tds/legendql_api/frames/functions/legendql_api_select_function.py +131 -0
  84. pylegend/core/tds/legendql_api/frames/functions/legendql_api_slice_function.py +82 -0
  85. pylegend/core/tds/legendql_api/frames/functions/legendql_api_sort_function.py +93 -0
  86. pylegend/core/tds/legendql_api/frames/functions/legendql_api_window_extend_function.py +283 -0
  87. pylegend/core/tds/legendql_api/frames/legendql_api_applied_function_tds_frame.py +37 -0
  88. pylegend/core/tds/legendql_api/frames/legendql_api_base_tds_frame.py +419 -0
  89. pylegend/core/tds/legendql_api/frames/legendql_api_input_tds_frame.py +50 -0
  90. pylegend/core/tds/legendql_api/frames/legendql_api_tds_frame.py +327 -0
  91. pylegend/core/tds/pandas_api/frames/functions/assign_function.py +6 -6
  92. pylegend/core/tds/pandas_api/frames/pandas_api_applied_function_tds_frame.py +4 -0
  93. pylegend/core/tds/pandas_api/frames/pandas_api_base_tds_frame.py +11 -3
  94. pylegend/core/tds/pandas_api/frames/pandas_api_tds_frame.py +2 -2
  95. pylegend/core/tds/tds_frame.py +32 -2
  96. pylegend/extensions/database/vendors/postgres/postgres_sql_to_string.py +1 -1
  97. pylegend/extensions/tds/abstract/legend_function_input_frame.py +4 -0
  98. pylegend/extensions/tds/abstract/legend_service_input_frame.py +4 -0
  99. pylegend/extensions/tds/abstract/table_spec_input_frame.py +4 -0
  100. pylegend/extensions/tds/{legend_api/frames/legend_api_legend_function_input_frame.py → legacy_api/frames/legacy_api_legend_function_input_frame.py} +5 -5
  101. pylegend/extensions/tds/{legend_api/frames/legend_api_legend_service_input_frame.py → legacy_api/frames/legacy_api_legend_service_input_frame.py} +6 -6
  102. pylegend/extensions/tds/{legend_api/frames/legend_api_table_spec_input_frame.py → legacy_api/frames/legacy_api_table_spec_input_frame.py} +5 -5
  103. pylegend/extensions/tds/legendql_api/__init__.py +13 -0
  104. pylegend/extensions/tds/legendql_api/frames/__init__.py +13 -0
  105. pylegend/extensions/tds/legendql_api/frames/legendql_api_legend_service_input_frame.py +46 -0
  106. pylegend/extensions/tds/legendql_api/frames/legendql_api_table_spec_input_frame.py +36 -0
  107. pylegend/{legend_api_tds_client.py → legacy_api_tds_client.py} +15 -15
  108. {pylegend-0.3.0.dist-info → pylegend-0.5.0.dist-info}/METADATA +7 -8
  109. pylegend-0.5.0.dist-info/NOTICE +5 -0
  110. pylegend-0.5.0.dist-info/RECORD +155 -0
  111. {pylegend-0.3.0.dist-info → pylegend-0.5.0.dist-info}/WHEEL +1 -1
  112. pylegend/core/language/operations/primitive_operation_expressions.py +0 -56
  113. pylegend/core/tds/legend_api/frames/legend_api_base_tds_frame.py +0 -294
  114. pylegend-0.3.0.dist-info/RECORD +0 -115
  115. /pylegend/core/{databse → database}/__init__.py +0 -0
  116. /pylegend/core/{databse → database}/sql_to_string/config.py +0 -0
  117. /pylegend/core/language/{operations → shared/operations}/__init__.py +0 -0
  118. /pylegend/core/tds/{legend_api → legacy_api}/__init__.py +0 -0
  119. /pylegend/core/tds/{legend_api → legacy_api}/frames/__init__.py +0 -0
  120. /pylegend/core/tds/{legend_api → legacy_api}/frames/functions/__init__.py +0 -0
  121. /pylegend/extensions/tds/{legend_api → legacy_api}/__init__.py +0 -0
  122. /pylegend/extensions/tds/{legend_api → legacy_api}/frames/__init__.py +0 -0
  123. {pylegend-0.3.0.dist-info → pylegend-0.5.0.dist-info}/LICENSE +0 -0
  124. {pylegend-0.3.0.dist-info → pylegend-0.5.0.dist-info}/LICENSE.spdx +0 -0
@@ -17,10 +17,10 @@ from pylegend._typing import (
17
17
  PyLegendDict,
18
18
  PyLegendUnion,
19
19
  )
20
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive
21
- from pylegend.core.language.expression import PyLegendExpressionBooleanReturn, PyLegendExpression
22
- from pylegend.core.language.literal_expressions import PyLegendBooleanLiteralExpression
23
- from pylegend.core.language.operations.boolean_operation_expressions import (
20
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive
21
+ from pylegend.core.language.shared.expression import PyLegendExpressionBooleanReturn
22
+ from pylegend.core.language.shared.literal_expressions import PyLegendBooleanLiteralExpression
23
+ from pylegend.core.language.shared.operations.boolean_operation_expressions import (
24
24
  PyLegendBooleanOrExpression,
25
25
  PyLegendBooleanAndExpression,
26
26
  PyLegendBooleanNotExpression,
@@ -30,6 +30,7 @@ from pylegend.core.sql.metamodel import (
30
30
  QuerySpecification
31
31
  )
32
32
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
33
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
33
34
 
34
35
 
35
36
  __all__: PyLegendSequence[str] = [
@@ -53,7 +54,10 @@ class PyLegendBoolean(PyLegendPrimitive):
53
54
  ) -> Expression:
54
55
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
55
56
 
56
- def value(self) -> PyLegendExpression:
57
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
58
+ return self.__value.to_pure_expression(config)
59
+
60
+ def value(self) -> PyLegendExpressionBooleanReturn:
57
61
  return self.__value
58
62
 
59
63
  def __or__(self, other: PyLegendUnion[bool, "PyLegendBoolean"]) -> "PyLegendBoolean":
@@ -19,17 +19,17 @@ from pylegend._typing import (
19
19
  PyLegendUnion,
20
20
  TYPE_CHECKING,
21
21
  )
22
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive
23
- from pylegend.core.language.primitives.integer import PyLegendInteger
24
- from pylegend.core.language.expression import (
25
- PyLegendExpression,
22
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive
23
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
24
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
25
+ from pylegend.core.language.shared.expression import (
26
26
  PyLegendExpressionDateReturn,
27
27
  )
28
- from pylegend.core.language.literal_expressions import (
28
+ from pylegend.core.language.shared.literal_expressions import (
29
29
  PyLegendDateTimeLiteralExpression,
30
30
  PyLegendStrictDateLiteralExpression,
31
31
  )
32
- from pylegend.core.language.operations.date_operation_expressions import (
32
+ from pylegend.core.language.shared.operations.date_operation_expressions import (
33
33
  PyLegendFirstDayOfYearExpression,
34
34
  PyLegendFirstDayOfQuarterExpression,
35
35
  PyLegendFirstDayOfMonthExpression,
@@ -49,15 +49,21 @@ from pylegend.core.language.operations.date_operation_expressions import (
49
49
  PyLegendMinuteExpression,
50
50
  PyLegendSecondExpression,
51
51
  PyLegendEpochExpression,
52
+ PyLegendDatePartExpression,
53
+ PyLegendDateLessThanExpression,
54
+ PyLegendDateLessThanEqualExpression,
55
+ PyLegendDateGreaterThanExpression,
56
+ PyLegendDateGreaterThanEqualExpression,
52
57
  )
53
58
  from pylegend.core.sql.metamodel import (
54
59
  Expression,
55
60
  QuerySpecification
56
61
  )
57
62
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
63
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
58
64
  if TYPE_CHECKING:
59
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
60
- from pylegend.core.language.primitives.strictdate import PyLegendStrictDate
65
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
66
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
61
67
 
62
68
 
63
69
  __all__: PyLegendSequence[str] = [
@@ -81,7 +87,10 @@ class PyLegendDate(PyLegendPrimitive):
81
87
  ) -> Expression:
82
88
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
83
89
 
84
- def value(self) -> PyLegendExpression:
90
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
91
+ return self.__value.to_pure_expression(config)
92
+
93
+ def value(self) -> PyLegendExpressionDateReturn:
85
94
  return self.__value
86
95
 
87
96
  def first_day_of_year(self) -> "PyLegendDate":
@@ -97,19 +106,19 @@ class PyLegendDate(PyLegendPrimitive):
97
106
  return PyLegendDate(PyLegendFirstDayOfWeekExpression(self.__value))
98
107
 
99
108
  def first_hour_of_day(self) -> "PyLegendDateTime":
100
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
109
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
101
110
  return PyLegendDateTime(PyLegendFirstHourOfDayExpression(self.__value))
102
111
 
103
112
  def first_minute_of_hour(self) -> "PyLegendDateTime":
104
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
113
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
105
114
  return PyLegendDateTime(PyLegendFirstMinuteOfHourExpression(self.__value))
106
115
 
107
116
  def first_second_of_minute(self) -> "PyLegendDateTime":
108
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
117
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
109
118
  return PyLegendDateTime(PyLegendFirstSecondOfMinuteExpression(self.__value))
110
119
 
111
120
  def first_millisecond_of_second(self) -> "PyLegendDateTime":
112
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
121
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
113
122
  return PyLegendDateTime(PyLegendFirstMillisecondOfSecondExpression(self.__value))
114
123
 
115
124
  def year(self) -> "PyLegendInteger":
@@ -145,6 +154,42 @@ class PyLegendDate(PyLegendPrimitive):
145
154
  def day_of_week(self) -> "PyLegendInteger":
146
155
  return PyLegendInteger(PyLegendDayOfWeekExpression(self.__value))
147
156
 
157
+ def date_part(self) -> "PyLegendStrictDate":
158
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
159
+ return PyLegendStrictDate(PyLegendDatePartExpression(self.__value))
160
+
161
+ def __lt__(
162
+ self,
163
+ other: PyLegendUnion[date, datetime, "PyLegendStrictDate", "PyLegendDateTime", "PyLegendDate"]
164
+ ) -> "PyLegendBoolean":
165
+ PyLegendDate.validate_param_to_be_date(other, "Date less than (<) parameter")
166
+ other_op = PyLegendDate.__convert_to_date_expr(other)
167
+ return PyLegendBoolean(PyLegendDateLessThanExpression(self.__value, other_op))
168
+
169
+ def __le__(
170
+ self,
171
+ other: PyLegendUnion[date, datetime, "PyLegendStrictDate", "PyLegendDateTime", "PyLegendDate"]
172
+ ) -> "PyLegendBoolean":
173
+ PyLegendDate.validate_param_to_be_date(other, "Date less than equal (<=) parameter")
174
+ other_op = PyLegendDate.__convert_to_date_expr(other)
175
+ return PyLegendBoolean(PyLegendDateLessThanEqualExpression(self.__value, other_op))
176
+
177
+ def __gt__(
178
+ self,
179
+ other: PyLegendUnion[date, datetime, "PyLegendStrictDate", "PyLegendDateTime", "PyLegendDate"]
180
+ ) -> "PyLegendBoolean":
181
+ PyLegendDate.validate_param_to_be_date(other, "Date greater than (>) parameter")
182
+ other_op = PyLegendDate.__convert_to_date_expr(other)
183
+ return PyLegendBoolean(PyLegendDateGreaterThanExpression(self.__value, other_op))
184
+
185
+ def __ge__(
186
+ self,
187
+ other: PyLegendUnion[date, datetime, "PyLegendStrictDate", "PyLegendDateTime", "PyLegendDate"]
188
+ ) -> "PyLegendBoolean":
189
+ PyLegendDate.validate_param_to_be_date(other, "Date greater than equal (>=) parameter")
190
+ other_op = PyLegendDate.__convert_to_date_expr(other)
191
+ return PyLegendBoolean(PyLegendDateGreaterThanEqualExpression(self.__value, other_op))
192
+
148
193
  @staticmethod
149
194
  def __convert_to_date_expr(
150
195
  val: PyLegendUnion[date, datetime, "PyLegendDateTime", "PyLegendStrictDate", "PyLegendDate"]
@@ -160,8 +205,8 @@ class PyLegendDate(PyLegendPrimitive):
160
205
  param: PyLegendUnion[date, datetime, "PyLegendDateTime", "PyLegendStrictDate", "PyLegendDate"],
161
206
  desc: str
162
207
  ) -> None:
163
- from pylegend.core.language.primitives.datetime import PyLegendDateTime
164
- from pylegend.core.language.primitives.strictdate import PyLegendStrictDate
208
+ from pylegend.core.language.shared.primitives.datetime import PyLegendDateTime
209
+ from pylegend.core.language.shared.primitives.strictdate import PyLegendStrictDate
165
210
  if not isinstance(param, (date, datetime, PyLegendDateTime, PyLegendStrictDate, PyLegendDate)):
166
211
  raise TypeError(desc + " should be a datetime.date/datetime.datetime or a Date expression"
167
212
  " (PyLegendDateTime/PyLegendStrictDate/PyLegendDate)."
@@ -18,12 +18,11 @@ from pylegend._typing import (
18
18
  PyLegendDict,
19
19
  PyLegendUnion,
20
20
  )
21
- from pylegend.core.language.primitives.date import PyLegendDate
22
- from pylegend.core.language.expression import (
23
- PyLegendExpression,
21
+ from pylegend.core.language.shared.primitives.date import PyLegendDate
22
+ from pylegend.core.language.shared.expression import (
24
23
  PyLegendExpressionDateTimeReturn,
25
24
  )
26
- from pylegend.core.language.literal_expressions import (
25
+ from pylegend.core.language.shared.literal_expressions import (
27
26
  PyLegendDateTimeLiteralExpression,
28
27
  )
29
28
  from pylegend.core.sql.metamodel import (
@@ -55,7 +54,7 @@ class PyLegendDateTime(PyLegendDate):
55
54
  ) -> Expression:
56
55
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
57
56
 
58
- def value(self) -> PyLegendExpression:
57
+ def value(self) -> PyLegendExpressionDateTimeReturn:
59
58
  return self.__value
60
59
 
61
60
  @staticmethod
@@ -18,15 +18,15 @@ from pylegend._typing import (
18
18
  PyLegendUnion,
19
19
  TYPE_CHECKING,
20
20
  )
21
- from pylegend.core.language.primitives.number import PyLegendNumber
22
- from pylegend.core.language.expression import PyLegendExpressionFloatReturn, PyLegendExpression
23
- from pylegend.core.language.literal_expressions import PyLegendFloatLiteralExpression
21
+ from pylegend.core.language.shared.primitives.number import PyLegendNumber
22
+ from pylegend.core.language.shared.expression import PyLegendExpressionFloatReturn
23
+ from pylegend.core.language.shared.literal_expressions import PyLegendFloatLiteralExpression
24
24
  from pylegend.core.sql.metamodel import (
25
25
  Expression,
26
26
  QuerySpecification
27
27
  )
28
28
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
29
- from pylegend.core.language.operations.float_operation_expressions import (
29
+ from pylegend.core.language.shared.operations.float_operation_expressions import (
30
30
  PyLegendFloatAbsoluteExpression,
31
31
  PyLegendFloatAddExpression,
32
32
  PyLegendFloatNegativeExpression,
@@ -34,7 +34,7 @@ from pylegend.core.language.operations.float_operation_expressions import (
34
34
  PyLegendFloatMultiplyExpression,
35
35
  )
36
36
  if TYPE_CHECKING:
37
- from pylegend.core.language.primitives import PyLegendInteger
37
+ from pylegend.core.language.shared.primitives import PyLegendInteger
38
38
 
39
39
  __all__: PyLegendSequence[str] = [
40
40
  "PyLegendFloat"
@@ -141,7 +141,7 @@ class PyLegendFloat(PyLegendNumber):
141
141
  ) -> Expression:
142
142
  return super().to_sql_expression(frame_name_to_base_query_map, config)
143
143
 
144
- def value(self) -> PyLegendExpression:
144
+ def value(self) -> PyLegendExpressionFloatReturn:
145
145
  return self.__value_copy
146
146
 
147
147
  @staticmethod
@@ -18,15 +18,15 @@ from pylegend._typing import (
18
18
  PyLegendUnion,
19
19
  TYPE_CHECKING,
20
20
  )
21
- from pylegend.core.language.primitives.number import PyLegendNumber
22
- from pylegend.core.language.expression import PyLegendExpressionIntegerReturn, PyLegendExpression
23
- from pylegend.core.language.literal_expressions import PyLegendIntegerLiteralExpression
21
+ from pylegend.core.language.shared.primitives.number import PyLegendNumber
22
+ from pylegend.core.language.shared.expression import PyLegendExpressionIntegerReturn
23
+ from pylegend.core.language.shared.literal_expressions import PyLegendIntegerLiteralExpression
24
24
  from pylegend.core.sql.metamodel import (
25
25
  Expression,
26
26
  QuerySpecification
27
27
  )
28
28
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
29
- from pylegend.core.language.operations.integer_operation_expressions import (
29
+ from pylegend.core.language.shared.operations.integer_operation_expressions import (
30
30
  PyLegendIntegerAddExpression,
31
31
  PyLegendIntegerAbsoluteExpression,
32
32
  PyLegendIntegerNegativeExpression,
@@ -35,7 +35,7 @@ from pylegend.core.language.operations.integer_operation_expressions import (
35
35
  PyLegendIntegerModuloExpression,
36
36
  )
37
37
  if TYPE_CHECKING:
38
- from pylegend.core.language.primitives import PyLegendFloat
38
+ from pylegend.core.language.shared.primitives import PyLegendFloat
39
39
 
40
40
  __all__: PyLegendSequence[str] = [
41
41
  "PyLegendInteger"
@@ -59,7 +59,7 @@ class PyLegendInteger(PyLegendNumber):
59
59
  ) -> Expression:
60
60
  return super().to_sql_expression(frame_name_to_base_query_map, config)
61
61
 
62
- def value(self) -> PyLegendExpression:
62
+ def value(self) -> PyLegendExpressionIntegerReturn:
63
63
  return self.__value_copy
64
64
 
65
65
  def __add__(
@@ -19,17 +19,16 @@ from pylegend._typing import (
19
19
  PyLegendOptional,
20
20
  TYPE_CHECKING,
21
21
  )
22
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive
23
- from pylegend.core.language.primitives.boolean import PyLegendBoolean
24
- from pylegend.core.language.expression import (
25
- PyLegendExpression,
22
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive
23
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
24
+ from pylegend.core.language.shared.expression import (
26
25
  PyLegendExpressionNumberReturn,
27
26
  )
28
- from pylegend.core.language.literal_expressions import (
27
+ from pylegend.core.language.shared.literal_expressions import (
29
28
  PyLegendIntegerLiteralExpression,
30
29
  PyLegendFloatLiteralExpression,
31
30
  )
32
- from pylegend.core.language.operations.number_operation_expressions import (
31
+ from pylegend.core.language.shared.operations.number_operation_expressions import (
33
32
  PyLegendNumberAddExpression,
34
33
  PyLegendNumberMultiplyExpression,
35
34
  PyLegendNumberDivideExpression,
@@ -63,9 +62,10 @@ from pylegend.core.sql.metamodel import (
63
62
  QuerySpecification
64
63
  )
65
64
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
65
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
66
66
  if TYPE_CHECKING:
67
- from pylegend.core.language.primitives.integer import PyLegendInteger
68
- from pylegend.core.language.primitives.float import PyLegendFloat
67
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
68
+ from pylegend.core.language.shared.primitives.float import PyLegendFloat
69
69
 
70
70
 
71
71
  __all__: PyLegendSequence[str] = [
@@ -89,7 +89,10 @@ class PyLegendNumber(PyLegendPrimitive):
89
89
  ) -> Expression:
90
90
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
91
91
 
92
- def value(self) -> PyLegendExpression:
92
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
93
+ return self.__value.to_pure_expression(config)
94
+
95
+ def value(self) -> PyLegendExpressionNumberReturn:
93
96
  return self.__value
94
97
 
95
98
  def __add__(
@@ -214,14 +217,14 @@ class PyLegendNumber(PyLegendPrimitive):
214
217
  return PyLegendNumber(PyLegendNumberPowerExpression(other_op, self.__value))
215
218
 
216
219
  def ceil(self) -> "PyLegendInteger":
217
- from pylegend.core.language.primitives.integer import PyLegendInteger
220
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
218
221
  return PyLegendInteger(PyLegendNumberCeilExpression(self.__value))
219
222
 
220
223
  def __ceil__(self) -> "PyLegendInteger":
221
224
  return self.ceil()
222
225
 
223
226
  def floor(self) -> "PyLegendInteger":
224
- from pylegend.core.language.primitives.integer import PyLegendInteger
227
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
225
228
  return PyLegendInteger(PyLegendNumberFloorExpression(self.__value))
226
229
 
227
230
  def __floor__(self) -> "PyLegendInteger":
@@ -305,8 +308,8 @@ class PyLegendNumber(PyLegendPrimitive):
305
308
  param: PyLegendUnion[int, float, "PyLegendInteger", "PyLegendFloat", "PyLegendNumber"],
306
309
  desc: str
307
310
  ) -> None:
308
- from pylegend.core.language.primitives.integer import PyLegendInteger
309
- from pylegend.core.language.primitives.float import PyLegendFloat
311
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
312
+ from pylegend.core.language.shared.primitives.float import PyLegendFloat
310
313
  if not isinstance(param, (int, float, PyLegendInteger, PyLegendFloat, PyLegendNumber)):
311
314
  raise TypeError(desc + " should be a int/float or a int/float/number expression"
312
315
  " (PyLegendInteger/PyLegendFloat/PyLegendNumber)."
@@ -25,14 +25,18 @@ from pylegend.core.sql.metamodel import (
25
25
  Expression,
26
26
  QuerySpecification
27
27
  )
28
- from pylegend.core.language.expression import PyLegendExpression
29
- from pylegend.core.language.literal_expressions import convert_literal_to_literal_expression
30
- from pylegend.core.language.operations.primitive_operation_expressions import (
28
+ from pylegend.core.language.shared.expression import PyLegendExpression
29
+ from pylegend.core.language.shared.literal_expressions import convert_literal_to_literal_expression
30
+ from pylegend.core.language.shared.operations.primitive_operation_expressions import (
31
31
  PyLegendPrimitiveEqualsExpression,
32
+ PyLegendPrimitiveNotEqualsExpression,
33
+ PyLegendIsEmptyExpression,
34
+ PyLegendIsNotEmptyExpression,
32
35
  )
33
36
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
37
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
34
38
  if TYPE_CHECKING:
35
- from pylegend.core.language.primitives.boolean import PyLegendBoolean
39
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
36
40
 
37
41
  __all__: PyLegendSequence[str] = [
38
42
  "PyLegendPrimitive",
@@ -50,6 +54,10 @@ class PyLegendPrimitive(metaclass=ABCMeta):
50
54
  ) -> Expression:
51
55
  pass
52
56
 
57
+ @abstractmethod
58
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
59
+ pass
60
+
53
61
  def __eq__( # type: ignore
54
62
  self,
55
63
  other: "PyLegendUnion[int, float, bool, str, date, datetime, PyLegendPrimitive]"
@@ -61,9 +69,37 @@ class PyLegendPrimitive(metaclass=ABCMeta):
61
69
  else:
62
70
  other_op = other.value()
63
71
 
64
- from pylegend.core.language.primitives.boolean import PyLegendBoolean
72
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
65
73
  return PyLegendBoolean(PyLegendPrimitiveEqualsExpression(self.value(), other_op))
66
74
 
75
+ def __ne__( # type: ignore
76
+ self,
77
+ other: "PyLegendUnion[int, float, bool, str, date, datetime, PyLegendPrimitive]"
78
+ ) -> "PyLegendBoolean":
79
+ PyLegendPrimitive.__validate_param_to_be_primitive(other, "Not Equals (!=) parameter")
80
+
81
+ if isinstance(other, (int, float, bool, str, date, datetime)):
82
+ other_op = convert_literal_to_literal_expression(other)
83
+ else:
84
+ other_op = other.value()
85
+
86
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
87
+ return PyLegendBoolean(PyLegendPrimitiveNotEqualsExpression(self.value(), other_op))
88
+
89
+ def is_empty(self) -> "PyLegendBoolean":
90
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
91
+ return PyLegendBoolean(PyLegendIsEmptyExpression(self.value()))
92
+
93
+ def is_null(self) -> "PyLegendBoolean":
94
+ return self.is_empty()
95
+
96
+ def is_not_empty(self) -> "PyLegendBoolean":
97
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
98
+ return PyLegendBoolean(PyLegendIsNotEmptyExpression(self.value()))
99
+
100
+ def is_not_null(self) -> "PyLegendBoolean":
101
+ return self.is_not_empty()
102
+
67
103
  @staticmethod
68
104
  def __validate_param_to_be_primitive(
69
105
  param: "PyLegendUnion[int, float, bool, str, date, datetime, PyLegendPrimitive]",
@@ -18,12 +18,11 @@ from pylegend._typing import (
18
18
  PyLegendDict,
19
19
  PyLegendUnion,
20
20
  )
21
- from pylegend.core.language.primitives.date import PyLegendDate
22
- from pylegend.core.language.expression import (
23
- PyLegendExpression,
21
+ from pylegend.core.language.shared.primitives.date import PyLegendDate
22
+ from pylegend.core.language.shared.expression import (
24
23
  PyLegendExpressionStrictDateReturn,
25
24
  )
26
- from pylegend.core.language.literal_expressions import (
25
+ from pylegend.core.language.shared.literal_expressions import (
27
26
  PyLegendStrictDateLiteralExpression,
28
27
  )
29
28
  from pylegend.core.sql.metamodel import (
@@ -55,7 +54,7 @@ class PyLegendStrictDate(PyLegendDate):
55
54
  ) -> Expression:
56
55
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
57
56
 
58
- def value(self) -> PyLegendExpression:
57
+ def value(self) -> PyLegendExpressionStrictDateReturn:
59
58
  return self.__value
60
59
 
61
60
  @staticmethod
@@ -17,20 +17,23 @@ from pylegend._typing import (
17
17
  PyLegendDict,
18
18
  PyLegendUnion,
19
19
  )
20
- from pylegend.core.language.primitives.primitive import PyLegendPrimitive
21
- from pylegend.core.language.primitives.integer import PyLegendInteger
22
- from pylegend.core.language.primitives.float import PyLegendFloat
23
- from pylegend.core.language.primitives.boolean import PyLegendBoolean
24
- from pylegend.core.language.expression import PyLegendExpressionStringReturn, PyLegendExpression
25
- from pylegend.core.language.literal_expressions import PyLegendStringLiteralExpression
20
+ from pylegend.core.language.shared.primitives.primitive import PyLegendPrimitive
21
+ from pylegend.core.language.shared.primitives.integer import PyLegendInteger
22
+ from pylegend.core.language.shared.primitives.float import PyLegendFloat
23
+ from pylegend.core.language.shared.primitives.boolean import PyLegendBoolean
24
+ from pylegend.core.language.shared.expression import PyLegendExpressionStringReturn
25
+ from pylegend.core.language.shared.literal_expressions import PyLegendStringLiteralExpression
26
26
  from pylegend.core.sql.metamodel import (
27
27
  Expression,
28
28
  QuerySpecification
29
29
  )
30
30
  from pylegend.core.tds.tds_frame import FrameToSqlConfig
31
- from pylegend.core.language.operations.string_operation_expressions import (
31
+ from pylegend.core.tds.tds_frame import FrameToPureConfig
32
+ from pylegend.core.language.shared.operations.string_operation_expressions import (
32
33
  PyLegendStringLengthExpression,
33
- PyLegendStringLikeExpression,
34
+ PyLegendStringStartsWithExpression,
35
+ PyLegendStringEndsWithExpression,
36
+ PyLegendStringContainsExpression,
34
37
  PyLegendStringUpperExpression,
35
38
  PyLegendStringLowerExpression,
36
39
  PyLegendStringLTrimExpression,
@@ -69,23 +72,20 @@ class PyLegendString(PyLegendPrimitive):
69
72
 
70
73
  def startswith(self, prefix: str) -> PyLegendBoolean:
71
74
  PyLegendString.__validate_param_to_be_str(prefix, "startswith prefix parameter")
72
- escaped_prefix = PyLegendString.__escape_like_param(prefix)
73
75
  return PyLegendBoolean(
74
- PyLegendStringLikeExpression(self.__value, PyLegendStringLiteralExpression(escaped_prefix + '%'))
76
+ PyLegendStringStartsWithExpression(self.__value, PyLegendStringLiteralExpression(prefix))
75
77
  )
76
78
 
77
79
  def endswith(self, suffix: str) -> PyLegendBoolean:
78
80
  PyLegendString.__validate_param_to_be_str(suffix, "endswith suffix parameter")
79
- escaped_suffix = PyLegendString.__escape_like_param(suffix)
80
81
  return PyLegendBoolean(
81
- PyLegendStringLikeExpression(self.__value, PyLegendStringLiteralExpression("%" + escaped_suffix))
82
+ PyLegendStringEndsWithExpression(self.__value, PyLegendStringLiteralExpression(suffix))
82
83
  )
83
84
 
84
85
  def contains(self, other: str) -> PyLegendBoolean:
85
86
  PyLegendString.__validate_param_to_be_str(other, "contains/in other parameter")
86
- escaped_other = PyLegendString.__escape_like_param(other)
87
87
  return PyLegendBoolean(
88
- PyLegendStringLikeExpression(self.__value, PyLegendStringLiteralExpression("%" + escaped_other + "%"))
88
+ PyLegendStringContainsExpression(self.__value, PyLegendStringLiteralExpression(other))
89
89
  )
90
90
 
91
91
  def upper(self) -> "PyLegendString":
@@ -157,12 +157,11 @@ class PyLegendString(PyLegendPrimitive):
157
157
  ) -> Expression:
158
158
  return self.__value.to_sql_expression(frame_name_to_base_query_map, config)
159
159
 
160
- def value(self) -> PyLegendExpression:
161
- return self.__value
160
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
161
+ return self.__value.to_pure_expression(config)
162
162
 
163
- @staticmethod
164
- def __escape_like_param(param: str) -> str:
165
- return param.replace("_", "\\_").replace("%", "\\%")
163
+ def value(self) -> PyLegendExpressionStringReturn:
164
+ return self.__value
166
165
 
167
166
  @staticmethod
168
167
  def __validate_param_to_be_str_or_str_expr(param: PyLegendUnion[str, "PyLegendString"], desc: str) -> None:
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Goldman Sachs
1
+ # Copyright 2025 Goldman Sachs
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -12,10 +12,21 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from abc import ABCMeta
15
16
  from pylegend._typing import (
16
17
  PyLegendSequence,
18
+ PyLegendDict,
19
+ )
20
+ from pylegend.core.sql.metamodel import (
21
+ QuerySpecification,
22
+ Expression,
23
+ SingleColumn,
24
+ )
25
+ from pylegend.core.tds.tds_frame import (
26
+ PyLegendTdsFrame,
27
+ FrameToPureConfig,
28
+ FrameToSqlConfig,
17
29
  )
18
- from pylegend.core.tds.tds_frame import PyLegendTdsFrame
19
30
  from pylegend.core.tds.tds_column import TdsColumn, PrimitiveTdsColumn
20
31
  from pylegend.core.language import (
21
32
  PyLegendColumnExpression,
@@ -39,11 +50,11 @@ from pylegend.core.language import (
39
50
  )
40
51
 
41
52
  __all__: PyLegendSequence[str] = [
42
- "TdsRow",
53
+ "AbstractTdsRow",
43
54
  ]
44
55
 
45
56
 
46
- class TdsRow:
57
+ class AbstractTdsRow(metaclass=ABCMeta):
47
58
  __frame_name: str
48
59
  __columns: PyLegendSequence[TdsColumn]
49
60
 
@@ -51,10 +62,6 @@ class TdsRow:
51
62
  self.__frame_name = frame_name
52
63
  self.__columns = frame.columns()
53
64
 
54
- @staticmethod
55
- def from_tds_frame(frame_name: str, frame: PyLegendTdsFrame) -> "TdsRow":
56
- return TdsRow(frame_name=frame_name, frame=frame)
57
-
58
65
  def get_boolean(self, column: str) -> PyLegendBoolean:
59
66
  col_expr = self.__get_col(column)
60
67
  if not isinstance(col_expr, PyLegendBooleanColumnExpression):
@@ -161,21 +168,21 @@ class TdsRow:
161
168
  if base_col.get_name() == column:
162
169
  if isinstance(base_col, PrimitiveTdsColumn):
163
170
  if base_col.get_type() == "Boolean":
164
- return PyLegendBooleanColumnExpression(self.__frame_name, column)
171
+ return PyLegendBooleanColumnExpression(self, column)
165
172
  if base_col.get_type() == "String":
166
- return PyLegendStringColumnExpression(self.__frame_name, column)
173
+ return PyLegendStringColumnExpression(self, column)
167
174
  if base_col.get_type() == "Number":
168
- return PyLegendNumberColumnExpression(self.__frame_name, column)
175
+ return PyLegendNumberColumnExpression(self, column)
169
176
  if base_col.get_type() == "Integer":
170
- return PyLegendIntegerColumnExpression(self.__frame_name, column)
177
+ return PyLegendIntegerColumnExpression(self, column)
171
178
  if base_col.get_type() == "Float":
172
- return PyLegendFloatColumnExpression(self.__frame_name, column)
179
+ return PyLegendFloatColumnExpression(self, column)
173
180
  if base_col.get_type() == "Date":
174
- return PyLegendDateColumnExpression(self.__frame_name, column)
181
+ return PyLegendDateColumnExpression(self, column)
175
182
  if base_col.get_type() == "DateTime":
176
- return PyLegendDateTimeColumnExpression(self.__frame_name, column)
183
+ return PyLegendDateTimeColumnExpression(self, column)
177
184
  if base_col.get_type() == "StrictDate":
178
- return PyLegendStrictDateColumnExpression(self.__frame_name, column)
185
+ return PyLegendStrictDateColumnExpression(self, column)
179
186
 
180
187
  raise RuntimeError(f"Column '{column}' of type {base_col.get_type()} not supported yet")
181
188
 
@@ -183,3 +190,26 @@ class TdsRow:
183
190
  f"Column - '{column}' doesn't exist in the current frame. "
184
191
  f"Current frame columns: {[x.get_name() for x in self.__columns]}"
185
192
  )
193
+
194
+ def get_frame_name(self) -> str:
195
+ return self.__frame_name
196
+
197
+ def to_pure_expression(self, config: FrameToPureConfig) -> str:
198
+ return f"${self.__frame_name}"
199
+
200
+ def column_sql_expression(
201
+ self,
202
+ column: str,
203
+ frame_name_to_base_query_map: PyLegendDict[str, QuerySpecification],
204
+ config: FrameToSqlConfig
205
+ ) -> Expression:
206
+ query = frame_name_to_base_query_map[self.__frame_name]
207
+ db_extension = config.sql_to_string_generator().get_db_extension()
208
+ filtered = [
209
+ s for s in query.select.selectItems
210
+ if (isinstance(s, SingleColumn) and
211
+ s.alias == db_extension.quote_identifier(column))
212
+ ]
213
+ if len(filtered) == 0:
214
+ raise RuntimeError("Cannot find column: " + column) # pragma: no cover
215
+ return filtered[0].expression
@@ -16,7 +16,12 @@ from pylegend._typing import (
16
16
  PyLegendSequence,
17
17
  )
18
18
  from pylegend.core.request.legend_client import LegendClient
19
- from pylegend.core.request.auth import AuthScheme, LocalhostEmptyAuthScheme, HeaderTokenAuthScheme
19
+ from pylegend.core.request.auth import (
20
+ AuthScheme,
21
+ LocalhostEmptyAuthScheme,
22
+ HeaderTokenAuthScheme,
23
+ CookieAuthScheme,
24
+ )
20
25
  from pylegend.core.request.response_reader import ResponseReader
21
26
 
22
27
  __all__: PyLegendSequence[str] = [
@@ -25,6 +30,7 @@ __all__: PyLegendSequence[str] = [
25
30
  "AuthScheme",
26
31
  "LocalhostEmptyAuthScheme",
27
32
  "HeaderTokenAuthScheme",
33
+ "CookieAuthScheme",
28
34
 
29
35
  "ResponseReader"
30
36
  ]