Added Bing's Chatbot, extended API and example, updated README
This commit is contained in:
parent
308bf0730f
commit
c8361abe28
4 changed files with 110 additions and 17 deletions
13
README.md
13
README.md
|
@ -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
64
chatgpt_pyapi/bing.py
Normal 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 = []
|
|
@ -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'''
|
||||
|
|
39
example.py
39
example.py
|
@ -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__":
|
||||
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
|
||||
system_in = "Please provide the following answers as cynical as possible, but still correct."
|
||||
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(Message(system_in, role=Roles.SYSTEM))
|
||||
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]
|
||||
|
|
Reference in a new issue