|
| 1 | +# (C) 2026 GoodData Corporation |
| 2 | +from __future__ import annotations |
| 3 | + |
| 4 | +from typing import Any, Union |
| 5 | + |
| 6 | +from attr import define |
| 7 | +from gooddata_api_client.model.aws_bedrock_provider_config import AwsBedrockProviderConfig |
| 8 | +from gooddata_api_client.model.azure_foundry_provider_auth import AzureFoundryProviderAuth |
| 9 | +from gooddata_api_client.model.azure_foundry_provider_config import AzureFoundryProviderConfig |
| 10 | +from gooddata_api_client.model.bedrock_provider_auth import BedrockProviderAuth |
| 11 | +from gooddata_api_client.model.json_api_llm_provider_in import JsonApiLlmProviderIn |
| 12 | +from gooddata_api_client.model.json_api_llm_provider_in_attributes import JsonApiLlmProviderInAttributes |
| 13 | +from gooddata_api_client.model.json_api_llm_provider_in_attributes_models_inner import ( |
| 14 | + JsonApiLlmProviderInAttributesModelsInner, |
| 15 | +) |
| 16 | +from gooddata_api_client.model.json_api_llm_provider_in_document import JsonApiLlmProviderInDocument |
| 17 | +from gooddata_api_client.model.json_api_llm_provider_patch import JsonApiLlmProviderPatch |
| 18 | +from gooddata_api_client.model.json_api_llm_provider_patch_attributes import JsonApiLlmProviderPatchAttributes |
| 19 | +from gooddata_api_client.model.json_api_llm_provider_patch_document import JsonApiLlmProviderPatchDocument |
| 20 | +from gooddata_api_client.model.open_ai_provider_auth import OpenAiProviderAuth |
| 21 | +from gooddata_api_client.model.open_ai_provider_config import OpenAIProviderConfig |
| 22 | + |
| 23 | +from gooddata_sdk.catalog.base import Base |
| 24 | +from gooddata_sdk.utils import safeget |
| 25 | + |
| 26 | +# --- OpenAI auth --- |
| 27 | + |
| 28 | + |
| 29 | +@define(kw_only=True) |
| 30 | +class CatalogOpenAiApiKeyAuth(Base): |
| 31 | + """API key authentication for the OpenAI provider.""" |
| 32 | + |
| 33 | + api_key: str | None = None |
| 34 | + type: str = "API_KEY" |
| 35 | + |
| 36 | + @staticmethod |
| 37 | + def client_class() -> type[OpenAiProviderAuth]: |
| 38 | + return OpenAiProviderAuth |
| 39 | + |
| 40 | + |
| 41 | +CatalogOpenAiAuth = Union[CatalogOpenAiApiKeyAuth] |
| 42 | + |
| 43 | +# --- AWS Bedrock auth --- |
| 44 | + |
| 45 | + |
| 46 | +@define(kw_only=True) |
| 47 | +class CatalogBedrockAccessKeyAuth(Base): |
| 48 | + """AWS access key authentication for the Bedrock provider.""" |
| 49 | + |
| 50 | + access_key_id: str | None = None |
| 51 | + secret_access_key: str | None = None |
| 52 | + session_token: str | None = None |
| 53 | + type: str = "ACCESS_KEY" |
| 54 | + |
| 55 | + @staticmethod |
| 56 | + def client_class() -> type[BedrockProviderAuth]: |
| 57 | + return BedrockProviderAuth |
| 58 | + |
| 59 | + |
| 60 | +CatalogBedrockAuth = Union[CatalogBedrockAccessKeyAuth] |
| 61 | + |
| 62 | +# --- Azure Foundry auth --- |
| 63 | + |
| 64 | + |
| 65 | +@define(kw_only=True) |
| 66 | +class CatalogAzureFoundryApiKeyAuth(Base): |
| 67 | + """API key authentication for the Azure Foundry provider.""" |
| 68 | + |
| 69 | + api_key: str | None = None |
| 70 | + type: str = "API_KEY" |
| 71 | + |
| 72 | + @staticmethod |
| 73 | + def client_class() -> type[AzureFoundryProviderAuth]: |
| 74 | + return AzureFoundryProviderAuth |
| 75 | + |
| 76 | + |
| 77 | +CatalogAzureFoundryAuth = Union[CatalogAzureFoundryApiKeyAuth] |
| 78 | + |
| 79 | +# --- Provider config types --- |
| 80 | + |
| 81 | + |
| 82 | +@define(kw_only=True) |
| 83 | +class CatalogOpenAiProviderConfig(Base): |
| 84 | + """OpenAI provider configuration.""" |
| 85 | + |
| 86 | + auth: CatalogOpenAiAuth | None = None |
| 87 | + base_url: str | None = None |
| 88 | + organization: str | None = None |
| 89 | + type: str = "OPENAI" |
| 90 | + |
| 91 | + @staticmethod |
| 92 | + def client_class() -> type[OpenAIProviderConfig]: |
| 93 | + return OpenAIProviderConfig |
| 94 | + |
| 95 | + |
| 96 | +@define(kw_only=True) |
| 97 | +class CatalogAwsBedrockProviderConfig(Base): |
| 98 | + """AWS Bedrock provider configuration.""" |
| 99 | + |
| 100 | + auth: CatalogBedrockAuth | None = None |
| 101 | + region: str | None = None |
| 102 | + type: str = "AWS_BEDROCK" |
| 103 | + |
| 104 | + @staticmethod |
| 105 | + def client_class() -> type[AwsBedrockProviderConfig]: |
| 106 | + return AwsBedrockProviderConfig |
| 107 | + |
| 108 | + |
| 109 | +@define(kw_only=True) |
| 110 | +class CatalogAzureFoundryProviderConfig(Base): |
| 111 | + """Azure Foundry provider configuration.""" |
| 112 | + |
| 113 | + auth: CatalogAzureFoundryAuth | None = None |
| 114 | + endpoint: str | None = None |
| 115 | + type: str = "AZURE_FOUNDRY" |
| 116 | + |
| 117 | + @staticmethod |
| 118 | + def client_class() -> type[AzureFoundryProviderConfig]: |
| 119 | + return AzureFoundryProviderConfig |
| 120 | + |
| 121 | + |
| 122 | +CatalogLlmProviderConfig = Union[ |
| 123 | + CatalogOpenAiProviderConfig, |
| 124 | + CatalogAwsBedrockProviderConfig, |
| 125 | + CatalogAzureFoundryProviderConfig, |
| 126 | +] |
| 127 | + |
| 128 | + |
| 129 | +def _openai_auth_from_api(data: dict[str, Any]) -> CatalogOpenAiAuth: |
| 130 | + auth_type = safeget(data, ["type"]) or "API_KEY" |
| 131 | + if auth_type == "API_KEY": |
| 132 | + return CatalogOpenAiApiKeyAuth( |
| 133 | + api_key="", # Credentials are not returned for security reasons |
| 134 | + type=auth_type, |
| 135 | + ) |
| 136 | + raise ValueError(f"Unknown OpenAI auth type: {auth_type}") |
| 137 | + |
| 138 | + |
| 139 | +def _bedrock_auth_from_api(data: dict[str, Any]) -> CatalogBedrockAuth: |
| 140 | + auth_type = safeget(data, ["type"]) or "ACCESS_KEY" |
| 141 | + if auth_type == "ACCESS_KEY": |
| 142 | + return CatalogBedrockAccessKeyAuth( |
| 143 | + access_key_id="", # Credentials are not returned for security reasons |
| 144 | + secret_access_key="", |
| 145 | + session_token=safeget(data, ["sessionToken"]), |
| 146 | + type=auth_type, |
| 147 | + ) |
| 148 | + raise ValueError(f"Unknown Bedrock auth type: {auth_type}") |
| 149 | + |
| 150 | + |
| 151 | +def _azure_foundry_auth_from_api(data: dict[str, Any]) -> CatalogAzureFoundryAuth: |
| 152 | + auth_type = safeget(data, ["type"]) or "API_KEY" |
| 153 | + if auth_type == "API_KEY": |
| 154 | + return CatalogAzureFoundryApiKeyAuth( |
| 155 | + api_key="", # Credentials are not returned for security reasons |
| 156 | + type=auth_type, |
| 157 | + ) |
| 158 | + raise ValueError(f"Unknown Azure Foundry auth type: {auth_type}") |
| 159 | + |
| 160 | + |
| 161 | +def _provider_config_from_api(data: dict[str, Any]) -> CatalogLlmProviderConfig: |
| 162 | + provider_type = safeget(data, ["type"]) or "OPENAI" |
| 163 | + auth_data = safeget(data, ["auth"]) |
| 164 | + |
| 165 | + if provider_type == "AWS_BEDROCK": |
| 166 | + return CatalogAwsBedrockProviderConfig( |
| 167 | + auth=_bedrock_auth_from_api(auth_data) if auth_data is not None else None, |
| 168 | + region=safeget(data, ["region"]), |
| 169 | + ) |
| 170 | + |
| 171 | + if provider_type == "AZURE_FOUNDRY": |
| 172 | + return CatalogAzureFoundryProviderConfig( |
| 173 | + auth=_azure_foundry_auth_from_api(auth_data) if auth_data is not None else None, |
| 174 | + endpoint=safeget(data, ["endpoint"]), |
| 175 | + ) |
| 176 | + |
| 177 | + # Default: OpenAI |
| 178 | + return CatalogOpenAiProviderConfig( |
| 179 | + auth=_openai_auth_from_api(auth_data) if auth_data is not None else None, |
| 180 | + base_url=safeget(data, ["baseUrl"]), |
| 181 | + organization=safeget(data, ["organization"]), |
| 182 | + ) |
| 183 | + |
| 184 | + |
| 185 | +# --- Document wrappers --- |
| 186 | + |
| 187 | + |
| 188 | +@define(kw_only=True) |
| 189 | +class CatalogLlmProviderDocument(Base): |
| 190 | + data: CatalogLlmProvider |
| 191 | + |
| 192 | + @staticmethod |
| 193 | + def client_class() -> type[JsonApiLlmProviderInDocument]: |
| 194 | + return JsonApiLlmProviderInDocument |
| 195 | + |
| 196 | + |
| 197 | +@define(kw_only=True) |
| 198 | +class CatalogLlmProviderPatchDocument(Base): |
| 199 | + data: CatalogLlmProviderPatch |
| 200 | + |
| 201 | + @staticmethod |
| 202 | + def client_class() -> type[JsonApiLlmProviderPatchDocument]: |
| 203 | + return JsonApiLlmProviderPatchDocument |
| 204 | + |
| 205 | + |
| 206 | +# --- Model type --- |
| 207 | + |
| 208 | + |
| 209 | +@define(kw_only=True) |
| 210 | +class CatalogLlmProviderModel(Base): |
| 211 | + """Represents a single LLM model available for a provider.""" |
| 212 | + |
| 213 | + id: str |
| 214 | + family: str |
| 215 | + |
| 216 | + @staticmethod |
| 217 | + def client_class() -> type[JsonApiLlmProviderInAttributesModelsInner]: |
| 218 | + return JsonApiLlmProviderInAttributesModelsInner |
| 219 | + |
| 220 | + |
| 221 | +# --- Main entity types --- |
| 222 | + |
| 223 | + |
| 224 | +@define(kw_only=True) |
| 225 | +class CatalogLlmProvider(Base): |
| 226 | + id: str |
| 227 | + attributes: CatalogLlmProviderAttributes | None = None |
| 228 | + |
| 229 | + @staticmethod |
| 230 | + def client_class() -> type[JsonApiLlmProviderIn]: |
| 231 | + return JsonApiLlmProviderIn |
| 232 | + |
| 233 | + @classmethod |
| 234 | + def init( |
| 235 | + cls, |
| 236 | + id: str, |
| 237 | + models: list[CatalogLlmProviderModel], |
| 238 | + provider_config: CatalogLlmProviderConfig, |
| 239 | + name: str | None = None, |
| 240 | + description: str | None = None, |
| 241 | + default_model_id: str | None = None, |
| 242 | + ) -> CatalogLlmProvider: |
| 243 | + return cls( |
| 244 | + id=id, |
| 245 | + attributes=CatalogLlmProviderAttributes( |
| 246 | + models=models, |
| 247 | + provider_config=provider_config, |
| 248 | + name=name, |
| 249 | + description=description, |
| 250 | + default_model_id=default_model_id, |
| 251 | + ), |
| 252 | + ) |
| 253 | + |
| 254 | + @classmethod |
| 255 | + def from_api(cls, entity: dict[str, Any]) -> CatalogLlmProvider: |
| 256 | + ea = entity["attributes"] |
| 257 | + raw_models = safeget(ea, ["models"]) or [] |
| 258 | + models = [ |
| 259 | + CatalogLlmProviderModel( |
| 260 | + id=safeget(m, ["id"]), |
| 261 | + family=safeget(m, ["family"]), |
| 262 | + ) |
| 263 | + for m in raw_models |
| 264 | + ] |
| 265 | + raw_config = safeget(ea, ["providerConfig"]) or {} |
| 266 | + provider_config = _provider_config_from_api(raw_config) |
| 267 | + return cls( |
| 268 | + id=entity["id"], |
| 269 | + attributes=CatalogLlmProviderAttributes( |
| 270 | + models=models, |
| 271 | + provider_config=provider_config, |
| 272 | + name=safeget(ea, ["name"]), |
| 273 | + description=safeget(ea, ["description"]), |
| 274 | + default_model_id=safeget(ea, ["defaultModelId"]), |
| 275 | + ), |
| 276 | + ) |
| 277 | + |
| 278 | + |
| 279 | +@define(kw_only=True) |
| 280 | +class CatalogLlmProviderPatch(Base): |
| 281 | + id: str |
| 282 | + attributes: CatalogLlmProviderPatchAttributes | None = None |
| 283 | + |
| 284 | + @staticmethod |
| 285 | + def client_class() -> type[JsonApiLlmProviderPatch]: |
| 286 | + return JsonApiLlmProviderPatch |
| 287 | + |
| 288 | + @classmethod |
| 289 | + def init( |
| 290 | + cls, |
| 291 | + id: str, |
| 292 | + models: list[CatalogLlmProviderModel] | None = None, |
| 293 | + provider_config: CatalogLlmProviderConfig | None = None, |
| 294 | + name: str | None = None, |
| 295 | + description: str | None = None, |
| 296 | + default_model_id: str | None = None, |
| 297 | + ) -> CatalogLlmProviderPatch: |
| 298 | + return cls( |
| 299 | + id=id, |
| 300 | + attributes=CatalogLlmProviderPatchAttributes( |
| 301 | + models=models, |
| 302 | + provider_config=provider_config, |
| 303 | + name=name, |
| 304 | + description=description, |
| 305 | + default_model_id=default_model_id, |
| 306 | + ), |
| 307 | + ) |
| 308 | + |
| 309 | + |
| 310 | +# --- Attributes --- |
| 311 | + |
| 312 | + |
| 313 | +@define(kw_only=True) |
| 314 | +class CatalogLlmProviderAttributes(Base): |
| 315 | + models: list[CatalogLlmProviderModel] |
| 316 | + provider_config: CatalogLlmProviderConfig |
| 317 | + name: str | None = None |
| 318 | + description: str | None = None |
| 319 | + default_model_id: str | None = None |
| 320 | + |
| 321 | + @staticmethod |
| 322 | + def client_class() -> type[JsonApiLlmProviderInAttributes]: |
| 323 | + return JsonApiLlmProviderInAttributes |
| 324 | + |
| 325 | + |
| 326 | +@define(kw_only=True) |
| 327 | +class CatalogLlmProviderPatchAttributes(Base): |
| 328 | + models: list[CatalogLlmProviderModel] | None = None |
| 329 | + provider_config: CatalogLlmProviderConfig | None = None |
| 330 | + name: str | None = None |
| 331 | + description: str | None = None |
| 332 | + default_model_id: str | None = None |
| 333 | + |
| 334 | + @staticmethod |
| 335 | + def client_class() -> type[JsonApiLlmProviderPatchAttributes]: |
| 336 | + return JsonApiLlmProviderPatchAttributes |
0 commit comments