├── .devcontainer └── devcontainer.json ├── .example.env ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── dbt ├── .gitignore ├── README.md ├── analyses │ └── .gitkeep ├── dbt_project.yml ├── macros │ └── .gitkeep ├── models │ └── example │ │ ├── my_first_dbt_model.sql │ │ ├── my_second_dbt_model.sql │ │ └── schema.yml ├── profiles.yml ├── seeds │ └── .gitkeep ├── snapshots │ └── .gitkeep └── tests │ └── .gitkeep ├── poetry.lock ├── pyproject.toml └── scripts └── dev_container.sh /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template_dbt_docker", 3 | // Sets the run context to one level up instead of the .devcontainer folder. 4 | // Update the 'dockerFile' property if you aren't using the standard 5 | // 'Dockerfile' filename. 6 | "build": { 7 | "dockerfile": "../Dockerfile", 8 | "context": "..", 9 | "target": "dev_container" 10 | }, 11 | // Check architecture of the host machine before building the 12 | // `docker-from-docker` stage of the dev container. 13 | "initializeCommand": [ 14 | "./scripts/dev_container.sh", "initialize" 15 | ], 16 | // Set *default* container specific settings.json values on container create. 17 | "runArgs": [ 18 | "--env-file", 19 | ".env" 20 | ], 21 | // VS Code User Settings Inside the Remote Container 22 | "settings": { 23 | "files.insertFinalNewline": true, 24 | "files.trimFinalNewlines": true, 25 | "files.trimTrailingWhitespace": true, 26 | "files.associations": { 27 | "/code/dbt/models/target/**/*.sql": "sql" 28 | }, 29 | "terminal.integrated.cwd": "/code/dbt", 30 | "python.pythonPath": "/usr/local/bin/python", 31 | "editor.formatOnSave": false, 32 | "editor.quickSuggestions": { 33 | "strings": true 34 | }, 35 | "extensions.autoUpdate": false, 36 | "extensions.autoCheckUpdates": false, 37 | // SQLTools is a VS Code native SQL Workbench extension 38 | "sqltools.autoOpenSessionFiles": false, 39 | "sqltools.results.reuseTabs": "connection", 40 | // Provide a connection to a warehouse so the SQLTools Client 41 | // can connect from within the dev container 42 | "sqltools.connections": [ 43 | { 44 | "authenticator": "SNOWFLAKE", 45 | "ocspOptions": { 46 | "ocspFailOpen": true 47 | }, 48 | "snowflakeOptions": { 49 | "clientSessionKeepAlive": true, 50 | "clientSessionKeepAliveHeartbeatFrequency": 3600 51 | }, 52 | "previewLimit": 50, 53 | "driver": "Snowflake", 54 | "group": "Snowflake", 55 | "name": "", 56 | "account": "", 57 | "username": "", 58 | "password": "", 59 | "database": "", 60 | "warehouse": "" 61 | } 62 | ] 63 | }, 64 | // Add the IDs of extensions you want installed when the container is created. 65 | "extensions": [ 66 | "eamodio.gitlens@12.2.2", 67 | "ms-python.python", 68 | // For a VS Code warehouse connection - see results in the warehouse 69 | // from the devcontainer 70 | "mtxr.sqltools@0.25.1", 71 | "koszti.snowflake-driver-for-sqltools@0.4.2", 72 | // For go-to-definition in dbt 73 | "innoverio.vscode-dbt-power-user@0.6.2", 74 | // For documentation 75 | "stkb.rewrap@1.16.3", 76 | "yzhang.markdown-all-in-one@3.4.3", 77 | "streetsidesoftware.code-spell-checker@2.11.10" 78 | ], 79 | "workspaceMount": "source=${localWorkspaceFolder}/,target=/code,type=bind,consistency=cached", 80 | "workspaceFolder": "/code", 81 | "mounts": [ 82 | // Forwards the hosts Docker socket for 'Docker from Docker' functionality 83 | "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", 84 | // Copy in the .ssh keys from host for use with git, if applicable 85 | "source=${localEnv:HOME}/.ssh,target=/root/.ssh,type=bind", 86 | // Create a dev-container-extensions docker volume to avoid re-installing 87 | // extensions on rebuilds of the dev container. See here for more 88 | // information: https://bit.ly/3EBcadH 89 | "source=dev-container-extensions,target=/root/.vscode-server/extensions,type=volume" 90 | ], 91 | "postAttachCommand": [ 92 | "./scripts/dev_container.sh", "post_attach" 93 | ] 94 | } 95 | -------------------------------------------------------------------------------- /.example.env: -------------------------------------------------------------------------------- 1 | # Instructions: 2 | 3 | ## Copy this file into a .env that will be ignored by git and 4 | ## fill in the values as indicated. 5 | 6 | # Note that the profiles.yml is inside the dbt/ folder 7 | DBT_PROFILES_DIR=. 8 | 9 | # Set these for your warehouse 10 | SNOWFLAKE_ACCOUNT= 11 | SNOWFLAKE_DATABASE= 12 | SNOWFLAKE_PASSWORD= 13 | SNOWFLAKE_ROLE= 14 | SNOWFLAKE_SCHEMA= 15 | SNOWFLAKE_USER= 16 | SNOWFLAKE_WAREHOUSE= 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .arch 3 | .vscode 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ######################################## 2 | # --------------- BASE --------------- # 3 | ######################################## 4 | FROM python:3.9.14-slim-bullseye AS base 5 | 6 | ENV POETRY_VIRTUALENVS_CREATE=false \ 7 | POETRY_VERSION=1.1.13 \ 8 | POETRY_HOME=/usr/local \ 9 | AWS_CLI_VERSION=2.8.2 10 | 11 | RUN apt-get update \ 12 | && apt-get install -y git curl vim jq unzip sudo \ 13 | && apt-get clean 14 | 15 | RUN curl -sSL https://install.python-poetry.org | python - 16 | 17 | # Installs the AWS CLI v2, which is not available via PyPi 18 | RUN ARCH=$([ "$(uname -m)" = "x86_64" ] && echo "x86_64" || echo "aarch64") \ 19 | && curl "https://awscli.amazonaws.com/awscli-exe-linux-${ARCH}-${AWS_CLI_VERSION}.zip" -o "awscliv2.zip" \ 20 | && unzip -q awscliv2.zip \ 21 | && sudo ./aws/install 22 | 23 | WORKDIR /code/ 24 | 25 | COPY ["poetry.lock", "pyproject.toml", "/code/"] 26 | RUN poetry install --no-interaction --without dev 27 | 28 | ########################## 29 | # --------- DEV -------- # 30 | ########################## 31 | FROM base AS dev_container 32 | # Used in VS Code development Container. Enables "Docker from Docker" ie. 33 | # building and running containers on the host (laptop) within the VS Code 34 | # Development Container See for more details: https://bit.ly/3yIRcWA 35 | 36 | # .devcontainer/.arch contains either 'amd64' or 'arm64' depending on the 37 | # architecture of the host machine (eg. Apple M1 = 'arm64') and is used 38 | # to ensure the correct the debian installation of the Docker CLI is fetched 39 | # from the linux package registry. 40 | COPY [".devcontainer/.arch", "/code/"] 41 | 42 | RUN apt-get update \ 43 | && apt-get install -y apt-transport-https ca-certificates curl gnupg2 lsb-release \ 44 | && ARCH=$(cat /code/.arch) \ 45 | && curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | apt-key add - 2>/dev/null \ 46 | && echo "deb [arch=$ARCH] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list \ 47 | && apt-get update \ 48 | && apt-get install -y docker-ce-cli 49 | 50 | COPY --from=base ["/usr", "/usr"] 51 | 52 | ###################### 53 | # ------- PROD ----- # 54 | ###################### 55 | FROM base as prod 56 | # Used for runs in pipelines and jobs. 57 | 58 | COPY --from=base ["/usr/local/bin", "/usr/local/bin"] 59 | 60 | COPY ["dbt", "/code/dbt/"] 61 | 62 | WORKDIR /code/dbt/ 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Teghan Nightengale 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dbt & VS Code Dev Containers 2 | A template for [dbt-Core](https://docs.getdbt.com/docs/introduction) projects inside of [docker](https://docs.docker.com/get-started/), 3 | using [poetry](https://python-poetry.org) to manage dependencies and VS Code [Dev Containers](https://code.visualstudio.com/docs/remote/containers) for local development. 4 | 5 | ## Table of Contents 6 | - [Overview](#overview) 7 | - [Getting Started](#getting-started) 8 | - [Configuring the Template](#configuring-the-template) 9 | - [Contributions](#contributions) 10 | 11 | ## Overview 12 | VS Code [Dev Containers](https://code.visualstudio.com/docs/devcontainers/containers) provide an 13 | immediate development environment for teams to manage their [dbt-Core](https://github.com/dbt-labs/dbt-core/pkgs/container/dbt-core) project. 14 | 15 | A dockerized dbt environment allows for a consistent runtime across 16 | contributors and orchestration tools: the versions, packages, scripts and behavior of a dbt-Core project are identical whether the project is run locally or deployed. 17 | 18 | Examples of possible changes to the environment are: 19 | - package versions controlled with poetry 20 | - VS Code extensions (versions, included extensions) 21 | - other scripts (eg. CI scripts that can be run locally) 22 | - CLI tools like aws, git, etc 23 | 24 | These changes can be made through changes to the relevant files. Simply 25 | rebuilding the container will allow every team member and tool to use the new environment. 26 | 27 | ## Getting Started 28 | Complete the following steps to launch the Dev Container in VS Code: 29 | 30 | 1. Download [Docker Desktop](https://www.docker.com/products/docker-desktop/). 31 | 2. Download [VS Code](https://code.visualstudio.com/download). 32 | 3. Install the [VS Code Dev Containers Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers). 33 | 4. Open the project in VS Code and click "Repoen in Container" when prompted. 34 | 35 | ## Configuring the Template 36 | The following features of this template repository can be configured to specific 37 | use cases: 38 | 39 | - The [dbt project](dbt/) can be replaced with an existing project. 40 | - Note that `dbt/profiles.yml` should be retained within the container. 41 | - Typically dbt uses profiles from `~/.dbt/profiles.yml`. 42 | - However this dbt project is designed to be run both locally and by pipelines/orchestration tools. 43 | - Thus, the profiles need to be included in the container. 44 | - The connection secrets in the profile should be provided to the 45 | container via the environment. 46 | - Environment variables should be passed to the development container for local 47 | development via an `.env` file. 48 | - Any local `.env` files are ignored by git. 49 | - See `.example.env` for an example of passing connection details. 50 | - Use [poetry](https://python-poetry.org) to install and manage new 51 | dependencies in the container. 52 | - The [scripts/](scripts/) folder can be used to house build and pipeline 53 | scripts. 54 | - The [devcontainer.json](.devcontainer/devcontainer.json) contains 55 | recommended VS Code extensions for development. 56 | - These are cached by default 57 | in a docker volume for fast rebuilds of the Dev Container. 58 | - The 59 | [SQLTools](https://marketplace.visualstudio.com/items?itemName=mtxr.sqltools) 60 | extension is setup with a Snowflake connection by default. 61 | - The connection uses params in `.example.env` which are injected by the 62 | `postAttachCommand` in the [devcontainer.json](.devcontainer/devcontainer.json). 63 | - SQLTools connections allow viewing and querying data in the warehouse 64 | directly from the VS Code Dev Container. 65 | - dbt models can be created in the warehouse and the data viewed from within 66 | VS Code to accelerate development. 67 | 68 | ## Contributions 69 | Please reach out and start a discussion if you are interested in enhancing or 70 | altering this 71 | template. 72 | 73 | You can find the author in the [dbt 74 | Slack](https://app.slack.com/team/USPDHN49M) or simply open an issue here. Cheers! 75 | -------------------------------------------------------------------------------- /dbt/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | target/ 3 | dbt_packages/ 4 | logs/ 5 | -------------------------------------------------------------------------------- /dbt/README.md: -------------------------------------------------------------------------------- 1 | Welcome to your new dbt project! 2 | 3 | ### Using the starter project 4 | 5 | Try running the following commands: 6 | - dbt run 7 | - dbt test 8 | 9 | 10 | ### Resources: 11 | - Learn more about dbt [in the docs](https://docs.getdbt.com/docs/introduction) 12 | - Check out [Discourse](https://discourse.getdbt.com/) for commonly asked questions and answers 13 | - Join the [chat](https://community.getdbt.com/) on Slack for live discussions and support 14 | - Find [dbt events](https://events.getdbt.com) near you 15 | - Check out [the blog](https://blog.getdbt.com/) for the latest news on dbt's development and best practices 16 | -------------------------------------------------------------------------------- /dbt/analyses/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnightengale/template-dbt-docker/e97e980cca7a3417f0f3452f5f6a57a7984ff4d0/dbt/analyses/.gitkeep -------------------------------------------------------------------------------- /dbt/dbt_project.yml: -------------------------------------------------------------------------------- 1 | 2 | # Name your project! Project names should contain only lowercase characters 3 | # and underscores. A good package name should reflect your organization's 4 | # name or the intended use of these models 5 | name: 'template_dbt_docker' 6 | version: '1.0.0' 7 | config-version: 2 8 | 9 | # This setting configures which "profile" dbt uses for this project. 10 | profile: 'template_dbt_docker' 11 | 12 | # These configurations specify where dbt should look for different types of files. 13 | # The `model-paths` config, for example, states that models in this project can be 14 | # found in the "models/" directory. You probably won't need to change these! 15 | model-paths: ["models"] 16 | analysis-paths: ["analyses"] 17 | test-paths: ["tests"] 18 | seed-paths: ["seeds"] 19 | macro-paths: ["macros"] 20 | snapshot-paths: ["snapshots"] 21 | 22 | target-path: "target" # directory which will store compiled SQL files 23 | clean-targets: # directories to be removed by `dbt clean` 24 | - "target" 25 | - "dbt_packages" 26 | 27 | 28 | # Configuring models 29 | # Full documentation: https://docs.getdbt.com/docs/configuring-models 30 | 31 | # In this example config, we tell dbt to build all models in the example/ directory 32 | # as tables. These settings can be overridden in the individual model files 33 | # using the `{{ config(...) }}` macro. 34 | models: 35 | template_dbt_docker: 36 | # Config indicated by + and applies to all files under models/example/ 37 | example: 38 | +materialized: view 39 | -------------------------------------------------------------------------------- /dbt/macros/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnightengale/template-dbt-docker/e97e980cca7a3417f0f3452f5f6a57a7984ff4d0/dbt/macros/.gitkeep -------------------------------------------------------------------------------- /dbt/models/example/my_first_dbt_model.sql: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Welcome to your first dbt model! 4 | Did you know that you can also configure models directly within SQL files? 5 | This will override configurations stated in dbt_project.yml 6 | 7 | Try changing "table" to "view" below 8 | */ 9 | 10 | {{ config(materialized='table') }} 11 | 12 | with source_data as ( 13 | 14 | select 1 as id 15 | union all 16 | select null as id 17 | 18 | ) 19 | 20 | select * 21 | from source_data 22 | 23 | /* 24 | Uncomment the line below to remove records with null `id` values 25 | */ 26 | 27 | -- where id is not null 28 | -------------------------------------------------------------------------------- /dbt/models/example/my_second_dbt_model.sql: -------------------------------------------------------------------------------- 1 | 2 | -- Use the `ref` function to select from other models 3 | 4 | select * 5 | from {{ ref('my_first_dbt_model') }} 6 | where id = 1 7 | -------------------------------------------------------------------------------- /dbt/models/example/schema.yml: -------------------------------------------------------------------------------- 1 | 2 | version: 2 3 | 4 | models: 5 | - name: my_first_dbt_model 6 | description: "A starter dbt model" 7 | columns: 8 | - name: id 9 | description: "The primary key for this table" 10 | tests: 11 | - unique 12 | - not_null 13 | 14 | - name: my_second_dbt_model 15 | description: "A starter dbt model" 16 | columns: 17 | - name: id 18 | description: "The primary key for this table" 19 | tests: 20 | - unique 21 | - not_null 22 | -------------------------------------------------------------------------------- /dbt/profiles.yml: -------------------------------------------------------------------------------- 1 | template_dbt_docker: 2 | outputs: 3 | dev: 4 | account: "{{ env(SNOWFLAKE_ACCOUNT) }}" 5 | database: "{{ env(SNOWFLAKE_DATABASE) }}" 6 | password: "{{ env(SNOWFLAKE_PASSWORD) }}" 7 | role: "{{ env(SNOWFLAKE_ROLE) }}" 8 | schema: "{{ env(SNOWFLAKE_SCHEMA) }}" 9 | threads: 4 10 | type: snowflake 11 | user: "{{ env(SNOWFLAKE_USER) }}" 12 | warehouse: "{{ env(SNOWFLAKE_WAREHOUSE) }}" 13 | target: dev 14 | -------------------------------------------------------------------------------- /dbt/seeds/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnightengale/template-dbt-docker/e97e980cca7a3417f0f3452f5f6a57a7984ff4d0/dbt/seeds/.gitkeep -------------------------------------------------------------------------------- /dbt/snapshots/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnightengale/template-dbt-docker/e97e980cca7a3417f0f3452f5f6a57a7984ff4d0/dbt/snapshots/.gitkeep -------------------------------------------------------------------------------- /dbt/tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tnightengale/template-dbt-docker/e97e980cca7a3417f0f3452f5f6a57a7984ff4d0/dbt/tests/.gitkeep -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "agate" 3 | version = "1.6.3" 4 | description = "A data analysis library that is optimized for humans instead of machines." 5 | category = "main" 6 | optional = false 7 | python-versions = "*" 8 | 9 | [package.dependencies] 10 | Babel = ">=2.0" 11 | isodate = ">=0.5.4" 12 | leather = ">=0.3.2" 13 | parsedatetime = ">=2.1,<2.5 || >2.5,<2.6 || >2.6" 14 | python-slugify = ">=1.2.1" 15 | pytimeparse = ">=1.1.5" 16 | six = ">=1.9.0" 17 | 18 | [package.extras] 19 | docs = ["Sphinx (>=1.2.2)", "sphinx-rtd-theme (>=0.1.6)"] 20 | test = ["coverage (>=3.7.1)", "cssselect (>=0.9.1)", "lxml (>=3.6.0)", "nose (>=1.1.2)", "pytz (>=2015.4)", "mock (>=1.3.0)", "unittest2 (>=1.1.0)", "PyICU (>=2.4.2)"] 21 | 22 | [[package]] 23 | name = "asn1crypto" 24 | version = "1.5.1" 25 | description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" 26 | category = "main" 27 | optional = false 28 | python-versions = "*" 29 | 30 | [[package]] 31 | name = "attrs" 32 | version = "22.1.0" 33 | description = "Classes Without Boilerplate" 34 | category = "main" 35 | optional = false 36 | python-versions = ">=3.5" 37 | 38 | [package.extras] 39 | dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] 40 | docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] 41 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] 42 | tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"] 43 | 44 | [[package]] 45 | name = "babel" 46 | version = "2.11.0" 47 | description = "Internationalization utilities" 48 | category = "main" 49 | optional = false 50 | python-versions = ">=3.6" 51 | 52 | [package.dependencies] 53 | pytz = ">=2015.7" 54 | 55 | [[package]] 56 | name = "boto3" 57 | version = "1.26.8" 58 | description = "The AWS SDK for Python" 59 | category = "main" 60 | optional = false 61 | python-versions = ">= 3.7" 62 | 63 | [package.dependencies] 64 | botocore = ">=1.29.8,<1.30.0" 65 | jmespath = ">=0.7.1,<2.0.0" 66 | s3transfer = ">=0.6.0,<0.7.0" 67 | 68 | [package.extras] 69 | crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] 70 | 71 | [[package]] 72 | name = "botocore" 73 | version = "1.29.8" 74 | description = "Low-level, data-driven core of boto 3." 75 | category = "main" 76 | optional = false 77 | python-versions = ">= 3.7" 78 | 79 | [package.dependencies] 80 | jmespath = ">=0.7.1,<2.0.0" 81 | python-dateutil = ">=2.1,<3.0.0" 82 | urllib3 = ">=1.25.4,<1.27" 83 | 84 | [package.extras] 85 | crt = ["awscrt (==0.14.0)"] 86 | 87 | [[package]] 88 | name = "certifi" 89 | version = "2022.9.24" 90 | description = "Python package for providing Mozilla's CA Bundle." 91 | category = "main" 92 | optional = false 93 | python-versions = ">=3.6" 94 | 95 | [[package]] 96 | name = "cffi" 97 | version = "1.15.1" 98 | description = "Foreign Function Interface for Python calling C code." 99 | category = "main" 100 | optional = false 101 | python-versions = "*" 102 | 103 | [package.dependencies] 104 | pycparser = "*" 105 | 106 | [[package]] 107 | name = "charset-normalizer" 108 | version = "2.1.1" 109 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 110 | category = "main" 111 | optional = false 112 | python-versions = ">=3.6.0" 113 | 114 | [package.extras] 115 | unicode_backport = ["unicodedata2"] 116 | 117 | [[package]] 118 | name = "click" 119 | version = "8.1.3" 120 | description = "Composable command line interface toolkit" 121 | category = "main" 122 | optional = false 123 | python-versions = ">=3.7" 124 | 125 | [package.dependencies] 126 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 127 | 128 | [[package]] 129 | name = "colorama" 130 | version = "0.4.5" 131 | description = "Cross-platform colored terminal text." 132 | category = "main" 133 | optional = false 134 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 135 | 136 | [[package]] 137 | name = "cryptography" 138 | version = "36.0.2" 139 | description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." 140 | category = "main" 141 | optional = false 142 | python-versions = ">=3.6" 143 | 144 | [package.dependencies] 145 | cffi = ">=1.12" 146 | 147 | [package.extras] 148 | docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] 149 | docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] 150 | pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] 151 | sdist = ["setuptools_rust (>=0.11.4)"] 152 | ssh = ["bcrypt (>=3.1.5)"] 153 | test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] 154 | 155 | [[package]] 156 | name = "dbt-core" 157 | version = "1.3.0" 158 | description = "With dbt, data analysts and engineers can build analytics the way engineers build applications." 159 | category = "main" 160 | optional = false 161 | python-versions = ">=3.7.2" 162 | 163 | [package.dependencies] 164 | agate = ">=1.6,<1.6.4" 165 | cffi = ">=1.9,<2.0.0" 166 | click = ">=7.0,<9" 167 | colorama = ">=0.3.9,<0.4.6" 168 | dbt-extractor = ">=0.4.1,<0.5.0" 169 | hologram = ">=0.0.14,<=0.0.15" 170 | idna = ">=2.5,<4" 171 | isodate = ">=0.6,<0.7" 172 | Jinja2 = "3.1.2" 173 | logbook = ">=1.5,<1.6" 174 | mashumaro = {version = "3.0.4", extras = ["msgpack"]} 175 | minimal-snowplow-tracker = "0.0.2" 176 | networkx = {version = ">=2.3,<3", markers = "python_version >= \"3.8\""} 177 | packaging = ">=20.9,<22.0" 178 | pathspec = ">=0.9.0,<0.10.0" 179 | pyyaml = ">=6.0" 180 | requests = "<3.0.0" 181 | sqlparse = ">=0.2.3,<0.5" 182 | typing-extensions = ">=3.7.4" 183 | werkzeug = ">=1,<3" 184 | 185 | [[package]] 186 | name = "dbt-extractor" 187 | version = "0.4.1" 188 | description = "A tool to analyze and extract information from Jinja used in dbt projects." 189 | category = "main" 190 | optional = false 191 | python-versions = ">=3.6.1" 192 | 193 | [[package]] 194 | name = "dbt-postgres" 195 | version = "1.3.0" 196 | description = "The postgres adapter plugin for dbt (data build tool)" 197 | category = "main" 198 | optional = false 199 | python-versions = ">=3.7" 200 | 201 | [package.dependencies] 202 | dbt-core = "1.3.0" 203 | psycopg2-binary = ">=2.8,<3.0" 204 | 205 | [[package]] 206 | name = "dbt-redshift" 207 | version = "1.3.0" 208 | description = "The Redshift adapter plugin for dbt" 209 | category = "main" 210 | optional = false 211 | python-versions = ">=3.7" 212 | 213 | [package.dependencies] 214 | boto3 = ">=1.4.4,<2.0.0" 215 | dbt-core = ">=1.3.0,<1.4.0" 216 | dbt-postgres = ">=1.3.0,<1.4.0" 217 | 218 | [[package]] 219 | name = "dbt-snowflake" 220 | version = "1.3.0" 221 | description = "The Snowflake adapter plugin for dbt" 222 | category = "main" 223 | optional = false 224 | python-versions = ">=3.7" 225 | 226 | [package.dependencies] 227 | cryptography = ">=3.2,<37.0.0" 228 | dbt-core = ">=1.3.0,<1.4.0" 229 | requests = "<3.0.0" 230 | snowflake-connector-python = {version = ">=2.4.1,<2.8.0", extras = ["secure-local-storage"]} 231 | 232 | [[package]] 233 | name = "filelock" 234 | version = "3.8.0" 235 | description = "A platform independent file lock." 236 | category = "main" 237 | optional = false 238 | python-versions = ">=3.7" 239 | 240 | [package.extras] 241 | docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"] 242 | testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"] 243 | 244 | [[package]] 245 | name = "future" 246 | version = "0.18.2" 247 | description = "Clean single-source support for Python 3 and 2" 248 | category = "main" 249 | optional = false 250 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 251 | 252 | [[package]] 253 | name = "hologram" 254 | version = "0.0.15" 255 | description = "JSON schema generation from dataclasses" 256 | category = "main" 257 | optional = false 258 | python-versions = "*" 259 | 260 | [package.dependencies] 261 | jsonschema = ">=3.0,<4.0" 262 | python-dateutil = ">=2.8,<2.9" 263 | 264 | [[package]] 265 | name = "idna" 266 | version = "3.4" 267 | description = "Internationalized Domain Names in Applications (IDNA)" 268 | category = "main" 269 | optional = false 270 | python-versions = ">=3.5" 271 | 272 | [[package]] 273 | name = "importlib-metadata" 274 | version = "5.0.0" 275 | description = "Read metadata from Python packages" 276 | category = "main" 277 | optional = false 278 | python-versions = ">=3.7" 279 | 280 | [package.dependencies] 281 | zipp = ">=0.5" 282 | 283 | [package.extras] 284 | docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] 285 | perf = ["ipython"] 286 | testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] 287 | 288 | [[package]] 289 | name = "isodate" 290 | version = "0.6.1" 291 | description = "An ISO 8601 date/time/duration parser and formatter" 292 | category = "main" 293 | optional = false 294 | python-versions = "*" 295 | 296 | [package.dependencies] 297 | six = "*" 298 | 299 | [[package]] 300 | name = "jaraco.classes" 301 | version = "3.2.3" 302 | description = "Utility functions for Python class constructs" 303 | category = "main" 304 | optional = false 305 | python-versions = ">=3.7" 306 | 307 | [package.dependencies] 308 | more-itertools = "*" 309 | 310 | [package.extras] 311 | docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] 312 | testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] 313 | 314 | [[package]] 315 | name = "jeepney" 316 | version = "0.8.0" 317 | description = "Low-level, pure Python DBus protocol wrapper." 318 | category = "main" 319 | optional = false 320 | python-versions = ">=3.7" 321 | 322 | [package.extras] 323 | test = ["pytest", "pytest-trio", "pytest-asyncio (>=0.17)", "testpath", "trio", "async-timeout"] 324 | trio = ["trio", "async-generator"] 325 | 326 | [[package]] 327 | name = "jinja2" 328 | version = "3.1.2" 329 | description = "A very fast and expressive template engine." 330 | category = "main" 331 | optional = false 332 | python-versions = ">=3.7" 333 | 334 | [package.dependencies] 335 | MarkupSafe = ">=2.0" 336 | 337 | [package.extras] 338 | i18n = ["Babel (>=2.7)"] 339 | 340 | [[package]] 341 | name = "jmespath" 342 | version = "1.0.1" 343 | description = "JSON Matching Expressions" 344 | category = "main" 345 | optional = false 346 | python-versions = ">=3.7" 347 | 348 | [[package]] 349 | name = "jsonschema" 350 | version = "3.2.0" 351 | description = "An implementation of JSON Schema validation for Python" 352 | category = "main" 353 | optional = false 354 | python-versions = "*" 355 | 356 | [package.dependencies] 357 | attrs = ">=17.4.0" 358 | pyrsistent = ">=0.14.0" 359 | six = ">=1.11.0" 360 | 361 | [package.extras] 362 | format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] 363 | format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"] 364 | 365 | [[package]] 366 | name = "keyring" 367 | version = "23.11.0" 368 | description = "Store and access your passwords safely." 369 | category = "main" 370 | optional = false 371 | python-versions = ">=3.7" 372 | 373 | [package.dependencies] 374 | importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} 375 | "jaraco.classes" = "*" 376 | jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} 377 | pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""} 378 | SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} 379 | 380 | [package.extras] 381 | docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] 382 | testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] 383 | 384 | [[package]] 385 | name = "leather" 386 | version = "0.3.4" 387 | description = "Python charting for 80% of humans." 388 | category = "main" 389 | optional = false 390 | python-versions = "*" 391 | 392 | [package.dependencies] 393 | six = ">=1.6.1" 394 | 395 | [[package]] 396 | name = "logbook" 397 | version = "1.5.3" 398 | description = "A logging replacement for Python" 399 | category = "main" 400 | optional = false 401 | python-versions = "*" 402 | 403 | [package.extras] 404 | all = ["redis", "brotli", "pytest (>4.0)", "execnet (>=1.0.9)", "cython", "pyzmq", "pytest-cov (>=2.6)", "sqlalchemy", "jinja2"] 405 | compression = ["brotli"] 406 | dev = ["pytest-cov (>=2.6)", "pytest (>4.0)", "cython"] 407 | execnet = ["execnet (>=1.0.9)"] 408 | jinja = ["jinja2"] 409 | redis = ["redis"] 410 | sqlalchemy = ["sqlalchemy"] 411 | test = ["pytest-cov (>=2.6)", "pytest (>4.0)"] 412 | zmq = ["pyzmq"] 413 | 414 | [[package]] 415 | name = "markupsafe" 416 | version = "2.1.1" 417 | description = "Safely add untrusted strings to HTML/XML markup." 418 | category = "main" 419 | optional = false 420 | python-versions = ">=3.7" 421 | 422 | [[package]] 423 | name = "mashumaro" 424 | version = "3.0.4" 425 | description = "Fast serialization framework on top of dataclasses" 426 | category = "main" 427 | optional = false 428 | python-versions = ">=3.6" 429 | 430 | [package.dependencies] 431 | msgpack = {version = ">=0.5.6", optional = true, markers = "extra == \"msgpack\""} 432 | typing-extensions = "*" 433 | 434 | [package.extras] 435 | msgpack = ["msgpack (>=0.5.6)"] 436 | yaml = ["pyyaml (>=3.13)"] 437 | 438 | [[package]] 439 | name = "minimal-snowplow-tracker" 440 | version = "0.0.2" 441 | description = "A minimal snowplow event tracker for Python. Add analytics to your Python and Django apps, webapps and games" 442 | category = "main" 443 | optional = false 444 | python-versions = "*" 445 | 446 | [package.dependencies] 447 | requests = ">=2.2.1,<3.0" 448 | six = ">=1.9.0,<2.0" 449 | 450 | [[package]] 451 | name = "more-itertools" 452 | version = "9.0.0" 453 | description = "More routines for operating on iterables, beyond itertools" 454 | category = "main" 455 | optional = false 456 | python-versions = ">=3.7" 457 | 458 | [[package]] 459 | name = "msgpack" 460 | version = "1.0.4" 461 | description = "MessagePack serializer" 462 | category = "main" 463 | optional = false 464 | python-versions = "*" 465 | 466 | [[package]] 467 | name = "networkx" 468 | version = "2.8.8" 469 | description = "Python package for creating and manipulating graphs and networks" 470 | category = "main" 471 | optional = false 472 | python-versions = ">=3.8" 473 | 474 | [package.extras] 475 | default = ["numpy (>=1.19)", "scipy (>=1.8)", "matplotlib (>=3.4)", "pandas (>=1.3)"] 476 | developer = ["pre-commit (>=2.20)", "mypy (>=0.982)"] 477 | doc = ["sphinx (>=5.2)", "pydata-sphinx-theme (>=0.11)", "sphinx-gallery (>=0.11)", "numpydoc (>=1.5)", "pillow (>=9.2)", "nb2plots (>=0.6)", "texext (>=0.6.6)"] 478 | extra = ["lxml (>=4.6)", "pygraphviz (>=1.9)", "pydot (>=1.4.2)", "sympy (>=1.10)"] 479 | test = ["pytest (>=7.2)", "pytest-cov (>=4.0)", "codecov (>=2.1)"] 480 | 481 | [[package]] 482 | name = "oscrypto" 483 | version = "1.3.0" 484 | description = "TLS (SSL) sockets, key generation, encryption, decryption, signing, verification and KDFs using the OS crypto libraries. Does not require a compiler, and relies on the OS for patching. Works on Windows, OS X and Linux/BSD." 485 | category = "main" 486 | optional = false 487 | python-versions = "*" 488 | 489 | [package.dependencies] 490 | asn1crypto = ">=1.5.1" 491 | 492 | [[package]] 493 | name = "packaging" 494 | version = "21.3" 495 | description = "Core utilities for Python packages" 496 | category = "main" 497 | optional = false 498 | python-versions = ">=3.6" 499 | 500 | [package.dependencies] 501 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" 502 | 503 | [[package]] 504 | name = "parsedatetime" 505 | version = "2.4" 506 | description = "Parse human-readable date/time text." 507 | category = "main" 508 | optional = false 509 | python-versions = "*" 510 | 511 | [package.dependencies] 512 | future = "*" 513 | 514 | [[package]] 515 | name = "pathspec" 516 | version = "0.9.0" 517 | description = "Utility library for gitignore style pattern matching of file paths." 518 | category = "main" 519 | optional = false 520 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 521 | 522 | [[package]] 523 | name = "psycopg2-binary" 524 | version = "2.9.5" 525 | description = "psycopg2 - Python-PostgreSQL Database Adapter" 526 | category = "main" 527 | optional = false 528 | python-versions = ">=3.6" 529 | 530 | [[package]] 531 | name = "pycparser" 532 | version = "2.21" 533 | description = "C parser in Python" 534 | category = "main" 535 | optional = false 536 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 537 | 538 | [[package]] 539 | name = "pycryptodomex" 540 | version = "3.15.0" 541 | description = "Cryptographic library for Python" 542 | category = "main" 543 | optional = false 544 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 545 | 546 | [[package]] 547 | name = "pyjwt" 548 | version = "2.6.0" 549 | description = "JSON Web Token implementation in Python" 550 | category = "main" 551 | optional = false 552 | python-versions = ">=3.7" 553 | 554 | [package.extras] 555 | crypto = ["cryptography (>=3.4.0)"] 556 | dev = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.4.0)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "pre-commit"] 557 | docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"] 558 | tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"] 559 | 560 | [[package]] 561 | name = "pyopenssl" 562 | version = "22.0.0" 563 | description = "Python wrapper module around the OpenSSL library" 564 | category = "main" 565 | optional = false 566 | python-versions = ">=3.6" 567 | 568 | [package.dependencies] 569 | cryptography = ">=35.0" 570 | 571 | [package.extras] 572 | docs = ["sphinx", "sphinx-rtd-theme"] 573 | test = ["flaky", "pretend", "pytest (>=3.0.1)"] 574 | 575 | [[package]] 576 | name = "pyparsing" 577 | version = "3.0.9" 578 | description = "pyparsing module - Classes and methods to define and execute parsing grammars" 579 | category = "main" 580 | optional = false 581 | python-versions = ">=3.6.8" 582 | 583 | [package.extras] 584 | diagrams = ["railroad-diagrams", "jinja2"] 585 | 586 | [[package]] 587 | name = "pyrsistent" 588 | version = "0.19.2" 589 | description = "Persistent/Functional/Immutable data structures" 590 | category = "main" 591 | optional = false 592 | python-versions = ">=3.7" 593 | 594 | [[package]] 595 | name = "python-dateutil" 596 | version = "2.8.2" 597 | description = "Extensions to the standard Python datetime module" 598 | category = "main" 599 | optional = false 600 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 601 | 602 | [package.dependencies] 603 | six = ">=1.5" 604 | 605 | [[package]] 606 | name = "python-slugify" 607 | version = "6.1.2" 608 | description = "A Python slugify application that also handles Unicode" 609 | category = "main" 610 | optional = false 611 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" 612 | 613 | [package.dependencies] 614 | text-unidecode = ">=1.3" 615 | 616 | [package.extras] 617 | unidecode = ["Unidecode (>=1.1.1)"] 618 | 619 | [[package]] 620 | name = "pytimeparse" 621 | version = "1.1.8" 622 | description = "Time expression parser" 623 | category = "main" 624 | optional = false 625 | python-versions = "*" 626 | 627 | [[package]] 628 | name = "pytz" 629 | version = "2022.6" 630 | description = "World timezone definitions, modern and historical" 631 | category = "main" 632 | optional = false 633 | python-versions = "*" 634 | 635 | [[package]] 636 | name = "pywin32-ctypes" 637 | version = "0.2.0" 638 | description = "" 639 | category = "main" 640 | optional = false 641 | python-versions = "*" 642 | 643 | [[package]] 644 | name = "pyyaml" 645 | version = "6.0" 646 | description = "YAML parser and emitter for Python" 647 | category = "main" 648 | optional = false 649 | python-versions = ">=3.6" 650 | 651 | [[package]] 652 | name = "requests" 653 | version = "2.28.1" 654 | description = "Python HTTP for Humans." 655 | category = "main" 656 | optional = false 657 | python-versions = ">=3.7, <4" 658 | 659 | [package.dependencies] 660 | certifi = ">=2017.4.17" 661 | charset-normalizer = ">=2,<3" 662 | idna = ">=2.5,<4" 663 | urllib3 = ">=1.21.1,<1.27" 664 | 665 | [package.extras] 666 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 667 | use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] 668 | 669 | [[package]] 670 | name = "s3transfer" 671 | version = "0.6.0" 672 | description = "An Amazon S3 Transfer Manager" 673 | category = "main" 674 | optional = false 675 | python-versions = ">= 3.7" 676 | 677 | [package.dependencies] 678 | botocore = ">=1.12.36,<2.0a.0" 679 | 680 | [package.extras] 681 | crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] 682 | 683 | [[package]] 684 | name = "secretstorage" 685 | version = "3.3.3" 686 | description = "Python bindings to FreeDesktop.org Secret Service API" 687 | category = "main" 688 | optional = false 689 | python-versions = ">=3.6" 690 | 691 | [package.dependencies] 692 | cryptography = ">=2.0" 693 | jeepney = ">=0.6" 694 | 695 | [[package]] 696 | name = "six" 697 | version = "1.16.0" 698 | description = "Python 2 and 3 compatibility utilities" 699 | category = "main" 700 | optional = false 701 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 702 | 703 | [[package]] 704 | name = "snowflake-connector-python" 705 | version = "2.7.12" 706 | description = "Snowflake Connector for Python" 707 | category = "main" 708 | optional = false 709 | python-versions = ">=3.7" 710 | 711 | [package.dependencies] 712 | asn1crypto = ">0.24.0,<2.0.0" 713 | certifi = ">=2017.4.17" 714 | cffi = ">=1.9,<2.0.0" 715 | charset-normalizer = ">=2,<3" 716 | cryptography = ">=3.1.0,<37.0.0" 717 | filelock = ">=3.5,<4" 718 | idna = ">=2.5,<4" 719 | keyring = {version = "<16.1.0 || >16.1.0,<24.0.0", optional = true, markers = "extra == \"secure-local-storage\""} 720 | oscrypto = "<2.0.0" 721 | pycryptodomex = ">=3.2,<3.5.0 || >3.5.0,<4.0.0" 722 | pyjwt = "<3.0.0" 723 | pyOpenSSL = ">=16.2.0,<23.0.0" 724 | pytz = "*" 725 | requests = "<3.0.0" 726 | typing-extensions = ">=4.3,<5" 727 | urllib3 = ">=1.21.1,<1.27" 728 | 729 | [package.extras] 730 | development = ["cython", "coverage", "more-itertools", "numpy (<1.24.0)", "pendulum (!=2.1.1)", "pexpect", "pytest (<7.2.0)", "pytest-cov", "pytest-rerunfailures", "pytest-timeout", "pytest-xdist", "pytzdata"] 731 | pandas = ["pandas (>=1.0.0,<1.5.0)", "pyarrow (>=8.0.0,<8.1.0)"] 732 | secure-local-storage = ["keyring (!=16.1.0,<24.0.0)"] 733 | 734 | [[package]] 735 | name = "sqlparse" 736 | version = "0.4.3" 737 | description = "A non-validating SQL parser." 738 | category = "main" 739 | optional = false 740 | python-versions = ">=3.5" 741 | 742 | [[package]] 743 | name = "text-unidecode" 744 | version = "1.3" 745 | description = "The most basic Text::Unidecode port" 746 | category = "main" 747 | optional = false 748 | python-versions = "*" 749 | 750 | [[package]] 751 | name = "typing-extensions" 752 | version = "4.4.0" 753 | description = "Backported and Experimental Type Hints for Python 3.7+" 754 | category = "main" 755 | optional = false 756 | python-versions = ">=3.7" 757 | 758 | [[package]] 759 | name = "urllib3" 760 | version = "1.26.12" 761 | description = "HTTP library with thread-safe connection pooling, file post, and more." 762 | category = "main" 763 | optional = false 764 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" 765 | 766 | [package.extras] 767 | brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] 768 | secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] 769 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 770 | 771 | [[package]] 772 | name = "werkzeug" 773 | version = "2.2.2" 774 | description = "The comprehensive WSGI web application library." 775 | category = "main" 776 | optional = false 777 | python-versions = ">=3.7" 778 | 779 | [package.dependencies] 780 | MarkupSafe = ">=2.1.1" 781 | 782 | [package.extras] 783 | watchdog = ["watchdog"] 784 | 785 | [[package]] 786 | name = "zipp" 787 | version = "3.10.0" 788 | description = "Backport of pathlib-compatible object wrapper for zip files" 789 | category = "main" 790 | optional = false 791 | python-versions = ">=3.7" 792 | 793 | [package.extras] 794 | docs = ["sphinx (>=3.5)", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "furo", "jaraco.tidelift (>=1.4)"] 795 | testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "flake8 (<5)", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "jaraco.functools", "more-itertools", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] 796 | 797 | [metadata] 798 | lock-version = "1.1" 799 | python-versions = "^3.9" 800 | content-hash = "691df7d18dd3f592ea335c7951361f0d87381b64f916785b340471ef7292db96" 801 | 802 | [metadata.files] 803 | agate = [] 804 | asn1crypto = [] 805 | attrs = [] 806 | babel = [] 807 | boto3 = [] 808 | botocore = [] 809 | certifi = [] 810 | cffi = [] 811 | charset-normalizer = [] 812 | click = [] 813 | colorama = [] 814 | cryptography = [] 815 | dbt-core = [] 816 | dbt-extractor = [] 817 | dbt-postgres = [] 818 | dbt-redshift = [] 819 | dbt-snowflake = [] 820 | filelock = [] 821 | future = [] 822 | hologram = [] 823 | idna = [] 824 | importlib-metadata = [] 825 | isodate = [] 826 | "jaraco.classes" = [] 827 | jeepney = [] 828 | jinja2 = [] 829 | jmespath = [] 830 | jsonschema = [] 831 | keyring = [] 832 | leather = [] 833 | logbook = [] 834 | markupsafe = [] 835 | mashumaro = [] 836 | minimal-snowplow-tracker = [] 837 | more-itertools = [] 838 | msgpack = [] 839 | networkx = [] 840 | oscrypto = [] 841 | packaging = [] 842 | parsedatetime = [] 843 | pathspec = [] 844 | psycopg2-binary = [] 845 | pycparser = [] 846 | pycryptodomex = [] 847 | pyjwt = [] 848 | pyopenssl = [] 849 | pyparsing = [] 850 | pyrsistent = [] 851 | python-dateutil = [] 852 | python-slugify = [] 853 | pytimeparse = [] 854 | pytz = [] 855 | pywin32-ctypes = [] 856 | pyyaml = [] 857 | requests = [] 858 | s3transfer = [] 859 | secretstorage = [] 860 | six = [] 861 | snowflake-connector-python = [] 862 | sqlparse = [] 863 | text-unidecode = [] 864 | typing-extensions = [] 865 | urllib3 = [] 866 | werkzeug = [] 867 | zipp = [] 868 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "template-dbt-docker" 3 | version = "1.0.0" 4 | description = "A starting point for dockerized dbt development." 5 | authors = ["Teghan Nightengale "] 6 | license = "MIT" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.9" 10 | dbt-core = "^1.3.0" 11 | dbt-snowflake = "^1.3.0" 12 | 13 | [tool.poetry.dev-dependencies] 14 | 15 | [build-system] 16 | requires = ["poetry-core>=1.0.0"] 17 | build-backend = "poetry.core.masonry.api" 18 | -------------------------------------------------------------------------------- /scripts/dev_container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | get_host_architecture_for_debian_packages() { 4 | if [[ $(uname -m) == 'arm64' ]]; then 5 | echo arm64 6 | else 7 | echo amd64 8 | fi 9 | } 10 | 11 | initialize() { 12 | # Write .arch 13 | get_host_architecture_for_debian_packages > .devcontainer/.arch 14 | } 15 | 16 | post_attach() { 17 | # Used to apply secrets from the VS Code Remote Container to the SQLTool 18 | # extension settings. Unfortunately, the SQLTools extension does not support 19 | # reading using VS Code environment variables. See here for more details: 20 | # https://github.com/mtxr/vscode-sqltools/issues/452 21 | 22 | CONTAINER_SETTINGS_PATH=/root/.vscode-server/data/Machine/settings.json 23 | TEMP=$CONTAINER_SETTINGS_PATH.temp 24 | 25 | jq --arg var "$SNOWFLAKE_ACCOUNT" '."sqltools.connections"[0].server = $var' $CONTAINER_SETTINGS_PATH > $TEMP && mv $TEMP $CONTAINER_SETTINGS_PATH 26 | jq --arg var "$SNOWFLAKE_USER" '."sqltools.connections"[0].database = $var' $CONTAINER_SETTINGS_PATH > $TEMP && mv $TEMP $CONTAINER_SETTINGS_PATH 27 | jq --arg var "$SNOWFLAKE_DATABASE" '."sqltools.connections"[0].username = $var' $CONTAINER_SETTINGS_PATH > $TEMP && mv $TEMP $CONTAINER_SETTINGS_PATH 28 | jq --arg var "$SNOWFLAKE_PASSWORD" '."sqltools.connections"[0].password = $var' $CONTAINER_SETTINGS_PATH > $TEMP && mv $TEMP $CONTAINER_SETTINGS_PATH 29 | jq --arg var "$SNOWFLAKE_WAREHOUSE" '."sqltools.connections"[0].password = $var' $CONTAINER_SETTINGS_PATH > $TEMP && mv $TEMP $CONTAINER_SETTINGS_PATH 30 | } 31 | 32 | "$@" 33 | --------------------------------------------------------------------------------