Skip to content

Commit 83c18b8

Browse files
authored
[Face] Remove FaceAdministrationClient (#35742)
* Regenerate SDK with the latest TypeSpec * Remove samples and tests which are related to `FaceAdministrationClient` * Update README.md and CHANGLOG.md * Update test recordings
1 parent 69b370f commit 83c18b8

File tree

23 files changed

+1954
-34867
lines changed

23 files changed

+1954
-34867
lines changed

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,18 @@ This package's [documentation](https://github.com/Azure/azure-sdk-for-python/tre
1010
### Features Added
1111

1212
- Added support for Liveness detection.
13-
- Added support for `person` and `dynamic_person_group` operations.
14-
- Added support for face recognition with `PersonDirectory` (`identify_from_person_directory()` and `identify_from_dynamic_person_group()`).
1513
- Asynchronous APIs are added under `azure.ai.vision.face.aio` namespace.
1614
- Authentication with Microsoft Entra ID is supported using `DefaultAzureCredential()` from `azure.identity`.
1715

1816
### Breaking Changes
1917

20-
- This library supports only the Azure AI Face v1.1-preview.1 API.
18+
- This library only supports the API of the the operation groups below of [Azure AI Face v1.1-preview.1](https://learn.microsoft.com/rest/api/face/operation-groups?view=rest-face-v1.1-preview.1):
19+
- Face Detection Operations
20+
- Face Recognition Operations: only `Find Similiar`, `Group` and `Verify Face To Face`.
21+
- Liveness Session Operations
2122
- The namespace/package name for Azure AI Face has changed from `azure.cognitiveservices.vision.face` to `azure.ai.vision.face`.
22-
- Three client design:
23-
- `FaceClient` to perform core Face functions such as face detection, recognition(identification and verification),
24-
finding similar faces and grouping faces.
25-
- `FaceAdministrationClient` to managed the following data structures that hold data on faces and persons for
26-
Face recognition, like `face_list`, `large_face_list`, `person_group`, `large_person_group`, `person` and
27-
`dynamic_person_group`.
23+
- Two client design:
24+
- `FaceClient` to perform core Face functions such as face detection, verification, finding similar faces and grouping faces.
2825
- `FaceSessionClient` to interact with sessions which is used for Liveness detection.
2926
- New function names that comply with [Azure Python SDK Design Guidelines](https://azure.github.io/azure-sdk/python_design.html):
3027
- For example, the method `person_group_person.create()` is changed to `create_person_group_person()`.

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

Lines changed: 0 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ 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)
109
- Find similar faces
1110
- Group faces
1211

@@ -130,33 +129,6 @@ face_client = FaceClient(endpoint, credential)
130129
- Finding similar faces from a smaller set of faces that look similar to the target face.
131130
- Grouping faces into several smaller groups based on similarity.
132131

133-
### FaceAdministrationClient
134-
135-
`FaceAdministrationClient` is provided to interact with the following data structures that hold data on faces and
136-
persons for Face recognition:
137-
138-
- `person`: It is a container that holds faces and is used by face recognition. It can either not belong to any group or be a member of multiple `dynamic_person_group` simultaneously.
139-
- Each person can have up to 248 faces, and the total number of persons can reach 75 million.
140-
- For [face verification][face_verification], call `verify_from_person_directory()`.
141-
- For [face identification][face_identification], training is not needed before calling `identify_from_person_directory()`.
142-
- See [Use the PersonDirectory structure][use_person_directory_structure] to get more information.
143-
- `dynamic_person_group`: It is a group that can hold several `person`, and is used by face identification.
144-
- The total `dynamic_person_group` is unlimited.
145-
- Training is not needed before calling `identify_from_dynamic_person_group()`.
146-
- See [Use the PersonDirectory structure][use_person_directory_structure] to get more information.
147-
- `face_list`: It is a list of faces and used by [find similar faces][find_similar] (call `find_similar_from_face_list()`).
148-
- It can up to 1,000 faces.
149-
- `large_face_list`: It is a list of faces which can hold more faces and used by [find similar faces][find_similar].
150-
- It can up to 1,000,000 faces.
151-
- Training (`begin_train_large_face_list()`) is required before calling `find_similar_from_large_face_list()`.
152-
- `person_group`: It is a container that store the uploaded person data, including their face recognition features, and is used by face recognition.
153-
- It can up to 10,000 persons, with each person capable of holding up to 248 faces.
154-
- For [face verification][face_verification], call `verify_from_person_group()`.
155-
- For [face identification][face_identification], training (`begin_train_person_group()`) is required before calling `identify_from_person_group()`.
156-
- `large_person_group`: It is a container which can hold more persons, and is used by face recognition.
157-
- It can up to 1,000,000 persons, with each person capable of holding up to 248 faces. The total persons in all `large_person_group` should not exceed 1,000,000,000.
158-
- For [face verification][face_verification], call `verify_from_large_person_group()`.
159-
- For [face identification][face_identification], training (`begin_train_large_person_group()`) is required before calling `identify_from_large_person_group()`.
160132

161133
### FaceSessionClient
162134

@@ -166,24 +138,12 @@ persons for Face recognition:
166138
- Query the liveness and verification result.
167139
- Query the audit result.
168140

169-
### Long-running operations
170-
171-
Long-running operations are operations which consist of an initial request sent to the service to start an operation,
172-
followed by polling the service at intervals to determine whether the operation has completed or failed, and if it has
173-
succeeded, to get the result.
174-
175-
Methods that train a group (LargeFaceList, PersonGroup or LargePersonGroup), create/delete a Person/DynamicPersonGroup,
176-
add a face or delete a face from a Person are modeled as long-running operations.
177-
The client exposes a `begin_<method-name>` method that returns an `LROPoller` or `AsyncLROPoller`. Callers should wait
178-
for the operation to complete by calling `result()` on the poller object returned from the `begin_<method-name>` method.
179-
Sample code snippets are provided to illustrate using long-running operations [below](#examples "Examples").
180141

181142
## Examples
182143

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

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

189149
### Face Detection
@@ -231,103 +191,6 @@ with FaceClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_c
231191
print(f"Face: {face.as_dict()}")
232192
```
233193

234-
### Face Recognition from LargePersonGroup
235-
Identify a face against a defined LargePersonGroup.
236-
237-
First, we have to use `FaceAdministrationClient` to create a `LargePersonGroup`, add a few `Person` to it,
238-
and then register faces with these `Person`.
239-
240-
```python
241-
from azure.core.credentials import AzureKeyCredential
242-
from azure.ai.vision.face import FaceAdministrationClient, FaceClient
243-
from azure.ai.vision.face.models import FaceDetectionModel, FaceRecognitionModel
244-
245-
246-
def read_file_content(file_path: str):
247-
with open(file_path, "rb") as fd:
248-
file_content = fd.read()
249-
250-
return file_content
251-
252-
253-
endpoint = "<your endpoint>"
254-
key = "<your api key>"
255-
256-
large_person_group_id = "lpg_family"
257-
258-
with FaceAdministrationClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_admin_client:
259-
print(f"Create a large person group with id: {large_person_group_id}")
260-
face_admin_client.create_large_person_group(
261-
large_person_group_id, name="My Family", recognition_model=FaceRecognitionModel.RECOGNITION_04
262-
)
263-
264-
print("Create a Person Bill and add a face to him.")
265-
bill_person_id = face_admin_client.create_large_person_group_person(
266-
large_person_group_id, name="Bill", user_data="Dad"
267-
).person_id
268-
bill_image_file_path = "./samples/images/Family1-Dad1.jpg"
269-
face_admin_client.add_large_person_group_person_face(
270-
large_person_group_id,
271-
bill_person_id,
272-
read_file_content(bill_image_file_path),
273-
detection_model=FaceDetectionModel.DETECTION_03,
274-
user_data="Dad-0001",
275-
)
276-
277-
print("Create a Person Clare and add a face to her.")
278-
clare_person_id = face_admin_client.create_large_person_group_person(
279-
large_person_group_id, name="Clare", user_data="Mom"
280-
).person_id
281-
clare_image_file_path = "./samples/images/Family1-Mom1.jpg"
282-
face_admin_client.add_large_person_group_person_face(
283-
large_person_group_id,
284-
clare_person_id,
285-
read_file_content(clare_image_file_path),
286-
detection_model=FaceDetectionModel.DETECTION_03,
287-
user_data="Mom-0001",
288-
)
289-
```
290-
291-
Before doing the identification, we need to train the LargePersonGroup first.
292-
```python
293-
print(f"Start to train the large person group: {large_person_group_id}.")
294-
poller = face_admin_client.begin_train_large_person_group(large_person_group_id)
295-
296-
# Wait for the train operation to be completed.
297-
# If the training status isn't succeed, an exception will be thrown from the poller.
298-
training_result = poller.result()
299-
```
300-
301-
When the training operation is completed successfully, we can identify the faces in this LargePersonGroup through
302-
`FaceClient`.
303-
```python
304-
with FaceClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_client:
305-
# Detect the face from the target image.
306-
target_image_file_path = "./samples/images/identification1.jpg"
307-
detect_result = face_client.detect(
308-
read_file_content(target_image_file_path),
309-
detection_model=FaceDetectionModel.DETECTION_03,
310-
recognition_model=FaceRecognitionModel.RECOGNITION_04,
311-
return_face_id=True,
312-
)
313-
target_face_ids = list(f.face_id for f in detect_result)
314-
315-
# Identify the faces in the large person group.
316-
result = face_client.identify_from_large_person_group(
317-
face_ids=target_face_ids, large_person_group_id=large_person_group_id
318-
)
319-
for idx, r in enumerate(result):
320-
print(f"----- Identification result: #{idx+1} -----")
321-
print(f"{r.as_dict()}")
322-
```
323-
324-
Finally, use `FaceAdministrationClient` to remove the large person group if you don't need it anymore.
325-
```python
326-
with FaceAdministrationClient(endpoint=endpoint, credential=AzureKeyCredential(key)) as face_admin_client:
327-
print(f"Delete the large person group: {large_person_group_id}")
328-
face_admin_client.delete_large_person_group(large_person_group_id)
329-
```
330-
331194
### Liveness detection
332195
Face Liveness detection can be used to determine if a face in an input video stream is real (live) or fake (spoof).
333196
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_6a3095279a"
5+
"Tag": "python/face/azure-ai-vision-face_f787b7aa30"
66
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
# --------------------------------------------------------------------------
88

99
from ._patch import FaceClient
10-
from ._client import FaceAdministrationClient
1110
from ._patch import FaceSessionClient
1211
from ._version import VERSION
1312

@@ -18,7 +17,6 @@
1817

1918
__all__ = [
2019
"FaceClient",
21-
"FaceAdministrationClient",
2220
"FaceSessionClient",
2321
]
2422

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

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,8 @@
1414
from azure.core.pipeline import policies
1515
from azure.core.rest import HttpRequest, HttpResponse
1616

17-
from ._configuration import (
18-
FaceAdministrationClientConfiguration,
19-
FaceClientConfiguration,
20-
FaceSessionClientConfiguration,
21-
)
22-
from ._operations import (
23-
FaceAdministrationClientOperationsMixin,
24-
FaceClientOperationsMixin,
25-
FaceSessionClientOperationsMixin,
26-
)
17+
from ._configuration import FaceClientConfiguration, FaceSessionClientConfiguration
18+
from ._operations import FaceClientOperationsMixin, FaceSessionClientOperationsMixin
2719
from ._serialization import Deserializer, Serializer
2820

2921
if TYPE_CHECKING:
@@ -110,89 +102,6 @@ def __exit__(self, *exc_details: Any) -> None:
110102
self._client.__exit__(*exc_details)
111103

112104

113-
class FaceAdministrationClient(
114-
FaceAdministrationClientOperationsMixin
115-
): # pylint: disable=client-accepts-api-version-keyword
116-
"""FaceAdministrationClient.
117-
118-
:param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
119-
https://{resource-name}.cognitiveservices.azure.com). Required.
120-
:type endpoint: str
121-
:param credential: Credential used to authenticate requests to the service. Is either a
122-
AzureKeyCredential type or a TokenCredential type. Required.
123-
:type credential: ~azure.core.credentials.AzureKeyCredential or
124-
~azure.core.credentials.TokenCredential
125-
:keyword api_version: API Version. Default value is "v1.1-preview.1". Note that overriding this
126-
default value may result in unsupported behavior.
127-
:paramtype api_version: str or ~azure.ai.vision.face.models.Versions
128-
:keyword int polling_interval: Default waiting time between two polls for LRO operations if no
129-
Retry-After header is present.
130-
"""
131-
132-
def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None:
133-
_endpoint = "{endpoint}/face/{apiVersion}"
134-
self._config = FaceAdministrationClientConfiguration(endpoint=endpoint, credential=credential, **kwargs)
135-
_policies = kwargs.pop("policies", None)
136-
if _policies is None:
137-
_policies = [
138-
policies.RequestIdPolicy(**kwargs),
139-
self._config.headers_policy,
140-
self._config.user_agent_policy,
141-
self._config.proxy_policy,
142-
policies.ContentDecodePolicy(**kwargs),
143-
self._config.redirect_policy,
144-
self._config.retry_policy,
145-
self._config.authentication_policy,
146-
self._config.custom_hook_policy,
147-
self._config.logging_policy,
148-
policies.DistributedTracingPolicy(**kwargs),
149-
policies.SensitiveHeaderCleanupPolicy(**kwargs) if self._config.redirect_policy else None,
150-
self._config.http_logging_policy,
151-
]
152-
self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs)
153-
154-
self._serialize = Serializer()
155-
self._deserialize = Deserializer()
156-
self._serialize.client_side_validation = False
157-
158-
def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse:
159-
"""Runs the network request through the client's chained policies.
160-
161-
>>> from azure.core.rest import HttpRequest
162-
>>> request = HttpRequest("GET", "https://www.example.org/")
163-
<HttpRequest [GET], url: 'https://www.example.org/'>
164-
>>> response = client.send_request(request)
165-
<HttpResponse: 200 OK>
166-
167-
For more information on this code flow, see https://aka.ms/azsdk/dpcodegen/python/send_request
168-
169-
:param request: The network request you want to make. Required.
170-
:type request: ~azure.core.rest.HttpRequest
171-
:keyword bool stream: Whether the response payload will be streamed. Defaults to False.
172-
:return: The response of your network call. Does not do error handling on your response.
173-
:rtype: ~azure.core.rest.HttpResponse
174-
"""
175-
176-
request_copy = deepcopy(request)
177-
path_format_arguments = {
178-
"endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
179-
"apiVersion": self._serialize.url("self._config.api_version", self._config.api_version, "str"),
180-
}
181-
182-
request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments)
183-
return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore
184-
185-
def close(self) -> None:
186-
self._client.close()
187-
188-
def __enter__(self) -> "FaceAdministrationClient":
189-
self._client.__enter__()
190-
return self
191-
192-
def __exit__(self, *exc_details: Any) -> None:
193-
self._client.__exit__(*exc_details)
194-
195-
196105
class FaceSessionClient(FaceSessionClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword
197106
"""FaceSessionClient.
198107

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

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -73,61 +73,6 @@ def _configure(self, **kwargs: Any) -> None:
7373
self.authentication_policy = self._infer_policy(**kwargs)
7474

7575

76-
class FaceAdministrationClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long
77-
"""Configuration for FaceAdministrationClient.
78-
79-
Note that all parameters used to create this instance are saved as instance
80-
attributes.
81-
82-
:param endpoint: Supported Cognitive Services endpoints (protocol and hostname, for example:
83-
https://{resource-name}.cognitiveservices.azure.com). Required.
84-
:type endpoint: str
85-
:param credential: Credential used to authenticate requests to the service. Is either a
86-
AzureKeyCredential type or a TokenCredential type. Required.
87-
:type credential: ~azure.core.credentials.AzureKeyCredential or
88-
~azure.core.credentials.TokenCredential
89-
:keyword api_version: API Version. Default value is "v1.1-preview.1". Note that overriding this
90-
default value may result in unsupported behavior.
91-
:paramtype api_version: str or ~azure.ai.vision.face.models.Versions
92-
"""
93-
94-
def __init__(self, endpoint: str, credential: Union[AzureKeyCredential, "TokenCredential"], **kwargs: Any) -> None:
95-
api_version: str = kwargs.pop("api_version", "v1.1-preview.1")
96-
97-
if endpoint is None:
98-
raise ValueError("Parameter 'endpoint' must not be None.")
99-
if credential is None:
100-
raise ValueError("Parameter 'credential' must not be None.")
101-
102-
self.endpoint = endpoint
103-
self.credential = credential
104-
self.api_version = api_version
105-
self.credential_scopes = kwargs.pop("credential_scopes", ["https://cognitiveservices.azure.com/.default"])
106-
kwargs.setdefault("sdk_moniker", "ai-vision-face/{}".format(VERSION))
107-
self.polling_interval = kwargs.get("polling_interval", 30)
108-
self._configure(**kwargs)
109-
110-
def _infer_policy(self, **kwargs):
111-
if isinstance(self.credential, AzureKeyCredential):
112-
return policies.AzureKeyCredentialPolicy(self.credential, "Ocp-Apim-Subscription-Key", **kwargs)
113-
if hasattr(self.credential, "get_token"):
114-
return policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs)
115-
raise TypeError(f"Unsupported credential: {self.credential}")
116-
117-
def _configure(self, **kwargs: Any) -> None:
118-
self.user_agent_policy = kwargs.get("user_agent_policy") or policies.UserAgentPolicy(**kwargs)
119-
self.headers_policy = kwargs.get("headers_policy") or policies.HeadersPolicy(**kwargs)
120-
self.proxy_policy = kwargs.get("proxy_policy") or policies.ProxyPolicy(**kwargs)
121-
self.logging_policy = kwargs.get("logging_policy") or policies.NetworkTraceLoggingPolicy(**kwargs)
122-
self.http_logging_policy = kwargs.get("http_logging_policy") or policies.HttpLoggingPolicy(**kwargs)
123-
self.custom_hook_policy = kwargs.get("custom_hook_policy") or policies.CustomHookPolicy(**kwargs)
124-
self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs)
125-
self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs)
126-
self.authentication_policy = kwargs.get("authentication_policy")
127-
if self.credential and not self.authentication_policy:
128-
self.authentication_policy = self._infer_policy(**kwargs)
129-
130-
13176
class FaceSessionClientConfiguration: # pylint: disable=too-many-instance-attributes,name-too-long
13277
"""Configuration for FaceSessionClient.
13378

0 commit comments

Comments
 (0)