Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rules section to documentation #27

Merged
merged 10 commits into from
May 27, 2024
71 changes: 71 additions & 0 deletions docs/create_rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Create rules

In order to lint and score models, `dbt-score` uses a set of rules that are
applied to each model. A rule can pass or fail when it is run. Based on the
severity of the rule models are scored. `dbt-score` has a set of rules enabled
by default, which can be found [here](reference/rules/generic.md).

On top of the generic rules, it's possible to add your own rules. Two ways exist
to create a new rule:

1. By using the `@rule` decorator, which is the preferred/simple way.
2. By inheriting from the `Rule` class, which is more advanced and allows to
keep state between evaluations.

### Using the `@rule` decorator

The `@rule` decorator can be used to easily create a new rule:

```python
matthieucan marked this conversation as resolved.
Show resolved Hide resolved
from dbt_score import Model, rule, RuleViolation


@rule
def has_description(model: Model) -> RuleViolation | None:
"""A model should have a description."""
if not model.description:
return RuleViolation(message="Model lacks a description.")
jochemvandooren marked this conversation as resolved.
Show resolved Hide resolved
```

The name of the function is the name of the rule and the docstring of the
function is its description. Therefore, it is important to use a
self-explanatory name for the function and document it well.

The severity of a rule can be set using the `severity` argument:

```python
from dbt_score import rule, Severity


@rule(severity=Severity.HIGH)
```

jochemvandooren marked this conversation as resolved.
Show resolved Hide resolved
### Using the `Rule` class

For more advanced use cases, a rule can be created by inheriting from the `Rule`
class:

```python
from dbt_score import Model, Rule, RuleViolation


class HasDescription(Rule):
description = "A model should have a description."

def evaluate(self, model: Model) -> RuleViolation | None:
"""Evaluate the rule."""
if not model.description:
return RuleViolation(message="Model lacks a description.")
```

### Rules location

By default `dbt-score` will look for rules in the Python namespace
`dbt_score_rules`. Rules can be stored anywhere in the Python path under the
`dbt_score_rules` namespace. In many cases, having such a folder in the dbt
project from where you invoke dbt and dbt-score will work. In this folder, all
rules defined in `.py` files will be automatically discovered.

If nested folders are used, e.g. `dbt_score_rules/generic_rules/rules.py`, an
`__init__.py` file needs to be present in the nested folder to make it
discoverable.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ markdown_extensions:
nav:
- Home: index.md
- Get started: get_started.md
- Create rules: create_rules.md
- Rules:
- rules/generic.md
- Reference:
Expand Down