code: from __future__ import annotations
  import os
  
  try:
      from llama_index import (
          VectorStoreIndex,
          SimpleDirectoryReader,
          StorageContext,
          load_index_from_storage
      )
  except:
      pass
  
  from dataclasses import dataclass
  
  def get_or_create_index_local(persist_dir = './storage', documents_dir :str= "data"):
      if not os.path.exists(persist_dir):
          documents = SimpleDirectoryReader(documents_dir).load_data()
          index = VectorStoreIndex.from_documents(documents)
          index.storage_context.persist(persist_dir = persist_dir)
      else:
          storage_context = StorageContext.from_defaults(persist_dir=persist_dir)
          index = load_index_from_storage(storage_context)
          
      return index
  
  @dataclass
  class LocalDirRag:
      
      documents_dir:str = "data"
      persist_dir:str = './storage'
      
      def __post_init__(self):
          try:
              import openai
              openai.api_key = os.environ["OPENAI_API_KEY"]
          except:
              raise ValueError("OpenAI API not installed. Please install it using pip install openai")
          
          try:
              import llama_index
          except:
              raise ValueError("llama_index not installed. Please install it using pip install llama_index")
          
          if openai.api_key is None:
              raise ValueError("OpenAI API key not found. Please set it as an environment variable OPENAI_API_KEY")
          
          if len(openai.api_key) < 5:
              raise ValueError("OpenAI API key not in correct format. Please set it as an environment variable OPENAI_API_KEY")
          
          self.index = get_or_create_index_local(persist_dir = self.persist_dir, 
                                            documents_dir = self.documents_dir)
      
      def ask(self, query:str):
          engine = self.index.as_query_engine()
          return engine.query(query)
      
      @property 
      def chatbot(self):
          engine = self.index.as_chat_engine()
          return RagChatBot(engine)
      
      def __call__(self, query:str):
          return self.ask(query).response
      
  
  class RagChatBot:
      def __init__(self, engine):
          self.engine = engine
          
      def __call__(self,query):
          return self.engine.chat(query)
      
apis: llama_index.VectorStoreIndex.from_documents llama_index.StorageContext.from_defaults llama_index.load_index_from_storage llama_index.SimpleDirectoryReader
extract_api: [((350, 377), 'os.path.exists', 'os.path.exists', (['persist_dir'], {}), '(persist_dir)\n', (364, 377), False, 'import os\n'), ((464, 506), 'llama_index.VectorStoreIndex.from_documents', 'VectorStoreIndex.from_documents', (['documents'], {}), '(documents)\n', (495, 506), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage\n'), ((608, 661), 'llama_index.StorageContext.from_defaults', 'StorageContext.from_defaults', ([], {'persist_dir': 'persist_dir'}), '(persist_dir=persist_dir)\n', (636, 661), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage\n'), ((678, 718), 'llama_index.load_index_from_storage', 'load_index_from_storage', (['storage_context'], {}), '(storage_context)\n', (701, 718), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage\n'), ((399, 435), 'llama_index.SimpleDirectoryReader', 'SimpleDirectoryReader', (['documents_dir'], {}), '(documents_dir)\n', (420, 435), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage\n')]