Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions authors/bharath-swamy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name="Bharath Swamy"
title="Product Team"
image="singlestore"
external=false
13 changes: 13 additions & 0 deletions notebooks/python-udf-template/meta.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[meta]
authors=["bharath-swamy"]
title="Run your first Python UDF"
description="""\
Learn how to connect to create and\
publish a python UDF and call it in SQL.
"""
icon="browser"
difficulty="beginner"
tags=["starter", "notebooks", "python"]
lesson_areas=[]
destinations=["spaces"]
minimum_tier="free-shared"
258 changes: 258 additions & 0 deletions notebooks/python-udf-template/notebook.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
{
"cells": [
{
"id": "1ae3a481",
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"singlestore-header\" style=\"display: flex; background-color: rgba(235, 249, 245, 0.25); padding: 5px;\">\n",
" <div id=\"icon-image\" style=\"width: 90px; height: 90px;\">\n",
" <img width=\"100%\" height=\"100%\" src=\"https://raw.githubusercontent.com/singlestore-labs/spaces-notebooks/master/common/images/header-icons/browser.png\" />\n",
" </div>\n",
" <div id=\"text\" style=\"padding: 5px; margin-left: 10px;\">\n",
" <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",
" <h1 style=\"font-weight: 500; margin: 8px 0 0 4px;\">Run your first Python UDF</h1>\n",
" </div>\n",
"</div>"
]
},
{
"id": "bd0ae268",
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-warning\">\n",
" <b class=\"fa fa-solid fa-exclamation-circle\"></b>\n",
" <div>\n",
" <p><b>Note</b></p>\n",
" <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",
" </div>\n",
"</div>"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "bcb6e6a7",
"metadata": {},
"source": [
"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."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "5776ded1",
"metadata": {},
"source": [
"## Create some simple tables\n",
"\n",
"This setup establishes a basic relational structure to store some reviews for restaurants. Ensure you have selected a database."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "2bbf6a44",
"metadata": {},
"outputs": [],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS reviews;\n",
"\n",
"CREATE TABLE IF NOT EXISTS\n",
"reviews (\n",
" review_id INT PRIMARY KEY,\n",
" store_name VARCHAR(255) NOT NULL,\n",
" review TEXT NOT NULL\n",
");"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "3aace2e9",
"metadata": {},
"source": [
"## Insert sample data"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "0a123cd7",
"metadata": {},
"outputs": [],
"source": [
"%%sql INSERT into reviews (review_id, store_name, review) values\n",
"(\"1\", \"Single Pizza\", \"The staff were very respectful and made thoughtful suggestions. I will definitely go again. 10/10!\"),\n",
"(\"2\", \"Single Pizza\", \"The food was absolutely amazing and the service was fantastic!\"),\n",
"(\"3\", \"Single Pizza\", \"The experience was terrible. The food was cold and the waiter was rude.\"),\n",
"(\"4\", \"Single Pizza\", \"I loved the ambiance and the desserts were out of this world!\"),\n",
"(\"5\", \"Single Pizza\", \"Not worth the price. I expected more based on the reviews\");"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "d58c8382",
"metadata": {},
"source": [
"## Define Python UDF functions\n",
"\n",
"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."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1556ad3c",
"metadata": {},
"outputs": [],
"source": [
"!pip install nltk"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "f3f3b047",
"metadata": {},
"outputs": [],
"source": [
"from singlestoredb.functions import udf\n",
"import nltk\n",
"from nltk.sentiment import SentimentIntensityAnalyzer\n",
"\n",
"nltk.download('vader_lexicon')\n",
"sia = SentimentIntensityAnalyzer()\n",
"\n",
"@udf\n",
"def review_sentiment(review: str) -> str:\n",
" print(\"review:\" + review)\n",
" scores = sia.polarity_scores(review)\n",
" sentiment = (\n",
" \"Positive\" if scores['compound'] > 0.05 else\n",
" \"Negative\" if scores['compound'] < -0.05 else\n",
" \"Neutral\"\n",
" )\n",
" print(\"sentiment:\" + sentiment)\n",
" return sentiment"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "40e2ad59",
"metadata": {},
"source": [
"## Start the Python UDF server\n",
"\n",
"This will start the server as well as register all the functions annotated with `@udf` as external user defined functions on your selected database."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ed4b22cd",
"metadata": {},
"outputs": [],
"source": [
"import singlestoredb.apps as apps\n",
"connection_info = await apps.run_udf_app(replace_existing=True)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "b53cd3d1",
"metadata": {},
"source": [
"## List all registered UDFs\n",
"\n",
"In interactive notebooks, the udf function will be suffixed with `_test` to differentiate it from the published version"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "6008982d",
"metadata": {},
"outputs": [],
"source": [
"%%sql\n",
"SHOW functions"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "58560b03",
"metadata": {},
"source": [
"## Call the UDF from SQL\n",
"\n",
"You will now be able to run queries like\n",
"\n",
"```\n",
"SELECT review_id, store_name, review, review_sentiment_test(review) from reviews order by review_id;\n",
"```\n",
"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."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "4a825f0d",
"metadata": {},
"source": [
"## Publish Python UDF\n",
"\n",
"After validating the Python UDF interactively, you can publish it and access it like\n",
"\n",
"```\n",
"%%sql\n",
"SELECT review_id, store_name, review, review_sentiment(review) from reviews order by review_id\n",
"```\n",
"\n",
"enriching your data exploration experience seamlessly!"
]
},
{
"id": "b6c75678",
"cell_type": "markdown",
"metadata": {},
"source": [
"<div id=\"singlestore-footer\" style=\"background-color: rgba(194, 193, 199, 0.25); height:2px; margin-bottom:10px\"></div>\n",
"<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>"
]
}
],
"metadata": {
"jupyterlab": {
"notebooks": {
"version_major": 6,
"version_minor": 4
}
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}