Skip to content

Commit 6087691

Browse files
authored
Fix section "3-Bad Word Service" in e2e tutorial (#6425)
* Fix section "3-Bad Word Service" in e2e tutorial The latest func cli generates a different Python function template than shown in the tutorial. There is no setup.py anymore and the project uses a toml file for configuration. The entire section was updated and code was corrected. The required func cli version `v0.46.0` was added to the tutorial with a link to the GitHub func repository tags page. The `solution-create-bad-word-filter-service.md` was removed because it was identical to the `create-bad-word-filter-service.md`. All references to it were removed. Issue #6420. Signed-off-by: Stanislav Jakuschevskij <[email protected]> * Remove func version Signed-off-by: Stanislav Jakuschevskij <[email protected]> --------- Signed-off-by: Stanislav Jakuschevskij <[email protected]>
1 parent 1818bf3 commit 6087691

File tree

3 files changed

+101
-298
lines changed

3 files changed

+101
-298
lines changed

docs/versioned/bookstore/page-2/sentiment-analysis-service-for-bookstore-reviews.md

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ In order to do so, you need to install the func CLI. You can follow the [officia
4343
???+ success "Verify"
4444
Running `func version` in your terminal to verify the installation, and you should see the version of the func CLI you installed.
4545

46+
4647
???+ bug "Troubleshooting"
4748
If you see `command not found`, you may need to add the func CLI to your PATH.
4849

@@ -206,9 +207,9 @@ The `sentiment-analysis-app/pyproject.toml` file contains the project configurat
206207
Knative Function will automatically install the dependencies listed here when you build the function.
207208

208209
### **Step 4: Build and run your Knative Function locally (Optional)**
210+
209211
??? info "Click here to expand"
210-
211-
212+
212213
![Image4](images/image4.png)
213214

214215
In Knative Function, there are two ways to build: using the [pack build](https://github.com/knative/func/blob/8f3f718a5a036aa6b6eaa9f70c03aeea740015b9/docs/reference/func_build.md?plain=1#L46){:target="_blank"} or using the [source-to-image (s2i) build](https://github.com/knative/func/blob/4f48549c8ad4dad34bf750db243d81d503f0090f/docs/reference/func_build.md?plain=1#L43){:target="_blank"}.
@@ -276,7 +277,7 @@ Knative Function will automatically install the dependencies listed here when yo
276277

277278
In this case, you will get the full CloudEvent response:
278279

279-
```
280+
```sh
280281
Context Attributes,
281282
specversion: 1.0
282283
type: new-review-comment
@@ -319,7 +320,7 @@ func deploy -b=s2i -v
319320
Function deployed in namespace "default" and exposed at URL:
320321
http://sentiment-analysis-app.default.svc.cluster.local
321322
```
322-
323+
323324
!!! tip
324325
You can find the URL of the Knative Function (Knative Service) by running the following command:
325326

@@ -334,7 +335,6 @@ func deploy -b=s2i -v
334335
sentiment-analysis-app http://sentiment-analysis-app.default.svc.cluster.local sentiment-analysis-app-00001 sentiment-analysis-app-00001 True
335336
```
336337

337-
338338
## **Knative Serving: scale down to zero**
339339

340340
![Image13](images/image13.png)
@@ -368,7 +368,7 @@ After deployment, the `func` CLI provides a URL to access your function. You can
368368

369369
Simply use Knative Function's command `func invoke` to directly send a CloudEvent to the function on your cluster:
370370

371-
```bash
371+
```sh
372372
func invoke -f=cloudevent --data='{"reviewText":"I love Knative so much"}' -v
373373
```
374374

@@ -380,7 +380,7 @@ func invoke -f=cloudevent --data='{"reviewText":"I love Knative so much"}' -v
380380

381381
If you see the response, it means that the function is running successfully.
382382

383-
```
383+
```sh
384384
Context Attributes,
385385
specversion: 1.0
386386
type: moderated-comment
@@ -399,23 +399,15 @@ func invoke -f=cloudevent --data='{"reviewText":"I love Knative so much"}' -v
399399
}
400400
```
401401

402+
## **Next Step**
403+
402404
![Image16](images/image16.png)
403405

404406
In this tutorial, you learned how to create a serverless function for a simple sentiment analysis service with Knative.
405407

406-
## **Next Step**
407-
408-
![Image5](images/image5.png)
409-
410-
Next, we'll deploy another ML service following the same procedure. We encourage you to try it yourself!
408+
Next, we'll deploy another ML service following the same procedure.
411409

412410
!!! tip
413411
Don't forget to `cd` into the root directory `/start` before proceeding.
414412

415-
If you feel comfortable deploying the other ML service yourself, follow this **simplified guide**:
416-
417413
[Go to Deploy ML workflow: Bad word filter :fontawesome-solid-paper-plane:](../page-3/create-bad-word-filter-service.md){ .md-button .md-button--primary }
418-
419-
If you encounter any issues, don't worry—we have a detailed tutorial ready for you.
420-
421-
[Solution - Go to Deploy ML workflow: Bad word filter :fontawesome-solid-paper-plane:](../page-3/solution-create-bad-word-filter-service.md){ .md-button .md-button--primary }

docs/versioned/bookstore/page-3/create-bad-word-filter-service.md

Lines changed: 91 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ function: tutorial
1010

1111
![Image 4](images/image4.png)
1212

13-
As a bookstore owner, you aim to receive instant notifications in a Slack channel whenever a customer submits a new negative review comment. By leveraging Knative Function, you can set up a serverless function that contains a simple bad word filter service to tell whether the text contains any hateful/insultive speech.
14-
15-
If you ever get stuck, check the solution here.
16-
17-
[Solution - Go to Deploy ML workflow: Bad word filter :fontawesome-solid-paper-plane:](../page-3/solution-create-bad-word-filter-service.md){ .md-button .md-button--primary }
13+
As a bookstore owner, you aim to receive instant notifications in a Slack channel whenever a customer submits a new negative review comment. By leveraging Knative Function, you can set up a serverless function that contains a simple bad word filter service to tell whether the text contains any hateful/insulting speech.
1814

1915
## **What Knative features will we learn about?**
2016

@@ -59,78 +55,106 @@ func create -l python bad-word-filter
5955

6056
The file tree will look like this:
6157

62-
```
63-
/start/bad-word-filter
64-
├── func.yaml
58+
```txt
59+
start/bad-word-filter
6560
├── .funcignore
61+
├── function
62+
│   ├── func.py
63+
│   └── __init__.py
64+
├── func.yaml
6665
├── .gitignore
67-
├── requirements.txt
68-
├── app.sh
69-
├── test_func.py
66+
├── pyproject.toml
7067
├── README.md
71-
└── Procfile
72-
└── func.py
68+
└── tests
69+
└── test_func.py
7370
```
7471

7572
### **Step 2: Replace the generated code with the bad word filter logic**
7673

7774
![Image 5](images/image5.png)
7875

79-
`bad-word-filter/func.py` is the file that contains the code for the function. You can replace the generated code with the bad word filter logic. You can use the following code as a starting point:
76+
`bad-word-filter/function/func.py` is the file that contains the code for the function. You can replace the generated code with the bad word filter logic. You can use the following code as a starting point:
77+
78+
???+ abstract "_bad-word-filter/function/func.py_"
8079

81-
???+ abstract "_bad-word-filter/func.py_"
8280
```python
83-
from parliament import Context
84-
from profanity_check import predict
81+
import logging
8582
from cloudevents.http import CloudEvent
83+
from profanity_check import predict
84+
85+
def new():
86+
return Function()
87+
88+
class Function:
89+
async def handle(self, scope, receive, send):
90+
""" Handle all HTTP requests to this Function. The incoming CloudEvent is in scope["event"]. """
91+
logging.info("Request Received")
92+
93+
# 1. Extract the CloudEvent from the scope
94+
request_event = scope["event"]
8695

87-
# The function to convert the bad word filter result into a CloudEvent
88-
def create_cloud_event(inputText, data):
89-
attributes = {
90-
"type": "new-review-comment",
91-
"source": "book-review-broker",
92-
"datacontenttype": "application/json",
93-
"badwordfilter": data,
94-
}
95-
96-
# Put the bad word filter result into a dictionary
97-
data = {"reviewText": inputText, "badWordResult": data}
98-
99-
# Create a CloudEvent object
100-
event = CloudEvent(attributes, data)
101-
return event
102-
103-
def inappropriate_language_filter(text):
104-
profanity_result = predict([text["reviewText"]])
105-
result = "good"
106-
if profanity_result[0] == 1:
107-
result = "bad"
108-
109-
profanity_event = create_cloud_event(text["reviewText"], result)
110-
return profanity_event
111-
112-
def main(context: Context):
113-
"""
114-
Function template
115-
The context parameter contains the Flask request object and any
116-
CloudEvent received with the request.
117-
"""
118-
print("Received CloudEvent: ", context.cloud_event)
119-
120-
# Add your business logic here
121-
return inappropriate_language_filter(context.cloud_event.data)
96+
# 2. Extract the data payload from the event, analyze and create CloudEvent
97+
response_event = self.inappropriate_language_filter(request_event.data)
98+
99+
# 3. Send the response
100+
logging.info(f"Sending response: {response_event.data}")
101+
await send(response_event)
102+
103+
def create_cloud_event(self, inputText, data):
104+
attributes = {
105+
"type": "new-review-comment",
106+
"source": "book-review-broker",
107+
"datacontenttype": "application/json",
108+
"badwordfilter": data,
109+
}
110+
111+
data = {"reviewText": inputText, "badWordResult": data}
112+
113+
return CloudEvent(attributes, data)
114+
115+
def inappropriate_language_filter(self, text):
116+
review_text = text.get("reviewText", "")
117+
profanity_result = predict([review_text])
118+
result = "good"
119+
if profanity_result[0] == 1:
120+
result = "bad"
121+
122+
return self.create_cloud_event(review_text, result)
122123
```
123124

124125
### **Step 3: Configure the dependencies**
125126

126127
![Image 8](images/image8.png)
127-
The content of `bad-word-filter/requirements.txt`:
128-
129-
???+ abstract "_bad-word-filter/requirements.txt_"
130-
```plaintext
131-
parliament-functions==0.1.0
132-
alt-profanity-check==1.4.1.post1
133-
cloudevents==1.10.1
128+
The content of `bad-word-filter/pyproject.toml`:
129+
130+
???+ abstract "_bad-word-filter/pyproject.toml_"
131+
132+
```toml
133+
[project]
134+
name = "function"
135+
description = ""
136+
version = "0.1.0"
137+
requires-python = ">=3.9"
138+
readme = "README.md"
139+
license = "MIT"
140+
dependencies = [
141+
"httpx",
142+
"cloudevents",
143+
"pytest",
144+
"pytest-asyncio",
145+
"alt-profanity-check==1.4.1.post1" # <-- add this dependency
146+
]
147+
authors = [
148+
{ name="Your Name", email="[email protected]"},
149+
]
150+
151+
[build-system]
152+
requires = ["hatchling"]
153+
build-backend = "hatchling.build"
154+
155+
[tool.pytest.ini_options]
156+
asyncio_mode = "strict"
157+
asyncio_default_fixture_loop_scope = "function"
134158
```
135159

136160
### **Step 4: Deploy the function to the cluster**
@@ -139,12 +163,14 @@ The content of `bad-word-filter/requirements.txt`:
139163
!!! note
140164
Please enter `/bad-word-filter` when you are executing the following commands.
141165

142-
```plaintext
166+
```sh
143167
func deploy -b=s2i -v
144168
```
169+
145170
???+ success "Verify"
146171
Expect to see the following message:
147-
```
172+
173+
```sh
148174
Function deployed in namespace "default" and exposed at URL:
149175
http://bad-word-filter.default.svc.cluster.local
150176
```
@@ -153,14 +179,14 @@ func deploy -b=s2i -v
153179

154180
![Image 7](images/image7.png)
155181

156-
```plaintext
182+
```sh
157183
func invoke -f=cloudevent --data='{"reviewText":"I love Knative so much"}' -v
158184
```
159185

160186
???+ success "Verify"
161187
Expect to receive a CloudEvent response:
162188

163-
```plaintext
189+
```sh
164190
Context Attributes,
165191
specversion: 1.0
166192
type: new-review-comment
@@ -183,8 +209,8 @@ If you see the response, it means that the function is running successfully.
183209

184210
![Image 9](images/image9.png)
185211

186-
In this tutorial, you learned how to create a serverless function for a simple service that can detect inappropriate languages in text with Knative.
212+
In this tutorial, you learned how to create a serverless function for a simple service that can detect inappropriate languages in text with Knative.
187213

188-
Next, we'll be learning how to use Knative Sequence to connect the 2 ML workflows and make sure they are executed in the order you want.
214+
Next, we'll be learning how to use Knative Sequence to connect the 2 ML workflows and make sure they are executed in the order you want.
189215

190216
[Go to Create Knative Sequence :fontawesome-solid-paper-plane:](../page-4/create-sequence-to-streamline-ML-workflows.md){ .md-button .md-button--primary }

0 commit comments

Comments
 (0)