MingDoan commited on
Commit
4d5b0bf
1 Parent(s): e83cec6

feat: Add VQA feature

Browse files
controllers/config.py CHANGED
@@ -1,4 +1,5 @@
1
  from controllers.fw import add_fw_option, del_fw_option, fetch_fw_options
 
2
 
3
 
4
  def on_fw_add_btn_click(url: str):
@@ -16,3 +17,7 @@ def on_del_btn_click(url: str):
16
  options.pop(url)
17
  # Return new options
18
  return options, ""
 
 
 
 
 
1
  from controllers.fw import add_fw_option, del_fw_option, fetch_fw_options
2
+ from services.state import set_state
3
 
4
 
5
  def on_fw_add_btn_click(url: str):
 
17
  options.pop(url)
18
  # Return new options
19
  return options, ""
20
+
21
+
22
+ def on_fw_radio_change(option: str):
23
+ set_state('fw_option', option)
controllers/fd.py CHANGED
@@ -18,10 +18,9 @@ def draw_bboxs(image: Image, faces: list, color: str):
18
  return np_image
19
 
20
 
21
- def fd_controller(image: Image, model: str, color: str, fw_option: str = 'none'):
22
  request_data = {
23
  "image": image_to_bytes(image),
24
- "model": model
25
  }
26
  response = post_data(
27
  f"/api/fd/{get_fw_query_params(fw_option)}", files=request_data)
 
18
  return np_image
19
 
20
 
21
+ def fd_controller(image: Image, color: str, fw_option: str = 'none'):
22
  request_data = {
23
  "image": image_to_bytes(image),
 
24
  }
25
  response = post_data(
26
  f"/api/fd/{get_fw_query_params(fw_option)}", files=request_data)
controllers/vqa.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from PIL import Image
2
+ from controllers.utils import image_to_bytes
3
+ from services.api_service import post_data
4
+ from .fw import get_fw_query_params
5
+
6
+
7
+ def vqa_controller(image: Image, question: str, fw_option: str = 'none'):
8
+ request_data_files = {
9
+ "image": image_to_bytes(image),
10
+ }
11
+ request_data_form = {
12
+ "question": question,
13
+ }
14
+ response = post_data(
15
+ f"/api/vqa/{get_fw_query_params(fw_option)}", files=request_data_files, data=request_data_form)
16
+ print(response)
17
+ if response is None:
18
+ return None
19
+ return response['answer']
db/state.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"fw_option": "auto"}
services/api_service.py CHANGED
@@ -15,10 +15,10 @@ def get_data(url, params=None, parse_json=True):
15
  return None
16
 
17
 
18
- def post_data(url, json=None, files=None, parse_json=True):
19
  if url.startswith("/"):
20
  url = API_ENDPOINT + url
21
- response = post(url, json=json, files=files)
22
  if response.status_code == 200:
23
  if parse_json:
24
  return response.json()
 
15
  return None
16
 
17
 
18
+ def post_data(url, json=None, files=None, data=None, parse_json=True):
19
  if url.startswith("/"):
20
  url = API_ENDPOINT + url
21
+ response = post(url, json=json, files=files, data=data)
22
  if response.status_code == 200:
23
  if parse_json:
24
  return response.json()
services/state.py CHANGED
@@ -1,19 +1,16 @@
1
- from utilities.constants import FW_DEFAULT_OPTION
 
2
 
3
 
4
- class AppState():
5
- def __init__(self):
6
- self._state = {}
 
7
 
8
- def get(self, key):
9
- return self._state.get(key)
10
 
11
- def set(self, key, value):
12
- self._state[key] = value
13
-
14
-
15
- # Create app state
16
- app_state = AppState()
17
-
18
- # Initialize app state
19
- app_state.set('fw_option', FW_DEFAULT_OPTION)
 
1
+ import json
2
+ from utilities.constants import STATE_JSON_FILE
3
 
4
 
5
+ def get_state(key: str, default=None):
6
+ with open(STATE_JSON_FILE, 'r') as f:
7
+ state: dict = json.load(f)
8
+ return state.get(key, default)
9
 
 
 
10
 
11
+ def set_state(key: str, value):
12
+ with open(STATE_JSON_FILE, 'r') as f:
13
+ state = json.load(f)
14
+ state[key] = value
15
+ with open(STATE_JSON_FILE, 'w') as f:
16
+ json.dump(state, f)
 
 
 
utilities/constants.py CHANGED
@@ -1,4 +1,8 @@
 
 
1
  API_ENDPOINT = "https://gdscfptu-ai-service-hf.hf.space"
 
 
2
  FW_DEFAULT_OPTION = "auto"
3
  CHAT_EXAMPLES = ["Where should I go in Da Nang?",
4
  "Best destinations in Quy Nhon"]
 
1
+ import os
2
+
3
  API_ENDPOINT = "https://gdscfptu-ai-service-hf.hf.space"
4
+ STATE_JSON_FILE = os.path.join(os.getcwd(), "db", "state.json")
5
+
6
  FW_DEFAULT_OPTION = "auto"
7
  CHAT_EXAMPLES = ["Where should I go in Da Nang?",
8
  "Best destinations in Quy Nhon"]
views/__init__.py CHANGED
@@ -3,6 +3,7 @@ import gradio as gr
3
  from .rembg import rembg_interface
4
  from .fd import fd_interface
5
  from .chat import chat_interface
 
6
  from .config import config_interface
7
 
8
 
@@ -11,10 +12,11 @@ def create_interface():
11
  fd_ui = fd_interface()
12
  chat_ui = chat_interface()
13
  config_ui = config_interface()
 
14
 
15
  return gr.TabbedInterface(
16
  title="GDSC AI Service Inference",
17
- interface_list=[rembg_ui, fd_ui, chat_ui.queue(), config_ui],
18
  tab_names=[rembg_ui.title, fd_ui.title,
19
- chat_ui.title, config_ui.title],
20
  )
 
3
  from .rembg import rembg_interface
4
  from .fd import fd_interface
5
  from .chat import chat_interface
6
+ from .vqa import vqa_interface
7
  from .config import config_interface
8
 
9
 
 
12
  fd_ui = fd_interface()
13
  chat_ui = chat_interface()
14
  config_ui = config_interface()
15
+ vqa_ui = vqa_interface()
16
 
17
  return gr.TabbedInterface(
18
  title="GDSC AI Service Inference",
19
+ interface_list=[rembg_ui, fd_ui, chat_ui.queue(), vqa_ui, config_ui],
20
  tab_names=[rembg_ui.title, fd_ui.title,
21
+ chat_ui.title, vqa_ui.title, config_ui.title],
22
  )
views/chat.py CHANGED
@@ -1,13 +1,11 @@
1
  import gradio as gr
2
  from controllers.chat import chat_controller
3
- from services.state import app_state
4
-
5
- CHAT_EXAMPLES = ["Where should I go in Da Nang?",
6
- "Best destinations in Quy Nhon"]
7
 
8
 
9
  def chats_yielding(prompt: str, histories: list[list]):
10
- for msg in chat_controller(prompt, histories, app_state.get('fw_option')):
11
  yield msg
12
 
13
 
 
1
  import gradio as gr
2
  from controllers.chat import chat_controller
3
+ from services.state import get_state
4
+ from utilities.constants import FW_DEFAULT_OPTION, CHAT_EXAMPLES
 
 
5
 
6
 
7
  def chats_yielding(prompt: str, histories: list[list]):
8
+ for msg in chat_controller(prompt, histories, get_state('fw_option', FW_DEFAULT_OPTION)):
9
  yield msg
10
 
11
 
views/config.py CHANGED
@@ -1,13 +1,13 @@
1
  import gradio as gr
2
- from controllers.config import on_del_btn_click, on_fw_add_btn_click
3
  from controllers.fw import fetch_fw_options
4
- from utilities.constants import FW_RADIO_CHOICES, FW_DEFAULT_OPTION
5
 
6
 
7
  def config_interface():
8
  with gr.Blocks() as ui:
9
  gr.Markdown("### Forwarding Endpoint")
10
- radio_btn = gr.Radio(choices=FW_RADIO_CHOICES, value=FW_DEFAULT_OPTION,
11
  label="Select Forwarding Option")
12
  fw_list = gr.Label(value=fetch_fw_options,
13
  label="Current Endpoints", every=2)
@@ -17,13 +17,13 @@ def config_interface():
17
  with gr.Row():
18
  add_btn = gr.Button(value="Add Endpoint", variant="secondary")
19
  del_btn = gr.Button(value="Delete Endpoint", variant="stop")
20
- gr.Markdown("### OpenAI API Key")
21
- with gr.Column():
22
- input_box2 = gr.Textbox(
23
- label="OpenAI API Key", placeholder="sk_...")
24
- with gr.Row():
25
- add_btn2 = gr.Button(value="Add Key", variant="secondary")
26
- del_btn2 = gr.Button(value="Reset Key", variant="stop")
27
 
28
  # Assign actions
29
  add_btn.click(
@@ -36,6 +36,10 @@ def config_interface():
36
  inputs=[input_box],
37
  outputs=[fw_list, input_box]
38
  )
 
 
 
 
39
 
40
  ui.title = "Configuration"
41
  return ui
 
1
  import gradio as gr
2
+ from controllers.config import on_del_btn_click, on_fw_add_btn_click, on_fw_radio_change
3
  from controllers.fw import fetch_fw_options
4
+ from utilities.constants import FW_RADIO_CHOICES
5
 
6
 
7
  def config_interface():
8
  with gr.Blocks() as ui:
9
  gr.Markdown("### Forwarding Endpoint")
10
+ radio_btn = gr.Radio(choices=FW_RADIO_CHOICES,
11
  label="Select Forwarding Option")
12
  fw_list = gr.Label(value=fetch_fw_options,
13
  label="Current Endpoints", every=2)
 
17
  with gr.Row():
18
  add_btn = gr.Button(value="Add Endpoint", variant="secondary")
19
  del_btn = gr.Button(value="Delete Endpoint", variant="stop")
20
+ # gr.Markdown("### OpenAI API Key")
21
+ # with gr.Column():
22
+ # input_box2 = gr.Textbox(
23
+ # label="OpenAI API Key", placeholder="sk_...")
24
+ # with gr.Row():
25
+ # add_btn2 = gr.Button(value="Add Key", variant="secondary")
26
+ # del_btn2 = gr.Button(value="Reset Key", variant="stop")
27
 
28
  # Assign actions
29
  add_btn.click(
 
36
  inputs=[input_box],
37
  outputs=[fw_list, input_box]
38
  )
39
+ radio_btn.change(
40
+ fn=on_fw_radio_change,
41
+ inputs=[radio_btn],
42
+ )
43
 
44
  ui.title = "Configuration"
45
  return ui
views/fd.py CHANGED
@@ -1,17 +1,15 @@
1
  import gradio as gr
2
- from utilities.constants import FD_DROPDOWN_CHOICES
3
  from controllers.fd import fd_controller
4
- from services.state import app_state
5
 
6
 
7
  def fd_interface():
8
  return gr.Interface(
9
  title="Face Detection",
10
- fn=lambda model, image, color: fd_controller(
11
- image, model, color, app_state.get('fw_option')),
12
  inputs=[
13
- gr.Dropdown(choices=FD_DROPDOWN_CHOICES,
14
- value=FD_DROPDOWN_CHOICES[0], label="Select Model. *Not affect in forwarding mode*"),
15
  gr.Image(type="pil", label="Input Image"),
16
  gr.ColorPicker(label="Box Color")
17
  ],
 
1
  import gradio as gr
2
+ from utilities.constants import FW_DEFAULT_OPTION
3
  from controllers.fd import fd_controller
4
+ from services.state import get_state
5
 
6
 
7
  def fd_interface():
8
  return gr.Interface(
9
  title="Face Detection",
10
+ fn=lambda image, color: fd_controller(
11
+ image, color, get_state('fw_option', FW_DEFAULT_OPTION)),
12
  inputs=[
 
 
13
  gr.Image(type="pil", label="Input Image"),
14
  gr.ColorPicker(label="Box Color")
15
  ],
views/rembg.py CHANGED
@@ -1,14 +1,14 @@
1
  import gradio as gr
2
  from controllers.rembg import rembg_controller
3
- from services.state import app_state
4
- from utilities.constants import REMBG_DROPDOWN_CHOICES
5
 
6
 
7
  def rembg_interface():
8
  return gr.Interface(
9
  title="Remove Background",
10
  fn=lambda resolution, image: rembg_controller(
11
- image, resolution, app_state.get('fw_option')),
12
  inputs=[
13
  gr.Dropdown(choices=REMBG_DROPDOWN_CHOICES,
14
  value=REMBG_DROPDOWN_CHOICES[0], label="Resolution"),
 
1
  import gradio as gr
2
  from controllers.rembg import rembg_controller
3
+ from services.state import get_state
4
+ from utilities.constants import REMBG_DROPDOWN_CHOICES, FW_DEFAULT_OPTION
5
 
6
 
7
  def rembg_interface():
8
  return gr.Interface(
9
  title="Remove Background",
10
  fn=lambda resolution, image: rembg_controller(
11
+ image, resolution, get_state('fw_option', FW_DEFAULT_OPTION)),
12
  inputs=[
13
  gr.Dropdown(choices=REMBG_DROPDOWN_CHOICES,
14
  value=REMBG_DROPDOWN_CHOICES[0], label="Resolution"),
views/vqa.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from services.state import get_state
3
+ from controllers.vqa import vqa_controller
4
+ from utilities.constants import FW_DEFAULT_OPTION
5
+
6
+
7
+ def vqa_interface():
8
+ return gr.Interface(
9
+ title="Visual Question Answering",
10
+ fn=lambda image, question: vqa_controller(
11
+ image, question, get_state('fw_option', FW_DEFAULT_OPTION)),
12
+ inputs=[
13
+ gr.Image(type="pil", label="Input Image"),
14
+ gr.Textbox(label="Question")
15
+ ],
16
+ outputs=[
17
+ gr.Textbox(label="Answer")
18
+ ],
19
+ flagging_options=[]
20
+ )