Skip to content

Commit 8d6a26c

Browse files
authored
Azure AI Face SDK beta2 (Azure#37044)
* codegen update * Update client _patch * Update version * Update assets * Update codegen * Sample for large face list * Add LPG sample * Update codegen * Remove unused testcase * Add findsimilar test * Add identify test * Remove FL and PG * Fix test * Update codegen * Remove _operations * Add changelog * Codegen * Add new content to README * Regen * Update model enum * Update typo in generated test * Add enum breaking change schangelog * update codegen * Fix customization * Suppress verifytypes * Update to latest tsp * Pause verifytypes * Update release date * Update date
1 parent a7e3707 commit 8d6a26c

File tree

107 files changed

+18721
-9615
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+18721
-9615
lines changed

sdk/face/azure-ai-vision-face/CHANGELOG.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
# Release History
22

3-
## 1.0.0b2 (Unreleased)
3+
## 1.0.0b2 (2024-10-23)
44

55
### Features Added
66

7+
- Added support for the Large Face List and Large Person Group:
8+
- Added operation groups `LargeFaceListOperations` and `LargePersonGroupOperations` to `FaceAdministrationClient`.
9+
- Added operations `find_similar_from_large_face_list`, `identify_from_large_person_group` and `verify_from_large_person_group` to `FaceClient`.
10+
- Added models for supporting Large Face List and Large Person Group.
11+
- Added support for latest Detect Liveness Session API:
12+
- Added operations `get_session_image` and `detect_from_session_image` to `FaceSessionClient`.
13+
- Added properties `enable_session_image` and `liveness_single_modal_model` to model `CreateLivenessSessionContent`.
14+
- Added model `CreateLivenessWithVerifySessionContent`.
15+
716
### Breaking Changes
817

9-
### Bugs Fixed
18+
- Changed the parameter of `create_liveness_with_verify_session` from model `CreateLivenessSessionContent` to `CreateLivenessWithVerifySessionContent`.
19+
- Changed the enum value of `FaceDetectionModel`, `FaceRecognitionModel`, `LivenessModel` and `Versions`.
1020

1121
### Other Changes
1222

23+
- Change the default service API version to `v1.2-preview.1`.
24+
1325
## 1.0.0b1 (2024-05-28)
1426

1527
This is the first preview of the `azure-ai-vision-face` client library that follows the [Azure Python SDK Design Guidelines](https://azure.github.io/azure-sdk/python_design.html).

sdk/face/azure-ai-vision-face/README.md

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The Azure AI Face service provides AI algorithms that detect, recognize, and ana
66
- Liveness detection
77
- Face recognition
88
- Face verification ("one-to-one" matching)
9+
- Face identification ("one-to-many" matching)
910
- Find similar faces
1011
- Group faces
1112

@@ -130,6 +131,18 @@ face_client = FaceClient(endpoint, credential)
130131
- Finding similar faces from a smaller set of faces that look similar to the target face.
131132
- Grouping faces into several smaller groups based on similarity.
132133

134+
### FaceAdministrationClient
135+
136+
`FaceAdministrationClient` is provided to interact with the following data structures that hold data on faces and
137+
person for Face recognition:
138+
139+
- `large_face_list`: It is a list of faces which can hold faces and used by [find similar faces][find_similar].
140+
- It can up to 1,000,000 faces.
141+
- Training (`begin_train()`) is required before calling `find_similar_from_large_face_list()`.
142+
- `large_person_group`: It is a container which can hold person objects, and is used by face recognition.
143+
- It can up to 1,000,000 person objects, with each person capable of holding up to 248 faces. The total person objects in all `large_person_group` should not exceed 1,000,000,000.
144+
- For [face verification][face_verification], call `verify_from_large_person_group()`.
145+
- For [face identification][face_identification], training (`begin_train()`) is required before calling `identify_from_large_person_group()`.
133146

134147
### FaceSessionClient
135148

@@ -139,12 +152,23 @@ face_client = FaceClient(endpoint, credential)
139152
- Query the liveness and verification result.
140153
- Query the audit result.
141154

155+
### Long-running operations
156+
157+
Long-running operations are operations which consist of an initial request sent to the service to start an operation,
158+
followed by polling the service at intervals to determine whether the operation has completed or failed, and if it has
159+
succeeded, to get the result.
160+
161+
Methods that train a group (LargeFaceList or LargePersonGroup) are modeled as long-running operations.
162+
The client exposes a `begin_<method-name>` method that returns an `LROPoller` or `AsyncLROPoller`. Callers should wait
163+
for the operation to complete by calling `result()` on the poller object returned from the `begin_<method-name>` method.
164+
Sample code snippets are provided to illustrate using long-running operations [below](#examples "Examples").
142165

143166
## Examples
144167

145168
The following section provides several code snippets covering some of the most common Face tasks, including:
146169

147170
* [Detecting faces in an image](#face-detection "Face Detection")
171+
* [Identifying the specific face from a LargePersonGroup](#face-recognition-from-largepersongroup "Face Recognition from LargePersonGroup")
148172
* [Determining if a face in an video is real (live) or fake (spoof)](#liveness-detection "Liveness Detection")
149173

150174
### Face Detection
@@ -173,8 +197,8 @@ with FaceClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_c
173197

174198
result = face_client.detect(
175199
file_content,
176-
detection_model=FaceDetectionModel.DETECTION_03, # The latest detection model.
177-
recognition_model=FaceRecognitionModel.RECOGNITION_04, # The latest recognition model.
200+
detection_model=FaceDetectionModel.DETECTION03, # The latest detection model.
201+
recognition_model=FaceRecognitionModel.RECOGNITION04, # The latest recognition model.
178202
return_face_id=True,
179203
return_face_attributes=[
180204
FaceAttributeTypeDetection03.HEAD_POSE,
@@ -192,6 +216,103 @@ with FaceClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_c
192216
print(f"Face: {face.as_dict()}")
193217
```
194218

219+
### Face Recognition from LargePersonGroup
220+
221+
Identify a face against a defined LargePersonGroup.
222+
223+
First, we have to use `FaceAdministrationClient` to create a `LargePersonGroup`, add a few `Person` to it, and then register faces with these `Person`.
224+
225+
```python
226+
from azure.core.credentials import AzureKeyCredential
227+
from azure.ai.vision.face import FaceAdministrationClient, FaceClient
228+
from azure.ai.vision.face.models import FaceDetectionModel, FaceRecognitionModel
229+
230+
231+
def read_file_content(file_path: str):
232+
with open(file_path, "rb") as fd:
233+
file_content = fd.read()
234+
235+
return file_content
236+
237+
238+
endpoint = "<your endpoint>"
239+
key = "<your api key>"
240+
241+
large_person_group_id = "lpg_family"
242+
243+
with FaceAdministrationClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_admin_client:
244+
print(f"Create a large person group with id: {large_person_group_id}")
245+
face_admin_client.large_person_group.create(
246+
large_person_group_id, name="My Family", recognition_model=FaceRecognitionModel.RECOGNITION04
247+
)
248+
249+
print("Create a Person Bill and add a face to him.")
250+
bill_person_id = face_admin_client.large_person_group.create_person(
251+
large_person_group_id, name="Bill", user_data="Dad"
252+
).person_id
253+
bill_image_file_path = "./samples/images/Family1-Dad1.jpg"
254+
face_admin_client.large_person_group.add_face(
255+
large_person_group_id,
256+
bill_person_id,
257+
read_file_content(bill_image_file_path),
258+
detection_model=FaceDetectionModel.DETECTION03,
259+
user_data="Dad-0001",
260+
)
261+
262+
print("Create a Person Clare and add a face to her.")
263+
clare_person_id = face_admin_client.large_person_group.create_person(
264+
large_person_group_id, name="Clare", user_data="Mom"
265+
).person_id
266+
clare_image_file_path = "./samples/images/Family1-Mom1.jpg"
267+
face_admin_client.large_person_group.add_face(
268+
large_person_group_id,
269+
clare_person_id,
270+
read_file_content(clare_image_file_path),
271+
detection_model=FaceDetectionModel.DETECTION03,
272+
user_data="Mom-0001",
273+
)
274+
```
275+
276+
Before doing the identification, we need to train the LargePersonGroup first.
277+
```python
278+
print(f"Start to train the large person group: {large_person_group_id}.")
279+
poller = face_admin_client.large_person_group.begin_train(large_person_group_id)
280+
281+
# Wait for the train operation to be completed.
282+
# If the training status isn't succeed, an exception will be thrown from the poller.
283+
training_result = poller.result()
284+
```
285+
286+
When the training operation is completed successfully, we can identify the faces in this LargePersonGroup through
287+
`FaceClient`.
288+
```python
289+
with FaceClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_client:
290+
# Detect the face from the target image.
291+
target_image_file_path = "./samples/images/identification1.jpg"
292+
detect_result = face_client.detect(
293+
read_file_content(target_image_file_path),
294+
detection_model=FaceDetectionModel.DETECTION03,
295+
recognition_model=FaceRecognitionModel.RECOGNITION04,
296+
return_face_id=True,
297+
)
298+
target_face_ids = list(f.face_id for f in detect_result)
299+
300+
# Identify the faces in the large person group.
301+
result = face_client.identify_from_large_person_group(
302+
face_ids=target_face_ids, large_person_group_id=large_person_group_id
303+
)
304+
for idx, r in enumerate(result):
305+
print(f"----- Identification result: #{idx+1} -----")
306+
print(f"{r.as_dict()}")
307+
```
308+
309+
Finally, use `FaceAdministrationClient` to remove the large person group if you don't need it anymore.
310+
```python
311+
with FaceAdministrationClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_admin_client:
312+
print(f"Delete the large person group: {large_person_group_id}")
313+
face_admin_client.large_person_group.delete(large_person_group_id)
314+
```
315+
195316
### Liveness detection
196317
Face Liveness detection can be used to determine if a face in an input video stream is real (live) or fake (spoof).
197318
The goal of liveness detection is to ensure that the system is interacting with a physically present live person at

sdk/face/azure-ai-vision-face/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/face/azure-ai-vision-face",
5-
"Tag": "python/face/azure-ai-vision-face_f787b7aa30"
5+
"Tag": "python/face/azure-ai-vision-face_0b4013000f"
66
}

sdk/face/azure-ai-vision-face/azure/ai/vision/face/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
77
# --------------------------------------------------------------------------
88

9+
from ._client import FaceAdministrationClient
910
from ._patch import FaceClient
1011
from ._patch import FaceSessionClient
1112
from ._version import VERSION
@@ -16,6 +17,7 @@
1617
from ._patch import patch_sdk as _patch_sdk
1718

1819
__all__ = [
20+
"FaceAdministrationClient",
1921
"FaceClient",
2022
"FaceSessionClient",
2123
]

sdk/face/azure-ai-vision-face/azure/ai/vision/face/_client.py

Lines changed: 109 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,120 @@
88

99
from copy import deepcopy
1010
from typing import Any, TYPE_CHECKING, Union
11+
from typing_extensions import Self
1112

1213
from azure.core import PipelineClient
1314
from azure.core.credentials import AzureKeyCredential
1415
from azure.core.pipeline import policies
1516
from azure.core.rest import HttpRequest, HttpResponse
1617

17-
from ._configuration import FaceClientConfiguration, FaceSessionClientConfiguration
18-
from ._operations import FaceClientOperationsMixin, FaceSessionClientOperationsMixin
18+
from ._configuration import (
19+
FaceAdministrationClientConfiguration,
20+
FaceClientConfiguration,
21+
FaceSessionClientConfiguration,
22+
)
1923
from ._serialization import Deserializer, Serializer
24+
from .operations import (
25+
FaceClientOperationsMixin,
26+
FaceSessionClientOperationsMixin,
27+
LargeFaceListOperations,
28+
LargePersonGroupOperations,
29+
)
2030

2131
if TYPE_CHECKING:
22-
# pylint: disable=unused-import,ungrouped-imports
2332
from azure.core.credentials import TokenCredential
2433

2534

26-
class FaceClient(FaceClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword
35+
class FaceAdministrationClient:
36+
"""FaceAdministrationClient.
37+
38+
:ivar large_face_list: LargeFaceListOperations operations
39+
:vartype large_face_list: azure.ai.vision.face.operations.LargeFaceListOperations
40+
:ivar large_person_group: LargePersonGroupOperations operations
41+
:vartype large_person_group: azure.ai.vision.face.operations.LargePersonGroupOperations
42+
:param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
43+
https://{resource-name}.cognitiveservices.azure.com). Required.
44+
:type endpoint: str
45+
:param credential: Credential used to authenticate requests to the service. Is either a
46+
AzureKeyCredential type or a TokenCredential type. Required.
47+
:type credential: ~azure.core.credentials.AzureKeyCredential or
48+
~azure.core.credentials.TokenCredential
49+
:keyword api_version: API Version. Known values are "v1.2-preview.1" and None. Default value is
50+
"v1.2-preview.1". Note that overriding this default value may result in unsupported behavior.
51+
:paramtype api_version: str or ~azure.ai.vision.face.models.Versions
52+
:keyword int polling_interval: Default waiting time between two polls for LRO operations if no
53+
Retry-After header is present.
54+
"""
55+
56+
def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None:
57+
_endpoint = "{endpoint}/face/{apiVersion}"
58+
self._config = FaceAdministrationClientConfiguration(endpoint=endpoint, credential=credential, **kwargs)
59+
_policies = kwargs.pop("policies", None)
60+
if _policies is None:
61+
_policies = [
62+
policies.RequestIdPolicy(**kwargs),
63+
self._config.headers_policy,
64+
self._config.user_agent_policy,
65+
self._config.proxy_policy,
66+
policies.ContentDecodePolicy(**kwargs),
67+
self._config.redirect_policy,
68+
self._config.retry_policy,
69+
self._config.authentication_policy,
70+
self._config.custom_hook_policy,
71+
self._config.logging_policy,
72+
policies.DistributedTracingPolicy(**kwargs),
73+
policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,
74+
self._config.http_logging_policy,
75+
]
76+
self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs)
77+
78+
self._serialize = Serializer()
79+
self._deserialize = Deserializer()
80+
self._serialize.client_side_validation = False
81+
self.large_face_list = LargeFaceListOperations(self._client, self._config, self._serialize, self._deserialize)
82+
self.large_person_group = LargePersonGroupOperations(
83+
self._client, self._config, self._serialize, self._deserialize
84+
)
85+
86+
def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse:
87+
"""Runs the network request through the client's chained policies.
88+
89+
>>> from azure.core.rest import HttpRequest
90+
>>> request = HttpRequest("GET", "https://www.example.org/")
91+
<HttpRequest [GET], url: 'https://www.example.org/'>
92+
>>> response = client.send_request(request)
93+
<HttpResponse: 200 OK>
94+
95+
For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request
96+
97+
:param request: The network request you want to make. Required.
98+
:type request: ~azure.core.rest.HttpRequest
99+
:keyword bool stream: Whether the response payload will be streamed. Defaults to False.
100+
:return: The response of your network call. Does not do error handling on your response.
101+
:rtype: ~azure.core.rest.HttpResponse
102+
"""
103+
104+
request_copy = deepcopy(request)
105+
path_format_arguments = {
106+
"endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
107+
"apiVersion": self._serialize.url("self._config.api_version", self._config.api_version, "str"),
108+
}
109+
110+
request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments)
111+
return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore
112+
113+
def close(self) -> None:
114+
self._client.close()
115+
116+
def __enter__(self) -> Self:
117+
self._client.__enter__()
118+
return self
119+
120+
def __exit__(self, *exc_details: Any) -> None:
121+
self._client.__exit__(*exc_details)
122+
123+
124+
class FaceClient(FaceClientOperationsMixin):
27125
"""FaceClient.
28126
29127
:param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
@@ -33,8 +131,8 @@ class FaceClient(FaceClientOperationsMixin): # pylint: disable=client-accepts-a
33131
AzureKeyCredential type or a TokenCredential type. Required.
34132
:type credential: ~azure.core.credentials.AzureKeyCredential or
35133
~azure.core.credentials.TokenCredential
36-
:keyword api_version: API Version. Default value is "v1.1-preview.1". Note that overriding this
37-
default value may result in unsupported behavior.
134+
:keyword api_version: API Version. Known values are "v1.2-preview.1" and None. Default value is
135+
"v1.2-preview.1". Note that overriding this default value may result in unsupported behavior.
38136
:paramtype api_version: str or ~azure.ai.vision.face.models.Versions
39137
"""
40138

@@ -94,15 +192,15 @@ def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs:
94192
def close(self) -> None:
95193
self._client.close()
96194

97-
def __enter__(self) -> "FaceClient":
195+
def __enter__(self) -> Self:
98196
self._client.__enter__()
99197
return self
100198

101199
def __exit__(self, *exc_details: Any) -> None:
102200
self._client.__exit__(*exc_details)
103201

104202

105-
class FaceSessionClient(FaceSessionClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword
203+
class FaceSessionClient(FaceSessionClientOperationsMixin):
106204
"""FaceSessionClient.
107205
108206
:param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
@@ -112,8 +210,8 @@ class FaceSessionClient(FaceSessionClientOperationsMixin): # pylint: disable=cl
112210
AzureKeyCredential type or a TokenCredential type. Required.
113211
:type credential: ~azure.core.credentials.AzureKeyCredential or
114212
~azure.core.credentials.TokenCredential
115-
:keyword api_version: API Version. Default value is "v1.1-preview.1". Note that overriding this
116-
default value may result in unsupported behavior.
213+
:keyword api_version: API Version. Known values are "v1.2-preview.1" and None. Default value is
214+
"v1.2-preview.1". Note that overriding this default value may result in unsupported behavior.
117215
:paramtype api_version: str or ~azure.ai.vision.face.models.Versions
118216
"""
119217

@@ -173,7 +271,7 @@ def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs:
173271
def close(self) -> None:
174272
self._client.close()
175273

176-
def __enter__(self) -> "FaceSessionClient":
274+
def __enter__(self) -> Self:
177275
self._client.__enter__()
178276
return self
179277

0 commit comments

Comments
 (0)