Skip to content

Commit a5e3813

Browse files
bharathts07Bharath Swamykesmit13
authored
Add python UDF template for Free shared Tier users (#134)
* add(notebooks): python udf template * add(author): entry for bharath * update(python-udf-template): author * Update notebook.ipynb * update(python-udf-template): add directions on how to run the udf --------- Co-authored-by: Bharath Swamy <[email protected]> Co-authored-by: Kevin D Smith <[email protected]>
1 parent 52e8597 commit a5e3813

File tree

3 files changed

+275
-0
lines changed

3 files changed

+275
-0
lines changed

authors/bharath-swamy.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
name="Bharath Swamy"
2+
title="Product Team"
3+
image="singlestore"
4+
external=false
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[meta]
2+
authors=["bharath-swamy"]
3+
title="Run your first Python UDF"
4+
description="""\
5+
Learn how to connect to create and\
6+
publish a python UDF and call it in SQL.
7+
"""
8+
icon="browser"
9+
difficulty="beginner"
10+
tags=["starter", "notebooks", "python"]
11+
lesson_areas=[]
12+
destinations=["spaces"]
13+
minimum_tier="free-shared"
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
{
2+
"cells": [
3+
{
4+
"id": "1ae3a481",
5+
"cell_type": "markdown",
6+
"metadata": {},
7+
"source": [
8+
"<div id=\"singlestore-header\" style=\"display: flex; background-color: rgba(235, 249, 245, 0.25); padding: 5px;\">\n",
9+
" <div id=\"icon-image\" style=\"width: 90px; height: 90px;\">\n",
10+
" <img width=\"100%\" height=\"100%\" src=\"https://raw.githubusercontent.com/singlestore-labs/spaces-notebooks/master/common/images/header-icons/browser.png\" />\n",
11+
" </div>\n",
12+
" <div id=\"text\" style=\"padding: 5px; margin-left: 10px;\">\n",
13+
" <div id=\"badge\" style=\"display: inline-block; background-color: rgba(0, 0, 0, 0.15); border-radius: 4px; padding: 4px 8px; align-items: center; margin-top: 6px; margin-bottom: -2px; font-size: 80%\">SingleStore Notebooks</div>\n",
14+
" <h1 style=\"font-weight: 500; margin: 8px 0 0 4px;\">Run your first Python UDF</h1>\n",
15+
" </div>\n",
16+
"</div>"
17+
]
18+
},
19+
{
20+
"id": "bd0ae268",
21+
"cell_type": "markdown",
22+
"metadata": {},
23+
"source": [
24+
"<div class=\"alert alert-block alert-warning\">\n",
25+
" <b class=\"fa fa-solid fa-exclamation-circle\"></b>\n",
26+
" <div>\n",
27+
" <p><b>Note</b></p>\n",
28+
" <p>This notebook can be run on a Free Starter Workspace. To create a Free Starter Workspace navigate to <tt>Start</tt> using the left nav. You can also use your existing Standard or Premium workspace with this Notebook.</p>\n",
29+
" </div>\n",
30+
"</div>"
31+
]
32+
},
33+
{
34+
"attachments": {},
35+
"cell_type": "markdown",
36+
"id": "bcb6e6a7",
37+
"metadata": {},
38+
"source": [
39+
"This Jupyter notebook will help you build your first Python UDF using Notebooks, registering it with your database and calling it as part of SQL query."
40+
]
41+
},
42+
{
43+
"attachments": {},
44+
"cell_type": "markdown",
45+
"id": "5776ded1",
46+
"metadata": {},
47+
"source": [
48+
"## Create some simple tables\n",
49+
"\n",
50+
"This setup establishes a basic relational structure to store some reviews for restaurants. Ensure you have selected a database."
51+
]
52+
},
53+
{
54+
"cell_type": "code",
55+
"execution_count": 1,
56+
"id": "2bbf6a44",
57+
"metadata": {},
58+
"outputs": [],
59+
"source": [
60+
"%%sql\n",
61+
"DROP TABLE IF EXISTS reviews;\n",
62+
"\n",
63+
"CREATE TABLE IF NOT EXISTS\n",
64+
"reviews (\n",
65+
" review_id INT PRIMARY KEY,\n",
66+
" store_name VARCHAR(255) NOT NULL,\n",
67+
" review TEXT NOT NULL\n",
68+
");"
69+
]
70+
},
71+
{
72+
"attachments": {},
73+
"cell_type": "markdown",
74+
"id": "3aace2e9",
75+
"metadata": {},
76+
"source": [
77+
"## Insert sample data"
78+
]
79+
},
80+
{
81+
"cell_type": "code",
82+
"execution_count": 2,
83+
"id": "0a123cd7",
84+
"metadata": {},
85+
"outputs": [],
86+
"source": [
87+
"%%sql INSERT into reviews (review_id, store_name, review) values\n",
88+
"(\"1\", \"Single Pizza\", \"The staff were very respectful and made thoughtful suggestions. I will definitely go again. 10/10!\"),\n",
89+
"(\"2\", \"Single Pizza\", \"The food was absolutely amazing and the service was fantastic!\"),\n",
90+
"(\"3\", \"Single Pizza\", \"The experience was terrible. The food was cold and the waiter was rude.\"),\n",
91+
"(\"4\", \"Single Pizza\", \"I loved the ambiance and the desserts were out of this world!\"),\n",
92+
"(\"5\", \"Single Pizza\", \"Not worth the price. I expected more based on the reviews\");"
93+
]
94+
},
95+
{
96+
"attachments": {},
97+
"cell_type": "markdown",
98+
"id": "d58c8382",
99+
"metadata": {},
100+
"source": [
101+
"## Define Python UDF functions\n",
102+
"\n",
103+
"Next, we will be Python UDF function using the `@udf` annotation. We will be using the `VADER` model of `nltk` library to perform sentiment analysis on the review text."
104+
]
105+
},
106+
{
107+
"cell_type": "code",
108+
"execution_count": 3,
109+
"id": "1556ad3c",
110+
"metadata": {},
111+
"outputs": [],
112+
"source": [
113+
"!pip install nltk"
114+
]
115+
},
116+
{
117+
"cell_type": "code",
118+
"execution_count": 4,
119+
"id": "f3f3b047",
120+
"metadata": {},
121+
"outputs": [],
122+
"source": [
123+
"from singlestoredb.functions import udf\n",
124+
"import nltk\n",
125+
"from nltk.sentiment import SentimentIntensityAnalyzer\n",
126+
"\n",
127+
"nltk.download('vader_lexicon')\n",
128+
"sia = SentimentIntensityAnalyzer()\n",
129+
"\n",
130+
"@udf\n",
131+
"def review_sentiment(review: str) -> str:\n",
132+
" print(\"review:\" + review)\n",
133+
" scores = sia.polarity_scores(review)\n",
134+
" sentiment = (\n",
135+
" \"Positive\" if scores['compound'] > 0.05 else\n",
136+
" \"Negative\" if scores['compound'] < -0.05 else\n",
137+
" \"Neutral\"\n",
138+
" )\n",
139+
" print(\"sentiment:\" + sentiment)\n",
140+
" return sentiment"
141+
]
142+
},
143+
{
144+
"attachments": {},
145+
"cell_type": "markdown",
146+
"id": "40e2ad59",
147+
"metadata": {},
148+
"source": [
149+
"## Start the Python UDF server\n",
150+
"\n",
151+
"This will start the server as well as register all the functions annotated with `@udf` as external user defined functions on your selected database."
152+
]
153+
},
154+
{
155+
"cell_type": "code",
156+
"execution_count": 5,
157+
"id": "ed4b22cd",
158+
"metadata": {},
159+
"outputs": [],
160+
"source": [
161+
"import singlestoredb.apps as apps\n",
162+
"connection_info = await apps.run_udf_app(replace_existing=True)"
163+
]
164+
},
165+
{
166+
"attachments": {},
167+
"cell_type": "markdown",
168+
"id": "b53cd3d1",
169+
"metadata": {},
170+
"source": [
171+
"## List all registered UDFs\n",
172+
"\n",
173+
"In interactive notebooks, the udf function will be suffixed with `_test` to differentiate it from the published version"
174+
]
175+
},
176+
{
177+
"cell_type": "code",
178+
"execution_count": 6,
179+
"id": "6008982d",
180+
"metadata": {},
181+
"outputs": [],
182+
"source": [
183+
"%%sql\n",
184+
"SHOW functions"
185+
]
186+
},
187+
{
188+
"attachments": {},
189+
"cell_type": "markdown",
190+
"id": "58560b03",
191+
"metadata": {},
192+
"source": [
193+
"## Call the UDF from SQL\n",
194+
"\n",
195+
"You will now be able to run queries like\n",
196+
"\n",
197+
"```\n",
198+
"SELECT review_id, store_name, review, review_sentiment_test(review) from reviews order by review_id;\n",
199+
"```\n",
200+
"from the SQL editor or any other SQL client. Try it out by opening another notebook, selecting the current Database and running this query in a new cell."
201+
]
202+
},
203+
{
204+
"attachments": {},
205+
"cell_type": "markdown",
206+
"id": "4a825f0d",
207+
"metadata": {},
208+
"source": [
209+
"## Publish Python UDF\n",
210+
"\n",
211+
"After validating the Python UDF interactively, you can publish it and access it like\n",
212+
"\n",
213+
"```\n",
214+
"%%sql\n",
215+
"SELECT review_id, store_name, review, review_sentiment(review) from reviews order by review_id\n",
216+
"```\n",
217+
"\n",
218+
"enriching your data exploration experience seamlessly!"
219+
]
220+
},
221+
{
222+
"id": "b6c75678",
223+
"cell_type": "markdown",
224+
"metadata": {},
225+
"source": [
226+
"<div id=\"singlestore-footer\" style=\"background-color: rgba(194, 193, 199, 0.25); height:2px; margin-bottom:10px\"></div>\n",
227+
"<div><img src=\"https://raw.githubusercontent.com/singlestore-labs/spaces-notebooks/master/common/images/singlestore-logo-grey.png\" style=\"padding: 0px; margin: 0px; height: 24px\"/></div>"
228+
]
229+
}
230+
],
231+
"metadata": {
232+
"jupyterlab": {
233+
"notebooks": {
234+
"version_major": 6,
235+
"version_minor": 4
236+
}
237+
},
238+
"kernelspec": {
239+
"display_name": "Python 3 (ipykernel)",
240+
"language": "python",
241+
"name": "python3"
242+
},
243+
"language_info": {
244+
"codemirror_mode": {
245+
"name": "ipython",
246+
"version": 3
247+
},
248+
"file_extension": ".py",
249+
"mimetype": "text/x-python",
250+
"name": "python",
251+
"nbconvert_exporter": "python",
252+
"pygments_lexer": "ipython3",
253+
"version": "3.11.9"
254+
}
255+
},
256+
"nbformat": 4,
257+
"nbformat_minor": 5
258+
}

0 commit comments

Comments
 (0)