pylegend 0.1.0__py3-none-any.whl → 0.2.2__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 (25) hide show
  1. pylegend/__init__.py +31 -1
  2. pylegend/core/language/__init__.py +2 -1
  3. pylegend/core/language/aggregate_specification.py +9 -0
  4. pylegend/core/project_cooridnates.py +125 -0
  5. pylegend/core/request/__init__.py +16 -0
  6. pylegend/core/request/auth.py +61 -0
  7. pylegend/core/request/legend_client.py +18 -3
  8. pylegend/core/request/service_client.py +17 -3
  9. pylegend/core/tds/tds_column.py +1 -1
  10. pylegend/extensions/tds/abstract/__init__.py +13 -0
  11. pylegend/extensions/tds/abstract/legend_function_input_frame.py +108 -0
  12. pylegend/extensions/tds/abstract/legend_service_input_frame.py +108 -0
  13. pylegend/extensions/tds/abstract/table_spec_input_frame.py +70 -0
  14. pylegend/extensions/tds/legend_api/frames/legend_api_legend_function_input_frame.py +46 -0
  15. pylegend/extensions/tds/legend_api/frames/legend_api_legend_service_input_frame.py +46 -0
  16. pylegend/extensions/tds/legend_api/frames/legend_api_table_spec_input_frame.py +4 -43
  17. pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_function_input_frame.py +46 -0
  18. pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_service_input_frame.py +46 -0
  19. pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py +4 -43
  20. pylegend/legend_api_tds_client.py +73 -0
  21. {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/METADATA +10 -4
  22. {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/RECORD +25 -14
  23. {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/WHEEL +1 -1
  24. {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/LICENSE +0 -0
  25. {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/LICENSE.spdx +0 -0
pylegend/__init__.py CHANGED
@@ -15,10 +15,40 @@
15
15
  from pylegend._typing import (
16
16
  PyLegendSequence,
17
17
  )
18
+ from pylegend.legend_api_tds_client import (
19
+ LegendApiTdsClient,
20
+ legend_api_tds_client,
21
+ )
22
+ from pylegend.core.request import (
23
+ LegendClient,
24
+ AuthScheme,
25
+ LocalhostEmptyAuthScheme,
26
+ ResponseReader,
27
+ )
28
+ from pylegend.core.project_cooridnates import (
29
+ VersionedProjectCoordinates,
30
+ PersonalWorkspaceProjectCoordinates,
31
+ GroupWorkspaceProjectCoordinates,
32
+ )
33
+ from pylegend.core.language import agg
18
34
 
19
35
 
20
36
  __all__: PyLegendSequence[str] = [
21
- "__version__"
37
+ "__version__",
38
+
39
+ "LegendApiTdsClient",
40
+ "legend_api_tds_client",
41
+
42
+ "LegendClient",
43
+ "AuthScheme",
44
+ "LocalhostEmptyAuthScheme",
45
+ "ResponseReader",
46
+
47
+ "VersionedProjectCoordinates",
48
+ "PersonalWorkspaceProjectCoordinates",
49
+ "GroupWorkspaceProjectCoordinates",
50
+
51
+ "agg",
22
52
  ]
23
53
 
24
54
 
@@ -58,7 +58,7 @@ from pylegend.core.language.column_expressions import (
58
58
  PyLegendStrictDateColumnExpression,
59
59
  )
60
60
  from pylegend.core.language.tds_row import TdsRow
61
- from pylegend.core.language.aggregate_specification import AggregateSpecification
61
+ from pylegend.core.language.aggregate_specification import AggregateSpecification, agg
62
62
  from pylegend.core.language.primitive_collection import (
63
63
  PyLegendPrimitiveCollection,
64
64
  PyLegendIntegerCollection,
@@ -117,6 +117,7 @@ __all__: PyLegendSequence[str] = [
117
117
 
118
118
  "TdsRow",
119
119
  "AggregateSpecification",
120
+ "agg",
120
121
 
121
122
  "PyLegendPrimitiveCollection",
122
123
  "PyLegendIntegerCollection",
@@ -25,6 +25,7 @@ from pylegend.core.language import (
25
25
 
26
26
  __all__: PyLegendSequence[str] = [
27
27
  "AggregateSpecification",
28
+ "agg",
28
29
  ]
29
30
 
30
31
 
@@ -51,3 +52,11 @@ class AggregateSpecification:
51
52
 
52
53
  def get_aggregate_fn(self) -> PyLegendCallable[[PyLegendPrimitiveCollection], PyLegendPrimitive]:
53
54
  return self.__aggregate_fn
55
+
56
+
57
+ def agg(
58
+ map_fn: PyLegendCallable[[TdsRow], PyLegendPrimitiveOrPythonPrimitive],
59
+ aggregate_fn: PyLegendCallable[[PyLegendPrimitiveCollection], PyLegendPrimitive],
60
+ name: str
61
+ ) -> AggregateSpecification:
62
+ return AggregateSpecification(map_fn=map_fn, aggregate_fn=aggregate_fn, name=name)
@@ -0,0 +1,125 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import abc
16
+ from abc import ABCMeta
17
+ from pylegend._typing import (
18
+ PyLegendSequence,
19
+ PyLegendList,
20
+ )
21
+ from pylegend.core.sql.metamodel import (
22
+ NamedArgumentExpression,
23
+ StringLiteral,
24
+ )
25
+
26
+ __all__: PyLegendSequence[str] = [
27
+ "ProjectCoordinates",
28
+ "VersionedProjectCoordinates",
29
+ "PersonalWorkspaceProjectCoordinates",
30
+ "GroupWorkspaceProjectCoordinates",
31
+ ]
32
+
33
+
34
+ class ProjectCoordinates(metaclass=ABCMeta):
35
+
36
+ @abc.abstractmethod
37
+ def sql_params(self) -> PyLegendList[NamedArgumentExpression]:
38
+ pass
39
+
40
+
41
+ class VersionedProjectCoordinates(ProjectCoordinates):
42
+ __group_id: str
43
+ __artifact_id: str
44
+ __version: str
45
+
46
+ def __init__(self, group_id: str, artifact_id: str, version: str) -> None:
47
+ self.__group_id = group_id
48
+ self.__artifact_id = artifact_id
49
+ self.__version = version
50
+
51
+ def get_group_id(self) -> str:
52
+ return self.__group_id
53
+
54
+ def get_artifact_id(self) -> str:
55
+ return self.__artifact_id
56
+
57
+ def get_version(self) -> str:
58
+ return self.__version
59
+
60
+ def sql_params(self) -> PyLegendList[NamedArgumentExpression]:
61
+ return [
62
+ NamedArgumentExpression(
63
+ name="coordinates",
64
+ expression=StringLiteral(
65
+ value=f"{self.__group_id}:{self.__artifact_id}:{self.__version}",
66
+ quoted=False
67
+ )
68
+ )
69
+ ]
70
+
71
+
72
+ class WorkspaceProjectCoordinates(ProjectCoordinates, metaclass=ABCMeta):
73
+ __project_id: str
74
+
75
+ def __init__(self, project_id: str) -> None:
76
+ self.__project_id = project_id
77
+
78
+ def get_project_id(self) -> str:
79
+ return self.__project_id
80
+
81
+
82
+ class PersonalWorkspaceProjectCoordinates(WorkspaceProjectCoordinates):
83
+ __workspace: str
84
+
85
+ def __init__(self, project_id: str, workspace: str) -> None:
86
+ super().__init__(project_id)
87
+ self.__workspace = workspace
88
+
89
+ def get_workspace(self) -> str:
90
+ return self.__workspace
91
+
92
+ def sql_params(self) -> PyLegendList[NamedArgumentExpression]:
93
+ return [
94
+ NamedArgumentExpression(
95
+ name="project",
96
+ expression=StringLiteral(value=self.get_project_id(), quoted=False)
97
+ ),
98
+ NamedArgumentExpression(
99
+ name="workspace",
100
+ expression=StringLiteral(value=self.__workspace, quoted=False)
101
+ )
102
+ ]
103
+
104
+
105
+ class GroupWorkspaceProjectCoordinates(WorkspaceProjectCoordinates):
106
+ __group_workspace: str
107
+
108
+ def __init__(self, project_id: str, group_workspace: str) -> None:
109
+ super().__init__(project_id)
110
+ self.__group_workspace = group_workspace
111
+
112
+ def get_group_workspace(self) -> str:
113
+ return self.__group_workspace
114
+
115
+ def sql_params(self) -> PyLegendList[NamedArgumentExpression]:
116
+ return [
117
+ NamedArgumentExpression(
118
+ name="project",
119
+ expression=StringLiteral(value=self.get_project_id(), quoted=False)
120
+ ),
121
+ NamedArgumentExpression(
122
+ name="groupWorkspace",
123
+ expression=StringLiteral(value=self.__group_workspace, quoted=False)
124
+ )
125
+ ]
@@ -11,3 +11,19 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
+
15
+ from pylegend._typing import (
16
+ PyLegendSequence,
17
+ )
18
+ from pylegend.core.request.legend_client import LegendClient
19
+ from pylegend.core.request.auth import AuthScheme, LocalhostEmptyAuthScheme
20
+ from pylegend.core.request.response_reader import ResponseReader
21
+
22
+ __all__: PyLegendSequence[str] = [
23
+ "LegendClient",
24
+
25
+ "AuthScheme",
26
+ "LocalhostEmptyAuthScheme",
27
+
28
+ "ResponseReader"
29
+ ]
@@ -0,0 +1,61 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from abc import ABCMeta, abstractmethod
16
+
17
+ from requests import PreparedRequest
18
+
19
+ from pylegend._typing import (
20
+ PyLegendSequence,
21
+ PyLegendOptional,
22
+ )
23
+ from requests.auth import AuthBase
24
+
25
+ __all__: PyLegendSequence[str] = [
26
+ "AuthScheme",
27
+ "LocalhostEmptyAuthScheme",
28
+ "BearerAuthScheme"
29
+ ]
30
+
31
+
32
+ class AuthScheme(metaclass=ABCMeta):
33
+
34
+ @abstractmethod
35
+ def get_auth_base(self) -> PyLegendOptional[AuthBase]:
36
+ pass
37
+
38
+
39
+ class LocalhostEmptyAuthScheme(AuthScheme):
40
+
41
+ def get_auth_base(self) -> PyLegendOptional[AuthBase]:
42
+ return None
43
+
44
+
45
+ class BearerAuth(AuthBase):
46
+ def __init__(self, headerName: str, token: str) -> None:
47
+ self.headerName = headerName
48
+ self.token = token
49
+
50
+ def __call__(self, r: PreparedRequest) -> PreparedRequest:
51
+ r.headers[self.headerName] = self.token
52
+ return r
53
+
54
+
55
+ class BearerAuthScheme(AuthScheme):
56
+ def __init__(self, headerName: str, token: str) -> None:
57
+ self.headerName = headerName
58
+ self.token = token
59
+
60
+ def get_auth_base(self) -> PyLegendOptional[AuthBase]:
61
+ return BearerAuth(self.headerName, self.token)
@@ -17,6 +17,7 @@ from pylegend.core.request.service_client import (
17
17
  RequestMethod
18
18
  )
19
19
  from pylegend.core.request.response_reader import ResponseReader
20
+ from pylegend.core.request.auth import AuthScheme, LocalhostEmptyAuthScheme
20
21
  from pylegend._typing import (
21
22
  PyLegendSequence,
22
23
  PyLegendOptional,
@@ -24,15 +25,29 @@ from pylegend._typing import (
24
25
  from pylegend.core.tds.tds_column import TdsColumn, tds_columns_from_json
25
26
 
26
27
 
28
+ __all__: PyLegendSequence[str] = [
29
+ "LegendClient",
30
+ ]
31
+
32
+
27
33
  class LegendClient(ServiceClient):
28
34
  def __init__(
29
35
  self,
30
36
  host: str,
31
37
  port: int,
32
38
  secure_http: bool = True,
39
+ path_prefix: PyLegendOptional[str] = "/api",
40
+ auth_scheme: AuthScheme = LocalhostEmptyAuthScheme(),
33
41
  retry_count: int = 2
34
42
  ) -> None:
35
- super().__init__(host=host, port=port, secure_http=secure_http, retry_count=retry_count)
43
+ super().__init__(
44
+ host=host,
45
+ port=port,
46
+ secure_http=secure_http,
47
+ path_prefix=path_prefix,
48
+ auth_scheme=auth_scheme,
49
+ retry_count=retry_count
50
+ )
36
51
 
37
52
  def get_sql_string_schema(
38
53
  self,
@@ -40,7 +55,7 @@ class LegendClient(ServiceClient):
40
55
  ) -> PyLegendSequence[TdsColumn]:
41
56
  response = super()._execute_service(
42
57
  method=RequestMethod.POST,
43
- path="api/sql/v1/execution/getSchemaFromQueryString",
58
+ path="sql/v1/execution/getSchemaFromQueryString",
44
59
  data=sql,
45
60
  headers={"Content-Type": "text/plain"},
46
61
  stream=False
@@ -55,7 +70,7 @@ class LegendClient(ServiceClient):
55
70
  ) -> ResponseReader:
56
71
  iter_content = super()._execute_service(
57
72
  method=RequestMethod.POST,
58
- path="api/sql/v1/execution/executeQueryString",
73
+ path="sql/v1/execution/executeQueryString",
59
74
  data=sql,
60
75
  headers={"Content-Type": "text/plain"},
61
76
  stream=True
@@ -17,6 +17,7 @@ from enum import Enum
17
17
 
18
18
  import requests
19
19
  from requests.adapters import HTTPAdapter, Retry
20
+ from pylegend.core.request.auth import AuthScheme
20
21
  from pylegend._typing import (
21
22
  PyLegendSequence,
22
23
  PyLegendOptional,
@@ -39,9 +40,19 @@ class RequestMethod(Enum):
39
40
 
40
41
  class ServiceClient(metaclass=ABCMeta):
41
42
 
42
- def __init__(self, host: str, port: int, secure_http: bool, retry_count: int) -> None:
43
+ def __init__(
44
+ self,
45
+ host: str,
46
+ port: int,
47
+ secure_http: bool,
48
+ path_prefix: PyLegendOptional[str],
49
+ auth_scheme: AuthScheme,
50
+ retry_count: int
51
+ ) -> None:
43
52
  self.__host = host
44
53
  self.__port = port
54
+ self.__auth_scheme = auth_scheme
55
+ self.__path_prefix = path_prefix
45
56
  self.__secure_http = secure_http
46
57
  if retry_count < 1:
47
58
  raise ValueError("Retry count should be a number greater than 1. Got " + str(retry_count))
@@ -64,14 +75,17 @@ class ServiceClient(metaclass=ABCMeta):
64
75
  ) -> requests.Response:
65
76
 
66
77
  scheme = "https" if self.__secure_http else "http"
67
- url = f"{scheme}://{self.__host}:{self.__port}/{path}"
78
+ prefix = (self.__path_prefix if self.__path_prefix.startswith("/") else f"/{self.__path_prefix}") \
79
+ if self.__path_prefix is not None else ""
80
+ url = f"{scheme}://{self.__host}:{self.__port}{prefix}/{path}"
68
81
 
69
82
  request = requests.Request(
70
83
  method=method.name,
71
84
  url=url,
72
85
  headers=headers,
73
86
  data=data,
74
- params=query_params
87
+ params=query_params,
88
+ auth=self.__auth_scheme.get_auth_base(),
75
89
  )
76
90
 
77
91
  session = requests.Session()
@@ -150,7 +150,7 @@ def tds_columns_from_json(s: str) -> PyLegendSequence[TdsColumn]:
150
150
 
151
151
  result_columns: PyLegendList[TdsColumn] = []
152
152
  for col in columns:
153
- if col["__TYPE"] == "meta::external::query::sql::PrimitiveValueSchemaColumn":
153
+ if col["_type"] == "primitiveSchemaColumn":
154
154
  result_columns.append(PrimitiveTdsColumn(col["name"], PrimitiveType[col["type"]]))
155
155
  else:
156
156
  result_columns.append(
@@ -0,0 +1,13 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
@@ -0,0 +1,108 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from abc import ABCMeta
16
+ from pylegend._typing import (
17
+ PyLegendList,
18
+ PyLegendSequence,
19
+ )
20
+ from pylegend.core.tds.tds_frame import (
21
+ PyLegendTdsFrame,
22
+ FrameToSqlConfig,
23
+ )
24
+ from pylegend.core.project_cooridnates import ProjectCoordinates
25
+ from pylegend.core.sql.metamodel import (
26
+ QuerySpecification,
27
+ TableFunction,
28
+ Select,
29
+ AllColumns,
30
+ FunctionCall,
31
+ QualifiedName,
32
+ NamedArgumentExpression,
33
+ StringLiteral,
34
+ AliasedRelation,
35
+ SingleColumn,
36
+ QualifiedNameReference,
37
+ Expression,
38
+ )
39
+
40
+ __all__: PyLegendSequence[str] = [
41
+ "LegendFunctionInputFrameAbstract",
42
+ ]
43
+
44
+
45
+ class LegendFunctionInputFrameAbstract(PyLegendTdsFrame, metaclass=ABCMeta):
46
+ __path: str
47
+ __project_coordinates: ProjectCoordinates
48
+ __initialized: bool = False
49
+
50
+ def __init__(
51
+ self,
52
+ path: str,
53
+ project_coordinates: ProjectCoordinates,
54
+ ) -> None:
55
+ self.__path = path
56
+ self.__project_coordinates = project_coordinates
57
+
58
+ def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
59
+ db_extension = config.sql_to_string_generator().get_db_extension()
60
+ root_alias = db_extension.quote_identifier("root")
61
+ args: PyLegendList[Expression] = [
62
+ NamedArgumentExpression(
63
+ name="path",
64
+ expression=StringLiteral(value=self.__path, quoted=False)
65
+ )
66
+ ]
67
+ args += self.__project_coordinates.sql_params()
68
+ func_call = FunctionCall(
69
+ name=QualifiedName(["func"]),
70
+ distinct=False,
71
+ filter_=None,
72
+ window=None,
73
+ arguments=args
74
+ )
75
+
76
+ return QuerySpecification(
77
+ select=Select(
78
+ selectItems=[
79
+ SingleColumn(
80
+ alias=db_extension.quote_identifier(x.get_name()),
81
+ expression=QualifiedNameReference(
82
+ name=QualifiedName(parts=[root_alias, db_extension.quote_identifier(x.get_name())])
83
+ )
84
+ )
85
+ for x in self.columns()
86
+ ] if self.__initialized else [AllColumns(prefix=root_alias)],
87
+ distinct=False
88
+ ),
89
+ from_=[
90
+ AliasedRelation(
91
+ relation=TableFunction(functionCall=func_call),
92
+ alias=root_alias,
93
+ columnNames=[x.get_name() for x in self.columns()] if self.__initialized else []
94
+ )
95
+ ],
96
+ where=None,
97
+ groupBy=[],
98
+ having=None,
99
+ orderBy=[],
100
+ limit=None,
101
+ offset=None
102
+ )
103
+
104
+ def get_path(self) -> str:
105
+ return self.__path
106
+
107
+ def set_initialized(self, val: bool) -> None:
108
+ self.__initialized = val
@@ -0,0 +1,108 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from abc import ABCMeta
16
+ from pylegend._typing import (
17
+ PyLegendList,
18
+ PyLegendSequence,
19
+ )
20
+ from pylegend.core.tds.tds_frame import (
21
+ PyLegendTdsFrame,
22
+ FrameToSqlConfig,
23
+ )
24
+ from pylegend.core.project_cooridnates import ProjectCoordinates
25
+ from pylegend.core.sql.metamodel import (
26
+ QuerySpecification,
27
+ TableFunction,
28
+ Select,
29
+ AllColumns,
30
+ FunctionCall,
31
+ QualifiedName,
32
+ NamedArgumentExpression,
33
+ StringLiteral,
34
+ AliasedRelation,
35
+ SingleColumn,
36
+ QualifiedNameReference,
37
+ Expression,
38
+ )
39
+
40
+ __all__: PyLegendSequence[str] = [
41
+ "LegendServiceInputFrameAbstract",
42
+ ]
43
+
44
+
45
+ class LegendServiceInputFrameAbstract(PyLegendTdsFrame, metaclass=ABCMeta):
46
+ __pattern: str
47
+ __project_coordinates: ProjectCoordinates
48
+ __initialized: bool = False
49
+
50
+ def __init__(
51
+ self,
52
+ pattern: str,
53
+ project_coordinates: ProjectCoordinates,
54
+ ) -> None:
55
+ self.__pattern = pattern
56
+ self.__project_coordinates = project_coordinates
57
+
58
+ def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
59
+ db_extension = config.sql_to_string_generator().get_db_extension()
60
+ root_alias = db_extension.quote_identifier("root")
61
+ args: PyLegendList[Expression] = [
62
+ NamedArgumentExpression(
63
+ name="pattern",
64
+ expression=StringLiteral(value=self.__pattern, quoted=False)
65
+ )
66
+ ]
67
+ args += self.__project_coordinates.sql_params()
68
+ func_call = FunctionCall(
69
+ name=QualifiedName(["service"]),
70
+ distinct=False,
71
+ filter_=None,
72
+ window=None,
73
+ arguments=args
74
+ )
75
+
76
+ return QuerySpecification(
77
+ select=Select(
78
+ selectItems=[
79
+ SingleColumn(
80
+ alias=db_extension.quote_identifier(x.get_name()),
81
+ expression=QualifiedNameReference(
82
+ name=QualifiedName(parts=[root_alias, db_extension.quote_identifier(x.get_name())])
83
+ )
84
+ )
85
+ for x in self.columns()
86
+ ] if self.__initialized else [AllColumns(prefix=root_alias)],
87
+ distinct=False
88
+ ),
89
+ from_=[
90
+ AliasedRelation(
91
+ relation=TableFunction(functionCall=func_call),
92
+ alias=root_alias,
93
+ columnNames=[x.get_name() for x in self.columns()] if self.__initialized else []
94
+ )
95
+ ],
96
+ where=None,
97
+ groupBy=[],
98
+ having=None,
99
+ orderBy=[],
100
+ limit=None,
101
+ offset=None
102
+ )
103
+
104
+ def get_pattern(self) -> str:
105
+ return self.__pattern
106
+
107
+ def set_initialized(self, val: bool) -> None:
108
+ self.__initialized = val
@@ -0,0 +1,70 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from abc import ABCMeta
16
+ from pylegend._typing import (
17
+ PyLegendSequence,
18
+ PyLegendList,
19
+ )
20
+ from pylegend.core.sql.metamodel import (
21
+ QualifiedName,
22
+ QualifiedNameReference,
23
+ QuerySpecification,
24
+ Select,
25
+ SingleColumn,
26
+ Table,
27
+ AliasedRelation
28
+ )
29
+ from pylegend.core.tds.tds_frame import PyLegendTdsFrame
30
+ from pylegend.core.tds.tds_frame import FrameToSqlConfig
31
+
32
+ __all__: PyLegendSequence[str] = [
33
+ "TableSpecInputFrameAbstract",
34
+ ]
35
+
36
+
37
+ class TableSpecInputFrameAbstract(PyLegendTdsFrame, metaclass=ABCMeta):
38
+ table: QualifiedName
39
+
40
+ def __init__(self, table_name_parts: PyLegendList[str]) -> None:
41
+ self.table = QualifiedName(table_name_parts)
42
+
43
+ def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
44
+ db_extension = config.sql_to_string_generator().get_db_extension()
45
+ root_alias = db_extension.quote_identifier("root")
46
+ return QuerySpecification(
47
+ select=Select(
48
+ selectItems=[
49
+ SingleColumn(
50
+ alias=db_extension.quote_identifier(x.get_name()),
51
+ expression=QualifiedNameReference(name=QualifiedName(parts=[root_alias, x.get_name()]))
52
+ )
53
+ for x in self.columns()
54
+ ],
55
+ distinct=False
56
+ ),
57
+ from_=[
58
+ AliasedRelation(
59
+ relation=Table(name=self.table),
60
+ alias=root_alias,
61
+ columnNames=[x.get_name() for x in self.columns()]
62
+ )
63
+ ],
64
+ where=None,
65
+ groupBy=[],
66
+ having=None,
67
+ orderBy=[],
68
+ limit=None,
69
+ offset=None
70
+ )
@@ -0,0 +1,46 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from pylegend._typing import (
16
+ PyLegendSequence
17
+ )
18
+ from pylegend.core.tds.legend_api.frames.legend_api_input_tds_frame import LegendApiExecutableInputTdsFrame
19
+ from pylegend.core.project_cooridnates import ProjectCoordinates
20
+ from pylegend.core.request.legend_client import LegendClient
21
+ from pylegend.extensions.tds.abstract.legend_function_input_frame import LegendFunctionInputFrameAbstract
22
+
23
+
24
+ __all__: PyLegendSequence[str] = [
25
+ "LegendApiLegendFunctionInputFrame"
26
+ ]
27
+
28
+
29
+ class LegendApiLegendFunctionInputFrame(LegendFunctionInputFrameAbstract, LegendApiExecutableInputTdsFrame):
30
+
31
+ def __init__(
32
+ self,
33
+ path: str,
34
+ project_coordinates: ProjectCoordinates,
35
+ legend_client: LegendClient,
36
+ ) -> None:
37
+ LegendFunctionInputFrameAbstract.__init__(self, path=path, project_coordinates=project_coordinates)
38
+ LegendApiExecutableInputTdsFrame.__init__(
39
+ self,
40
+ legend_client=legend_client,
41
+ columns=legend_client.get_sql_string_schema(self.to_sql_query())
42
+ )
43
+ LegendFunctionInputFrameAbstract.set_initialized(self, True)
44
+
45
+ def __str__(self) -> str:
46
+ return f"LegendApiLegendFunctionInputFrame({'.'.join(self.get_path())})"
@@ -0,0 +1,46 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from pylegend._typing import (
16
+ PyLegendSequence
17
+ )
18
+ from pylegend.core.tds.legend_api.frames.legend_api_input_tds_frame import LegendApiExecutableInputTdsFrame
19
+ from pylegend.core.project_cooridnates import ProjectCoordinates
20
+ from pylegend.core.request.legend_client import LegendClient
21
+ from pylegend.extensions.tds.abstract.legend_service_input_frame import LegendServiceInputFrameAbstract
22
+
23
+
24
+ __all__: PyLegendSequence[str] = [
25
+ "LegendApiLegendServiceInputFrame"
26
+ ]
27
+
28
+
29
+ class LegendApiLegendServiceInputFrame(LegendServiceInputFrameAbstract, LegendApiExecutableInputTdsFrame):
30
+
31
+ def __init__(
32
+ self,
33
+ pattern: str,
34
+ project_coordinates: ProjectCoordinates,
35
+ legend_client: LegendClient,
36
+ ) -> None:
37
+ LegendServiceInputFrameAbstract.__init__(self, pattern=pattern, project_coordinates=project_coordinates)
38
+ LegendApiExecutableInputTdsFrame.__init__(
39
+ self,
40
+ legend_client=legend_client,
41
+ columns=legend_client.get_sql_string_schema(self.to_sql_query())
42
+ )
43
+ LegendApiLegendServiceInputFrame.set_initialized(self, True)
44
+
45
+ def __str__(self) -> str:
46
+ return f"LegendApiLegendServiceInputFrame({'.'.join(self.get_pattern())})"
@@ -16,18 +16,9 @@ from pylegend._typing import (
16
16
  PyLegendList,
17
17
  PyLegendSequence
18
18
  )
19
- from pylegend.core.sql.metamodel import (
20
- QualifiedName,
21
- QualifiedNameReference,
22
- QuerySpecification,
23
- Select,
24
- SingleColumn,
25
- Table,
26
- AliasedRelation
27
- )
28
19
  from pylegend.core.tds.legend_api.frames.legend_api_input_tds_frame import LegendApiNonExecutableInputTdsFrame
29
20
  from pylegend.core.tds.tds_column import TdsColumn
30
- from pylegend.core.tds.tds_frame import FrameToSqlConfig
21
+ from pylegend.extensions.tds.abstract.table_spec_input_frame import TableSpecInputFrameAbstract
31
22
 
32
23
 
33
24
  __all__: PyLegendSequence[str] = [
@@ -35,41 +26,11 @@ __all__: PyLegendSequence[str] = [
35
26
  ]
36
27
 
37
28
 
38
- class LegendApiTableSpecInputFrame(LegendApiNonExecutableInputTdsFrame):
39
- table: QualifiedName
29
+ class LegendApiTableSpecInputFrame(TableSpecInputFrameAbstract, LegendApiNonExecutableInputTdsFrame):
40
30
 
41
31
  def __init__(self, table_name_parts: PyLegendList[str], columns: PyLegendSequence[TdsColumn]) -> None:
42
- super().__init__(columns=columns)
43
- self.table = QualifiedName(table_name_parts)
44
-
45
- def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
46
- db_extension = config.sql_to_string_generator().get_db_extension()
47
- root_alias = db_extension.quote_identifier("root")
48
- return QuerySpecification(
49
- select=Select(
50
- selectItems=[
51
- SingleColumn(
52
- alias=db_extension.quote_identifier(x.get_name()),
53
- expression=QualifiedNameReference(name=QualifiedName(parts=[root_alias, x.get_name()]))
54
- )
55
- for x in self.columns()
56
- ],
57
- distinct=False
58
- ),
59
- from_=[
60
- AliasedRelation(
61
- relation=Table(name=self.table),
62
- alias=root_alias,
63
- columnNames=[x.get_name() for x in self.columns()]
64
- )
65
- ],
66
- where=None,
67
- groupBy=[],
68
- having=None,
69
- orderBy=[],
70
- limit=None,
71
- offset=None
72
- )
32
+ TableSpecInputFrameAbstract.__init__(self, table_name_parts=table_name_parts)
33
+ LegendApiNonExecutableInputTdsFrame.__init__(self, columns=columns)
73
34
 
74
35
  def __str__(self) -> str:
75
36
  return f"LegendApiTableSpecInputFrame({'.'.join(self.table.parts)})"
@@ -0,0 +1,46 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from pylegend._typing import (
16
+ PyLegendSequence
17
+ )
18
+ from pylegend.core.tds.pandas_api.frames.pandas_api_input_tds_frame import PandasApiExecutableInputTdsFrame
19
+ from pylegend.core.project_cooridnates import ProjectCoordinates
20
+ from pylegend.core.request.legend_client import LegendClient
21
+ from pylegend.extensions.tds.abstract.legend_function_input_frame import LegendFunctionInputFrameAbstract
22
+
23
+
24
+ __all__: PyLegendSequence[str] = [
25
+ "PandasApiLegendFunctionInputFrame"
26
+ ]
27
+
28
+
29
+ class PandasApiLegendFunctionInputFrame(LegendFunctionInputFrameAbstract, PandasApiExecutableInputTdsFrame):
30
+
31
+ def __init__(
32
+ self,
33
+ path: str,
34
+ project_coordinates: ProjectCoordinates,
35
+ legend_client: LegendClient,
36
+ ) -> None:
37
+ LegendFunctionInputFrameAbstract.__init__(self, path=path, project_coordinates=project_coordinates)
38
+ PandasApiExecutableInputTdsFrame.__init__(
39
+ self,
40
+ legend_client=legend_client,
41
+ columns=legend_client.get_sql_string_schema(self.to_sql_query())
42
+ )
43
+ LegendFunctionInputFrameAbstract.set_initialized(self, True)
44
+
45
+ def __str__(self) -> str:
46
+ return f"PandasApiLegendFunctionInputFrame({'.'.join(self.get_path())})"
@@ -0,0 +1,46 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from pylegend._typing import (
16
+ PyLegendSequence
17
+ )
18
+ from pylegend.core.tds.pandas_api.frames.pandas_api_input_tds_frame import PandasApiExecutableInputTdsFrame
19
+ from pylegend.core.project_cooridnates import ProjectCoordinates
20
+ from pylegend.core.request.legend_client import LegendClient
21
+ from pylegend.extensions.tds.abstract.legend_service_input_frame import LegendServiceInputFrameAbstract
22
+
23
+
24
+ __all__: PyLegendSequence[str] = [
25
+ "PandasApiLegendServiceInputFrame"
26
+ ]
27
+
28
+
29
+ class PandasApiLegendServiceInputFrame(LegendServiceInputFrameAbstract, PandasApiExecutableInputTdsFrame):
30
+
31
+ def __init__(
32
+ self,
33
+ pattern: str,
34
+ project_coordinates: ProjectCoordinates,
35
+ legend_client: LegendClient,
36
+ ) -> None:
37
+ LegendServiceInputFrameAbstract.__init__(self, pattern=pattern, project_coordinates=project_coordinates)
38
+ PandasApiExecutableInputTdsFrame.__init__(
39
+ self,
40
+ legend_client=legend_client,
41
+ columns=legend_client.get_sql_string_schema(self.to_sql_query())
42
+ )
43
+ LegendServiceInputFrameAbstract.set_initialized(self, True)
44
+
45
+ def __str__(self) -> str:
46
+ return f"PandasApiLegendServiceInputFrame({'.'.join(self.get_pattern())})"
@@ -16,18 +16,9 @@ from pylegend._typing import (
16
16
  PyLegendList,
17
17
  PyLegendSequence
18
18
  )
19
- from pylegend.core.sql.metamodel import (
20
- QualifiedName,
21
- QualifiedNameReference,
22
- QuerySpecification,
23
- Select,
24
- SingleColumn,
25
- Table,
26
- AliasedRelation
27
- )
28
19
  from pylegend.core.tds.pandas_api.frames.pandas_api_input_tds_frame import PandasApiNonExecutableInputTdsFrame
29
20
  from pylegend.core.tds.tds_column import TdsColumn
30
- from pylegend.core.tds.tds_frame import FrameToSqlConfig
21
+ from pylegend.extensions.tds.abstract.table_spec_input_frame import TableSpecInputFrameAbstract
31
22
 
32
23
 
33
24
  __all__: PyLegendSequence[str] = [
@@ -35,41 +26,11 @@ __all__: PyLegendSequence[str] = [
35
26
  ]
36
27
 
37
28
 
38
- class PandasApiTableSpecInputFrame(PandasApiNonExecutableInputTdsFrame):
39
- table: QualifiedName
29
+ class PandasApiTableSpecInputFrame(TableSpecInputFrameAbstract, PandasApiNonExecutableInputTdsFrame):
40
30
 
41
31
  def __init__(self, table_name_parts: PyLegendList[str], columns: PyLegendSequence[TdsColumn]) -> None:
42
- super().__init__(columns=columns)
43
- self.table = QualifiedName(table_name_parts)
44
-
45
- def to_sql_query_object(self, config: FrameToSqlConfig) -> QuerySpecification:
46
- db_extension = config.sql_to_string_generator().get_db_extension()
47
- root_alias = db_extension.quote_identifier("root")
48
- return QuerySpecification(
49
- select=Select(
50
- selectItems=[
51
- SingleColumn(
52
- alias=db_extension.quote_identifier(x.get_name()),
53
- expression=QualifiedNameReference(name=QualifiedName(parts=[root_alias, x.get_name()]))
54
- )
55
- for x in self.columns()
56
- ],
57
- distinct=False
58
- ),
59
- from_=[
60
- AliasedRelation(
61
- relation=Table(name=self.table),
62
- alias=root_alias,
63
- columnNames=[x.get_name() for x in self.columns()]
64
- )
65
- ],
66
- where=None,
67
- groupBy=[],
68
- having=None,
69
- orderBy=[],
70
- limit=None,
71
- offset=None
72
- )
32
+ TableSpecInputFrameAbstract.__init__(self, table_name_parts=table_name_parts)
33
+ PandasApiNonExecutableInputTdsFrame.__init__(self, columns=columns)
73
34
 
74
35
  def __str__(self) -> str:
75
36
  return f"PandasApiTableSpecInputFrame({'.'.join(self.table.parts)})"
@@ -0,0 +1,73 @@
1
+ # Copyright 2023 Goldman Sachs
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ from pylegend._typing import (
17
+ PyLegendSequence,
18
+ )
19
+ from pylegend.core.request import LegendClient
20
+ from pylegend.core.project_cooridnates import ProjectCoordinates
21
+ from pylegend.core.tds.legend_api.frames.legend_api_tds_frame import LegendApiTdsFrame
22
+
23
+
24
+ __all__: PyLegendSequence[str] = [
25
+ "LegendApiTdsClient",
26
+ "legend_api_tds_client",
27
+ ]
28
+
29
+
30
+ class LegendApiTdsClient:
31
+ __legend_client: LegendClient
32
+
33
+ def __init__(
34
+ self,
35
+ legend_client: LegendClient
36
+ ) -> None:
37
+ self.__legend_client = legend_client
38
+
39
+ def legend_service_frame(
40
+ self,
41
+ service_pattern: str,
42
+ project_coordinates: ProjectCoordinates
43
+ ) -> LegendApiTdsFrame:
44
+ from pylegend.extensions.tds.legend_api.frames.legend_api_legend_service_input_frame import (
45
+ LegendApiLegendServiceInputFrame
46
+ )
47
+ return LegendApiLegendServiceInputFrame(
48
+ pattern=service_pattern,
49
+ project_coordinates=project_coordinates,
50
+ legend_client=self.__legend_client
51
+ )
52
+
53
+ def legend_function_frame(
54
+ self,
55
+ function_path: str,
56
+ project_coordinates: ProjectCoordinates
57
+ ) -> LegendApiTdsFrame:
58
+ from pylegend.extensions.tds.legend_api.frames.legend_api_legend_function_input_frame import (
59
+ LegendApiLegendFunctionInputFrame
60
+ )
61
+ return LegendApiLegendFunctionInputFrame(
62
+ path=function_path,
63
+ project_coordinates=project_coordinates,
64
+ legend_client=self.__legend_client
65
+ )
66
+
67
+
68
+ def legend_api_tds_client(
69
+ legend_client: LegendClient
70
+ ) -> LegendApiTdsClient:
71
+ return LegendApiTdsClient(
72
+ legend_client=legend_client
73
+ )
@@ -1,26 +1,32 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pylegend
3
- Version: 0.1.0
3
+ Version: 0.2.2
4
4
  Summary: Python language binding for Legend data management platform
5
5
  Home-page: https://github.com/finos/pylegend
6
6
  License: Apache-2.0
7
7
  Author: PyLegend Maintainers
8
8
  Author-email: legend@finos.org
9
- Requires-Python: >=3.8
9
+ Requires-Python: >=3.8,<3.13
10
10
  Classifier: License :: OSI Approved :: Apache Software License
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.8
13
13
  Classifier: Programming Language :: Python :: 3.9
14
14
  Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
16
17
  Requires-Dist: ijson (>=3.1.4)
17
- Requires-Dist: numpy (>=1.20.0)
18
- Requires-Dist: pandas (>=1.0.0)
18
+ Requires-Dist: numpy (>=1.20.0) ; python_version < "3.12"
19
+ Requires-Dist: numpy (>=1.26.0) ; python_version >= "3.12"
20
+ Requires-Dist: pandas (>=1.0.0) ; python_version < "3.12"
21
+ Requires-Dist: pandas (>=2.1.1) ; python_version >= "3.12"
19
22
  Requires-Dist: requests (>=2.27.1)
20
23
  Project-URL: Repository, https://github.com/finos/pylegend
21
24
  Description-Content-Type: text/markdown
22
25
 
23
26
  [![FINOS - Incubating](https://cdn.jsdelivr.net/gh/finos/contrib-toolbox@master/images/badge-incubating.svg)](https://community.finos.org/docs/governance/Software-Projects/stages/incubating)
27
+ [![pypi](https://img.shields.io/pypi/v/pylegend.svg)](https://pypi.org/project/pylegend/)
28
+ [![python](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)](https://www.python.org/downloads)
29
+ ![CI Testing](https://img.shields.io/badge/CI%20Testing-Linux%20%7C%20%20macOS%20%7C%20Windows%20-orange)
24
30
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
25
31
  ![Build](https://github.com/finos/pylegend/workflows/Build%20CI/badge.svg)
26
32
  ![CVE Scan](https://github.com/finos/pylegend/workflows/CVE%20Scan/badge.svg)
@@ -1,4 +1,4 @@
1
- pylegend/__init__.py,sha256=kUUTGXn35cN0-MKcpxA_1winDqTSnrIiVoGkpDyQMdI,773
1
+ pylegend/__init__.py,sha256=hFFvPRA9R38h7qO-REhP45L5VSCqpJTeSQ83x88LOcU,1475
2
2
  pylegend/_typing.py,sha256=3P2K9xyyODrYRx3iDI8jtF1vGGqPbYiKqLEN9bBCdi0,1479
3
3
  pylegend/core/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
4
4
  pylegend/core/databse/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
@@ -6,8 +6,8 @@ pylegend/core/databse/sql_to_string/__init__.py,sha256=LPvE3XwipxzoTLD5Iw0pQXHbq
6
6
  pylegend/core/databse/sql_to_string/config.py,sha256=xrwPFcuZyzZcKNGeOQTnFW2y7CqhT6laSAazVl93JLU,1384
7
7
  pylegend/core/databse/sql_to_string/db_extension.py,sha256=KrliUcObJfKucHRxVNVV5FDGwZm9U7yH0T0TCQmIDy8,52468
8
8
  pylegend/core/databse/sql_to_string/generator.py,sha256=Tlz9ta3cY_LzZhe8XHn0afgsfV36Pd-bLyUng-oIprs,2605
9
- pylegend/core/language/__init__.py,sha256=f8GKgTChl3uOFJg9S8gp6HJM13T5D2-R0D-pSfB7iUQ,4166
10
- pylegend/core/language/aggregate_specification.py,sha256=a16Fd9Lsd7EXsnSTjUmTF1cYYGmKpGDBiFcnpCrh8fk,1805
9
+ pylegend/core/language/__init__.py,sha256=DPhfz3HDui64H5ez954pMvjK66h2LUozPVTi2kePCtE,4182
10
+ pylegend/core/language/aggregate_specification.py,sha256=3AJKZ9f2mi9n-nbHY8zo6T2ecKCixYzYUV82jyWVNG0,2119
11
11
  pylegend/core/language/column_expressions.py,sha256=YfLs-h0NVDKiKSdIhGe0dlDQ3u24KCJB38fviuI_di4,4335
12
12
  pylegend/core/language/expression.py,sha256=0fl0l1RnvkbyqfWbMAB_5VjL4Y21NeRkjq3eMCooFds,2225
13
13
  pylegend/core/language/functions.py,sha256=vp-JhTn6ITEKD1wpvcppzsYV_T3UVaIp0IzQYkhmgMM,1159
@@ -36,10 +36,12 @@ pylegend/core/language/primitives/primitive.py,sha256=YTN56bdI9uyz5WBAO4oCfZM-9u
36
36
  pylegend/core/language/primitives/strictdate.py,sha256=QUbUMMIViSC0HMBPUDXfFqbYiv4eE4r67fjFMsJTiFY,2490
37
37
  pylegend/core/language/primitives/string.py,sha256=riI340Iytk7zfThbPIfnJ3dyGnOZycfHM05jtKIgewQ,8341
38
38
  pylegend/core/language/tds_row.py,sha256=lrf129CatediTnbEh_d_IAIWjddoywxer_1L6fsBtUY,8175
39
- pylegend/core/request/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
40
- pylegend/core/request/legend_client.py,sha256=WXUqAPQ5wXXbLfGQFZ1wIidgHX8yXv_oR1MweJIRHwk,2391
39
+ pylegend/core/project_cooridnates.py,sha256=t1G6gJzcRQRbCjGpCOk0vBiqd0F8Y_e15Nu4NuzYd6I,3751
40
+ pylegend/core/request/__init__.py,sha256=IHt1dQ2lEa7ibDgZC2jUAnGXG_lG-UOC_I4V7JkC6qk,967
41
+ pylegend/core/request/auth.py,sha256=IuoRYqolYPQA83lQuoOk7_7lPlJPvMeKovbpZwM8pm0,1701
42
+ pylegend/core/request/legend_client.py,sha256=upAAQt9Zhtf_oczlfV-LoWR7cm7y5bsGVf2p2aU7s_E,2773
41
43
  pylegend/core/request/response_reader.py,sha256=TNMi2GKk4lkmf7VMeY5n2AwhxxuWbX4M8pgC2_pXFbE,1691
42
- pylegend/core/request/service_client.py,sha256=Qy1OwaGHFauxpeMtUxhM6TFhyevA5TZZp0c_MXciFvU,2870
44
+ pylegend/core/request/service_client.py,sha256=oNvMR6qNl5UcxpcAjIb4CCpd0MB3Z-Y5OJSyFPGeerM,3377
43
45
  pylegend/core/sql/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
44
46
  pylegend/core/sql/metamodel.py,sha256=B7aqblDyyiTsqWZUW2Is9_2FHTsYTkvhJ1FVxXxoSF8,20134
45
47
  pylegend/core/sql/metamodel_extension.py,sha256=A3B1anMf1x54sjBIjZJhQWXX5IKIsQXFYaL5vWJC4ow,15348
@@ -79,7 +81,7 @@ pylegend/core/tds/result_handler/to_csv_file_result_handler.py,sha256=lm0UG87RNU
79
81
  pylegend/core/tds/result_handler/to_json_file_result_handler.py,sha256=6Qc6hxNvWhceMeIE8skdwcY5V_dLJ7YHmxV37W6MRdo,1357
80
82
  pylegend/core/tds/result_handler/to_string_result_handler.py,sha256=y7xlSahtrsMhzFU2aPHgoT2NKm-Jn7RC2rEZmbYfYTY,1142
81
83
  pylegend/core/tds/sql_query_helpers.py,sha256=9uN6I8D-fLdqVbkJb5gWm0wU-QrKDdtH4pdM_Njn55c,3614
82
- pylegend/core/tds/tds_column.py,sha256=Rg27xqwY2SvOWLtqqBCPg0Fgboh0D7FEnzO7RJIJo0U,5265
84
+ pylegend/core/tds/tds_column.py,sha256=Kyi39cO0X9lFOom1m0gC4GrWBSmzlMj4BMT-9x_cG3A,5231
83
85
  pylegend/core/tds/tds_frame.py,sha256=xQHjlFF7OQvENDCfhg3wwcgHrWFCFyuZWbMJcFtFeH0,2745
84
86
  pylegend/extensions/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
85
87
  pylegend/extensions/database/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
@@ -87,18 +89,27 @@ pylegend/extensions/database/vendors/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZ
87
89
  pylegend/extensions/database/vendors/postgres/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
88
90
  pylegend/extensions/database/vendors/postgres/postgres_sql_to_string.py,sha256=u4ct89lOjpi5yP7A_-HpvfuJ6C7k62Q0WnfOhhYm8yg,1340
89
91
  pylegend/extensions/tds/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
92
+ pylegend/extensions/tds/abstract/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
93
+ pylegend/extensions/tds/abstract/legend_function_input_frame.py,sha256=5oj5q-tVqsT86tBYDFdr3KV4P0f8eOuv_BbJpyc4LAI,3428
94
+ pylegend/extensions/tds/abstract/legend_service_input_frame.py,sha256=ho-jiUYpYJazVtWxc7Cdtk3B7A5-LI5b-PYu0osS4go,3453
95
+ pylegend/extensions/tds/abstract/table_spec_input_frame.py,sha256=MMaMdk_XVVW4jwKLnkHET7s6HkZl_WfLlFZUHLvt5Gc,2326
90
96
  pylegend/extensions/tds/legend_api/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
91
97
  pylegend/extensions/tds/legend_api/frames/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
92
- pylegend/extensions/tds/legend_api/frames/legend_api_table_spec_input_frame.py,sha256=b7czYczx3ugI45JjBZZ2mv3jgGOc3Y-pHVJQQmdQoAk,2596
98
+ pylegend/extensions/tds/legend_api/frames/legend_api_legend_function_input_frame.py,sha256=0pQHk9SsJcND8oCWwhjBEHPxh6ddjwak8MLEmVKoFnw,1818
99
+ pylegend/extensions/tds/legend_api/frames/legend_api_legend_service_input_frame.py,sha256=1-vR9sES55ZGkylGHlNTPrkq1aWRnsZrt3kCvXFftTo,1823
100
+ pylegend/extensions/tds/legend_api/frames/legend_api_table_spec_input_frame.py,sha256=fdcs00l2LKcEhrsnpjIfKzHPenucVeALGkSniVxdx_Q,1465
93
101
  pylegend/extensions/tds/pandas_api/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
94
102
  pylegend/extensions/tds/pandas_api/frames/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
95
- pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py,sha256=HkxeDUWY2kugYV0xp5_75exus0CY6nINgQfOBCb_S_w,2596
103
+ pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_function_input_frame.py,sha256=aJaNPJcfMdc8HTJKErah4BYSnHfmKMIMvoKtEeCx4zQ,1818
104
+ pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_service_input_frame.py,sha256=dOV6qXIrNkZ8gwmPt0ljr5CVViS4AH5Y4h3L-1WnNdM,1822
105
+ pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py,sha256=2pj-siOOvIFEqNOG-f4VUvhY9gBGUFFDZz7jZl7QpLg,1465
96
106
  pylegend/extensions/tds/result_handler/__init__.py,sha256=NIIUcl39wpSc51IhUUEKtEYlve89Xncq0YEG78Gren4,864
97
107
  pylegend/extensions/tds/result_handler/to_pandas_df_result_handler.py,sha256=tvVsxDOzHNTvzjdApIhmeefws5_u0N8Rqm7UvEtj70w,4958
108
+ pylegend/legend_api_tds_client.py,sha256=I0uRF7ADGvV5fHN-dEBIrdxTy7GC8jV91V62rgXn6c0,2319
98
109
  pylegend/utils/__init__.py,sha256=LXTDJSDmHQXtnMDZouhZp9IZQVpY6ONkINbUYjtnMkE,578
99
110
  pylegend/utils/class_utils.py,sha256=t4PpF3jAXS_D6p9TqlSppryNYNOuy5C-kbKn2Kgb4QU,973
100
- pylegend-0.1.0.dist-info/LICENSE,sha256=AGR96_qQPZO66Gjqq4G6r_g670K35VtW-IobTAkmZJM,11343
101
- pylegend-0.1.0.dist-info/LICENSE.spdx,sha256=i7TsBclLotUvMjx9vZ_6S8Pp0r4uknWGw1RwiKBBvQ4,207
102
- pylegend-0.1.0.dist-info/METADATA,sha256=KPcgW_QcwcmoLuFIWL_6ydYHVD7E8qz7jqghlu7yvEM,3701
103
- pylegend-0.1.0.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
104
- pylegend-0.1.0.dist-info/RECORD,,
111
+ pylegend-0.2.2.dist-info/LICENSE,sha256=AGR96_qQPZO66Gjqq4G6r_g670K35VtW-IobTAkmZJM,11343
112
+ pylegend-0.2.2.dist-info/LICENSE.spdx,sha256=i7TsBclLotUvMjx9vZ_6S8Pp0r4uknWGw1RwiKBBvQ4,207
113
+ pylegend-0.2.2.dist-info/METADATA,sha256=lmfSjBstKvYcjXXTrlAkhGfvA3llmC_iOxK2SYbx8t8,4267
114
+ pylegend-0.2.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
115
+ pylegend-0.2.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.7.0
2
+ Generator: poetry-core 1.8.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any