Skip to content

Commit 5ad9b0a

Browse files
authored
Merge pull request #387 from howardbaik/main
Add AzureOpenAI as a model provider to `DraftValidation`
2 parents 84aef77 + 8883fbb commit 5ad9b0a

3 files changed

Lines changed: 79 additions & 5 deletions

File tree

pointblank/draft.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ class DraftValidation:
2222
starting point for validating a table. This can be useful when you have a new table and you
2323
want to get a sense of how to validate it (and adjustments could always be made later). The
2424
`DraftValidation` class uses the `chatlas` package to draft a validation plan for a given table
25-
using an LLM from either the `"anthropic"`, `"openai"`, `"ollama"` or `"bedrock"` provider. You
26-
can install all requirements for the class through an optional 'generate' install of Pointblank
27-
via `pip install pointblank[generate]`.
25+
using an LLM from the `"anthropic"`, `"openai"`, `"ollama"`, `"bedrock"`, or `"azure-openai"`
26+
provider. You can install all requirements for the class through an optional 'generate' install
27+
of Pointblank via `pip install pointblank[generate]`.
2828
2929
:::{.callout-warning}
3030
The `DraftValidation` class is still experimental. Please report any issues you encounter in
@@ -38,7 +38,8 @@ class DraftValidation:
3838
model
3939
The model to be used. This should be in the form of `provider:model` (e.g.,
4040
`"anthropic:claude-opus-4-6"`). Supported providers are `"anthropic"`, `"openai"`,
41-
`"ollama"`, and `"bedrock"`.
41+
`"ollama"`, `"bedrock"`, and `"azure-openai"`. For `"azure-openai"`, the value after the
42+
colon is the Azure *deployment id*, not an OpenAI model id.
4243
api_key
4344
The API key to be used for the model.
4445
verify_ssl
@@ -61,9 +62,15 @@ class DraftValidation:
6162
- `"openai"` (OpenAI)
6263
- `"ollama"` (Ollama)
6364
- `"bedrock"` (Amazon Bedrock)
65+
- `"azure-openai"` (Azure OpenAI)
6466
6567
The model name should be the specific model to be used from the provider. Model names are
6668
subject to change so consult the provider's documentation for the most up-to-date model names.
69+
For `"azure-openai"`, the value after the colon is the Azure *deployment id* (the name you
70+
assigned when deploying the model in your Azure OpenAI resource). It also requires the
71+
environment variables `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_ENDPOINT` (e.g.,
72+
`https://<resource>.openai.azure.com`), and `OPENAI_API_VERSION` (e.g., `"2024-06-01"`) to
73+
be set.
6774
6875
Notes on Authentication
6976
-----------------------
@@ -251,7 +258,9 @@ def __post_init__(self) -> None:
251258
)
252259

253260
# Read the API/examples text from a file
254-
with files("pointblank.data").joinpath("api-docs.txt").open() as f: # pragma: no cover
261+
with (
262+
files("pointblank.data").joinpath("api-docs.txt").open(encoding="utf-8") as f
263+
): # pragma: no cover
255264
api_and_examples_text = f.read()
256265

257266
# Get the model name from the `model` value
@@ -389,6 +398,41 @@ def __post_init__(self) -> None:
389398
kwargs={"http_client": http_client},
390399
)
391400

401+
if provider == "azure-openai": # pragma: no cover
402+
try:
403+
import openai # noqa
404+
except ImportError: # pragma: no cover
405+
raise ImportError( # pragma: no cover
406+
"The `openai` package is required to use the `DraftValidation` class with "
407+
"the `azure-openai` provider. Please install it using `pip install openai`."
408+
)
409+
410+
import os
411+
412+
endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
413+
api_version = os.getenv("OPENAI_API_VERSION")
414+
if not endpoint:
415+
raise ValueError(
416+
"AZURE_OPENAI_ENDPOINT environment variable must be set to use "
417+
"the 'azure-openai' provider."
418+
)
419+
if not api_version:
420+
raise ValueError(
421+
"OPENAI_API_VERSION environment variable must be set to use "
422+
"the 'azure-openai' provider (e.g. '2024-06-01')."
423+
)
424+
425+
from chatlas import ChatAzureOpenAI # pragma: no cover
426+
427+
chat = ChatAzureOpenAI( # pragma: no cover
428+
endpoint=endpoint,
429+
deployment_id=model_name,
430+
api_version=api_version,
431+
api_key=self.api_key,
432+
system_prompt="You are a terse assistant and a Python expert.",
433+
kwargs={"http_client": http_client},
434+
)
435+
392436
self.response = str(chat.chat(prompt, stream=False, echo="none")) # pragma: no cover
393437

394438
def __str__(self) -> str:

tests/test_draft.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,23 @@ def test_draft_fail_invalid_provider():
1818

1919
with pytest.raises(ValueError):
2020
DraftValidation(data=small_table, model="invalid:model")
21+
22+
23+
def test_draft_fail_azure_openai_missing_endpoint(monkeypatch):
24+
pytest.importorskip("openai")
25+
pytest.importorskip("chatlas")
26+
monkeypatch.delenv("AZURE_OPENAI_ENDPOINT", raising=False)
27+
monkeypatch.setenv("OPENAI_API_VERSION", "2024-06-01")
28+
small_table = load_dataset(dataset="small_table")
29+
with pytest.raises(ValueError, match="AZURE_OPENAI_ENDPOINT"):
30+
DraftValidation(data=small_table, model="azure-openai:my-deployment")
31+
32+
33+
def test_draft_fail_azure_openai_missing_api_version(monkeypatch):
34+
pytest.importorskip("openai")
35+
pytest.importorskip("chatlas")
36+
monkeypatch.setenv("AZURE_OPENAI_ENDPOINT", "https://example.openai.azure.com")
37+
monkeypatch.delenv("OPENAI_API_VERSION", raising=False)
38+
small_table = load_dataset(dataset="small_table")
39+
with pytest.raises(ValueError, match="OPENAI_API_VERSION"):
40+
DraftValidation(data=small_table, model="azure-openai:my-deployment")

user_guide/02-advanced-validation/04-draft-validation.qmd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ The `DraftValidation` class supports multiple LLM providers:
4949
- **OpenAI** (GPT models)
5050
- **Ollama** (local LLMs)
5151
- **Amazon Bedrock** (AWS-hosted models)
52+
- **Azure OpenAI** (OpenAI models deployed on Azure)
5253

5354
Each provider has different capabilities and performance characteristics, but all can be used to
5455
generate validation plans through a consistent interface.
@@ -171,6 +172,11 @@ You can also store API keys in a `.env` file in your project's root directory:
171172
# Contents of .env file
172173
ANTHROPIC_API_KEY=your_anthropic_api_key_here
173174
OPENAI_API_KEY=your_openai_api_key_here
175+
176+
# For Azure OpenAI, three variables are required:
177+
AZURE_OPENAI_API_KEY=your_azure_openai_api_key_here
178+
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
179+
OPENAI_API_VERSION=2025-03-01-preview
174180
```
175181

176182
If your API keys have standard names (like `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`),
@@ -280,6 +286,10 @@ pb.DraftValidation(data=data, model="ollama:llama3:latest")
280286

281287
# Using Amazon Bedrock
282288
pb.DraftValidation(data=data, model="bedrock:anthropic.claude-3-sonnet-20240229-v1:0")
289+
290+
# Using Azure OpenAI (the value after the colon is the Azure deployment id, not an OpenAI model id;
291+
# requires AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT, and OPENAI_API_VERSION env vars)
292+
pb.DraftValidation(data=data, model="azure-openai:my-gpt4-deployment")
283293
```
284294

285295
### Model Performance and Privacy

0 commit comments

Comments
 (0)