google-cloud-modelarmor 0.2.8__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {google_cloud_modelarmor-0.2.8/google_cloud_modelarmor.egg-info → google_cloud_modelarmor-0.4.0}/PKG-INFO +5 -2
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/README.rst +1 -1
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor/gapic_version.py +1 -1
- google_cloud_modelarmor-0.4.0/google/cloud/modelarmor_v1/__init__.py +222 -0
- {google_cloud_modelarmor-0.2.8/google/cloud/modelarmor_v1beta → google_cloud_modelarmor-0.4.0/google/cloud/modelarmor_v1}/gapic_version.py +1 -1
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/client.py +32 -14
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/transports/base.py +3 -2
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/transports/grpc.py +5 -3
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/transports/grpc_asyncio.py +5 -3
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/transports/rest.py +3 -2
- google_cloud_modelarmor-0.4.0/google/cloud/modelarmor_v1beta/__init__.py +222 -0
- {google_cloud_modelarmor-0.2.8/google/cloud/modelarmor_v1 → google_cloud_modelarmor-0.4.0/google/cloud/modelarmor_v1beta}/gapic_version.py +1 -1
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/client.py +32 -14
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/transports/base.py +3 -2
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/transports/grpc.py +5 -3
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/transports/grpc_asyncio.py +5 -3
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/transports/rest.py +3 -2
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0/google_cloud_modelarmor.egg-info}/PKG-INFO +5 -2
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google_cloud_modelarmor.egg-info/requires.txt +4 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/setup.py +3 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/unit/gapic/modelarmor_v1/test_model_armor.py +226 -29
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/unit/gapic/modelarmor_v1beta/test_model_armor.py +226 -29
- google_cloud_modelarmor-0.2.8/google/cloud/modelarmor_v1/__init__.py +0 -118
- google_cloud_modelarmor-0.2.8/google/cloud/modelarmor_v1beta/__init__.py +0 -118
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/LICENSE +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/MANIFEST.in +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor/py.typed +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/gapic_metadata.json +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/py.typed +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/async_client.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/pagers.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/transports/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/services/model_armor/transports/rest_base.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/types/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1/types/service.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/gapic_metadata.json +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/py.typed +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/async_client.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/pagers.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/transports/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/services/model_armor/transports/rest_base.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/types/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google/cloud/modelarmor_v1beta/types/service.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google_cloud_modelarmor.egg-info/SOURCES.txt +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google_cloud_modelarmor.egg-info/dependency_links.txt +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google_cloud_modelarmor.egg-info/not-zip-safe +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/google_cloud_modelarmor.egg-info/top_level.txt +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/setup.cfg +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/unit/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/unit/gapic/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/unit/gapic/modelarmor_v1/__init__.py +0 -0
- {google_cloud_modelarmor-0.2.8 → google_cloud_modelarmor-0.4.0}/tests/unit/gapic/modelarmor_v1beta/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: google-cloud-modelarmor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Google Cloud Modelarmor API client library
|
|
5
5
|
Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-cloud-modelarmor
|
|
6
6
|
Author: Google LLC
|
|
@@ -19,12 +19,15 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: Operating System :: OS Independent
|
|
23
24
|
Classifier: Topic :: Internet
|
|
24
25
|
Requires-Python: >=3.7
|
|
25
26
|
License-File: LICENSE
|
|
26
27
|
Requires-Dist: google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0,>=1.34.1
|
|
27
28
|
Requires-Dist: google-auth!=2.24.0,!=2.25.0,<3.0.0,>=2.14.1
|
|
29
|
+
Requires-Dist: grpcio<2.0.0,>=1.33.2
|
|
30
|
+
Requires-Dist: grpcio<2.0.0,>=1.75.1; python_version >= "3.14"
|
|
28
31
|
Requires-Dist: proto-plus<2.0.0,>=1.22.3
|
|
29
32
|
Requires-Dist: proto-plus<2.0.0,>=1.25.0; python_version >= "3.13"
|
|
30
33
|
Requires-Dist: protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<7.0.0,>=3.20.2
|
|
@@ -103,7 +106,7 @@ Supported Python Versions
|
|
|
103
106
|
Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of
|
|
104
107
|
Python.
|
|
105
108
|
|
|
106
|
-
Python >= 3.7
|
|
109
|
+
Python >= 3.7, including 3.14
|
|
107
110
|
|
|
108
111
|
.. _active: https://devguide.python.org/devcycle/#in-development-main-branch
|
|
109
112
|
.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches
|
|
@@ -61,7 +61,7 @@ Supported Python Versions
|
|
|
61
61
|
Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of
|
|
62
62
|
Python.
|
|
63
63
|
|
|
64
|
-
Python >= 3.7
|
|
64
|
+
Python >= 3.7, including 3.14
|
|
65
65
|
|
|
66
66
|
.. _active: https://devguide.python.org/devcycle/#in-development-main-branch
|
|
67
67
|
.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright 2025 Google LLC
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
import google.api_core as api_core
|
|
19
|
+
|
|
20
|
+
from google.cloud.modelarmor_v1 import gapic_version as package_version
|
|
21
|
+
|
|
22
|
+
__version__ = package_version.__version__
|
|
23
|
+
|
|
24
|
+
if sys.version_info >= (3, 8): # pragma: NO COVER
|
|
25
|
+
from importlib import metadata
|
|
26
|
+
else: # pragma: NO COVER
|
|
27
|
+
# TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
|
|
28
|
+
# this code path once we drop support for Python 3.7
|
|
29
|
+
import importlib_metadata as metadata
|
|
30
|
+
|
|
31
|
+
from .services.model_armor import ModelArmorAsyncClient, ModelArmorClient
|
|
32
|
+
from .types.service import (
|
|
33
|
+
AiPlatformFloorSetting,
|
|
34
|
+
ByteDataItem,
|
|
35
|
+
CreateTemplateRequest,
|
|
36
|
+
CsamFilterResult,
|
|
37
|
+
DataItem,
|
|
38
|
+
DeleteTemplateRequest,
|
|
39
|
+
DetectionConfidenceLevel,
|
|
40
|
+
FilterConfig,
|
|
41
|
+
FilterExecutionState,
|
|
42
|
+
FilterMatchState,
|
|
43
|
+
FilterResult,
|
|
44
|
+
FloorSetting,
|
|
45
|
+
GetFloorSettingRequest,
|
|
46
|
+
GetTemplateRequest,
|
|
47
|
+
InvocationResult,
|
|
48
|
+
ListTemplatesRequest,
|
|
49
|
+
ListTemplatesResponse,
|
|
50
|
+
MaliciousUriFilterResult,
|
|
51
|
+
MaliciousUriFilterSettings,
|
|
52
|
+
MessageItem,
|
|
53
|
+
MultiLanguageDetectionMetadata,
|
|
54
|
+
PiAndJailbreakFilterResult,
|
|
55
|
+
PiAndJailbreakFilterSettings,
|
|
56
|
+
RaiFilterResult,
|
|
57
|
+
RaiFilterSettings,
|
|
58
|
+
RaiFilterType,
|
|
59
|
+
RangeInfo,
|
|
60
|
+
SanitizationResult,
|
|
61
|
+
SanitizeModelResponseRequest,
|
|
62
|
+
SanitizeModelResponseResponse,
|
|
63
|
+
SanitizeUserPromptRequest,
|
|
64
|
+
SanitizeUserPromptResponse,
|
|
65
|
+
SdpAdvancedConfig,
|
|
66
|
+
SdpBasicConfig,
|
|
67
|
+
SdpDeidentifyResult,
|
|
68
|
+
SdpFilterResult,
|
|
69
|
+
SdpFilterSettings,
|
|
70
|
+
SdpFinding,
|
|
71
|
+
SdpFindingLikelihood,
|
|
72
|
+
SdpInspectResult,
|
|
73
|
+
Template,
|
|
74
|
+
UpdateFloorSettingRequest,
|
|
75
|
+
UpdateTemplateRequest,
|
|
76
|
+
VirusDetail,
|
|
77
|
+
VirusScanFilterResult,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if hasattr(api_core, "check_python_version") and hasattr(
|
|
81
|
+
api_core, "check_dependency_versions"
|
|
82
|
+
): # pragma: NO COVER
|
|
83
|
+
api_core.check_python_version("google.cloud.modelarmor_v1") # type: ignore
|
|
84
|
+
api_core.check_dependency_versions("google.cloud.modelarmor_v1") # type: ignore
|
|
85
|
+
else: # pragma: NO COVER
|
|
86
|
+
# An older version of api_core is installed which does not define the
|
|
87
|
+
# functions above. We do equivalent checks manually.
|
|
88
|
+
try:
|
|
89
|
+
import sys
|
|
90
|
+
import warnings
|
|
91
|
+
|
|
92
|
+
_py_version_str = sys.version.split()[0]
|
|
93
|
+
_package_label = "google.cloud.modelarmor_v1"
|
|
94
|
+
if sys.version_info < (3, 9):
|
|
95
|
+
warnings.warn(
|
|
96
|
+
"You are using a non-supported Python version "
|
|
97
|
+
+ f"({_py_version_str}). Google will not post any further "
|
|
98
|
+
+ f"updates to {_package_label} supporting this Python version. "
|
|
99
|
+
+ "Please upgrade to the latest Python version, or at "
|
|
100
|
+
+ f"least to Python 3.9, and then update {_package_label}.",
|
|
101
|
+
FutureWarning,
|
|
102
|
+
)
|
|
103
|
+
if sys.version_info[:2] == (3, 9):
|
|
104
|
+
warnings.warn(
|
|
105
|
+
f"You are using a Python version ({_py_version_str}) "
|
|
106
|
+
+ f"which Google will stop supporting in {_package_label} in "
|
|
107
|
+
+ "January 2026. Please "
|
|
108
|
+
+ "upgrade to the latest Python version, or at "
|
|
109
|
+
+ "least to Python 3.10, before then, and "
|
|
110
|
+
+ f"then update {_package_label}.",
|
|
111
|
+
FutureWarning,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def parse_version_to_tuple(version_string: str):
|
|
115
|
+
"""Safely converts a semantic version string to a comparable tuple of integers.
|
|
116
|
+
Example: "4.25.8" -> (4, 25, 8)
|
|
117
|
+
Ignores non-numeric parts and handles common version formats.
|
|
118
|
+
Args:
|
|
119
|
+
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
|
|
120
|
+
Returns:
|
|
121
|
+
Tuple of integers for the parsed version string.
|
|
122
|
+
"""
|
|
123
|
+
parts = []
|
|
124
|
+
for part in version_string.split("."):
|
|
125
|
+
try:
|
|
126
|
+
parts.append(int(part))
|
|
127
|
+
except ValueError:
|
|
128
|
+
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
|
|
129
|
+
# This is a simplification compared to 'packaging.parse_version', but sufficient
|
|
130
|
+
# for comparing strictly numeric semantic versions.
|
|
131
|
+
break
|
|
132
|
+
return tuple(parts)
|
|
133
|
+
|
|
134
|
+
def _get_version(dependency_name):
|
|
135
|
+
try:
|
|
136
|
+
version_string: str = metadata.version(dependency_name)
|
|
137
|
+
parsed_version = parse_version_to_tuple(version_string)
|
|
138
|
+
return (parsed_version, version_string)
|
|
139
|
+
except Exception:
|
|
140
|
+
# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
|
|
141
|
+
# or errors during parse_version_to_tuple
|
|
142
|
+
return (None, "--")
|
|
143
|
+
|
|
144
|
+
_dependency_package = "google.protobuf"
|
|
145
|
+
_next_supported_version = "4.25.8"
|
|
146
|
+
_next_supported_version_tuple = (4, 25, 8)
|
|
147
|
+
_recommendation = " (we recommend 6.x)"
|
|
148
|
+
(_version_used, _version_used_string) = _get_version(_dependency_package)
|
|
149
|
+
if _version_used and _version_used < _next_supported_version_tuple:
|
|
150
|
+
warnings.warn(
|
|
151
|
+
f"Package {_package_label} depends on "
|
|
152
|
+
+ f"{_dependency_package}, currently installed at version "
|
|
153
|
+
+ f"{_version_used_string}. Future updates to "
|
|
154
|
+
+ f"{_package_label} will require {_dependency_package} at "
|
|
155
|
+
+ f"version {_next_supported_version} or higher{_recommendation}."
|
|
156
|
+
+ " Please ensure "
|
|
157
|
+
+ "that either (a) your Python environment doesn't pin the "
|
|
158
|
+
+ f"version of {_dependency_package}, so that updates to "
|
|
159
|
+
+ f"{_package_label} can require the higher version, or "
|
|
160
|
+
+ "(b) you manually update your Python environment to use at "
|
|
161
|
+
+ f"least version {_next_supported_version} of "
|
|
162
|
+
+ f"{_dependency_package}.",
|
|
163
|
+
FutureWarning,
|
|
164
|
+
)
|
|
165
|
+
except Exception:
|
|
166
|
+
warnings.warn(
|
|
167
|
+
"Could not determine the version of Python "
|
|
168
|
+
+ "currently being used. To continue receiving "
|
|
169
|
+
+ "updates for {_package_label}, ensure you are "
|
|
170
|
+
+ "using a supported version of Python; see "
|
|
171
|
+
+ "https://devguide.python.org/versions/"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
__all__ = (
|
|
175
|
+
"ModelArmorAsyncClient",
|
|
176
|
+
"AiPlatformFloorSetting",
|
|
177
|
+
"ByteDataItem",
|
|
178
|
+
"CreateTemplateRequest",
|
|
179
|
+
"CsamFilterResult",
|
|
180
|
+
"DataItem",
|
|
181
|
+
"DeleteTemplateRequest",
|
|
182
|
+
"DetectionConfidenceLevel",
|
|
183
|
+
"FilterConfig",
|
|
184
|
+
"FilterExecutionState",
|
|
185
|
+
"FilterMatchState",
|
|
186
|
+
"FilterResult",
|
|
187
|
+
"FloorSetting",
|
|
188
|
+
"GetFloorSettingRequest",
|
|
189
|
+
"GetTemplateRequest",
|
|
190
|
+
"InvocationResult",
|
|
191
|
+
"ListTemplatesRequest",
|
|
192
|
+
"ListTemplatesResponse",
|
|
193
|
+
"MaliciousUriFilterResult",
|
|
194
|
+
"MaliciousUriFilterSettings",
|
|
195
|
+
"MessageItem",
|
|
196
|
+
"ModelArmorClient",
|
|
197
|
+
"MultiLanguageDetectionMetadata",
|
|
198
|
+
"PiAndJailbreakFilterResult",
|
|
199
|
+
"PiAndJailbreakFilterSettings",
|
|
200
|
+
"RaiFilterResult",
|
|
201
|
+
"RaiFilterSettings",
|
|
202
|
+
"RaiFilterType",
|
|
203
|
+
"RangeInfo",
|
|
204
|
+
"SanitizationResult",
|
|
205
|
+
"SanitizeModelResponseRequest",
|
|
206
|
+
"SanitizeModelResponseResponse",
|
|
207
|
+
"SanitizeUserPromptRequest",
|
|
208
|
+
"SanitizeUserPromptResponse",
|
|
209
|
+
"SdpAdvancedConfig",
|
|
210
|
+
"SdpBasicConfig",
|
|
211
|
+
"SdpDeidentifyResult",
|
|
212
|
+
"SdpFilterResult",
|
|
213
|
+
"SdpFilterSettings",
|
|
214
|
+
"SdpFinding",
|
|
215
|
+
"SdpFindingLikelihood",
|
|
216
|
+
"SdpInspectResult",
|
|
217
|
+
"Template",
|
|
218
|
+
"UpdateFloorSettingRequest",
|
|
219
|
+
"UpdateTemplateRequest",
|
|
220
|
+
"VirusDetail",
|
|
221
|
+
"VirusScanFilterResult",
|
|
222
|
+
)
|
|
@@ -151,6 +151,34 @@ class ModelArmorClient(metaclass=ModelArmorClientMeta):
|
|
|
151
151
|
_DEFAULT_ENDPOINT_TEMPLATE = "modelarmor.{UNIVERSE_DOMAIN}"
|
|
152
152
|
_DEFAULT_UNIVERSE = "googleapis.com"
|
|
153
153
|
|
|
154
|
+
@staticmethod
|
|
155
|
+
def _use_client_cert_effective():
|
|
156
|
+
"""Returns whether client certificate should be used for mTLS if the
|
|
157
|
+
google-auth version supports should_use_client_cert automatic mTLS enablement.
|
|
158
|
+
|
|
159
|
+
Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
bool: whether client certificate should be used for mTLS
|
|
163
|
+
Raises:
|
|
164
|
+
ValueError: (If using a version of google-auth without should_use_client_cert and
|
|
165
|
+
GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
|
|
166
|
+
"""
|
|
167
|
+
# check if google-auth version supports should_use_client_cert for automatic mTLS enablement
|
|
168
|
+
if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
|
|
169
|
+
return mtls.should_use_client_cert()
|
|
170
|
+
else: # pragma: NO COVER
|
|
171
|
+
# if unsupported, fallback to reading from env var
|
|
172
|
+
use_client_cert_str = os.getenv(
|
|
173
|
+
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
|
|
174
|
+
).lower()
|
|
175
|
+
if use_client_cert_str not in ("true", "false"):
|
|
176
|
+
raise ValueError(
|
|
177
|
+
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
|
|
178
|
+
" either `true` or `false`"
|
|
179
|
+
)
|
|
180
|
+
return use_client_cert_str == "true"
|
|
181
|
+
|
|
154
182
|
@classmethod
|
|
155
183
|
def from_service_account_info(cls, info: dict, *args, **kwargs):
|
|
156
184
|
"""Creates an instance of this client using the provided credentials
|
|
@@ -358,12 +386,8 @@ class ModelArmorClient(metaclass=ModelArmorClientMeta):
|
|
|
358
386
|
)
|
|
359
387
|
if client_options is None:
|
|
360
388
|
client_options = client_options_lib.ClientOptions()
|
|
361
|
-
use_client_cert =
|
|
389
|
+
use_client_cert = ModelArmorClient._use_client_cert_effective()
|
|
362
390
|
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
|
|
363
|
-
if use_client_cert not in ("true", "false"):
|
|
364
|
-
raise ValueError(
|
|
365
|
-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
|
|
366
|
-
)
|
|
367
391
|
if use_mtls_endpoint not in ("auto", "never", "always"):
|
|
368
392
|
raise MutualTLSChannelError(
|
|
369
393
|
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
|
|
@@ -371,7 +395,7 @@ class ModelArmorClient(metaclass=ModelArmorClientMeta):
|
|
|
371
395
|
|
|
372
396
|
# Figure out the client cert source to use.
|
|
373
397
|
client_cert_source = None
|
|
374
|
-
if use_client_cert
|
|
398
|
+
if use_client_cert:
|
|
375
399
|
if client_options.client_cert_source:
|
|
376
400
|
client_cert_source = client_options.client_cert_source
|
|
377
401
|
elif mtls.has_default_client_cert_source():
|
|
@@ -403,20 +427,14 @@ class ModelArmorClient(metaclass=ModelArmorClientMeta):
|
|
|
403
427
|
google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
|
|
404
428
|
is not any of ["auto", "never", "always"].
|
|
405
429
|
"""
|
|
406
|
-
use_client_cert =
|
|
407
|
-
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
|
|
408
|
-
).lower()
|
|
430
|
+
use_client_cert = ModelArmorClient._use_client_cert_effective()
|
|
409
431
|
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
|
|
410
432
|
universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
|
|
411
|
-
if use_client_cert not in ("true", "false"):
|
|
412
|
-
raise ValueError(
|
|
413
|
-
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
|
|
414
|
-
)
|
|
415
433
|
if use_mtls_endpoint not in ("auto", "never", "always"):
|
|
416
434
|
raise MutualTLSChannelError(
|
|
417
435
|
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
|
|
418
436
|
)
|
|
419
|
-
return use_client_cert
|
|
437
|
+
return use_client_cert, use_mtls_endpoint, universe_domain_env
|
|
420
438
|
|
|
421
439
|
@staticmethod
|
|
422
440
|
def _get_client_cert_source(provided_cert_source, use_cert_flag):
|
|
@@ -68,9 +68,10 @@ class ModelArmorTransport(abc.ABC):
|
|
|
68
68
|
credentials identify the application to the service; if none
|
|
69
69
|
are specified, the client will attempt to ascertain the
|
|
70
70
|
credentials from the environment.
|
|
71
|
-
credentials_file (Optional[str]): A file with credentials that can
|
|
71
|
+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
|
|
72
72
|
be loaded with :func:`google.auth.load_credentials_from_file`.
|
|
73
|
-
This argument is mutually exclusive with credentials.
|
|
73
|
+
This argument is mutually exclusive with credentials. This argument will be
|
|
74
|
+
removed in the next major version of this library.
|
|
74
75
|
scopes (Optional[Sequence[str]]): A list of scopes.
|
|
75
76
|
quota_project_id (Optional[str]): An optional project to use for billing
|
|
76
77
|
and quota.
|
|
@@ -152,9 +152,10 @@ class ModelArmorGrpcTransport(ModelArmorTransport):
|
|
|
152
152
|
are specified, the client will attempt to ascertain the
|
|
153
153
|
credentials from the environment.
|
|
154
154
|
This argument is ignored if a ``channel`` instance is provided.
|
|
155
|
-
credentials_file (Optional[str]): A file with credentials that can
|
|
155
|
+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
|
|
156
156
|
be loaded with :func:`google.auth.load_credentials_from_file`.
|
|
157
157
|
This argument is ignored if a ``channel`` instance is provided.
|
|
158
|
+
This argument will be removed in the next major version of this library.
|
|
158
159
|
scopes (Optional(Sequence[str])): A list of scopes. This argument is
|
|
159
160
|
ignored if a ``channel`` instance is provided.
|
|
160
161
|
channel (Optional[Union[grpc.Channel, Callable[..., grpc.Channel]]]):
|
|
@@ -287,9 +288,10 @@ class ModelArmorGrpcTransport(ModelArmorTransport):
|
|
|
287
288
|
credentials identify this application to the service. If
|
|
288
289
|
none are specified, the client will attempt to ascertain
|
|
289
290
|
the credentials from the environment.
|
|
290
|
-
credentials_file (Optional[str]): A file with credentials that can
|
|
291
|
+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
|
|
291
292
|
be loaded with :func:`google.auth.load_credentials_from_file`.
|
|
292
|
-
This argument is mutually exclusive with credentials.
|
|
293
|
+
This argument is mutually exclusive with credentials. This argument will be
|
|
294
|
+
removed in the next major version of this library.
|
|
293
295
|
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
|
|
294
296
|
service. These are only used when credentials are not specified and
|
|
295
297
|
are passed to :func:`google.auth.default`.
|
|
@@ -149,8 +149,9 @@ class ModelArmorGrpcAsyncIOTransport(ModelArmorTransport):
|
|
|
149
149
|
credentials identify this application to the service. If
|
|
150
150
|
none are specified, the client will attempt to ascertain
|
|
151
151
|
the credentials from the environment.
|
|
152
|
-
credentials_file (Optional[str]): A file with credentials that can
|
|
153
|
-
be loaded with :func:`google.auth.load_credentials_from_file`.
|
|
152
|
+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
|
|
153
|
+
be loaded with :func:`google.auth.load_credentials_from_file`. This argument will be
|
|
154
|
+
removed in the next major version of this library.
|
|
154
155
|
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
|
|
155
156
|
service. These are only used when credentials are not specified and
|
|
156
157
|
are passed to :func:`google.auth.default`.
|
|
@@ -201,9 +202,10 @@ class ModelArmorGrpcAsyncIOTransport(ModelArmorTransport):
|
|
|
201
202
|
are specified, the client will attempt to ascertain the
|
|
202
203
|
credentials from the environment.
|
|
203
204
|
This argument is ignored if a ``channel`` instance is provided.
|
|
204
|
-
credentials_file (Optional[str]): A file with credentials that can
|
|
205
|
+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
|
|
205
206
|
be loaded with :func:`google.auth.load_credentials_from_file`.
|
|
206
207
|
This argument is ignored if a ``channel`` instance is provided.
|
|
208
|
+
This argument will be removed in the next major version of this library.
|
|
207
209
|
scopes (Optional[Sequence[str]]): A optional list of scopes needed for this
|
|
208
210
|
service. These are only used when credentials are not specified and
|
|
209
211
|
are passed to :func:`google.auth.default`.
|
|
@@ -628,9 +628,10 @@ class ModelArmorRestTransport(_BaseModelArmorRestTransport):
|
|
|
628
628
|
are specified, the client will attempt to ascertain the
|
|
629
629
|
credentials from the environment.
|
|
630
630
|
|
|
631
|
-
credentials_file (Optional[str]): A file with credentials that can
|
|
631
|
+
credentials_file (Optional[str]): Deprecated. A file with credentials that can
|
|
632
632
|
be loaded with :func:`google.auth.load_credentials_from_file`.
|
|
633
|
-
This argument is ignored if ``channel`` is provided.
|
|
633
|
+
This argument is ignored if ``channel`` is provided. This argument will be
|
|
634
|
+
removed in the next major version of this library.
|
|
634
635
|
scopes (Optional(Sequence[str])): A list of scopes. This argument is
|
|
635
636
|
ignored if ``channel`` is provided.
|
|
636
637
|
client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright 2025 Google LLC
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
import google.api_core as api_core
|
|
19
|
+
|
|
20
|
+
from google.cloud.modelarmor_v1beta import gapic_version as package_version
|
|
21
|
+
|
|
22
|
+
__version__ = package_version.__version__
|
|
23
|
+
|
|
24
|
+
if sys.version_info >= (3, 8): # pragma: NO COVER
|
|
25
|
+
from importlib import metadata
|
|
26
|
+
else: # pragma: NO COVER
|
|
27
|
+
# TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
|
|
28
|
+
# this code path once we drop support for Python 3.7
|
|
29
|
+
import importlib_metadata as metadata
|
|
30
|
+
|
|
31
|
+
from .services.model_armor import ModelArmorAsyncClient, ModelArmorClient
|
|
32
|
+
from .types.service import (
|
|
33
|
+
AiPlatformFloorSetting,
|
|
34
|
+
ByteDataItem,
|
|
35
|
+
CreateTemplateRequest,
|
|
36
|
+
CsamFilterResult,
|
|
37
|
+
DataItem,
|
|
38
|
+
DeleteTemplateRequest,
|
|
39
|
+
DetectionConfidenceLevel,
|
|
40
|
+
FilterConfig,
|
|
41
|
+
FilterExecutionState,
|
|
42
|
+
FilterMatchState,
|
|
43
|
+
FilterResult,
|
|
44
|
+
FloorSetting,
|
|
45
|
+
GetFloorSettingRequest,
|
|
46
|
+
GetTemplateRequest,
|
|
47
|
+
InvocationResult,
|
|
48
|
+
ListTemplatesRequest,
|
|
49
|
+
ListTemplatesResponse,
|
|
50
|
+
MaliciousUriFilterResult,
|
|
51
|
+
MaliciousUriFilterSettings,
|
|
52
|
+
MessageItem,
|
|
53
|
+
MultiLanguageDetectionMetadata,
|
|
54
|
+
PiAndJailbreakFilterResult,
|
|
55
|
+
PiAndJailbreakFilterSettings,
|
|
56
|
+
RaiFilterResult,
|
|
57
|
+
RaiFilterSettings,
|
|
58
|
+
RaiFilterType,
|
|
59
|
+
RangeInfo,
|
|
60
|
+
SanitizationResult,
|
|
61
|
+
SanitizeModelResponseRequest,
|
|
62
|
+
SanitizeModelResponseResponse,
|
|
63
|
+
SanitizeUserPromptRequest,
|
|
64
|
+
SanitizeUserPromptResponse,
|
|
65
|
+
SdpAdvancedConfig,
|
|
66
|
+
SdpBasicConfig,
|
|
67
|
+
SdpDeidentifyResult,
|
|
68
|
+
SdpFilterResult,
|
|
69
|
+
SdpFilterSettings,
|
|
70
|
+
SdpFinding,
|
|
71
|
+
SdpFindingLikelihood,
|
|
72
|
+
SdpInspectResult,
|
|
73
|
+
Template,
|
|
74
|
+
UpdateFloorSettingRequest,
|
|
75
|
+
UpdateTemplateRequest,
|
|
76
|
+
VirusDetail,
|
|
77
|
+
VirusScanFilterResult,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if hasattr(api_core, "check_python_version") and hasattr(
|
|
81
|
+
api_core, "check_dependency_versions"
|
|
82
|
+
): # pragma: NO COVER
|
|
83
|
+
api_core.check_python_version("google.cloud.modelarmor_v1beta") # type: ignore
|
|
84
|
+
api_core.check_dependency_versions("google.cloud.modelarmor_v1beta") # type: ignore
|
|
85
|
+
else: # pragma: NO COVER
|
|
86
|
+
# An older version of api_core is installed which does not define the
|
|
87
|
+
# functions above. We do equivalent checks manually.
|
|
88
|
+
try:
|
|
89
|
+
import sys
|
|
90
|
+
import warnings
|
|
91
|
+
|
|
92
|
+
_py_version_str = sys.version.split()[0]
|
|
93
|
+
_package_label = "google.cloud.modelarmor_v1beta"
|
|
94
|
+
if sys.version_info < (3, 9):
|
|
95
|
+
warnings.warn(
|
|
96
|
+
"You are using a non-supported Python version "
|
|
97
|
+
+ f"({_py_version_str}). Google will not post any further "
|
|
98
|
+
+ f"updates to {_package_label} supporting this Python version. "
|
|
99
|
+
+ "Please upgrade to the latest Python version, or at "
|
|
100
|
+
+ f"least to Python 3.9, and then update {_package_label}.",
|
|
101
|
+
FutureWarning,
|
|
102
|
+
)
|
|
103
|
+
if sys.version_info[:2] == (3, 9):
|
|
104
|
+
warnings.warn(
|
|
105
|
+
f"You are using a Python version ({_py_version_str}) "
|
|
106
|
+
+ f"which Google will stop supporting in {_package_label} in "
|
|
107
|
+
+ "January 2026. Please "
|
|
108
|
+
+ "upgrade to the latest Python version, or at "
|
|
109
|
+
+ "least to Python 3.10, before then, and "
|
|
110
|
+
+ f"then update {_package_label}.",
|
|
111
|
+
FutureWarning,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def parse_version_to_tuple(version_string: str):
|
|
115
|
+
"""Safely converts a semantic version string to a comparable tuple of integers.
|
|
116
|
+
Example: "4.25.8" -> (4, 25, 8)
|
|
117
|
+
Ignores non-numeric parts and handles common version formats.
|
|
118
|
+
Args:
|
|
119
|
+
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
|
|
120
|
+
Returns:
|
|
121
|
+
Tuple of integers for the parsed version string.
|
|
122
|
+
"""
|
|
123
|
+
parts = []
|
|
124
|
+
for part in version_string.split("."):
|
|
125
|
+
try:
|
|
126
|
+
parts.append(int(part))
|
|
127
|
+
except ValueError:
|
|
128
|
+
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
|
|
129
|
+
# This is a simplification compared to 'packaging.parse_version', but sufficient
|
|
130
|
+
# for comparing strictly numeric semantic versions.
|
|
131
|
+
break
|
|
132
|
+
return tuple(parts)
|
|
133
|
+
|
|
134
|
+
def _get_version(dependency_name):
|
|
135
|
+
try:
|
|
136
|
+
version_string: str = metadata.version(dependency_name)
|
|
137
|
+
parsed_version = parse_version_to_tuple(version_string)
|
|
138
|
+
return (parsed_version, version_string)
|
|
139
|
+
except Exception:
|
|
140
|
+
# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
|
|
141
|
+
# or errors during parse_version_to_tuple
|
|
142
|
+
return (None, "--")
|
|
143
|
+
|
|
144
|
+
_dependency_package = "google.protobuf"
|
|
145
|
+
_next_supported_version = "4.25.8"
|
|
146
|
+
_next_supported_version_tuple = (4, 25, 8)
|
|
147
|
+
_recommendation = " (we recommend 6.x)"
|
|
148
|
+
(_version_used, _version_used_string) = _get_version(_dependency_package)
|
|
149
|
+
if _version_used and _version_used < _next_supported_version_tuple:
|
|
150
|
+
warnings.warn(
|
|
151
|
+
f"Package {_package_label} depends on "
|
|
152
|
+
+ f"{_dependency_package}, currently installed at version "
|
|
153
|
+
+ f"{_version_used_string}. Future updates to "
|
|
154
|
+
+ f"{_package_label} will require {_dependency_package} at "
|
|
155
|
+
+ f"version {_next_supported_version} or higher{_recommendation}."
|
|
156
|
+
+ " Please ensure "
|
|
157
|
+
+ "that either (a) your Python environment doesn't pin the "
|
|
158
|
+
+ f"version of {_dependency_package}, so that updates to "
|
|
159
|
+
+ f"{_package_label} can require the higher version, or "
|
|
160
|
+
+ "(b) you manually update your Python environment to use at "
|
|
161
|
+
+ f"least version {_next_supported_version} of "
|
|
162
|
+
+ f"{_dependency_package}.",
|
|
163
|
+
FutureWarning,
|
|
164
|
+
)
|
|
165
|
+
except Exception:
|
|
166
|
+
warnings.warn(
|
|
167
|
+
"Could not determine the version of Python "
|
|
168
|
+
+ "currently being used. To continue receiving "
|
|
169
|
+
+ "updates for {_package_label}, ensure you are "
|
|
170
|
+
+ "using a supported version of Python; see "
|
|
171
|
+
+ "https://devguide.python.org/versions/"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
__all__ = (
|
|
175
|
+
"ModelArmorAsyncClient",
|
|
176
|
+
"AiPlatformFloorSetting",
|
|
177
|
+
"ByteDataItem",
|
|
178
|
+
"CreateTemplateRequest",
|
|
179
|
+
"CsamFilterResult",
|
|
180
|
+
"DataItem",
|
|
181
|
+
"DeleteTemplateRequest",
|
|
182
|
+
"DetectionConfidenceLevel",
|
|
183
|
+
"FilterConfig",
|
|
184
|
+
"FilterExecutionState",
|
|
185
|
+
"FilterMatchState",
|
|
186
|
+
"FilterResult",
|
|
187
|
+
"FloorSetting",
|
|
188
|
+
"GetFloorSettingRequest",
|
|
189
|
+
"GetTemplateRequest",
|
|
190
|
+
"InvocationResult",
|
|
191
|
+
"ListTemplatesRequest",
|
|
192
|
+
"ListTemplatesResponse",
|
|
193
|
+
"MaliciousUriFilterResult",
|
|
194
|
+
"MaliciousUriFilterSettings",
|
|
195
|
+
"MessageItem",
|
|
196
|
+
"ModelArmorClient",
|
|
197
|
+
"MultiLanguageDetectionMetadata",
|
|
198
|
+
"PiAndJailbreakFilterResult",
|
|
199
|
+
"PiAndJailbreakFilterSettings",
|
|
200
|
+
"RaiFilterResult",
|
|
201
|
+
"RaiFilterSettings",
|
|
202
|
+
"RaiFilterType",
|
|
203
|
+
"RangeInfo",
|
|
204
|
+
"SanitizationResult",
|
|
205
|
+
"SanitizeModelResponseRequest",
|
|
206
|
+
"SanitizeModelResponseResponse",
|
|
207
|
+
"SanitizeUserPromptRequest",
|
|
208
|
+
"SanitizeUserPromptResponse",
|
|
209
|
+
"SdpAdvancedConfig",
|
|
210
|
+
"SdpBasicConfig",
|
|
211
|
+
"SdpDeidentifyResult",
|
|
212
|
+
"SdpFilterResult",
|
|
213
|
+
"SdpFilterSettings",
|
|
214
|
+
"SdpFinding",
|
|
215
|
+
"SdpFindingLikelihood",
|
|
216
|
+
"SdpInspectResult",
|
|
217
|
+
"Template",
|
|
218
|
+
"UpdateFloorSettingRequest",
|
|
219
|
+
"UpdateTemplateRequest",
|
|
220
|
+
"VirusDetail",
|
|
221
|
+
"VirusScanFilterResult",
|
|
222
|
+
)
|