sylvainHellin commited on
Commit
500f3c8
·
1 Parent(s): a61ffd1

added image generation tab

Browse files
Files changed (3) hide show
  1. .gitignore +1 -0
  2. app.py +149 -59
  3. style.css +3 -0
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ secrets.env
app.py CHANGED
@@ -1,16 +1,15 @@
1
- # %% [markdown]
2
- # # ChatBot app with Gradio
3
-
4
- # %%
5
  import os
6
  from dotenv import load_dotenv, find_dotenv
7
  import gradio as gr
8
  import openai
 
 
 
9
 
 
10
  _ = load_dotenv(find_dotenv(filename="secrets.env", raise_error_if_not_found=False))
11
 
12
  # Global variable
13
- # ROOT_DIR = os.environ["ROOT_DIR"]
14
  AUTH_USERNAME = os.environ["AUTH_USERNAME"]
15
  AUTH_PASSWORD = os.environ["AUTH_PASSWORD"]
16
 
@@ -20,12 +19,8 @@ openai.api_key = os.environ["OPENAI_API_KEY"]
20
  SYSTEM_PROMPT = "You are a helpful assistant and do your best to answer the user's questions.\
21
  You do not make up answers."
22
 
23
- # %% [markdown]
24
- # ## Define and test the API calls
25
-
26
- # %%
27
- # define the function that will make the API calls
28
- def APIcall(prompt:str, temperature = 0.7, max_tokens = 1024, model="GPT-3.5", stream=True):
29
  if model == "GPT-3.5":
30
  model = "gpt-3.5-turbo-0125"
31
  else:
@@ -47,13 +42,8 @@ def APIcall(prompt:str, temperature = 0.7, max_tokens = 1024, model="GPT-3.5", s
47
  else:
48
  output = response.choices[0].message.content # when Stream is set to False
49
 
50
-
51
- # %% [markdown]
52
- # ## Building the ChatBot with Gradio
53
-
54
- # %%
55
- # Helper function: format the prompt to include history
56
- def formatPrompt(newMsg:str, chatHistory, instruction):
57
 
58
  # start with the system prompt
59
  messages = []
@@ -89,17 +79,17 @@ def formatPrompt(newMsg:str, chatHistory, instruction):
89
  return messages
90
 
91
  # def the response function (to get the answer as one block after generation)
92
- def response(newMsg:str, chatHistory, instruction, temperature, max_tokens, model, stream=False):
93
- prompt = formatPrompt(newMsg=newMsg, chatHistory=chatHistory, instruction=instruction)
94
- response = APIcall(prompt=prompt, temperature=temperature, max_tokens=max_tokens, model=model)
95
  chatHistory.append([newMsg, response])
96
  return "", chatHistory
97
 
98
  # def the streamResponse function, to stream the results as they are generated
99
- def streamResponse(newMsg:str, chatHistory, instruction, temperature, max_tokens, model, stream = True):
100
  chatHistory.append([newMsg, ""])
101
- prompt = formatPrompt(newMsg=newMsg, chatHistory=chatHistory, instruction=instruction)
102
- stream = APIcall(prompt=prompt, temperature=temperature, max_tokens=max_tokens, model=model)
103
  for chunk in stream:
104
  if chunk != None:
105
  chatHistory[-1][1] += chunk
@@ -107,6 +97,26 @@ def streamResponse(newMsg:str, chatHistory, instruction, temperature, max_tokens
107
  else:
108
  return "", chatHistory
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  # Define some components
111
  model = gr.Dropdown(
112
  choices=["GPT-3.5", "GPT-4"],
@@ -136,42 +146,122 @@ max_token = gr.Slider(
136
  info="Maximum number of token the model will take into consideration"
137
  )
138
 
139
- # Build the app
140
- with gr.Blocks(theme='Insuz/Mocha') as app:
141
- with gr.Row():
142
- with gr.Column(scale = 8, elem_classes=["float-left"]):
143
- gr.Markdown("# Private GPT")
144
- gr.Markdown("This chatbot is powered by the openAI GPT series.\
145
- The default model is `GPT-3.5`, but `GPT-4` can be selected in the advanced options.\
146
- \nAs it uses the openAI API, user data is not used to train openAI models (see their official [website](https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance)).")
147
- chatbot = gr.Chatbot() # Associated variable: chatHistory
148
- msg = gr.Textbox(label="Message")
149
- with gr.Row():
150
- with gr.Column(scale=4):
151
- Button = gr.Button(value="Submit")
152
- with gr.Column(scale=4):
153
- clearButton = gr.ClearButton([chatbot, msg])
154
- msg.submit(
155
- fn=streamResponse,
156
- inputs=[msg, chatbot, instruction, temperature, max_token, model],
157
- outputs=[msg, chatbot]
158
- )
159
- Button.click(
160
- fn=streamResponse,
161
- inputs=[msg, chatbot, instruction, temperature, max_token, model],
162
- outputs=[msg, chatbot]
163
- )
164
- with gr.Column(scale = 1, elem_classes=["float-right"]):
165
- with gr.Accordion(label="Advanced options", open=True):
166
- model.render()
167
- instruction.render()
168
- temperature.render()
169
- max_token.render()
170
- gr.close_all()
171
- app.queue().launch(auth=(AUTH_USERNAME, AUTH_PASSWORD))
172
- # app.queue().launch()
173
 
174
- # %%
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
  from dotenv import load_dotenv, find_dotenv
3
  import gradio as gr
4
  import openai
5
+ import requests
6
+ from PIL import Image
7
+ from io import BytesIO
8
 
9
+ # load the secrets if running locally
10
  _ = load_dotenv(find_dotenv(filename="secrets.env", raise_error_if_not_found=False))
11
 
12
  # Global variable
 
13
  AUTH_USERNAME = os.environ["AUTH_USERNAME"]
14
  AUTH_PASSWORD = os.environ["AUTH_PASSWORD"]
15
 
 
19
  SYSTEM_PROMPT = "You are a helpful assistant and do your best to answer the user's questions.\
20
  You do not make up answers."
21
 
22
+ # define the function that will make the API calls for the catbot
23
+ def chatBotCompletionApiCall(prompt:str, temperature = 0.7, max_tokens = 1024, model="GPT-3.5", stream=True):
 
 
 
 
24
  if model == "GPT-3.5":
25
  model = "gpt-3.5-turbo-0125"
26
  else:
 
42
  else:
43
  output = response.choices[0].message.content # when Stream is set to False
44
 
45
+ # Helper function: format the prompt to include history for fhe chatbot
46
+ def chatBotFormatPrompt(newMsg:str, chatHistory, instruction):
 
 
 
 
 
47
 
48
  # start with the system prompt
49
  messages = []
 
79
  return messages
80
 
81
  # def the response function (to get the answer as one block after generation)
82
+ def responseChatBot(newMsg:str, chatHistory, instruction, temperature, max_tokens, model, stream=False):
83
+ prompt = chatBotFormatPrompt(newMsg=newMsg, chatHistory=chatHistory, instruction=instruction)
84
+ response = chatBotCompletionApiCall(prompt=prompt, temperature=temperature, max_tokens=max_tokens, model=model)
85
  chatHistory.append([newMsg, response])
86
  return "", chatHistory
87
 
88
  # def the streamResponse function, to stream the results as they are generated
89
+ def streamResponseChatBot(newMsg:str, chatHistory, instruction, temperature, max_tokens, model, stream = True):
90
  chatHistory.append([newMsg, ""])
91
+ prompt = chatBotFormatPrompt(newMsg=newMsg, chatHistory=chatHistory, instruction=instruction)
92
+ stream = chatBotCompletionApiCall(prompt=prompt, temperature=temperature, max_tokens=max_tokens, model=model)
93
  for chunk in stream:
94
  if chunk != None:
95
  chatHistory[-1][1] += chunk
 
97
  else:
98
  return "", chatHistory
99
 
100
+ # helper function for image generation
101
+ def generateImageOpenAI(prompt, size = "1024x1024", quality = "standard", model = "dall-e-3", n=1):
102
+ '''
103
+ Make an API call to OpenAI's DALL-E model and return the generated image in PIL format
104
+ '''
105
+ print("request sent")
106
+ openAIresponse = openai.images.generate(model=model, prompt=prompt,size=size,quality=quality,n=n,)
107
+ image_url = openAIresponse.data[0].url
108
+
109
+ # get the image in Bytes format
110
+ imageResponse = requests.get(url=image_url)
111
+ imageBytes = imageResponse.content
112
+
113
+ # convert it to PIL format
114
+ image = Image.open(BytesIO(imageBytes))
115
+
116
+ print("image received!")
117
+ # return the result
118
+ return image
119
+
120
  # Define some components
121
  model = gr.Dropdown(
122
  choices=["GPT-3.5", "GPT-4"],
 
146
  info="Maximum number of token the model will take into consideration"
147
  )
148
 
149
+ # Components for Image generator
150
+ genImage = gr.Image(
151
+ label="Result",
152
+ type="pil",
153
+ render = False
154
+ ) # Box for generated image
155
+
156
+ # def helper function to update and render the component
157
+ def generateAndRender(prompt:str, size, quality,):
158
+ '''
159
+ Send the request to the API endpoint and update the components. Outputs:
160
+ - oldPrompt
161
+ - genImage
162
+ - promptBox
163
+ '''
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ # get the image
166
+ image = generateImageOpenAI(prompt, size, quality)
167
+
168
+ # update the components
169
+ oldPrompt = gr.Textbox(value=prompt, label = "Your prompt", render=True)
170
+ genImage = gr.Image(value=image, label="Result", type="pil", render = True)
171
+ promptBox = gr.Textbox(label="Enter your prompt", lines=3)
172
+
173
+ # return the components
174
+ return oldPrompt, genImage, promptBox
175
+
176
+ # Build the app
177
+ with gr.Blocks(theme='Insuz/Mocha', css="style.css") as app:
178
+
179
+ # First tab: chatbot
180
+ with gr.Tab(label="ChatBot"):
181
+ with gr.Row():
182
+ with gr.Column(scale = 8, elem_classes=["float-left"]):
183
+ gr.Markdown("# Private GPT")
184
+ gr.Markdown("This chatbot is powered by the openAI GPT series.\
185
+ The default model is `GPT-3.5`, but `GPT-4` can be selected in the advanced options.\
186
+ \nAs it uses the openAI API, user data is not used to train openAI models (see their official [website](https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance)).")
187
+ chatbot = gr.Chatbot() # Associated variable: chatHistory
188
+ msg = gr.Textbox(label="Message")
189
+ with gr.Row():
190
+ with gr.Column(scale=4):
191
+ Button = gr.Button(value="Submit")
192
+ with gr.Column(scale=4):
193
+ clearButton = gr.ClearButton([chatbot, msg])
194
+ msg.submit(
195
+ fn=streamResponseChatBot,
196
+ inputs=[msg, chatbot, instruction, temperature, max_token, model],
197
+ outputs=[msg, chatbot]
198
+ )
199
+ Button.click(
200
+ fn=streamResponseChatBot,
201
+ inputs=[msg, chatbot, instruction, temperature, max_token, model],
202
+ outputs=[msg, chatbot]
203
+ )
204
+ with gr.Column(scale = 1, elem_classes=["float-right"]):
205
+ with gr.Accordion(label="Advanced options", open=True):
206
+ model.render()
207
+ instruction.render()
208
+ temperature.render()
209
+ max_token.render()
210
 
211
+ # Second Tab: image generation
212
+ with gr.Tab(label="Image Creation"):
213
+ # Title and description
214
+ gr.Markdown("# Image generation")
215
+ gr.Markdown("Powered by OpenAI's `DALL-E 3` Model under the hood.\n\
216
+ You can change the `size` as well as the `quality`.")
217
+
218
+ # First row: prompt
219
+ with gr.Row():
220
+ prompt = gr.Textbox(label="Enter your prompt", lines=3)
221
+
222
+ # Second row: allow for advanced customization
223
+ with gr.Accordion(label="Advanced option", open=False): # should not be visible by default
224
 
225
+ # Three columns of advanced options
226
+ with gr.Row():
227
+ with gr.Column():
228
+ size = gr.Dropdown(
229
+ choices = ["1024x1024", "1024x1792","1792x1024"],
230
+ value = "1024x1024",
231
+ info = "Choose the size of the image",
232
+ )
233
+ with gr.Column():
234
+ quality = gr.Dropdown(
235
+ choices = ["standard", "hd"],
236
+ value = "standard",
237
+ info="Define the quality of the image",
238
+ )
239
+ model = gr.Text(value="dall-e-3", render=False)
240
+ n = gr.Text(value=1, render=False)
241
+
242
+ # Button
243
+ # Submit and clear
244
+ with gr.Row():
245
+ with gr.Column():
246
+ button = gr.Button(value="submit", min_width=30, )
247
+ with gr.Column():
248
+ clearImageButton = gr.ClearButton(components=[prompt, genImage])
249
+
250
+ # Generated Image
251
+ genImage.render()
252
 
253
+ # Not rendered - logic of the app
254
+ button.click(
255
+ fn=generateImageOpenAI,
256
+ inputs=[prompt, size, quality],
257
+ outputs=[genImage],
258
+ )
259
+ prompt.submit(
260
+ fn=generateImageOpenAI,
261
+ inputs=[prompt, size, quality],
262
+ outputs=[genImage],
263
+ )
264
+
265
+ gr.close_all()
266
+ # app.queue().launch(auth=(AUTH_USERNAME, AUTH_PASSWORD))
267
+ app.queue().launch(share=False)
style.css ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ footer {
2
+ visibility: hidden;
3
+ }