Skip to content

Commit

Permalink
Added aws_role to the AILabConfig
Browse files Browse the repository at this point in the history
  • Loading branch information
ahsimb committed Jan 16, 2024
1 parent 88f6a64 commit 0efea5b
Show file tree
Hide file tree
Showing 25 changed files with 265 additions and 178 deletions.
2 changes: 2 additions & 0 deletions doc/changes/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changes

* [0.2.6](changes_0.2.6.md)
* [0.2.5](changes_0.2.5.md)
* [0.2.4](changes_0.2.4.md)
* [0.2.3](changes_0.2.3.md)
Expand All @@ -14,6 +15,7 @@
---
hidden:
---
changes_0.2.6
changes_0.2.5
changes_0.2.4
changes_0.2.3
Expand Down
14 changes: 14 additions & 0 deletions doc/changes/changes_0.2.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Exasol Notebook Connector 0.2.6, released T.B.C.

## Summary

This release adds the extension wrappers and makes full use of the configuration enumeration.

## Changes

* #50: [Add iterable features to the secret store](https://github.com/exasol/notebook-connector/issues/50)
* #52: [Make data conversion utility for the secret store commonly accessible](https://github.com/exasol/notebook-connector/issues/52)
* #55: [Unified language activation SQL command](https://github.com/exasol/notebook-connector/pull/55)
* #56: [Transformers extension wrapper](https://github.com/exasol/notebook-connector/pull/56)
* #47: [Create a Sagemaker Extension wrapper](https://github.com/exasol/notebook-connector/issues/47)
* #60: [Start using the AILabConfig internally](https://github.com/exasol/notebook-connector/issues/60)
5 changes: 4 additions & 1 deletion exasol/ai_lab_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from enum import Enum, auto
from enum import (
Enum,
auto,
)


class AILabConfig(Enum):
Expand Down
9 changes: 5 additions & 4 deletions exasol/bfs_utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
"""
Bucketfs-related functions.
"""
import pathlib
import logging
import exasol.bucketfs as bfs # type: ignore
import pathlib

import exasol.bucketfs as bfs # type: ignore

_logger = logging.getLogger(__name__)


def put_file(bucket: bfs.Bucket, file_path: pathlib.Path,
skip_if_exists: bool = True) -> pathlib.Path:
def put_file(
bucket: bfs.Bucket, file_path: pathlib.Path, skip_if_exists: bool = True
) -> pathlib.Path:
"""
Uploads given file into bucketfs
:param bucket: bucket to use
Expand Down
28 changes: 16 additions & 12 deletions exasol/cloud_storage.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import pyexasol # type: ignore


_SETUP_SQL = [
"OPEN SCHEMA {schema!i}",
"""
"OPEN SCHEMA {schema!i}",
"""
--/
CREATE OR REPLACE JAVA SET SCRIPT IMPORT_PATH(...) EMITS (...) AS
%scriptclass com.exasol.cloudetl.scriptclasses.FilesImportQueryGenerator;
%jar {jar_path!r};
/
""",
"""
"""
--/
CREATE OR REPLACE JAVA SCALAR SCRIPT IMPORT_METADATA(...)
EMITS (
Expand All @@ -23,17 +22,19 @@
%jar {jar_path!r};
/
""",
"""
"""
--/
CREATE OR REPLACE JAVA SET SCRIPT IMPORT_FILES(...) EMITS (...) AS
%scriptclass com.exasol.cloudetl.scriptclasses.FilesDataImporter;
%jar {jar_path!r};
/
"""
]
""",
]


def setup_scripts(db_connection: pyexasol.ExaConnection, schema_name: str, bucketfs_jar_path: str):
def setup_scripts(
db_connection: pyexasol.ExaConnection, schema_name: str, bucketfs_jar_path: str
):
"""
Perform initialization of scripts for could-storage-extension.
:param db_connection: DB connection
Expand All @@ -42,7 +43,10 @@ def setup_scripts(db_connection: pyexasol.ExaConnection, schema_name: str, bucke
:return:
"""
for sql in _SETUP_SQL:
db_connection.execute(sql, query_params={
"schema": schema_name,
"jar_path": bucketfs_jar_path,
})
db_connection.execute(
sql,
query_params={
"schema": schema_name,
"jar_path": bucketfs_jar_path,
},
)
10 changes: 5 additions & 5 deletions exasol/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
import sqlalchemy # type: ignore

import exasol.bucketfs as bfs # type: ignore
from exasol.ai_lab_config import AILabConfig as CKey
from exasol.secret_store import Secrets
from exasol.utils import optional_str_to_bool
from exasol.ai_lab_config import AILabConfig as CKey


def _optional_encryption(conf: Secrets, key: CKey = CKey.db_encryption) -> Optional[bool]:
def _optional_encryption(
conf: Secrets, key: CKey = CKey.db_encryption
) -> Optional[bool]:
return optional_str_to_bool(conf.get(key))


Expand Down Expand Up @@ -125,9 +127,7 @@ def open_sqlalchemy_connection(conf: Secrets):
it is possible to set the client TLS/SSL certificate.
"""

websocket_url = (
f"exa+websocket://{conf.get(CKey.db_user)}:{conf.get(CKey.db_password)}@{get_external_host(conf)}"
)
websocket_url = f"exa+websocket://{conf.get(CKey.db_user)}:{conf.get(CKey.db_password)}@{get_external_host(conf)}"

delimiter = "?"
encryption = _optional_encryption(conf)
Expand Down
2 changes: 1 addition & 1 deletion exasol/extension_wrapper_common.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from exasol.ai_lab_config import AILabConfig as CKey
from exasol.connections import open_pyexasol_connection
from exasol.secret_store import Secrets
from exasol.utils import optional_str_to_bool
from exasol.ai_lab_config import AILabConfig as CKey


def str_to_bool(conf: Secrets, key: CKey, default_value: bool) -> bool:
Expand Down
51 changes: 33 additions & 18 deletions exasol/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
project, retrieval of artefacts, etc.
"""
import enum
import requests
import pathlib
import logging
from typing import Tuple, Optional
import pathlib
from typing import (
Optional,
Tuple,
)

import requests

_logger = logging.getLogger(__name__)

Expand All @@ -16,6 +20,7 @@ class Project(enum.Enum):
Names of github projects to be retrieved. Values have to
match github project names.
"""

CLOUD_STORAGE_EXTENSION = "cloud-storage-extension"
KAFKA_CONNECTOR_EXTENSION = "kafka-connector-extension"

Expand All @@ -28,26 +33,33 @@ def get_latest_version_and_jar_url(project: Project) -> Tuple[str, str]:
:param project: name of the project
:return: tuple with version and url to retrieve the artefact.
"""
req = requests.get(f"https://api.github.com/repos/exasol/{project.value}"
f"/releases/latest", timeout=10)
req = requests.get(
f"https://api.github.com/repos/exasol/{project.value}" f"/releases/latest",
timeout=10,
)
if req.status_code != 200:
raise RuntimeError("Error sending request to the github, code: %d" %
req.status_code)
raise RuntimeError(
"Error sending request to the github, code: %d" % req.status_code
)
data = req.json()
version = data.get('tag_name')
version = data.get("tag_name")
if version is None:
raise RuntimeError(f"The latest version of {project.value} "
f"has no tag, something is wrong")
for asset in data.get('assets', []):
name = asset['name']
raise RuntimeError(
f"The latest version of {project.value} " f"has no tag, something is wrong"
)
for asset in data.get("assets", []):
name = asset["name"]
if name.endswith(f"{version}.jar"):
dl_url = asset['browser_download_url']
dl_url = asset["browser_download_url"]
return version, dl_url
raise RuntimeError("Could not find proper jar url for the latest release")


def retrieve_jar(project: Project, use_local_cache: bool = True,
storage_path: Optional[pathlib.Path] = None) -> pathlib.Path:
def retrieve_jar(
project: Project,
use_local_cache: bool = True,
storage_path: Optional[pathlib.Path] = None,
) -> pathlib.Path:
"""
Returns latest jar file for the project, possibly using local cache.
:param project: project to be used
Expand All @@ -57,16 +69,19 @@ def retrieve_jar(project: Project, use_local_cache: bool = True,
:return: path to the jar file on the local filesystem
"""
version, jar_url = get_latest_version_and_jar_url(project)
_, local_jar_name = jar_url.rsplit('/', maxsplit=1)
_, local_jar_name = jar_url.rsplit("/", maxsplit=1)
local_jar_path = pathlib.Path(local_jar_name)
if storage_path is not None:
if not storage_path.exists():
raise ValueError(f"Local storage path doesn't exist: {storage_path}")
local_jar_path = storage_path / local_jar_path

if use_local_cache and local_jar_path.exists():
_logger.info("Jar for version %s already exists in %s, skip downloading",
version, local_jar_path)
_logger.info(
"Jar for version %s already exists in %s, skip downloading",
version,
local_jar_path,
)
else:
_logger.info("Fetching jar for version %s from %s...", version, jar_url)
req = requests.get(jar_url, stream=True, timeout=10)
Expand Down
8 changes: 4 additions & 4 deletions exasol/itde_manager.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from exasol_integration_test_docker_environment.lib import api # type: ignore
from exasol_integration_test_docker_environment.lib.docker import ( # type: ignore
from exasol_integration_test_docker_environment.lib.docker import ( # type: ignore
ContextDockerClient,
)
from exasol_integration_test_docker_environment.lib.docker.container.utils import ( # type: ignore
from exasol_integration_test_docker_environment.lib.docker.container.utils import ( # type: ignore
remove_docker_container,
)
from exasol_integration_test_docker_environment.lib.docker.networks.utils import ( # type: ignore
from exasol_integration_test_docker_environment.lib.docker.networks.utils import ( # type: ignore
remove_docker_networks,
)
from exasol_integration_test_docker_environment.lib.docker.volumes.utils import ( # type: ignore
from exasol_integration_test_docker_environment.lib.docker.volumes.utils import ( # type: ignore
remove_docker_volumes,
)

Expand Down
2 changes: 1 addition & 1 deletion exasol/language_container_activation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Dict
import re
from typing import Dict

from exasol.secret_store import Secrets

Expand Down
37 changes: 24 additions & 13 deletions exasol/sagemaker_extension_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
from exasol_sagemaker_extension.deployment.deploy_create_statements import DeployCreateStatements # type: ignore
from exasol_sagemaker_extension.deployment.language_container_deployer import LanguageActivationLevel # type: ignore
from exasol_sagemaker_extension.deployment.sme_language_container_deployer import SmeLanguageContainerDeployer # type: ignore
from exasol_sagemaker_extension.deployment.deploy_create_statements import (
DeployCreateStatements, # type: ignore
)
from exasol_sagemaker_extension.deployment.language_container_deployer import (
LanguageActivationLevel, # type: ignore
)
from exasol_sagemaker_extension.deployment.sme_language_container_deployer import (
SmeLanguageContainerDeployer, # type: ignore
)

from exasol.ai_lab_config import AILabConfig as CKey
from exasol.connections import (
get_external_host,
open_pyexasol_connection,
)
from exasol.extension_wrapper_common import (
encapsulate_aws_credentials,
str_to_bool
str_to_bool,
)
from exasol.language_container_activation import (
ACTIVATION_KEY_PREFIX,
get_activation_sql
get_activation_sql,
)
from exasol.secret_store import Secrets
from exasol.ai_lab_config import AILabConfig as CKey

# Root directory in a bucket-fs bucket where all stuff of the Sagemaker
# Extension, including its language container, will be uploaded.
Expand Down Expand Up @@ -63,7 +69,7 @@ def deploy_language_container(conf: Secrets, version: str) -> None:
bucketfs_port=int(str(conf.get(CKey.bfs_port))),
bucketfs_user=conf.get(CKey.bfs_user),
bucketfs_password=conf.get(CKey.bfs_password),
bucketfs_use_https=str_to_bool(conf, CKey.bfs_encryption, True),
bucketfs_use_https=str_to_bool(conf, CKey.bfs_encryption, True),
bucket=conf.get(CKey.bfs_bucket),
path_in_bucket=PATH_IN_BUCKET,
use_ssl_cert_validation=str_to_bool(conf, CKey.cert_vld, True),
Expand Down Expand Up @@ -99,16 +105,21 @@ def deploy_scripts(conf: Secrets) -> None:
conn.execute(activation_sql)

scripts_deployer = DeployCreateStatements(
exasol_conn=conn, schema=conf.get(CKey.db_schema), to_print=False, develop=False
exasol_conn=conn,
schema=conf.get(CKey.db_schema),
to_print=False,
develop=False,
)
scripts_deployer.run()


def initialize_sme_extension(conf: Secrets,
version: str = LATEST_KNOWN_VERSION,
run_deploy_container: bool = True,
run_deploy_scripts: bool = True,
run_encapsulate_aws_credentials: bool = True) -> None:
def initialize_sme_extension(
conf: Secrets,
version: str = LATEST_KNOWN_VERSION,
run_deploy_container: bool = True,
run_deploy_scripts: bool = True,
run_encapsulate_aws_credentials: bool = True,
) -> None:
"""
Performs all necessary operations to get the Sagemaker Extension
up and running. See the "Getting Started" and "Setup" sections of the
Expand Down
7 changes: 4 additions & 3 deletions exasol/secret_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Iterable,
Optional,
Tuple,
Union
Union,
)

from sqlcipher3 import dbapi2 as sqlcipher # type: ignore
Expand Down Expand Up @@ -123,8 +123,9 @@ def insert(cur) -> None:
insert(cur)
return self

def get(self, key: Union[str, CKey], default_value: Optional[str] = None) -> Optional[str]:

def get(
self, key: Union[str, CKey], default_value: Optional[str] = None
) -> Optional[str]:
key = key.name if isinstance(key, CKey) else key

with self._cursor() as cur:
Expand Down
Loading

0 comments on commit 0efea5b

Please sign in to comment.