Package: reflekt
Reflekt/rəˈflek(t)/To embody or represent (something) in a faithful or appropriate wayReflekt helps Data, Engineering, and Product teams work together to define, manage, and model events for product analytics. ThereflektCLI integrates withschema registries, clouddata warehouses, anddbt.Define event schemas/contracts usingJSON schema, creating a version controlled source of truth.Configure schema naming and metadata conventions and enforce them withreflekt lint.Push schemas to a schema registry withreflekt pushfor use in event validation. Pull existing schemas withreflekt pull.Open pull requests to propose schemas changes, tag stakeholders for input, and request reviews.Build dbt sources, staging models, and docs thatreflektevent schemas withreflekt build dbt.https://user-images.githubusercontent.com/28986302/217134526-df83ec90-86f3-491e-9588-b7cd56956db1.mp4Table of ContentsGetting StartedInstallationReflekt--helpCreating a projectProject configurationUsing ReflektDefining schemasIdentifying and selecting schemasSchema versionsLinting schemasInteracting with schema registriesBuilding dbt artifactsSupported data warehousesGetting StartedInstallationReflekt is available onPyPI. Install withpip(or package manager of choice), preferably in a virtual environment:❯source/path/to/venv/bin/activate# Activate virtual environment❯pipinstallreflekt# Install Reflekt❯reflekt--version# Confirm installationReflektCLIVersion:0.3.1Reflekt--helpThe--helpflag provides an overview of availablereflektcommands.❯reflekt--help# Show general --help detailsUsage:reflekt[OPTIONS]COMMAND[ARGS]...ReflektCLI.

╭─Options────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│--version│
│--install-completion[bash|zsh|fish|powershell|pwsh]Installcompletionforthespecifiedshell.[default:None]│
│--show-completion[bash|zsh|fish|powershell|pwsh]Showcompletionforthespecifiedshell,tocopyitorcustomizetheinstallation.[default:None]│
│--helpShowthismessageandexit.│
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─Commands───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│buildBuilddataartifactsbasedonschemas.│
│debugCheckReflektprojectconfiguration.│
│initInitializeaReflektproject.│
│lintLintschema(s)totestfornamingandmetadataconventions.│
│pullPullschema(s)fromaschemaregistry.│
│pushPushschema(s)toaschemaregistry.│
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯Each command also has a--helpflag providing command details (arguments, options, syntax, etc.).❯reflektlint--help# Show --help details for `reflekt lint`Usage:reflektlint[OPTIONS]Lintschema(s)totestfornamingandmetadataconventions.

╭─Options────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│*--select-sTEXTSchema(s)tolint.[default:None][required]│
│--helpShowthismessageandexit.│
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯Creating a projectCreate a new directory, initialize a new Git repo, and runreflekt initto create a new Reflekt project.❯mkdir~/Repos/my-reflekt-project# Create a new directory for the project❯cd~/Repos/my-reflekt-project# Navigate to the project directory❯gitinit# Initialize a new Git repo❯reflektinit# Initialize a new Reflekt project in the current directory# Follow the prompts to configure the projectThis will create a new Reflekt project with the following structure:my-reflekt-project
├──.logs/# Reflekt command logs├──.reflekt_cache/# Local cache used by Reflekt├──artifacts/# Where Reflekt builds data artifacts (i.e., dbt packages)├──schemas/# Where event schemas are defined and stored├──.gitignore
├──README.md
└──reflekt_project.yml# Project configurationProject configurationReflekt uses 3 files to configure a project:reflekt_project.yml,reflekt_profiles.yml, andschemas/.reflekt/meta/1-0.json. Under the hood, Reflekt validates these configuration files before running, raising errors if an invalid configuration is detected. Examples of each file with configuration details are found below.reflekt_project.ymlContains general project settings as well as configuration for schema conventions, schema registry details (if needed), and data artifact generation. Click to expand the example below with details on each setting.example_reflekt_project.yml(CLICK TO EXPAND)# Example reflekt_project.yml# GENERAL CONFIG ----------------------------------------------------------------------version:1.0name:reflekt_demo# Project namevendor:com.company_name# Default vendor for schemas in reflekt projectdefault_profile:dev_reflekt# Default profile to use from reflekt_profiles.ymlprofiles_path:~/.reflekt/reflekt_profiles.yml# Path to reflekt_profiles.yml# SCHEMAS CONFIG ----------------------------------------------------------------------schemas:# Define schema conventionsconventions:event:casing:title# title | snake | camel | pascal | anynumbers:false# Allow numbers in event namesreserved:[]# Reserved event namesproperty:casing:snake# title | snake | camel | pascal | anynumbers:false# Allow numbers in property namesreserved:[]# Reserved property namesdata_types:[# Allowed data typesstring,integer,number,boolean,object,array,any,'null']# REGISTRY CONFIG ---------------------------------------------------------------------registry:# Additional config for schema registry if neededavo:# Avo specific configbranches:# Provide ID for Avo branches for `reflekt pull` to workstaging:AbC12dEfG# Safe to version control (See Avo docs to find branch ID: https://bit.ly/avo-docs-branch-id)main:main# 'main' always refers to the main branch# ARTIFACTS CONFIG -----------------------------------------------------------------------artifacts:# Configure how data artifacts are builtdbt:# dbt package configsources:prefix:__src_# Source files will start with this prefixmodels:prefix:stg_# Model files will start with this prefixdocs:prefix:_stg_# Docs files will start with this prefixin_folder:false# Docs files in separate folder?tests:# dbt tests to add based on column name (can be empty dict {})id:[unique,not_null]reflekt_profiles.ymlContains connection details for schema registries (used to validate event data) and data sources (i.e., data warehouse with raw event data). Click to expand the example below with details on each setting.example_reflekt_profiles.yml(CLICK TO EXPAND)# Example reflekt_profiles.ymlversion:1.0dev_reflekt:# Profile name (multiple profiles can be defined)# Define connections to schema registries (multiple allowed)registry:-type:segmentapi_token:segment_api_token# https://docs.segmentapis.com/tag/Getting-Started#section/Get-an-API-token-type:avoworkspace_id:avo_workspace_id# https://www.avo.app/docs/public-api/export-tracking-plan#endpointservice_account_name:avo_service_account_name# https://www.avo.app/docs/public-api/authentication#creating-service-accountsservice_account_secret:avo_service_account_secret# Connections to data sources (data warehouses) where event data is stored.# Sources are uniquely identified by their ID and are used in the `--source` arg when running `reflekt build`.source:-id:snowflake# For simplicity, we use the same ID as the source type.type:snowflake# Snowflake DWH. Credentials follow.account:abc12345database:rawwarehouse:transformingrole:transformeruser:reflekt_userpassword:reflekt_user_password-id:redshift# For simplicity, we use the same ID as the source type.type:redshift# Redshift DWH. Credentials follow.host:example-redshift-cluster-1.abc123.us-west-1.redshift.amazonaws.comdatabase:analyticsport:5439user:reflekt_userpassword:reflekt_user_passwordschemas/.reflekt/meta/1-0.jsonA meta-schema used to validate all event schemas in the project. Under the hood, Reflekt uses this meta-schema along with the naming conventions defined in thereflekt_project.ymlfile to validate all event schemas.To definerequired metadatafor all event schemas in your project, you can update themetadataobject inschemas/.reflekt/meta/1-0.json. See the example below showing how to require bothcode ownerandproduct ownermetadata.schemas/.reflekt/meta/1-0.json(CLICK TO EXPAND){"$schema":"http://json-schema.org/draft-07/schema#","$id":".reflekt/meta/1-0.json","description":"Meta-schema for all Reflekt events","self":{"vendor":"reflekt","name":"meta","format":"jsonschema","version":"1-0"},"type":"object","allOf":[{"$ref":"http://json-schema.org/draft-07/schema#"},{"properties":{"self":{"type":"object","properties":{"vendor":{"type":"string","description":"The company, application, team, or system that authored the schema (e.g., com.company, com.company.android, com.company.marketing)"},"name":{"type":"string","description":"The schema name. Describes what the schema is meant to capture (e.g., pageViewed, clickedLink)"},"format":{"type":"string","description":"The format of the schema","const":"jsonschema"},"version":{"type":"string","description":"The schema version, in MODEL-ADDITION format (e.g., 1-0, 1-1, 2-3, etc.)","pattern":"^[1-9][0-9]*-(0|[1-9][0-9]*)$"},"metadata":{// EXAMPLE: Defining required metadata (code_owner, product_owner)"type":"object","description":"Required metadata for all event schemas","properties":{"code_owner":{"type":"string"},"product_owner":{"type":"string"}},"required":["code_owner","product_owner"],"additionalProperties":false},},"required":["vendor","name","format","version"],"additionalProperties":false},"properties":{},"tests":{},},"required":["self","metadata","properties"]}]}Using ReflektDefining schemasEvent schemas are defined usingjsonschema. Each schema is defined as a separate JSON file, stored in theschemas/directory of a Reflekt project. An exampleProductClickedevent schema is shown below.my-reflekt-project/schemas/segment/ecommerce/ProductClicked/1-0.json(CLICK TO EXPAND){"$id":"segment/ecommerce/ProductClicked/1-0.json",// Unique ID for the schema"$schema":"http://json-schema.org/draft-07/schema#",// JSON Schema version"self":{"vendor":"com.company_name",// Company, application, team, or system that authored the schema"name":"ProductClicked",// Name of the event"format":"jsonschema",// Format of the schema"version":"1-0",// Version of the schema"metadata":{// Metadata for the event"code_owner":"engineering/ecommerce-squad","product_owner":"product_manager_name@company_name.com",}},"type":"object","properties":{// Properties of the event"product_id":{"type":"string","description":"Database id of the product being viewed"},"sku":{"type":"string","description":"Sku of the product being viewed"},"category":{"type":"string","description":"Category of the product being viewed"},"name":{"type":"string","description":"Name of the product being viewed"},"brand":{"type":"string","description":"Brand of the product being viewed"},"variant":{"type":"string","description":"Variant of the product being viewed"},"price":{"type":"number","description":"Price of the product ($) being viewed"},"quantity":{"type":"integer","description":"Quantity of the product being viewed"},"coupon":{"type":"string","description":"Coupon code associated with a product (for example, MAY_DEALS_3)"},"position":{"type":"integer","description":"Position in the product list (ex. 3)"},"url":{"type":"string","description":"URL of the product being viewed"},"image_url":{"type":"string","description":"URL of the product image being viewed"},},"required":[// Required properties"product_id","sku","category","name","brand","price","quantity"],"additionalProperties":false,// No additional properties allowed}Identifying and selecting schemasSchemas are uniquely identified by their$id, which is determine by their path relative to theschemas/directory. For example:Path to schemaSchema$idmy-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.jsonsegment/ecommerce/CartViewed/1-0.jsonmy-reflekt-project/schemas/segment/ecommerce/LinkClicked/2-1.jsonsegment/ecommerce/LinkClicked/2-1.jsonThese$ids are used to--selectschemas when running Reflekt commands. For example:❯reflektlint--selectsegment/ecommerce/CartViewed/1-0.json# Lint version 1-0 of the CartViewed schema❯reflektlint--select"segment/ecommerce/Link Clicked/2-1.json"# $ids with spaces must be surrounded by quotes❯reflektlint--selectsegment/ecommerce# Lint all schemas in the segment/ecommerce directorySchema versionsAs data collection requirements change, event schemas must be updated toreflektthe new schema. Reflekt supports schema evolution by defining aversionfor each schema, starting at1-0and following aMAJOR-MINORversion spec. The definition ofMAJORandMINORis as follows:MAJOR- Breaking schema changes incompatible with previous data. Examples:Add/remove/rename a required propertyChange a property fromoptional to requiredChange a property's typeMINOR- Non-breaking schema changes compatible with previous data. Examples:Add/remove/rename an optional propertyChange a property fromrequired to optionalWhen defining a new schema version,create a new filewith the incremented version and updated schema definition.Interacting with schema registriesSchema registries are used to store and serve schemas. Once a schema is in a registry, it can be used to validate event data against the schema to ensure event data quality. Reflekt supports interacting with schema registries to push (publish) and pull (retrieve) schemas. Currently, the following registries are supported:Registry--pushsupport--pullsupportSchema--selectsyntaxSchemaversionsupportSegment Protocols✅✅--select segment/tracking_plan_nameOnly supportsMAJOR-0versions.Avo❌✅--select avo/branch_nameSchema changes managed in Avobranches-"version": "1-0"(always).Avo customers pull schemas withreflekt pulland build dbt artifacts withreflekt build.Pull schemas from a registryPulling schemas from a registry is as easy as ...❯reflektpull--selectsegment/ecommerce[19:28:32]INFORunningwithreflekt=0.3.1[19:28:32]INFOSearchingSegmentforschemas[19:28:33]INFOFound9schemastopull:[19:28:33]INFO1of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Identify/1-0.json[19:28:34]INFO2of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Group/1-0.json[19:28:34]INFO3of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.json[19:28:34]INFO4of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStarted/1-0.json[19:28:34]INFO5of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStepCompleted/1-0.json[19:28:34]INFO6of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStepViewed/1-0.json[19:28:34]INFO7of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/OrderCompleted/1-0.json[19:28:34]INFO8of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/PageViewed/1-0.json[19:28:34]INFO9of9Writingto/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/ProductAdded/1-0.json[19:28:34]INFOCompletedsuccessfullyThereflekt pullcommand builds the corresponding JSON files in theschemas/directory. For the example above, the resulting directory structure would be:schemas
├──.reflekt
└──segment└──ecommerce├──CartViewed│└──1-0.json├──CheckoutStarted│└──1-0.json├──CheckoutStepCompleted│└──1-0.json├──CheckoutStepViewed│└──1-0.json├──Group│└──1-0.json├──Identify│└──1-0.json├──OrderCompleted│└──1-0.json├──PageViewed│└──1-0.json└──ProductAdded└──1-0.jsonPush schemas to a registryPublishing schemas to a registry follows the same pattern ...❯reflektpush--selectsegment/ecommerce[19:29:06]INFORunningwithreflekt=0.3.1[19:29:07]INFOSearchingforJSONschemasin:/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce[19:29:07]INFOFound9schemastopush[19:29:07]INFO1of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Identify/1-0.json[19:29:07]INFO2of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.json[19:29:07]INFO3of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStepViewed/1-0.json[19:29:07]INFO4of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Group/1-0.json[19:29:07]INFO5of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/OrderCompleted/1-0.json[19:29:07]INFO6of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStepCompleted/1-0.json[19:29:07]INFO7of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStarted/1-0.json[19:29:07]INFO8of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/PageViewed/1-0.json[19:29:07]INFO9of9Pushing/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/ProductAdded/1-0.json[19:29:08]INFOCompletedsuccessfullyLinting schemasSchemas can be linted to test if they follow the naming and metadata conventions configured for a Reflekt project.❯reflektlint--selectsegment/ecommerce[18:57:45]INFORunningwithreflekt=0.3.1[18:57:46]INFOSearchingforJSONschemasin:/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce[18:57:46]INFOFound9schema(s)tolint[18:57:46]INFO1of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Identify/1-0.json[18:57:47]INFO2of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.json[18:57:48]ERRORProperty'cartId'in/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.jsondoesnotmatchnamingconvention'casing: snake'in/Users/myuser/Repos/my-reflekt-project/reflekt_project.yml.[18:57:48]INFO3of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStepViewed/1-0.json[18:57:50]INFO4of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Group/1-0.json[18:57:50]INFO5of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/OrderCompleted/1-0.json[18:57:54]INFO6of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStepCompleted/1-0.json[18:57:55]INFO7of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CheckoutStarted/1-0.json[18:57:58]INFO8of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/PageViewed/1-0.json[18:58:01]INFO9of9Linting/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/ProductAdded/1-0.json[18:58:04]ERRORLintingfailedwith1error(s):[18:58:04]ERRORProperty'cartId'in/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.jsondoesnotmatchnamingconvention'casing: snake'in/Users/myuser/Repos/my-reflekt-project/reflekt_project.yml.Runningreflekt lintin a CI/CD pipeline is a great way to ensure schema consistency and quality before pushing schemas to a schema registry.dbt artifactsdbtis a popular data tool to transformation and model data. When modeling data in dbt, it isbest practiceto:Define sources pointing to the raw data.Define staging models, 1-to-1 for each source, thatrename, recast, or usefully reconsidercolumns into a consistent format. Materialized as views.Document staging models with descriptions for the model and its fields, including relevant tests (e.g., unique and not_null IDs) as required.While we recommend following this practice, it can bea lot of work to maintainfor product analytics, where:There are many events (often 100+) and properties.Events and properties are added or updated regularly as the product and data requirements evolve.The Product and Engineer teams are bigger than the Data team, making it hard to keep up with the changes.Reflekt can help by building dbt artifacts for you with a single CLI command.Think of this as dbt'scodegenpackage on steroids :muscle: :pill:.Building private dbt packagesTo build a private dbt package with sources, staging models, and docs that perfectlyreflektsthe schemas in a Reflekt project and the raw data in the warehouse, you can run a command like the example below.Where:--select segment/ecommerceselects all the schemas in theschemas/segment/ecommerce/directory.--source snowflake.raw.ecomm_demospecifies to connect to a data source with IDsnowflake, databaseraw, and schemaecomm_demoas defined inreflekt_profiles.yml.--sdk segmentspecifies the event data was collected via the Segment SDK. Reflekt knows how Segment loads data into data warehouses and writes SQL models accordingly.If an event schema has multiple versions, Reflekt builds a staging model for both versions, allowing the Data team to easily consolidate schema changes as needed.❯reflektbuilddbt--selectsegment/ecommerce--sourcesnowflake.raw.ecomm_demo--sdksegment[09:45:23]INFORunningwithreflekt=0.3.1[09:45:24]INFOSearchingforJSONschemasin:/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce[09:45:24]INFOFound10schemastobuild[09:45:24]INFOBuildingdbtpackage:name:reflekt_demodir:/Users/myuser/Repos/my-reflekt-project/artifacts/dbt/reflekt_demo--select:segment/ecommerce--sdk_arg:segment--source:snowflake.raw.ecomm_demo[09:45:24]INFOBuildingdbtsource'ecomm_demo'[09:45:24]INFOBuildingdbtartifactsforschema:/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/Identify/1-0.json[09:45:26]INFOBuildingdbttable'identifies'insource'ecomm_demo'[09:45:26]INFOBuildingstagingmodel'stg_ecomm_demo__identifies.sql'[09:45:26]INFOBuildingdbtdocumentation'_stg_ecomm_demo__identifies.yml'[09:45:26]INFOBuildingdbtartifactsforschema:Segment'users'table[09:45:26]INFOBuildingdbttable'users'insource'ecomm_demo'[09:45:26]INFOBuildingstagingmodel'stg_ecomm_demo__users.sql'[09:45:26]INFOBuildingdbtdocumentation'_stg_ecomm_demo__users.yml'[09:45:26]INFOBuildingdbtartifactsforschema:/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/2-0.json[09:45:26]INFOBuildingdbttable'cart_viewed'insource'ecomm_demo'[09:45:26]INFOBuildingstagingmodel'stg_ecomm_demo__cart_viewed__v2_0.sql'[09:45:26]INFOBuildingdbtdocumentation'_stg_ecomm_demo__cart_viewed__v2_0.yml'[09:45:26]INFOBuildingdbtartifactsforschema:/Users/myuser/Repos/my-reflekt-project/schemas/segment/ecommerce/CartViewed/1-0.json[09:45:27]INFOBuildingstagingmodel'stg_ecomm_demo__cart_viewed.sql'[09:45:27]INFOBuildingdbtdocumentation'_stg_ecomm_demo__cart_viewed.yml'...
...# Full output omitted for brevity...[09:45:29]INFOBuildingdbtartifactsforschema:Segment'tracks'table[09:45:29]INFOBuildingdbttable'tracks'insource'ecomm_demo'[09:45:29]INFOBuildingstagingmodel'stg_ecomm_demo__tracks.sql'[09:45:29]INFOBuildingdbtdocumentation'_stg_ecomm_demo__tracks.yml'[09:45:29]INFOCopyingdbtpackagefromtemporarypath/Users/myuser/Repos/my-reflekt-project/.reflekt_cache/artifacts/dbt/reflekt_demoto/Users/myuser/Repos/my-reflekt-project/artifacts/dbt/reflekt_demo[09:45:29]INFOSuccessfullybuiltdbtpackageUsing private dbt packagesTo use a Reflekt dbt package in a downstream dbt project, add it to the dbt project'spackages.yml.dbt-core# packages.ymlpackages:-git:"https://github.com/<your_user_or_org>/<your_repo>"# Reflekt project Github repo URLsubdirectory:"dbt-packages/<reflekt_dbt_package_name>"revision:v0.1.0__reflekt_demo# Branch, tag, or commit (40-character hash). For latest, use 'main' branch.dbt-cloud# packages.ymlpackages:-git:""https://{{env_var('DBT_ENV_SECRET_GITHUB_PAT')}}@github.com/<your_user_or_org>/<your_repo>.git""# Reflekt project Github repo URL with GitHub PATsubdirectory:"dbt-packages/<reflekt_dbt_package_name>"revision:v0.1.0__reflekt_demo# Branch, tag, or commit (40-character hash). For latest, use 'main' branch.To use with dbt-cloud, you will need to create aGithub personal access token(e.g.,DBT_ENV_SECRET_GITHUB_PAT) andconfigure it as an environment variablein your dbt-cloud account.For local dbt development, set the environment variable on your local machine.# Add the following line to your .zshrc, .bash_profile, etc.exportDBT_ENV_SECRET_GITHUB_PAT=YOUR_TOKENSupported data warehousesReflekt currently supports the following data warehouses:SnowflakeRedshift:construction: BigQuery support coming soon! :construction: