code: import argparse
  import duckdb
  import lancedb
  import pyarrow.compute as pc
  from transformers import CLIPModel, CLIPProcessor, CLIPTokenizerFast
  import gradio as gr
  
  MODEL_ID = None
  MODEL = None
  TOKENIZER = None
  PROCESSOR = None
  
  
  def get_table():
      db = lancedb.connect("data/video-lancedb")
      return db.open_table("multimodal_video")
  
  
  def setup_clip_model(model_id):
      global MODEL_ID, MODEL, TOKENIZER, PROCESSOR
      MODEL_ID = model_id
      TOKENIZER = CLIPTokenizerFast.from_pretrained(MODEL_ID)
      MODEL = CLIPModel.from_pretrained(MODEL_ID)
      PROCESSOR = CLIPProcessor.from_pretrained(MODEL_ID)
  
  
  def embed_func(query):
      inputs = TOKENIZER([query], padding=True, return_tensors="pt")
      text_features = MODEL.get_text_features(**inputs)
      return text_features.detach().numpy()[0]
  
  
  def find_video_vectors(query):
      emb = embed_func(query)
      code = (
          "import lancedb\n"
          "db = lancedb.connect('data/video-lancedb')\n"
          "tbl = db.open_table('multimodal_video')\n\n"
          f"embedding = embed_func('{query}')\n"
          "tbl.search(embedding).limit(9).to_df()"
      )
      return (_extract(tbl.search(emb).limit(9).to_df()), code)
  
  
  def find_video_keywords(query):
      code = (
          "import lancedb\n"
          "db = lancedb.connect('data/video-lancedb')\n"
          "tbl = db.open_table('multimodal_video')\n\n"
          f"tbl.search('{query}').limit(9).to_df()"
      )
      return (_extract(tbl.search(query).limit(9).to_df()), code)
  
  
  def find_video_sql(query):
      code = (
          "import lancedb\n"
          "import duckdb\n"
          "db = lancedb.connect('data/video-lancedb')\n"
          "tbl = db.open_table('multimodal_video')\n\n"
          "videos = tbl.to_lance()\n"
          f"duckdb.sql('{query}').to_df()"
      )
      videos = tbl.to_lance()
      return (_extract(duckdb.sql(query).to_df()), code)
  
  
  def _extract(df):  # Define a 3x3 Python list to store the HTML code
      video_id_col = "video_id"
      start_time_col = "start_time"
      grid_html = '<div style="display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px;">'
  
      for _, row in df.iterrows():
          iframe_code = f'<iframe width="100%" height="315" src="https://www.youtube.com/embed/{row[video_id_col]}?start={str(row[start_time_col])}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>'
          grid_html += f'<div style="width: 100%;">{iframe_code}</div>'
  
      grid_html += "</div>"
      return grid_html
  
  
  def create_gradio_dash():
      with gr.Blocks() as demo:
          gr.Markdown(
              """
                      # Multimodal Video Search with LanceDB
                      We used LanceDB to store frames every thirty seconds and the title of 13000+ videos, 5 random from each top category from the Youtube 8M dataset. 
                      Then, we used the CLIP model to embed frames and titles together. With LanceDB, we can perform embedding, keyword, and SQL search on these videos.
                      """
          )
          with gr.Row():
              with gr.Tab("Embeddings"):
                  vector_query = gr.Textbox(value="retro gaming", show_label=False)
                  b1 = gr.Button("Submit")
              with gr.Tab("Keywords"):
                  keyword_query = gr.Textbox(value="ninja turtles", show_label=False)
                  b2 = gr.Button("Submit")
              with gr.Tab("SQL"):
                  sql_query = gr.Textbox(
                      value="SELECT DISTINCT video_id, * from videos WHERE start_time > 0 LIMIT 9",
                      show_label=False,
                  )
                  b3 = gr.Button("Submit")
          with gr.Row():
              code = gr.Code(label="Code", language="python")
          with gr.Row():
              gallery = gr.HTML()
  
          b1.click(find_video_vectors, inputs=vector_query, outputs=[gallery, code])
          b2.click(find_video_keywords, inputs=keyword_query, outputs=[gallery, code])
          b3.click(find_video_sql, inputs=sql_query, outputs=[gallery, code])
  
      demo.launch()
  
  
  def args_parse():
      parser = argparse.ArgumentParser()
      parser.add_argument("--model_id", type=str, default="openai/clip-vit-base-patch32")
      return parser.parse_args()
  
  
  if __name__ == "__main__":
      args = args_parse()
      setup_clip_model(args.model_id)
      tbl = get_table()
      create_gradio_dash()
  
apis: lancedb.connect
extract_api: [((255, 292), 'lancedb.connect', 'lancedb.connect', (['"""data/video-lancedb"""'], {}), "('data/video-lancedb')\n", (270, 292), False, 'import lancedb\n'), ((461, 504), 'transformers.CLIPTokenizerFast.from_pretrained', 'CLIPTokenizerFast.from_pretrained', (['MODEL_ID'], {}), '(MODEL_ID)\n', (494, 504), False, 'from transformers import CLIPModel, CLIPProcessor, CLIPTokenizerFast\n'), ((517, 552), 'transformers.CLIPModel.from_pretrained', 'CLIPModel.from_pretrained', (['MODEL_ID'], {}), '(MODEL_ID)\n', (542, 552), False, 'from transformers import CLIPModel, CLIPProcessor, CLIPTokenizerFast\n'), ((569, 608), 'transformers.CLIPProcessor.from_pretrained', 'CLIPProcessor.from_pretrained', (['MODEL_ID'], {}), '(MODEL_ID)\n', (598, 608), False, 'from transformers import CLIPModel, CLIPProcessor, CLIPTokenizerFast\n'), ((4123, 4148), 'argparse.ArgumentParser', 'argparse.ArgumentParser', ([], {}), '()\n', (4146, 4148), False, 'import argparse\n'), ((2589, 2600), 'gradio.Blocks', 'gr.Blocks', ([], {}), '()\n', (2598, 2600), True, 'import gradio as gr\n'), ((2618, 3061), 'gradio.Markdown', 'gr.Markdown', (['"""\n                    # Multimodal Video Search with LanceDB\n                    We used LanceDB to store frames every thirty seconds and the title of 13000+ videos, 5 random from each top category from the Youtube 8M dataset. \n                    Then, we used the CLIP model to embed frames and titles together. With LanceDB, we can perform embedding, keyword, and SQL search on these videos.\n                    """'], {}), '(\n    """\n                    # Multimodal Video Search with LanceDB\n                    We used LanceDB to store frames every thirty seconds and the title of 13000+ videos, 5 random from each top category from the Youtube 8M dataset. \n                    Then, we used the CLIP model to embed frames and titles together. With LanceDB, we can perform embedding, keyword, and SQL search on these videos.\n                    """\n    )\n', (2629, 3061), True, 'import gradio as gr\n'), ((3087, 3095), 'gradio.Row', 'gr.Row', ([], {}), '()\n', (3093, 3095), True, 'import gradio as gr\n'), ((3701, 3709), 'gradio.Row', 'gr.Row', ([], {}), '()\n', (3707, 3709), True, 'import gradio as gr\n'), ((3730, 3770), 'gradio.Code', 'gr.Code', ([], {'label': '"""Code"""', 'language': '"""python"""'}), "(label='Code', language='python')\n", (3737, 3770), True, 'import gradio as gr\n'), ((3784, 3792), 'gradio.Row', 'gr.Row', ([], {}), '()\n', (3790, 3792), True, 'import gradio as gr\n'), ((3816, 3825), 'gradio.HTML', 'gr.HTML', ([], {}), '()\n', (3823, 3825), True, 'import gradio as gr\n'), ((3114, 3134), 'gradio.Tab', 'gr.Tab', (['"""Embeddings"""'], {}), "('Embeddings')\n", (3120, 3134), True, 'import gradio as gr\n'), ((3167, 3217), 'gradio.Textbox', 'gr.Textbox', ([], {'value': '"""retro gaming"""', 'show_label': '(False)'}), "(value='retro gaming', show_label=False)\n", (3177, 3217), True, 'import gradio as gr\n'), ((3239, 3258), 'gradio.Button', 'gr.Button', (['"""Submit"""'], {}), "('Submit')\n", (3248, 3258), True, 'import gradio as gr\n'), ((3276, 3294), 'gradio.Tab', 'gr.Tab', (['"""Keywords"""'], {}), "('Keywords')\n", (3282, 3294), True, 'import gradio as gr\n'), ((3328, 3379), 'gradio.Textbox', 'gr.Textbox', ([], {'value': '"""ninja turtles"""', 'show_label': '(False)'}), "(value='ninja turtles', show_label=False)\n", (3338, 3379), True, 'import gradio as gr\n'), ((3401, 3420), 'gradio.Button', 'gr.Button', (['"""Submit"""'], {}), "('Submit')\n", (3410, 3420), True, 'import gradio as gr\n'), ((3438, 3451), 'gradio.Tab', 'gr.Tab', (['"""SQL"""'], {}), "('SQL')\n", (3444, 3451), True, 'import gradio as gr\n'), ((3481, 3596), 'gradio.Textbox', 'gr.Textbox', ([], {'value': '"""SELECT DISTINCT video_id, * from videos WHERE start_time > 0 LIMIT 9"""', 'show_label': '(False)'}), "(value=\n    'SELECT DISTINCT video_id, * from videos WHERE start_time > 0 LIMIT 9',\n    show_label=False)\n", (3491, 3596), True, 'import gradio as gr\n'), ((3668, 3687), 'gradio.Button', 'gr.Button', (['"""Submit"""'], {}), "('Submit')\n", (3677, 3687), True, 'import gradio as gr\n'), ((1813, 1830), 'duckdb.sql', 'duckdb.sql', (['query'], {}), '(query)\n', (1823, 1830), False, 'import duckdb\n')]