chore: set Snowflake user agent (#22432)

This commit is contained in:
Beto Dealmeida
2022-12-15 17:08:34 -08:00
committed by GitHub
parent 4f9c2c8165
commit bdeedaaf80
5 changed files with 107 additions and 17 deletions

View File

@@ -163,11 +163,13 @@ class DatabricksNativeEngineSpec(DatabricksODBCEngineSpec, BasicParametersMixin)
""" """
Add a user agent to be used in the requests. Add a user agent to be used in the requests.
""" """
extra = { extra: Dict[str, Any] = BaseEngineSpec.get_extra_params(database)
"http_headers": [("User-Agent", USER_AGENT)], engine_params: Dict[str, Any] = extra.setdefault("engine_params", {})
"_user_agent_entry": USER_AGENT, connect_args: Dict[str, Any] = engine_params.setdefault("connect_args", {})
}
extra.update(BaseEngineSpec.get_extra_params(database)) connect_args.setdefault("http_headers", [("User-Agent", USER_AGENT)])
connect_args.setdefault("_user_agent_entry", USER_AGENT)
return extra return extra
@classmethod @classmethod

View File

@@ -31,8 +31,9 @@ from marshmallow import fields, Schema
from sqlalchemy.engine.url import URL from sqlalchemy.engine.url import URL
from typing_extensions import TypedDict from typing_extensions import TypedDict
from superset.constants import USER_AGENT
from superset.databases.utils import make_url_safe from superset.databases.utils import make_url_safe
from superset.db_engine_specs.base import BasicPropertiesType from superset.db_engine_specs.base import BaseEngineSpec, BasicPropertiesType
from superset.db_engine_specs.postgres import PostgresBaseEngineSpec from superset.db_engine_specs.postgres import PostgresBaseEngineSpec
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
from superset.models.sql_lab import Query from superset.models.sql_lab import Query
@@ -118,6 +119,19 @@ class SnowflakeEngineSpec(PostgresBaseEngineSpec):
), ),
} }
@staticmethod
def get_extra_params(database: "Database") -> Dict[str, Any]:
"""
Add a user agent to be used in the requests.
"""
extra: Dict[str, Any] = BaseEngineSpec.get_extra_params(database)
engine_params: Dict[str, Any] = extra.setdefault("engine_params", {})
connect_args: Dict[str, Any] = engine_params.setdefault("connect_args", {})
connect_args.setdefault("application", USER_AGENT)
return extra
@classmethod @classmethod
def adjust_database_uri( def adjust_database_uri(
cls, uri: URL, selected_schema: Optional[str] = None cls, uri: URL, selected_schema: Optional[str] = None

View File

@@ -44,16 +44,17 @@ class TestDatabricksDbEngineSpec(TestDbEngineSpec):
db.extra = default_db_extra db.extra = default_db_extra
db.server_cert = None db.server_cert = None
extras = DatabricksNativeEngineSpec.get_extra_params(db) extras = DatabricksNativeEngineSpec.get_extra_params(db)
assert "connect_args" not in extras["engine_params"] assert extras == {
"engine_params": {
def test_extras_with_user_agent(self): "connect_args": {
db = mock.Mock() "_user_agent_entry": "Apache Superset",
db.extra = default_db_extra "http_headers": [("User-Agent", "Apache Superset")],
extras = DatabricksNativeEngineSpec.get_extra_params(db) },
_, user_agent = extras["http_headers"][0] },
user_agent_entry = extras["_user_agent_entry"] "metadata_cache_timeout": {},
assert user_agent == USER_AGENT "metadata_params": {},
assert user_agent_entry == USER_AGENT "schemas_allowed_for_file_upload": [],
}
def test_extras_with_ssl_custom(self): def test_extras_with_ssl_custom(self):
db = mock.Mock() db = mock.Mock()

View File

@@ -18,8 +18,9 @@
import json import json
from pytest_mock import MockerFixture
from superset.utils.core import GenericDataType from superset.utils.core import GenericDataType
from tests.integration_tests.db_engine_specs.base_tests import assert_generic_types
def test_get_parameters_from_uri() -> None: def test_get_parameters_from_uri() -> None:
@@ -110,6 +111,7 @@ def test_generic_type() -> None:
assert that generic types match assert that generic types match
""" """
from superset.db_engine_specs.databricks import DatabricksNativeEngineSpec from superset.db_engine_specs.databricks import DatabricksNativeEngineSpec
from tests.integration_tests.db_engine_specs.base_tests import assert_generic_types
type_expectations = ( type_expectations = (
# Numeric # Numeric
@@ -133,3 +135,43 @@ def test_generic_type() -> None:
("BOOLEAN", GenericDataType.BOOLEAN), ("BOOLEAN", GenericDataType.BOOLEAN),
) )
assert_generic_types(DatabricksNativeEngineSpec, type_expectations) assert_generic_types(DatabricksNativeEngineSpec, type_expectations)
def test_get_extra_params(mocker: MockerFixture) -> None:
"""
Test the ``get_extra_params`` method.
"""
from superset.db_engine_specs.databricks import DatabricksNativeEngineSpec
database = mocker.MagicMock()
database.extra = {}
assert DatabricksNativeEngineSpec.get_extra_params(database) == {
"engine_params": {
"connect_args": {
"http_headers": [("User-Agent", "Apache Superset")],
"_user_agent_entry": "Apache Superset",
}
}
}
database.extra = json.dumps(
{
"engine_params": {
"connect_args": {
"http_headers": [("User-Agent", "Custom user agent")],
"_user_agent_entry": "Custom user agent",
"foo": "bar",
}
}
}
)
assert DatabricksNativeEngineSpec.get_extra_params(database) == {
"engine_params": {
"connect_args": {
"http_headers": [["User-Agent", "Custom user agent"]],
"_user_agent_entry": "Custom user agent",
"foo": "bar",
}
}
}

View File

@@ -14,11 +14,15 @@
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# pylint: disable=import-outside-toplevel
import json import json
from datetime import datetime from datetime import datetime
from unittest import mock from unittest import mock
import pytest import pytest
from pytest_mock import MockerFixture
from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.errors import ErrorLevel, SupersetError, SupersetErrorType
from tests.unit_tests.fixtures.common import dttm from tests.unit_tests.fixtures.common import dttm
@@ -122,3 +126,30 @@ def test_cancel_query_failed(engine_mock: mock.Mock) -> None:
query = Query() query = Query()
cursor_mock = engine_mock.raiseError.side_effect = Exception() cursor_mock = engine_mock.raiseError.side_effect = Exception()
assert SnowflakeEngineSpec.cancel_query(cursor_mock, query, "123") is False assert SnowflakeEngineSpec.cancel_query(cursor_mock, query, "123") is False
def test_get_extra_params(mocker: MockerFixture) -> None:
"""
Test the ``get_extra_params`` method.
"""
from superset.db_engine_specs.snowflake import SnowflakeEngineSpec
database = mocker.MagicMock()
database.extra = {}
assert SnowflakeEngineSpec.get_extra_params(database) == {
"engine_params": {"connect_args": {"application": "Apache Superset"}}
}
database.extra = json.dumps(
{
"engine_params": {
"connect_args": {"application": "Custom user agent", "foo": "bar"}
}
}
)
assert SnowflakeEngineSpec.get_extra_params(database) == {
"engine_params": {
"connect_args": {"application": "Custom user agent", "foo": "bar"}
}
}