Skip to content

Commit aee89e8

Browse files
authored
Add Report Generation and Configuration Improvements for GuideLLM (#24)
## Summary Introduces a report file generation feature for GuideLLM and fixes the configuration functionality. Once the frontend is live, we will add the report generation functionality to the CLI and add integration and end to end tests ## Details - **Report Generation Feature**: - Added logic to generate and inject reports from Pydantic models. - Created utility functions for loading HTML templates, injecting data, and saving reports. - Implemented support for both local file paths and URLs as sources for HTML templates. - Included handling for different environments (local, dev, staging, prod) with environment-specific report URLs. - **Configuration Improvements**: - Refactored configuration structure into a more modular and maintainable format. - Updated configuration to use Pydantic's `BaseSettings` and `model_validator` for environment-based settings. - Improved logging configuration with customizable options for console and file logging levels. - Enhanced OpenAI settings for more robust API connectivity. - **Testing**: - Added comprehensive unit and integration tests for the new report generation feature. - Updated existing tests to align with the new configuration structure. - Ensured all tests pass successfully and that code coverage is maintained. ## Test Plan - **Automation Testing**: - Added and verified unit tests for the report generation and configuration functionalities pass without issues. - **Manual Testing**: - Manually tested the report generation process using various Pydantic models and HTML templates.
1 parent a09623b commit aee89e8

File tree

18 files changed

+435
-67
lines changed

18 files changed

+435
-67
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ repos:
2929

3030
# dev dependencies
3131
pytest,
32+
pydantic_settings,
3233

3334
# types
3435
types-click,

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ dev = [
4848
"pytest~=8.2.2",
4949
"pytest-cov~=5.0.0",
5050
"pytest-mock~=3.14.0",
51+
"requests-mock~=1.12.1",
5152

5253
# code quality
5354
"mypy~=1.10.1",

src/config/__init__.py

Lines changed: 0 additions & 54 deletions
This file was deleted.

src/guidellm/backend/openai.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from typing import Any, Dict, Generator, List, Optional
22

33
import openai
4-
from config import settings
54
from loguru import logger
65
from openai import OpenAI, Stream
76
from openai.types import Completion
87
from transformers import AutoTokenizer
98

109
from guidellm.backend import Backend, BackendEngine, GenerativeResponse
10+
from guidellm.config import settings
1111
from guidellm.core import TextGenerationRequest
1212

1313
__all__ = ["OpenAIBackend"]

src/guidellm/config/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .base import settings
2+
3+
__all__ = ["settings"]

src/guidellm/config/base.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from enum import Enum
2+
from typing import Optional
3+
4+
from pydantic import BaseModel, model_validator
5+
from pydantic_settings import BaseSettings, SettingsConfigDict
6+
7+
__all__ = [
8+
"settings",
9+
"Settings",
10+
"Environment",
11+
"LoggingSettings",
12+
"OpenAISettings",
13+
"ReportGenerationSettings",
14+
]
15+
16+
17+
class Environment(str, Enum):
18+
"""
19+
Enum for the supported environments
20+
"""
21+
22+
LOCAL = "local"
23+
DEV = "dev"
24+
STAGING = "staging"
25+
PROD = "prod"
26+
27+
28+
ENV_REPORT_MAPPING = {
29+
Environment.PROD: "https://guidellm.neuralmagic.com/local-report/index.html",
30+
Environment.STAGING: "https://staging.guidellm.neuralmagic.com/local-report/index.html",
31+
Environment.DEV: "https://dev.guidellm.neuralmagic.com/local-report/index.html",
32+
Environment.LOCAL: "tests/dummy/report.html",
33+
}
34+
35+
36+
class LoggingSettings(BaseModel):
37+
"""
38+
Logging settings for the application
39+
"""
40+
41+
disabled: bool = False
42+
clear_loggers: bool = True
43+
console_log_level: str = "INFO"
44+
log_file: Optional[str] = None
45+
log_file_level: Optional[str] = None
46+
47+
48+
class OpenAISettings(BaseModel):
49+
"""
50+
OpenAI settings for the application to connect to the API
51+
for OpenAI server based pathways
52+
"""
53+
54+
# OpenAI API key.
55+
api_key: str = "invalid"
56+
57+
# OpenAI-compatible server URL
58+
# NOTE: The default value is default address of llama.cpp web server
59+
base_url: str = "http://localhost:8080"
60+
61+
max_gen_tokens: int = 4096
62+
63+
64+
class ReportGenerationSettings(BaseModel):
65+
source: str = ""
66+
67+
68+
class Settings(BaseSettings):
69+
"""
70+
All the settings are powered by pydantic_settings and could be
71+
populated from the .env file.
72+
73+
The format to populate the settings is next
74+
75+
```sh
76+
export GUIDELLM__LOGGING__DISABLED=true
77+
export GUIDELLM__OPENAI__API_KEY=******
78+
```
79+
80+
"""
81+
82+
model_config = SettingsConfigDict(
83+
env_prefix="GUIDELLM__",
84+
env_nested_delimiter="__",
85+
extra="ignore",
86+
validate_default=True,
87+
env_file=".env",
88+
)
89+
90+
env: Environment = Environment.PROD
91+
request_timeout: int = 30
92+
93+
logging: LoggingSettings = LoggingSettings()
94+
openai: OpenAISettings = OpenAISettings()
95+
report_generation: ReportGenerationSettings = ReportGenerationSettings()
96+
97+
@model_validator(mode="after")
98+
@classmethod
99+
def set_default_source(cls, values):
100+
if not values.report_generation.source:
101+
values.report_generation.source = ENV_REPORT_MAPPING.get(values.env)
102+
103+
return values
104+
105+
106+
settings = Settings()

src/guidellm/logger.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@
3636

3737
import sys
3838

39-
from config import LoggingSettings, settings
4039
from loguru import logger
4140

41+
from guidellm.config import settings
42+
from guidellm.config.base import LoggingSettings
43+
4244
__all__ = ["configure_logger", "logger"]
4345

4446

src/guidellm/request/emulated.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from loguru import logger
1111
from transformers import PreTrainedTokenizer
1212

13+
from guidellm.config import settings
1314
from guidellm.core.request import TextGenerationRequest
1415
from guidellm.request.base import RequestGenerator
1516

@@ -117,7 +118,7 @@ def _load_config(self, config: Union[str, Dict]) -> EmulatedConfig:
117118
def _load_emulated_data(self) -> List[str]:
118119
url = "https://www.gutenberg.org/files/1342/1342-0.txt"
119120
logger.info(f"Downloading text corpus from {url}")
120-
response = requests.get(url, timeout=30)
121+
response = requests.get(url, timeout=settings.request_timeout)
121122
response.raise_for_status()
122123

123124
content = response.text

src/guidellm/utils/__init__.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
from .constants import (
22
PREFERRED_DATA_COLUMNS,
33
PREFERRED_DATA_SPLITS,
4-
STANDARD_SLEEP_INTERVAL,
4+
REPORT_HTML_MATCH,
5+
REPORT_HTML_PLACEHOLDER,
56
)
7+
from .injector import create_report, inject_data, load_html_file
68

79
__all__ = [
810
"PREFERRED_DATA_COLUMNS",
911
"PREFERRED_DATA_SPLITS",
10-
"STANDARD_SLEEP_INTERVAL",
12+
"REPORT_HTML_MATCH",
13+
"REPORT_HTML_PLACEHOLDER",
14+
"create_report",
15+
"inject_data",
16+
"load_html_file",
1117
]

src/guidellm/utils/constants.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
__all__ = ["PREFERRED_DATA_COLUMNS", "PREFERRED_DATA_SPLITS", "STANDARD_SLEEP_INTERVAL"]
1+
__all__ = [
2+
"PREFERRED_DATA_COLUMNS",
3+
"PREFERRED_DATA_SPLITS",
4+
"REPORT_HTML_MATCH",
5+
"REPORT_HTML_PLACEHOLDER",
6+
]
27

38

49
PREFERRED_DATA_COLUMNS = [
@@ -16,4 +21,6 @@
1621

1722
PREFERRED_DATA_SPLITS = ["test", "validation", "train"]
1823

19-
STANDARD_SLEEP_INTERVAL = 0.1
24+
REPORT_HTML_MATCH = "window.report_data = {};"
25+
26+
REPORT_HTML_PLACEHOLDER = "{}"

0 commit comments

Comments
 (0)