Skip to content

Commit 4f26aeb

Browse files
authored
Upgrade syntax to Python 3.9 (#2484)
1 parent 56294c9 commit 4f26aeb

25 files changed

+91
-82
lines changed

app/backend/app.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import mimetypes
66
import os
77
import time
8+
from collections.abc import AsyncGenerator
89
from pathlib import Path
9-
from typing import Any, AsyncGenerator, Dict, Union, cast
10+
from typing import Any, Union, cast
1011

1112
from azure.cognitiveservices.speech import (
1213
ResultReason,
@@ -129,7 +130,7 @@ async def assets(path):
129130

130131
@bp.route("/content/<path>")
131132
@authenticated_path
132-
async def content_file(path: str, auth_claims: Dict[str, Any]):
133+
async def content_file(path: str, auth_claims: dict[str, Any]):
133134
"""
134135
Serve content files from blob storage from within the app to keep the example self-contained.
135136
*** NOTE *** if you are using app services authentication, this route will return unauthorized to all users that are not logged in
@@ -174,7 +175,7 @@ async def content_file(path: str, auth_claims: Dict[str, Any]):
174175

175176
@bp.route("/ask", methods=["POST"])
176177
@authenticated
177-
async def ask(auth_claims: Dict[str, Any]):
178+
async def ask(auth_claims: dict[str, Any]):
178179
if not request.is_json:
179180
return jsonify({"error": "request must be json"}), 415
180181
request_json = await request.get_json()
@@ -213,7 +214,7 @@ async def format_as_ndjson(r: AsyncGenerator[dict, None]) -> AsyncGenerator[str,
213214

214215
@bp.route("/chat", methods=["POST"])
215216
@authenticated
216-
async def chat(auth_claims: Dict[str, Any]):
217+
async def chat(auth_claims: dict[str, Any]):
217218
if not request.is_json:
218219
return jsonify({"error": "request must be json"}), 415
219220
request_json = await request.get_json()
@@ -247,7 +248,7 @@ async def chat(auth_claims: Dict[str, Any]):
247248

248249
@bp.route("/chat/stream", methods=["POST"])
249250
@authenticated
250-
async def chat_stream(auth_claims: Dict[str, Any]):
251+
async def chat_stream(auth_claims: dict[str, Any]):
251252
if not request.is_json:
252253
return jsonify({"error": "request must be json"}), 415
253254
request_json = await request.get_json()

app/backend/approaches/approach.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import os
22
from abc import ABC
3+
from collections.abc import AsyncGenerator, Awaitable
34
from dataclasses import dataclass
45
from typing import (
56
Any,
6-
AsyncGenerator,
7-
Awaitable,
87
Callable,
9-
Dict,
10-
List,
118
Optional,
129
TypedDict,
1310
Union,
@@ -41,14 +38,14 @@
4138
class Document:
4239
id: Optional[str]
4340
content: Optional[str]
44-
embedding: Optional[List[float]]
45-
image_embedding: Optional[List[float]]
41+
embedding: Optional[list[float]]
42+
image_embedding: Optional[list[float]]
4643
category: Optional[str]
4744
sourcepage: Optional[str]
4845
sourcefile: Optional[str]
49-
oids: Optional[List[str]]
50-
groups: Optional[List[str]]
51-
captions: List[QueryCaptionResult]
46+
oids: Optional[list[str]]
47+
groups: Optional[list[str]]
48+
captions: list[QueryCaptionResult]
5249
score: Optional[float] = None
5350
reranker_score: Optional[float] = None
5451

@@ -80,7 +77,7 @@ def serialize_for_results(self) -> dict[str, Any]:
8077
}
8178

8279
@classmethod
83-
def trim_embedding(cls, embedding: Optional[List[float]]) -> Optional[str]:
80+
def trim_embedding(cls, embedding: Optional[list[float]]) -> Optional[str]:
8481
"""Returns a trimmed list of floats from the vector embedding."""
8582
if embedding:
8683
if len(embedding) > 2:
@@ -105,15 +102,15 @@ def update_token_usage(self, usage: CompletionUsage) -> None:
105102

106103
@dataclass
107104
class DataPoints:
108-
text: Optional[List[str]] = None
109-
images: Optional[List] = None
105+
text: Optional[list[str]] = None
106+
images: Optional[list] = None
110107

111108

112109
@dataclass
113110
class ExtraInfo:
114111
data_points: DataPoints
115-
thoughts: Optional[List[ThoughtStep]] = None
116-
followup_questions: Optional[List[Any]] = None
112+
thoughts: Optional[list[ThoughtStep]] = None
113+
followup_questions: Optional[list[Any]] = None
117114

118115

119116
@dataclass
@@ -201,15 +198,15 @@ async def search(
201198
top: int,
202199
query_text: Optional[str],
203200
filter: Optional[str],
204-
vectors: List[VectorQuery],
201+
vectors: list[VectorQuery],
205202
use_text_search: bool,
206203
use_vector_search: bool,
207204
use_semantic_ranker: bool,
208205
use_semantic_captions: bool,
209206
minimum_search_score: Optional[float] = None,
210207
minimum_reranker_score: Optional[float] = None,
211208
use_query_rewriting: Optional[bool] = None,
212-
) -> List[Document]:
209+
) -> list[Document]:
213210
search_text = query_text if use_text_search else ""
214211
search_vectors = vectors if use_vector_search else []
215212
if use_semantic_ranker:
@@ -248,7 +245,7 @@ async def search(
248245
sourcefile=document.get("sourcefile"),
249246
oids=document.get("oids"),
250247
groups=document.get("groups"),
251-
captions=cast(List[QueryCaptionResult], document.get("@search.captions")),
248+
captions=cast(list[QueryCaptionResult], document.get("@search.captions")),
252249
score=document.get("@search.score"),
253250
reranker_score=document.get("@search.reranker_score"),
254251
)
@@ -266,7 +263,7 @@ async def search(
266263
return qualified_documents
267264

268265
def get_sources_content(
269-
self, results: List[Document], use_semantic_captions: bool, use_image_citation: bool
266+
self, results: list[Document], use_semantic_captions: bool, use_image_citation: bool
270267
) -> list[str]:
271268

272269
def nonewlines(s: str) -> str:
@@ -358,13 +355,13 @@ def create_chat_completion(
358355
overrides: dict[str, Any],
359356
response_token_limit: int,
360357
should_stream: bool = False,
361-
tools: Optional[List[ChatCompletionToolParam]] = None,
358+
tools: Optional[list[ChatCompletionToolParam]] = None,
362359
temperature: Optional[float] = None,
363360
n: Optional[int] = None,
364361
reasoning_effort: Optional[ChatCompletionReasoningEffort] = None,
365362
) -> Union[Awaitable[ChatCompletion], Awaitable[AsyncStream[ChatCompletionChunk]]]:
366363
if chatgpt_model in self.GPT_REASONING_MODELS:
367-
params: Dict[str, Any] = {
364+
params: dict[str, Any] = {
368365
# max_tokens is not supported
369366
"max_completion_tokens": response_token_limit
370367
}
@@ -400,14 +397,14 @@ def create_chat_completion(
400397
def format_thought_step_for_chatcompletion(
401398
self,
402399
title: str,
403-
messages: List[ChatCompletionMessageParam],
400+
messages: list[ChatCompletionMessageParam],
404401
overrides: dict[str, Any],
405402
model: str,
406403
deployment: Optional[str],
407404
usage: Optional[CompletionUsage] = None,
408405
reasoning_effort: Optional[ChatCompletionReasoningEffort] = None,
409406
) -> ThoughtStep:
410-
properties: Dict[str, Any] = {"model": model}
407+
properties: dict[str, Any] = {"model": model}
411408
if deployment:
412409
properties["deployment"] = deployment
413410
# Only add reasoning_effort setting if the model supports it

app/backend/approaches/chatapproach.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import json
22
import re
33
from abc import ABC, abstractmethod
4-
from typing import Any, AsyncGenerator, Awaitable, Optional, Union, cast
4+
from collections.abc import AsyncGenerator, Awaitable
5+
from typing import Any, Optional, Union, cast
56

67
from openai import AsyncStream
78
from openai.types.chat import (

app/backend/approaches/chatreadretrieveread.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any, Awaitable, List, Optional, Union, cast
1+
from collections.abc import Awaitable
2+
from typing import Any, Optional, Union, cast
23

34
from azure.search.documents.aio import SearchClient
45
from azure.search.documents.models import VectorQuery
@@ -90,7 +91,7 @@ async def run_until_final_call(
9091
query_messages = self.prompt_manager.render_prompt(
9192
self.query_rewrite_prompt, {"user_query": original_user_query, "past_messages": messages[:-1]}
9293
)
93-
tools: List[ChatCompletionToolParam] = self.query_rewrite_tools
94+
tools: list[ChatCompletionToolParam] = self.query_rewrite_tools
9495

9596
# STEP 1: Generate an optimized keyword search query based on the chat history and the last question
9697

app/backend/approaches/chatreadretrievereadvision.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any, Awaitable, Callable, List, Optional, Union, cast
1+
from collections.abc import Awaitable
2+
from typing import Any, Callable, Optional, Union, cast
23

34
from azure.search.documents.aio import SearchClient
45
from azure.storage.blob.aio import ContainerClient
@@ -100,7 +101,7 @@ async def run_until_final_call(
100101
query_messages = self.prompt_manager.render_prompt(
101102
self.query_rewrite_prompt, {"user_query": original_user_query, "past_messages": messages[:-1]}
102103
)
103-
tools: List[ChatCompletionToolParam] = self.query_rewrite_tools
104+
tools: list[ChatCompletionToolParam] = self.query_rewrite_tools
104105

105106
# STEP 1: Generate an optimized keyword search query based on the chat history and the last question
106107
chat_completion: ChatCompletion = await self.openai_client.chat.completions.create(

app/backend/approaches/retrievethenreadvision.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any, Awaitable, Callable, Optional
1+
from collections.abc import Awaitable
2+
from typing import Any, Callable, Optional
23

34
from azure.search.documents.aio import SearchClient
45
from azure.storage.blob.aio import ContainerClient

app/backend/chat_history/cosmosdb.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22
import time
3-
from typing import Any, Dict, Union
3+
from typing import Any, Union
44

55
from azure.cosmos.aio import ContainerProxy, CosmosClient
66
from azure.identity.aio import AzureDeveloperCliCredential, ManagedIdentityCredential
@@ -21,7 +21,7 @@
2121

2222
@chat_history_cosmosdb_bp.post("/chat_history")
2323
@authenticated
24-
async def post_chat_history(auth_claims: Dict[str, Any]):
24+
async def post_chat_history(auth_claims: dict[str, Any]):
2525
if not current_app.config[CONFIG_CHAT_HISTORY_COSMOS_ENABLED]:
2626
return jsonify({"error": "Chat history not enabled"}), 400
2727

@@ -78,7 +78,7 @@ async def post_chat_history(auth_claims: Dict[str, Any]):
7878

7979
@chat_history_cosmosdb_bp.get("/chat_history/sessions")
8080
@authenticated
81-
async def get_chat_history_sessions(auth_claims: Dict[str, Any]):
81+
async def get_chat_history_sessions(auth_claims: dict[str, Any]):
8282
if not current_app.config[CONFIG_CHAT_HISTORY_COSMOS_ENABLED]:
8383
return jsonify({"error": "Chat history not enabled"}), 400
8484

@@ -131,7 +131,7 @@ async def get_chat_history_sessions(auth_claims: Dict[str, Any]):
131131

132132
@chat_history_cosmosdb_bp.get("/chat_history/sessions/<session_id>")
133133
@authenticated
134-
async def get_chat_history_session(auth_claims: Dict[str, Any], session_id: str):
134+
async def get_chat_history_session(auth_claims: dict[str, Any], session_id: str):
135135
if not current_app.config[CONFIG_CHAT_HISTORY_COSMOS_ENABLED]:
136136
return jsonify({"error": "Chat history not enabled"}), 400
137137

@@ -171,7 +171,7 @@ async def get_chat_history_session(auth_claims: Dict[str, Any], session_id: str)
171171

172172
@chat_history_cosmosdb_bp.delete("/chat_history/sessions/<session_id>")
173173
@authenticated
174-
async def delete_chat_history_session(auth_claims: Dict[str, Any], session_id: str):
174+
async def delete_chat_history_session(auth_claims: dict[str, Any], session_id: str):
175175
if not current_app.config[CONFIG_CHAT_HISTORY_COSMOS_ENABLED]:
176176
return jsonify({"error": "Chat history not enabled"}), 400
177177

app/backend/decorators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
from functools import wraps
3-
from typing import Any, Callable, Dict, TypeVar, cast
3+
from typing import Any, Callable, TypeVar, cast
44

55
from quart import abort, current_app, request
66

@@ -9,7 +9,7 @@
99
from error import error_response
1010

1111

12-
def authenticated_path(route_fn: Callable[[str, Dict[str, Any]], Any]):
12+
def authenticated_path(route_fn: Callable[[str, dict[str, Any]], Any]):
1313
"""
1414
Decorator for routes that request a specific file that might require access control enforcement
1515
"""

app/backend/prepdocslib/blobmanager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
import os
55
import re
6-
from typing import List, Optional, Union
6+
from typing import Optional, Union
77

88
import pymupdf
99
from azure.core.credentials_async import AsyncTokenCredential
@@ -45,7 +45,7 @@ def __init__(
4545
self.subscriptionId = subscriptionId
4646
self.user_delegation_key: Optional[UserDelegationKey] = None
4747

48-
async def upload_blob(self, file: File) -> Optional[List[str]]:
48+
async def upload_blob(self, file: File) -> Optional[list[str]]:
4949
async with BlobServiceClient(
5050
account_url=self.endpoint, credential=self.credential, max_single_put_size=4 * 1024 * 1024
5151
) as service_client, service_client.get_container_client(self.container) as container_client:
@@ -73,7 +73,7 @@ def get_managedidentity_connectionstring(self):
7373

7474
async def upload_pdf_blob_images(
7575
self, service_client: BlobServiceClient, container_client: ContainerClient, file: File
76-
) -> List[str]:
76+
) -> list[str]:
7777
with open(file.content.name, "rb") as reopened_file:
7878
reader = PdfReader(reopened_file)
7979
page_count = len(reader.pages)

app/backend/prepdocslib/csvparser.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import csv
2-
from typing import IO, AsyncGenerator
2+
from collections.abc import AsyncGenerator
3+
from typing import IO
34

45
from .page import Page
56
from .parser import Parser

0 commit comments

Comments
 (0)