Skip to content

Commit

Permalink
Support disabling event tracking when using Cosmos profile mapping (a…
Browse files Browse the repository at this point in the history
…stronomer#768)

Since dbt by default tracks events by sending anonymous statistic usage
when dbt is invoked, users who currently use Cosmos profile mapping can
only opt-out by setting environment variables as described in
astronomer#724 (comment)

This PR adds a new arg to the profile mapping so that the [dbt
recommended config
block](https://docs.getdbt.com/reference/global-configs/usage-stats) can
be added in the generated `profiles.yml` file:

```yaml
config:
  send_anonymous_usage_stats: False
```

Closes: astronomer#724
  • Loading branch information
jbandoro authored and arojasb3 committed Jul 14, 2024
1 parent daeb727 commit d21baee
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
7 changes: 6 additions & 1 deletion cosmos/profiles/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ class BaseProfileMapping(ABC):

_conn: Connection | None = None

def __init__(self, conn_id: str, profile_args: dict[str, Any] | None = None):
def __init__(self, conn_id: str, profile_args: dict[str, Any] | None = None, disable_event_tracking: bool = False):
self.conn_id = conn_id
self.profile_args = profile_args or {}
self._validate_profile_args()
self.disable_event_tracking = disable_event_tracking

def _validate_profile_args(self) -> None:
"""
Expand Down Expand Up @@ -178,6 +179,10 @@ def get_profile_file_contents(
"outputs": {target_name: profile_vars},
}
}

if self.disable_event_tracking:
profile_contents["config"] = {"send_anonymous_usage_stats": "False"}

return str(yaml.dump(profile_contents, indent=4))

def get_dbt_value(self, name: str) -> Any:
Expand Down
31 changes: 31 additions & 0 deletions docs/templates/index.rst.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,37 @@ but override the ``database`` and ``schema`` values:
Note that when using a profile mapping, the profiles.yml file gets generated with the profile name and target name
you specify in ``ProfileConfig``.

Disabling dbt event tracking
--------------------------------
.. versionadded:: 1.3

By default `dbt will track events <https://docs.getdbt.com/reference/global-configs/usage-stats>`_ by sending anonymous usage data
when dbt commands are invoked. Users have an option to opt out of event tracking by updating their ``profiles.yml`` file.

If you'd like to disable this behavior in the Cosmos generated profile, you can pass ``disable_event_tracking=True`` to the profile mapping like in
the example below:

.. code-block:: python

from cosmos.profiles import SnowflakeUserPasswordProfileMapping

profile_config = ProfileConfig(
profile_name="my_profile_name",
target_name="my_target_name",
profile_mapping=SnowflakeUserPasswordProfileMapping(
conn_id="my_snowflake_conn_id",
profile_args={
"database": "my_snowflake_database",
"schema": "my_snowflake_schema",
},
disable_event_tracking=True,
),
)

dag = DbtDag(profile_config=profile_config, ...)




Using your own profiles.yml file
++++++++++++++++++++++++++++++++++++
Expand Down
25 changes: 23 additions & 2 deletions tests/profiles/test_base_profile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from __future__ import annotations

import pytest
import yaml

from cosmos.profiles.base import BaseProfileMapping
from cosmos.exceptions import CosmosValueError

Expand All @@ -7,8 +11,9 @@ class TestProfileMapping(BaseProfileMapping):
dbt_profile_method: str = "fake-method"
dbt_profile_type: str = "fake-type"

def profile(self):
raise NotImplementedError
@property
def profile(self) -> dict[str, str]:
return {"some-profile-key": "some-profile-value"}


@pytest.mark.parametrize("profile_arg", ["type", "method"])
Expand All @@ -29,3 +34,19 @@ def test_validate_profile_args(profile_arg: str):
conn_id="fake_conn_id",
profile_args=profile_args,
)


@pytest.mark.parametrize("disable_event_tracking", [True, False])
def test_disable_event_tracking(disable_event_tracking: str):
"""
Tests the config block in the profile is set correctly if disable_event_tracking is set.
"""
test_profile = TestProfileMapping(
conn_id="fake_conn_id",
disable_event_tracking=disable_event_tracking,
)
profile_contents = yaml.safe_load(test_profile.get_profile_file_contents(profile_name="fake-profile-name"))

assert ("config" in profile_contents) == disable_event_tracking
if disable_event_tracking:
assert profile_contents["config"]["send_anonymous_usage_stats"] == "False"

0 comments on commit d21baee

Please sign in to comment.