datarobot-genai 0.2.6__py3-none-any.whl → 0.2.7__py3-none-any.whl
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.
- datarobot_genai/nat/datarobot_auth_provider.py +58 -1
- datarobot_genai/nat/datarobot_mcp_client.py +55 -2
- {datarobot_genai-0.2.6.dist-info → datarobot_genai-0.2.7.dist-info}/METADATA +1 -1
- {datarobot_genai-0.2.6.dist-info → datarobot_genai-0.2.7.dist-info}/RECORD +8 -8
- {datarobot_genai-0.2.6.dist-info → datarobot_genai-0.2.7.dist-info}/WHEEL +0 -0
- {datarobot_genai-0.2.6.dist-info → datarobot_genai-0.2.7.dist-info}/entry_points.txt +0 -0
- {datarobot_genai-0.2.6.dist-info → datarobot_genai-0.2.7.dist-info}/licenses/AUTHORS +0 -0
- {datarobot_genai-0.2.6.dist-info → datarobot_genai-0.2.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -11,13 +11,22 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
from collections.abc import AsyncGenerator
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
14
17
|
from datarobot.core.config import DataRobotAppFrameworkBaseSettings
|
|
15
18
|
from nat.authentication.api_key.api_key_auth_provider import APIKeyAuthProvider
|
|
16
19
|
from nat.authentication.api_key.api_key_auth_provider_config import APIKeyAuthProviderConfig
|
|
20
|
+
from nat.authentication.interfaces import AuthProviderBase
|
|
17
21
|
from nat.builder.builder import Builder
|
|
18
22
|
from nat.cli.register_workflow import register_auth_provider
|
|
23
|
+
from nat.data_models.authentication import AuthProviderBaseConfig
|
|
24
|
+
from nat.data_models.authentication import AuthResult
|
|
25
|
+
from nat.data_models.authentication import HeaderCred
|
|
19
26
|
from pydantic import Field
|
|
20
27
|
|
|
28
|
+
from datarobot_genai.core.mcp.common import MCPConfig
|
|
29
|
+
|
|
21
30
|
|
|
22
31
|
class Config(DataRobotAppFrameworkBaseSettings):
|
|
23
32
|
"""
|
|
@@ -49,5 +58,53 @@ class DataRobotAPIKeyAuthProviderConfig(APIKeyAuthProviderConfig, name="datarobo
|
|
|
49
58
|
@register_auth_provider(config_type=DataRobotAPIKeyAuthProviderConfig)
|
|
50
59
|
async def datarobot_api_key_client(
|
|
51
60
|
config: DataRobotAPIKeyAuthProviderConfig, builder: Builder
|
|
52
|
-
) ->
|
|
61
|
+
) -> AsyncGenerator[APIKeyAuthProvider]:
|
|
53
62
|
yield APIKeyAuthProvider(config=config)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
mcp_config = MCPConfig().server_config
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class DataRobotMCPAuthProviderConfig(AuthProviderBaseConfig, name="datarobot_mcp_auth"): # type: ignore[call-arg]
|
|
69
|
+
headers: dict[str, str] | None = Field(
|
|
70
|
+
description=("Headers to be used for authentication. "),
|
|
71
|
+
default=mcp_config["headers"] if mcp_config else None,
|
|
72
|
+
)
|
|
73
|
+
default_user_id: str | None = Field(default="default-user", description="Default user ID")
|
|
74
|
+
allow_default_user_id_for_tool_calls: bool = Field(
|
|
75
|
+
default=True, description="Allow default user ID for tool calls"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class DataRobotMCPAuthProvider(AuthProviderBase[DataRobotMCPAuthProviderConfig]):
|
|
80
|
+
def __init__(
|
|
81
|
+
self, config: DataRobotMCPAuthProviderConfig, config_name: str | None = None
|
|
82
|
+
) -> None:
|
|
83
|
+
assert isinstance(config, DataRobotMCPAuthProviderConfig), (
|
|
84
|
+
"Config is not DataRobotMCPAuthProviderConfig"
|
|
85
|
+
)
|
|
86
|
+
super().__init__(config)
|
|
87
|
+
|
|
88
|
+
async def authenticate(self, user_id: str | None = None, **kwargs: Any) -> AuthResult | None:
|
|
89
|
+
"""
|
|
90
|
+
Authenticate the user using the API key credentials.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
user_id (str): The user ID to authenticate.
|
|
94
|
+
|
|
95
|
+
Returns
|
|
96
|
+
-------
|
|
97
|
+
AuthenticatedContext: The authenticated context containing headers
|
|
98
|
+
"""
|
|
99
|
+
return AuthResult(
|
|
100
|
+
credentials=[
|
|
101
|
+
HeaderCred(name=name, value=value) for name, value in self.config.headers.items()
|
|
102
|
+
]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@register_auth_provider(config_type=DataRobotMCPAuthProviderConfig)
|
|
107
|
+
async def datarobot_mcp_auth_provider(
|
|
108
|
+
config: DataRobotMCPAuthProviderConfig, builder: Builder
|
|
109
|
+
) -> AsyncGenerator[DataRobotMCPAuthProvider]:
|
|
110
|
+
yield DataRobotMCPAuthProvider(config=config)
|
|
@@ -13,11 +13,15 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import logging
|
|
16
|
+
from datetime import timedelta
|
|
16
17
|
from typing import Literal
|
|
17
18
|
|
|
19
|
+
import httpx
|
|
20
|
+
from nat.authentication.interfaces import AuthProviderBase
|
|
18
21
|
from nat.builder.builder import Builder
|
|
19
22
|
from nat.cli.register_workflow import register_function_group
|
|
20
23
|
from nat.data_models.component_ref import AuthenticationRef
|
|
24
|
+
from nat.plugins.mcp.client_base import AuthAdapter
|
|
21
25
|
from nat.plugins.mcp.client_base import MCPSSEClient
|
|
22
26
|
from nat.plugins.mcp.client_base import MCPStdioClient
|
|
23
27
|
from nat.plugins.mcp.client_base import MCPStreamableHTTPClient
|
|
@@ -47,7 +51,7 @@ class DataRobotMCPServerConfig(MCPServerConfig):
|
|
|
47
51
|
)
|
|
48
52
|
# Authentication configuration
|
|
49
53
|
auth_provider: str | AuthenticationRef | None = Field(
|
|
50
|
-
default="
|
|
54
|
+
default="datarobot_mcp_auth" if config else None,
|
|
51
55
|
description="Reference to authentication provider",
|
|
52
56
|
)
|
|
53
57
|
command: str | None = Field(
|
|
@@ -62,6 +66,55 @@ class DataRobotMCPClientConfig(MCPClientConfig, name="datarobot_mcp_client"): #
|
|
|
62
66
|
)
|
|
63
67
|
|
|
64
68
|
|
|
69
|
+
class DataRobotAuthAdapter(AuthAdapter):
|
|
70
|
+
async def _get_auth_headers(
|
|
71
|
+
self, request: httpx.Request | None = None, response: httpx.Response | None = None
|
|
72
|
+
) -> dict[str, str]:
|
|
73
|
+
"""Get authentication headers from the NAT auth provider."""
|
|
74
|
+
try:
|
|
75
|
+
# Use the user_id passed to this AuthAdapter instance
|
|
76
|
+
auth_result = await self.auth_provider.authenticate(
|
|
77
|
+
user_id=self.user_id, response=response
|
|
78
|
+
)
|
|
79
|
+
as_kwargs = auth_result.as_requests_kwargs()
|
|
80
|
+
return as_kwargs["headers"]
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logger.warning("Failed to get auth token: %s", e)
|
|
83
|
+
return {}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class DataRobotMCPStreamableHTTPClient(MCPStreamableHTTPClient):
|
|
87
|
+
def __init__(
|
|
88
|
+
self,
|
|
89
|
+
url: str,
|
|
90
|
+
auth_provider: AuthProviderBase | None = None,
|
|
91
|
+
user_id: str | None = None,
|
|
92
|
+
tool_call_timeout: timedelta = timedelta(seconds=60),
|
|
93
|
+
auth_flow_timeout: timedelta = timedelta(seconds=300),
|
|
94
|
+
reconnect_enabled: bool = True,
|
|
95
|
+
reconnect_max_attempts: int = 2,
|
|
96
|
+
reconnect_initial_backoff: float = 0.5,
|
|
97
|
+
reconnect_max_backoff: float = 50.0,
|
|
98
|
+
):
|
|
99
|
+
super().__init__(
|
|
100
|
+
url=url,
|
|
101
|
+
auth_provider=auth_provider,
|
|
102
|
+
user_id=user_id,
|
|
103
|
+
tool_call_timeout=tool_call_timeout,
|
|
104
|
+
auth_flow_timeout=auth_flow_timeout,
|
|
105
|
+
reconnect_enabled=reconnect_enabled,
|
|
106
|
+
reconnect_max_attempts=reconnect_max_attempts,
|
|
107
|
+
reconnect_initial_backoff=reconnect_initial_backoff,
|
|
108
|
+
reconnect_max_backoff=reconnect_max_backoff,
|
|
109
|
+
)
|
|
110
|
+
effective_user_id = user_id or (
|
|
111
|
+
auth_provider.config.default_user_id if auth_provider else None
|
|
112
|
+
)
|
|
113
|
+
self._httpx_auth = (
|
|
114
|
+
DataRobotAuthAdapter(auth_provider, effective_user_id) if auth_provider else None
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
65
118
|
@register_function_group(config_type=DataRobotMCPClientConfig)
|
|
66
119
|
async def datarobot_mcp_client_function_group(
|
|
67
120
|
config: DataRobotMCPClientConfig, _builder: Builder
|
|
@@ -108,7 +161,7 @@ async def datarobot_mcp_client_function_group(
|
|
|
108
161
|
elif config.server.transport == "streamable-http":
|
|
109
162
|
# Use default_user_id for the base client
|
|
110
163
|
base_user_id = auth_provider.config.default_user_id if auth_provider else None
|
|
111
|
-
client =
|
|
164
|
+
client = DataRobotMCPStreamableHTTPClient(
|
|
112
165
|
str(config.server.url),
|
|
113
166
|
auth_provider=auth_provider,
|
|
114
167
|
user_id=base_user_id,
|
|
@@ -101,13 +101,13 @@ datarobot_genai/llama_index/base.py,sha256=ovcQQtC-djD_hcLrWdn93jg23AmD6NBEj7xtw
|
|
|
101
101
|
datarobot_genai/llama_index/mcp.py,sha256=leXqF1C4zhuYEKFwNEfZHY4dsUuGZk3W7KArY-zxVL8,2645
|
|
102
102
|
datarobot_genai/nat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
103
|
datarobot_genai/nat/agent.py,sha256=jDeIS9f-8vGbeLy5gQkSjeuHINx5Fh_4BvXYERsgIIk,10516
|
|
104
|
-
datarobot_genai/nat/datarobot_auth_provider.py,sha256=
|
|
104
|
+
datarobot_genai/nat/datarobot_auth_provider.py,sha256=Z4NSsrHxK8hUeiqtK_lryHsUuZC74ziNo_FHbsZgtiM,4230
|
|
105
105
|
datarobot_genai/nat/datarobot_llm_clients.py,sha256=STzAZ4OF8U-Y_cUTywxmKBGVotwsnbGP6vTojnu6q0g,9921
|
|
106
106
|
datarobot_genai/nat/datarobot_llm_providers.py,sha256=aDoQcTeGI-odqydPXEX9OGGNFbzAtpqzTvHHEkmJuEQ,4963
|
|
107
|
-
datarobot_genai/nat/datarobot_mcp_client.py,sha256=
|
|
108
|
-
datarobot_genai-0.2.
|
|
109
|
-
datarobot_genai-0.2.
|
|
110
|
-
datarobot_genai-0.2.
|
|
111
|
-
datarobot_genai-0.2.
|
|
112
|
-
datarobot_genai-0.2.
|
|
113
|
-
datarobot_genai-0.2.
|
|
107
|
+
datarobot_genai/nat/datarobot_mcp_client.py,sha256=35FzilxNp4VqwBYI0NsOc91-xZm1C-AzWqrOdDy962A,9612
|
|
108
|
+
datarobot_genai-0.2.7.dist-info/METADATA,sha256=dWVPDIxuaXhv5tFM-_yhFvatzWmHzLvZtcC5pM_NsLw,6172
|
|
109
|
+
datarobot_genai-0.2.7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
110
|
+
datarobot_genai-0.2.7.dist-info/entry_points.txt,sha256=jEW3WxDZ8XIK9-ISmTyt5DbmBb047rFlzQuhY09rGrM,284
|
|
111
|
+
datarobot_genai-0.2.7.dist-info/licenses/AUTHORS,sha256=isJGUXdjq1U7XZ_B_9AH8Qf0u4eX0XyQifJZ_Sxm4sA,80
|
|
112
|
+
datarobot_genai-0.2.7.dist-info/licenses/LICENSE,sha256=U2_VkLIktQoa60Nf6Tbt7E4RMlfhFSjWjcJJfVC-YCE,11341
|
|
113
|
+
datarobot_genai-0.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|