Skip to content

Commit 1f86926

Browse files
authored
Merge pull request #135 from Azure-Samples/python39
Make repo Python 3.9 compatible
2 parents e477b96 + 6f7192b commit 1f86926

File tree

15 files changed

+65
-59
lines changed

15 files changed

+65
-59
lines changed

.devcontainer/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ services:
66
context: ..
77
dockerfile: .devcontainer/Dockerfile
88
args:
9-
IMAGE: python:3.11
9+
IMAGE: python:3.12
1010

1111
volumes:
1212
- ..:/workspace:cached

.github/workflows/app-tests.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ jobs:
2828
fail-fast: false
2929
matrix:
3030
os: ["ubuntu-latest", "macos-latest-xlarge", "macos-13", "windows-latest"]
31-
python_version: ["3.10"]
31+
python_version: ["3.9", "3.10", "3.11", "3.12"]
3232
exclude:
33+
- os: macos-latest-xlarge
34+
python_version: "3.9"
3335
- os: macos-latest-xlarge
3436
python_version: "3.10"
3537
env:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ A related option is VS Code Dev Containers, which will open the project in your
6969

7070
* [Azure Developer CLI (azd)](https://aka.ms/install-azd)
7171
* [Node.js 18+](https://nodejs.org/download/)
72-
* [Python 3.10+](https://www.python.org/downloads/)
72+
* [Python 3.9+](https://www.python.org/downloads/)
7373
* [PostgreSQL 14+](https://www.postgresql.org/download/)
7474
* [pgvector](https://github.com/pgvector/pgvector)
7575
* [Docker Desktop](https://www.docker.com/products/docker-desktop/)

evals/generate_ground_truth.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
from collections.abc import Generator
55
from pathlib import Path
6+
from typing import Union
67

78
from azure.identity import AzureDeveloperCliCredential, get_bearer_token_provider
89
from dotenv_azd import load_azd_env
@@ -77,9 +78,9 @@ def answer_formatter(answer, source) -> str:
7778
return f"{answer} [{source['id']}]"
7879

7980

80-
def get_openai_client() -> tuple[AzureOpenAI | OpenAI, str]:
81+
def get_openai_client() -> tuple[Union[AzureOpenAI, OpenAI], str]:
8182
"""Return an OpenAI client based on the environment variables"""
82-
openai_client: AzureOpenAI | OpenAI
83+
openai_client: Union[AzureOpenAI, OpenAI]
8384
OPENAI_CHAT_HOST = os.getenv("OPENAI_CHAT_HOST")
8485
if OPENAI_CHAT_HOST == "azure":
8586
if api_key := os.getenv("AZURE_OPENAI_KEY"):

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[tool.ruff]
22
line-length = 120
3-
target-version = "py312"
3+
target-version = "py39"
44
lint.select = ["E", "F", "I", "UP"]
55
lint.ignore = ["D203"]
66
lint.isort.known-first-party = ["fastapi_app"]
77

88
[tool.mypy]
99
check_untyped_defs = true
10-
python_version = 3.12
10+
python_version = 3.9
1111
exclude = [".venv/*"]
1212

1313
[tool.pytest.ini_options]

src/backend/fastapi_app/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
from collections.abc import AsyncIterator
44
from contextlib import asynccontextmanager
5-
from typing import TypedDict
5+
from typing import TypedDict, Union
66

77
import fastapi
88
from azure.monitor.opentelemetry import configure_azure_monitor
@@ -27,8 +27,8 @@
2727
class State(TypedDict):
2828
sessionmaker: async_sessionmaker[AsyncSession]
2929
context: FastAPIAppContext
30-
chat_client: AsyncOpenAI | AsyncAzureOpenAI
31-
embed_client: AsyncOpenAI | AsyncAzureOpenAI
30+
chat_client: Union[AsyncOpenAI, AsyncAzureOpenAI]
31+
embed_client: Union[AsyncOpenAI, AsyncAzureOpenAI]
3232

3333

3434
@asynccontextmanager

src/backend/fastapi_app/api_models.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from enum import Enum
2-
from typing import Any
2+
from typing import Any, Optional
33

44
from openai.types.chat import ChatCompletionMessageParam
55
from pydantic import BaseModel
@@ -27,8 +27,8 @@ class ChatRequestOverrides(BaseModel):
2727
temperature: float = 0.3
2828
retrieval_mode: RetrievalMode = RetrievalMode.HYBRID
2929
use_advanced_flow: bool = True
30-
prompt_template: str | None = None
31-
seed: int | None = None
30+
prompt_template: Optional[str] = None
31+
seed: Optional[int] = None
3232

3333

3434
class ChatRequestContext(BaseModel):
@@ -38,7 +38,7 @@ class ChatRequestContext(BaseModel):
3838
class ChatRequest(BaseModel):
3939
messages: list[ChatCompletionMessageParam]
4040
context: ChatRequestContext
41-
sessionState: Any | None = None
41+
sessionState: Optional[Any] = None
4242

4343

4444
class ThoughtStep(BaseModel):
@@ -50,7 +50,7 @@ class ThoughtStep(BaseModel):
5050
class RAGContext(BaseModel):
5151
data_points: dict[int, dict[str, Any]]
5252
thoughts: list[ThoughtStep]
53-
followup_questions: list[str] | None = None
53+
followup_questions: Optional[list[str]] = None
5454

5555

5656
class ErrorResponse(BaseModel):
@@ -60,13 +60,13 @@ class ErrorResponse(BaseModel):
6060
class RetrievalResponse(BaseModel):
6161
message: Message
6262
context: RAGContext
63-
sessionState: Any | None = None
63+
sessionState: Optional[Any] = None
6464

6565

6666
class RetrievalResponseDelta(BaseModel):
67-
delta: Message | None = None
68-
context: RAGContext | None = None
69-
sessionState: Any | None = None
67+
delta: Optional[Message] = None
68+
context: Optional[RAGContext] = None
69+
sessionState: Optional[Any] = None
7070

7171

7272
class ItemPublic(BaseModel):

src/backend/fastapi_app/dependencies.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
import os
33
from collections.abc import AsyncGenerator
4-
from typing import Annotated
4+
from typing import Annotated, Optional, Union
55

66
import azure.identity
77
from fastapi import Depends, Request
@@ -17,7 +17,7 @@ class OpenAIClient(BaseModel):
1717
OpenAI client
1818
"""
1919

20-
client: AsyncOpenAI | AsyncAzureOpenAI
20+
client: Union[AsyncOpenAI, AsyncAzureOpenAI]
2121
model_config = {"arbitrary_types_allowed": True}
2222

2323

@@ -28,9 +28,9 @@ class FastAPIAppContext(BaseModel):
2828

2929
openai_chat_model: str
3030
openai_embed_model: str
31-
openai_embed_dimensions: int | None
32-
openai_chat_deployment: str | None
33-
openai_embed_deployment: str | None
31+
openai_embed_dimensions: Optional[int]
32+
openai_chat_deployment: Optional[str]
33+
openai_embed_deployment: Optional[str]
3434
embedding_column: str
3535

3636

@@ -77,9 +77,9 @@ async def common_parameters():
7777

7878

7979
async def get_azure_credential() -> (
80-
azure.identity.AzureDeveloperCliCredential | azure.identity.ManagedIdentityCredential
80+
Union[azure.identity.AzureDeveloperCliCredential, azure.identity.ManagedIdentityCredential]
8181
):
82-
azure_credential: azure.identity.AzureDeveloperCliCredential | azure.identity.ManagedIdentityCredential
82+
azure_credential: Union[azure.identity.AzureDeveloperCliCredential, azure.identity.ManagedIdentityCredential]
8383
try:
8484
if client_id := os.getenv("APP_IDENTITY_ID"):
8585
# Authenticate using a user-assigned managed identity on Azure

src/backend/fastapi_app/embeddings.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
from typing import (
2-
TypedDict,
3-
)
1+
from typing import Optional, TypedDict, Union
42

53
from openai import AsyncAzureOpenAI, AsyncOpenAI
64

75

86
async def compute_text_embedding(
97
q: str,
10-
openai_client: AsyncOpenAI | AsyncAzureOpenAI,
8+
openai_client: Union[AsyncOpenAI, AsyncAzureOpenAI],
119
embed_model: str,
12-
embed_deployment: str | None = None,
13-
embedding_dimensions: int | None = None,
10+
embed_deployment: Optional[str] = None,
11+
embedding_dimensions: Optional[int] = None,
1412
) -> list[float]:
1513
SUPPORTED_DIMENSIONS_MODEL = {
1614
"text-embedding-ada-002": False,

src/backend/fastapi_app/openai_clients.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import os
3+
from typing import Union
34

45
import azure.identity
56
import openai
@@ -8,9 +9,9 @@
89

910

1011
async def create_openai_chat_client(
11-
azure_credential: azure.identity.AzureDeveloperCliCredential | azure.identity.ManagedIdentityCredential,
12-
) -> openai.AsyncAzureOpenAI | openai.AsyncOpenAI:
13-
openai_chat_client: openai.AsyncAzureOpenAI | openai.AsyncOpenAI
12+
azure_credential: Union[azure.identity.AzureDeveloperCliCredential, azure.identity.ManagedIdentityCredential],
13+
) -> Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]:
14+
openai_chat_client: Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]
1415
OPENAI_CHAT_HOST = os.getenv("OPENAI_CHAT_HOST")
1516
if OPENAI_CHAT_HOST == "azure":
1617
api_version = os.environ["AZURE_OPENAI_VERSION"] or "2024-03-01-preview"
@@ -57,9 +58,9 @@ async def create_openai_chat_client(
5758

5859

5960
async def create_openai_embed_client(
60-
azure_credential: azure.identity.AzureDeveloperCliCredential | azure.identity.ManagedIdentityCredential,
61-
) -> openai.AsyncAzureOpenAI | openai.AsyncOpenAI:
62-
openai_embed_client: openai.AsyncAzureOpenAI | openai.AsyncOpenAI
61+
azure_credential: Union[azure.identity.AzureDeveloperCliCredential, azure.identity.ManagedIdentityCredential],
62+
) -> Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]:
63+
openai_embed_client: Union[openai.AsyncAzureOpenAI, openai.AsyncOpenAI]
6364
OPENAI_EMBED_HOST = os.getenv("OPENAI_EMBED_HOST")
6465
if OPENAI_EMBED_HOST == "azure":
6566
api_version = os.environ["AZURE_OPENAI_VERSION"] or "2024-03-01-preview"

0 commit comments

Comments
 (0)