code: #!/usr/bin/env python3
  ##
  # Chat with PDF document using OpenAI, LlamaIndex, and Gradio
  # github.com/deadbits
  ##
  import os
  import sys
  import logging
  import argparse
  import openai
  import gradio as gr
  import urllib.request
  
  from pathlib import Path
  
  from langchain import OpenAI
  
  from llama_index import GPTSimpleVectorIndex
  from llama_index import LLMPredictor
  from llama_index import ServiceContext
  from llama_index import download_loader
  
  
  # disable some of the more verbose llama_index logging
  logging.basicConfig(level=logging.CRITICAL)
  
  # change this to your preferred model
  MODEL_NAME = 'gpt-3.5-turbo'
  
  
  def download_pdf(url, output_path):
      urllib.request.urlretrieve(url, output_path)
  
  
  def load_document(fpath):
      print('[status] loading document ({})'.format(fpath))
      PDFReader = download_loader('PDFReader')
      loader = PDFReader()
      docs = loader.load_data(file=Path(fpath))
      return docs
  
  
  def answer_question(url='', fpath='', question='', api_key=''):
      if url.strip() == '' and fpath is None:
          return '[error] file and url cannot both be empty'
  
      if url.strip() != '' and fpath is not None:
          return '[error] file and url cannot both be provided'
  
      if question.strip() == '':
          return '[error] question cannot be empty'
  
      if api_key.strip() == '':
          return '[error] OpenAI API key cannot be empty'
  
      if url.strip() != '':
          download_pdf(url, 'corpus.pdf')
          fpath = 'corpus.pdf'
      elif fpath != '':
          fname = fpath.name
          os.rename(fname, 'corpus.pdf')
  
      docs = load_document('corpus.pdf')
  
      llm = LLMPredictor(llm=OpenAI(openai_api_key=api_key, temperature=0, model_name=MODEL_NAME))
      ctx = ServiceContext.from_defaults(llm_predictor=llm, chunk_size_limit=1024)
      index = GPTSimpleVectorIndex.from_documents(docs, service_context=ctx)
  
      response = index.query(question)
      response = str(response)
      if response.startswith('\n'):
          response = response[1:]
  
      return response
  
  
  title = 'PDF Chat with OpenAI'
  description = """Upload local PDF document or enter URL to PDF"""
  
  with gr.Blocks() as demo:
  
      gr.Markdown(f'<center><h1>{title}</h1></center>')
      gr.Markdown(description)
  
      with gr.Row():
  
          with gr.Group():
              openai_api_key = gr.Textbox(label='OpenAI API key')
  
              url = gr.Textbox(label='PDF URL to download')
              gr.Markdown("<center><h4>OR<h4></center>")
              fpath = gr.File(label='Upload PDF', file_types=['.pdf'])
  
              question = gr.Textbox(label='User prompt')
              btn = gr.Button(value='Submit')
              btn.style(full_width=True)
  
          with gr.Group():
              answer = gr.Textbox(label='Response:', lines=15, placeholder='Output')
  
          btn.click(answer_question, inputs=[url, fpath, question, openai_api_key], outputs=[answer])
  
  demo.launch(share=True)
  
apis: llama_index.GPTSimpleVectorIndex.from_documents llama_index.ServiceContext.from_defaults llama_index.download_loader
extract_api: [((496, 539), 'logging.basicConfig', 'logging.basicConfig', ([], {'level': 'logging.CRITICAL'}), '(level=logging.CRITICAL)\n', (515, 539), False, 'import logging\n'), ((797, 825), 'llama_index.download_loader', 'download_loader', (['"""PDFReader"""'], {}), "('PDFReader')\n", (812, 825), False, 'from llama_index import download_loader\n'), ((1694, 1764), 'llama_index.ServiceContext.from_defaults', 'ServiceContext.from_defaults', ([], {'llm_predictor': 'llm', 'chunk_size_limit': '(1024)'}), '(llm_predictor=llm, chunk_size_limit=1024)\n', (1722, 1764), False, 'from llama_index import ServiceContext\n'), ((1777, 1839), 'llama_index.GPTSimpleVectorIndex.from_documents', 'GPTSimpleVectorIndex.from_documents', (['docs'], {'service_context': 'ctx'}), '(docs, service_context=ctx)\n', (1812, 1839), False, 'from llama_index import GPTSimpleVectorIndex\n'), ((2099, 2110), 'gradio.Blocks', 'gr.Blocks', ([], {}), '()\n', (2108, 2110), True, 'import gradio as gr\n'), ((2125, 2174), 'gradio.Markdown', 'gr.Markdown', (['f"""<center><h1>{title}</h1></center>"""'], {}), "(f'<center><h1>{title}</h1></center>')\n", (2136, 2174), True, 'import gradio as gr\n'), ((2179, 2203), 'gradio.Markdown', 'gr.Markdown', (['description'], {}), '(description)\n', (2190, 2203), True, 'import gradio as gr\n'), ((2214, 2222), 'gradio.Row', 'gr.Row', ([], {}), '()\n', (2220, 2222), True, 'import gradio as gr\n'), ((884, 895), 'pathlib.Path', 'Path', (['fpath'], {}), '(fpath)\n', (888, 895), False, 'from pathlib import Path\n'), ((1515, 1545), 'os.rename', 'os.rename', (['fname', '"""corpus.pdf"""'], {}), "(fname, 'corpus.pdf')\n", (1524, 1545), False, 'import os\n'), ((1614, 1682), 'langchain.OpenAI', 'OpenAI', ([], {'openai_api_key': 'api_key', 'temperature': '(0)', 'model_name': 'MODEL_NAME'}), '(openai_api_key=api_key, temperature=0, model_name=MODEL_NAME)\n', (1620, 1682), False, 'from langchain import OpenAI\n'), ((2238, 2248), 'gradio.Group', 'gr.Group', ([], {}), '()\n', (2246, 2248), True, 'import gradio as gr\n'), ((2279, 2313), 'gradio.Textbox', 'gr.Textbox', ([], {'label': '"""OpenAI API key"""'}), "(label='OpenAI API key')\n", (2289, 2313), True, 'import gradio as gr\n'), ((2333, 2372), 'gradio.Textbox', 'gr.Textbox', ([], {'label': '"""PDF URL to download"""'}), "(label='PDF URL to download')\n", (2343, 2372), True, 'import gradio as gr\n'), ((2385, 2427), 'gradio.Markdown', 'gr.Markdown', (['"""<center><h4>OR<h4></center>"""'], {}), "('<center><h4>OR<h4></center>')\n", (2396, 2427), True, 'import gradio as gr\n'), ((2448, 2496), 'gradio.File', 'gr.File', ([], {'label': '"""Upload PDF"""', 'file_types': "['.pdf']"}), "(label='Upload PDF', file_types=['.pdf'])\n", (2455, 2496), True, 'import gradio as gr\n'), ((2521, 2552), 'gradio.Textbox', 'gr.Textbox', ([], {'label': '"""User prompt"""'}), "(label='User prompt')\n", (2531, 2552), True, 'import gradio as gr\n'), ((2571, 2596), 'gradio.Button', 'gr.Button', ([], {'value': '"""Submit"""'}), "(value='Submit')\n", (2580, 2596), True, 'import gradio as gr\n'), ((2650, 2660), 'gradio.Group', 'gr.Group', ([], {}), '()\n', (2658, 2660), True, 'import gradio as gr\n'), ((2683, 2744), 'gradio.Textbox', 'gr.Textbox', ([], {'label': '"""Response:"""', 'lines': '(15)', 'placeholder': '"""Output"""'}), "(label='Response:', lines=15, placeholder='Output')\n", (2693, 2744), True, 'import gradio as gr\n')]