├── .gitignore
├── .streamlit
└── config.toml
├── Home.py
├── LICENSE
├── Pipfile
├── Pipfile.lock
├── README.md
├── pages
├── 01_🔹_Compute_insights.py
├── 02_🔹_Storage_insights.py
├── 03_🔹_Data_Transfer_insights.py
└── 04_🤔_About_this_app.py
└── utils
├── charts.py
├── gui.py
├── processing.py
├── snowflake_connector.py
└── sql.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Streamlit secrets
2 | .streamlit/secrets.toml
3 |
4 | .DS_Store
5 |
--------------------------------------------------------------------------------
/.streamlit/config.toml:
--------------------------------------------------------------------------------
1 | [runner]
2 | fastReruns = true
3 |
4 | [theme]
5 | primaryColor = "#1c83e1"
6 |
--------------------------------------------------------------------------------
/Home.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 |
3 | st.set_page_config(page_title="Usage Insights app", page_icon="🌀", layout="centered")
4 |
5 | from utils import gui
6 |
7 | gui.icon("🌀")
8 |
9 | # Make sure session state is preserved
10 | for key in st.session_state:
11 | st.session_state[key] = st.session_state[key]
12 |
13 | st.title("Welcome to the Usage Insights app!")
14 | st.sidebar.text(f"Account: {st.secrets.sf_usage_app.account}")
15 | st.sidebar.info("Choose a page!")
16 | st.markdown(
17 | """
18 | This app provides insights on a demo Snowflake account usage.
19 |
20 | ### Get started!
21 |
22 | 👈 Select a page in the sidebar!
23 | """
24 | )
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Pipfile:
--------------------------------------------------------------------------------
1 | [[source]]
2 | url = "https://pypi.org/simple"
3 | verify_ssl = true
4 | name = "pypi"
5 |
6 | [requires]
7 | python_version = "3.9"
8 |
9 | [packages]
10 | streamlit = ">=1.10.0" # Requires multipage app
11 | requests = "*"
12 | matplotlib = "*"
13 | millify = "*"
14 | plost = {editable = true, ref = "streamlit-style", git = "https://github.com/jrieke/plost"} # Docs https://share.streamlit.io/jrieke/plost/streamlit-style/
15 | numpy = "*"
16 | snowflake-connector-python = ">=2.7.8"
17 | sqlparse = "*"
18 |
19 | [dev-packages]
20 | black = "*" # Pretty formatting of Python code
21 | pynvim = "*" # Allows nvim users to use black formatting
22 | pre-commit = "*"
23 | flake8 = "*"
24 | flake8-bugbear = "*"
25 | typed-ast = ">=1.5.0"
26 | mypy = "*"
27 |
--------------------------------------------------------------------------------
/Pipfile.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_meta": {
3 | "hash": {
4 | "sha256": "2f652e94201d84d4069906fa9b57fbaead9e3d9942989e45aa473bdd471bfc90"
5 | },
6 | "pipfile-spec": 6,
7 | "requires": {
8 | "python_version": "3.9"
9 | },
10 | "sources": [
11 | {
12 | "name": "pypi",
13 | "url": "https://pypi.org/simple",
14 | "verify_ssl": true
15 | }
16 | ]
17 | },
18 | "default": {
19 | "altair": {
20 | "hashes": [
21 | "sha256:0c724848ae53410c13fa28be2b3b9a9dcb7b5caa1a70f7f217bd663bb419935a",
22 | "sha256:d87d9372e63b48cd96b2a6415f0cf9457f50162ab79dc7a31cd7e024dd840026"
23 | ],
24 | "markers": "python_version >= '3.7'",
25 | "version": "==4.2.0"
26 | },
27 | "appnope": {
28 | "hashes": [
29 | "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24",
30 | "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"
31 | ],
32 | "markers": "platform_system == 'Darwin'",
33 | "version": "==0.1.3"
34 | },
35 | "argon2-cffi": {
36 | "hashes": [
37 | "sha256:8c976986f2c5c0e5000919e6de187906cfd81fb1c72bf9d88c01177e77da7f80",
38 | "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"
39 | ],
40 | "markers": "python_version >= '3.6'",
41 | "version": "==21.3.0"
42 | },
43 | "argon2-cffi-bindings": {
44 | "hashes": [
45 | "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670",
46 | "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f",
47 | "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583",
48 | "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194",
49 | "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c",
50 | "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a",
51 | "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082",
52 | "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5",
53 | "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f",
54 | "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7",
55 | "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d",
56 | "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f",
57 | "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae",
58 | "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3",
59 | "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86",
60 | "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367",
61 | "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d",
62 | "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93",
63 | "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb",
64 | "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e",
65 | "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"
66 | ],
67 | "markers": "python_version >= '3.6'",
68 | "version": "==21.2.0"
69 | },
70 | "asn1crypto": {
71 | "hashes": [
72 | "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c",
73 | "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"
74 | ],
75 | "version": "==1.5.1"
76 | },
77 | "asttokens": {
78 | "hashes": [
79 | "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c",
80 | "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"
81 | ],
82 | "version": "==2.0.5"
83 | },
84 | "attrs": {
85 | "hashes": [
86 | "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4",
87 | "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"
88 | ],
89 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
90 | "version": "==21.4.0"
91 | },
92 | "backcall": {
93 | "hashes": [
94 | "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e",
95 | "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"
96 | ],
97 | "version": "==0.2.0"
98 | },
99 | "beautifulsoup4": {
100 | "hashes": [
101 | "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30",
102 | "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"
103 | ],
104 | "markers": "python_version >= '3.6'",
105 | "version": "==4.11.1"
106 | },
107 | "bleach": {
108 | "hashes": [
109 | "sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1",
110 | "sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565"
111 | ],
112 | "markers": "python_version >= '3.7'",
113 | "version": "==5.0.0"
114 | },
115 | "blinker": {
116 | "hashes": [
117 | "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6"
118 | ],
119 | "version": "==1.4"
120 | },
121 | "cachetools": {
122 | "hashes": [
123 | "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757",
124 | "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"
125 | ],
126 | "markers": "python_version ~= '3.7'",
127 | "version": "==5.2.0"
128 | },
129 | "certifi": {
130 | "hashes": [
131 | "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7",
132 | "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"
133 | ],
134 | "markers": "python_version >= '3.6'",
135 | "version": "==2022.5.18.1"
136 | },
137 | "cffi": {
138 | "hashes": [
139 | "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3",
140 | "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2",
141 | "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636",
142 | "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20",
143 | "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728",
144 | "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27",
145 | "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66",
146 | "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443",
147 | "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0",
148 | "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7",
149 | "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39",
150 | "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605",
151 | "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a",
152 | "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37",
153 | "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029",
154 | "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139",
155 | "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc",
156 | "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df",
157 | "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14",
158 | "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880",
159 | "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2",
160 | "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a",
161 | "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e",
162 | "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474",
163 | "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024",
164 | "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8",
165 | "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0",
166 | "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e",
167 | "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a",
168 | "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e",
169 | "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032",
170 | "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6",
171 | "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e",
172 | "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b",
173 | "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e",
174 | "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954",
175 | "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962",
176 | "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c",
177 | "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4",
178 | "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55",
179 | "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962",
180 | "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023",
181 | "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c",
182 | "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6",
183 | "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8",
184 | "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382",
185 | "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7",
186 | "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc",
187 | "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997",
188 | "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"
189 | ],
190 | "version": "==1.15.0"
191 | },
192 | "charset-normalizer": {
193 | "hashes": [
194 | "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597",
195 | "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"
196 | ],
197 | "markers": "python_version >= '3.5'",
198 | "version": "==2.0.12"
199 | },
200 | "click": {
201 | "hashes": [
202 | "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
203 | "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
204 | ],
205 | "markers": "python_version >= '3.7'",
206 | "version": "==8.1.3"
207 | },
208 | "colour": {
209 | "hashes": [
210 | "sha256:33f6db9d564fadc16e59921a56999b79571160ce09916303d35346dddc17978c",
211 | "sha256:af20120fefd2afede8b001fbef2ea9da70ad7d49fafdb6489025dae8745c3aee"
212 | ],
213 | "version": "==0.1.5"
214 | },
215 | "commonmark": {
216 | "hashes": [
217 | "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60",
218 | "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"
219 | ],
220 | "version": "==0.9.1"
221 | },
222 | "cryptography": {
223 | "hashes": [
224 | "sha256:0a3bf09bb0b7a2c93ce7b98cb107e9170a90c51a0162a20af1c61c765b90e60b",
225 | "sha256:1f64a62b3b75e4005df19d3b5235abd43fa6358d5516cfc43d87aeba8d08dd51",
226 | "sha256:32db5cc49c73f39aac27574522cecd0a4bb7384e71198bc65a0d23f901e89bb7",
227 | "sha256:4881d09298cd0b669bb15b9cfe6166f16fc1277b4ed0d04a22f3d6430cb30f1d",
228 | "sha256:4e2dddd38a5ba733be6a025a1475a9f45e4e41139d1321f412c6b360b19070b6",
229 | "sha256:53e0285b49fd0ab6e604f4c5d9c5ddd98de77018542e88366923f152dbeb3c29",
230 | "sha256:70f8f4f7bb2ac9f340655cbac89d68c527af5bb4387522a8413e841e3e6628c9",
231 | "sha256:7b2d54e787a884ffc6e187262823b6feb06c338084bbe80d45166a1cb1c6c5bf",
232 | "sha256:7be666cc4599b415f320839e36367b273db8501127b38316f3b9f22f17a0b815",
233 | "sha256:8241cac0aae90b82d6b5c443b853723bcc66963970c67e56e71a2609dc4b5eaf",
234 | "sha256:82740818f2f240a5da8dfb8943b360e4f24022b093207160c77cadade47d7c85",
235 | "sha256:8897b7b7ec077c819187a123174b645eb680c13df68354ed99f9b40a50898f77",
236 | "sha256:c2c5250ff0d36fd58550252f54915776940e4e866f38f3a7866d92b32a654b86",
237 | "sha256:ca9f686517ec2c4a4ce930207f75c00bf03d94e5063cbc00a1dc42531511b7eb",
238 | "sha256:d2b3d199647468d410994dbeb8cec5816fb74feb9368aedf300af709ef507e3e",
239 | "sha256:da73d095f8590ad437cd5e9faf6628a218aa7c387e1fdf67b888b47ba56a17f0",
240 | "sha256:e167b6b710c7f7bc54e67ef593f8731e1f45aa35f8a8a7b72d6e42ec76afd4b3",
241 | "sha256:ea634401ca02367c1567f012317502ef3437522e2fc44a3ea1844de028fa4b84",
242 | "sha256:ec6597aa85ce03f3e507566b8bcdf9da2227ec86c4266bd5e6ab4d9e0cc8dab2",
243 | "sha256:f64b232348ee82f13aac22856515ce0195837f6968aeaa94a3d0353ea2ec06a6"
244 | ],
245 | "markers": "python_version >= '3.6'",
246 | "version": "==36.0.2"
247 | },
248 | "cycler": {
249 | "hashes": [
250 | "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3",
251 | "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"
252 | ],
253 | "markers": "python_version >= '3.6'",
254 | "version": "==0.11.0"
255 | },
256 | "debugpy": {
257 | "hashes": [
258 | "sha256:0d383b91efee57dbb923ba20801130cf60450a0eda60bce25bccd937de8e323a",
259 | "sha256:0e3aa2368883e83e7b689ddff3cafb595f7b711f6a065886b46a96a7fef874e7",
260 | "sha256:132defb585b518955358321d0f42f6aa815aa15b432be27db654807707c70b2f",
261 | "sha256:1ff853e60e77e1c16f85a31adb8360bb2d98ca588d7ed645b7f0985b240bdb5e",
262 | "sha256:245c7789a012f86210847ec7ee9f38c30a30d4c2223c3e111829a76c9006a5d0",
263 | "sha256:30abefefd2ff5a5481162d613cb70e60e2fa80a5eb4c994717c0f008ed25d2e1",
264 | "sha256:40de9ba137d355538432209d05e0f5fe5d0498dce761c39119ad4b950b51db31",
265 | "sha256:4de7777842da7e08652f2776c552070bbdd758557fdec73a15d7be0e4aab95ce",
266 | "sha256:5c492235d6b68f879df3bdbdb01f25c15be15682665517c2c7d0420e5658d71f",
267 | "sha256:72bcfa97f3afa0064afc77ab811f48ad4a06ac330f290b675082c24437730366",
268 | "sha256:7b79c40852991f7b6c3ea65845ed0f5f6b731c37f4f9ad9c61e2ab4bd48a9275",
269 | "sha256:8e972c717d95f56b6a3a7a29a5ede1ee8f2c3802f6f0e678203b0778eb322bf1",
270 | "sha256:8ee75844242b4537beb5899f3e60a578454d1f136b99e8d57ac424573797b94a",
271 | "sha256:a65a2499761d47df3e9ea9567109be6e73d412e00ac3ffcf74839f3ddfcdf028",
272 | "sha256:a8aaeb53e87225141fda7b9081bd87155c1debc13e2f5a532d341112d1983b65",
273 | "sha256:bd980d533d0ddfc451e03a3bb32acb2900049fec39afc3425b944ebf0889be62",
274 | "sha256:e3513399177dd37af4c1332df52da5da1d0c387e5927dc4c0709e26ee7302e8f",
275 | "sha256:eb1946efac0c0c3d411cea0b5ac772fbde744109fd9520fb0c5a51979faf05ad"
276 | ],
277 | "markers": "python_version >= '3.7'",
278 | "version": "==1.6.0"
279 | },
280 | "decorator": {
281 | "hashes": [
282 | "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330",
283 | "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"
284 | ],
285 | "markers": "python_version >= '3.5'",
286 | "version": "==5.1.1"
287 | },
288 | "defusedxml": {
289 | "hashes": [
290 | "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69",
291 | "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"
292 | ],
293 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
294 | "version": "==0.7.1"
295 | },
296 | "entrypoints": {
297 | "hashes": [
298 | "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4",
299 | "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"
300 | ],
301 | "markers": "python_version >= '3.6'",
302 | "version": "==0.4"
303 | },
304 | "executing": {
305 | "hashes": [
306 | "sha256:c6554e21c6b060590a6d3be4b82fb78f8f0194d809de5ea7df1c093763311501",
307 | "sha256:d1eef132db1b83649a3905ca6dd8897f71ac6f8cac79a7e58a1a09cf137546c9"
308 | ],
309 | "version": "==0.8.3"
310 | },
311 | "fastjsonschema": {
312 | "hashes": [
313 | "sha256:0a572f0836962d844c1fc435e200b2e4f4677e4e6611a2e3bdd01ba697c275ec",
314 | "sha256:ddb0b1d8243e6e3abb822bd14e447a89f4ab7439342912d590444831fa00b6a0"
315 | ],
316 | "version": "==2.15.3"
317 | },
318 | "fonttools": {
319 | "hashes": [
320 | "sha256:c0fdcfa8ceebd7c1b2021240bd46ef77aa8e7408cf10434be55df52384865f8e",
321 | "sha256:f829c579a8678fa939a1d9e9894d01941db869de44390adb49ce67055a06cc2a"
322 | ],
323 | "markers": "python_version >= '3.7'",
324 | "version": "==4.33.3"
325 | },
326 | "gitdb": {
327 | "hashes": [
328 | "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd",
329 | "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"
330 | ],
331 | "markers": "python_version >= '3.6'",
332 | "version": "==4.0.9"
333 | },
334 | "gitpython": {
335 | "hashes": [
336 | "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704",
337 | "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"
338 | ],
339 | "markers": "python_version >= '3.7'",
340 | "version": "==3.1.27"
341 | },
342 | "idna": {
343 | "hashes": [
344 | "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
345 | "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
346 | ],
347 | "markers": "python_version >= '3.5'",
348 | "version": "==3.3"
349 | },
350 | "importlib-metadata": {
351 | "hashes": [
352 | "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700",
353 | "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"
354 | ],
355 | "markers": "python_version >= '3.7'",
356 | "version": "==4.11.4"
357 | },
358 | "ipykernel": {
359 | "hashes": [
360 | "sha256:6f42070a5d87ecbf4a2fc27a7faae8d690fd3794825a090ddf6b00b9678a5b69",
361 | "sha256:fedc79bebd8a438162d056e0c7662d5ac8a47d1f6ef33a702e8460248dc4517f"
362 | ],
363 | "markers": "python_version >= '3.4'",
364 | "version": "==6.13.1"
365 | },
366 | "ipython": {
367 | "hashes": [
368 | "sha256:7ca74052a38fa25fe9bedf52da0be7d3fdd2fb027c3b778ea78dfe8c212937d1",
369 | "sha256:f2db3a10254241d9b447232cec8b424847f338d9d36f9a577a6192c332a46abd"
370 | ],
371 | "markers": "python_version >= '3.8'",
372 | "version": "==8.4.0"
373 | },
374 | "ipython-genutils": {
375 | "hashes": [
376 | "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8",
377 | "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"
378 | ],
379 | "version": "==0.2.0"
380 | },
381 | "ipywidgets": {
382 | "hashes": [
383 | "sha256:ab4a5596855a88b83761921c768707d65e5847068139bc1729ddfe834703542a",
384 | "sha256:e58ff58bc94d481e91ecb6e13a5cb96a87b6b8ade135e055603d0ca24593df38"
385 | ],
386 | "markers": "python_version >= '3.7'",
387 | "version": "==7.7.0"
388 | },
389 | "jedi": {
390 | "hashes": [
391 | "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d",
392 | "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"
393 | ],
394 | "markers": "python_version >= '3.6'",
395 | "version": "==0.18.1"
396 | },
397 | "jinja2": {
398 | "hashes": [
399 | "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852",
400 | "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"
401 | ],
402 | "markers": "python_version >= '3.7'",
403 | "version": "==3.1.2"
404 | },
405 | "jsonschema": {
406 | "hashes": [
407 | "sha256:1c92d2db1900b668201f1797887d66453ab1fbfea51df8e4b46236689c427baf",
408 | "sha256:9d6397ba4a6c0bf0300736057f649e3e12ecbc07d3e81a0dacb72de4e9801957"
409 | ],
410 | "markers": "python_version >= '3.7'",
411 | "version": "==4.6.0"
412 | },
413 | "jupyter-client": {
414 | "hashes": [
415 | "sha256:17d74b0d0a7b24f1c8c527b24fcf4607c56bee542ffe8e3418e50b21e514b621",
416 | "sha256:aa9a6c32054b290374f95f73bb0cae91455c58dfb84f65c8591912b8f65e6d56"
417 | ],
418 | "markers": "python_version >= '3.7'",
419 | "version": "==7.3.4"
420 | },
421 | "jupyter-core": {
422 | "hashes": [
423 | "sha256:a6de44b16b7b31d7271130c71a6792c4040f077011961138afed5e5e73181aec",
424 | "sha256:e7f5212177af7ab34179690140f188aa9bf3d322d8155ed972cbded19f55b6f3"
425 | ],
426 | "markers": "python_version >= '3.7'",
427 | "version": "==4.10.0"
428 | },
429 | "jupyterlab-pygments": {
430 | "hashes": [
431 | "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f",
432 | "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"
433 | ],
434 | "markers": "python_version >= '3.7'",
435 | "version": "==0.2.2"
436 | },
437 | "jupyterlab-widgets": {
438 | "hashes": [
439 | "sha256:c2a9bd3789f120f64d73268c066ed3b000c56bc1dda217be5cdc43e7b4ebad3f",
440 | "sha256:d5f41bc1713795385f718d44dcba47e1e1473c6289f28a95aa6b2c0782ee372a"
441 | ],
442 | "markers": "python_version >= '3.6'",
443 | "version": "==1.1.0"
444 | },
445 | "kiwisolver": {
446 | "hashes": [
447 | "sha256:0b7f50a1a25361da3440f07c58cd1d79957c2244209e4f166990e770256b6b0b",
448 | "sha256:0c380bb5ae20d829c1a5473cfcae64267b73aaa4060adc091f6df1743784aae0",
449 | "sha256:0d98dca86f77b851350c250f0149aa5852b36572514d20feeadd3c6b1efe38d0",
450 | "sha256:0e45e780a74416ef2f173189ef4387e44b5494f45e290bcb1f03735faa6779bf",
451 | "sha256:0e8afdf533b613122e4bbaf3c1e42c2a5e9e2d1dd3a0a017749a7658757cb377",
452 | "sha256:1008346a7741620ab9cc6c96e8ad9b46f7a74ce839dbb8805ddf6b119d5fc6c2",
453 | "sha256:1d1078ba770d6165abed3d9a1be1f9e79b61515de1dd00d942fa53bba79f01ae",
454 | "sha256:1dcade8f6fe12a2bb4efe2cbe22116556e3b6899728d3b2a0d3b367db323eacc",
455 | "sha256:240009fdf4fa87844f805e23f48995537a8cb8f8c361e35fda6b5ac97fcb906f",
456 | "sha256:240c2d51d098395c012ddbcb9bd7b3ba5de412a1d11840698859f51d0e643c4f",
457 | "sha256:262c248c60f22c2b547683ad521e8a3db5909c71f679b93876921549107a0c24",
458 | "sha256:2e6cda72db409eefad6b021e8a4f964965a629f577812afc7860c69df7bdb84a",
459 | "sha256:3c032c41ae4c3a321b43a3650e6ecc7406b99ff3e5279f24c9b310f41bc98479",
460 | "sha256:42f6ef9b640deb6f7d438e0a371aedd8bef6ddfde30683491b2e6f568b4e884e",
461 | "sha256:484f2a5f0307bc944bc79db235f41048bae4106ffa764168a068d88b644b305d",
462 | "sha256:69b2d6c12f2ad5f55104a36a356192cfb680c049fe5e7c1f6620fc37f119cdc2",
463 | "sha256:6e395ece147f0692ca7cdb05a028d31b83b72c369f7b4a2c1798f4b96af1e3d8",
464 | "sha256:6ece2e12e4b57bc5646b354f436416cd2a6f090c1dadcd92b0ca4542190d7190",
465 | "sha256:71469b5845b9876b8d3d252e201bef6f47bf7456804d2fbe9a1d6e19e78a1e65",
466 | "sha256:7f606d91b8a8816be476513a77fd30abe66227039bd6f8b406c348cb0247dcc9",
467 | "sha256:7f88c4b8e449908eeddb3bbd4242bd4dc2c7a15a7aa44bb33df893203f02dc2d",
468 | "sha256:81237957b15469ea9151ec8ca08ce05656090ffabc476a752ef5ad7e2644c526",
469 | "sha256:89b57c2984f4464840e4b768affeff6b6809c6150d1166938ade3e22fbe22db8",
470 | "sha256:8a830a03970c462d1a2311c90e05679da56d3bd8e78a4ba9985cb78ef7836c9f",
471 | "sha256:8ae5a071185f1a93777c79a9a1e67ac46544d4607f18d07131eece08d415083a",
472 | "sha256:8b6086aa6936865962b2cee0e7aaecf01ab6778ce099288354a7229b4d9f1408",
473 | "sha256:8ec2e55bf31b43aabe32089125dca3b46fdfe9f50afbf0756ae11e14c97b80ca",
474 | "sha256:8ff3033e43e7ca1389ee59fb7ecb8303abb8713c008a1da49b00869e92e3dd7c",
475 | "sha256:91eb4916271655dfe3a952249cb37a5c00b6ba68b4417ee15af9ba549b5ba61d",
476 | "sha256:9d2bb56309fb75a811d81ed55fbe2208aa77a3a09ff5f546ca95e7bb5fac6eff",
477 | "sha256:a4e8f072db1d6fb7a7cc05a6dbef8442c93001f4bb604f1081d8c2db3ca97159",
478 | "sha256:b1605c7c38cc6a85212dfd6a641f3905a33412e49f7c003f35f9ac6d71f67720",
479 | "sha256:b3e251e5c38ac623c5d786adb21477f018712f8c6fa54781bd38aa1c60b60fc2",
480 | "sha256:b978afdb913ca953cf128d57181da2e8798e8b6153be866ae2a9c446c6162f40",
481 | "sha256:be9a650890fb60393e60aacb65878c4a38bb334720aa5ecb1c13d0dac54dd73b",
482 | "sha256:c222f91a45da9e01a9bc4f760727ae49050f8e8345c4ff6525495f7a164c8973",
483 | "sha256:c839bf28e45d7ddad4ae8f986928dbf5a6d42ff79760d54ec8ada8fb263e097c",
484 | "sha256:cbb5eb4a2ea1ffec26268d49766cafa8f957fe5c1b41ad00733763fae77f9436",
485 | "sha256:e348f1904a4fab4153407f7ccc27e43b2a139752e8acf12e6640ba683093dd96",
486 | "sha256:e677cc3626287f343de751e11b1e8a5b915a6ac897e8aecdbc996cd34de753a0",
487 | "sha256:f74f2a13af201559e3d32b9ddfc303c94ae63d63d7f4326d06ce6fe67e7a8255",
488 | "sha256:fa4d97d7d2b2c082e67907c0b8d9f31b85aa5d3ba0d33096b7116f03f8061261",
489 | "sha256:ffbdb9a96c536f0405895b5e21ee39ec579cb0ed97bdbd169ae2b55f41d73219"
490 | ],
491 | "markers": "python_version >= '3.7'",
492 | "version": "==1.4.2"
493 | },
494 | "markupsafe": {
495 | "hashes": [
496 | "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003",
497 | "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88",
498 | "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5",
499 | "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7",
500 | "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a",
501 | "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603",
502 | "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1",
503 | "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135",
504 | "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247",
505 | "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6",
506 | "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601",
507 | "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77",
508 | "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02",
509 | "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e",
510 | "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63",
511 | "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f",
512 | "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980",
513 | "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b",
514 | "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812",
515 | "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff",
516 | "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96",
517 | "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1",
518 | "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925",
519 | "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a",
520 | "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6",
521 | "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e",
522 | "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f",
523 | "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4",
524 | "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f",
525 | "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3",
526 | "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c",
527 | "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a",
528 | "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417",
529 | "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a",
530 | "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a",
531 | "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37",
532 | "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452",
533 | "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933",
534 | "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a",
535 | "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"
536 | ],
537 | "markers": "python_version >= '3.7'",
538 | "version": "==2.1.1"
539 | },
540 | "matplotlib": {
541 | "hashes": [
542 | "sha256:03bbb3f5f78836855e127b5dab228d99551ad0642918ccbf3067fcd52ac7ac5e",
543 | "sha256:24173c23d1bcbaed5bf47b8785d27933a1ac26a5d772200a0f3e0e38f471b001",
544 | "sha256:2a0967d4156adbd0d46db06bc1a877f0370bce28d10206a5071f9ecd6dc60b79",
545 | "sha256:2e8bda1088b941ead50caabd682601bece983cadb2283cafff56e8fcddbf7d7f",
546 | "sha256:31fbc2af27ebb820763f077ec7adc79b5a031c2f3f7af446bd7909674cd59460",
547 | "sha256:364e6bca34edc10a96aa3b1d7cd76eb2eea19a4097198c1b19e89bee47ed5781",
548 | "sha256:3d8e129af95b156b41cb3be0d9a7512cc6d73e2b2109f82108f566dbabdbf377",
549 | "sha256:44c6436868186564450df8fd2fc20ed9daaef5caad699aa04069e87099f9b5a8",
550 | "sha256:48cf850ce14fa18067f2d9e0d646763681948487a8080ec0af2686468b4607a2",
551 | "sha256:49a5938ed6ef9dda560f26ea930a2baae11ea99e1c2080c8714341ecfda72a89",
552 | "sha256:4a05f2b37222319753a5d43c0a4fd97ed4ff15ab502113e3f2625c26728040cf",
553 | "sha256:4a44cdfdb9d1b2f18b1e7d315eb3843abb097869cd1ef89cfce6a488cd1b5182",
554 | "sha256:4fa28ca76ac5c2b2d54bc058b3dad8e22ee85d26d1ee1b116a6fd4d2277b6a04",
555 | "sha256:5844cea45d804174bf0fac219b4ab50774e504bef477fc10f8f730ce2d623441",
556 | "sha256:5a32ea6e12e80dedaca2d4795d9ed40f97bfa56e6011e14f31502fdd528b9c89",
557 | "sha256:6c623b355d605a81c661546af7f24414165a8a2022cddbe7380a31a4170fa2e9",
558 | "sha256:751d3815b555dcd6187ad35b21736dc12ce6925fc3fa363bbc6dc0f86f16484f",
559 | "sha256:75c406c527a3aa07638689586343f4b344fcc7ab1f79c396699eb550cd2b91f7",
560 | "sha256:77157be0fc4469cbfb901270c205e7d8adb3607af23cef8bd11419600647ceed",
561 | "sha256:7d7705022df2c42bb02937a2a824f4ec3cca915700dd80dc23916af47ff05f1a",
562 | "sha256:7f409716119fa39b03da3d9602bd9b41142fab7a0568758cd136cd80b1bf36c8",
563 | "sha256:9480842d5aadb6e754f0b8f4ebeb73065ac8be1855baa93cd082e46e770591e9",
564 | "sha256:9776e1a10636ee5f06ca8efe0122c6de57ffe7e8c843e0fb6e001e9d9256ec95",
565 | "sha256:a91426ae910819383d337ba0dc7971c7cefdaa38599868476d94389a329e599b",
566 | "sha256:b4fedaa5a9aa9ce14001541812849ed1713112651295fdddd640ea6620e6cf98",
567 | "sha256:b6c63cd01cad0ea8704f1fd586e9dc5777ccedcd42f63cbbaa3eae8dd41172a1",
568 | "sha256:b8d3f4e71e26307e8c120b72c16671d70c5cd08ae412355c11254aa8254fb87f",
569 | "sha256:c4b82c2ae6d305fcbeb0eb9c93df2602ebd2f174f6e8c8a5d92f9445baa0c1d3",
570 | "sha256:c772264631e5ae61f0bd41313bbe48e1b9bcc95b974033e1118c9caa1a84d5c6",
571 | "sha256:c87973ddec10812bddc6c286b88fdd654a666080fbe846a1f7a3b4ba7b11ab78",
572 | "sha256:e2b696699386766ef171a259d72b203a3c75d99d03ec383b97fc2054f52e15cf",
573 | "sha256:ea75df8e567743207e2b479ba3d8843537be1c146d4b1e3e395319a4e1a77fe9",
574 | "sha256:ebc27ad11df3c1661f4677a7762e57a8a91dd41b466c3605e90717c9a5f90c82",
575 | "sha256:ee0b8e586ac07f83bb2950717e66cb305e2859baf6f00a9c39cc576e0ce9629c",
576 | "sha256:ee175a571e692fc8ae8e41ac353c0e07259113f4cb063b0ec769eff9717e84bb"
577 | ],
578 | "index": "pypi",
579 | "version": "==3.5.2"
580 | },
581 | "matplotlib-inline": {
582 | "hashes": [
583 | "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee",
584 | "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"
585 | ],
586 | "markers": "python_version >= '3.5'",
587 | "version": "==0.1.3"
588 | },
589 | "millify": {
590 | "hashes": [
591 | "sha256:619defdc98b6d23f941b5ce4aaf4bf87a0e0f64cd0446ffa299be94486597f1a"
592 | ],
593 | "index": "pypi",
594 | "version": "==0.1.1"
595 | },
596 | "mistune": {
597 | "hashes": [
598 | "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e",
599 | "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"
600 | ],
601 | "version": "==0.8.4"
602 | },
603 | "nbclient": {
604 | "hashes": [
605 | "sha256:cdef7757cead1735d2c70cc66095b072dced8a1e6d1c7639ef90cd3e04a11f2e",
606 | "sha256:f251bba200a2b401a061dfd700a7a70b5772f664fb49d4a2d3e5536ec0e98c76"
607 | ],
608 | "markers": "python_version >= '3.7'",
609 | "version": "==0.6.4"
610 | },
611 | "nbconvert": {
612 | "hashes": [
613 | "sha256:223e46e27abe8596b8aed54301fadbba433b7ffea8196a68fd7b1ff509eee99d",
614 | "sha256:c56dd0b8978a1811a5654f74c727ff16ca87dd5a43abd435a1c49b840fcd8360"
615 | ],
616 | "markers": "python_version >= '3.7'",
617 | "version": "==6.5.0"
618 | },
619 | "nbformat": {
620 | "hashes": [
621 | "sha256:0d6072aaec95dddc39735c144ee8bbc6589c383fb462e4058abc855348152dad",
622 | "sha256:44ba5ca6acb80c5d5a500f1e5b83ede8cbe364d5a495c4c8cf60aaf1ba656501"
623 | ],
624 | "markers": "python_version >= '3.7'",
625 | "version": "==5.4.0"
626 | },
627 | "nest-asyncio": {
628 | "hashes": [
629 | "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2",
630 | "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65"
631 | ],
632 | "markers": "python_version >= '3.5'",
633 | "version": "==1.5.5"
634 | },
635 | "notebook": {
636 | "hashes": [
637 | "sha256:6268c9ec9048cff7a45405c990c29ac9ca40b0bc3ec29263d218c5e01f2b4e86",
638 | "sha256:8c07a3bb7640e371f8a609bdbb2366a1976c6a2589da8ef917f761a61e3ad8b1"
639 | ],
640 | "markers": "python_version >= '3.7'",
641 | "version": "==6.4.12"
642 | },
643 | "numpy": {
644 | "hashes": [
645 | "sha256:0791fbd1e43bf74b3502133207e378901272f3c156c4df4954cad833b1380207",
646 | "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887",
647 | "sha256:2d487e06ecbf1dc2f18e7efce82ded4f705f4bd0cd02677ffccfb39e5c284c7e",
648 | "sha256:37431a77ceb9307c28382c9773da9f306435135fae6b80b62a11c53cfedd8802",
649 | "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077",
650 | "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af",
651 | "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74",
652 | "sha256:4c6036521f11a731ce0648f10c18ae66d7143865f19f7299943c985cdc95afb5",
653 | "sha256:59d55e634968b8f77d3fd674a3cf0b96e85147cd6556ec64ade018f27e9479e1",
654 | "sha256:64f56fc53a2d18b1924abd15745e30d82a5782b2cab3429aceecc6875bd5add0",
655 | "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0",
656 | "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e",
657 | "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c",
658 | "sha256:b89bf9b94b3d624e7bb480344e91f68c1c6c75f026ed6755955117de00917a7c",
659 | "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3",
660 | "sha256:c1d937820db6e43bec43e8d016b9b3165dcb42892ea9f106c70fb13d430ffe72",
661 | "sha256:cc7f00008eb7d3f2489fca6f334ec19ca63e31371be28fd5dad955b16ec285bd",
662 | "sha256:d4c5d5eb2ec8da0b4f50c9a843393971f31f1d60be87e0fb0917a49133d257d6",
663 | "sha256:e96d7f3096a36c8754207ab89d4b3282ba7b49ea140e4973591852c77d09eb76",
664 | "sha256:f0725df166cf4785c0bc4cbfb320203182b1ecd30fee6e541c8752a92df6aa32",
665 | "sha256:f3eb268dbd5cfaffd9448113539e44e2dd1c5ca9ce25576f7c04a5453edc26fa",
666 | "sha256:fb7a980c81dd932381f8228a426df8aeb70d59bbcda2af075b627bbc50207cba"
667 | ],
668 | "index": "pypi",
669 | "version": "==1.22.4"
670 | },
671 | "oscrypto": {
672 | "hashes": [
673 | "sha256:2b2f1d2d42ec152ca90ccb5682f3e051fb55986e1b170ebde472b133713e7085",
674 | "sha256:6f5fef59cb5b3708321db7cca56aed8ad7e662853351e7991fcf60ec606d47a4"
675 | ],
676 | "version": "==1.3.0"
677 | },
678 | "packaging": {
679 | "hashes": [
680 | "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
681 | "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"
682 | ],
683 | "markers": "python_version >= '3.6'",
684 | "version": "==21.3"
685 | },
686 | "pandas": {
687 | "hashes": [
688 | "sha256:0010771bd9223f7afe5f051eb47c4a49534345dfa144f2f5470b27189a4dd3b5",
689 | "sha256:061609334a8182ab500a90fe66d46f6f387de62d3a9cb9aa7e62e3146c712167",
690 | "sha256:09d8be7dd9e1c4c98224c4dfe8abd60d145d934e9fc1f5f411266308ae683e6a",
691 | "sha256:295872bf1a09758aba199992c3ecde455f01caf32266d50abc1a073e828a7b9d",
692 | "sha256:3228198333dd13c90b6434ddf61aa6d57deaca98cf7b654f4ad68a2db84f8cfe",
693 | "sha256:385c52e85aaa8ea6a4c600a9b2821181a51f8be0aee3af6f2dcb41dafc4fc1d0",
694 | "sha256:51649ef604a945f781105a6d2ecf88db7da0f4868ac5d45c51cb66081c4d9c73",
695 | "sha256:5586cc95692564b441f4747c47c8a9746792e87b40a4680a2feb7794defb1ce3",
696 | "sha256:5a206afa84ed20e07603f50d22b5f0db3fb556486d8c2462d8bc364831a4b417",
697 | "sha256:5b79af3a69e5175c6fa7b4e046b21a646c8b74e92c6581a9d825687d92071b51",
698 | "sha256:5c54ea4ef3823108cd4ec7fb27ccba4c3a775e0f83e39c5e17f5094cb17748bc",
699 | "sha256:8c5bf555b6b0075294b73965adaafb39cf71c312e38c5935c93d78f41c19828a",
700 | "sha256:92bc1fc585f1463ca827b45535957815b7deb218c549b7c18402c322c7549a12",
701 | "sha256:95c1e422ced0199cf4a34385ff124b69412c4bc912011ce895582bee620dfcaa",
702 | "sha256:b8134651258bce418cb79c71adeff0a44090c98d955f6953168ba16cc285d9f7",
703 | "sha256:be67c782c4f1b1f24c2f16a157e12c2693fd510f8df18e3287c77f33d124ed07",
704 | "sha256:c072c7f06b9242c855ed8021ff970c0e8f8b10b35e2640c657d2a541c5950f59",
705 | "sha256:d0d4f13e4be7ce89d7057a786023c461dd9370040bdb5efa0a7fe76b556867a0",
706 | "sha256:df82739e00bb6daf4bba4479a40f38c718b598a84654cbd8bb498fd6b0aa8c16",
707 | "sha256:f549097993744ff8c41b5e8f2f0d3cbfaabe89b4ae32c8c08ead6cc535b80139",
708 | "sha256:ff08a14ef21d94cdf18eef7c569d66f2e24e0bc89350bcd7d243dd804e3b5eb2"
709 | ],
710 | "markers": "python_version >= '3.8'",
711 | "version": "==1.4.2"
712 | },
713 | "pandocfilters": {
714 | "hashes": [
715 | "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38",
716 | "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"
717 | ],
718 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
719 | "version": "==1.5.0"
720 | },
721 | "parso": {
722 | "hashes": [
723 | "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0",
724 | "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"
725 | ],
726 | "markers": "python_version >= '3.6'",
727 | "version": "==0.8.3"
728 | },
729 | "pexpect": {
730 | "hashes": [
731 | "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937",
732 | "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"
733 | ],
734 | "markers": "sys_platform != 'win32'",
735 | "version": "==4.8.0"
736 | },
737 | "pickleshare": {
738 | "hashes": [
739 | "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca",
740 | "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"
741 | ],
742 | "version": "==0.7.5"
743 | },
744 | "pillow": {
745 | "hashes": [
746 | "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f",
747 | "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d",
748 | "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b",
749 | "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c",
750 | "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9",
751 | "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546",
752 | "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578",
753 | "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1",
754 | "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe",
755 | "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098",
756 | "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2",
757 | "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a",
758 | "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45",
759 | "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530",
760 | "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108",
761 | "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1",
762 | "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd",
763 | "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0",
764 | "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6",
765 | "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c",
766 | "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf",
767 | "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4",
768 | "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d",
769 | "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765",
770 | "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602",
771 | "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340",
772 | "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c",
773 | "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b",
774 | "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84",
775 | "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8",
776 | "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92",
777 | "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54",
778 | "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601",
779 | "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a",
780 | "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf",
781 | "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251",
782 | "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a",
783 | "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e"
784 | ],
785 | "markers": "python_version >= '3.7'",
786 | "version": "==9.1.1"
787 | },
788 | "plost": {
789 | "editable": true,
790 | "git": "https://github.com/jrieke/plost",
791 | "ref": "7cdd932077c9b56f2e6b3c87e8095f76679bf30d"
792 | },
793 | "prometheus-client": {
794 | "hashes": [
795 | "sha256:522fded625282822a89e2773452f42df14b5a8e84a86433e3f8a189c1d54dc01",
796 | "sha256:5459c427624961076277fdc6dc50540e2bacb98eebde99886e59ec55ed92093a"
797 | ],
798 | "markers": "python_version >= '3.6'",
799 | "version": "==0.14.1"
800 | },
801 | "prompt-toolkit": {
802 | "hashes": [
803 | "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752",
804 | "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"
805 | ],
806 | "markers": "python_full_version >= '3.6.2'",
807 | "version": "==3.0.29"
808 | },
809 | "protobuf": {
810 | "hashes": [
811 | "sha256:06059eb6953ff01e56a25cd02cca1a9649a75a7e65397b5b9b4e929ed71d10cf",
812 | "sha256:097c5d8a9808302fb0da7e20edf0b8d4703274d140fd25c5edabddcde43e081f",
813 | "sha256:284f86a6207c897542d7e956eb243a36bb8f9564c1742b253462386e96c6b78f",
814 | "sha256:32ca378605b41fd180dfe4e14d3226386d8d1b002ab31c969c366549e66a2bb7",
815 | "sha256:3cc797c9d15d7689ed507b165cd05913acb992d78b379f6014e013f9ecb20996",
816 | "sha256:62f1b5c4cd6c5402b4e2d63804ba49a327e0c386c99b1675c8a0fefda23b2067",
817 | "sha256:69ccfdf3657ba59569c64295b7d51325f91af586f8d5793b734260dfe2e94e2c",
818 | "sha256:6f50601512a3d23625d8a85b1638d914a0970f17920ff39cec63aaef80a93fb7",
819 | "sha256:7403941f6d0992d40161aa8bb23e12575637008a5a02283a930addc0508982f9",
820 | "sha256:755f3aee41354ae395e104d62119cb223339a8f3276a0cd009ffabfcdd46bb0c",
821 | "sha256:77053d28427a29987ca9caf7b72ccafee011257561259faba8dd308fda9a8739",
822 | "sha256:7e371f10abe57cee5021797126c93479f59fccc9693dafd6bd5633ab67808a91",
823 | "sha256:9016d01c91e8e625141d24ec1b20fed584703e527d28512aa8c8707f105a683c",
824 | "sha256:9be73ad47579abc26c12024239d3540e6b765182a91dbc88e23658ab71767153",
825 | "sha256:adc31566d027f45efe3f44eeb5b1f329da43891634d61c75a5944e9be6dd42c9",
826 | "sha256:adfc6cf69c7f8c50fd24c793964eef18f0ac321315439d94945820612849c388",
827 | "sha256:af0ebadc74e281a517141daad9d0f2c5d93ab78e9d455113719a45a49da9db4e",
828 | "sha256:cb29edb9eab15742d791e1025dd7b6a8f6fcb53802ad2f6e3adcb102051063ab",
829 | "sha256:cd68be2559e2a3b84f517fb029ee611546f7812b1fdd0aa2ecc9bc6ec0e4fdde",
830 | "sha256:cdee09140e1cd184ba9324ec1df410e7147242b94b5f8b0c64fc89e38a8ba531",
831 | "sha256:db977c4ca738dd9ce508557d4fce0f5aebd105e158c725beec86feb1f6bc20d8",
832 | "sha256:dd5789b2948ca702c17027c84c2accb552fc30f4622a98ab5c51fcfe8c50d3e7",
833 | "sha256:e250a42f15bf9d5b09fe1b293bdba2801cd520a9f5ea2d7fb7536d4441811d20",
834 | "sha256:ff8d8fa42675249bb456f5db06c00de6c2f4c27a065955917b28c4f15978b9c3"
835 | ],
836 | "markers": "python_version >= '3.7'",
837 | "version": "==3.20.1"
838 | },
839 | "psutil": {
840 | "hashes": [
841 | "sha256:068935df39055bf27a29824b95c801c7a5130f118b806eee663cad28dca97685",
842 | "sha256:0904727e0b0a038830b019551cf3204dd48ef5c6868adc776e06e93d615fc5fc",
843 | "sha256:0f15a19a05f39a09327345bc279c1ba4a8cfb0172cc0d3c7f7d16c813b2e7d36",
844 | "sha256:19f36c16012ba9cfc742604df189f2f28d2720e23ff7d1e81602dbe066be9fd1",
845 | "sha256:20b27771b077dcaa0de1de3ad52d22538fe101f9946d6dc7869e6f694f079329",
846 | "sha256:28976df6c64ddd6320d281128817f32c29b539a52bdae5e192537bc338a9ec81",
847 | "sha256:29a442e25fab1f4d05e2655bb1b8ab6887981838d22effa2396d584b740194de",
848 | "sha256:3054e923204b8e9c23a55b23b6df73a8089ae1d075cb0bf711d3e9da1724ded4",
849 | "sha256:32c52611756096ae91f5d1499fe6c53b86f4a9ada147ee42db4991ba1520e574",
850 | "sha256:3a76ad658641172d9c6e593de6fe248ddde825b5866464c3b2ee26c35da9d237",
851 | "sha256:44d1826150d49ffd62035785a9e2c56afcea66e55b43b8b630d7706276e87f22",
852 | "sha256:4b6750a73a9c4a4e689490ccb862d53c7b976a2a35c4e1846d049dcc3f17d83b",
853 | "sha256:56960b9e8edcca1456f8c86a196f0c3d8e3e361320071c93378d41445ffd28b0",
854 | "sha256:57f1819b5d9e95cdfb0c881a8a5b7d542ed0b7c522d575706a80bedc848c8954",
855 | "sha256:58678bbadae12e0db55186dc58f2888839228ac9f41cc7848853539b70490021",
856 | "sha256:645bd4f7bb5b8633803e0b6746ff1628724668681a434482546887d22c7a9537",
857 | "sha256:799759d809c31aab5fe4579e50addf84565e71c1dc9f1c31258f159ff70d3f87",
858 | "sha256:79c9108d9aa7fa6fba6e668b61b82facc067a6b81517cab34d07a84aa89f3df0",
859 | "sha256:91c7ff2a40c373d0cc9121d54bc5f31c4fa09c346528e6a08d1845bce5771ffc",
860 | "sha256:9272167b5f5fbfe16945be3db475b3ce8d792386907e673a209da686176552af",
861 | "sha256:944c4b4b82dc4a1b805329c980f270f170fdc9945464223f2ec8e57563139cf4",
862 | "sha256:a6a11e48cb93a5fa606306493f439b4aa7c56cb03fc9ace7f6bfa21aaf07c453",
863 | "sha256:a8746bfe4e8f659528c5c7e9af5090c5a7d252f32b2e859c584ef7d8efb1e689",
864 | "sha256:abd9246e4cdd5b554a2ddd97c157e292ac11ef3e7af25ac56b08b455c829dca8",
865 | "sha256:b14ee12da9338f5e5b3a3ef7ca58b3cba30f5b66f7662159762932e6d0b8f680",
866 | "sha256:b88f75005586131276634027f4219d06e0561292be8bd6bc7f2f00bdabd63c4e",
867 | "sha256:c7be9d7f5b0d206f0bbc3794b8e16fb7dbc53ec9e40bbe8787c6f2d38efcf6c9",
868 | "sha256:d2d006286fbcb60f0b391741f520862e9b69f4019b4d738a2a45728c7e952f1b",
869 | "sha256:db417f0865f90bdc07fa30e1aadc69b6f4cad7f86324b02aa842034efe8d8c4d",
870 | "sha256:e7e10454cb1ab62cc6ce776e1c135a64045a11ec4c6d254d3f7689c16eb3efd2",
871 | "sha256:f65f9a46d984b8cd9b3750c2bdb419b2996895b005aefa6cbaba9a143b1ce2c5",
872 | "sha256:fea896b54f3a4ae6f790ac1d017101252c93f6fe075d0e7571543510f11d2676"
873 | ],
874 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
875 | "version": "==5.9.1"
876 | },
877 | "ptyprocess": {
878 | "hashes": [
879 | "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35",
880 | "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"
881 | ],
882 | "version": "==0.7.0"
883 | },
884 | "pure-eval": {
885 | "hashes": [
886 | "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350",
887 | "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"
888 | ],
889 | "version": "==0.2.2"
890 | },
891 | "pyarrow": {
892 | "hashes": [
893 | "sha256:03a10daad957970e914920b793f6a49416699e791f4c827927fd4e4d892a5d16",
894 | "sha256:15511ce2f50343f3fd5e9f7c30e4d004da9134e9597e93e9c96c3985928cbe82",
895 | "sha256:1dd482ccb07c96188947ad94d7536ab696afde23ad172df8e18944ec79f55055",
896 | "sha256:25a5f7c7f36df520b0b7363ba9f51c3070799d4b05d587c60c0adaba57763479",
897 | "sha256:3bd201af6e01f475f02be88cf1f6ee9856ab98c11d8bbb6f58347c58cd07be00",
898 | "sha256:3fee786259d986f8c046100ced54d63b0c8c9f7cdb7d1bbe07dc69e0f928141c",
899 | "sha256:42b7982301a9ccd06e1dd4fabd2e8e5df74b93ce4c6b87b81eb9e2d86dc79871",
900 | "sha256:4a18a211ed888f1ac0b0ebcb99e2d9a3e913a481120ee9b1fe33d3fedb945d4e",
901 | "sha256:51e58778fcb8829fca37fbfaea7f208d5ce7ea89ea133dd13d8ce745278ee6f0",
902 | "sha256:541e7845ce5f27a861eb5b88ee165d931943347eec17b9ff1e308663531c9647",
903 | "sha256:65c7f4cc2be195e3db09296d31a654bb6d8786deebcab00f0e2455fd109d7456",
904 | "sha256:69b043a3fce064ebd9fbae6abc30e885680296e5bd5e6f7353e6a87966cf2ad7",
905 | "sha256:6ea2c54e6b5ecd64e8299d2abb40770fe83a718f5ddc3825ddd5cd28e352cce1",
906 | "sha256:78a6ac39cd793582998dac88ab5c1c1dd1e6503df6672f064f33a21937ec1d8d",
907 | "sha256:81b87b782a1366279411f7b235deab07c8c016e13f9af9f7c7b0ee564fedcc8f",
908 | "sha256:8392b9a1e837230090fe916415ed4c3433b2ddb1a798e3f6438303c70fbabcfc",
909 | "sha256:863be6bad6c53797129610930794a3e797cb7d41c0a30e6794a2ac0e42ce41b8",
910 | "sha256:8cd86e04a899bef43e25184f4b934584861d787cf7519851a8c031803d45c6d8",
911 | "sha256:95c7822eb37663e073da9892f3499fe28e84f3464711a3e555e0c5463fd53a19",
912 | "sha256:98c13b2e28a91b0fbf24b483df54a8d7814c074c2623ecef40dce1fa52f6539b",
913 | "sha256:ba2b7aa7efb59156b87987a06f5241932914e4d5bbb74a465306b00a6c808849",
914 | "sha256:c9c97c8e288847e091dfbcdf8ce51160e638346f51919a9e74fe038b2e8aee62",
915 | "sha256:cb06cacc19f3b426681f2f6803cc06ff481e7fe5b3a533b406bc5b2138843d4f",
916 | "sha256:ce64bc1da3109ef5ab9e4c60316945a7239c798098a631358e9ab39f6e5529e9",
917 | "sha256:d5ef4372559b191cafe7db8932801eee252bfc35e983304e7d60b6954576a071",
918 | "sha256:d6f1e1040413651819074ef5b500835c6c42e6c446532a1ddef8bc5054e8dba5",
919 | "sha256:deb400df8f19a90b662babceb6dd12daddda6bb357c216e558b207c0770c7654",
920 | "sha256:ea132067ec712d1b1116a841db1c95861508862b21eddbcafefbce8e4b96b867",
921 | "sha256:ece333706a94c1221ced8b299042f85fd88b5db802d71be70024433ddf3aecab",
922 | "sha256:edad25522ad509e534400d6ab98cf1872d30c31bc5e947712bfd57def7af15bb"
923 | ],
924 | "markers": "python_version >= '3.7'",
925 | "version": "==8.0.0"
926 | },
927 | "pycparser": {
928 | "hashes": [
929 | "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9",
930 | "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"
931 | ],
932 | "version": "==2.21"
933 | },
934 | "pycryptodomex": {
935 | "hashes": [
936 | "sha256:1ca8e1b4c62038bb2da55451385246f51f412c5f5eabd64812c01766a5989b4a",
937 | "sha256:298c00ea41a81a491d5b244d295d18369e5aac4b61b77b2de5b249ca61cd6659",
938 | "sha256:2aa887683eee493e015545bd69d3d21ac8d5ad582674ec98f4af84511e353e45",
939 | "sha256:2ce76ed0081fd6ac8c74edc75b9d14eca2064173af79843c24fa62573263c1f2",
940 | "sha256:3da13c2535b7aea94cc2a6d1b1b37746814c74b6e80790daddd55ca5c120a489",
941 | "sha256:406ec8cfe0c098fadb18d597dc2ee6de4428d640c0ccafa453f3d9b2e58d29e2",
942 | "sha256:4d0db8df9ffae36f416897ad184608d9d7a8c2b46c4612c6bc759b26c073f750",
943 | "sha256:530756d2faa40af4c1f74123e1d889bd07feae45bac2fd32f259a35f7aa74151",
944 | "sha256:77931df40bb5ce5e13f4de2bfc982b2ddc0198971fbd947776c8bb5050896eb2",
945 | "sha256:797a36bd1f69df9e2798e33edb4bd04e5a30478efc08f9428c087f17f65a7045",
946 | "sha256:8085bd0ad2034352eee4d4f3e2da985c2749cb7344b939f4d95ead38c2520859",
947 | "sha256:8536bc08d130cae6dcba1ea689f2913dfd332d06113904d171f2f56da6228e89",
948 | "sha256:a4d412eba5679ede84b41dbe48b1bed8f33131ab9db06c238a235334733acc5e",
949 | "sha256:aebecde2adc4a6847094d3bd6a8a9538ef3438a5ea84ac1983fcb167db614461",
950 | "sha256:b276cc4deb4a80f9dfd47a41ebb464b1fe91efd8b1b8620cf5ccf8b824b850d6",
951 | "sha256:b5a185ae79f899b01ca49f365bdf15a45d78d9856f09b0de1a41b92afce1a07f",
952 | "sha256:c4d8977ccda886d88dc3ca789de2f1adc714df912ff3934b3d0a3f3d777deafb",
953 | "sha256:c5dd3ffa663c982d7f1be9eb494a8924f6d40e2e2f7d1d27384cfab1b2ac0662",
954 | "sha256:ca88f2f7020002638276439a01ffbb0355634907d1aa5ca91f3dc0c2e44e8f3b",
955 | "sha256:d2cce1c82a7845d7e2e8a0956c6b7ed3f1661c9acf18eb120fc71e098ab5c6fe",
956 | "sha256:d709572d64825d8d59ea112e11cc7faf6007f294e9951324b7574af4251e4de8",
957 | "sha256:da8db8374295fb532b4b0c467e66800ef17d100e4d5faa2bbbd6df35502da125",
958 | "sha256:e36c7e3b5382cd5669cf199c4a04a0279a43b2a3bdd77627e9b89778ac9ec08c",
959 | "sha256:e95a4a6c54d27a84a4624d2af8bb9ee178111604653194ca6880c98dcad92f48",
960 | "sha256:ee835def05622e0c8b1435a906491760a43d0c462f065ec9143ec4b8d79f8bff",
961 | "sha256:f75009715dcf4a3d680c2338ab19dac5498f8121173a929872950f4fb3a48fbf",
962 | "sha256:f8524b8bc89470cec7ac51734907818d3620fb1637f8f8b542d650ebec42a126"
963 | ],
964 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
965 | "version": "==3.14.1"
966 | },
967 | "pydeck": {
968 | "hashes": [
969 | "sha256:7fc49b00840608068b930f9269169c7c9f3198b8b4635c934ba6d887c4e54503",
970 | "sha256:907601c99f7510e16d27d7cb62bfa145216d166a2b5c9c50cfe2b65b032ebd2e"
971 | ],
972 | "markers": "python_version >= '3.7'",
973 | "version": "==0.7.1"
974 | },
975 | "pygments": {
976 | "hashes": [
977 | "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb",
978 | "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"
979 | ],
980 | "markers": "python_version >= '3.6'",
981 | "version": "==2.12.0"
982 | },
983 | "pyjwt": {
984 | "hashes": [
985 | "sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf",
986 | "sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba"
987 | ],
988 | "markers": "python_version >= '3.6'",
989 | "version": "==2.4.0"
990 | },
991 | "pympler": {
992 | "hashes": [
993 | "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa",
994 | "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"
995 | ],
996 | "markers": "python_version >= '3.6'",
997 | "version": "==1.0.1"
998 | },
999 | "pyopenssl": {
1000 | "hashes": [
1001 | "sha256:660b1b1425aac4a1bea1d94168a85d99f0b3144c869dd4390d27629d0087f1bf",
1002 | "sha256:ea252b38c87425b64116f808355e8da644ef9b07e429398bfece610f893ee2e0"
1003 | ],
1004 | "markers": "python_version >= '3.6'",
1005 | "version": "==22.0.0"
1006 | },
1007 | "pyparsing": {
1008 | "hashes": [
1009 | "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb",
1010 | "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"
1011 | ],
1012 | "markers": "python_full_version >= '3.6.8'",
1013 | "version": "==3.0.9"
1014 | },
1015 | "pyrsistent": {
1016 | "hashes": [
1017 | "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c",
1018 | "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc",
1019 | "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e",
1020 | "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26",
1021 | "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec",
1022 | "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286",
1023 | "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045",
1024 | "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec",
1025 | "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8",
1026 | "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c",
1027 | "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca",
1028 | "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22",
1029 | "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a",
1030 | "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96",
1031 | "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc",
1032 | "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1",
1033 | "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07",
1034 | "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6",
1035 | "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b",
1036 | "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5",
1037 | "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"
1038 | ],
1039 | "markers": "python_version >= '3.7'",
1040 | "version": "==0.18.1"
1041 | },
1042 | "python-dateutil": {
1043 | "hashes": [
1044 | "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
1045 | "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
1046 | ],
1047 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1048 | "version": "==2.8.2"
1049 | },
1050 | "pytz": {
1051 | "hashes": [
1052 | "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7",
1053 | "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"
1054 | ],
1055 | "version": "==2022.1"
1056 | },
1057 | "pytz-deprecation-shim": {
1058 | "hashes": [
1059 | "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6",
1060 | "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"
1061 | ],
1062 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
1063 | "version": "==0.1.0.post0"
1064 | },
1065 | "pyzmq": {
1066 | "hashes": [
1067 | "sha256:057176dd3f5ccf5aad4abd662d76b6a39bbf799baaf2f39cd4fdaf2eab326e43",
1068 | "sha256:05ec90a8da618f2398f9d1aa20b18a9ef332992c6ac23e8c866099faad6ef0d6",
1069 | "sha256:154de02b15422af28b53d29a02de72121ba503634955017255573fc1f995143d",
1070 | "sha256:16b832adb5d8716f46051da5533c480250bf126984ce86804db6137a3a7f931b",
1071 | "sha256:1df26aa854bdd3a8341bf199064dd6aa6e240f2eaa3c9fa8d217e5d8b868c73e",
1072 | "sha256:28f9164fb2658b7b414fa0894c75b1a9c61375774cdc1bdb7298beb042a2cd87",
1073 | "sha256:2951c29b8649f3672af9dca8ff61d86310d3664d9629788b1c66422fb13b1239",
1074 | "sha256:2b08774057ae7ce8a2eb4e7d54db05358234440706ce43a85814500c5d7bd22e",
1075 | "sha256:2e2ac40f7a91c740ec68d6db07ae19ea9259c959333c68bee56ab2c799a67d66",
1076 | "sha256:312e56799410c34797417a4060a8bd37d4db1f06d1ec0c54f7c8fd81e0d90376",
1077 | "sha256:38f778a74e3889392e949326cfd0e9b2eb37dcbb2980d98fad2c51703d523db2",
1078 | "sha256:3955dd5bbbe02f454655296ee36a66c334c7102a29b8458223d168c0380edfd5",
1079 | "sha256:425ba851a6f9892bde1da2024d82e2fe6796bd77e3391fb96665c50fe9d4c6a5",
1080 | "sha256:48bbc2db041ab28eeee4a3e8ada0ed336640946dd5a8e53dbd3805f9dbdcf0dc",
1081 | "sha256:4fbcd657cda75574fd1315a4c44bd322bc2e219039fb09f146bbe6f8aef039e9",
1082 | "sha256:523ba7fd4d8fe75ad09c1e574a648892b75a97d0cfc8005727681053ac19555b",
1083 | "sha256:53b2c1326c2e484d450932d2be739f064b7cb572faabec38386098a28516a529",
1084 | "sha256:540d7146c3cdc9bbffab039ea067f494eba24d1abe5bd33eb9f963c01e3305d4",
1085 | "sha256:563d4281c4dbdf647d93114420151d33f895afc4c46b7115a67a0aa5347e6624",
1086 | "sha256:67a049bcf967a39993858beed873ed3405536019820922d4efacfe35ab3da51a",
1087 | "sha256:67ec63ae3c9c1fa2e077fcb42e77035e2121a04f987464bdf9945a28535d30ad",
1088 | "sha256:68e22c5d3be451e87d47f956b397a7823bfbde2176341bc902fba30f96831d7e",
1089 | "sha256:6ab4b6108e69f63c917cd7ef7217c5727955b1ac90600e44a13ed5312019a014",
1090 | "sha256:6bd7f18bd4cf51ea8d7e54825902cf36f9d2f35cc51ef618373988d5398b8dd0",
1091 | "sha256:6cd53e861bccc0bdc4620f68fb4a91d5bcfe9f4213cf8e200fa498044d33a6dc",
1092 | "sha256:6d346e551fa64b89d57a4ac74b9bc66703413f02f50093e089e861999ec5cccc",
1093 | "sha256:6ff8708fabc9f9bc2949f457d39b4088c9656c4c9ac15fbbbbaafce8f6d07833",
1094 | "sha256:7626e8384275a7dea6f3d1f749fb5e00299042e9c895fc3dbe24cb154909c242",
1095 | "sha256:7e7346b2b33dcd4a2171dd8a9870ae283eec8f6231dcbcf237a0f41e74751a50",
1096 | "sha256:81623c67cb71b93b5f7e06c9107f3781738ae86866db830c950223d87af2a235",
1097 | "sha256:83f1c76068faf62c32a36dd62dc4db642c2027bbbd960f8f6345b59e9d4dc472",
1098 | "sha256:8679bb1dd723ecbea03b1f96c98972815775fd8ec756c440a14f289c436c472e",
1099 | "sha256:86fb683cb9a9c0bb7476988b7957393ecdd22777d87d804442c66e62c99197f9",
1100 | "sha256:8757c62f7960cd26122f7aaaf86eda1e016fa85734c3777b8054dd334d7dea4d",
1101 | "sha256:894be7d17228e7328cc188096c0162697211ec91761f6812fff12790cbe11c66",
1102 | "sha256:8a0f240bf43c29be1bd82d77e602a61c798e9de02e5f8bb7bb414cb814f43236",
1103 | "sha256:8c3abf7eab5b76ae162c4fbb16d514a947fc57fd995b64e5ea8ef8ba3b888a69",
1104 | "sha256:93332c6972e4c91522c4810e907f3aea067424338071161b39cacded022559df",
1105 | "sha256:97d6c676dc97d593625d9fc48154f2ffeabb619a1e6fe8d2a5b53f97e3e9bdee",
1106 | "sha256:99dd85f0ca1db8d17a01a25c2bbb7784d25a2d39497c6beddbe96bff74194e04",
1107 | "sha256:9c7fb691fb07ec7ab99fd173bb0e7e0248d31bf83d484a87b917a342f63812c9",
1108 | "sha256:b3bc3cf200aab74f3d758586ac50295214eda496ac6a6636e0c881c5958d9123",
1109 | "sha256:bba54f97578943f48f621b4a7afb8eb022370da26a88b88ccc9fee9f3ef7ce45",
1110 | "sha256:bd2a13a0f8367e50347cbac87ae230ae1953935443240238f956bf10668bead6",
1111 | "sha256:cbc1184349ca6e5112898aa7fc3efa1b1bbae24ab1edc774cfd09cbfd3b091d7",
1112 | "sha256:cd82cca9c489e441574804dbda2dd8e114cf3be7935b03de11dade2c9478aea6",
1113 | "sha256:ce8ba5ed8b0a7a203922d61cff45ee6001a41a9359f04f00d055a4e988755569",
1114 | "sha256:cfee22e072a382b92ee0709dbb8203dabd52d54258051e770d9d2a81b162530b",
1115 | "sha256:d977df6f7c4109ed1d96ffb6795f6af77114be606ae4556efbfc9cac725db65d",
1116 | "sha256:da72a384a1d7e87490ca71182f3ab469ed21d847adc16b70c34faac5a3b12801",
1117 | "sha256:ddf4ad1d651e6c9234945061e1a31fe27a4be0dea21c498b87b186fadf8f5919",
1118 | "sha256:eb0ae5dfda83bbce660179d7b41c1c38fd833a54d2e6d9b258c644f3b75ef94d",
1119 | "sha256:f4c7d370badc60ac94a554bc571a46d03e39d8aacfba8006b334512e184aed59",
1120 | "sha256:f6c378b435a26fda8996579c0e324b108d2ca0d01b4661503a75634e5155559f",
1121 | "sha256:f6c9d30888503f2f5f87d6d41f016301352dd98da4a861bd10663c3a2d99d3b5",
1122 | "sha256:fab8a7877275060f7b303e1f91c218069a2814a616b6a5ee2d8a3737deb15915",
1123 | "sha256:fc32e7d7f98cac3d8d5153ed2cb583158ae3d446a6efb8e28ccb1c54a09f4169"
1124 | ],
1125 | "markers": "python_version >= '3.6'",
1126 | "version": "==23.1.0"
1127 | },
1128 | "requests": {
1129 | "hashes": [
1130 | "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f",
1131 | "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"
1132 | ],
1133 | "index": "pypi",
1134 | "version": "==2.28.0"
1135 | },
1136 | "rich": {
1137 | "hashes": [
1138 | "sha256:4c586de507202505346f3e32d1363eb9ed6932f0c2f63184dea88983ff4971e2",
1139 | "sha256:d2bbd99c320a2532ac71ff6a3164867884357da3e3301f0240090c5d2fdac7ec"
1140 | ],
1141 | "markers": "python_version < '4' and python_full_version >= '3.6.3'",
1142 | "version": "==12.4.4"
1143 | },
1144 | "semver": {
1145 | "hashes": [
1146 | "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4",
1147 | "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"
1148 | ],
1149 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1150 | "version": "==2.13.0"
1151 | },
1152 | "send2trash": {
1153 | "hashes": [
1154 | "sha256:d2c24762fd3759860a0aff155e45871447ea58d2be6bdd39b5c8f966a0c99c2d",
1155 | "sha256:f20eaadfdb517eaca5ce077640cb261c7d2698385a6a0f072a4a5447fd49fa08"
1156 | ],
1157 | "version": "==1.8.0"
1158 | },
1159 | "setuptools": {
1160 | "hashes": [
1161 | "sha256:d1746e7fd520e83bbe210d02fff1aa1a425ad671c7a9da7d246ec2401a087198",
1162 | "sha256:e7d11f3db616cda0751372244c2ba798e8e56a28e096ec4529010b803485f3fe"
1163 | ],
1164 | "markers": "python_version >= '3.7'",
1165 | "version": "==62.3.3"
1166 | },
1167 | "six": {
1168 | "hashes": [
1169 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
1170 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
1171 | ],
1172 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1173 | "version": "==1.16.0"
1174 | },
1175 | "smmap": {
1176 | "hashes": [
1177 | "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94",
1178 | "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"
1179 | ],
1180 | "markers": "python_version >= '3.6'",
1181 | "version": "==5.0.0"
1182 | },
1183 | "snowflake-connector-python": {
1184 | "hashes": [
1185 | "sha256:05ca68da880a73d366c16605e7debf04b257ed08a19d0f32fe383394d8dbb923",
1186 | "sha256:5b1752d45c897fbb3b4a582702a28519ec7c1b4025c4f1d6845b8d0431077697",
1187 | "sha256:606aa9ef66c540f1474d0e2c03720750487bfa1998ad4089c454c14f1b5373d6",
1188 | "sha256:62ba074b03e359edd409866c6e9c330c6d009bfeab5533d04dfe328e13e99ae8",
1189 | "sha256:714a27d322ff9f1f078cbf2a3209633743475fc05e4f6caee39f7859f2e68d69",
1190 | "sha256:98e3ed26ea976af6b09e3b015c4fa0d626bf36ffdb550bee81d9b88a50ea76b4",
1191 | "sha256:9cfb07b048bcb1fe646d03f7480ccb6a877e9c45067302e90bcff7fd72f6bc2f",
1192 | "sha256:9f49fe81994bf38f4c44cd5df6b2f1a5df4735625d0a516ba689dcbc6eb8fa7e",
1193 | "sha256:ac18f39e1dfc703fb4668e1a133887fab999a314acec7ad7c55dfeab50b5a247",
1194 | "sha256:b4cd78bf75f98afbbf02f5eb2cd2f735b0c212f7f679384aee358bb84930e1aa",
1195 | "sha256:bbd4d74837f25aa673f02ff450233bc81858af872192b45b11e11e0c2531d669",
1196 | "sha256:ca7a26c4d628a552811d2235a88d5ba9bce2b1931d46c6f3aaa7db4edc20a616",
1197 | "sha256:db828f6091160db51447eb713438576d0f62f2d963b260e1d3b753f37033284c",
1198 | "sha256:e597c51133e1ab7c63bdc3031a40b58d833d6e56b96fcc61e23bdfaad58aff3c",
1199 | "sha256:f7b08aba0ed5b33ff869d3e28848919cfc593753f24fd1b68fd7f3f8424691c8",
1200 | "sha256:ff414bf9649cc72b6f5254491b233c8b64f29f82a1c4578ff7a6b14fc2576436"
1201 | ],
1202 | "index": "pypi",
1203 | "version": "==2.7.8"
1204 | },
1205 | "soupsieve": {
1206 | "hashes": [
1207 | "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759",
1208 | "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"
1209 | ],
1210 | "markers": "python_version >= '3.6'",
1211 | "version": "==2.3.2.post1"
1212 | },
1213 | "sqlparse": {
1214 | "hashes": [
1215 | "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae",
1216 | "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"
1217 | ],
1218 | "index": "pypi",
1219 | "version": "==0.4.2"
1220 | },
1221 | "stack-data": {
1222 | "hashes": [
1223 | "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12",
1224 | "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e"
1225 | ],
1226 | "version": "==0.2.0"
1227 | },
1228 | "streamlit": {
1229 | "hashes": [
1230 | "sha256:4febd37144a62177e583d6970ab50f351a2bfd4eb112cf19e38c25b12246a4db",
1231 | "sha256:9479d623dd4bec1fc7bd27e85d5012672351210e640889022ee7b4631c4efb2c"
1232 | ],
1233 | "index": "pypi",
1234 | "version": "==1.10.0"
1235 | },
1236 | "terminado": {
1237 | "hashes": [
1238 | "sha256:0d5f126fbfdb5887b25ae7d9d07b0d716b1cc0ccaacc71c1f3c14d228e065197",
1239 | "sha256:ab4eeedccfcc1e6134bfee86106af90852c69d602884ea3a1e8ca6d4486e9bfe"
1240 | ],
1241 | "markers": "python_version >= '3.7'",
1242 | "version": "==0.15.0"
1243 | },
1244 | "tinycss2": {
1245 | "hashes": [
1246 | "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf",
1247 | "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8"
1248 | ],
1249 | "markers": "python_version >= '3.6'",
1250 | "version": "==1.1.1"
1251 | },
1252 | "toml": {
1253 | "hashes": [
1254 | "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
1255 | "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
1256 | ],
1257 | "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1258 | "version": "==0.10.2"
1259 | },
1260 | "toolz": {
1261 | "hashes": [
1262 | "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33",
1263 | "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"
1264 | ],
1265 | "markers": "python_version >= '3.5'",
1266 | "version": "==0.11.2"
1267 | },
1268 | "tornado": {
1269 | "hashes": [
1270 | "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb",
1271 | "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c",
1272 | "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288",
1273 | "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95",
1274 | "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558",
1275 | "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe",
1276 | "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791",
1277 | "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d",
1278 | "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326",
1279 | "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b",
1280 | "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4",
1281 | "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c",
1282 | "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910",
1283 | "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5",
1284 | "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c",
1285 | "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0",
1286 | "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675",
1287 | "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd",
1288 | "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f",
1289 | "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c",
1290 | "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea",
1291 | "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6",
1292 | "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05",
1293 | "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd",
1294 | "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575",
1295 | "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a",
1296 | "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37",
1297 | "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795",
1298 | "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f",
1299 | "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32",
1300 | "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c",
1301 | "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01",
1302 | "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4",
1303 | "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2",
1304 | "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921",
1305 | "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085",
1306 | "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df",
1307 | "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102",
1308 | "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5",
1309 | "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68",
1310 | "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"
1311 | ],
1312 | "markers": "python_version >= '3.5'",
1313 | "version": "==6.1"
1314 | },
1315 | "traitlets": {
1316 | "hashes": [
1317 | "sha256:1530d04badddc6a73d50b7ee34667d4b96914da352109117b4280cb56523a51b",
1318 | "sha256:74803a1baa59af70f023671d86d5c7a834c931186df26d50d362ee6a1ff021fd"
1319 | ],
1320 | "markers": "python_version >= '3.7'",
1321 | "version": "==5.2.2.post1"
1322 | },
1323 | "typing-extensions": {
1324 | "hashes": [
1325 | "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708",
1326 | "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"
1327 | ],
1328 | "markers": "python_version >= '3.7'",
1329 | "version": "==4.2.0"
1330 | },
1331 | "tzdata": {
1332 | "hashes": [
1333 | "sha256:238e70234214138ed7b4e8a0fab0e5e13872edab3be586ab8198c407620e2ab9",
1334 | "sha256:8b536a8ec63dc0751342b3984193a3118f8fca2afe25752bb9b7fffd398552d3"
1335 | ],
1336 | "markers": "python_version >= '3.6'",
1337 | "version": "==2022.1"
1338 | },
1339 | "tzlocal": {
1340 | "hashes": [
1341 | "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745",
1342 | "sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"
1343 | ],
1344 | "markers": "python_version >= '3.6'",
1345 | "version": "==4.2"
1346 | },
1347 | "urllib3": {
1348 | "hashes": [
1349 | "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14",
1350 | "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"
1351 | ],
1352 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
1353 | "version": "==1.26.9"
1354 | },
1355 | "validators": {
1356 | "hashes": [
1357 | "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a"
1358 | ],
1359 | "markers": "python_version >= '3.4'",
1360 | "version": "==0.20.0"
1361 | },
1362 | "wcwidth": {
1363 | "hashes": [
1364 | "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784",
1365 | "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"
1366 | ],
1367 | "version": "==0.2.5"
1368 | },
1369 | "webencodings": {
1370 | "hashes": [
1371 | "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
1372 | "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
1373 | ],
1374 | "version": "==0.5.1"
1375 | },
1376 | "widgetsnbextension": {
1377 | "hashes": [
1378 | "sha256:4fd321cad39fdcf8a8e248a657202d42917ada8e8ed5dd3f60f073e0d54ceabd",
1379 | "sha256:e84a7a9fcb9baf3d57106e184a7389a8f8eb935bf741a5eb9d60aa18cc029a80"
1380 | ],
1381 | "markers": "python_version >= '3.7'",
1382 | "version": "==3.6.0"
1383 | },
1384 | "zipp": {
1385 | "hashes": [
1386 | "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad",
1387 | "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"
1388 | ],
1389 | "markers": "python_version >= '3.7'",
1390 | "version": "==3.8.0"
1391 | }
1392 | },
1393 | "develop": {
1394 | "attrs": {
1395 | "hashes": [
1396 | "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4",
1397 | "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"
1398 | ],
1399 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
1400 | "version": "==21.4.0"
1401 | },
1402 | "black": {
1403 | "hashes": [
1404 | "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b",
1405 | "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176",
1406 | "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09",
1407 | "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a",
1408 | "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015",
1409 | "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79",
1410 | "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb",
1411 | "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20",
1412 | "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464",
1413 | "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968",
1414 | "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82",
1415 | "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21",
1416 | "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0",
1417 | "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265",
1418 | "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b",
1419 | "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a",
1420 | "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72",
1421 | "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce",
1422 | "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0",
1423 | "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a",
1424 | "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163",
1425 | "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad",
1426 | "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"
1427 | ],
1428 | "index": "pypi",
1429 | "version": "==22.3.0"
1430 | },
1431 | "cfgv": {
1432 | "hashes": [
1433 | "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426",
1434 | "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"
1435 | ],
1436 | "markers": "python_full_version >= '3.6.1'",
1437 | "version": "==3.3.1"
1438 | },
1439 | "click": {
1440 | "hashes": [
1441 | "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
1442 | "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
1443 | ],
1444 | "markers": "python_version >= '3.7'",
1445 | "version": "==8.1.3"
1446 | },
1447 | "distlib": {
1448 | "hashes": [
1449 | "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b",
1450 | "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"
1451 | ],
1452 | "version": "==0.3.4"
1453 | },
1454 | "filelock": {
1455 | "hashes": [
1456 | "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404",
1457 | "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"
1458 | ],
1459 | "markers": "python_version >= '3.7'",
1460 | "version": "==3.7.1"
1461 | },
1462 | "flake8": {
1463 | "hashes": [
1464 | "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d",
1465 | "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"
1466 | ],
1467 | "index": "pypi",
1468 | "version": "==4.0.1"
1469 | },
1470 | "flake8-bugbear": {
1471 | "hashes": [
1472 | "sha256:ec374101cddf65bd7a96d393847d74e58d3b98669dbf9768344c39b6290e8bd6",
1473 | "sha256:f7c080563fca75ee6b205d06b181ecba22b802babb96b0b084cc7743d6908a55"
1474 | ],
1475 | "index": "pypi",
1476 | "version": "==22.4.25"
1477 | },
1478 | "greenlet": {
1479 | "hashes": [
1480 | "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3",
1481 | "sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711",
1482 | "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd",
1483 | "sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073",
1484 | "sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708",
1485 | "sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67",
1486 | "sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23",
1487 | "sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1",
1488 | "sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08",
1489 | "sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd",
1490 | "sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2",
1491 | "sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa",
1492 | "sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8",
1493 | "sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40",
1494 | "sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab",
1495 | "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6",
1496 | "sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc",
1497 | "sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b",
1498 | "sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e",
1499 | "sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963",
1500 | "sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3",
1501 | "sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d",
1502 | "sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d",
1503 | "sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe",
1504 | "sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28",
1505 | "sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3",
1506 | "sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e",
1507 | "sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c",
1508 | "sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d",
1509 | "sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0",
1510 | "sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497",
1511 | "sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee",
1512 | "sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713",
1513 | "sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58",
1514 | "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a",
1515 | "sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06",
1516 | "sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88",
1517 | "sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965",
1518 | "sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f",
1519 | "sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4",
1520 | "sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5",
1521 | "sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c",
1522 | "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a",
1523 | "sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1",
1524 | "sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43",
1525 | "sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627",
1526 | "sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b",
1527 | "sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168",
1528 | "sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d",
1529 | "sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5",
1530 | "sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478",
1531 | "sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf",
1532 | "sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce",
1533 | "sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c",
1534 | "sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b"
1535 | ],
1536 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
1537 | "version": "==1.1.2"
1538 | },
1539 | "identify": {
1540 | "hashes": [
1541 | "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa",
1542 | "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"
1543 | ],
1544 | "markers": "python_version >= '3.7'",
1545 | "version": "==2.5.1"
1546 | },
1547 | "mccabe": {
1548 | "hashes": [
1549 | "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
1550 | "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
1551 | ],
1552 | "version": "==0.6.1"
1553 | },
1554 | "msgpack": {
1555 | "hashes": [
1556 | "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467",
1557 | "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae",
1558 | "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92",
1559 | "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef",
1560 | "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624",
1561 | "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227",
1562 | "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88",
1563 | "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9",
1564 | "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8",
1565 | "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd",
1566 | "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6",
1567 | "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55",
1568 | "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e",
1569 | "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2",
1570 | "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44",
1571 | "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6",
1572 | "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9",
1573 | "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab",
1574 | "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae",
1575 | "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa",
1576 | "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9",
1577 | "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e",
1578 | "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250",
1579 | "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce",
1580 | "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075",
1581 | "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236",
1582 | "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae",
1583 | "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e",
1584 | "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f",
1585 | "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08",
1586 | "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6",
1587 | "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d",
1588 | "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43",
1589 | "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1",
1590 | "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6",
1591 | "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0",
1592 | "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c",
1593 | "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff",
1594 | "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db",
1595 | "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243",
1596 | "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661",
1597 | "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba",
1598 | "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e",
1599 | "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb",
1600 | "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52",
1601 | "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6",
1602 | "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1",
1603 | "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f",
1604 | "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da",
1605 | "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f",
1606 | "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c",
1607 | "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8"
1608 | ],
1609 | "version": "==1.0.4"
1610 | },
1611 | "mypy": {
1612 | "hashes": [
1613 | "sha256:006be38474216b833eca29ff6b73e143386f352e10e9c2fbe76aa8549e5554f5",
1614 | "sha256:03c6cc893e7563e7b2949b969e63f02c000b32502a1b4d1314cabe391aa87d66",
1615 | "sha256:0e9f70df36405c25cc530a86eeda1e0867863d9471fe76d1273c783df3d35c2e",
1616 | "sha256:1ece702f29270ec6af25db8cf6185c04c02311c6bb21a69f423d40e527b75c56",
1617 | "sha256:3e09f1f983a71d0672bbc97ae33ee3709d10c779beb613febc36805a6e28bb4e",
1618 | "sha256:439c726a3b3da7ca84a0199a8ab444cd8896d95012c4a6c4a0d808e3147abf5d",
1619 | "sha256:5a0b53747f713f490affdceef835d8f0cb7285187a6a44c33821b6d1f46ed813",
1620 | "sha256:5f1332964963d4832a94bebc10f13d3279be3ce8f6c64da563d6ee6e2eeda932",
1621 | "sha256:63e85a03770ebf403291ec50097954cc5caf2a9205c888ce3a61bd3f82e17569",
1622 | "sha256:64759a273d590040a592e0f4186539858c948302c653c2eac840c7a3cd29e51b",
1623 | "sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0",
1624 | "sha256:9940e6916ed9371809b35b2154baf1f684acba935cd09928952310fbddaba648",
1625 | "sha256:9f5f5a74085d9a81a1f9c78081d60a0040c3efb3f28e5c9912b900adf59a16e6",
1626 | "sha256:a5ea0875a049de1b63b972456542f04643daf320d27dc592d7c3d9cd5d9bf950",
1627 | "sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15",
1628 | "sha256:b24be97351084b11582fef18d79004b3e4db572219deee0212078f7cf6352723",
1629 | "sha256:b88f784e9e35dcaa075519096dc947a388319cb86811b6af621e3523980f1c8a",
1630 | "sha256:bdd5ca340beffb8c44cb9dc26697628d1b88c6bddf5c2f6eb308c46f269bb6f3",
1631 | "sha256:d5aaf1edaa7692490f72bdb9fbd941fbf2e201713523bdb3f4038be0af8846c6",
1632 | "sha256:e999229b9f3198c0c880d5e269f9f8129c8862451ce53a011326cad38b9ccd24",
1633 | "sha256:f4a21d01fc0ba4e31d82f0fff195682e29f9401a8bdb7173891070eb260aeb3b",
1634 | "sha256:f4b794db44168a4fc886e3450201365c9526a522c46ba089b55e1f11c163750d",
1635 | "sha256:f730d56cb924d371c26b8eaddeea3cc07d78ff51c521c6d04899ac6904b75492"
1636 | ],
1637 | "index": "pypi",
1638 | "version": "==0.961"
1639 | },
1640 | "mypy-extensions": {
1641 | "hashes": [
1642 | "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
1643 | "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
1644 | ],
1645 | "version": "==0.4.3"
1646 | },
1647 | "nodeenv": {
1648 | "hashes": [
1649 | "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b",
1650 | "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"
1651 | ],
1652 | "version": "==1.6.0"
1653 | },
1654 | "pathspec": {
1655 | "hashes": [
1656 | "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a",
1657 | "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"
1658 | ],
1659 | "version": "==0.9.0"
1660 | },
1661 | "platformdirs": {
1662 | "hashes": [
1663 | "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788",
1664 | "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"
1665 | ],
1666 | "markers": "python_version >= '3.7'",
1667 | "version": "==2.5.2"
1668 | },
1669 | "pre-commit": {
1670 | "hashes": [
1671 | "sha256:10c62741aa5704faea2ad69cb550ca78082efe5697d6f04e5710c3c229afdd10",
1672 | "sha256:4233a1e38621c87d9dda9808c6606d7e7ba0e087cd56d3fe03202a01d2919615"
1673 | ],
1674 | "index": "pypi",
1675 | "version": "==2.19.0"
1676 | },
1677 | "pycodestyle": {
1678 | "hashes": [
1679 | "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20",
1680 | "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"
1681 | ],
1682 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
1683 | "version": "==2.8.0"
1684 | },
1685 | "pyflakes": {
1686 | "hashes": [
1687 | "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c",
1688 | "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"
1689 | ],
1690 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1691 | "version": "==2.4.0"
1692 | },
1693 | "pynvim": {
1694 | "hashes": [
1695 | "sha256:3a795378bde5e8092fbeb3a1a99be9c613d2685542f1db0e5c6fd467eed56dff"
1696 | ],
1697 | "index": "pypi",
1698 | "version": "==0.4.3"
1699 | },
1700 | "pyyaml": {
1701 | "hashes": [
1702 | "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293",
1703 | "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b",
1704 | "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57",
1705 | "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b",
1706 | "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4",
1707 | "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07",
1708 | "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba",
1709 | "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9",
1710 | "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287",
1711 | "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513",
1712 | "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0",
1713 | "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0",
1714 | "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92",
1715 | "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f",
1716 | "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2",
1717 | "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc",
1718 | "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c",
1719 | "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86",
1720 | "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4",
1721 | "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c",
1722 | "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34",
1723 | "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b",
1724 | "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c",
1725 | "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb",
1726 | "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737",
1727 | "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3",
1728 | "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d",
1729 | "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53",
1730 | "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78",
1731 | "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803",
1732 | "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a",
1733 | "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174",
1734 | "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"
1735 | ],
1736 | "markers": "python_version >= '3.6'",
1737 | "version": "==6.0"
1738 | },
1739 | "six": {
1740 | "hashes": [
1741 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
1742 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
1743 | ],
1744 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1745 | "version": "==1.16.0"
1746 | },
1747 | "toml": {
1748 | "hashes": [
1749 | "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
1750 | "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
1751 | ],
1752 | "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
1753 | "version": "==0.10.2"
1754 | },
1755 | "tomli": {
1756 | "hashes": [
1757 | "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
1758 | "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
1759 | ],
1760 | "markers": "python_version < '3.11'",
1761 | "version": "==2.0.1"
1762 | },
1763 | "typed-ast": {
1764 | "hashes": [
1765 | "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2",
1766 | "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1",
1767 | "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6",
1768 | "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62",
1769 | "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac",
1770 | "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d",
1771 | "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc",
1772 | "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2",
1773 | "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97",
1774 | "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35",
1775 | "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6",
1776 | "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1",
1777 | "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4",
1778 | "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c",
1779 | "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e",
1780 | "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec",
1781 | "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f",
1782 | "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72",
1783 | "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47",
1784 | "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72",
1785 | "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe",
1786 | "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6",
1787 | "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3",
1788 | "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"
1789 | ],
1790 | "index": "pypi",
1791 | "version": "==1.5.4"
1792 | },
1793 | "typing-extensions": {
1794 | "hashes": [
1795 | "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708",
1796 | "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"
1797 | ],
1798 | "markers": "python_version >= '3.7'",
1799 | "version": "==4.2.0"
1800 | },
1801 | "virtualenv": {
1802 | "hashes": [
1803 | "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a",
1804 | "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"
1805 | ],
1806 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
1807 | "version": "==20.14.1"
1808 | }
1809 | }
1810 | }
1811 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > [!NOTE]
2 | > Discover many more Streamlit & Snowflake apps in the [snowflake-demo-streamlit](https://github.com/Snowflake-Labs/snowflake-demo-streamlit) repository
3 |
4 | ---
5 |
6 | # Streamlit demo: 🌀 The Snowflake Usage Insights app
7 |
8 | This app provides insights on a demo Snowflake account usage.
9 |
10 | It was made using :balloon: [Streamlit](https://www.streamlit.io) and the :snowflake: [Snowflake Python connector](https://github.com/snowflakedb/snowflake-connector-python)!
11 |
12 |
13 |
14 | ### Can I use this app with my own Snowflake account?
15 |
16 | This demo app currently only supports basic username / password authentication
17 | to connect to your Snowflake account. For security purposes, we recommend cloning this app and running it **locally** instead of on Streamlit Cloud. If you're interested, head over to the next section!
18 |
19 | ### Run this app locally
20 | Follow these steps:
21 |
22 | 1. **Set up dependencies.** Get [Pipenv](https://pipenv-fork.readthedocs.io/en/latest/install.html#pragmatic-installation-of-pipenv),
23 | clone/fork this repository and within the directory, run:
24 | ```
25 | pipenv clean && pipenv install --python 3.9
26 | ```
27 |
28 | 2. **Set up credentials.** Create a file `.streamlit/secrets.toml` and fill in your Snowflake account
29 | credentials. The file should look like this:
30 | ```
31 | [sf_usage_app]
32 | user = "..."
33 | account = "..."
34 | password = "..."
35 | warehouse = "..."
36 | ```
37 |
38 | 3. **Run the app locally.** Simply run:
39 | ```
40 | pipenv run streamlit run Home.py
41 | ```
42 |
43 | 🎊 Your browser should now be opened with the Streamlit app running locally!
44 |
45 | ### Contribute
46 |
47 | Feel free to contribute! Simply make sure to:
48 | 1. Install development dependencies `pipenv install --python 3.9 --dev`
49 | 2. Set up pre-commit hooks `pipenv run pre-commit install`
50 |
51 | ### Questions? Comments?
52 |
53 | Please ask in the [Streamlit community](https://discuss.streamlit.io).
54 |
--------------------------------------------------------------------------------
/pages/01_🔹_Compute_insights.py:
--------------------------------------------------------------------------------
1 | import plost
2 | import streamlit as st
3 |
4 | st.set_page_config(
5 | page_title="Usage Insights app - Compute", page_icon="🔹", layout="centered"
6 | )
7 |
8 | from utils import charts, gui, processing
9 | from utils import snowflake_connector as sf
10 | from utils import sql as sql
11 |
12 |
13 | def main():
14 |
15 | # Date selector widget
16 | with st.sidebar:
17 | date_from, date_to = gui.date_selector()
18 |
19 | # Header
20 | gui.icon("🔹")
21 | st.title("Compute insights")
22 |
23 | # ----------------------
24 | # ---- Service type ----
25 | # ----------------------
26 |
27 | gui.space(1)
28 | st.subheader("Service type")
29 |
30 | # Get data
31 | query = sql.CONSUMPTION_PER_SERVICE_TYPE_QUERY
32 | df = sf.sql_to_dataframe(
33 | query.format(date_from=date_from, date_to=date_to)
34 | )
35 |
36 | # Add filtering widget per Service type
37 | all_values = df["SERVICE_TYPE"].unique().tolist()
38 | selected_value = st.selectbox(
39 | "Choose service type",
40 | ["All"] + all_values,
41 | 0,
42 | )
43 |
44 | if selected_value == "All":
45 | selected_value = all_values
46 | else:
47 | selected_value = [selected_value]
48 |
49 | # Filter df accordingly
50 | df = df[df["SERVICE_TYPE"].isin(selected_value)]
51 |
52 | # Get consumption
53 | consumption = int(df["CREDITS_USED"].sum())
54 |
55 | if df.empty:
56 | st.caption("No data found.")
57 | elif consumption == 0:
58 | st.caption("No consumption found.")
59 | else:
60 | # Sum of credits used
61 | credits_used_html = gui.underline(
62 | text=gui.pretty_print_credits(consumption),
63 | )
64 | credits_used_html += " were used"
65 |
66 | gui.space(1)
67 | st.write(credits_used_html, unsafe_allow_html=True)
68 |
69 | gui.space(1)
70 | gui.subsubheader(
71 | "**Compute** spend over time",
72 | "Aggregated by day",
73 | )
74 |
75 | # Resample by day
76 | df_resampled = processing.resample_by_day(
77 | df,
78 | date_column="START_TIME",
79 | )
80 |
81 | # Bar chart
82 | bar_chart = charts.get_bar_chart(
83 | df=df_resampled,
84 | date_column="START_TIME",
85 | value_column="CREDITS_USED",
86 | )
87 |
88 | st.altair_chart(bar_chart, use_container_width=True)
89 |
90 | # Group by
91 | agg_config = {"CREDITS_USED": "sum"}
92 | df_grouped = (
93 | df.groupby(["NAME", "SERVICE_TYPE"]).agg(agg_config).reset_index()
94 | )
95 |
96 | # Sort and pretty print credits
97 | df_grouped_top_10 = df_grouped.sort_values(
98 | by="CREDITS_USED", ascending=False
99 | ).head(10)
100 |
101 | df_grouped_top_10["CREDITS_USED"] = df_grouped_top_10[
102 | "CREDITS_USED"
103 | ].apply(gui.pretty_print_credits)
104 |
105 | gui.subsubheader(
106 | "**Compute** spend",
107 | " Grouped by NAME",
108 | "Top 10",
109 | )
110 |
111 | st.dataframe(
112 | gui.dataframe_with_podium(
113 | df_grouped_top_10,
114 | )[["NAME", "SERVICE_TYPE", "CREDITS_USED"]],
115 | width=600,
116 | )
117 |
118 | gui.space(1)
119 | gui.hbar()
120 |
121 | # -------------------
122 | # ---- Warehouse ----
123 | # -------------------
124 |
125 | st.subheader("Warehouse")
126 |
127 | # Get data
128 | warehouse_usage_hourly = sf.sql_to_dataframe(
129 | sql.WAREHOUSE_USAGE_HOURLY.format(
130 | date_from=date_from,
131 | date_to=date_to,
132 | )
133 | )
134 |
135 | # Add filtering widget per Warehouse name
136 | warehouses = warehouse_usage_hourly.WAREHOUSE_NAME.unique()
137 | selected_warehouse = st.selectbox(
138 | "Choose warehouse",
139 | warehouses.tolist(),
140 | )
141 |
142 | # Filter accordingly
143 | warehouse_usage_hourly_filtered = warehouse_usage_hourly[
144 | warehouse_usage_hourly.WAREHOUSE_NAME.eq(selected_warehouse)
145 | ]
146 |
147 | # Resample so that all the period has data (fill with 0 if needed)
148 | warehouse_usage_hourly_filtered = processing.resample_date_period(
149 | warehouse_usage_hourly_filtered,
150 | date_from,
151 | date_to,
152 | value_column="CREDITS_USED_COMPUTE",
153 | )
154 |
155 | gui.subsubheader("Time-histogram of **warehouse usage**")
156 |
157 | plost.time_hist(
158 | data=warehouse_usage_hourly_filtered,
159 | date="START_TIME",
160 | x_unit="day",
161 | y_unit="hours",
162 | color={
163 | "field": "CREDITS_USED_COMPUTE",
164 | "scale": {
165 | "scheme": charts.ALTAIR_SCHEME,
166 | },
167 | },
168 | aggregate=None,
169 | legend=None,
170 | )
171 |
172 | gui.space(1)
173 | gui.hbar()
174 |
175 | # -----------------
176 | # ---- Queries ----
177 | # -----------------
178 |
179 | st.subheader("Queries")
180 |
181 | # Get data
182 | queries_data = sf.get_queries_data(
183 | date_from,
184 | date_to,
185 | )
186 |
187 | # Add filtering widget per Warehouse name
188 | warehouses = queries_data.WAREHOUSE_NAME.dropna().unique().tolist()
189 | selected_warehouse = st.selectbox(
190 | "Choose warehouse",
191 | warehouses,
192 | )
193 |
194 | # Filter accordingly
195 | queries_data = queries_data[
196 | queries_data.WAREHOUSE_NAME.eq(selected_warehouse)
197 | ]
198 |
199 | gui.subsubheader(
200 | "Histogram of **queries duration** (in secs)", "Log scale"
201 | )
202 |
203 | # Histogram
204 | histogram = charts.get_histogram_chart(
205 | df=queries_data,
206 | date_column="DURATION_SECS",
207 | )
208 |
209 | st.altair_chart(histogram, use_container_width=True)
210 |
211 | # Top-3 longest queries
212 | queries_podium_df = gui.dataframe_with_podium(
213 | queries_data, "DURATION_SECS"
214 | ).head(3)
215 |
216 | # Only show if at least three queries!
217 | if len(queries_podium_df) >= 3:
218 | with st.expander("🔎 Zoom into top-3 longest queries in detail"):
219 | for query in queries_podium_df.itertuples():
220 | st.caption(f"{query.Index} {query.DURATION_SECS_PP}")
221 | st.code(query.QUERY_TEXT_PP, "sql")
222 |
223 | gui.space(1)
224 | st.write("Time-histograms of **aggregate queries duration** (in secs)")
225 |
226 | # Resample so that all the period has data (fill with 0 if needed)
227 | queries_data = processing.resample_date_period(
228 | queries_data, date_from, date_to, "DURATION_SECS"
229 | )
230 |
231 | num_days_selected = (date_to - date_from).days
232 | if num_days_selected > 14:
233 | st.caption("Week-day histogram")
234 | plost.time_hist(
235 | data=queries_data,
236 | date="START_TIME",
237 | x_unit="week",
238 | y_unit="day",
239 | color={
240 | "field": "DURATION_SECS",
241 | "scale": {"scheme": charts.ALTAIR_SCHEME},
242 | },
243 | aggregate="sum",
244 | legend=None,
245 | )
246 |
247 | st.caption("Day-hour histogram")
248 | plost.time_hist(
249 | data=queries_data,
250 | date="START_TIME",
251 | x_unit="day",
252 | y_unit="hours",
253 | color={
254 | "field": "DURATION_SECS",
255 | "scale": {"scheme": charts.ALTAIR_SCHEME},
256 | },
257 | aggregate="sum",
258 | legend=None,
259 | )
260 |
261 | gui.space(1)
262 | gui.subsubheader(
263 | "**Query optimization**: longest and most frequent queries",
264 | "Log scales (🖱️ hover for real values!)",
265 | )
266 |
267 | queries_agg = sf.sql_to_dataframe(
268 | sql.QUERIES_COUNT_QUERY.format(
269 | date_from=date_from,
270 | date_to=date_to,
271 | num_min=1,
272 | limit=10_000,
273 | warehouse_name=selected_warehouse,
274 | )
275 | )
276 |
277 | queries_agg = processing.apply_log1p(
278 | df=queries_agg, columns=["EXECUTION_MINUTES", "NUMBER_OF_QUERIES"]
279 | )
280 |
281 | scatter_chart = charts.get_scatter_chart(df=queries_agg)
282 |
283 | st.altair_chart(
284 | scatter_chart,
285 | use_container_width=True,
286 | )
287 |
288 | gui.space(1)
289 | gui.hbar()
290 |
291 | # -------------
292 | # --- Users ---
293 | # -------------
294 |
295 | st.subheader("Users")
296 |
297 | # Get data
298 | users_data = sf.sql_to_dataframe(
299 | sql.USERS_QUERY.format(
300 | date_from=date_from,
301 | date_to=date_to,
302 | )
303 | )
304 |
305 | gui.subsubheader("**Users** with the **largest** number of credits spent")
306 |
307 | # Bar chart
308 | plost.bar_chart(
309 | data=users_data,
310 | bar="USER_NAME",
311 | value="APPROXIMATE_CREDITS_USED",
312 | color=gui.BLUE_COLOR,
313 | direction="horizontal",
314 | height=200,
315 | use_container_width=True,
316 | )
317 |
318 |
319 | if __name__ == "__main__":
320 | main()
321 |
--------------------------------------------------------------------------------
/pages/02_🔹_Storage_insights.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 |
3 | st.set_page_config(
4 | page_title="Usage Insights app - Storage", page_icon="🔹", layout="centered"
5 | )
6 |
7 | from utils import charts, gui, processing
8 | from utils import snowflake_connector as sf
9 | from utils import sql
10 |
11 |
12 | def main():
13 |
14 | # Date selector widget
15 | with st.sidebar:
16 | date_from, date_to = gui.date_selector()
17 |
18 | # Header
19 | gui.icon("🔹")
20 | st.title("Storage insights")
21 |
22 | # Get data
23 | query = sql.STORAGE_QUERY
24 | df = sf.sql_to_dataframe(
25 | query.format(date_from=date_from, date_to=date_to)
26 | )
27 |
28 | # Get consumption
29 | consumption = df["DATABASE_BYTES"].sum()
30 |
31 | if df.empty:
32 | st.caption("No data found.")
33 | st.stop()
34 | if consumption == 0:
35 | st.caption("No consumption!")
36 | st.stop()
37 |
38 | # Resample by day
39 | df_resampled = processing.resample_by_day(
40 | df,
41 | date_column="USAGE_DATE",
42 | )
43 |
44 | # Average bytes used per day
45 | credits_used_html = "Average "
46 | credits_used_html += gui.underline(
47 | text=gui.pretty_print_bytes(int(df_resampled.DATABASE_BYTES.mean())),
48 | color=gui.BLUE_COLOR,
49 | )
50 | credits_used_html += " were used per day"
51 |
52 | gui.space(1)
53 | st.write(credits_used_html, unsafe_allow_html=True)
54 |
55 | gui.space(1)
56 | gui.subsubheader(
57 | "**Storage** spend over time",
58 | "Aggregated by day",
59 | )
60 |
61 | # Bar chart
62 | chart = charts.get_bar_chart(
63 | df=df_resampled,
64 | date_column="USAGE_DATE",
65 | value_column="DATABASE_BYTES",
66 | )
67 |
68 | st.altair_chart(chart, use_container_width=True)
69 |
70 | # st.write(
71 | # df_resampled.groupby(
72 | # ["OBJECT_NAME", "USAGE_DATE"]
73 | # ).DATABASE_BYTES.mean()
74 | # )
75 |
76 | # Group by
77 | df_grouped = (
78 | df.groupby(["OBJECT_NAME", "USAGE_DATE"])
79 | .DATABASE_BYTES.mean()
80 | .reset_index()
81 | .groupby("OBJECT_NAME")
82 | .mean()
83 | .reset_index()
84 | )
85 | # agg_config = {"DATABASE_BYTES": "sum"}
86 | # df_grouped = df.groupby("OBJECT_NAME").agg(agg_config).reset_index()
87 |
88 | # Sort and pretty print credits
89 | df_grouped_top_10 = df_grouped.sort_values(
90 | by="DATABASE_BYTES", ascending=False
91 | ).head(10)
92 |
93 | df_grouped_top_10["AVG_DAILY_STORAGE_SIZE"] = df_grouped_top_10[
94 | "DATABASE_BYTES"
95 | ].apply(gui.pretty_print_bytes)
96 |
97 | # Pretty print BYTES
98 | # value_pretty_print_column = "DATABASE_BYTES_PP"
99 | # df_grouped[value_pretty_print_column] = df_grouped["DATABASE_BYTES"].apply(
100 | # gui.pretty_print_bytes
101 | # )
102 | # df_grouped["AVG_DAILY_STORAGE_SIZE"] = df_grouped[
103 | # "DATABASE_BYTES_PP"
104 | # ].apply(lambda x: x + " " * 10)
105 |
106 | # df_grouped = df_grouped.sort_values(
107 | # by="DATABASE_BYTES",
108 | # ascending=False,
109 | # )
110 |
111 | gui.subsubheader(
112 | "**Storage** spend per day",
113 | "Average",
114 | "Grouped by OBJECT_NAME",
115 | "Top 10",
116 | )
117 |
118 | st.dataframe(
119 | gui.dataframe_with_podium(
120 | df_grouped_top_10[["OBJECT_NAME", "AVG_DAILY_STORAGE_SIZE"]],
121 | ),
122 | )
123 |
124 |
125 | if __name__ == "__main__":
126 | main()
127 |
--------------------------------------------------------------------------------
/pages/03_🔹_Data_Transfer_insights.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 |
3 | st.set_page_config(
4 | page_title="Usage Insights app - Data Transfer",
5 | page_icon="🔹",
6 | layout="centered",
7 | )
8 |
9 | from utils import charts, gui, processing
10 | from utils import snowflake_connector as sf
11 | from utils import sql
12 |
13 |
14 | def main():
15 |
16 | # Date selector widget
17 | with st.sidebar:
18 | date_from, date_to = gui.date_selector()
19 |
20 | # Header
21 | gui.icon("🔹")
22 | st.title("Data Transfer insights")
23 |
24 | # Get data
25 | query = sql.DATA_TRANSFER_QUERY
26 | df = sf.sql_to_dataframe(
27 | query.format(
28 | date_from=date_from,
29 | date_to=date_to,
30 | )
31 | )
32 |
33 | gui.space(1)
34 | st.subheader("Target region")
35 |
36 | # Add filtering widget
37 | all_values = df["TARGET_REGION"].unique().tolist()
38 | selected_value = st.selectbox(
39 | "Choose target region",
40 | ["All"] + all_values,
41 | 0,
42 | )
43 |
44 | if selected_value == "All":
45 | selected_value = all_values
46 | else:
47 | selected_value = [selected_value]
48 |
49 | # Filter df accordingly
50 | df = df[df["TARGET_REGION"].isin(selected_value)]
51 |
52 | # Get consumption
53 | consumption = int(df["BYTES_TRANSFERRED"].sum())
54 |
55 | if df.empty:
56 | st.caption("No data found.")
57 | st.stop()
58 | if consumption == 0:
59 | st.caption("No consumption!")
60 | st.stop()
61 |
62 | # Sum of credits used
63 | credits_used_html = gui.underline(
64 | text=gui.pretty_print_bytes(consumption),
65 | color=gui.BLUE_COLOR,
66 | )
67 | credits_used_html += " were used"
68 |
69 | gui.space(1)
70 | st.write(credits_used_html, unsafe_allow_html=True)
71 |
72 | gui.space(1)
73 | gui.subsubheader(
74 | "**Data Transfer** spend over time",
75 | "Aggregated by day",
76 | )
77 |
78 | # Resample by day
79 | df_resampled = processing.resample_by_day(
80 | df,
81 | date_column="START_TIME",
82 | )
83 |
84 | # Bar chart
85 | chart = charts.get_bar_chart(
86 | df=df_resampled,
87 | date_column="START_TIME",
88 | value_column="BYTES_TRANSFERRED",
89 | )
90 |
91 | st.altair_chart(chart, use_container_width=True)
92 |
93 | # Group by
94 | agg_config = {"BYTES_TRANSFERRED": "sum"}
95 | df_grouped = (
96 | df.groupby(["TRANSFER_TYPE", "TARGET_CLOUD", "TARGET_REGION"])
97 | .agg(agg_config)
98 | .reset_index()
99 | )
100 |
101 | # Sort and pretty print credits
102 | df_grouped_top_10 = df_grouped.sort_values(
103 | by="BYTES_TRANSFERRED", ascending=False
104 | ).head(10)
105 |
106 | df_grouped_top_10["BYTES_TRANSFERRED"] = df_grouped_top_10[
107 | "BYTES_TRANSFERRED"
108 | ].apply(gui.pretty_print_bytes)
109 |
110 | gui.subsubheader(
111 | "**Storage** spend",
112 | " Grouped by TRANSFER_TYPE",
113 | "Top 10",
114 | )
115 |
116 | st.dataframe(
117 | gui.dataframe_with_podium(
118 | df_grouped_top_10[
119 | [
120 | "TRANSFER_TYPE",
121 | "TARGET_CLOUD",
122 | "TARGET_REGION",
123 | "BYTES_TRANSFERRED",
124 | ]
125 | ]
126 | ),
127 | width=600,
128 | )
129 |
130 |
131 | if __name__ == "__main__":
132 | main()
133 |
--------------------------------------------------------------------------------
/pages/04_🤔_About_this_app.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 |
3 | st.set_page_config(
4 | page_title="Usage Insights app - About", page_icon="🤔", layout="centered"
5 | )
6 |
7 | from utils import gui
8 |
9 | gui.icon("🤔")
10 | st.title("About this app")
11 |
12 | st.write(
13 | """
14 | ### How does this app work?
15 |
16 | - Using [Streamlit](https://www.streamlit.io) and the [Snowflake Python
17 | connector](https://github.com/snowflakedb/snowflake-connector-python).
18 | - Check out our public repository 🐙
19 | [snowflake-usage-app](https://github.com/streamlit/snowflake-usage-app) to
20 | learn more about it!
21 |
22 | ### Questions? Comments?
23 |
24 | Please ask in the [Streamlit community](https://discuss.streamlit.io).
25 | """
26 | )
27 |
--------------------------------------------------------------------------------
/utils/charts.py:
--------------------------------------------------------------------------------
1 | import altair as alt
2 | import pandas as pd
3 | import streamlit as st
4 |
5 | from utils import gui
6 |
7 | ALTAIR_AXIS_CONFIG = dict(
8 | gridColor="#e6eaf1",
9 | tickColor="#e6eaf1",
10 | domainColor="#e6eaf1",
11 | labelColor="#828797",
12 | titleFontWeight="bold",
13 | )
14 |
15 | ALTAIR_SCHEME = "blues"
16 |
17 |
18 | @st.cache_data(ttl=60 * 60 * 12)
19 | def get_bar_chart(
20 | df: pd.DataFrame,
21 | date_column: str,
22 | value_column: str,
23 | color: str = gui.BLUE_COLOR,
24 | ) -> alt.Chart:
25 |
26 | config = {
27 | "x": alt.X(f"yearmonthdate({date_column})", title="Day"),
28 | "y": alt.Y(f"sum({value_column})", title="Consumption"),
29 | "tooltip": (date_column, value_column),
30 | }
31 |
32 | chart = (
33 | alt.Chart(df)
34 | .mark_bar()
35 | .encode(**config)
36 | .configure_mark(opacity=1, color=color)
37 | .configure_axis(**ALTAIR_AXIS_CONFIG)
38 | .interactive()
39 | )
40 |
41 | return chart
42 |
43 |
44 | @st.cache_data(ttl=60 * 60 * 12)
45 | def get_histogram_chart(
46 | df: pd.DataFrame,
47 | date_column: str,
48 | ) -> alt.Chart:
49 |
50 | chart = (
51 | alt.Chart(df)
52 | .mark_bar()
53 | .encode(
54 | x=alt.X(
55 | date_column,
56 | bin=alt.BinParams(
57 | maxbins=100,
58 | ),
59 | ),
60 | y=alt.Y(
61 | "count()",
62 | title="Count of Records",
63 | scale=alt.Scale(type="symlog"),
64 | ),
65 | tooltip=[date_column, "count()"],
66 | )
67 | .configure_mark(
68 | color=gui.BLUE_COLOR,
69 | )
70 | .configure_axis(**ALTAIR_AXIS_CONFIG)
71 | .interactive()
72 | )
73 |
74 | return chart
75 |
76 |
77 | @st.cache_data(ttl=60 * 60 * 12)
78 | def get_scatter_chart(
79 | df: pd.DataFrame,
80 | ) -> alt.Chart:
81 | chart = (
82 | alt.Chart(df)
83 | .mark_circle(
84 | size=200,
85 | )
86 | .encode(
87 | x=alt.X(
88 | "NUMBER_OF_QUERIES_LOG:Q",
89 | title="Number of queries (log scale)",
90 | scale=alt.Scale(
91 | domain=[
92 | df.NUMBER_OF_QUERIES_LOG.min() - 0.5,
93 | df.NUMBER_OF_QUERIES_LOG.max() + 0.5,
94 | ]
95 | ),
96 | ),
97 | y=alt.Y(
98 | "EXECUTION_MINUTES_LOG:Q",
99 | title="Execution minutes (log scale)",
100 | scale=alt.Scale(
101 | domain=[
102 | df.EXECUTION_MINUTES_LOG.min() - 0.5,
103 | df.EXECUTION_MINUTES_LOG.max() + 0.5,
104 | ]
105 | ),
106 | ),
107 | tooltip=[
108 | "QUERY_TEXT",
109 | "NUMBER_OF_QUERIES",
110 | "EXECUTION_MINUTES",
111 | ],
112 | )
113 | .configure_mark(opacity=0.7, color=gui.BLUE_COLOR)
114 | .configure_axis(**ALTAIR_AXIS_CONFIG)
115 | .interactive()
116 | )
117 |
118 | return chart
119 |
120 |
121 | if __name__ == "__main__":
122 | pass
123 |
--------------------------------------------------------------------------------
/utils/gui.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import math
3 |
4 | import pandas as pd
5 | import sqlparse
6 | import streamlit as st
7 | from millify import millify
8 |
9 | BLUE_COLOR = "#1c83e1"
10 |
11 |
12 | def icon(emoji: str):
13 | """Shows an emoji as a Notion-style page icon."""
14 | st.write(
15 | f'{emoji}',
16 | unsafe_allow_html=True,
17 | )
18 |
19 |
20 | def space(num_lines: int = 1):
21 | """Adds empty lines to the Streamlit app."""
22 | for _ in range(num_lines):
23 | st.write("")
24 |
25 |
26 | def hbar():
27 | """Adds a horizontal bar"""
28 | st.write("---")
29 |
30 |
31 | def subsubheader(*args):
32 | text = " · ".join(tuple(args))
33 | st.write(text)
34 |
35 |
36 | def underline(text: str, color: str = BLUE_COLOR) -> str:
37 | """Underlines input text using HTML"""
38 | style = "font-size:18px; text-decoration-style: dotted; "
39 | style += "text-underline-offset: 5px; "
40 | style += f"text-decoration-color:{color};"
41 | return f""" {text} """
42 |
43 |
44 | def dataframe_with_podium(
45 | df: pd.DataFrame, sort_by: str = None
46 | ) -> pd.DataFrame:
47 | """Replaces dataframe indices 1, 2, 3 with medals 🥇, 🥈, 🥉"""
48 |
49 | if sort_by:
50 | # Sort dataframe and take top-10
51 | sorted_df = (
52 | df.sort_values(by=sort_by, ascending=False)
53 | .reset_index(drop=True)
54 | .head(10)
55 | )
56 | else:
57 | sorted_df = df.head(10).copy()
58 |
59 | # Replace index to highlight the podium (gold, metal, bronze)
60 | new_index = ["🥇", "🥈", "🥉"] + list(map(str, range(4, 11)))
61 | sorted_df.index = new_index[: len(sorted_df)]
62 | return sorted_df
63 |
64 |
65 | def date_selector() -> tuple[datetime.date, datetime.date]:
66 | """Adds a date selector with a few different options."""
67 |
68 | DATE_RANGE_OPTIONS = [
69 | "Last 7 days",
70 | "Last 28 days",
71 | "Last 3 months",
72 | "Last 6 months",
73 | "Last 12 months",
74 | "All time",
75 | "Custom",
76 | ]
77 |
78 | if "date_range" in st.session_state:
79 | index = DATE_RANGE_OPTIONS.index(st.session_state.date_range)
80 | else:
81 | index = 0
82 |
83 | date_range = st.selectbox(
84 | "Date range",
85 | options=[
86 | "Last 7 days",
87 | "Last 28 days",
88 | "Last 3 months",
89 | "Last 6 months",
90 | "Last 12 months",
91 | "All time",
92 | "Custom",
93 | ],
94 | index=index,
95 | key="date_range",
96 | )
97 |
98 | if date_range != "Custom":
99 | date_to = datetime.date.today()
100 | if date_range == "Last 7 days":
101 | date_from = date_to - datetime.timedelta(days=7)
102 | elif date_range == "Last 28 days":
103 | date_from = date_to - datetime.timedelta(days=28)
104 | elif date_range == "Last 3 months":
105 | date_from = date_to - datetime.timedelta(weeks=12)
106 | elif date_range == "Last 6 months":
107 | date_from = date_to - datetime.timedelta(weeks=24)
108 | elif date_range == "Last 12 months":
109 | date_from = date_to - datetime.timedelta(days=365)
110 | else:
111 | date_from = datetime.date(year=2016, month=1, day=1)
112 |
113 | if "custom" in st.session_state:
114 | value = st.session_state.custom
115 | else:
116 | value = (
117 | date_to - datetime.timedelta(days=7),
118 | date_to,
119 | )
120 |
121 | if date_range == "Custom":
122 | date_from, date_to = st.date_input(
123 | "Choose start and end date",
124 | value=value,
125 | key="custom",
126 | )
127 |
128 | st.caption(f"Your selection is from **{date_from}** to **{date_to}**")
129 |
130 | return date_from, date_to
131 |
132 |
133 | def pretty_print_credits(credits: float) -> str:
134 | return f"{millify(credits, 1)} Credits"
135 |
136 |
137 | def pretty_print_bytes(size_bytes: int, binary: bool = False) -> str:
138 | basis = 1024 if binary else 1000
139 | if size_bytes == 0:
140 | return "0B"
141 | size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
142 | i = int(math.floor(math.log(size_bytes, basis)))
143 | p = math.pow(basis, i)
144 | s = round(size_bytes / p, 2)
145 | return "%s %s" % (s, size_name[i]) + " " * 8
146 |
147 |
148 | def pretty_print_seconds(seconds: int) -> str:
149 | minutes, seconds = divmod(seconds, 60)
150 | hours, minutes = divmod(minutes, 60)
151 |
152 | pretty_print = ""
153 | if hours:
154 | pretty_print += f"{hours} hr{'s' if hours > 1 else ''} "
155 | if minutes:
156 | pretty_print += f"{minutes} min{'s' if minutes > 1 else ''} "
157 | if seconds:
158 | pretty_print += f"{seconds} sec{'s' if seconds > 1 else ''}"
159 | return pretty_print
160 |
161 |
162 | def pretty_print_sql_query(query: str) -> str:
163 | return sqlparse.format(
164 | query,
165 | reindent=True,
166 | keyword_case="upper",
167 | )
168 |
169 |
170 | if __name__ == "__main__":
171 | pass
172 |
--------------------------------------------------------------------------------
/utils/processing.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pandas as pd
3 | import streamlit as st
4 |
5 |
6 | @st.cache_data
7 | def resample_by_day(df: pd.DataFrame, date_column: str) -> pd.DataFrame:
8 | """Resample a dataframe's date_column by day, summing values."""
9 | return (
10 | df.set_index(date_column).resample("1D").sum().reset_index(date_column)
11 | )
12 |
13 |
14 | @st.cache_data
15 | def resample_date_period(
16 | df: pd.DataFrame, date_from: str, date_to: str, value_column: str
17 | ) -> pd.DataFrame:
18 | """Resample a dataframe to make sure there are values in value_column
19 | for the full date period from date_from to date_to."""
20 |
21 | empty_df = pd.DataFrame()
22 | empty_df["START_TIME"] = pd.date_range(date_from, date_to, freq="H")
23 | empty_df[value_column] = 0
24 | return empty_df.append(
25 | df,
26 | ignore_index=True,
27 | )
28 |
29 |
30 | @st.cache_data
31 | def apply_log1p(df: pd.DataFrame, columns: list) -> pd.DataFrame:
32 | """Apply log1p on input columns and store into new columns in input df
33 | with suffix _LOG."""
34 | log_columns = [f"{column}_LOG" for column in columns]
35 | df[log_columns] = df[columns].apply(np.log1p)
36 | return df
37 |
38 |
39 | if __name__ == "__main__":
40 | pass
41 |
--------------------------------------------------------------------------------
/utils/snowflake_connector.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | from typing import Any, Dict
3 |
4 | import pandas as pd
5 | import streamlit as st
6 | from snowflake.connector import connect
7 | from snowflake.connector.connection import SnowflakeConnection
8 |
9 | from utils import gui, sql
10 |
11 | TIME_TO_LIVE = 60 * 60 * 6 # 6 hours caching
12 |
13 |
14 | # Share the connector across all users connected to the app
15 | @st.cache_resource
16 | def get_connector(
17 | secrets_key: str = "snowflake",
18 | input_params: Dict[str, Any] = None,
19 | use_browser=True,
20 | ) -> SnowflakeConnection:
21 | """Get a connector to Snowflake. By default, the connector will look
22 | for credentials found under st.secrets["snowflake"].
23 |
24 | Args:
25 | secrets_key (str, optional): Streamlit secrets key for the credentials.
26 | Defaults to 'snowflake'
27 |
28 | params (dict, optional): Connector parameters.
29 | Overrides Streamlit secrets. Defaults to None.
30 |
31 | local_development (bool, optional): If True, this will open a
32 | tab in your browser to collect requirements. Defaults to True.
33 |
34 | Returns:
35 | SnowflakeConnection: Snowflake connector object.
36 | """
37 |
38 | # Default params
39 | params: Dict[str, Any] = {
40 | **st.secrets[secrets_key],
41 | "client_session_keep_alive": True,
42 | "client_store_temporary_credential": True,
43 | }
44 |
45 | # Override default params with input params
46 | if input_params:
47 | for key in input_params.keys():
48 | params[key] = input_params[key]
49 |
50 | # This will open a tab in your browser and sign you in
51 | if use_browser:
52 | params["authenticator"] = "externalbrowser"
53 |
54 | connector = connect(**params)
55 | return connector
56 |
57 |
58 | snowflake_connector = get_connector(
59 | secrets_key="sf_usage_app",
60 | use_browser=False,
61 | )
62 |
63 | cur = snowflake_connector.cursor()
64 | cur.execute(f"use warehouse {st.secrets.sf_usage_app.warehouse};")
65 |
66 |
67 | @st.cache_data(ttl=TIME_TO_LIVE)
68 | def sql_to_dataframe(sql_query: str) -> pd.DataFrame:
69 | data = pd.read_sql(
70 | sql_query,
71 | snowflake_connector,
72 | )
73 | return data
74 |
75 |
76 | @st.cache_data(ttl=TIME_TO_LIVE)
77 | def get_queries_data(
78 | date_from: datetime.date,
79 | date_to: datetime.date,
80 | ):
81 | queries_data = sql_to_dataframe(
82 | sql.QUERIES_QUERY.format(
83 | date_from=date_from,
84 | date_to=date_to,
85 | )
86 | )
87 | queries_data["DURATION_SECS"] = round(
88 | (queries_data.TOTAL_ELAPSED_TIME) / 1000
89 | )
90 | queries_data["DURATION_SECS_PP"] = queries_data.DURATION_SECS.apply(
91 | gui.pretty_print_seconds
92 | )
93 | queries_data["QUERY_TEXT_PP"] = queries_data.QUERY_TEXT.apply(
94 | gui.pretty_print_sql_query
95 | )
96 | return queries_data
97 |
98 |
99 | if __name__ == "__main__":
100 | pass
101 |
--------------------------------------------------------------------------------
/utils/sql.py:
--------------------------------------------------------------------------------
1 | QUERIES_QUERY = """
2 | select *
3 | from snowflake.account_usage.query_history
4 | where START_TIME >= convert_timezone('UTC', 'UTC', ('{date_from}T00:00:00Z')::timestamp_ltz)
5 | and START_TIME < convert_timezone('UTC', 'UTC', ('{date_to}T00:00:00Z')::timestamp_ltz);
6 | """
7 |
8 | QUERIES_COUNT_QUERY = """
9 | select QUERY_TEXT,
10 | count(*) as number_of_queries,
11 | sum(TOTAL_ELAPSED_TIME)/1000 as execution_seconds,
12 | sum(TOTAL_ELAPSED_TIME)/(1000*60) as execution_minutes,
13 | sum(TOTAL_ELAPSED_TIME)/(1000*60*60) as execution_hours
14 | from SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY Q
15 | where 1=1
16 | and Q.START_TIME >= convert_timezone('UTC', 'UTC', ('{date_from}T00:00:00Z')::timestamp_ltz)
17 | and Q.START_TIME <= convert_timezone('UTC', 'UTC', ('{date_to}T00:00:00Z')::timestamp_ltz)
18 | and TOTAL_ELAPSED_TIME > 0 --only get queries that actually used compute
19 | and WAREHOUSE_NAME = '{warehouse_name}'
20 |
21 | group by 1
22 | having count(*) >= {num_min} --configurable/minimal threshold
23 |
24 | order by 2 desc
25 | limit {limit}; --configurable upper bound threshold
26 | """
27 |
28 | CONSUMPTION_PER_SERVICE_TYPE_QUERY = """
29 | select date_trunc('hour', convert_timezone('UTC', start_time)) as start_time,
30 | name,
31 | service_type,
32 | round(sum(credits_used), 1) as credits_used,
33 | round(sum(credits_used_compute), 1) as credits_compute,
34 | round(sum(credits_used_cloud_services), 1) as credits_cloud
35 | from snowflake.account_usage.metering_history
36 | where start_time >= convert_timezone('UTC', 'UTC', ('{date_from}T00:00:00Z')::timestamp_ltz)
37 | and start_time < convert_timezone('UTC', 'UTC', ('{date_to}T00:00:00Z')::timestamp_ltz)
38 | group by 1, 2, 3;
39 | """
40 |
41 | WAREHOUSE_USAGE_HOURLY = """
42 | // Credits used by [hour, warehouse] (past 7 days)
43 | select START_TIME ,
44 | WAREHOUSE_NAME ,
45 | CREDITS_USED_COMPUTE
46 | from SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY
47 | where START_TIME >= convert_timezone('UTC', 'UTC', ('{date_from}T00:00:00Z')::timestamp_ltz)
48 | and start_time < convert_timezone('UTC', 'UTC', ('{date_to}T00:00:00Z')::timestamp_ltz)
49 | and WAREHOUSE_ID > 0 // Skip pseudo-VWs such as "CLOUD_SERVICES_ONLY"
50 | order by 1 desc,
51 | 2
52 | """
53 |
54 | STORAGE_QUERY = """
55 | select convert_timezone('UTC', usage_date) as usage_date,
56 | database_name as object_name,
57 | 'database' as object_type,
58 | max(AVERAGE_DATABASE_BYTES) as database_bytes,
59 | max(AVERAGE_FAILSAFE_BYTES) as failsafe_bytes,
60 | 0 as stage_bytes
61 | from snowflake.account_usage.database_storage_usage_history
62 | where usage_date >= date_trunc('day', ('{date_from}T00:00:00Z')::timestamp_ntz)
63 | and usage_date < date_trunc('day', ('{date_to}T00:00:00Z')::timestamp_ntz)
64 | group by 1, 2, 3
65 | union all
66 | select convert_timezone('UTC', usage_date) as usage_date,
67 | 'Stages' as object_name,
68 | 'stage' as object_type,
69 | 0 as database_bytes,
70 | 0 as failsafe_bytes,
71 | max(AVERAGE_STAGE_BYTES) as stage_bytes
72 | from snowflake.account_usage.stage_storage_usage_history
73 | where usage_date >= date_trunc('day', ('{date_from}T00:00:00Z')::timestamp_ntz)
74 | and usage_date < date_trunc('day', ('{date_to}T00:00:00Z')::timestamp_ntz)
75 | group by 1, 2, 3;
76 | """
77 |
78 | DATA_TRANSFER_QUERY = """
79 | select date_trunc('hour', convert_timezone('UTC', start_time)) as start_time,
80 | target_cloud,
81 | target_region,
82 | transfer_type,
83 | sum(bytes_transferred) as bytes_transferred
84 | from snowflake.account_usage.data_transfer_history
85 | where start_time >= convert_timezone('UTC', 'UTC', ('{date_from}T00:00:00Z')::timestamp_ltz)
86 | and start_time < convert_timezone('UTC', 'UTC', ('{date_to}T00:00:00Z')::timestamp_ltz)
87 | group by 1, 2, 3, 4;
88 | """
89 |
90 | USERS_QUERY = """
91 | with USER_HOUR_EXECUTION_CTE as
92 | (select USER_NAME ,
93 | WAREHOUSE_NAME ,
94 | DATE_TRUNC('hour', START_TIME) as START_TIME_HOUR ,
95 | SUM(EXECUTION_TIME) as USER_HOUR_EXECUTION_TIME
96 | from "SNOWFLAKE"."ACCOUNT_USAGE"."QUERY_HISTORY"
97 | where WAREHOUSE_NAME is not null
98 | and EXECUTION_TIME > 0
99 | and START_TIME > convert_timezone('UTC', 'UTC', ('{date_from}T00:00:00Z')::timestamp_ltz)
100 | and START_TIME <= convert_timezone('UTC', 'UTC', ('{date_to}T00:00:00Z')::timestamp_ltz)
101 | group by 1,
102 | 2,
103 | 3),
104 | HOUR_EXECUTION_CTE as
105 | (select START_TIME_HOUR ,
106 | WAREHOUSE_NAME ,
107 | SUM(USER_HOUR_EXECUTION_TIME) as HOUR_EXECUTION_TIME
108 | from USER_HOUR_EXECUTION_CTE
109 | group by 1,
110 | 2),
111 | APPROXIMATE_CREDITS as
112 | (select A.USER_NAME ,
113 | C.WAREHOUSE_NAME ,
114 | (A.USER_HOUR_EXECUTION_TIME/B.HOUR_EXECUTION_TIME)*C.CREDITS_USED as APPROXIMATE_CREDITS_USED
115 | from USER_HOUR_EXECUTION_CTE A
116 | join HOUR_EXECUTION_CTE B on A.START_TIME_HOUR = B.START_TIME_HOUR
117 | and B.WAREHOUSE_NAME = A.WAREHOUSE_NAME
118 | join "SNOWFLAKE"."ACCOUNT_USAGE"."WAREHOUSE_METERING_HISTORY" C on C.WAREHOUSE_NAME = A.WAREHOUSE_NAME
119 | and C.START_TIME = A.START_TIME_HOUR)
120 | select USER_NAME,
121 | WAREHOUSE_NAME,
122 | SUM(APPROXIMATE_CREDITS_USED) as APPROXIMATE_CREDITS_USED
123 | from APPROXIMATE_CREDITS
124 | group by 1,
125 | 2
126 | order by 3 desc;
127 | """
128 |
129 | if __name__ == "__main__":
130 | pass
131 |
--------------------------------------------------------------------------------