You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by hu...@apache.org on 2021/05/19 19:31:37 UTC

[superset] branch hugh-bg-form-3 updated: save bg form

This is an automated email from the ASF dual-hosted git repository.

hugh pushed a commit to branch hugh-bg-form-3
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/hugh-bg-form-3 by this push:
     new 139cd49  save bg form
139cd49 is described below

commit 139cd495e1b825fc405f938b981fcffdd3394b00
Author: hughhhh <hu...@gmail.com>
AuthorDate: Wed May 19 15:30:21 2021 -0400

    save bg form
---
 superset/db_engine_specs/bigquery.py | 64 ++++++++++++++++++++++++++++++++++++
 tests/databases/api_tests.py         | 41 +++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/superset/db_engine_specs/bigquery.py b/superset/db_engine_specs/bigquery.py
index 9c52b44..2e0cc8f 100644
--- a/superset/db_engine_specs/bigquery.py
+++ b/superset/db_engine_specs/bigquery.py
@@ -19,9 +19,13 @@ from datetime import datetime
 from typing import Any, Dict, List, Optional, Pattern, Tuple, TYPE_CHECKING
 
 import pandas as pd
+from apispec import APISpec
+from apispec.ext.marshmallow import MarshmallowPlugin
 from flask_babel import gettext as __
+from marshmallow import fields, Schema
 from sqlalchemy import literal_column
 from sqlalchemy.sql.expression import ColumnClause
+from typing_extensions import TypedDict
 
 from superset.db_engine_specs.base import BaseEngineSpec
 from superset.errors import SupersetErrorType
@@ -38,6 +42,32 @@ CONNECTION_DATABASE_PERMISSIONS_REGEX = re.compile(
     + "permission in project (?P<project>.+?)"
 )
 
+# TODO: Fill in descriptions of each field
+class BigQueryParametersSchema(Schema):
+    type = fields.String(required=True, description=__(""))
+    project_id = fields.String(required=True, description=__(""))
+    private_key_id = fields.String(required=True, description=__(""))
+    private_key = fields.String(required=True, description=__(""))
+    client_email = fields.String(required=True, description=__(""))
+    client_id = fields.String(required=True, description=__(""))
+    auth_uri = fields.String(required=True, description=__(""))
+    token_uri = fields.String(required=True, description=__(""))
+    auth_provider_x509_cert_url = fields.String(required=True, description=__(""))
+    client_x509_cert_url = fields.String(required=True, description=__(""))
+
+
+class BigQueryParametersType(TypedDict):
+    type: str
+    project_id: str
+    private_key_id: str
+    private_key: str
+    client_email: str
+    client_id: str
+    auth_uri: str
+    token_uri: str
+    auth_provider_x509_cert_url: str
+    client_x509_cert_url: str
+
 
 class BigQueryEngineSpec(BaseEngineSpec):
     """Engine spec for Google's BigQuery
@@ -48,6 +78,10 @@ class BigQueryEngineSpec(BaseEngineSpec):
     engine_name = "Google BigQuery"
     max_column_name_length = 128
 
+    parameters_schema = BigQueryParametersSchema()
+    drivername = engine
+    sqlalchemy_uri_placeholder = "bigquery://{project_id}"
+
     # BigQuery doesn't maintain context when running multiple statements in the
     # same cursor, so we need to run all statements at once
     run_multiple_statements_as_one = True
@@ -282,3 +316,33 @@ class BigQueryEngineSpec(BaseEngineSpec):
                 to_gbq_kwargs[key] = to_sql_kwargs[key]
 
         pandas_gbq.to_gbq(df, **to_gbq_kwargs)
+
+    @classmethod
+    def build_sqlalchemy_url(cls, parameters: BigQueryParametersType) -> str:
+        project_id = parameters.get("project_id")
+        return f"{cls.drivername}://{project_id}"
+
+    @classmethod
+    def get_parameters_from_uri(cls, uri: str) -> Any:
+        # We might need to add a special case for bigquery since
+        # we are relying on the json credentials
+        return {"foo": "bar"}
+
+    @classmethod
+    def parameters_json_schema(cls) -> Any:
+        """
+        Return configuration parameters as OpenAPI.
+        """
+        if not cls.parameters_schema:
+            return None
+
+        print(cls.parameters_schema)
+
+        spec = APISpec(
+            title="Database Parameters",
+            version="1.0.0",
+            openapi_version="3.0.2",
+            plugins=[MarshmallowPlugin()],
+        )
+        spec.components.schema(cls.__name__, schema=cls.parameters_schema)
+        return spec.to_dict()["components"]["schemas"][cls.__name__]
diff --git a/tests/databases/api_tests.py b/tests/databases/api_tests.py
index 7f53c57..c631c43 100644
--- a/tests/databases/api_tests.py
+++ b/tests/databases/api_tests.py
@@ -36,6 +36,7 @@ from superset import db, security_manager
 from superset.connectors.sqla.models import SqlaTable
 from superset.db_engine_specs.mysql import MySQLEngineSpec
 from superset.db_engine_specs.postgres import PostgresEngineSpec
+from superset.db_engine_specs.bigquery import BigQueryEngineSpec
 from superset.db_engine_specs.hana import HanaEngineSpec
 from superset.errors import SupersetError
 from superset.models.core import Database, ConfigurationMethod
@@ -1373,6 +1374,7 @@ class TestDatabaseApi(SupersetTestCase):
         app.config = {"PREFERRED_DATABASES": ["postgresql"]}
         get_available_engine_specs.return_value = [
             PostgresEngineSpec,
+            BigQueryEngineSpec,
             HanaEngineSpec,
         ]
 
@@ -1428,6 +1430,45 @@ class TestDatabaseApi(SupersetTestCase):
                     "preferred": True,
                     "sqlalchemy_uri_placeholder": "postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]",
                 },
+                {
+                    "engine": "bigquery",
+                    "name": "Google BigQuery",
+                    "parameters": {
+                        "properties": {
+                            "auth_provider_x509_cert_url": {
+                                "description": "",
+                                "type": "string",
+                            },
+                            "auth_uri": {"description": "", "type": "string",},
+                            "client_email": {"description": "", "type": "string",},
+                            "client_id": {"description": "", "type": "string",},
+                            "client_x509_cert_url": {
+                                "description": "",
+                                "type": "string",
+                            },
+                            "private_key": {"description": "", "type": "string",},
+                            "private_key_id": {"description": "", "type": "string",},
+                            "project_id": {"description": "", "type": "string",},
+                            "token_uri": {"description": "", "type": "string",},
+                            "type": {"description": "", "type": "string",},
+                        },
+                        "required": [
+                            "auth_provider_x509_cert_url",
+                            "auth_uri",
+                            "client_email",
+                            "client_id",
+                            "client_x509_cert_url",
+                            "private_key",
+                            "private_key_id",
+                            "project_id",
+                            "token_uri",
+                            "type",
+                        ],
+                        "type": "object",
+                    },
+                    "preferred": True,
+                    "sqlalchemy_uri_placeholder": "bigquery://{project_id}",
+                },
                 {"engine": "hana", "name": "SAP HANA", "preferred": False},
             ]
         }