code: 
  # LLama Index starter example from: https://gpt-index.readthedocs.io/en/latest/getting_started/starter_example.html
  # In order to run this, download into data/ Paul Graham's Essay 'What I Worked On' from
  # https://github.com/jerryjliu/llama_index/blob/main/examples/paul_graham_essay/data/paul_graham_essay.txt
  # curl https://raw.githubusercontent.com/jerryjliu/llama_index/main/examples/paul_graham_essay/data/paul_graham_essay.txt > data/paul_graham_essay.txt
  
  import json
  from dotenv import load_dotenv
  import os
  import pprint
  
  from llama_index import VectorStoreIndex, SimpleDirectoryReader
  from llama_index import StorageContext, load_index_from_storage
  from llama_index.node_parser import SimpleNodeParser
  from llama_index.schema import TextNode, NodeRelationship, RelatedNodeInfo
  
  load_dotenv()
  
  pp = pprint.PrettyPrinter(indent=4).pprint
  
  def make_index():
      print('Loading documents...')
      documents = SimpleDirectoryReader('data').load_data()
      index = VectorStoreIndex.from_documents(documents)
      index.storage_context.persist()
  
  def load_index():
      # rebuild storage context
      storage_context = StorageContext.from_defaults(persist_dir="./storage")
      # load index
      index = load_index_from_storage(storage_context)
      return  index
  
  def read_doc():
      with open('data/worked_on.txt') as f:
          doc = f.read()
      return doc
  
  
  def get_lines():
      doc = read_doc()
      lines = []
      for line in doc.split('\n'):
          line = line.strip().strip().strip().strip()
          if len(line) == 0:
              continue
          lines.append(line)
      print('lines', json.dumps(lines, indent=2))
      return lines
  
  # make an index from lines -> nodes -> index
  def index_from_lines(lines):
      count = 0
      nodes = []
      for idx, line in enumerate(lines):
          node = TextNode(text=line, id_=idx)
          print('----\n', line)
          nodes.append(node)
      for idx, node in enumerate(nodes):
          if idx < len(nodes) - 1:
              next = nodes[idx+1]
              node.relationships[NodeRelationship.NEXT] = RelatedNodeInfo(node_id=next.node_id)
          if idx > 0:
              prev = nodes[idx-1]
              node.relationships[NodeRelationship.PREVIOUS] = RelatedNodeInfo(node_id=prev.node_id)
      index = VectorStoreIndex(nodes)
      return index
  
  
  def get_nodes():
      parser = SimpleNodeParser()
      documents = SimpleDirectoryReader('data').load_data()
      nodes = parser.get_nodes_from_documents(documents)
      count = 0
      for node in nodes:
          print('\n--- node', count)
          print(vars(node))
          pp(node)
          # print(json.dumps(vars(node), indent=2))
  
  
  
  
apis: llama_index.VectorStoreIndex.from_documents llama_index.node_parser.SimpleNodeParser llama_index.schema.TextNode llama_index.StorageContext.from_defaults llama_index.schema.RelatedNodeInfo llama_index.VectorStoreIndex llama_index.SimpleDirectoryReader llama_index.load_index_from_storage
extract_api: [((789, 802), 'dotenv.load_dotenv', 'load_dotenv', ([], {}), '()\n', (800, 802), False, 'from dotenv import load_dotenv\n'), ((809, 839), 'pprint.PrettyPrinter', 'pprint.PrettyPrinter', ([], {'indent': '(4)'}), '(indent=4)\n', (829, 839), False, 'import pprint\n'), ((970, 1012), 'llama_index.VectorStoreIndex.from_documents', 'VectorStoreIndex.from_documents', (['documents'], {}), '(documents)\n', (1001, 1012), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader\n'), ((1120, 1173), 'llama_index.StorageContext.from_defaults', 'StorageContext.from_defaults', ([], {'persist_dir': '"""./storage"""'}), "(persist_dir='./storage')\n", (1148, 1173), False, 'from llama_index import StorageContext, load_index_from_storage\n'), ((1203, 1243), 'llama_index.load_index_from_storage', 'load_index_from_storage', (['storage_context'], {}), '(storage_context)\n', (1226, 1243), False, 'from llama_index import StorageContext, load_index_from_storage\n'), ((2243, 2266), 'llama_index.VectorStoreIndex', 'VectorStoreIndex', (['nodes'], {}), '(nodes)\n', (2259, 2266), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader\n'), ((2316, 2334), 'llama_index.node_parser.SimpleNodeParser', 'SimpleNodeParser', ([], {}), '()\n', (2332, 2334), False, 'from llama_index.node_parser import SimpleNodeParser\n'), ((1593, 1620), 'json.dumps', 'json.dumps', (['lines'], {'indent': '(2)'}), '(lines, indent=2)\n', (1603, 1620), False, 'import json\n'), ((1797, 1825), 'llama_index.schema.TextNode', 'TextNode', ([], {'text': 'line', 'id_': 'idx'}), '(text=line, id_=idx)\n', (1805, 1825), False, 'from llama_index.schema import TextNode, NodeRelationship, RelatedNodeInfo\n'), ((916, 945), 'llama_index.SimpleDirectoryReader', 'SimpleDirectoryReader', (['"""data"""'], {}), "('data')\n", (937, 945), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader\n'), ((2043, 2080), 'llama_index.schema.RelatedNodeInfo', 'RelatedNodeInfo', ([], {'node_id': 'next.node_id'}), '(node_id=next.node_id)\n', (2058, 2080), False, 'from llama_index.schema import TextNode, NodeRelationship, RelatedNodeInfo\n'), ((2193, 2230), 'llama_index.schema.RelatedNodeInfo', 'RelatedNodeInfo', ([], {'node_id': 'prev.node_id'}), '(node_id=prev.node_id)\n', (2208, 2230), False, 'from llama_index.schema import TextNode, NodeRelationship, RelatedNodeInfo\n'), ((2351, 2380), 'llama_index.SimpleDirectoryReader', 'SimpleDirectoryReader', (['"""data"""'], {}), "('data')\n", (2372, 2380), False, 'from llama_index import VectorStoreIndex, SimpleDirectoryReader\n')]