Skip to content

Commit

Permalink
Merge pull request #213 from godatadriven/merge-class-and-func-attempt-2
Browse files Browse the repository at this point in the history
Merge class and func attempt 2
  • Loading branch information
pgoslatara authored Sep 2, 2024
2 parents 803a0e2 + b116ebc commit e25f62b
Show file tree
Hide file tree
Showing 30 changed files with 1,613 additions and 1,258 deletions.
22 changes: 8 additions & 14 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,14 @@ To add a new check follow the below steps:

1. In `./src/dbt_bouncer/checks` choose the appropriate directory for your check. For example, if your check only requires the `manifest.json` then use the `manifest` directory, if your check requires the `catalog.json` then use the `catalog` directory.
1. Within the chosen directory assess if a suitable file already exists. For example, if your check applies to a model then `manifest/check_models.py` is a suitable location.
1. Within the chosen file, add both a class and a function:

- `class`: The class is a pydantic model defining the input arguments and must meet the following criteria:
- Start with "Check".
- Inherit from `dbt_bouncer.conf_validator_base.BaseCheck`.
- Have a `name` attribute that is a string.
- Not use `description` in a `Field`.
- A `default` value provided for optional input arguments.

- `function`: The function must meet the following criteria:
- Be called after the snake case equivalent of the `name` attribute of the created class.
- Accept `**kwargs`.
- Have a doc string that includes a description of the check, a list of possible input parameters and at least one example.
- A clear message in the event of a failure.
1. Within the chosen file, add a Pydantic model, this object must meet the following criteria:

- Start with "Check".
- Inherit from `dbt_bouncer.check_base.BaseCheck`.
- Have a `name` attribute that is a string whose value is the snake case equivalent of the class name.
- A `default` value provided for optional input arguments and arguments that are received at execution time.
- Have a doc string that includes a description of the check, a list of possible input parameters and at least one example.
- A clear message in the event of a failure.

1. After the check is added, add the check to `dbt-bouncer-example.yml` and run `dbt-bouncer --config-file dbt-bouncer-example.yml` to ensure the check succeeds.
1. (Optional) If the dbt project located in `./dbt_project` needs to be updated then do so and also run `make build-artifacts` to generate the new test artifacts.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{% import "language.html" as lang with context %}

<p><span class="doc-section-title">Other Parameters (passed via config file):</span></p>
<table>
<thead>
Expand Down
31 changes: 31 additions & 0 deletions docs/templates/python/material/docstring/receives.html.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{% import "language.html" as lang with context %}

<p><strong>Receives at execution time:</strong></p>
<table>
<thead>
<tr>
<th>{{ lang.t("Name") }}</th>
<th>{{ lang.t("Type") }}</th>
<th>{{ lang.t("Description") }}</th>
</tr>
</thead>
<tbody>
{% for receives in section.value %}
<tr>
<td>{% if receives.name %}<code>{{ receives.name }}</code>{% endif %}
<td>
{% if receives.annotation %}
{% with expression = receives.annotation %}
<code>{% include "expression.html" with context %}</code>
{% endwith %}
{% endif %}
</td>
<td>
<div class="doc-md-description">
{{ receives.description|convert_markdown(heading_level, html_id) }}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
4 changes: 2 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ plugins:
- src/dbt_bouncer/checks
options:
docstring_style: google
filters: ["check_"]
filters: ["Check"]
group_by_category: true
heading_level: 1
inherited_members: true
members_order: source
show_bases: false
show_docstring_classes: false
show_docstring_classes: true
show_docstring_raises: false
show_if_no_docstring: true
show_root_toc_entry: false
Expand Down
47 changes: 29 additions & 18 deletions src/dbt_bouncer/checks/catalog/check_catalog_sources.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
from typing import TYPE_CHECKING, List, Literal

from pydantic import Field

from dbt_bouncer.check_base import BaseCheck

if TYPE_CHECKING:
from dbt_bouncer.parsers import DbtBouncerCatalogNode, DbtBouncerSource
import warnings

from dbt_bouncer.parsers import (
DbtBouncerSourceBase,
)

class CheckSourceColumnsAreAllDocumented(BaseCheck):
name: Literal["check_source_columns_are_all_documented"]
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=UserWarning)
from dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogTable


def check_source_columns_are_all_documented(
catalog_source: "DbtBouncerCatalogNode",
sources: List["DbtBouncerSource"],
**kwargs,
) -> None:
class CheckSourceColumnsAreAllDocumented(BaseCheck):
"""All columns in a source should be included in the source's properties file, i.e. `.yml` file.
Parameters:
catalog_source (DbtBouncerCatalogNode): The DbtBouncerCatalogNode object to check.
sources (List[DbtBouncerSource]): List of DbtBouncerSource objects parsed from `catalog.json`.
Receives:
catalog_source (CatalogTable): The CatalogTable object to check.
sources (List[DbtBouncerSourceBase]): List of DbtBouncerSourceBase objects parsed from `catalog.json`.
Other Parameters:
exclude (Optional[str]): Regex pattern to match the source path (i.e the .yml file where the source is configured). Source paths that match the pattern will not be checked.
Expand All @@ -33,10 +35,19 @@ def check_source_columns_are_all_documented(
```
"""
source = next(s for s in sources if s.unique_id == catalog_source.unique_id)
undocumented_columns = [
v.name
for _, v in catalog_source.columns.items()
if v.name not in source.columns
]
assert not undocumented_columns, f"`{catalog_source.unique_id}` has columns that are not included in the sources properties file: {undocumented_columns}"

catalog_source: "CatalogTable" = Field(default=None)
name: Literal["check_source_columns_are_all_documented"]
sources: List["DbtBouncerSourceBase"] = Field(default=[])

def execute(self) -> None:
"""Execute the check."""
source = next(
s for s in self.sources if s.unique_id == self.catalog_source.unique_id
)
undocumented_columns = [
v.name
for _, v in self.catalog_source.columns.items()
if v.name not in source.columns
]
assert not undocumented_columns, f"`{self.catalog_source.unique_id}` has columns that are not included in the sources properties file: {undocumented_columns}"
Loading

0 comments on commit e25f62b

Please sign in to comment.