From e30180a17e27dc070b404ea85235385d73c9c273 Mon Sep 17 00:00:00 2001 From: z3z1ma Date: Thu, 30 Mar 2023 01:53:42 -0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20complete=20overhaul=20of=20workbenc?= =?UTF-8?q?h=202.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changes/0.11.12.md | 3 + CHANGELOG.md | 4 + poetry.lock | 220 +++++++------- pyproject.toml | 6 +- src/dbt_osmosis/app_v2.py | 386 ++++++++++++++++++++++++ src/dbt_osmosis/components/dashboard.py | 61 ++++ src/dbt_osmosis/components/editor.py | 113 +++++++ src/dbt_osmosis/components/feed.py | 47 +++ src/dbt_osmosis/components/preview.py | 56 ++++ src/dbt_osmosis/components/profiler.py | 45 +++ src/dbt_osmosis/components/renderer.py | 62 ++++ src/dbt_osmosis/main.py | 2 +- 12 files changed, 891 insertions(+), 114 deletions(-) create mode 100644 .changes/0.11.12.md create mode 100644 src/dbt_osmosis/app_v2.py create mode 100644 src/dbt_osmosis/components/dashboard.py create mode 100644 src/dbt_osmosis/components/editor.py create mode 100644 src/dbt_osmosis/components/feed.py create mode 100644 src/dbt_osmosis/components/preview.py create mode 100644 src/dbt_osmosis/components/profiler.py create mode 100644 src/dbt_osmosis/components/renderer.py diff --git a/.changes/0.11.12.md b/.changes/0.11.12.md new file mode 100644 index 0000000..c2fef79 --- /dev/null +++ b/.changes/0.11.12.md @@ -0,0 +1,3 @@ +## 0.11.12 - 2023-03-30 +### Added +* Rebuilt the dbt osmosis workbench with a complete overhaul diff --git a/CHANGELOG.md b/CHANGELOG.md index 19e68c9..17bf9fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## 0.11.12 - 2023-03-30 +### Added +* Rebuilt the dbt osmosis workbench with a complete overhaul + ## 0.11.11 - 2023-03-28 ### Fixed * Ensure pre-commit hook returns non-zero on file mutations diff --git a/poetry.lock b/poetry.lock index 2c2e70f..d2a49fc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -65,14 +65,14 @@ test = ["coverage", "flake8", "mypy", "pexpect", "wheel"] [[package]] name = "astroid" -version = "2.15.0" +version = "2.15.1" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.7.2" files = [ - {file = "astroid-2.15.0-py3-none-any.whl", hash = "sha256:e3e4d0ffc2d15d954065579689c36aac57a339a4679a679579af6401db4d3fdb"}, - {file = "astroid-2.15.0.tar.gz", hash = "sha256:525f126d5dc1b8b0b6ee398b33159105615d92dc4a17f2cd064125d57f6186fa"}, + {file = "astroid-2.15.1-py3-none-any.whl", hash = "sha256:89860bda98fe2bbd1f5d262229be7629d778ce280de68d95d4a73d1f592ad268"}, + {file = "astroid-2.15.1.tar.gz", hash = "sha256:af4e0aff46e2868218502789898269ed95b663fba49e65d91c1e09c966266c34"}, ] [package.dependencies] @@ -163,37 +163,37 @@ compiler = ["black", "jinja2", "protobuf"] [[package]] name = "black" -version = "23.1.0" +version = "23.3.0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"}, - {file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"}, - {file = "black-23.1.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:9880d7d419bb7e709b37e28deb5e68a49227713b623c72b2b931028ea65f619b"}, - {file = "black-23.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6663f91b6feca5d06f2ccd49a10f254f9298cc1f7f49c46e498a0771b507104"}, - {file = "black-23.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9afd3f493666a0cd8f8df9a0200c6359ac53940cbde049dcb1a7eb6ee2dd7074"}, - {file = "black-23.1.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:bfffba28dc52a58f04492181392ee380e95262af14ee01d4bc7bb1b1c6ca8d27"}, - {file = "black-23.1.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c1c476bc7b7d021321e7d93dc2cbd78ce103b84d5a4cf97ed535fbc0d6660648"}, - {file = "black-23.1.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:382998821f58e5c8238d3166c492139573325287820963d2f7de4d518bd76958"}, - {file = "black-23.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf649fda611c8550ca9d7592b69f0637218c2369b7744694c5e4902873b2f3a"}, - {file = "black-23.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:121ca7f10b4a01fd99951234abdbd97728e1240be89fde18480ffac16503d481"}, - {file = "black-23.1.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:a8471939da5e824b891b25751955be52ee7f8a30a916d570a5ba8e0f2eb2ecad"}, - {file = "black-23.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8178318cb74f98bc571eef19068f6ab5613b3e59d4f47771582f04e175570ed8"}, - {file = "black-23.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a436e7881d33acaf2536c46a454bb964a50eff59b21b51c6ccf5a40601fbef24"}, - {file = "black-23.1.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:a59db0a2094d2259c554676403fa2fac3473ccf1354c1c63eccf7ae65aac8ab6"}, - {file = "black-23.1.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:0052dba51dec07ed029ed61b18183942043e00008ec65d5028814afaab9a22fd"}, - {file = "black-23.1.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:49f7b39e30f326a34b5c9a4213213a6b221d7ae9d58ec70df1c4a307cf2a1580"}, - {file = "black-23.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:162e37d49e93bd6eb6f1afc3e17a3d23a823042530c37c3c42eeeaf026f38468"}, - {file = "black-23.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b70eb40a78dfac24842458476135f9b99ab952dd3f2dab738c1881a9b38b753"}, - {file = "black-23.1.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:a29650759a6a0944e7cca036674655c2f0f63806ddecc45ed40b7b8aa314b651"}, - {file = "black-23.1.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:bb460c8561c8c1bec7824ecbc3ce085eb50005883a6203dcfb0122e95797ee06"}, - {file = "black-23.1.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c91dfc2c2a4e50df0026f88d2215e166616e0c80e86004d0003ece0488db2739"}, - {file = "black-23.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a951cc83ab535d248c89f300eccbd625e80ab880fbcfb5ac8afb5f01a258ac9"}, - {file = "black-23.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0680d4380db3719ebcfb2613f34e86c8e6d15ffeabcf8ec59355c5e7b85bb555"}, - {file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"}, - {file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, + {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, + {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, + {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, + {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, + {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, + {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, + {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, + {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, + {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, + {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, + {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, + {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, + {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, + {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, + {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, + {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, + {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, ] [package.dependencies] @@ -857,14 +857,14 @@ sgmllib3k = "*" [[package]] name = "filelock" -version = "3.10.6" +version = "3.10.7" description = "A platform independent file lock." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "filelock-3.10.6-py3-none-any.whl", hash = "sha256:52f119747b2b9c4730dac715a7b1ab34b8ee70fd9259cba158ee53da566387ff"}, - {file = "filelock-3.10.6.tar.gz", hash = "sha256:409105becd604d6b176a483f855e7e8903c5cb2873e47f2c64f66a370c046aaf"}, + {file = "filelock-3.10.7-py3-none-any.whl", hash = "sha256:bde48477b15fde2c7e5a0713cbe72721cb5a5ad32ee0b8f419907960b9d75536"}, + {file = "filelock-3.10.7.tar.gz", hash = "sha256:892be14aa8efc01673b5ed6589dbccb95f9a8596f0507e232626155495c18105"}, ] [package.extras] @@ -873,14 +873,14 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.2)", "diff-cover (>=7.5)", "p [[package]] name = "fonttools" -version = "4.39.2" +version = "4.39.3" description = "Tools to manipulate font files" category = "main" optional = true python-versions = ">=3.8" files = [ - {file = "fonttools-4.39.2-py3-none-any.whl", hash = "sha256:85245aa2fd4cf502a643c9a9a2b5a393703e150a6eaacc3e0e84bb448053f061"}, - {file = "fonttools-4.39.2.zip", hash = "sha256:e2d9f10337c9e3b17f9bce17a60a16a885a7d23b59b7f45ce07ea643e5580439"}, + {file = "fonttools-4.39.3-py3-none-any.whl", hash = "sha256:64c0c05c337f826183637570ac5ab49ee220eec66cf50248e8df527edfa95aeb"}, + {file = "fonttools-4.39.3.zip", hash = "sha256:9234b9f57b74e31b192c3fc32ef1a40750a8fbc1cd9837a7b7bfc4ca4a5c51d7"}, ] [package.extras] @@ -1867,61 +1867,61 @@ files = [ [[package]] name = "orjson" -version = "3.8.8" +version = "3.8.9" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "orjson-3.8.8-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:18fcdea75d8b571dc9b185652b81397b62878ae7934fd62e6a0103a5b8448e34"}, - {file = "orjson-3.8.8-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:306618884929b596e2e083f82b5617da812df25b0c467542371f1d51f0c5a6f5"}, - {file = "orjson-3.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edc65ddb6ae6f8fbb2bbf78ac98f75b729c9eeb0776d5508dd76d3a948dda1dd"}, - {file = "orjson-3.8.8-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e6a6d55e01bce74516dff15302627a13b1f4edcb1c3942dd660978dee423ccf2"}, - {file = "orjson-3.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28075c4b502d792fb6703e983d456b2a30d5d6f332d26092eb312dc782e64c64"}, - {file = "orjson-3.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eda4c37e48ff549763183a1549c10eec6ea40439520b17d09359cd74a425069"}, - {file = "orjson-3.8.8-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a3eac485a15493164867729f44e1e1247b3094ff19d37708e8cdc9c88a93c623"}, - {file = "orjson-3.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:88bf40e5468444c04374d1b8f1877cebbaef6bb7406cb6b4a34a570c5cbb87bc"}, - {file = "orjson-3.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:747bd4e09d8aa61e1ff677a7dd1cffd28a5d13c22f3769123c58ec988bf1b83d"}, - {file = "orjson-3.8.8-cp310-none-win_amd64.whl", hash = "sha256:dd7d86c5f5f820ac9d4783477e86eb984b63bdb32359935609eb33cf65049c54"}, - {file = "orjson-3.8.8-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:52293a6097750c2d434737966fe6e2a1ed489ac70cc8e584f5944af83de0b787"}, - {file = "orjson-3.8.8-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9322450f392dceb49810d2f820b1932af22d66f67f1d45c31f160067dd06359f"}, - {file = "orjson-3.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68d59e3ae84a9b6f14b45a89f7fde4a08a87ea5eb76bfc854b354640de8156f5"}, - {file = "orjson-3.8.8-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:022347dad2253081eaa25366834bb8b06a5aceb0e83b39c6b0aa865759e49d69"}, - {file = "orjson-3.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddfcc54793e266056fe1c257d0804c336bca1c5c1ee7979d674e1fc19cfb0a6a"}, - {file = "orjson-3.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:449d8ed1e0e6b24e9df5a06b59fd66ea7f7293e141257069601ae8ff9fad705c"}, - {file = "orjson-3.8.8-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:0204bc414bc6f7a595211569840b422d96649fd8686efa1fbbcb12eed5dd9521"}, - {file = "orjson-3.8.8-cp311-none-win_amd64.whl", hash = "sha256:e991a5c2c5f2f299c77e1d07ef2812ff5b68e1d97a2aab01aca29cf756473aa3"}, - {file = "orjson-3.8.8-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:2006d9c046bbf335c951f61e016a27bd4f17323dd116f601e4a8a11739cd0a62"}, - {file = "orjson-3.8.8-cp37-cp37m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:4553d85bad4cbd634a40b7b5d36daaa197a6025f9ce3e2165b371e528759093d"}, - {file = "orjson-3.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57ee45d2cc6c11c50afb5a0c09d7cd559aea76c77250dbe996be6a03464d4a50"}, - {file = "orjson-3.8.8-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:02f5b5db1e424706eb9f70f1c25699ff4cef16fadfc64af5b70f8628eafe4771"}, - {file = "orjson-3.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d7c9f3b1598a1ccd806ef02257a76a00c7ede09662ddb54eec2b4bd92874254"}, - {file = "orjson-3.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b90d171932b6a9d50e79fa2762cb303e3556bbf25c08bb316fe346ec58af9c19"}, - {file = "orjson-3.8.8-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:28dfe774c345130f1117c4d023644ec52d9d50e3eaadb9bd1c668d91dc109bb5"}, - {file = "orjson-3.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8f84116fcc3714e7ba3cbeb1b11ac5e4549e7d2726c50142f8299fff9dea7d53"}, - {file = "orjson-3.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f989f8580db86166aaaa938ccd1597ba1817e3f5df14c047baafe783e3d24173"}, - {file = "orjson-3.8.8-cp37-none-win_amd64.whl", hash = "sha256:66045850f286090800a18662d81d44f88c3fcb60ea3a9947d5caeab5d1efc92e"}, - {file = "orjson-3.8.8-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:2c2c5f3d3bbd61dba646e2b9c54a0dd7941b03fba49726bd31c1c23fedf0b9aa"}, - {file = "orjson-3.8.8-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9cb36d4a14f3a911369219d5abc19b907bc41ed2730f7bfe0847b0fd3e834c87"}, - {file = "orjson-3.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:343124f84da0a33c83ee106a98b3e3c42767c88323d4a2809683cbe83816e8be"}, - {file = "orjson-3.8.8-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24ad122d8dd057acf2a9965a2ffc1bc12fb310ae1cfe2912db930cbb9ef7eaba"}, - {file = "orjson-3.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2f28a92a9bcb4e8635524b20db1b539bda8613872f306b36cdfd9d3577d03ac"}, - {file = "orjson-3.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81d3c5b253eebfc4a61cea1f255a576cb2b889afa99f4510f30ec13201d4f457"}, - {file = "orjson-3.8.8-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:317164f7d4c0540a6eb8b0a0faeec84ef011d359da05188423db762b65f84e1d"}, - {file = "orjson-3.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5e7e39357371d4ae5649f33c01886508a4c8e5fa5c7344554af041dc0f004c01"}, - {file = "orjson-3.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:60fefd4bbd796b4296f478e705fe2c2c7defd28da98d3017743eb87c3238a380"}, - {file = "orjson-3.8.8-cp38-none-win_amd64.whl", hash = "sha256:0dc4a52f1087baeec6b58248fd6b01f17c124fb99f6f770596851ea434a7be0b"}, - {file = "orjson-3.8.8-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a6bcb449537a99f55c5f05187bac00b4549a795e89c10dcca0d7629548852357"}, - {file = "orjson-3.8.8-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9c98dc791aa44268ba7f6e21124cf885c813b155316c6bf257560571d243fe15"}, - {file = "orjson-3.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b2abf93b727a6af7c5ec8816168cbdff39c716af18ced425dd50ae46d69765c"}, - {file = "orjson-3.8.8-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23447d38375a19d57975d4e32d9ce9f533803c197fd4292e10d3234c052037a8"}, - {file = "orjson-3.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c2e19d2b46cc93c7218bf8180807bf922ff61dc9883458a06edc66d22970fff"}, - {file = "orjson-3.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e480d74d7bf415e6548a364669404119a85dbe0e3c6cd5f7cb4c7003eac20164"}, - {file = "orjson-3.8.8-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:8e0bff5656b99dd975cae2e5230b39e5909d06c0692fd1f6f06dc46f1fe705d0"}, - {file = "orjson-3.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56bb6eb7a254eec3b15feba9b20f4172ccbe6ea50a54cf66cbc8e1e4a19585c2"}, - {file = "orjson-3.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1af1cfad5d90b68e15fd625c889c4f9f91d7a88f49512cdb89f01c3881e0c9d9"}, - {file = "orjson-3.8.8-cp39-none-win_amd64.whl", hash = "sha256:d5514dfe200356a1d5a6039e00dca78d87d063f3da1eb6a371253e5a8b7ab5b0"}, - {file = "orjson-3.8.8.tar.gz", hash = "sha256:c096d7a523bae6ffb9c4a228ba4691d66113f0f2231579dc945523fbef09c6da"}, + {file = "orjson-3.8.9-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:5d029843eae7b6cbd6468b63517b8b61471afed6572162171d8b6471b6dbf41f"}, + {file = "orjson-3.8.9-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:405933c05490efb209d0f940d8ef1403d2932a97e47010a26d2694e9dd49f84d"}, + {file = "orjson-3.8.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:183de66eff4d41c330a3006f210ab0bce7affe398da6f6eda9579b67245a34ff"}, + {file = "orjson-3.8.9-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb4081fe340ed1df42dddfd055e1d50479cb0ccb976d13e6b5e8667a07fec6f4"}, + {file = "orjson-3.8.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d11593a2e736055dd7b9587dbf89cd1cbe4a42a70e70f186e51aee7e1b38902e"}, + {file = "orjson-3.8.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e20649359e28f34d01b2570e4650a076f439a959bae3a8bbe7f5923ad80f54e8"}, + {file = "orjson-3.8.9-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c02ece4f36a160c83efe74adfba5f189c7c7702361f02b809ab73744923ee139"}, + {file = "orjson-3.8.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f0e19801836cf1b30f333d475b05d79051b8ae8639a8e2422fb5f64e82676ae7"}, + {file = "orjson-3.8.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d4850fe5650cead3c0f8822192e381cee9d4c3b8162eb082c86c927124572dc6"}, + {file = "orjson-3.8.9-cp310-none-win_amd64.whl", hash = "sha256:5fd4193f260d9d30112b5e379d0870b54dc88040807c93cbe8d67bfea148ba5a"}, + {file = "orjson-3.8.9-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:70eae063ad8d7405dc63873760567b600fc10728ba0da24a69d49c1a5d318d6d"}, + {file = "orjson-3.8.9-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:251653437632583d02203e6b118b72b99c04425175853f35340f4bac7034a36e"}, + {file = "orjson-3.8.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ea833751f017ba321c277e7425b51c0b1a18a2c60f8c9c0f4c6c4d7e16cbd6c"}, + {file = "orjson-3.8.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8563c2cdeb923b82a5cc5bfc76c28c786777428263ee39292d928e9687165fb4"}, + {file = "orjson-3.8.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f33e9ea45b4c9457eedca0c40f38cf5732c91b0fb68f091ac59e6ea68e03eb2"}, + {file = "orjson-3.8.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855dee152daecb7de7b4cd7069d7854e11aa291687bffe8433156af0a224417e"}, + {file = "orjson-3.8.9-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:74fa9e02589339defc9d3662de9e7eef51d8f9f3a7f6304b43b18b39d7bbf10f"}, + {file = "orjson-3.8.9-cp311-none-win_amd64.whl", hash = "sha256:6c5b10ba1e62df8f96cbc37f6d5ae9acb3f6475926dea8b1b6a1a60f201a64f7"}, + {file = "orjson-3.8.9-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:a651123d01bc399fcd866e56acc2d76512e62aae3673652b13b470ea69faf1f4"}, + {file = "orjson-3.8.9-cp37-cp37m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:73019b6d2cc998c99556020c6bd8f8bc28420c69583186ca290c66a27916a3b7"}, + {file = "orjson-3.8.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f5c3daa8b02786ad5f0e14ae16a59bbb4e02cbae3a41989a25188e5a6c962ff"}, + {file = "orjson-3.8.9-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:598598b7f81f8fda7c3e09c88165f844152b7be223bc4ea929ec8ad59b00ea17"}, + {file = "orjson-3.8.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:090b10bdb06baae6d5cd3550d772ecbabd833bfceed7592ff167c0a82f5b4c20"}, + {file = "orjson-3.8.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd46f688ddf9c2ea10367446fe9bf3ceba0f7490c15b4f96420491c7f00bb283"}, + {file = "orjson-3.8.9-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:b8ed8d780e9fab01bc404a70d755a8b2b34ea6c0b6604b65de135daaaadaf9a9"}, + {file = "orjson-3.8.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8a32c9fb742868a34346f3c52e12d893a9d27f8e0c0bf3c480db7e6903d8be28"}, + {file = "orjson-3.8.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2ba366009b98ac8899e935eff6fef7672d3ea43d3ce9deb3ee33452134b6cc3a"}, + {file = "orjson-3.8.9-cp37-none-win_amd64.whl", hash = "sha256:236b9313425cb2570626c64dd5cb6caff13882d1717d491da542cff228b96e97"}, + {file = "orjson-3.8.9-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:e8efc7e9ec35336f7cc98b6692536b1262046ff1d2a545295a4d89b8a2495903"}, + {file = "orjson-3.8.9-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:8c7eba3610ae69f4aba4032ecb61b0a6fbd1e4537283d1553eb8c1cb136e9118"}, + {file = "orjson-3.8.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7742649e4c357d4e7ad483a35ff5f55d519e895de56772cc486913614ee7d23b"}, + {file = "orjson-3.8.9-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b6566fb8daa538c7848fd6822e2409a7e1c41dae8e65e6536598d505f641a318"}, + {file = "orjson-3.8.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ce8a2a667221e2e5160021e26b09e9c13eeedafb5cda1981340c8c0c0bc8f9d"}, + {file = "orjson-3.8.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0399631b88fa4868956badef2561fba07dffcaf050bf53959ee50d26edf6f6"}, + {file = "orjson-3.8.9-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:189ccb16ed140a824d133fa1c55175cf0d2207edaade54f1db0456a526cb5fd8"}, + {file = "orjson-3.8.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b707fa4481e1af19b3052ec9352c688bad3f539d7bdd8aa4a451f6dd7e4bae73"}, + {file = "orjson-3.8.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c3d988eb562da1dda7d49e9abd8a64b3cabc632b4299d177fb9e0c0ca9f06b8c"}, + {file = "orjson-3.8.9-cp38-none-win_amd64.whl", hash = "sha256:b30240eb6b22daab604f1595f6aacf92bcdac0d29e2d7ad507dfac68d2b39182"}, + {file = "orjson-3.8.9-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:81869a6de00bc676d10056fa8bb28cbe805b1cf498a45c14cb7b1765eee33fcb"}, + {file = "orjson-3.8.9-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:a25a5a215b19d414de8d416a3c5414f29165843a06f704cc0345ded9eac34ac1"}, + {file = "orjson-3.8.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec0f2bea52e30ea98ce095f1f42da04535791f9a31b2aab2499caa88307bc49"}, + {file = "orjson-3.8.9-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b91d88fe96b698b28bb1b95b1fce226f72757ab3ab7d8d97551e23bc629c84f"}, + {file = "orjson-3.8.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7629841ccdcccd3c43ebc6a4165abe9844909fcedb2041994c0153470f610801"}, + {file = "orjson-3.8.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d875b304e19f4b2758d233bbf2b9d627c66fac50b3150b8d31a35ba6cda3db67"}, + {file = "orjson-3.8.9-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:723ec880c5290fe4de330febb8030e57c1978fbd624fc5b9399969e7d7d74984"}, + {file = "orjson-3.8.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b11f8a71c82d19fce11ce487efeec2ca0dc3bcf5b4564445fecfc68d9c268744"}, + {file = "orjson-3.8.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b2079bf86dec62731c1b90fdfea3211f993f0c894d9261e0ce9b68ed9c9dfbec"}, + {file = "orjson-3.8.9-cp39-none-win_amd64.whl", hash = "sha256:97d94322a2eaab767ba8d52f6bf9d0ec0f35313fe36287be6e6085dd65d55d37"}, + {file = "orjson-3.8.9.tar.gz", hash = "sha256:c40bece58c11cb09aff17424d21b41f6f767d2b1252b2f745ec3ff29cce6a240"}, ] [[package]] @@ -2624,14 +2624,14 @@ files = [ [[package]] name = "pytz" -version = "2023.2" +version = "2023.3" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" files = [ - {file = "pytz-2023.2-py2.py3-none-any.whl", hash = "sha256:8a8baaf1e237175b02f5c751eea67168043a749c843989e2b3015aa1ad9db68b"}, - {file = "pytz-2023.2.tar.gz", hash = "sha256:a27dcf612c05d2ebde626f7d506555f10dfc815b3eddccfaadfc7d99b11c9a07"}, + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] [[package]] @@ -2762,14 +2762,14 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.3.2" +version = "13.3.3" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.3.2-py3-none-any.whl", hash = "sha256:a104f37270bf677148d8acb07d33be1569eeee87e2d1beb286a4e9113caf6f2f"}, - {file = "rich-13.3.2.tar.gz", hash = "sha256:91954fe80cfb7985727a467ca98a7618e5dd15178cc2da10f553b36a93859001"}, + {file = "rich-13.3.3-py3-none-any.whl", hash = "sha256:540c7d6d26a1178e8e8b37e9ba44573a3cd1464ff6348b99ee7061b95d1c6333"}, + {file = "rich-13.3.3.tar.gz", hash = "sha256:dc84400a9d842b3a9c5ff74addd8eb798d155f36c1c91303888e0a66850d2a15"}, ] [package.dependencies] @@ -2956,14 +2956,14 @@ files = [ [[package]] name = "setuptools" -version = "67.6.0" +version = "67.6.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.6.0-py3-none-any.whl", hash = "sha256:b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2"}, - {file = "setuptools-67.6.0.tar.gz", hash = "sha256:2ee892cd5f29f3373097f5a814697e397cf3ce313616df0af11231e2ad118077"}, + {file = "setuptools-67.6.1-py3-none-any.whl", hash = "sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078"}, + {file = "setuptools-67.6.1.tar.gz", hash = "sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a"}, ] [package.extras] @@ -3125,15 +3125,15 @@ files = [ streamlit = ">=0.63" [[package]] -name = "streamlit-elements" -version = "0.1.0" +name = "streamlit-elements-fluence" +version = "0.1.4" description = "React Components for Streamlit." category = "main" optional = true python-versions = ">=3.6" files = [ - {file = "streamlit-elements-0.1.0.tar.gz", hash = "sha256:5f9f116f22df3ce4a8636b1dee7c2fd3dc3cb0c66267fd28c3e0314aa1d303a7"}, - {file = "streamlit_elements-0.1.0-py3-none-any.whl", hash = "sha256:593c4b88c399c55879aa76f7f42970f30106f66acaa4baada6338ae5571790df"}, + {file = "streamlit-elements-fluence-0.1.4.tar.gz", hash = "sha256:79263c002918b67ddc5a6ee929aa3f80f091ddc3df0b4703ffda134187e255ef"}, + {file = "streamlit_elements_fluence-0.1.4-py3-none-any.whl", hash = "sha256:6bf8c7ee582e4b0edf4603dc5b743888bb9df878ee1bd1780c8db287cd08c303"}, ] [package.dependencies] @@ -3200,14 +3200,14 @@ files = [ [[package]] name = "tomlkit" -version = "0.11.6" +version = "0.11.7" description = "Style preserving TOML library" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, - {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, + {file = "tomlkit-0.11.7-py3-none-any.whl", hash = "sha256:5325463a7da2ef0c6bbfefb62a3dc883aebe679984709aee32a317907d0a8d3c"}, + {file = "tomlkit-0.11.7.tar.gz", hash = "sha256:f392ef70ad87a672f02519f99967d28a4d3047133e2d1df936511465fbb3791d"}, ] [[package]] @@ -3294,14 +3294,14 @@ files = [ [[package]] name = "tzdata" -version = "2023.2" +version = "2023.3" description = "Provider of IANA time zone data" category = "main" optional = true python-versions = ">=2" files = [ - {file = "tzdata-2023.2-py2.py3-none-any.whl", hash = "sha256:905ae9e6744dd9ef5ce94d2aaa2dd00282fee38b670b2133407f23c388f110a1"}, - {file = "tzdata-2023.2.tar.gz", hash = "sha256:c3b51b235b07f9f1889089c2264bcbeaaba260a63f89bea09e350ea4205eb95f"}, + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] [[package]] @@ -3606,14 +3606,14 @@ files = [ [[package]] name = "ydata-profiling" -version = "4.1.1" +version = "4.1.2" description = "Generate profile report for pandas DataFrame" category = "main" optional = true python-versions = ">=3.7, <3.12" files = [ - {file = "ydata-profiling-4.1.1.tar.gz", hash = "sha256:ff8f8cb41f86485b4a6d7bff32ff5ada747b1644f2b20bc5dd05cc616d1aef2e"}, - {file = "ydata_profiling-4.1.1-py2.py3-none-any.whl", hash = "sha256:65d62b7d5bc1b4bac3c0122fb07c275796742739ba2c0cd2b2aceddd0ef413eb"}, + {file = "ydata-profiling-4.1.2.tar.gz", hash = "sha256:4fefde707122c037a0aa2e2cdcb98aa1bd4bce67f122c586fc570867568c8992"}, + {file = "ydata_profiling-4.1.2-py2.py3-none-any.whl", hash = "sha256:8866b96a04e726444f5797477f594393898520b9f0f018d832027b82372d7978"}, ] [package.dependencies] @@ -3659,9 +3659,9 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more duckdb = ["dbt-duckdb"] postgres = ["dbt-postgres"] sqlite = ["dbt-sqlite"] -workbench = ["streamlit", "streamlit-ace", "ydata-profiling", "feedparser", "streamlit-elements"] +workbench = ["streamlit", "streamlit-ace", "ydata-profiling", "feedparser", "streamlit-elements-fluence"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.11" -content-hash = "c8c29346ddc880d61224d8df6df284cadb6d4ab72baf88a7ed1aa73343ad26c1" +content-hash = "8d94f74425ff8920a87a37af9ec7206ab6eb40220cfbb8e62ae365a218c341cd" diff --git a/pyproject.toml b/pyproject.toml index c92e938..ac4fd2d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "dbt-osmosis" -version = "0.11.11" +version = "0.11.12" description = "A dbt server and suite of optional developer tools to make developing with dbt delightful." authors = ["z3z1ma "] license = "Apache 2.0" @@ -34,7 +34,7 @@ streamlit = { version = ">=1.0.0", optional = true } streamlit-ace = { version = ">=0.1.0", optional = true } ydata-profiling = { version = ">=3.6.0", optional = true } feedparser = { version = "^6.0.10", optional = true } -streamlit-elements = { version = ">=0.1.0", optional = true } +streamlit-elements-fluence = { version = ">=0.1.4", optional = true } # Testing duckdb + sqlite dbt-duckdb = { version = ">=1.0.0", optional = true } dbt-sqlite = { version = ">=1.0.0", optional = true } @@ -59,7 +59,7 @@ workbench = [ "streamlit-ace", "ydata-profiling", "feedparser", - "streamlit-elements", + "streamlit-elements-fluence", ] [build-system] diff --git a/src/dbt_osmosis/app_v2.py b/src/dbt_osmosis/app_v2.py new file mode 100644 index 0000000..a84473e --- /dev/null +++ b/src/dbt_osmosis/app_v2.py @@ -0,0 +1,386 @@ +import argparse +import decimal +import os +import sys +import time +from collections import OrderedDict +from datetime import datetime, date +from textwrap import dedent +from types import SimpleNamespace + +import dbt.config.profile as dbt_profile +import pandas as pd +import ydata_profiling +import streamlit as st +from streamlit import session_state as state +from streamlit_elements_fluence import elements, event, sync + +from dbt_osmosis.components.editor import Editor, Tabs as EditorTabs +from dbt_osmosis.components.dashboard import Dashboard +from dbt_osmosis.components.preview import Preview +from dbt_osmosis.components.profiler import Profiler +from dbt_osmosis.components.renderer import Renderer +from dbt_osmosis.components.feed import RssFeed +from dbt_osmosis.vendored.dbt_core_interface import ( + DbtProject, + default_profiles_dir, + default_project_dir, +) + +default_prompt = ( + "-- This is a scratch model\n-- it will not persist if you jump to another model\n-- you can" + " use this to test your dbt SQL queries\n\nselect 1 as id, 'hello' as name" +) + + +def _get_demo_query() -> str: + return dedent(""" + {% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %} + + with orders as ( + + select * from {{ ref('stg_orders') }} + + ), + + payments as ( + + select * from {{ ref('stg_payments') }} + + ), + + order_payments as ( + + select + order_id, + + {% for payment_method in payment_methods -%} + sum(case when payment_method = '{{ payment_method }}' then amount else 0 end) + as {{ payment_method }}_amount, + {% endfor -%} + + sum(amount) as total_amount + + from payments + + group by order_id + + ), + + final as ( + + select + orders.order_id, + orders.customer_id, + orders.order_date, + orders.status, + + {% for payment_method in payment_methods -%} + + order_payments.{{ payment_method }}_amount, + + {% endfor -%} + + order_payments.total_amount as amount + + from orders + + + left join order_payments + on orders.order_id = order_payments.order_id + + ) + + select * from final + """) + + +def _parse_args() -> dict: + """Parse command line arguments""" + try: + parser = argparse.ArgumentParser(description="dbt osmosis workbench") + parser.add_argument("--profiles-dir", help="dbt profile directory") + parser.add_argument("--project-dir", help="dbt project directory") + args = vars(parser.parse_args(sys.argv[1:])) + except Exception: + args = {} + return args + + +def change_target() -> None: + """Change the target profile""" + ctx: DbtProject = state.w.ctx + if ctx.config.target_name != state.target_profile: + print(f"Changing target to {state.target_profile}") + ctx.base_config.target = state.target_profile + ctx.safe_parse_project(reinit=True) + state.w.raw_sql += " " # invalidate cache on next compile? + state.w.cache_version += 1 + + +def inject_model() -> None: + """Inject model into editor""" + ctx: DbtProject = state.w.ctx + if state.model is not None and state.model != "SCRATCH": + path = os.path.join(ctx.project_root, state.model.original_file_path) + with open(path, "r") as f: + state.w.raw_sql = f.read() + state.w.editor.update_content("SQL", state.w.raw_sql) + elif state.model == "SCRATCH": + state.w.editor.update_content("SQL", default_prompt) + state.w.cache_version += 1 + + +def save_model() -> None: + """Save model to disk""" + ctx: DbtProject = state.w.ctx + if state.model is not None and state.model != "SCRATCH": + path = os.path.join(ctx.project_root, state.model.original_file_path) + with open(path, "w") as f: + f.write(state.w.editor.get_content("SQL")) + print(f"Saved model to {path}") + + +def sidebar(ctx: DbtProject) -> None: + # Model selector + with st.sidebar.expander("💡 Models", expanded=True): + st.caption( + "Select a model to use as a starting point for your query. The filter supports" + " typeahead. All changes are ephemeral unless you save the model." + ) + state.w.model = st.selectbox( + "Select a model", + options=state.w.model_opts, + format_func=lambda x: getattr(x, "name", x), + on_change=inject_model, + key="model", + ) + btn1, btn2 = st.columns(2) + if state.w.model != "SCRATCH": + btn1.button("💾 - Save", on_click=save_model, key="save_model") + btn2.button("⏮ - Revert", on_click=inject_model, key="reset_model") + + # Profile selector + with st.sidebar.expander("💁 Profiles", expanded=True): + st.caption( + "Select a profile used for materializing, compiling, and testing models.\n\nIf you" + " change profiles, you may need to modify the workbench query to invalidate the cache." + ) + state.w.target_profile = st.radio( + f"Loaded profiles from {ctx.config.profile_name}", + [target for target in state.w.raw_profiles[ctx.config.profile_name].get("outputs", [])], + on_change=change_target, + key="target_profile", + ) + st.markdown(f"Current Target: **{state.w.target_profile}**") + + # Query template + with st.sidebar.expander("📝 Query Template"): + st.caption( + "This is a template query that will be used when executing SQL. The {sql} variable will" + " be replaced with the compiled SQL." + ) + state.w.sql_template = st.text_area( + "SQL Template", + value=state.w.sql_template, + height=100, + ) + + # Refresh instructions + st.sidebar.write("Notes") + st.sidebar.caption( + "Refresh the page to reparse dbt. This is useful if any updated models or macros in your" + " physical project on disk have changed and are not yet reflected in the workbench as" + " refable or updated." + ) + + +def ttl_cache(wait): + """Debounce a function call.""" + + def decorator(func): + last_called = time.time() + cached_result = None + + def cached(*args, **kwargs): + nonlocal last_called, cached_result + elapsed = time.time() - last_called + if elapsed < wait and cached_result is not None: + return cached_result + cached_result = func(*args, **kwargs) + last_called = time.time() + return cached_result + + return cached + + return decorator + + +@ttl_cache(3.0) +def compile(ctx: DbtProject, sql: str) -> str: + """Compile SQL using dbt context.""" + try: + with ctx.adapter.connection_named("__sql_workbench__"): + return ctx.compile_code(sql).compiled_code + except Exception as e: + return str(e) + + +def ser(x): + if isinstance(x, decimal.Decimal): + return float(x) + if isinstance(x, date): + return x.isoformat() + if isinstance(x, datetime): + return x.isoformat() + return x + + +def run_query() -> None: + """Run SQL query using dbt context. + + This mutates the state of the app. + """ + ctx: DbtProject = state.w.ctx + sql = state.w.compiled_sql + try: + state.w.sql_query_state = "running" + with ctx.adapter.connection_named("__sql_workbench__"): + result = ctx.execute_code(state.w.sql_template.format(sql=sql)) + except Exception as error: + state.w.sql_query_state = "error" + state.w.sql_adapter_resp = str(error) + state.w.sql_result_columns = [] + else: + state.w.sql_query_state = "success" + state.w.sql_adapter_resp = result.adapter_response + output = [ + OrderedDict(zip(result.table.column_names, (ser(v) for v in row))) + for row in result.table.rows + ] + state.w.sql_result_df = pd.DataFrame(output) + state.w.sql_result_columns = [ + {"field": c, "headerName": c.upper()} for c in result.table.column_names + ] + state.w.sql_result_rows = output + + +@st.cache +def convert_df_to_csv(dataframe: pd.DataFrame) -> bytes: + """Convert a dataframe to a CSV file.""" + return state.w.sql_result_df.to_csv().encode("utf-8") + + +def build_profile_report(minimal: bool = True) -> ydata_profiling.ProfileReport: + """Build a profile report for a given dataframe. + + This is a wrapper around the ydata_profiling library. It is cached to avoid + re-running the report every time the user changes the SQL query. + """ + return state.w.sql_result_df.profile_report(minimal=minimal) + + +def convert_profile_report_to_html(profile: ydata_profiling.ProfileReport) -> str: + """Convert a profile report to HTML.""" + return profile.to_html() + + +def run_profile(minimal: bool = True) -> str: + """Run a profile report and return the HTML report.""" + if not state.w.sql_result_df.empty: + state.w.profile_html = convert_profile_report_to_html(build_profile_report(minimal)) + + +def main(): + args = _parse_args() + + st.title("dbt-osmosis 🌊") + + if "w" not in state: + # Initialize state + board = Dashboard() + w = SimpleNamespace( + # Components + dashboard=board, + editor=Editor(board, 0, 0, 6, 11, minW=3, minH=3, sql_compiler=compile), + renderer=Renderer(board, 6, 0, 6, 11, minW=3, minH=3), + preview=Preview(board, 0, 11, 12, 9, minW=3, minH=3), + profiler=Profiler(board, 0, 20, 8, 9, minW=3, minH=3), + feed=RssFeed(board, 8, 20, 4, 9, minW=3, minH=3), + # Base Args + project_dir=args.get("project_dir") or str(default_project_dir()), + profiles_dir=args.get("profiles_dir") or str(default_profiles_dir()), + # SQL Editor + compiled_sql="", + raw_sql="", + theme="dark", + lang="sql", + # Query Runner + sql_result_df=pd.DataFrame(), + sql_result_columns=[], + sql_result_rows=[], + sql_adapter_resp=None, + sql_query_state="test", + sql_template="select * from ({sql}) as _query limit 200", + # Profiler + profile_minimal=True, + profile_html="", + # Model + model="SCRATCH", + cache_version=0, + ) + # Load raw profiles + w.raw_profiles = dbt_profile.read_profile(w.profiles_dir) + # Seed demo project query + if w.project_dir.rstrip(os.path.sep).endswith(("demo_sqlite", "demo_duckdb")): + w.raw_sql = _get_demo_query() + else: + w.raw_sql = default_prompt + # Initialize dbt context + w.ctx = DbtProject( + project_dir=w.project_dir, + profiles_dir=w.profiles_dir, + ) + w.target_profile = w.ctx.config.target_name + # Demo compilation hook + seed editor + w.editor.tabs[EditorTabs.SQL]["content"] = w.raw_sql + w.compiled_sql = compile(w.ctx, w.raw_sql) if w.raw_sql else "" + # Grab nodes + model_nodes = [] + for node in w.ctx.manifest.nodes.values(): + if node.resource_type == "model" and node.package_name == w.ctx.config.project_name: + model_nodes.append(node) + w.model_nodes = model_nodes + w.model_opts = ["SCRATCH"] + [node for node in model_nodes] + # Save state + state.w = w + w.editor.update_content("SQL", w.raw_sql) + else: + # Load state + w = state.w + + ctx: DbtProject = w.ctx + + # Render Sidebar + sidebar(ctx) + + # Render Interface + with elements("dashboard"): + # Bind hotkeys, maybe one day we can figure out how to override Monaco's cmd+enter binding + event.Hotkey("ctrl+enter", sync(), bindInputs=True, overrideDefault=True) + event.Hotkey("command+s", sync(), bindInputs=True, overrideDefault=True) + event.Hotkey("ctrl+shift+enter", lambda: run_query(), bindInputs=True, overrideDefault=True) + event.Hotkey("command+shift+s", lambda: run_query(), bindInputs=True, overrideDefault=True) + + # Render Dashboard + with w.dashboard(rowHeight=57): + w.editor() + w.renderer() + w.preview(query_run_fn=run_query) + w.profiler(run_profile_fn=run_profile) + w.feed() + + +if __name__ == "__main__": + st.set_page_config(page_title="dbt-osmosis Workbench", page_icon="🌊", layout="wide") + main() diff --git a/src/dbt_osmosis/components/dashboard.py b/src/dbt_osmosis/components/dashboard.py new file mode 100644 index 0000000..469609f --- /dev/null +++ b/src/dbt_osmosis/components/dashboard.py @@ -0,0 +1,61 @@ +from abc import ABC, abstractmethod +from contextlib import contextmanager +from uuid import uuid4 + +from streamlit_elements_fluence import dashboard, mui + + +class Dashboard: + DRAGGABLE_CLASS = "draggable" + + def __init__(self): + self._layout = [] + + def _register(self, item): + self._layout.append(item) + + @contextmanager + def __call__(self, **props): + # Draggable classname query selector. + props["draggableHandle"] = f".{Dashboard.DRAGGABLE_CLASS}" + + with dashboard.Grid(self._layout, **props): + yield + + class Item(ABC): + def __init__(self, board, x, y, w, h, **item_props): + self._key = str(uuid4()) + self._draggable_class = Dashboard.DRAGGABLE_CLASS + self._dark_mode = True + board._register(dashboard.Item(self._key, x, y, w, h, **item_props)) + + def _switch_theme(self): + self._dark_mode = not self._dark_mode + + @contextmanager + def title_bar(self, padding="5px 15px 5px 15px", dark_switcher=True): + with mui.Stack( + className=self._draggable_class, + alignItems="center", + direction="row", + spacing=1, + sx={ + "padding": padding, + "borderBottom": 1, + "borderColor": "divider", + }, + ): + yield + + if dark_switcher: + if self._dark_mode: + mui.IconButton(mui.icon.DarkMode, onClick=self._switch_theme) + else: + mui.IconButton( + mui.icon.LightMode, sx={"color": "#ffc107"}, onClick=self._switch_theme + ) + + @abstractmethod + def __call__(self): + """Show elements.""" + raise NotImplementedError diff --git a/src/dbt_osmosis/components/editor.py b/src/dbt_osmosis/components/editor.py new file mode 100644 index 0000000..7eec84a --- /dev/null +++ b/src/dbt_osmosis/components/editor.py @@ -0,0 +1,113 @@ +from enum import Enum +from functools import partial + +from streamlit import session_state as state +from streamlit_elements_fluence import editor, lazy, mui, sync + +from .dashboard import Dashboard + + +class Tabs(str, Enum): + SQL = "SQL" + YAML = "YAML" + + +class DarkMode: + def __bool__(self): + return state.w.theme == "dark" + + +class Editor(Dashboard.Item): + def __init__(self, *args, sql_compiler=lambda content: content, **kwargs): + super().__init__(*args, **kwargs) + self._dark_mode = DarkMode() + + self.tabs = { + Tabs.SQL: {"content": "", "language": "sql"}, + Tabs.YAML: {"content": "version: 2\n", "language": "yaml"}, + } + self.sql_compiler = sql_compiler + + self._index = 0 + self._editor_box_style = { + "flex": 1, + "minHeight": 0, + "borderBottom": 1, + "borderTop": 1, + "borderColor": "divider", + } + self._realtime_compilation = False + + def _switch_theme(self): + if state.w.theme == "dark": + state.w.theme = "light" + else: + state.w.theme = "dark" + + def _change_tab(self, _, index): + self._index = index + + def update_content(self, label, content): + self.tabs[label]["content"] = content + if label == Tabs.SQL: + state.w.compiled_sql = self.sql_compiler(state.w.ctx, content) + + def get_content(self, label): + return self.tabs[label]["content"] + + def __call__(self, **options): + with mui.Paper( + key=self._key, + sx={ + "display": "flex", + "flexDirection": "column", + "borderRadius": 3, + "overflow": "hidden", + }, + elevation=1, + ): + with self.title_bar("0px 15px 0px 15px"): + mui.icon.Terminal() + mui.Typography("dbt Workbench") + + with mui.Tabs( + value=self._index, + onChange=self._change_tab, + scrollButtons=True, + variant="scrollable", + sx={"flex": 1}, + ): + for label in self.tabs.keys(): + mui.Tab(label=label) + + for index, (label, tab) in enumerate(self.tabs.items()): + with mui.Box(sx=self._editor_box_style, hidden=(index != self._index)): + if self._realtime_compilation: + onChange = partial(self.update_content, label) + else: + onChange = lazy(partial(self.update_content, label)) + if state.w.model and state.w.model != "SCRATCH": + path = state.w.model.original_file_path + else: + path = label + editor.Monaco( + css={"padding": "0 2px 0 2px"}, + defaultValue=tab["content"], + language=tab["language"], + onChange=onChange, + theme="vs-dark" if self._dark_mode else "light", + path=path, + options=options, + key=f"editor-{state.w.cache_version}-{index}" + ) + + with mui.Stack(direction="row", spacing=2, alignItems="center", sx={"padding": "10px"}): + mui.Button("Compile", variant="contained", onClick=sync()) + key = "Ctrl+Enter" + mui.Typography(f"Or press {key}", sx={"flex": 1}) + mui.Switch( + checked=self._realtime_compilation, + onChange=lambda _, checked: setattr(self, "_realtime_compilation", checked), + sx={"marginRight": 1}, + ) + mui.Typography("Realtime Compilation") diff --git a/src/dbt_osmosis/components/feed.py b/src/dbt_osmosis/components/feed.py new file mode 100644 index 0000000..a8e2603 --- /dev/null +++ b/src/dbt_osmosis/components/feed.py @@ -0,0 +1,47 @@ +import feedparser +from streamlit_elements_fluence import mui, extras + +from .dashboard import Dashboard + + +class RssFeed(Dashboard.Item): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self._dark_theme = False + self._editor_box_style = { + "flex": 1, + "minHeight": 0, + "borderBottom": 1, + "borderTop": 1, + "borderColor": "divider", + } + + def __call__(self, **options): + with mui.Paper( + key=self._key, + sx={ + "display": "flex", + "flexDirection": "column", + "borderRadius": 3, + "overflow": "scroll", + }, + elevation=1, + ): + with self.title_bar("12px 15px 12px 15px", dark_switcher=False): + mui.icon.Feed() + mui.Typography("Hacker News Feed") + + # Render hacker news feed + feed = feedparser.parse("https://news.ycombinator.com/rss") + + for entry in feed.entries: + extras.InnerHTML(f""" +
+ {entry.title} +
{entry.published} + | + Comments +
+
+ """) diff --git a/src/dbt_osmosis/components/preview.py b/src/dbt_osmosis/components/preview.py new file mode 100644 index 0000000..3b45281 --- /dev/null +++ b/src/dbt_osmosis/components/preview.py @@ -0,0 +1,56 @@ +from streamlit import session_state as state +from streamlit_elements_fluence import JSCallback, mui + +from .dashboard import Dashboard + + +class Preview(Dashboard.Item): + def __call__(self, query_run_fn): + with mui.Paper( + key=self._key, + sx={ + "display": "flex", + "flexDirection": "column", + "borderRadius": 3, + "overflow": "hidden", + }, + elevation=1, + ): + with self.title_bar(padding="10px 15px 10px 15px", dark_switcher=False): + mui.icon.ViewCompact() + mui.Typography("Query Preview") + if state.w.sql_query_state == "success": + mui.Typography( + "Adapter Response: {}".format(state.w.sql_adapter_resp), + sx={"marginRight": "auto", "color": "text.secondary"}, + ) + + with mui.Box(sx={"flex": 1, "minHeight": 0}): + if state.w.sql_query_state == "running": + mui.CircularProgress(sx={"padding": "25px"}) + elif state.w.sql_query_state == "error": + mui.Typography( + "Error running query\n\n{}".format(state.w.sql_adapter_resp), + sx={"padding": "25px"}, + ) + elif not state.w.sql_result_columns: + mui.Typography("No results to show...", sx={"padding": "25px"}) + else: + mui.DataGrid( + columns=state.w.sql_result_columns, + rows=state.w.sql_result_rows, + pageSize=20, + rowsPerPageOptions=[20, 50, 100], + checkboxSelection=False, + disableSelectionOnClick=True, + getRowId=JSCallback("(row) => Math.random()"), + ) + + with mui.Stack(direction="row", spacing=2, alignItems="center", sx={"padding": "10px"}): + mui.Button( + "Run Query", + variant="contained", + onClick=lambda: query_run_fn(), + ) + key = "Ctrl+Shift+Enter" + mui.Typography(f"Or press {key}", sx={"flex": 1}) diff --git a/src/dbt_osmosis/components/profiler.py b/src/dbt_osmosis/components/profiler.py new file mode 100644 index 0000000..debdaea --- /dev/null +++ b/src/dbt_osmosis/components/profiler.py @@ -0,0 +1,45 @@ +from streamlit import session_state as state +from streamlit_elements_fluence import extras, html, mui + +from .dashboard import Dashboard + + +class Profiler(Dashboard.Item): + def __call__(self, run_profile_fn): + with mui.Paper( + key=self._key, + sx={ + "display": "flex", + "flexDirection": "column", + "borderRadius": 3, + "overflow": "hidden", + }, + elevation=1, + ): + with self.title_bar(padding="10px 15px 10px 15px", dark_switcher=False): + mui.icon.Psychology() + mui.Typography("Pandas Profiler") + if state.w.sql_result_df.empty: + mui.Typography( + "No data to profile, execute a query first", sx={"color": "text.secondary"} + ) + + with mui.Box(sx={"flex": 1, "minHeight": 0}): + if state.w.profile_html: + html.Iframe( + srcDoc=state.w.profile_html, + style={"width": "100%", "height": "100%", "border": "none"}, + ) + else: + # extras.InnerHTML("Docs") + html.Iframe( + src="https://pandas-profiling.github.io/pandas-profiling/docs/master/rtd/", + style={"width": "100%", "height": "100%", "border": "none"}, + ) + + with mui.Stack(direction="row", spacing=2, alignItems="center", sx={"padding": "10px"}): + mui.Button( + "Profile Results", + variant="contained", + onClick=lambda: run_profile_fn(), + ) diff --git a/src/dbt_osmosis/components/renderer.py b/src/dbt_osmosis/components/renderer.py new file mode 100644 index 0000000..3b50fcc --- /dev/null +++ b/src/dbt_osmosis/components/renderer.py @@ -0,0 +1,62 @@ +from hashlib import md5 +from uuid import uuid4 + +from streamlit import session_state as state +from streamlit_elements_fluence import editor, mui, dashboard + +from .dashboard import Dashboard + + +class DarkMode: + def __bool__(self): + return state.w.theme == "dark" + + +class Renderer(Dashboard.Item): + def __init__(self, board, x, y, w, h, **item_props): + self._key = str(uuid4()) + self._draggable_class = Dashboard.DRAGGABLE_CLASS + board._register(dashboard.Item(self._key, x, y, w, h, **item_props)) + self._editor_box_style = { + "flex": 1, + "minHeight": 0, + "borderBottom": 1, + "borderTop": 1, + "borderColor": "divider", + } + self._dark_mode = DarkMode() + + def __call__( + self, + **options, + ): + with mui.Paper( + key=self._key, + sx={ + "display": "flex", + "flexDirection": "column", + "borderRadius": 3, + "overflow": "hidden", + }, + elevation=1, + ): + with self.title_bar("12px 15px 12px 15px", dark_switcher=False): + mui.icon.Preview() + mui.Typography("Compiled SQL") + + with mui.Box(sx=self._editor_box_style): + editor.Monaco( + css={"padding": "0 2px 0 2px"}, + defaultValue=state.w.compiled_sql or "", + language="sql", + theme="vs-dark" if self._dark_mode else "light", + options={**options, "readOnly": True}, + key=( + md5( + state.w.compiled_sql.encode("utf-8") + + state.target_profile.encode("utf-8") + ).hexdigest() + if state.w.compiled_sql + else "__empty__" + ), + ) diff --git a/src/dbt_osmosis/main.py b/src/dbt_osmosis/main.py index 66fe27d..bf6294e 100644 --- a/src/dbt_osmosis/main.py +++ b/src/dbt_osmosis/main.py @@ -589,7 +589,7 @@ def workbench( "--runner.magicEnabled=false", f"--browser.serverAddress={host}", f"--browser.serverPort={port}", - Path(__file__).parent / "app.py", + Path(__file__).parent / "app_v2.py", ] + ctx.args + script_args,