Skip to content

Commit

Permalink
Merge branch 'main' into package-zip
Browse files Browse the repository at this point in the history
  • Loading branch information
sammyCofactory authored Sep 8, 2023
2 parents ffaab83 + 58fa7f3 commit f15c0a5
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
OPENAI_API_KEY=
HUGGINGFACEHUB_API_TOKEN=
PALM_API_KEY=
49 changes: 49 additions & 0 deletions docs/docs/examples/palmai-bot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
sidebar_position: 2
---

# Google PaLM AI bot

This bot makes an API call to PaLMAI and processes the user input. It uses PaLM Chat.

```py
import os
from textbase import bot, Message
from textbase.models import PalmAI
from typing import List

# Load your PALM API key
# PALMAI.api_key = ""
# or from environment variable:
PalmAI.api_key = os.getenv("PALM_API_KEY")

@bot()
def on_message(message_history: List[Message], state: dict = None):

bot_response = PalmAI.generate(
message_history=message_history, # Assuming history is the list of user messages
)

response = {
"data": {
"messages": [
{
"data_type": "STRING",
"value": bot_response
}
],
"state": state
},
"errors": [
{
"message": ""
}
]
}

return {
"status_code": 200,
"response": response
}

```
39 changes: 39 additions & 0 deletions examples/palmai-bot/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import os
from textbase import bot, Message
from textbase.models import PalmAI
from typing import List

# Load your PALM API key
# PALMAI.api_key = ""
# or from environment variable:
PalmAI.api_key = os.getenv("PALM_API_KEY")


@bot()
def on_message(message_history: List[Message], state: dict = None):

bot_response = PalmAI.generate(
message_history=message_history, # Assuming history is the list of user messages
)

response = {
"data": {
"messages": [
{
"data_type": "STRING",
"value": bot_response
}
],
"state": state
},
"errors": [
{
"message": ""
}
]
}

return {
"status_code": 200,
"response": response
}
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ tabulate = "^0.9.0"
functions-framework = "^3.4.0"
yaspin = "^3.0.0"
pydantic = "^2.3.0"
google-generativeai = "^0.1.0"
rich = "^13.5.2"

[build-system]
requires = ["poetry-core"]
Expand Down
29 changes: 28 additions & 1 deletion textbase/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import openai
import google.generativeai as palm
import requests
import time
import typing
Expand Down Expand Up @@ -143,4 +144,30 @@ def generate(
data = json.loads(response.text) # parse the JSON data into a dictionary
message = data['message']

return message
return message

class PalmAI:
api_key = None

@classmethod
def generate(
cls,
message_history: list[Message],
):

assert cls.api_key is not None, "Palm API key is not set."
palm.configure(api_key=cls.api_key)

filtered_messages = []

for message in message_history:
#list of all the contents inside a single message
contents = extract_content_values(message)
if contents:
filtered_messages.extend(contents)

#send request to Google Palm chat API
response = palm.chat(messages=filtered_messages)

print(response)
return response.last
45 changes: 43 additions & 2 deletions textbase/textbase_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import importlib.resources
import re
import zipfile

import urllib.parse
from textbase.utils.logs import fetch_and_display_logs

CLOUD_URL = "https://us-east1-chat-agents.cloudfunctions.net/deploy-from-cli"
UPLOAD_URL = "https://us-east1-chat-agents.cloudfunctions.net/upload-file"
Expand Down Expand Up @@ -97,7 +98,8 @@ def validate_bot_name(ctx, param, value):
@click.option("--path", prompt="Path to the zip folder", required=True)
@click.option("--bot_name", prompt="Name of the bot", required=True, callback=validate_bot_name)
@click.option("--api_key", prompt="Textbase API Key", required=True)
def deploy(path, bot_name, api_key):
@click.option("--show_logs", is_flag=True, default=True, help="Fetch show_logs after deployment")
def deploy(path, bot_name, api_key, show_logs):
click.echo(click.style(f"Deploying bot '{bot_name}' with zip folder from path: {path}", fg='yellow'))

headers = {
Expand Down Expand Up @@ -142,6 +144,23 @@ def deploy(path, bot_name, api_key):
else:
click.echo(click.style("Something went wrong! ❌", fg='red'))
click.echo(response.text)

# Piping logs in the cli in real-time
if show_logs:
click.echo(click.style(f"Fetching logs for bot '{bot_name}'...", fg='green'))

cloud_url = f"{CLOUD_URL}/logs"
headers = {
"Authorization": f"Bearer {api_key}"
}
params = {
"botName": bot_name,
"pageToken": None
}

fetch_and_display_logs(cloud_url=cloud_url,
headers=headers,
params=params)
#################################################################################################################

@cli.command()
Expand Down Expand Up @@ -249,6 +268,28 @@ def delete(bot_id, api_key):
else:
click.echo(click.style("Something went wrong!", fg='red'))


@cli.command()
@click.option("--bot_name", prompt="Name of the bot", required=True)
@click.option("--api_key", prompt="Textbase API Key", required=True)
@click.option("--start_time", prompt="Logs for previous ___ minutes", required=False, default=5)
def logs(bot_name, api_key, start_time):
click.echo(click.style(f"Fetching logs for bot '{bot_name}'...", fg='green'))

cloud_url = f"{CLOUD_URL}/logs"
headers = {
"Authorization": f"Bearer {api_key}"
}
params = {
"botName": bot_name,
"startTime": start_time,
"pageToken": None
}

fetch_and_display_logs(cloud_url=cloud_url,
headers=headers,
params=params)

if __name__ == "__main__":
cli()

42 changes: 42 additions & 0 deletions textbase/utils/logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import requests
from rich.console import Console
from rich.table import Table
from rich.text import Text
import time
import click
from yaspin import yaspin

def fetch_and_display_logs(cloud_url, headers, params):
console = Console()
table = Table(show_header=True, header_style="bold magenta")
table.add_column("Timestamp")
table.add_column("Severity")
table.add_column("Summary")

while True:
with yaspin(text="Logs...", color="yellow") as spinner:
response = requests.get(cloud_url, headers=headers, params=params)

if response.ok:
response_data = response.json()
data = response_data.get('data')
if data is not None:
logs = data.get('logs')
if logs:
for log in logs:
severity_color = 'blue' if log['severity'].lower() in ['notice', 'info', 'debug'] else 'red' if log['severity'].lower() in ['alert', 'critical', 'error'] else 'yellow'

table.add_row(log['timestamp'], Text(log['severity'], style=severity_color), Text(log.get('text', ''), style=severity_color))

console.clear()
console.print(table)
# Update the params for the next request
params['pageToken'] = data.get('nextPageToken')
params['startTime'] = data.get('startTime')
else:
click.echo(click.style("No logs found in the response.", fg='yellow'))
else:
click.echo(click.style("Failed to retrieve logs.", fg='red'))

# Poll the endpoint every 3 seconds
time.sleep(3)

0 comments on commit f15c0a5

Please sign in to comment.