exasol-python-extension-common 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/PKG-INFO +4 -6
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/README.md +1 -1
- exasol_python_extension_common-0.3.0/exasol/python_extension_common/connections/pyexasol_connection.py +67 -0
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/exasol/python_extension_common/deployment/language_container_validator.py +15 -6
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/pyproject.toml +3 -3
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/setup.py +5 -4
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/LICENSE +0 -0
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/exasol/python_extension_common/__init__.py +0 -0
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/exasol/python_extension_common/deployment/language_container_deployer.py +0 -0
- {exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/exasol/python_extension_common/deployment/language_container_deployer_cli.py +0 -0
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: exasol-python-extension-common
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A collection of common utilities for Exasol extensions.
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Mikhail Beck
|
|
7
7
|
Author-email: mikhail.beck@exasol.com
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10.0,<4.0.0
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
13
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
16
14
|
Requires-Dist: exasol-bucketfs (>=0.10.0)
|
|
17
15
|
Requires-Dist: exasol-saas-api (>=0.7.0,<1.0.0)
|
|
18
|
-
Requires-Dist: pyexasol (>=0.25.0,<0.
|
|
16
|
+
Requires-Dist: pyexasol (>=0.25.0,<1.0.0)
|
|
19
17
|
Requires-Dist: requests (<2.32.0)
|
|
20
18
|
Requires-Dist: tenacity (>=8.3.0,<9.0.0)
|
|
21
19
|
Description-Content-Type: text/markdown
|
|
@@ -32,7 +30,7 @@ A deployer for script language containers (SLC) to be used by UDF-based extensio
|
|
|
32
30
|
|
|
33
31
|
## More documentation
|
|
34
32
|
|
|
35
|
-
* User Guide
|
|
33
|
+
* [User Guide](doc/user_guide/user-guide.md)
|
|
36
34
|
* [Developer Guide](doc/developer-guide.md)
|
|
37
35
|
* [User Defined Functions (UDF)](https://docs.exasol.com/db/latest/database_concepts/udf_scripts.htm)
|
|
38
36
|
* [Script Language Containers (SLC)](https://github.com/exasol/script-languages-release/)
|
|
@@ -10,7 +10,7 @@ A deployer for script language containers (SLC) to be used by UDF-based extensio
|
|
|
10
10
|
|
|
11
11
|
## More documentation
|
|
12
12
|
|
|
13
|
-
* User Guide
|
|
13
|
+
* [User Guide](doc/user_guide/user-guide.md)
|
|
14
14
|
* [Developer Guide](doc/developer-guide.md)
|
|
15
15
|
* [User Defined Functions (UDF)](https://docs.exasol.com/db/latest/database_concepts/udf_scripts.htm)
|
|
16
16
|
* [Script Language Containers (SLC)](https://github.com/exasol/script-languages-release/)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import pyexasol # type: ignore
|
|
2
|
+
import exasol.saas.client.api_access as saas_api # type: ignore
|
|
3
|
+
|
|
4
|
+
from exasol.python_extension_common.deployment.language_container_deployer import get_websocket_sslopt
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def open_pyexasol_connection(
|
|
8
|
+
dsn: str | None = None,
|
|
9
|
+
db_user: str | None = None,
|
|
10
|
+
db_pass: str | None = None,
|
|
11
|
+
saas_url: str | None = None,
|
|
12
|
+
saas_account_id: str | None = None,
|
|
13
|
+
saas_database_id: str | None = None,
|
|
14
|
+
saas_database_name: str | None = None,
|
|
15
|
+
saas_token: str | None = None,
|
|
16
|
+
schema: str = '',
|
|
17
|
+
use_ssl_cert_validation: bool = True,
|
|
18
|
+
ssl_trusted_ca: str | None = None,
|
|
19
|
+
ssl_client_certificate: str | None = None,
|
|
20
|
+
ssl_private_key: str | None = None) -> pyexasol.ExaConnection:
|
|
21
|
+
"""
|
|
22
|
+
Creates a database connections object, either in an On-Prem or SaaS database,
|
|
23
|
+
depending on the provided parameters.
|
|
24
|
+
|
|
25
|
+
Raises a ValueError if the provided parameters are sufficient for neither On-Prem
|
|
26
|
+
nor SaaS connections.
|
|
27
|
+
|
|
28
|
+
Parameters:
|
|
29
|
+
dsn - On-Prem database host address, including the port
|
|
30
|
+
db_user - On-Prem database username
|
|
31
|
+
db_pass - On-Prem database user password
|
|
32
|
+
saas_url - SaaS service url
|
|
33
|
+
saas_account_id - SaaS account id
|
|
34
|
+
saas_database_id - SaaS database id
|
|
35
|
+
saas_database_name - SaaS database name, to be used in case the id is unknown
|
|
36
|
+
saas_token - SaaS Personal Access Token (PAT)
|
|
37
|
+
schema - Schema where the scripts should be created
|
|
38
|
+
use_ssl_cert_validation - Use SSL server certificate validation
|
|
39
|
+
ssl_trusted_ca - Path to a file or directory with an SSL trusted CA bundle
|
|
40
|
+
ssl_client_certificate - Path to a file with the SSL client certificate
|
|
41
|
+
ssl_private_key - Path to a file with the SSL client private key
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
# Infer where the database is - On-Prem or SaaS.
|
|
45
|
+
if all((dsn, db_user, db_pass)):
|
|
46
|
+
connection_params = {'dsn': dsn, 'user': db_user, 'password': db_pass}
|
|
47
|
+
elif all((saas_url, saas_account_id, saas_token,
|
|
48
|
+
any((saas_database_id, saas_database_name)))):
|
|
49
|
+
connection_params = saas_api.get_connection_params(host=saas_url,
|
|
50
|
+
account_id=saas_account_id,
|
|
51
|
+
database_id=saas_database_id,
|
|
52
|
+
database_name=saas_database_name,
|
|
53
|
+
pat=saas_token)
|
|
54
|
+
else:
|
|
55
|
+
raise ValueError('Incomplete parameter list. '
|
|
56
|
+
'Please either provide the parameters [dns, db_user, db_pass] '
|
|
57
|
+
'for an On-Prem database or [saas_url, saas_account_id, '
|
|
58
|
+
'saas_database_id or saas_database_name, saas_token] '
|
|
59
|
+
'for a SaaS database.')
|
|
60
|
+
|
|
61
|
+
websocket_sslopt = get_websocket_sslopt(use_ssl_cert_validation, ssl_trusted_ca,
|
|
62
|
+
ssl_client_certificate, ssl_private_key)
|
|
63
|
+
|
|
64
|
+
return pyexasol.connect(**connection_params, schema=schema,
|
|
65
|
+
encryption=True,
|
|
66
|
+
websocket_sslopt=websocket_sslopt,
|
|
67
|
+
compression=True)
|
|
@@ -25,13 +25,14 @@ def _get_test_udf_name(schema: str | None) -> str:
|
|
|
25
25
|
def _create_dummy_udf(conn: pyexasol.ExaConnection, language_alias: str,
|
|
26
26
|
schema: str | None) -> None:
|
|
27
27
|
|
|
28
|
+
# The dummy UDF returns the ID of the node it is running at.
|
|
28
29
|
udf_name = _get_test_udf_name(schema)
|
|
29
30
|
sql = dedent(f"""
|
|
30
|
-
CREATE OR REPLACE {language_alias}
|
|
31
|
-
RETURNS DECIMAL(
|
|
31
|
+
CREATE OR REPLACE {language_alias} SET SCRIPT {udf_name}(i DECIMAL(10, 0))
|
|
32
|
+
RETURNS DECIMAL(10, 0) AS
|
|
32
33
|
|
|
33
34
|
def run(ctx):
|
|
34
|
-
return
|
|
35
|
+
return exa.meta.node_id
|
|
35
36
|
/
|
|
36
37
|
""")
|
|
37
38
|
conn.execute(sql)
|
|
@@ -39,13 +40,21 @@ def _create_dummy_udf(conn: pyexasol.ExaConnection, language_alias: str,
|
|
|
39
40
|
|
|
40
41
|
def _call_dummy_udf(conn: pyexasol.ExaConnection, schema: str | None) -> None:
|
|
41
42
|
|
|
43
|
+
# First, need to find out the number of nodes.
|
|
44
|
+
sql = "SELECT NPROC();"
|
|
45
|
+
nproc = conn.execute(sql).fetchval()
|
|
46
|
+
|
|
47
|
+
# This query should run the dummy udf on all nodes.
|
|
42
48
|
udf_name = _get_test_udf_name(schema)
|
|
43
49
|
sql = dedent(f"""
|
|
44
|
-
SELECT {udf_name}()
|
|
45
|
-
GROUP BY
|
|
50
|
+
SELECT {udf_name}(i) FROM VALUES BETWEEN 1 AND {nproc} t(i)
|
|
51
|
+
GROUP BY i;
|
|
46
52
|
""")
|
|
53
|
+
# The expected result is a collection of distinct node IDs from 0 to nproc - 1.
|
|
47
54
|
result = conn.execute(sql).fetchall()
|
|
48
|
-
|
|
55
|
+
set_result = {row[0] for row in result}
|
|
56
|
+
|
|
57
|
+
assert set_result == set(range(nproc))
|
|
49
58
|
|
|
50
59
|
|
|
51
60
|
def _delete_dummy_udf(conn: pyexasol.ExaConnection, schema: str | None) -> None:
|
{exasol_python_extension_common-0.2.0 → exasol_python_extension_common-0.3.0}/pyproject.toml
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "exasol-python-extension-common"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "A collection of common utilities for Exasol extensions."
|
|
5
5
|
packages = [ {include = "exasol"}, ]
|
|
6
6
|
authors = ["Mikhail Beck <mikhail.beck@exasol.com>"]
|
|
@@ -8,8 +8,8 @@ license = "MIT"
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
|
|
10
10
|
[tool.poetry.dependencies]
|
|
11
|
-
python = "
|
|
12
|
-
pyexasol = "
|
|
11
|
+
python = "^3.10.0"
|
|
12
|
+
pyexasol = ">=0.25.0,<1.0.0"
|
|
13
13
|
exasol-bucketfs = ">=0.10.0"
|
|
14
14
|
click = "^8.1.7"
|
|
15
15
|
exasol-saas-api = ">=0.7.0,<1.0.0"
|
|
@@ -4,6 +4,7 @@ from setuptools import setup
|
|
|
4
4
|
packages = \
|
|
5
5
|
['exasol',
|
|
6
6
|
'exasol.python_extension_common',
|
|
7
|
+
'exasol.python_extension_common.connections',
|
|
7
8
|
'exasol.python_extension_common.deployment']
|
|
8
9
|
|
|
9
10
|
package_data = \
|
|
@@ -13,15 +14,15 @@ install_requires = \
|
|
|
13
14
|
['click>=8.1.7,<9.0.0',
|
|
14
15
|
'exasol-bucketfs>=0.10.0',
|
|
15
16
|
'exasol-saas-api>=0.7.0,<1.0.0',
|
|
16
|
-
'pyexasol>=0.25.0,<0.
|
|
17
|
+
'pyexasol>=0.25.0,<1.0.0',
|
|
17
18
|
'requests<2.32.0',
|
|
18
19
|
'tenacity>=8.3.0,<9.0.0']
|
|
19
20
|
|
|
20
21
|
setup_kwargs = {
|
|
21
22
|
'name': 'exasol-python-extension-common',
|
|
22
|
-
'version': '0.
|
|
23
|
+
'version': '0.3.0',
|
|
23
24
|
'description': 'A collection of common utilities for Exasol extensions.',
|
|
24
|
-
'long_description': '# Exasol Python Extension Common\n\nA package with common functionality, shared by Exasol Python Extensions, e.g.\n* [transformers-extension](https://github.com/exasol/transformers-extension)\n* [sagemaker-extension](https://github.com/exasol/sagemaker-extension)\n\n## Features\n\nA deployer for script language containers (SLC) to be used by UDF-based extensions of Exasol database requiring a special SLC.\n\n## More documentation\n\n* User Guide\n* [Developer Guide](doc/developer-guide.md)\n* [User Defined Functions (UDF)](https://docs.exasol.com/db/latest/database_concepts/udf_scripts.htm)\n* [Script Language Containers (SLC)](https://github.com/exasol/script-languages-release/)\n',
|
|
25
|
+
'long_description': '# Exasol Python Extension Common\n\nA package with common functionality, shared by Exasol Python Extensions, e.g.\n* [transformers-extension](https://github.com/exasol/transformers-extension)\n* [sagemaker-extension](https://github.com/exasol/sagemaker-extension)\n\n## Features\n\nA deployer for script language containers (SLC) to be used by UDF-based extensions of Exasol database requiring a special SLC.\n\n## More documentation\n\n* [User Guide](doc/user_guide/user-guide.md)\n* [Developer Guide](doc/developer-guide.md)\n* [User Defined Functions (UDF)](https://docs.exasol.com/db/latest/database_concepts/udf_scripts.htm)\n* [Script Language Containers (SLC)](https://github.com/exasol/script-languages-release/)\n',
|
|
25
26
|
'author': 'Mikhail Beck',
|
|
26
27
|
'author_email': 'mikhail.beck@exasol.com',
|
|
27
28
|
'maintainer': 'None',
|
|
@@ -30,7 +31,7 @@ setup_kwargs = {
|
|
|
30
31
|
'packages': packages,
|
|
31
32
|
'package_data': package_data,
|
|
32
33
|
'install_requires': install_requires,
|
|
33
|
-
'python_requires': '>=3.
|
|
34
|
+
'python_requires': '>=3.10.0,<4.0.0',
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|