Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion doc/changes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Unreleased

## Summary

## Dependency Updates

* #130: Poetry relock
* #130: Poetry relock

## Features

* #132: Simplified using `LanguageContainerDeployer` in TE and similar projects
2 changes: 1 addition & 1 deletion exasol/python_extension_common/cli/std_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class ParameterFormatters:
the update if the value of the parameter dressed with the callback is None.
"""

def __init__(self):
def __init__(self) -> None:
self._formatters: dict[str, str] = {}

def __call__(self, ctx: click.Context, param: click.Parameter, value: Any | None) -> Any | None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,20 @@ def __init__(
def pyexasol_connection(self) -> pyexasol.ExaConnection:
return self._pyexasol_conn

def download_url(self, version: str | None) -> str:
"""
Sub classes can override this method to infer the download url
from the version in `download_and_run()`.
"""
return ""

def default_bucket_file_path(self, version: str | None) -> str:
"""
Sub classes can override this method to specify a default value
for `bucket_file_path` in `run()`.
"""
return ""

def download_and_run(
self,
url: str,
Expand All @@ -148,21 +162,40 @@ def download_and_run(
allow_override: bool = False,
wait_for_completion: bool = True,
print_activation_statements: bool = True,
version: str = "",
) -> None:
"""
Downloads the language container from the provided url to a temporary file and then deploys it.
See docstring on the `run` method for details on what is involved in the deployment.
Downloads the language container from the provided url to a
temporary file and then deploys it. See docstring on the `run` method
for details on what is involved in the deployment.

url - Address where the container will be downloaded from.
bucket_file_path - Path within the designated bucket where the container should be uploaded.
alter_system - If True will try to activate the container at the System level.
allow_override - If True the activation of a language container with the same alias will be
overriden, otherwise a RuntimeException will be thrown.
wait_for_completion - If True will wait until the language container becomes operational.
print_activation_statements - If True and alter_system is False,
it will print the ALTER SESSION command to stdout.
Arguments:

url: Address where the container will be downloaded from. If url is
empty, then method download_url(version) is called to retrieve a
default URL, that can depend on the version.

bucket_file_path: Path within the designated bucket where the
container should be uploaded.

alter_system: If True will try to activate the container at the System
level.

allow_override: If True the activation of a language container with
the same alias will be overriden, otherwise a RuntimeException
will be thrown.

wait_for_completion: If True will wait until the language container
becomes operational.

print_activation_statements: If True and alter_system is False, it
will print the ALTER SESSION command to stdout.

version: Optional argument to infer the download URL by calling method
self.download_url(version).
"""

url = url or self.download_url(version)
with tempfile.NamedTemporaryFile() as tmp_file:
response = requests.get(url, stream=True, timeout=300)
response.raise_for_status()
Expand All @@ -175,6 +208,7 @@ def download_and_run(
allow_override,
wait_for_completion,
print_activation_statements,
version,
)

def _upload_path(self, bucket_file_path: str | None) -> bfs.path.PathLike:
Expand All @@ -188,30 +222,54 @@ def run(
allow_override: bool = False,
wait_for_completion: bool = True,
print_activation_statements: bool = True,
version: str = "",
) -> None:
"""
Deploys the language container. This includes two steps, both of which are optional:
- Uploading the container into the database. This step can be skipped if the container
has already been uploaded.
- Activating the container. In case the container does not get activated at the System
level, two alternative activation SQL commands (one for the System and one for the Session
levels) will be printed on the console.
Deploys the language container.

container_file - Path of the container tar.gz file in a local file system.
If not provided the container is assumed to be uploaded already.
bucket_file_path - Path within the designated bucket where the container should be uploaded.
If not specified the name of the container file will be used instead.
alter_system - If True will try to activate the container at the System level.
allow_override - If True the activation of a language container with the same alias will be
overriden, otherwise a RuntimeException will be thrown.
wait_for_completion - If True will wait until the language container becomes operational.
For this to work either of the two conditions should be met.
The pyexasol connection should have an open schema, or
The calling user should have a permission to create schema.
print_activation_statements - If True and alter_system is False,
it will print the ALTER SESSION command to stdout.
This includes two steps, both of which are optional:

* Uploading the container into the database. This step can be skipped
if the container has already been uploaded.

* Activating the container. In case the container does not get
activated at the System level, two alternative activation SQL
commands (one for the System and one for the Session levels) will be
printed on the console.

Arguments:

container_file: Path of the container tar.gz file in a local file
system. If not provided the container is assumed to be uploaded
already.

bucket_file_path: Path within the designated bucket where the
container should be uploaded. If not specified then method
default_bucket_file_path(version) is called to get a default
value. If still empty, then the name of the container file will be
used instead.

alter_system: If True will try to activate the container at the System
level.

allow_override: If True the activation of a language container with
the same alias will be overriden, otherwise a RuntimeException
will be thrown.

wait_for_completion: If True will wait until the language container
becomes operational. For this to work either of the two conditions
should be met. The pyexasol connection should have an open schema,
or The calling user should have a permission to create schema.

print_activation_statements: If True and alter_system is False, it
will print the ALTER SESSION command to stdout.

version: Optional argument to infer the bucket_file_path by calling
method self.default_bucket_file_path(version).
"""

bucket_file_path = bucket_file_path or self.default_bucket_file_path(version)

if not bucket_file_path:
if not container_file:
raise ValueError("Either a container file or a bucket file path must be specified.")
Expand All @@ -237,10 +295,10 @@ def run(
f"""
In SQL, you can activate the SLC
by using the following statements:

To activate the SLC only for the current session:
{self.generate_activation_command(bucket_file_path, LanguageActivationLevel.Session, True)}

To activate the SLC on the system:
{self.generate_activation_command(bucket_file_path, LanguageActivationLevel.System, True)}
"""
Expand Down