Skip to content

Commit

Permalink
Update AI quickstart and quickstart instruction (#239)
Browse files Browse the repository at this point in the history
- Update the AI quickstart
- Add instructions for installing libpq. Solve
#231
  • Loading branch information
qianl15 authored Oct 7, 2024
1 parent d04db95 commit 9aa0249
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 137 deletions.
4 changes: 2 additions & 2 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import { RiCalendarScheduleLine } from "react-icons/ri";
language="python"
/>
<CardLink
label="AI-Powered Storyteller"
label="OpenAI Quickstart"
href="python/examples/ai-starter"
description="Use DBOS and OpenAI to build a reliable cloud AI app in 9 lines of code."
description="Build an interactive AI application and deploy it to the cloud in just 9 lines of code."
index="2"
icon={<SiOpenai color="white" size={50}/>}
language="python"
Expand Down
18 changes: 9 additions & 9 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ import { TbHexagonNumber1, TbHexagonNumber2, TbHexagonNumber3, TbHexagonNumber4
</section>

### Example Applications
import { FaSlack } from "react-icons/fa6";
import { MdOutlineShoppingCart } from "react-icons/md";
import { IoEarth } from "react-icons/io5";
import { SiOpenai } from "react-icons/si";

<section className="row list">
<NarrowCardLink
label="AI-Powered Slackbot"
href="python/examples/rag-slackbot"
description="Build a Slackbot that uses RAG to answer questions about previous Slack conversations."
label="OpenAI Quickstart"
href="python/examples/ai-starter"
description="Build an interactive AI application and deploy it to the cloud in just 9 lines of code."
index="1"
icon={<FaSlack color="white" size={30}/>}
icon={<SiOpenai color="white" size={30}/>}
/>
<NarrowCardLink
label="Widget Store"
Expand All @@ -65,11 +65,11 @@ import { IoEarth } from "react-icons/io5";
icon={<MdOutlineShoppingCart color="white" size={30}/>}
/>
<NarrowCardLink
label="Earthquake Tracker"
href="python/examples/earthquake-tracker"
description="Build a real-time earthquake dashboard by streaming data from the USGS into Postgres."
label="Scheduled Reminders"
href="python/examples/scheduled-reminders"
description="Use DBOS to build and deploy an app that schedules reminder emails for any day in the future."
index="3"
icon={<IoEarth color="white" size={30}/>}
icon={<RiCalendarScheduleLine color="white" size={30}/>}
/>
</section>

Expand Down
146 changes: 20 additions & 126 deletions docs/python/examples/ai-starter.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
---
displayed_sidebar: examplesSidebar
sidebar_position: 2
title: AI-Powered Storyteller
title: OpenAI Quickstart
hide_table_of_contents: false
---
import InstallNode from '/docs/partials/_install_node.mdx';

In this tutorial, you'll learn how to build a reliable AI agent with DBOS from scratch.
In just **9 lines of code** build an interactive AI application with LlamaIndex and OpenAI and host it on the cloud.

All source code is [available on GitHub](https://github.com/dbos-inc/dbos-demo-apps/tree/main/python/ai-storyteller).
In this tutorial, you'll learn how to build an interactive AI application and deploy it to the cloud in just **9 lines of code**.

### Preparation

<section className="row list">
<article className="col col--6">

First, you need to create a folder for your app and activate a virtual environment. You also want to create an empty file named `main.py` for your code.
First, create a folder for your app and activate a virtual environment.
</article>

<article className="col col--6">
Expand Down Expand Up @@ -112,7 +110,7 @@ ai-app/

### Load Data and Build a Q&A Engine

Let's start with a 5 line-of-code LlamaIndex starter.
Now, let's use LlamaIndex to write a simple AI application in just 5 lines of code.
Add the following code to your `main.py`:

```python showLineNumbers title="main.py"
Expand Down Expand Up @@ -189,12 +187,21 @@ def get_answer():
return str(response)
```

Now, install the DBOS Cloud CLI if you haven't already (requires Node):
Now, install the DBOS Cloud CLI if you haven't already (requires Node.js):


```shell
npm i -g @dbos-inc/dbos-cloud
```

<details>
<summary>Instructions to install Node.js</summary>

<InstallNode />

</details>


Then freeze dependencies to `requirements.txt` and deploy to DBOS Cloud:

```shell
Expand All @@ -210,122 +217,9 @@ To see that your app is working, visit `<URL>` in your browser.

Congratulations, you've successfully deployed your first AI app to DBOS Cloud! You can see your deployed app in the [cloud console](https://console.dbos.dev/login-redirect).

### Building a Reliable AI Agent

Want to have some fun?
Let's add multiple steps and turn this simple Q&A app into a more complex AI agent -- a storyteller Slackbot! Add the following lines to `main.py`.
Note that this is normal Python code, with DBOS-specific lines highlighted.

```python showLineNumbers title="main.py"
#highlight-next-line
from dbos import SetWorkflowID
import os
import requests
slack_webhook_url = os.getenv("SLACK_WEBHOOK_URL")
#highlight-next-line
@DBOS.step()
def get_growup():
response = query_engine.query("What did the author do growing up?")
return str(response)
#highlight-next-line
@DBOS.step()
def get_start_yc():
response = query_engine.query("How did the author start YC?")
return str(response)
#highlight-next-line
@DBOS.step()
def get_after_yc():
response = query_engine.query("What happened after YC?")
return str(response)
#highlight-next-line
@DBOS.step()
def post_to_slack(message: str):
requests.post(slack_webhook_url, headers={"Content-Type": "application/json"}, json={"text": message})
DBOS.logger.info(f"Sent story version {DBOS.workflow_id} to Slack!")
# This workflow invokes the above three steps to tell a whole story.
# Then, optionally send the story to a Slack channel.
#highlight-next-line
@DBOS.workflow()
def story_workflow():
res1 = get_growup()
res2 = get_start_yc()
res3 = get_after_yc()
story = f"Story Version {DBOS.workflow_id}: First, {res1} Then, {res2} Finally, {res3}"
if slack_webhook_url:
post_to_slack(story)
return story
# Let's define a route that generates a version of the story.
# Every time you visit the same version, you get the same story.
@app.get("/story/{version}")
def get_story(version: str):
#highlight-next-line
with SetWorkflowID(version):
return story_workflow()
```

<details>
<summary>(Optional) Setting up a Slack webhook </summary>

Optionally, you can create an [incoming webhook](https://api.slack.com/messaging/webhooks) to post stories from your app to your Slack workspace.
It should look something like this:

```
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
```

Set it as an environment variable:

<Tabs groupId="operating-systems" className="small-tabs">
<TabItem value="maclinux" label="macOS or Linux">
```shell
export SLACK_WEBHOOK_URL=XXXXX
```
</TabItem>
<TabItem value="win-ps" label="Windows (PowerShell)">
```shell
set SLACK_WEBHOOK_URL=XXXXX
```
</TabItem>
<TabItem value="win-cmd" label="Windows (cmd)">
```shell
set SLACK_WEBHOOK_URL=XXXXX
```
</TabItem>
</Tabs>


Declare the environment variable in `dbos-config.yaml`:


```yaml title="dbos-config.yaml"
env:
SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL}
```

</details>


Deploy it to DBOS Cloud again (or [run it locally](../../quickstart#run-your-app-locally)). Visit `<URL>/story/<version>` in your browser. For example:
<BrowserWindow url="https://<username>-ai-app.cloud.dbos.dev/story/v1">
"First, The author worked on writing short stories and programming... Then, The author started Y Combinator (YC) by organizing a summer program called the Summer Founders Program... Finally, After YC, the individual decided to pursue painting as a new endeavor..."
</BrowserWindow>

If you configured a Slack webhook, you should be able to see a copy of this story in your Slack channel!

To tell a slightly different version of the story, visit another version. For example:
<BrowserWindow url="https://<username>-ai-app.cloud.dbos.dev/story/v2">
"First, The author wrote short stories and tried programming on the IBM 1401 in 9th grade using an early version of Fortran... Then, The author started YC by deciding to create an investment firm with Jessica after facing delays from VCs... Finally, Paul Graham decided to hand over Y Combinator (YC) to someone else after his mother had a stroke in 2012..."
</BrowserWindow>

Because this app uses a DBOS workflow, it _executes durably_: if it is ever interrupted, it automatically resumes from the last completed step, completing the story and posting it to Slack.
It is also _idempotent_, using the version number you provide as an idempotency key (through `SetWorkflowID`).
That way, if you submit multiple requests for the same version, the workflow only executes once and subsequent re-executions with the same version number return the same story and don't re-post to Slack.
### Next Steps

Now you know how to build a reliable AI app! This is just the beginning of your DBOS journey. Check out the [Python guide](../programming-guide.md) to learn more or try out more [examples](../../examples) of apps you can build with DBOS.
This is just the beginning of your DBOS journey. Next, check out how DBOS can make your AI applications more scalable and resilient:
- Use [durable execution](../programming-guide.md) to write crashproof workflows.
- Use [queues](../tutorials/queue-tutorial.md) to gracefully manage AI/LLM API rate limits.
- Want to build a more complex app? Check out the [AI-Powered Slackbot](./rag-slackbot.md).
32 changes: 32 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,38 @@ Next, initialize your folder with a sample application.
```shell
dbos init
```

<details>
<summary>What if `dbos init` fails?</summary>

If you see an error message `ImportError: no pq wrapper available`, try to install the binary package:

```shell
pip install "psycopg[binary]"
```

If the binary package is unavailable for your machine, try to install `libpq`:

<Tabs groupId="operating-systems" className="small-tabs">
<TabItem value="mac" label="macOS">
```shell
brew install libpq
```
</TabItem>
<TabItem value="linux" label="Linux">
```shell
sudo apt install libpq5
```
</TabItem>
<TabItem value="win-ps" label="Windows">
Use the [interactive windows installer](https://www.postgresql.org/download/windows/) to install **Command Line Tools**.
</TabItem>
</Tabs>

If this fails, please check out the [psycopg3 installation guide](https://www.psycopg.org/psycopg3/docs/basic/install.html).

</details>

</article>

</section>
Expand Down

0 comments on commit 9aa0249

Please sign in to comment.