Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workflow #3

Merged
merged 2 commits into from
May 24, 2024
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
13 changes: 12 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
# API Keys
GOOGLE_API_KEY=
OPENAI_API_KEY=

# Postgres
POSTGRES_USERNAME=
POSTGRES_PASSWORD=
POSTGRES_PASSWORD=
POSTGRES_HOST=
POSTGRES_PORT=
POSTGRES_DATABASE=

# Redis
REDIS_HOST=
REDIS_PORT=
REDIS_PASSWORD=
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ _Built right after [Unopened AI](https://github.com/waynemaranga/unopened_ai), i
![Shell](https://img.shields.io/badge/Shell_Script-121011?style=for-the-badge&logo=gnu-bash&logoColor=white)
![GPT](https://img.shields.io/badge/ChatGPT-74aa9c?style=for-the-badge&logo=openai&logoColor=white)
![Postgres](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white)
![Python]()
![Lua]()

## 📝 TODO

Expand Down
52 changes: 52 additions & 0 deletions bin/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import click # https://click.palletsprojects.com/en/8.1.x/
from openai import OpenAI
from pathlib import Path # https://realpython.com/python-pathlib/
from collections import Counter
from os import getenv
from dotenv import load_dotenv
import datetime

load_dotenv()

cwd: Path = Path.cwd() # current working dir
HOME_DIR: Path = Path.home() # user's home dir; OS-agnostic
cmd = Path(__file__).parent # current module's location; cmd != cwd
OPENAI_API_KEY = getenv("OPENAI_API_KEY")
counter_cwd = Counter(i for i in cwd.iterdir())
counter_cmd = Counter(j.suffix for j in cmd.iterdir())


client = OpenAI(api_key=OPENAI_API_KEY)


def respond(prompt: str, model="gpt-3.5-turbo") -> str:
""""""
if type(prompt) != str:
prompt = prompt.to_string()

completion = client.chat.completions.create(
model=model,
max_tokens=1024,
temperature=0.2,
messages=[{"role": "system", "content": "You are a chatbot."},
{"role": "user", "content": prompt}], # fmt: skip
)

return completion.choices[0].message.content


@click.command()
@click.option("--model", default="gpt-3.5-turbo", help="MODEL")
@click.option("--input", prompt="You", help="Ask Elizabot a question")
def chat(model, input):
# return respond(prompt=input, model=model)
# return respond(prompt=input)
click.echo(respond(model=model, prompt=input))


if __name__ == "__main__":
# counter_home = Counter(j for j in HOME_DIR.iterdir())
# print(counter_cwd)
# print(counter_cmd)
# print(respond("How old was Genghis Khan when he was born?"))
chat()
5 changes: 2 additions & 3 deletions lib/backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,8 @@ class Backend {
String? postgresUsername = env['POSTGRES_USERNAME'] as String;
String? postgresDatabase = env['POSTGRES_DATABASE'] as String;
String? postgresHost = env['POSTGRES_HOST'] as String; // probably localhost
// int? postgresPort = env['POSTGRES_PORT'] as int; // probably 5432
// int postgresPort = int.parse(dotenv.env['POSTGRES_PORT']!);// probably 5432
int postgresPort = 5432;
int postgresPort = int.parse(env['POSTGRES_PORT']!); // probably 5432
// int postgresPort = 5432;
String? postgressPassword = env['POSTGRES_PASSWORD'] as String;

/// ## `endpoint`
Expand Down
88 changes: 88 additions & 0 deletions lib/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
from os import getenv
from dotenv import load_dotenv
import psycopg2
import redis
from redis import StrictRedis

load_dotenv()

POSTGRES_USERNAME = getenv("POSTGRES_")
POSTGRES_PASSWORD = getenv("POSTGRES_")
POSTGRES_HOST = getenv("POSTGRES_")
POSTGRES_PORT = getenv("POSTGRES_")
POSTGRES_DATABASE = getenv("POSTGRES_")
REDIS_HOST = getenv("REDIS_HOST")
REDIS_PORT = getenv("REDIS_PORT")
REDIS_PASSWORD = getenv("REDIS_PASSWORD")

# connection = psycopg2.connect(database=POSTGRES_DATABASE) # ... messy


class Chat:
def __init__(self, chat_id: str) -> None:
self.chat_id: str = chat_id
self.redis_client: StrictRedis = redis.StrictRedis(
host=REDIS_HOST,
port=REDIS_PORT,
password=REDIS_PASSWORD,
decode_responses=True,
)

def __str__(self) -> str:
return f"Chat ID: {self.chat_id}"

def save_chat(self, message: str) -> None:
#! can be named better, save != store i.e in-memory
self.redis_client.rpush(self.chat_id, message)

def get_conversation(self) -> list:
return self.redis_client.lrange(name=self.chat_id, start=0, end=-1)

def finalize_conversation(self) -> None:
"""Placeholder fn. for somethin mighty"""
conversation: list = self.get_conversation()
final_conversation: str = "\n".join(
conversation
) # maybe XML transformation, like complicated joins
self.store_in_postgres(final_conversation)
self.redis_client.delete(self.chat_id)

def store_in_postgres(self, final_conversation: str) -> None:
try:
connection = psycopg2.connect(
dbname=POSTGRES_DATABASE,
user=POSTGRES_USERNAME,
password=POSTGRES_PASSWORD,
host=POSTGRES_HOST,
port=POSTGRES_PORT,
)
_cursorrr = connection.cursor()
_cursorrr.execute(
"INSERT INTO chats (chat_id, conversation) VALUES (%s, %s)",
(self.chat_id, final_conversation),
)
connection.commit()
_cursorrr.close()
connection.close()
except (Exception, psycopg2.Error) as error:
print("Error while connecting to PostgreSQL", error)

def count_bill(self) -> None:
conversation = self.get_conversation()
joined_conversation = "\n".join(conversation)
tokens = joined_conversation.split()
token_count = len(tokens)
cost_per_1000_tokens = 0.02
cost = (token_count / 1000) * cost_per_1000_tokens
print(f"Total tokens used: {token_count}")
print(f"Total cost in USD: ${cost:.4f}")
return cost


if __name__ == "__main__":
test_chat = Chat(chat_id="test_chat_id")
test_chat.save_chat(message="Hello")
test_chat.save_chat(message="How are you?")
print(test_chat.get_conversation())
test_chat.finalize_conversation()
test_chat.count_bill()
Loading