Skip to content

Commit f2f1fbb

Browse files
committed
feat(gooddata-sdk): [AUTO] Add Anthropic provider config to LLM provider config
1 parent 38b0798 commit f2f1fbb

3 files changed

Lines changed: 78 additions & 0 deletions

File tree

packages/gooddata-sdk/src/gooddata_sdk/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
CatalogRsaSpecification,
117117
)
118118
from gooddata_sdk.catalog.organization.entity_model.llm_provider import (
119+
CatalogAnthropicApiKeyAuth,
120+
CatalogAnthropicProviderConfig,
119121
CatalogAwsBedrockProviderConfig,
120122
CatalogAzureFoundryApiKeyAuth,
121123
CatalogAzureFoundryProviderConfig,

packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/llm_provider.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,24 @@ def client_class() -> type[AzureFoundryProviderAuth]:
7575

7676
CatalogAzureFoundryAuth = Union[CatalogAzureFoundryApiKeyAuth]
7777

78+
# --- Anthropic auth ---
79+
80+
81+
@define(kw_only=True)
82+
class CatalogAnthropicApiKeyAuth(Base):
83+
"""API key authentication for the Anthropic provider."""
84+
85+
api_key: str | None = None
86+
type: str = "API_KEY"
87+
88+
@staticmethod
89+
def client_class() -> type[OpenAiProviderAuth]:
90+
# Stand-in: AnthropicProviderAuth not yet present in the generated client.
91+
return OpenAiProviderAuth
92+
93+
94+
CatalogAnthropicAuth = Union[CatalogAnthropicApiKeyAuth]
95+
7896
# --- Provider config types ---
7997

8098

@@ -118,10 +136,25 @@ def client_class() -> type[AzureFoundryProviderConfig]:
118136
return AzureFoundryProviderConfig
119137

120138

139+
@define(kw_only=True)
140+
class CatalogAnthropicProviderConfig(Base):
141+
"""Anthropic provider configuration."""
142+
143+
auth: CatalogAnthropicAuth | None = None
144+
base_url: str | None = None
145+
type: str = "ANTHROPIC"
146+
147+
@staticmethod
148+
def client_class() -> type[OpenAIProviderConfig]:
149+
# Stand-in: AnthropicProviderConfig not yet present in the generated client.
150+
return OpenAIProviderConfig
151+
152+
121153
CatalogLlmProviderConfig = Union[
122154
CatalogOpenAiProviderConfig,
123155
CatalogAwsBedrockProviderConfig,
124156
CatalogAzureFoundryProviderConfig,
157+
CatalogAnthropicProviderConfig,
125158
]
126159

127160

@@ -157,6 +190,16 @@ def _azure_foundry_auth_from_api(data: dict[str, Any]) -> CatalogAzureFoundryAut
157190
raise ValueError(f"Unknown Azure Foundry auth type: {auth_type}")
158191

159192

193+
def _anthropic_auth_from_api(data: dict[str, Any]) -> CatalogAnthropicAuth:
194+
auth_type = safeget(data, ["type"]) or "API_KEY"
195+
if auth_type == "API_KEY":
196+
return CatalogAnthropicApiKeyAuth(
197+
api_key="", # Credentials are not returned for security reasons
198+
type=auth_type,
199+
)
200+
raise ValueError(f"Unknown Anthropic auth type: {auth_type}")
201+
202+
160203
def _provider_config_from_api(data: dict[str, Any]) -> CatalogLlmProviderConfig:
161204
provider_type = safeget(data, ["type"]) or "OPENAI"
162205
auth_data = safeget(data, ["auth"])
@@ -173,6 +216,12 @@ def _provider_config_from_api(data: dict[str, Any]) -> CatalogLlmProviderConfig:
173216
endpoint=safeget(data, ["endpoint"]),
174217
)
175218

219+
if provider_type == "ANTHROPIC":
220+
return CatalogAnthropicProviderConfig(
221+
auth=_anthropic_auth_from_api(auth_data) if auth_data is not None else None,
222+
base_url=safeget(data, ["baseUrl"]),
223+
)
224+
176225
# Default: OpenAI
177226
return CatalogOpenAiProviderConfig(
178227
auth=_openai_auth_from_api(auth_data) if auth_data is not None else None,

packages/gooddata-sdk/tests/catalog/test_catalog_organization.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55

66
from gooddata_api_client.exceptions import NotFoundException
77
from gooddata_sdk import (
8+
CatalogAnthropicApiKeyAuth,
9+
CatalogAnthropicProviderConfig,
810
CatalogCspDirective,
911
CatalogDeclarativeNotificationChannel,
1012
CatalogJwk,
13+
CatalogLlmProvider,
14+
CatalogLlmProviderModel,
1115
CatalogOrganization,
1216
CatalogOrganizationSetting,
1317
CatalogRsaSpecification,
@@ -334,6 +338,29 @@ def test_layout_notification_channels(test_config, snapshot_notification_channel
334338
# snapshot_notification_channels fixture restores original state in teardown
335339

336340

341+
@gd_vcr.use_cassette(str(_fixtures_dir / "test_anthropic_llm_provider.yaml"))
342+
def test_create_anthropic_llm_provider(test_config):
343+
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"])
344+
provider_id = "test-anthropic-provider"
345+
new_provider = CatalogLlmProvider.init(
346+
id=provider_id,
347+
models=[CatalogLlmProviderModel(id="claude-3-5-sonnet-20241022", family="claude")],
348+
provider_config=CatalogAnthropicProviderConfig(
349+
auth=CatalogAnthropicApiKeyAuth(api_key="sk-ant-test-key"),
350+
base_url="https://api.anthropic.com",
351+
),
352+
name="Test Anthropic Provider",
353+
)
354+
try:
355+
created = sdk.catalog_organization.create_llm_provider(new_provider)
356+
assert created.id == provider_id
357+
fetched = sdk.catalog_organization.get_llm_provider(provider_id)
358+
assert fetched.id == provider_id
359+
assert isinstance(fetched.attributes.provider_config, CatalogAnthropicProviderConfig)
360+
finally:
361+
safe_delete(sdk.catalog_organization.delete_llm_provider, provider_id)
362+
363+
337364
#
338365
# The following tests are commented out as they require the organization to have the FEDERATED_IDENTITY_MANAGEMENT
339366
# entitlement enabled which cannot be done via SDK and must be done by GoodData support.

0 commit comments

Comments
 (0)