Added Bing's Chatbot, extended API and example, updated README

This commit is contained in:
Julian Müller (ChaoticByte) 2023-03-13 10:44:01 +01:00
parent 308bf0730f
commit c8361abe28
4 changed files with 110 additions and 17 deletions

View file

@ -1,3 +1,16 @@
# ChatGPT-PyAPI
A minimalistic Python API for OpenAI's ChatGPT
## Supported APIs
- Official ChatGPT API by OpenAI
- Unofficial API for Bing Chatbot (required `EdgeGPT` to be installed)
### Official ChatGPT API by OpenAI
You need an API key for the official ChatGPT API.
### Unofficial API for Bing Chatbot
This requires your Cookies to be exported to a json file. See [EdgeGPT's README](https://github.com/acheong08/EdgeGPT) for more infos.

64
chatgpt_pyapi/bing.py Normal file
View file

@ -0,0 +1,64 @@
# Copyright (c) 2023 Julian Müller (ChaoticByte)
import asyncio
from json import dumps, loads
from EdgeGPT import Chatbot as _Chatbot
from EdgeGPT import ConversationStyle
class _Roles:
ASSISTANT = "assistant"
USER = "user"
class Message:
'''Message type'''
def __init__(self, text: str, _role:str=_Roles.USER):
assert type(text) == str
assert type(_role) == str
self.text = text
self.role = _role
@classmethod
def from_api(cls, api_msg: dict):
'''Create a Message object from API format'''
assert type(api_msg) == dict
return cls(
api_msg["item"]["messages"][1]["adaptiveCards"][0]["body"][0]["text"],
_role=_Roles.ASSISTANT)
def to_api(self):
'''Convert to API format'''
return self.text
def __str__(self):
return f"Role: {self.role}, Text: {self.text}"
class ChatGPT:
'''ChatGPT API'''
def __init__(self, cookies_file_path:str, conversation_style=ConversationStyle.precise):
self.bot = _Chatbot(cookiePath=cookies_file_path)
self.conversation_style = conversation_style
self._message_history = []
self._event_loop = asyncio.get_event_loop()
def __del__(self):
self._event_loop.run_until_complete(
self.bot.close())
def chat(self, message: Message) -> Message:
'''Add a message to the message history & send it to Bings Chatbot. Returns the answer as a Message instance.'''
self._message_history.append(message)
# Ask the bot
api_output = self._event_loop.run_until_complete(
self.bot.ask(message.to_api(), conversation_style=self.conversation_style))
response_message = Message.from_api(api_output)
self._message_history.append(response_message)
return response_message
def clear_message_history(self):
self._message_history = []

View file

@ -40,6 +40,9 @@ class Message:
'''Convert to API format'''
return {"role": self.role, "content": self.text}
def __str__(self):
return f"Role: {self.role}, Text: {self.text}"
class ChatGPT:
'''ChatGPT API'''

View file

@ -3,26 +3,39 @@
# Copyright (c) 2023 Julian Müller (ChaoticByte)
from os import environ
from sys import argv
from chatgpt_pyapi.openai import ChatGPT, Message, Models, Roles
# Read the API key from a environment variable
API_KEY = environ["OPENAI_API_KEY"]
example_system_message = "Please provide the following answers as cynical as possible, but still correct."
example_questions = [
"Who are you?",
"Could you please elaborate?"
]
if __name__ == "__main__":
# Create ChatGPT API instance
cgpt = ChatGPT(API_KEY, model=Models.GPT_35_TURBO_0301)
# Provide a system message that will influence the answers
system_in = "Please provide the following answers as cynical as possible, but still correct."
# Add the message to the history, but don't send it yet
cgpt.add_to_chat(Message(system_in, role=Roles.SYSTEM))
bing = False
if len(argv) > 1:
bing = argv[1] == "bing"
if bing:
from chatgpt_pyapi.bing import ChatGPT, Message, ConversationStyle
# Read the path to the cookies file from a environment variable
BING_COOKIES_FILE = environ["BING_COOKIES_FILE"]
# Create ChatGPT API instance (with creative answers)
cgpt = ChatGPT(BING_COOKIES_FILE, ConversationStyle.creative)
cgpt.chat(Message(example_system_message))
else:
from chatgpt_pyapi.openai import ChatGPT, Message, Models, Roles
# Read the API key from a environment variable
API_KEY = environ["OPENAI_API_KEY"]
# Create ChatGPT API instance
cgpt = ChatGPT(API_KEY, model=Models.GPT_35_TURBO_0301)
# Provide a system message that will influence the answers
sys_msg = Message(example_system_message, role=Roles.SYSTEM)
# Add the message to the history, but don't send it yet
cgpt.add_to_chat(sys_msg)
# Have a little chat :D
user_in = "Who are you?"
print(f"USER: {user_in}")
print(cgpt.chat(Message(user_in)).text)
user_in = "Could you please elaborate?"
print(f"\nUSER: {user_in}")
print(cgpt.chat(Message(user_in)).text)
for q in example_questions:
print(f"\nUSER: {q}")
print(cgpt.chat(Message(q)).text)
# Print out message history
print("\nMessage History:")
[print(m.to_api()) for m in cgpt._message_history]
[print(str(m)) for m in cgpt._message_history]