Skip to content

Commit

Permalink
Restore Python 3.6+ compatibility (#55)
Browse files Browse the repository at this point in the history
* Set explicit Python version on GitHub Actions

* Install build requirements on GitHub Actions

* feat: use Enum instead of Literal for Python 3.6+ compatibility

Also wrap the use of importlib

* feat: use Enum instead of Literal for Python 3.6+ compatibility

Also wrap the use of importlib

* Move build dependencies to requirements-test.txt

* Fix typo

* Refactor check for importlib existence

Co-authored-by: Mike Gouline <1960272+gouline@users.noreply.github.com>
  • Loading branch information
fernandobrito and gouline authored Sep 13, 2021
1 parent de4e8f3 commit 696d417
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 62 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ jobs:
steps:
- uses: actions/checkout@v2

- uses: actions/setup-python@v2
with:
python-version: '3.6.x'

- name: Requirements
run: make requirements

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ jobs:
steps:
- uses: actions/checkout@v2

- uses: actions/setup-python@v2
with:
python-version: '3.6.x'

- uses: actions/cache@v2
with:
path: ~/.cache/pip
Expand Down
11 changes: 9 additions & 2 deletions dbtmetabase/models/metabase.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
from dataclasses import dataclass, field
from typing import Sequence, Optional, MutableMapping, Literal
from enum import Enum

from typing import Sequence, Optional, MutableMapping

# Allowed metabase.* fields
# Should be covered by attributes in the MetabaseColumn class
METABASE_META_FIELDS = ["special_type", "semantic_type", "visibility_type"]


class ModelKey(str, Enum):
nodes = "nodes"
sources = "sources"


@dataclass
class MetabaseColumn:
name: str
Expand All @@ -25,7 +32,7 @@ class MetabaseModel:
name: str
schema: str
description: str = ""
model_key: Literal["nodes", "sources"] = "nodes"
model_key: ModelKey = ModelKey.nodes
ref: Optional[str] = None

columns: Sequence[MetabaseColumn] = field(default_factory=list)
26 changes: 12 additions & 14 deletions dbtmetabase/parsers/dbt_folder.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import re
import os
import logging

from pathlib import Path
from typing import List, Iterable, Mapping, MutableMapping, Literal, Optional

import os
import re
import yaml
from pathlib import Path
from typing import List, Iterable, Mapping, MutableMapping, Optional

from ..models.metabase import METABASE_META_FIELDS
from ..models.metabase import METABASE_META_FIELDS, ModelKey
from ..models.metabase import MetabaseModel, MetabaseColumn


Expand Down Expand Up @@ -78,7 +76,7 @@ def read_models(
model,
schema.upper(),
include_tags=include_tags,
model_key="nodes",
model_key=ModelKey.nodes,
)
)
for source in schema_file.get("sources", []):
Expand All @@ -102,7 +100,7 @@ def read_models(
model,
source_schema_name.upper(),
include_tags=include_tags,
model_key="sources",
model_key=ModelKey.sources,
source=source["name"],
)
)
Expand All @@ -114,7 +112,7 @@ def _read_model(
model: dict,
schema: str,
include_tags: bool = True,
model_key: Literal["nodes", "sources"] = "nodes",
model_key: ModelKey = ModelKey.nodes,
source: str = None,
) -> MetabaseModel:
"""Reads one dbt model in Metabase-friendly format.
Expand All @@ -141,12 +139,12 @@ def _read_model(
description += "\n\n"
description += f"Tags: {tags}"

if model_key == "nodes":
ref: Optional[str] = None

if model_key == ModelKey.nodes:
ref = f"ref('{model.get('identifier', model['name'])}')"
elif model_key == "sources":
elif model_key == ModelKey.sources:
ref = f"source('{source}', '{model['name']}')"
else:
ref = None

return MetabaseModel(
# We are implicitly complying with aliases by doing this
Expand Down
18 changes: 9 additions & 9 deletions dbtmetabase/parsers/dbt_manifest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import json
import os
from typing import List, Iterable, Mapping, Optional, MutableMapping, Literal
import logging
import os
from typing import List, Iterable, Mapping, Optional, MutableMapping

from ..models.metabase import METABASE_META_FIELDS
from ..models.metabase import METABASE_META_FIELDS, ModelKey
from ..models.metabase import MetabaseModel, MetabaseColumn


Expand Down Expand Up @@ -146,7 +146,7 @@ def read_models(
node,
include_tags=include_tags,
docs_url=docs_url,
model_key="sources",
model_key=ModelKey.sources,
source=node["source_name"],
)
)
Expand All @@ -158,7 +158,7 @@ def _read_model(
model: dict,
include_tags: bool = True,
docs_url: Optional[str] = None,
model_key: Literal["nodes", "sources"] = "nodes",
model_key: ModelKey = ModelKey.nodes,
source: Optional[str] = None,
) -> MetabaseModel:
"""Reads one dbt model in Metabase-friendly format.
Expand Down Expand Up @@ -225,12 +225,12 @@ def _read_model(
description += "\n\n"
description += f"dbt docs link: {full_path}"

if model_key == "nodes":
ref: Optional[str] = None

if model_key == ModelKey.nodes:
ref = f"ref('{model.get('identifier', model['name'])}')"
elif model_key == "sources":
elif model_key == ModelKey.sources:
ref = f"source('{source}', '{model['name']}')"
else:
ref = None

return MetabaseModel(
name=model.get("alias", model.get("identifier", model.get("name"))).upper(),
Expand Down
15 changes: 10 additions & 5 deletions dbtmetabase/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
import importlib.metadata
import sys


def get_version() -> str:
Expand All @@ -16,9 +16,14 @@ def get_version() -> str:
except ModuleNotFoundError:
logging.debug("No _version.py found")

try:
return importlib.metadata.version("dbt-metabase")
except importlib.metadata.PackageNotFoundError:
logging.warning("No version found in metadata")
# importlib is only available on Python 3.8+
if sys.version_info >= (3, 8):
# pylint: disable=no-member
import importlib.metadata

try:
return importlib.metadata.version("dbt-metabase")
except importlib.metadata.PackageNotFoundError:
logging.warning("No version found in metadata")

return "0.0.0-UNKONWN"
2 changes: 2 additions & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
setuptools>=45
wheel
pylint
mypy
types-requests
Expand Down
13 changes: 7 additions & 6 deletions tests/test_dbt_folder_reader.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import logging
import unittest

from dbtmetabase.models.metabase import ModelKey
from dbtmetabase.parsers.dbt_folder import (
DbtFolderReader,
MetabaseModel,
MetabaseColumn,
)
import logging


class MockDbtFolderReader(DbtFolderReader):
Expand All @@ -29,7 +30,7 @@ def test_read_models(self):
name="CUSTOMERS",
schema="PUBLIC",
description="This table has basic information about a customer, as well as some derived facts based on a customer's orders",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('customers')",
columns=[
MetabaseColumn(
Expand Down Expand Up @@ -101,7 +102,7 @@ def test_read_models(self):
name="ORDERS",
schema="PUBLIC",
description="This table has basic information about orders, as well as some derived facts based on payments",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('orders')",
columns=[
MetabaseColumn(
Expand Down Expand Up @@ -191,7 +192,7 @@ def test_read_models(self):
name="STG_CUSTOMERS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_customers')",
columns=[
MetabaseColumn(
Expand All @@ -209,7 +210,7 @@ def test_read_models(self):
name="STG_ORDERS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_orders')",
columns=[
MetabaseColumn(
Expand All @@ -236,7 +237,7 @@ def test_read_models(self):
name="STG_PAYMENTS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_payments')",
columns=[
MetabaseColumn(
Expand Down
13 changes: 7 additions & 6 deletions tests/test_dbt_manifest_reader.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import logging
import unittest

from dbtmetabase.models.metabase import ModelKey
from dbtmetabase.parsers.dbt_manifest import (
DbtManifestReader,
MetabaseModel,
MetabaseColumn,
)
import logging


class MockDbtManifestReader(DbtManifestReader):
Expand All @@ -30,7 +31,7 @@ def test_read_models(self):
name="ORDERS",
schema="PUBLIC",
description="This table has basic information about orders, as well as some derived facts based on payments",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('orders')",
columns=[
MetabaseColumn(
Expand Down Expand Up @@ -120,7 +121,7 @@ def test_read_models(self):
name="CUSTOMERS",
schema="PUBLIC",
description="This table has basic information about a customer, as well as some derived facts based on a customer's orders",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('customers')",
columns=[
MetabaseColumn(
Expand Down Expand Up @@ -192,7 +193,7 @@ def test_read_models(self):
name="STG_ORDERS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_orders')",
columns=[
MetabaseColumn(
Expand All @@ -219,7 +220,7 @@ def test_read_models(self):
name="STG_PAYMENTS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_payments')",
columns=[
MetabaseColumn(
Expand All @@ -246,7 +247,7 @@ def test_read_models(self):
name="STG_CUSTOMERS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_customers')",
columns=[
MetabaseColumn(
Expand Down
21 changes: 10 additions & 11 deletions tests/test_metabase.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import json
import logging
import os
import unittest
import yaml

from dbtmetabase.metabase import MetabaseClient
from dbtmetabase.models.metabase import (
MetabaseModel,
MetabaseColumn,
ModelKey,
)

import logging
import json
import yaml
import os


MODELS = [
MetabaseModel(
name="ORDERS",
schema="PUBLIC",
description="This table has basic information about orders, as well as some derived facts based on payments",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('orders')",
columns=[
MetabaseColumn(
Expand Down Expand Up @@ -107,7 +106,7 @@
name="CUSTOMERS",
schema="PUBLIC",
description="This table has basic information about a customer, as well as some derived facts based on a customer's orders",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('customers')",
columns=[
MetabaseColumn(
Expand Down Expand Up @@ -179,7 +178,7 @@
name="STG_ORDERS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_orders')",
columns=[
MetabaseColumn(
Expand All @@ -206,7 +205,7 @@
name="STG_PAYMENTS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_payments')",
columns=[
MetabaseColumn(
Expand All @@ -233,7 +232,7 @@
name="STG_CUSTOMERS",
schema="PUBLIC",
description="",
model_key="nodes",
model_key=ModelKey.nodes,
ref="ref('stg_customers')",
columns=[
MetabaseColumn(
Expand Down
Loading

0 comments on commit 696d417

Please sign in to comment.