Skip to content

Commit

Permalink
Fixes the schema and empty config value bugs (#30)
Browse files Browse the repository at this point in the history
* Fixes the schema and empty config value bugs

* Added ticket references to changges_.md files

* Added ticket references to changges_.md files

* Updated changelog.md

* Updates the docstrings in the connection functions
  • Loading branch information
ahsimb authored Nov 24, 2023
1 parent 1faf6a9 commit caeff51
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 25 deletions.
4 changes: 4 additions & 0 deletions doc/changes/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changes

* [0.2.2](changes_0.2.2.md)
* [0.2.1](changes_0.2.1.md)
* [0.2.0](changes_0.2.0.md)
* [0.1.0](changes_0.1.0.md)
* [0.0.1](changes_0.0.1.md)
Expand All @@ -9,6 +11,8 @@
---
hidden:
---
changes_0.2.2
changes_0.2.1
changes_0.2.0
changes_0.1.0
changes_0.0.1
Expand Down
12 changes: 12 additions & 0 deletions doc/changes/changes_0.2.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Exasol Notebook Connector 0.2.1, released 2023-11-14

## Summary

This release adds the connections module and fixes a couple of bugs

## Changes

* #21: Bug fix: Removes uniqueness of values in the Secret Store
* #22: Bug fix: Corrects usage example in the documentation
* #23: Adds the connections module
* #26: Allows providing a default value when querying the Secret Store
10 changes: 10 additions & 0 deletions doc/changes/changes_0.2.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Exasol Notebook Connector 0.2.2, released 2023-11-23

## Summary

This release fixes a couple of issues with the connections module

## Changes

* #28: Treats empty string values in configuration as None
* #29: Connection does not try to set a default schema
23 changes: 8 additions & 15 deletions exasol/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
from pathlib import Path
from typing import Optional

import pyexasol # type: ignore
import sqlalchemy # type: ignore
import exasol.bucketfs as bfs # type: ignore

import pyexasol # type: ignore
import sqlalchemy # type: ignore
import exasol.bucketfs as bfs # type: ignore
from exasol.secret_store import Secrets


Expand Down Expand Up @@ -42,7 +41,7 @@ def _extract_ssl_options(conf: Secrets) -> dict:

# Is a bundle with trusted CAs provided?
trusted_ca = conf.get("TRUSTED_CA")
if trusted_ca is not None:
if trusted_ca:
trusted_ca_path = Path(trusted_ca)
if trusted_ca_path.is_dir():
sslopt["ca_cert_path"] = trusted_ca
Expand All @@ -53,12 +52,12 @@ def _extract_ssl_options(conf: Secrets) -> dict:

# Is client's own certificate provided?
client_certificate = conf.get("CLIENT_CERTIFICATE")
if client_certificate is not None:
if client_certificate:
if not Path(client_certificate).is_file():
raise ValueError(f"Certificate file {client_certificate} doesn't exist.")
sslopt["certfile"] = client_certificate
private_key = conf.get("PRIVATE_KEY")
if private_key is not None:
if private_key:
if not Path(private_key).is_file():
raise ValueError(f"Private key file {private_key} doesn't exist.")
sslopt["keyfile"] = private_key
Expand All @@ -74,6 +73,7 @@ def get_external_host(conf: Secrets):
def open_pyexasol_connection(conf: Secrets, **kwargs) -> pyexasol.ExaConnection:
"""
Opens a pyexasol connection using provided configuration parameters.
Does NOT set the default schema, even if it is defined in the configuration.
Any additional parameters can be passed to pyexasol via the kwargs.
Parameters in kwargs override the correspondent values in the configuration.
Expand All @@ -82,7 +82,6 @@ def open_pyexasol_connection(conf: Secrets, **kwargs) -> pyexasol.ExaConnection:
- Server address and port (EXTERNAL_HOST_NAME, DB_PORT),
- Client security credentials (USER, PASSWORD).
Optional parameters include:
- Database schema (SCHEMA),
- Secured comm flag (ENCRYPTION),
- Some of the SSL options (CERTIFICATE_VALIDATION, TRUSTED_CA, CLIENT_CERTIFICATE).
If the schema is not provided then it should be set explicitly in every SQL statement.
Expand All @@ -95,9 +94,6 @@ def open_pyexasol_connection(conf: Secrets, **kwargs) -> pyexasol.ExaConnection:
"password": conf.PASSWORD,
}

schema = conf.get("SCHEMA")
if schema:
conn_params["schema"] = schema
encryption = _optional_encryption(conf)
if encryption is not None:
conn_params["encryption"] = encryption
Expand All @@ -113,12 +109,12 @@ def open_pyexasol_connection(conf: Secrets, **kwargs) -> pyexasol.ExaConnection:
def open_sqlalchemy_connection(conf: Secrets):
"""
Creates an Exasol SQLAlchemy websocket engine using provided configuration parameters.
Does NOT set the default schema, even if it is defined in the configuration.
The configuration should provide the following parameters:
- Server address and port (EXTERNAL_HOST_NAME, DB_PORT),
- Client security credentials (USER, PASSWORD).
Optional parameters include:
- Database schema (SCHEMA),
- Secured comm flag (ENCRYPTION).
- Validation of the server's TLS/SSL certificate by the client (CERTIFICATE_VALIDATION).
If the schema is not provided then it should be set explicitly in every SQL statement.
Expand All @@ -130,9 +126,6 @@ def open_sqlalchemy_connection(conf: Secrets):
websocket_url = (
f"exa+websocket://{conf.USER}:{conf.PASSWORD}@{get_external_host(conf)}"
)
schema = conf.get("SCHEMA")
if schema:
websocket_url = f"{websocket_url}/{schema}"

delimiter = "?"
encryption = _optional_encryption(conf)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "exasol-notebook-connector"
version = "0.2.1"
version = "0.2.2"
description = "Components, tools, APIs, and configurations in order to connect Jupyter notebooks to Exasol and various other systems."
packages = [ {include = "exasol"}, ]
authors = [ "Christoph Kuhnke <[email protected]>" ]
Expand Down
17 changes: 9 additions & 8 deletions test/unit/test_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@ def test_get_external_host(conf):

@unittest.mock.patch("pyexasol.connect")
def test_open_pyexasol_connection(mock_connect, conf):
conf.save("SCHEMA", "IDA")

open_pyexasol_connection(conf)
mock_connect.assert_called_once_with(
dsn=get_external_host(conf), user=conf.USER, password=conf.PASSWORD, schema="IDA"
dsn=get_external_host(conf), user=conf.USER, password=conf.PASSWORD
)


Expand Down Expand Up @@ -107,11 +105,9 @@ def test_open_pyexasol_connection_error(mock_connect, conf):

@unittest.mock.patch("sqlalchemy.create_engine")
def test_open_sqlalchemy_connection(mock_create_engine, conf):
conf.save("SCHEMA", "IDA")

open_sqlalchemy_connection(conf)
mock_create_engine.assert_called_once_with(
f"exa+websocket://{conf.USER}:{conf.PASSWORD}@{get_external_host(conf)}/IDA"
f"exa+websocket://{conf.USER}:{conf.PASSWORD}@{get_external_host(conf)}"
)


Expand All @@ -122,7 +118,7 @@ def test_open_sqlalchemy_connection_ssl(mock_create_engine, conf):

open_sqlalchemy_connection(conf)
mock_create_engine.assert_called_once_with(
f"exa+websocket://{conf.USER}:{conf.PASSWORD}@{get_external_host(conf)}"
f"exa+websocket://{conf.USER}:{conf.PASSWORD}@{get_external_host(conf)}"
"?ENCRYPTION=Yes&SSLCertificate=SSL_VERIFY_NONE"
)

Expand All @@ -132,5 +128,10 @@ def test_open_bucketfs_connection(mock_bfs_service, conf):
open_bucketfs_connection(conf)
mock_bfs_service.assert_called_once_with(
f"http://{conf.EXTERNAL_HOST_NAME}:{conf.BUCKETFS_PORT}",
{conf.BUCKETFS_BUCKET: {"username": conf.BUCKETFS_USER, "password": conf.BUCKETFS_PASSWORD}},
{
conf.BUCKETFS_BUCKET: {
"username": conf.BUCKETFS_USER,
"password": conf.BUCKETFS_PASSWORD,
}
},
)
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
# If you need to change the version, do so in the project.toml, e.g. by using `poetry version X.Y.Z`.
MAJOR = 0
MINOR = 2
PATCH = 1
PATCH = 2
VERSION = f"{MAJOR}.{MINOR}.{PATCH}"

0 comments on commit caeff51

Please sign in to comment.