Skip to content

Commit 71ee57e

Browse files
committed
(fix): create all snowflake resources using scripts and related README updates
1 parent 8d8a975 commit 71ee57e

File tree

8 files changed

+162
-78
lines changed

8 files changed

+162
-78
lines changed

.envrc.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export KEYS_DIR="$DEMO_HOME/keys"
66
export SNOWSQL_ACCOUNT=<snowflake account>
77
export TODOAPP_USER=<snowflake todoapp user>
88
export TODOAPP_USER_PWD=<snowflake todoapp user password>
9+
export TODOAPP_USER_ROLE=todoapp_user
910
export TODOAPP_DATABASE=<snowflake todoapp database>
1011
# update to different warehouse, this is default for trial accounts
1112
export SNOWSQL_WAREHOUSE=COMPUTE_WH

README.md

Lines changed: 130 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ To run the demo you need the following tools on your local machine,
1616
- [direnv](https://direnv.net)
1717
- [miniconda](https://docs.anaconda.com/free/miniconda/)
1818

19+
## Environment Setup
20+
21+
The demo uses few environment variables, create and load it,
22+
23+
```shell
24+
copy $DEMO_HOME/.envrc.example $DEMO_HOME/.envrc
25+
```
26+
27+
> **NOTE**: `$DEMO_HOME` is the directory where you have cloned this repo
28+
29+
Adjust the values in the `$DEMO_HOME/.envrc` as per your requirements and load them,
30+
31+
```shell
32+
direnv allow .
33+
```
34+
1935
## Data Streaming Platform Setup
2036

2137
The entire demo is containerized and all the applications could be started using the Docker compose,
@@ -119,12 +135,31 @@ Once the task is added the terminal running the client should show an output sim
119135
```
120136

121137
> **TIP**: If you have downloaded the `add` binary then you can use it send Todo Tasks. Check `add -h` for possible options.
138+
> Add Todos from the file `$DEMO_HOME/samples/todos.jsonl`
139+
>
140+
> ```json
141+
> {"title": "Learn Redpanda CLI", "description": "Learn how to use rpk cli.","category": "learning","status": false}
142+
> {"title": "Learn Snowflake and Streamlit", "description": "Learn how to integrate snowflake with streamlit.",> "category": "learning","status": false}
143+
> {"title": "Create GitHub Repo", "description": "Create GitHub Repository for todo-demo.","category": "code","status": false}
144+
> {"title": "Todo ID Gen", "description": "Use SQLite for Todo ID generation via sequence.","category": "code","status": false}
145+
> {"title": "Car Service", "description": "Get the car to service this weekend.","category": "personal","status": false}
146+
> {"title": "Buy Groceries", "description": "Buy groceries for home before 8pm this evening.","category": "personal","status": false}
147+
> {"title": "Book Tickets for Movie", "description": "Get the movie tickets for Dune2.","category": "family","status": false}
148+
> ```
149+
>
150+
> ```shell
151+
> $DEMO_HOME/bin/add -d $DEMO_HOME/samples/todos.jsonl
152+
> ```
153+
154+
The added `todos` can ve viewed via the Redpanda [Web Console](http://localhost:8080).
122155
123156
## Snowflake Integration
124157
125158
The following section details on steps required to integrate the application with Snowflake data cloud. As result of the integration the data from Redpanda topic `todo-list` gets synchronized on to Snowflake table `TODO_LIST`.
126159
127-
### Create RSA Key Pair
160+
### RSA Key Pair
161+
162+
The `$TODOAPP_USER` will be using the Private Key authentication. In the following section we will create a RSA Private Key and encrypt the same.
128163
129164
Create directory to hold the keys,
130165
@@ -166,31 +201,54 @@ end
166201
Export the Private Key and Public Key into variables,
167202
168203
```shell
169-
set -lx TODOAPP_USER_RSA_PRIVATE_KEY (awk 'NR > 2 {print last} {last=$0}' ORS='' "$KEYS_DIR/rsa_key.p8")
170-
set -lx TODOAPP_USER_RSA_PUBLIC_KEY (awk 'NR > 2 {print last} {last=$0}' ORS='' "$KEYS_DIR/rsa_key.pub")
204+
export TODOAPP_USER_RSA_PRIVATE_KEY=$(awk 'NR > 2 {print last} {last=$0}' ORS='' "$KEYS_DIR/rsa_key.p8")
205+
export TODOAPP_USER_RSA_PUBLIC_KEY=$(awk 'NR > 2 {print last} {last=$0}' ORS='' "$KEYS_DIR/rsa_key.pub")
206+
```
207+
208+
> **NOTE**:
209+
> The variables strip the first and last line of the key as required by Snowflake Kafka Connector
210+
211+
## Database Setup
212+
213+
> **IMPORTANT**: The commands in this section will be executed as Snowflake Account Admin user
214+
215+
Create Database `$TODOAPP_DATABASE`,
216+
217+
```shell
218+
snowsql -c admin \
219+
--query "CREATE DATABASE IF NOT EXISTS $TODOAPP_DATABASE;"
171220
```
172221
173-
> **NOTE**: The variables strip the first and last line of the key as required by Snowflake Kafka Connector
222+
Create the `$TODOAPP_USER` user and provide the requried **GRANTs**,
174223
175-
### Update the SnowSQL User
224+
```shell
225+
snowsql -c admin \
226+
--warehouse "$SNOWSQL_WAREHOUSE" \
227+
--variable todo_warehouse=$SNOWSQL_WAREHOUSE \
228+
--variable db_name=$TODOAPP_DATABASE \
229+
--variable todo_user_role=$TODOAPP_USER_ROLE \
230+
--variable todoapp_user=$TODOAPP_USER \
231+
--variable todo_pub_key=$TODOAPP_USER_RSA_PUBLIC_KEY \
232+
--filename "$DEMO_HOME/etc/snowflake/acl.sql"
233+
```
176234
177-
Update the Snowflake `$TODOAPP_USER` to use the generated keys for authentication,
235+
Describe the user,
178236
179237
```shell
180-
snowsql -c admin -q "ALTER USER $TODOAPP_USER SET RSA_PUBLIC_KEY=\"$TODOAPP_USER_RSA_PUBLIC_KEY\";"
238+
snowsql -c admin \
239+
--warehouse "$SNOWSQL_WAREHOUSE" \
240+
--query "DESCRIBE USER $TODOAPP_USER;"
181241
```
182242
183243
Verify if `$TODOAPP_USER` is able to connect with key pair,
184244
185245
```shell
186-
snowsql -u $TODOAPP_USER --private-key-path="$DEMO_HOME/keys/rsa_key.p8" -q "SELECT CURRENT_DATE;"
246+
snowsql -u $TODOAPP_USER \
247+
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
248+
--query "SELECT CURRENT_DATE;"
187249
```
188250
189-
> **NOTE**: Can describe the user `$TODOAPP_USER` and check if `RSA_PUBLIC_KEY` column is same as `$TODOAPP_USER_RSA_PUBLIC_KEY`
190-
>
191-
> ```shell
192-
> snowsql -c admin -q "DESCRIBE USER $TODOAPP_USER;"
193-
> ```
251+
> **NOTE**: First time login will ask for a password change.
194252
195253
## Kafka Connect API
196254
@@ -289,9 +347,12 @@ Type SQL statements or !help
289347
1 Row(s) produced. Time Elapsed: 0.219s
290348
```
291349
350+
Select all rows from the `todo_list` table,
351+
292352
```shell
293353
snowsql -u $TODOAPP_USER \
294354
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
355+
--warehouse $SNOWSQL_WAREHOUSE \
295356
--dbname $TODOAPP_DATABASE \
296357
--variable redpanda_topic=$TOPICS \
297358
--filename "$DEMO_HOME/etc/snowflake/todo_list_query.sql"
@@ -300,25 +361,27 @@ snowsql -u $TODOAPP_USER \
300361
```text
301362
* SnowSQL * v1.2.32
302363
Type SQL statements or !help
303-
+----+-------------------------------+---------------------------------------------------+----------+--------+---------------+
304-
| ID | TITLE | DESCRIPTION | CATEGORY | STATUS | CREATE_TIME |
305-
|----+-------------------------------+---------------------------------------------------+----------+--------+---------------|
306-
| 1 | Learn Redpanda CLI | Learn how to use rpk cli. | learning | False | 1712635699878 |
307-
| 2 | Learn Snowflake and Streamlit | Learn how to integrate snowflake with streamlit. | learning | False | 1712635700215 |
308-
| 3 | Create GitHub Repo | Create GitHub Repository for todo-demo. | code | False | 1712635700218 |
309-
| 4 | Todo ID Gen | Use SQLite for Todo ID generation via sequence. | code | False | 1712635700222 |
310-
| 5 | Car Service | Get the car to service this weekend. | personal | False | 1712635700225 |
311-
| 6 | Buy Groceries | Buy groceries for home before 8pm this evening. | personal | False | 1712635700227 |
312-
| 7 | Book Tickets for Movie | Get the movie tickets for Dune2. | family | False | 1712635700229 |
313-
+----+-------------------------------+---------------------------------------------------+----------+--------+---------------+
314-
7 Row(s) produced. Time Elapsed: 0.345s
364+
+-----+---------------------------------+-----------------------------------------------------+------------+--------+---------------+
365+
| KEY | TITLE | DESCRIPTION | CATEGORY | STATUS | TZ |
366+
|-----+---------------------------------+-----------------------------------------------------+------------+--------+---------------|
367+
| "1" | "Learn Redpanda CLI" | "Learn how to use rpk cli." | "learning" | false | 1712731713770 |
368+
| "2" | "Learn Snowflake and Streamlit" | "Learn how to integrate snowflake with streamlit." | "learning" | false | 1712731714112 |
369+
| "3" | "Create GitHub Repo" | "Create GitHub Repository for todo-demo." | "code" | false | 1712731714120 |
370+
| "4" | "Todo ID Gen" | "Use SQLite for Todo ID generation via sequence." | "code" | false | 1712731714127 |
371+
| "5" | "Car Service" | "Get the car to service this weekend." | "personal" | false | 1712731714132 |
372+
| "6" | "Buy Groceries" | "Buy groceries for home before 8pm this evening." | "personal" | false | 1712731714138 |
373+
| "7" | "Book Tickets for Movie" | "Get the movie tickets for Dune2." | "family" | false | 1712731714143 |
374+
+-----+---------------------------------+-----------------------------------------------------+------------+--------+---------------+
375+
7 Row(s) produced. Time Elapsed: 1.548s
376+
Goodbye!
315377
```
316378
317379
**Optionally** you can run the following command to find the number of todos that has been inserted, it should return `7`.
318380
319381
```shell
320382
snowsql -u $TODOAPP_USER \
321383
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
384+
--warehouse $SNOWSQL_WAREHOUSE \
322385
--dbname $TODOAPP_DATABASE \
323386
--query "SELECT count(*) from TODO_LIST;"
324387
```
@@ -327,6 +390,43 @@ snowsql -u $TODOAPP_USER \
327390
328391
You can now use the synchronized data to build a dashboard using [Streamlit](https://streamlit.io). The demo builds a simple dashboard that shows task by category along with a tabular representation of the tasks data.
329392
393+
#### Create the Stored Procedure
394+
395+
Stored Procedure to extract the data the table synchronized with Redpanda topic to any custom table.
396+
397+
```shell
398+
snowsql -u $TODOAPP_USER \
399+
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
400+
--warehouse $SNOWSQL_WAREHOUSE \
401+
--dbname $TODOAPP_DATABASE \
402+
--filename "$DEMO_HOME/etc/snowflake/todos_sp.sql"
403+
```
404+
405+
#### Prepare Data for Dashboard
406+
407+
Extract the data from `TODO_LIST` table and load the same on to `todos` which will be used by Streamlit dashboard,
408+
409+
```shell
410+
snowsql -u $TODOAPP_USER \
411+
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
412+
--warehouse $SNOWSQL_WAREHOUSE \
413+
--dbname "$TODOAPP_DATABASE" \
414+
--query "CALL todos('todo_list','todos')"
415+
```
416+
417+
Query the `todos` table,
418+
419+
```shell
420+
snowsql -u $TODOAPP_USER \
421+
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
422+
--warehouse $SNOWSQL_WAREHOUSE \
423+
--dbname $TODOAPP_DATABASE \
424+
--query "SELECT * FROM TODOS;"
425+
```
426+
427+
> **NOTE**: You need to refresh the data on the `TODOS` table on every new task added to th Redpanda topic.
428+
> **WIP**: Leveraging streams and dynamic tables
429+
330430
#### Use predefined conda environment
331431
332432
Create a Python virtual environment for SnowPark using the conda environment configuration file `$DEMO_HOME/etc/python/environment.yml`.
@@ -354,6 +454,8 @@ streamlit run etc/snowflake/todo_dashboard.py
354454
355455
## Clean up
356456
457+
### Drop Table, User and Stored Procedures
458+
357459
Destroy Redpanda containers and cleanup associated volumes,
358460
359461
```shell
@@ -363,16 +465,15 @@ docker compose down --volumes
363465
```shell
364466
snowsql -u $TODOAPP_USER \
365467
--private-key-path="$DEMO_HOME/keys/rsa_key.p8" \
468+
--warehouse $SNOWSQL_WAREHOUSE \
366469
--dbname $TODOAPP_DATABASE \
367470
--filename "$DEMO_HOME/etc/snowflake/cleanup.sql"
368471
```
369472
370-
### Optional
371-
372-
Drop the database
473+
### Drop Database
373474
374475
```shell
375-
snowsql -c admin --dbname $TODOAPP_DATABASE \
476+
snowsql -c admin --warehouse $SNOWSQL_WAREHOUSE \
376477
--query "DROP DATABASE IF EXISTS $SNOWSQL_DATABASE;"
377478
```
378479

etc/snowflake/acl.sql

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,46 @@
1-
-- Grant user the '&todo_user_role' role
2-
GRANT ROLE '&todo_user_role' TO USER '&todoapp_user';
1+
-- The Role for Todo App
2+
CREATE ROLE IF NOT EXISTS &todo_user_role COMMENT="The Todo App User";
33

4-
GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE '&todo_user_role';
4+
-- Create Todo App User with default role of '&todo_user_role'
5+
CREATE USER IF NOT EXISTS &todoapp_user
6+
PASSWORD = 'superS3cret!'
7+
MUST_CHANGE_PASSWORD = TRUE
8+
RSA_PUBLIC_KEY = "&todo_pub_key"
9+
DEFAULT_ROLE = &todo_user_role
10+
DEFAULT_NAMESPACE = &db_name.PUBLIC
11+
DEFAULT_WAREHOUSE = &todo_warehouse
12+
COMMENT = "The Todo application user";
513

6-
-- Set default warehouse
7-
ALTER USER '&todoapp_user' SET DEFAULT_WAREHOUSE = "&warehouse"
814

9-
-- If you want to create a new database for Todo App, run
10-
CREATE DATABASE IF NOT EXISTS DEMODB;
15+
-- Grant user the "&todo_user_role" role
16+
GRANT ROLE &todo_user_role TO USER &todoapp_user;
1117

12-
-- Allow the '&todo_user_role' role to use database and public schema
13-
GRANT USAGE ON DATABASE DEMODB TO ROLE '&todo_user_role';
14-
GRANT ALL ON SCHEMA DEMODB.PUBLIC TO ROLE '&todo_user_role';
18+
-- Grant usage on Warehouse to user role
19+
GRANT USAGE ON WAREHOUSE &todo_warehouse TO ROLE &todo_user_role;
1520

16-
-- Grant '&todo_user_role' to create, modify and delete table on demo public schema
17-
GRANT OWNERSHIP ON ALL TABLES IN SCHEMA DEMODB.PUBLIC TO ROLE todo_app_user;
21+
-- Allow the "&todo_user_role" role to use database and public schema
22+
GRANT USAGE ON DATABASE &db_name TO ROLE &todo_user_role;
1823

19-
-- Grant CRUD on all tables on public schema of demodb to '&todo_user_role' role
20-
GRANT INSERT,DELETE,SELECT,UPDATE,TRUNCATE ON ALL TABLES IN SCHEMA DEMODB.PUBLIC
21-
TO ROLE '&todo_user_role';
24+
-- Allow all access on public schema of the demo db to the todo app user
25+
GRANT ALL ON SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
26+
27+
-- Grant "&todo_user_role" to create, modify and delete table on demo public schema
28+
GRANT OWNERSHIP ON ALL TABLES IN SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
29+
30+
-- Grant CRUD on all tables on public schema of demodb to "&todo_user_role" role
31+
GRANT INSERT,DELETE,SELECT,UPDATE,TRUNCATE ON ALL TABLES IN SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
2232

2333
-- Grant table operations on all future tables
24-
GRANT INSERT,DELETE,SELECT,UPDATE,TRUNCATE ON FUTURE TABLES IN SCHEMA DEMODB.PUBLIC
25-
TO ROLE '&todo_user_role';
34+
GRANT INSERT,DELETE,SELECT,UPDATE,TRUNCATE ON FUTURE TABLES IN SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
2635

2736
-- Ability to create stage(s)
28-
GRANT CREATE STAGE ON SCHEMA DEMODB.PUBLIC TO ROLE '&todo_user_role';
37+
GRANT CREATE STAGE ON SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
2938

30-
GRANT OWNERSHIP ON PROCEDURE TODOS(string,string) TO ROLE '&todo_user_role';
39+
-- GRANT OWNERSHIP ON PROCEDURE TODOS(string,string) TO ROLE &todo_user_role;
3140

3241
-- Create Streamlit apps in the PUBLIC schema
33-
GRANT CREATE STREAMLIT ON SCHEMA DEMODB.PUBLIC TO ROLE '&todo_user_role';
34-
GRANT CREATE STAGE ON SCHEMA DEMODB.PUBLIC TO ROLE '&todo_user_role';
42+
GRANT CREATE STREAMLIT ON SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
43+
GRANT CREATE STAGE ON SCHEMA &db_name.PUBLIC TO ROLE &todo_user_role;
3544

3645
-- List all grants
37-
show grants to role '&todo_user_role';
46+
show grants to role &todo_user_role;

etc/snowflake/cleanup.sql

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
USE WAREHOUSE COMPUTE_WH;
2-
USE SCHEMA public;
3-
41
-- Drop table
52
DROP TABLE IF EXISTS todo_list;
63
DROP TABLE IF EXISTS todos;

etc/snowflake/core.sql

Lines changed: 0 additions & 16 deletions
This file was deleted.

etc/snowflake/dashboard_data.sql

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
use WAREHOUSE COMPUTE_WH;
2-
use SCHEMA public;
3-
41
CALL todos('todo_list','&to_table')

etc/snowflake/todo_list_query.sql

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use WAREHOUSE COMPUTE_WH;
2-
use SCHEMA public;
3-
41
select
52
record_metadata:key as key,
63
record_content:title as title,

etc/snowflake/todos_sp.sql

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use WAREHOUSE COMPUTE_WH;
2-
use SCHEMA public;
31
CREATE OR REPLACE PROCEDURE todos(from_table string, to_table string)
42
RETURNS string
53
LANGUAGE python

0 commit comments

Comments
 (0)