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.
- pylegend/__init__.py +31 -1
- pylegend/core/language/__init__.py +2 -1
- pylegend/core/language/aggregate_specification.py +9 -0
- pylegend/core/project_cooridnates.py +125 -0
- pylegend/core/request/__init__.py +16 -0
- pylegend/core/request/auth.py +61 -0
- pylegend/core/request/legend_client.py +18 -3
- pylegend/core/request/service_client.py +17 -3
- pylegend/core/tds/tds_column.py +1 -1
- pylegend/extensions/tds/abstract/__init__.py +13 -0
- pylegend/extensions/tds/abstract/legend_function_input_frame.py +108 -0
- pylegend/extensions/tds/abstract/legend_service_input_frame.py +108 -0
- pylegend/extensions/tds/abstract/table_spec_input_frame.py +70 -0
- pylegend/extensions/tds/legend_api/frames/legend_api_legend_function_input_frame.py +46 -0
- pylegend/extensions/tds/legend_api/frames/legend_api_legend_service_input_frame.py +46 -0
- pylegend/extensions/tds/legend_api/frames/legend_api_table_spec_input_frame.py +4 -43
- pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_function_input_frame.py +46 -0
- pylegend/extensions/tds/pandas_api/frames/pandas_api_legend_service_input_frame.py +46 -0
- pylegend/extensions/tds/pandas_api/frames/pandas_api_table_spec_input_frame.py +4 -43
- pylegend/legend_api_tds_client.py +73 -0
- {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/METADATA +10 -4
- {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/RECORD +25 -14
- {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/WHEEL +1 -1
- {pylegend-0.1.0.dist-info → pylegend-0.2.2.dist-info}/LICENSE +0 -0
- {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__(
|
|
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="
|
|
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="
|
|
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__(
|
|
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
|
-
|
|
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()
|
pylegend/core/tds/tds_column.py
CHANGED
|
@@ -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["
|
|
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.
|
|
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
|
-
|
|
43
|
-
self
|
|
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.
|
|
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
|
-
|
|
43
|
-
self
|
|
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.
|
|
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:
|
|
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
|
[](https://community.finos.org/docs/governance/Software-Projects/stages/incubating)
|
|
27
|
+
[](https://pypi.org/project/pylegend/)
|
|
28
|
+
[](https://www.python.org/downloads)
|
|
29
|
+

|
|
24
30
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
25
31
|

|
|
26
32
|

|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pylegend/__init__.py,sha256=
|
|
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=
|
|
10
|
-
pylegend/core/language/aggregate_specification.py,sha256=
|
|
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/
|
|
40
|
-
pylegend/core/request/
|
|
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=
|
|
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=
|
|
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/
|
|
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/
|
|
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.
|
|
101
|
-
pylegend-0.
|
|
102
|
-
pylegend-0.
|
|
103
|
-
pylegend-0.
|
|
104
|
-
pylegend-0.
|
|
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,,
|
|
File without changes
|
|
File without changes
|