Imaginer/src/provider/openai.py

97 lines
3 KiB
Python
Raw Normal View History

from .base import ImaginerProvider
2023-04-30 19:03:34 +00:00
import openai
import socket
from gi.repository import Gtk, Adw, GLib
2023-04-30 19:03:34 +00:00
from PIL import Image, UnidentifiedImageError
import io
2023-04-30 23:45:31 +00:00
class OpenAIProvider(ImaginerProvider):
name = "Open AI"
slug = "openai"
2023-05-01 09:22:43 +00:00
version = "0.1.0"
api_key_title = "API Key"
url = "https://imaginer.codeberg.page/help/openai"
2023-04-30 19:03:34 +00:00
def __init__(self, win, app, *args, **kwargs):
super().__init__(win, app, *args, **kwargs)
self.chat = openai.ChatCompletion
def ask(self, prompt, negative_prompt):
2023-04-30 19:03:34 +00:00
try:
print("Prompt:", prompt)
response = openai.Image.create(
prompt=prompt, n=1, size="1024x1024"
)
image_url = response["data"][0]["url"]
image_bytes = requests.get(image_url).content
2023-04-30 19:03:34 +00:00
except openai.error.AuthenticationError:
print("No API key")
2023-04-30 19:03:34 +00:00
self.no_api_key()
return ""
except openai.error.OpenAIError as e:
print("Invalid request")
self.win.banner.props.title = e.error["message"]
2023-04-30 19:03:34 +00:00
self.win.banner.props.button_label = ""
self.win.banner.set_revealed(True)
return ""
except openai.error.RateLimitError:
print("Rate limit")
self.win.banner.props.title = "You exceeded your current quota, please check your plan and billing details."
self.win.banner.props.button_label = ""
self.win.banner.set_revealed(True)
return ""
2023-04-30 19:03:34 +00:00
except socket.gaierror:
self.no_connection()
return ""
else:
self.hide_banner()
if image_bytes:
try:
return Image.open(io.BytesIO(image_bytes))
except UnidentifiedImageError:
error = json.loads(image_bytes)["error"]
self.win.banner.set_title(error)
self.win.banner.set_revealed(True)
return None
else:
return None
2023-04-30 19:03:34 +00:00
@property
def require_api_key(self):
2023-04-30 22:30:58 +00:00
return True
2023-04-30 19:03:34 +00:00
2023-05-01 09:22:43 +00:00
def preferences(self, win):
self.pref_win = win
2023-04-30 19:03:34 +00:00
self.expander = Adw.ExpanderRow()
self.expander.props.title = self.name
2023-05-08 20:41:45 +00:00
self.expander.add_action(self.about()) # TODO: in Adw 1.4, use add_suffix
self.expander.add_action(self.enable_switch())
2023-05-07 13:27:45 +00:00
2023-04-30 19:03:34 +00:00
self.api_row = Adw.PasswordEntryRow()
self.api_row.connect("apply", self.on_apply)
2023-05-05 22:27:09 +00:00
self.api_row.props.text = openai.api_key or ""
self.api_row.props.title = self.api_key_title
2023-04-30 19:03:34 +00:00
self.api_row.set_show_apply_button(True)
self.api_row.add_suffix(self.how_to_get_a_token())
2023-04-30 19:03:34 +00:00
self.expander.add_row(self.api_row)
return self.expander
def on_apply(self, widget):
self.hide_banner()
api_key = self.api_row.get_text()
openai.api_key = api_key
def save(self):
2023-04-30 23:45:31 +00:00
return {"api_key": openai.api_key}
2023-04-30 19:03:34 +00:00
def load(self, data):
2023-05-05 22:27:09 +00:00
if data["api_key"]:
openai.api_key = data["api_key"]