|
14 | 14 | # limitations under the License.
|
15 | 15 | from __future__ import annotations
|
16 | 16 |
|
| 17 | +from typing import Callable |
| 18 | + |
17 | 19 | import google.ai.generativelanguage as glm
|
18 | 20 |
|
19 | 21 | from google.generativeai.types import permission_types
|
| 22 | +from google.generativeai.types import retriever_types |
| 23 | +from google.generativeai.types import model_types |
| 24 | + |
| 25 | + |
| 26 | +_RESOURCE_TYPE: dict[str, str] = { |
| 27 | + "corpus": "corpora", |
| 28 | + "corpora": "corpora", |
| 29 | + "tunedmodel": "tunedModels", |
| 30 | + "tunedmodels": "tunedModels", |
| 31 | +} |
| 32 | + |
| 33 | + |
| 34 | +def _to_resource_type(x: str) -> str: |
| 35 | + if isinstance(x, str): |
| 36 | + x = x.lower() |
| 37 | + resource_type = _RESOURCE_TYPE.get(x, None) |
| 38 | + if not resource_type: |
| 39 | + raise ValueError(f"Unsupported resource type. Got: `{x}` instead.") |
| 40 | + |
| 41 | + return resource_type |
| 42 | + |
| 43 | + |
| 44 | +def _validate_resource_name(x: str, resource_type: str) -> None: |
| 45 | + if resource_type == "corpora": |
| 46 | + if not retriever_types.valid_name(x): |
| 47 | + raise ValueError(retriever_types.NAME_ERROR_MSG.format(length=len(x), name=x)) |
| 48 | + |
| 49 | + elif resource_type == "tunedModels": |
| 50 | + if not model_types.valid_tuned_model_name(x): |
| 51 | + raise ValueError(model_types.TUNED_MODEL_NAME_ERROR_MSG.format(length=len(x), name=x)) |
| 52 | + |
| 53 | + else: |
| 54 | + raise ValueError(f"Unsupported resource type: {resource_type}") |
| 55 | + |
| 56 | + |
| 57 | +def _validate_permission_id(x: str) -> None: |
| 58 | + if not permission_types.valid_id(x): |
| 59 | + raise ValueError(permission_types.INVALID_PERMISSION_ID_MSG.format(permission_id=x)) |
| 60 | + |
| 61 | + |
| 62 | +def _get_valid_name_components(name: str) -> str: |
| 63 | + # name is of the format: resource_type/resource_name/permissions/permission_id |
| 64 | + name_path_components = name.split("/") |
| 65 | + if len(name_path_components) != 4: |
| 66 | + raise ValueError( |
| 67 | + f"Invalid name format. Expected format: \ |
| 68 | + `resource_type/<resource_name>/permissions/<permission_id>`. Got: `{name}` instead." |
| 69 | + ) |
| 70 | + |
| 71 | + resource_type, resource_name, permission_placeholder, permission_id = name_path_components |
| 72 | + resource_type = _to_resource_type(resource_type) |
| 73 | + |
| 74 | + permission_id = "/".join([permission_placeholder, permission_id]) |
| 75 | + |
| 76 | + _validate_resource_name(resource_name, resource_type) |
| 77 | + _validate_permission_id(permission_id) |
| 78 | + |
| 79 | + return "/".join([resource_type, resource_name, permission_id]) |
| 80 | + |
| 81 | + |
| 82 | +def _construct_name( |
| 83 | + name: str | None = None, |
| 84 | + resource_name: str | None = None, |
| 85 | + permission_id: str | int | None = None, |
| 86 | + resource_type: str | None = None, |
| 87 | +) -> str: |
| 88 | + # resource_name is the name of the supported resource (corpus or tunedModel as of now) for which the permission is being created. |
| 89 | + if not name: |
| 90 | + # if name is not provided, then try to construct name via provided resource_name and permission_id. |
| 91 | + if not (resource_name and permission_id): |
| 92 | + raise ValueError( |
| 93 | + "Either `name` or (`resource_name` and `permission_id`) must be provided." |
| 94 | + ) |
| 95 | + |
| 96 | + if resource_type: |
| 97 | + resource_type = _to_resource_type(resource_type) |
| 98 | + else: |
| 99 | + # if resource_type is not provided, then try to infer it from resource_name. |
| 100 | + resource_path_components = resource_name.split("/") |
| 101 | + if len(resource_path_components) != 2: |
| 102 | + raise ValueError( |
| 103 | + f"Invalid `resource_name` format. Expected format: \ |
| 104 | + `resource_type/resource_name`. Got: `{resource_name}` instead." |
| 105 | + ) |
| 106 | + resource_type = _to_resource_type(resource_path_components[0]) |
| 107 | + |
| 108 | + if f"{resource_type}/" in resource_name: |
| 109 | + name = f"{resource_name}/" |
| 110 | + else: |
| 111 | + name = f"{resource_type}/{resource_name}/" |
| 112 | + |
| 113 | + if isinstance(permission_id, int) or "permissions/" not in permission_id: |
| 114 | + name += f"permissions/{permission_id}" |
| 115 | + else: |
| 116 | + name += permission_id |
| 117 | + |
| 118 | + # if name is provided, override resource_name and permission_id |
| 119 | + name = _get_valid_name_components(name) |
| 120 | + return name |
20 | 121 |
|
21 | 122 |
|
22 | 123 | def get_permission(
|
23 |
| - name: str, |
| 124 | + name: str | None = None, |
| 125 | + *, |
24 | 126 | client: glm.PermissionServiceClient | None = None,
|
| 127 | + resource_name: str | None = None, |
| 128 | + permission_id: str | int | None = None, |
| 129 | + resource_type: str | None = None, |
25 | 130 | ) -> permission_types.Permission:
|
26 |
| - """Get a permission by name. |
| 131 | + """Get information about a permission by name. |
27 | 132 |
|
28 | 133 | Args:
|
29 | 134 | name: The name of the permission.
|
| 135 | + resource_name: The name of the supported resource for which the permission details are needed. |
| 136 | + permission_id: The name of the permission. |
| 137 | + resource_type: The type of the resource (corpus or tunedModel as of now) for which the permission details are needed. |
| 138 | + If not provided, it will be inferred from `resource_name`. |
30 | 139 |
|
31 | 140 | Returns:
|
32 | 141 | The permission as an instance of `permission_types.Permission`.
|
33 | 142 | """
|
| 143 | + name = _construct_name( |
| 144 | + name=name, |
| 145 | + resource_name=resource_name, |
| 146 | + permission_id=permission_id, |
| 147 | + resource_type=resource_type, |
| 148 | + ) |
34 | 149 | return permission_types.Permission.get(name=name, client=client)
|
35 | 150 |
|
36 | 151 |
|
37 | 152 | async def get_permission_async(
|
38 |
| - name: str, |
| 153 | + name: str | None = None, |
| 154 | + *, |
39 | 155 | client: glm.PermissionServiceAsyncClient | None = None,
|
| 156 | + resource_name: str | None = None, |
| 157 | + permission_id: str | int | None = None, |
| 158 | + resource_type: str | None = None, |
40 | 159 | ) -> permission_types.Permission:
|
41 | 160 | """
|
42 | 161 | This is the async version of `permission.get_permission`.
|
43 | 162 | """
|
| 163 | + name = _construct_name( |
| 164 | + name=name, |
| 165 | + resource_name=resource_name, |
| 166 | + permission_id=permission_id, |
| 167 | + resource_type=resource_type, |
| 168 | + ) |
44 | 169 | return await permission_types.Permission.get_async(name=name, client=client)
|
0 commit comments