Skip to content

Commit 48368c7

Browse files
committed
Update Jupyter notebook contents
* Use %pip instead of !pip * Add more explanation
1 parent 9bb0cf1 commit 48368c7

File tree

1 file changed

+72
-60
lines changed

1 file changed

+72
-60
lines changed

languages/python/jupyter_notebook/CipherStash-Getting-Started.ipynb

Lines changed: 72 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"* [Jupyter Notebook](https://jupyter.org/install)\n",
1717
"* [Docker](https://docs.docker.com/get-started/get-docker/)\n",
1818
"* [Docker compose](https://docs.docker.com/compose/install/)\n",
19+
"* [curl](https://curl.se)\n",
1920
"* [CipherStash account](https://cipherstash.com/signup)\n",
2021
"* [CipherStash CLI](https://github.com/cipherstash/cli-releases/releases/latest)"
2122
]
@@ -276,6 +277,18 @@
276277
"! docker compose up postgres -d"
277278
]
278279
},
280+
{
281+
"cell_type": "markdown",
282+
"id": "7f68e37d-210d-468d-b267-1b6930ba7957",
283+
"metadata": {},
284+
"source": [
285+
"The command above should start PostgreSQL.\n",
286+
"At any point, you can check the logs to see if there are any errors in your terminal window.\n",
287+
"From the directory where your docker-copmose.yml is located (`jupyter_notebook/` by default):\n",
288+
"\n",
289+
"> docker compose logs -f postgres"
290+
]
291+
},
279292
{
280293
"cell_type": "markdown",
281294
"id": "d9df0769-503c-4921-bb83-f4ff2a5f8a6d",
@@ -293,7 +306,7 @@
293306
"id": "85888d9c-388b-4026-aaac-d72cedbec99f",
294307
"metadata": {},
295308
"source": [
296-
"### Install database extensions"
309+
"### Install database extensions and EQL"
297310
]
298311
},
299312
{
@@ -303,25 +316,7 @@
303316
"metadata": {},
304317
"outputs": [],
305318
"source": [
306-
"! PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres cipherstash_getting_started < install.sql # should output messages like `CREATE *`"
307-
]
308-
},
309-
{
310-
"cell_type": "markdown",
311-
"id": "d91bc1e4-9a22-4561-bc37-052adaaf4cef",
312-
"metadata": {},
313-
"source": [
314-
"### Install EQL"
315-
]
316-
},
317-
{
318-
"cell_type": "code",
319-
"execution_count": null,
320-
"id": "dbfe2a97-f392-48e9-be64-e906684015b3",
321-
"metadata": {},
322-
"outputs": [],
323-
"source": [
324-
"! PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres cipherstash_getting_started < cipherstash_encrypt_eql.sql # should output messages like `CREATE *`"
319+
"! curl https://raw.githubusercontent.com/cipherstash/encrypt-query-language/refs/heads/main/release/cipherstash-encrypt-dsl.sql | PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres cipherstash_getting_started"
325320
]
326321
},
327322
{
@@ -380,6 +375,18 @@
380375
"! docker compose up proxy -d"
381376
]
382377
},
378+
{
379+
"cell_type": "markdown",
380+
"id": "97fde254-3eb5-4036-bf82-b49ec2a77f30",
381+
"metadata": {},
382+
"source": [
383+
"The command above should start CipherStash Proxy.\n",
384+
"At any point, you can check the logs to see if there are any errors in your terminal window.\n",
385+
"From the directory where your docker-copmose.yml is located (`jupyter_notebook/` by default):\n",
386+
"\n",
387+
"> docker compose logs -f proxy"
388+
]
389+
},
383390
{
384391
"cell_type": "markdown",
385392
"id": "0400e206-a337-404c-acc9-9706e626e94e",
@@ -401,20 +408,8 @@
401408
"\n",
402409
"There are classes prefixed with `Cs` defined in `cs_types.py` which handles conversion between the format CypherStash Proxy requires and the format for Python.\n",
403410
"\n",
404-
"In order to encrypt and store plaintext values, CipherStash Proxy requires encrypted columns to be in JSONB format like:\n",
405-
"```\n",
406-
"{\n",
407-
" \"k\": \"pt\",\n",
408-
" \"p\": \"hell, world\",\n",
409-
" \"i\": {\n",
410-
" \"t\": \"examples\",\n",
411-
" \"c\": \"encrypted_utf8_str\"\n",
412-
" },\n",
413-
" \"v\": 1,\n",
414-
"}\n",
415-
"```\n",
416-
"\n",
417-
"In Python, this conversion can be done by creating an object of `CsText` as:\n",
411+
"In order to encrypt and store plaintext values, CipherStash Proxy requires encrypted columns in its specific format.\n",
412+
"In Python, this conversion is done by creating an object of `CsText` as:\n",
418413
"```\n",
419414
"txt = CsText(\"hell, world\", \"examples\", \"encrypted_utf8_str\")\n",
420415
"txt.to_db_format()\n",
@@ -440,7 +435,7 @@
440435
"metadata": {},
441436
"outputs": [],
442437
"source": [
443-
"! pip install psycopg2 sqlalchemy"
438+
"%pip install psycopg2 sqlalchemy"
444439
]
445440
},
446441
{
@@ -462,37 +457,21 @@
462457
"outputs": [],
463458
"source": [
464459
"from cs_types import *\n",
465-
"from psycopg2.extras import RealDictCursor"
460+
"from psycopg2.extras import RealDictCursor\n",
461+
"\n",
462+
"print(\"Importing done.\")"
466463
]
467464
},
468465
{
469466
"cell_type": "markdown",
470467
"id": "6ac472ff-81d1-418a-998b-975b2b3f3a05",
471468
"metadata": {},
472469
"source": [
473-
"## Insert end query encrypted data\n",
470+
"## Insert test record\n",
474471
"\n",
475472
"With the database extensions, EQL, and application specific data types installed together with the type definitions for Python, your setup is now ready to encrypt and decrypt data."
476473
]
477474
},
478-
{
479-
"cell_type": "markdown",
480-
"id": "0bd5e34e-4840-4398-be46-3cc6b5969e5f",
481-
"metadata": {},
482-
"source": [
483-
"To check what the JSONB format looks like, run the following:"
484-
]
485-
},
486-
{
487-
"cell_type": "code",
488-
"execution_count": null,
489-
"id": "d2111106-e117-46c2-b1a1-ae8b4bb8598e",
490-
"metadata": {},
491-
"outputs": [],
492-
"source": [
493-
"CsText(\"hello, python\", \"examples\", \"encrypted_utf8_str\").to_db_format()"
494-
]
495-
},
496475
{
497476
"cell_type": "markdown",
498477
"id": "3c571924-c592-447b-88a7-fef6b50f2114",
@@ -539,7 +518,14 @@
539518
"id": "524c68bc-be47-4887-881b-1af0b365e259",
540519
"metadata": {},
541520
"source": [
542-
"Check What it looks like from both regular PostgreSQL running on port 5432 and CipherStash Proxy running on port 6432:"
521+
"This should insert a single row in the encrypted `examples` table as:\n",
522+
"\n",
523+
"|encrypted_int|encrypted_boolean|encrypted_date|encrypted_float|encrypted_utf8_str|\n",
524+
"|---|-----|--------------|----|------------|\n",
525+
"|-51|false|<current_date>|-0.5|hello, world|\n",
526+
"\n",
527+
"You can check what it looks like from both regular PostgreSQL running on port 5432 and CipherStash Proxy running on port 6432.\n",
528+
"To look at the data through CipherStash Proxy, run the following:"
543529
]
544530
},
545531
{
@@ -553,6 +539,14 @@
553539
"!printf '\\\\x \\n select * from examples limit 1;' | PGPASSWORD=postgres psql -h localhost -p 6432 -U postgres cipherstash_getting_started"
554540
]
555541
},
542+
{
543+
"cell_type": "markdown",
544+
"id": "802cbfb3-9869-43ce-adae-1367b23ea52e",
545+
"metadata": {},
546+
"source": [
547+
"To look at the data directly on the PostgreSQL server, run the following:"
548+
]
549+
},
556550
{
557551
"cell_type": "code",
558552
"execution_count": null,
@@ -569,7 +563,7 @@
569563
"id": "564d2bc7-0c45-4e5f-ba0a-5919961ee9ce",
570564
"metadata": {},
571565
"source": [
572-
"In the above example, not all fields are populated, but the populated fields should contain JSONB values including the encrypted values, with \"k\" set to \"ct\" indicating \"cipher text\"."
566+
"In the above example, not all fields are populated, but the populated fields contain JSONB values including the encrypted values."
573567
]
574568
},
575569
{
@@ -668,14 +662,31 @@
668662
"print(\"created data for MATCH and ORE queries\")"
669663
]
670664
},
665+
{
666+
"cell_type": "markdown",
667+
"id": "4e67be50-948d-4832-80e9-6411538cf974",
668+
"metadata": {},
669+
"source": [
670+
"The example code above should insert rows like these in the examples table:\n",
671+
"\n",
672+
"| | encrypted_utf_data | encrypted_float| encrypted_jsonb | |\n",
673+
"|--|---|---|---|---|\n",
674+
"| |hello, python| | | |\n",
675+
"| |hello, jupyter| | | |\n",
676+
"| | | 100.1 | | |\n",
677+
"| | | 100.2 | | |\n",
678+
"| | | | {\"top\": {\"level1\": {\"level2\": [\"a\", \"b\", \"c\"]}}} | |\n",
679+
"| | | | {\"top\": {\"level1\": {\"another_key\": [\"a\"]}}} | |\n"
680+
]
681+
},
671682
{
672683
"cell_type": "markdown",
673684
"id": "c2a6b812-980c-4958-a55e-45551cb474c2",
674685
"metadata": {},
675686
"source": [
676687
"### Partial matching\n",
677688
"\n",
678-
"Now, a query can be run to look for a record in the `examples` table where `encrypted_utf_8_str` field contains text `\"pyth\"`:"
689+
"Now, a query can be run to look for a record in the `examples` table where `encrypted_utf_8_str` field contains text `\"pyth\"`, which should match `\"hello, python\"`:"
679690
]
680691
},
681692
{
@@ -726,7 +737,7 @@
726737
"source": [
727738
"### ORE queries\n",
728739
"\n",
729-
"Finally, a query for a record with `encrypted_float` that is larger than `100.15`:"
740+
"Finally, a query for a record with `encrypted_float` that is larger than `100.15` which should match `100.2`:"
730741
]
731742
},
732743
{
@@ -751,7 +762,8 @@
751762
"### JSONB\n",
752763
"\n",
753764
"A record can be found using the JSONB path.\n",
754-
"This only works with a path from the root with no missing nodes in the middle."
765+
"This only works with a path from the root with no missing nodes in the middle.\n",
766+
"The following matches the JSONB field containing keys `top`, `level1` and `level2`:"
755767
]
756768
},
757769
{

0 commit comments

Comments
 (0)