Files
2026-07-13 13:22:34 +08:00

120 lines
3.2 KiB
Python

import os
import re
import shutil
import sys
import pytest
from llama_index.core import (
Document,
KnowledgeGraphIndex,
PromptTemplate,
Settings,
VectorStoreIndex,
)
from llama_index.core.callbacks import CallbackManager, LlamaDebugHandler
from llama_index.core.node_parser import SentenceSplitter
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI
from mlflow.tracing.provider import trace_disabled
from tests.helper_functions import start_mock_openai_server
#### General ####
@pytest.fixture
def model_path(tmp_path):
model_path = tmp_path.joinpath("model")
yield model_path
if os.environ.get("GITHUB_ACTIONS") == "true":
shutil.rmtree(model_path, ignore_errors=True)
@pytest.fixture(scope="module")
def spark():
from pyspark.sql import SparkSession
# NB: ensure that the driver and workers have the same python version
os.environ["PYSPARK_PYTHON"] = sys.executable
os.environ["PYSPARK_DRIVER_PYTHON"] = sys.executable
with SparkSession.builder.master("local[*]").getOrCreate() as s:
yield s
@pytest.fixture(scope="module", autouse=True)
def mock_openai():
with start_mock_openai_server() as base_url:
yield base_url
#### Settings ####
def _mock_tokenizer(text: str) -> list[str]:
"""Mock tokenizer."""
tokens = re.split(r"[ \n]", text)
result = []
for token in tokens:
if token.strip() == "":
continue
result.append(token.strip())
return result
@pytest.fixture(autouse=True)
def settings(monkeypatch, mock_openai):
"""Set the LLM and Embedding model to the mock OpenAI server."""
monkeypatch.setenv("OPENAI_API_KEY", "test")
# openai 1.x uses OPENAI_API_BASE; openai 2.x uses OPENAI_BASE_URL
monkeypatch.setenv("OPENAI_API_BASE", mock_openai)
monkeypatch.setenv("OPENAI_BASE_URL", mock_openai)
monkeypatch.setattr(Settings, "llm", OpenAI())
monkeypatch.setattr(Settings, "embed_model", OpenAIEmbedding())
monkeypatch.setattr(Settings, "callback_manager", CallbackManager([LlamaDebugHandler()]))
monkeypatch.setattr(Settings, "_tokenizer", _mock_tokenizer) # must bypass setter
monkeypatch.setattr(Settings, "context_window", 4096) # this enters the _prompt_helper field
monkeypatch.setattr(Settings, "node_parser", SentenceSplitter(chunk_size=1024))
monkeypatch.setattr(Settings, "transformations", [SentenceSplitter(chunk_size=1024)])
return Settings
#### Indexes ####
@pytest.fixture
def document():
return Document.example()
@pytest.fixture
@trace_disabled
def single_index(document):
return VectorStoreIndex(nodes=[document])
@pytest.fixture
@trace_disabled
def multi_index(document):
return VectorStoreIndex(nodes=[document] * 5)
@pytest.fixture
def single_graph(document):
return KnowledgeGraphIndex.from_documents([document])
#### Prompt Templates ####
@pytest.fixture
def qa_prompt_template():
return PromptTemplate(
template="""
Context information is below.
---------------------
{context_str}
---------------------
Given the context information and not prior knowledge, answer the query.
Please write the answer in the style of {tone_name}
Query: {query_str}
Answer:
"""
)