ibm-watsonx-orchestrate 1.6.0b0__py3-none-any.whl → 1.7.0a0__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.
- ibm_watsonx_orchestrate/__init__.py +1 -1
- ibm_watsonx_orchestrate/agent_builder/agents/agent.py +1 -0
- ibm_watsonx_orchestrate/agent_builder/agents/types.py +5 -1
- ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/__init__.py +2 -0
- ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/prompts.py +33 -0
- ibm_watsonx_orchestrate/agent_builder/agents/webchat_customizations/welcome_content.py +20 -0
- ibm_watsonx_orchestrate/agent_builder/connections/__init__.py +2 -2
- ibm_watsonx_orchestrate/agent_builder/connections/types.py +38 -31
- ibm_watsonx_orchestrate/agent_builder/tools/flow_tool.py +83 -0
- ibm_watsonx_orchestrate/agent_builder/tools/types.py +7 -1
- ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +25 -14
- ibm_watsonx_orchestrate/cli/commands/channels/webchat/channels_webchat_controller.py +104 -21
- ibm_watsonx_orchestrate/cli/commands/connections/connections_command.py +26 -18
- ibm_watsonx_orchestrate/cli/commands/connections/connections_controller.py +55 -57
- ibm_watsonx_orchestrate/cli/commands/knowledge_bases/knowledge_bases_controller.py +2 -2
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +137 -10
- ibm_watsonx_orchestrate/cli/commands/toolkit/toolkit_controller.py +9 -3
- ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +25 -12
- ibm_watsonx_orchestrate/client/agents/agent_client.py +74 -6
- ibm_watsonx_orchestrate/client/base_api_client.py +2 -1
- ibm_watsonx_orchestrate/client/connections/connections_client.py +18 -9
- ibm_watsonx_orchestrate/client/connections/utils.py +4 -2
- ibm_watsonx_orchestrate/client/local_service_instance.py +1 -1
- ibm_watsonx_orchestrate/client/service_instance.py +3 -3
- ibm_watsonx_orchestrate/client/tools/tempus_client.py +8 -3
- ibm_watsonx_orchestrate/client/utils.py +10 -0
- ibm_watsonx_orchestrate/docker/compose-lite.yml +400 -66
- ibm_watsonx_orchestrate/docker/default.env +44 -12
- ibm_watsonx_orchestrate/docker/proxy-config-single.yaml +12 -0
- ibm_watsonx_orchestrate/flow_builder/flows/flow.py +15 -5
- ibm_watsonx_orchestrate/flow_builder/utils.py +78 -48
- ibm_watsonx_orchestrate/run/connections.py +4 -4
- {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/METADATA +1 -1
- {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/RECORD +37 -32
- {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.6.0b0.dist-info → ibm_watsonx_orchestrate-1.7.0a0.dist-info}/licenses/LICENSE +0 -0
@@ -1,9 +1,10 @@
|
|
1
1
|
import logging
|
2
2
|
import rich
|
3
3
|
import jwt
|
4
|
+
import sys
|
4
5
|
|
5
6
|
from ibm_watsonx_orchestrate.cli.config import Config, ENV_WXO_URL_OPT, ENVIRONMENTS_SECTION_HEADER, CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT, CHAT_UI_PORT
|
6
|
-
from ibm_watsonx_orchestrate.client.utils import is_local_dev, AUTH_CONFIG_FILE_FOLDER, AUTH_SECTION_HEADER, AUTH_MCSP_TOKEN_OPT, AUTH_CONFIG_FILE
|
7
|
+
from ibm_watsonx_orchestrate.client.utils import is_local_dev, is_ibm_cloud, AUTH_CONFIG_FILE_FOLDER, AUTH_SECTION_HEADER, AUTH_MCSP_TOKEN_OPT, AUTH_CONFIG_FILE
|
7
8
|
|
8
9
|
from ibm_watsonx_orchestrate.client.agents.agent_client import AgentClient
|
9
10
|
|
@@ -19,7 +20,41 @@ class ChannelsWebchatController:
|
|
19
20
|
def get_native_client(self):
|
20
21
|
self.native_client = instantiate_client(AgentClient)
|
21
22
|
return self.native_client
|
22
|
-
|
23
|
+
|
24
|
+
def extract_tenant_id_from_crn(self, crn: str) -> str:
|
25
|
+
is_ibm_cloud_env = is_ibm_cloud()
|
26
|
+
if is_ibm_cloud_env:
|
27
|
+
try:
|
28
|
+
parts = crn.split("a/")[1].split(":")
|
29
|
+
account_part = parts[0]
|
30
|
+
instance_part = parts[1]
|
31
|
+
tenant_id = f"{account_part}_{instance_part}"
|
32
|
+
return tenant_id
|
33
|
+
except (IndexError, AttributeError):
|
34
|
+
raise ValueError(f"Invalid CRN format: {crn}")
|
35
|
+
else:
|
36
|
+
try:
|
37
|
+
parts = crn.split("sub/")[1].split(":")
|
38
|
+
account_part = parts[0]
|
39
|
+
instance_part = parts[1]
|
40
|
+
tenant_id = f"{account_part}_{instance_part}"
|
41
|
+
return tenant_id
|
42
|
+
except (IndexError, AttributeError):
|
43
|
+
raise ValueError(f"Invalid CRN format: {crn}")
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
def check_crn_is_correct(self, crn: str):
|
48
|
+
parts = crn.split("a/")[1].split(":")
|
49
|
+
instance_part_crn = parts[1]
|
50
|
+
cfg = Config()
|
51
|
+
active_env = cfg.read(CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT)
|
52
|
+
url = cfg.get(ENVIRONMENTS_SECTION_HEADER, active_env, ENV_WXO_URL_OPT)
|
53
|
+
instance_part_url = url.rstrip("/").split("/")[-1]
|
54
|
+
if instance_part_crn == instance_part_url:
|
55
|
+
return True
|
56
|
+
else:
|
57
|
+
return False
|
23
58
|
|
24
59
|
def get_agent_id(self, agent_name: str):
|
25
60
|
native_client = self.get_native_client()
|
@@ -39,7 +74,7 @@ class ChannelsWebchatController:
|
|
39
74
|
raise ValueError(f"No agent found with the name '{agent_name}'")
|
40
75
|
|
41
76
|
agent = existing_native_agents[0]
|
42
|
-
agent_environments = agent.get("environments", [])
|
77
|
+
agent_environments = agent.get("environments", [])
|
43
78
|
|
44
79
|
is_local = is_local_dev()
|
45
80
|
target_env = env or 'draft'
|
@@ -56,15 +91,37 @@ class ChannelsWebchatController:
|
|
56
91
|
logger.error(f'This agent does not exist in the {env} environment. You need to deploy it to {env} before you can embed the agent')
|
57
92
|
exit(1)
|
58
93
|
|
59
|
-
|
94
|
+
if target_env == 'draft' and is_local == False:
|
95
|
+
logger.error(f'For SAAS, please ensure this agent exists in a Live Environment')
|
96
|
+
exit(1)
|
97
|
+
|
60
98
|
|
61
99
|
|
100
|
+
return filtered_environments[0].get("id")
|
101
|
+
|
62
102
|
def get_tennent_id(self):
|
63
103
|
auth_cfg = Config(AUTH_CONFIG_FILE_FOLDER, AUTH_CONFIG_FILE)
|
64
104
|
|
65
105
|
cfg = Config()
|
66
106
|
active_env = cfg.read(CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT)
|
67
|
-
|
107
|
+
|
108
|
+
existing_auth_config = auth_cfg.get(AUTH_SECTION_HEADER).get(active_env, {})
|
109
|
+
|
110
|
+
existing_token = existing_auth_config.get(AUTH_MCSP_TOKEN_OPT) if existing_auth_config else None
|
111
|
+
token = jwt.decode(existing_token, options={"verify_signature": False})
|
112
|
+
crn = ""
|
113
|
+
crn = token.get('aud', None)
|
114
|
+
|
115
|
+
tenant_id = self.extract_tenant_id_from_crn(crn)
|
116
|
+
return tenant_id
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
def get_tenant_id_local(self):
|
121
|
+
auth_cfg = Config(AUTH_CONFIG_FILE_FOLDER, AUTH_CONFIG_FILE)
|
122
|
+
|
123
|
+
cfg = Config()
|
124
|
+
active_env = cfg.read(CONTEXT_SECTION_HEADER, CONTEXT_ACTIVE_ENV_OPT)
|
68
125
|
|
69
126
|
existing_auth_config = auth_cfg.get(AUTH_SECTION_HEADER).get(active_env, {})
|
70
127
|
|
@@ -72,10 +129,7 @@ class ChannelsWebchatController:
|
|
72
129
|
|
73
130
|
token = jwt.decode(existing_token, options={"verify_signature": False})
|
74
131
|
tenant_id = ""
|
75
|
-
|
76
|
-
tenant_id = token.get('woTenantId', None)
|
77
|
-
else:
|
78
|
-
tenant_id = token.get('tenantId', None)
|
132
|
+
tenant_id = token.get('woTenantId', None)
|
79
133
|
|
80
134
|
return tenant_id
|
81
135
|
|
@@ -99,41 +153,70 @@ class ChannelsWebchatController:
|
|
99
153
|
|
100
154
|
|
101
155
|
def create_webchat_embed_code(self):
|
102
|
-
|
156
|
+
crn = None
|
157
|
+
is_ibm_cloud_env = is_ibm_cloud()
|
158
|
+
is_local = is_local_dev()
|
159
|
+
if is_ibm_cloud_env is True:
|
160
|
+
crn = input("Please enter your CRN which can be gotten from the IBM Cloud UI: ")
|
161
|
+
if crn == "":
|
162
|
+
logger.error("You must enter your CRN for IBM Cloud instances")
|
163
|
+
sys.exit(1)
|
164
|
+
is_crn_correct = self.check_crn_is_correct(crn)
|
165
|
+
if is_crn_correct == False:
|
166
|
+
logger.error("Invalid CRN format provided.")
|
167
|
+
|
168
|
+
if is_ibm_cloud_env and crn is not None:
|
169
|
+
tenant_id = self.extract_tenant_id_from_crn(crn)
|
170
|
+
elif is_ibm_cloud_env is False and is_local is False:
|
171
|
+
tenant_id = self.get_tennent_id()
|
172
|
+
elif is_local:
|
173
|
+
tenant_id = self.get_tenant_id_local()
|
103
174
|
host_url = self.get_host_url()
|
104
175
|
agent_id = self.get_agent_id(self.agent_name)
|
105
176
|
agent_env_id = self.get_environment_id(self.agent_name, self.env)
|
106
177
|
|
107
|
-
is_local = is_local_dev()
|
108
178
|
script_path = (
|
109
179
|
"/wxoLoader.js?embed=true"
|
110
180
|
if is_local
|
111
181
|
else "/wxochat/wxoLoader.js?embed=true"
|
112
182
|
)
|
113
183
|
|
184
|
+
config_lines = [
|
185
|
+
f'orchestrationID: "{tenant_id}"',
|
186
|
+
f'hostURL: "{host_url}"',
|
187
|
+
'rootElementID: "root"',
|
188
|
+
'showLauncher: true',
|
189
|
+
]
|
190
|
+
|
191
|
+
# Conditional fields for IBM Cloud
|
192
|
+
if is_ibm_cloud_env:
|
193
|
+
config_lines.append(f'crn: "{crn}"')
|
194
|
+
if is_ibm_cloud_env:
|
195
|
+
config_lines.append(f'deploymentPlatform: "ibmcloud"')
|
196
|
+
|
197
|
+
config_lines.append(f"""chatOptions: {{
|
198
|
+
agentId: "{agent_id}",
|
199
|
+
agentEnvironmentId: "{agent_env_id}"
|
200
|
+
}}""")
|
201
|
+
|
202
|
+
config_body = ",\n ".join(config_lines)
|
203
|
+
|
114
204
|
script = f"""
|
115
205
|
<script>
|
116
206
|
window.wxOConfiguration = {{
|
117
|
-
|
118
|
-
hostURL: "{host_url}",
|
119
|
-
rootElementID: "root",
|
120
|
-
showLauncher: true,
|
121
|
-
chatOptions: {{
|
122
|
-
agentId: "{agent_id}",
|
123
|
-
agentEnvironmentId: "{agent_env_id}"
|
124
|
-
}},
|
207
|
+
{config_body}
|
125
208
|
}};
|
126
209
|
|
127
210
|
setTimeout(function () {{
|
128
211
|
const script = document.createElement('script');
|
129
212
|
script.src = `${{window.wxOConfiguration.hostURL}}{script_path}`;
|
130
213
|
script.addEventListener('load', function () {{
|
131
|
-
|
214
|
+
wxoLoader.init();
|
132
215
|
}});
|
133
216
|
document.head.appendChild(script);
|
134
217
|
}}, 0);
|
135
218
|
</script>
|
136
|
-
|
219
|
+
"""
|
137
220
|
|
138
221
|
rich.print(script)
|
139
222
|
return script
|
@@ -191,31 +191,31 @@ def set_credentials_connection_command(
|
|
191
191
|
typer.Option(
|
192
192
|
'--client-id',
|
193
193
|
# help='For oauth_auth_on_behalf_of_flow, oauth_auth_code_flow, oauth_auth_implicit_flow, oauth_auth_password_flow and oauth_auth_client_credentials_flow, the client_id to authenticate against the application token server'
|
194
|
-
help='For oauth_auth_on_behalf_of_flow, the client_id to authenticate against the application token server'
|
194
|
+
help='For oauth_auth_on_behalf_of_flow and oauth_auth_client_credentials_flow, the client_id to authenticate against the application token server'
|
195
|
+
)
|
196
|
+
] = None,
|
197
|
+
client_secret: Annotated[
|
198
|
+
str,
|
199
|
+
typer.Option(
|
200
|
+
'--client-secret',
|
201
|
+
help='For oauth_auth_client_credentials_flow, the client_secret to authenticate with'
|
195
202
|
)
|
196
203
|
] = None,
|
197
|
-
# client_secret: Annotated[
|
198
|
-
# str,
|
199
|
-
# typer.Option(
|
200
|
-
# '--client-secret',
|
201
|
-
# help='For oauth_auth_code_flow, oauth_auth_password_flow and oauth_auth_client_credentials_flow, the client_secret to authenticate with'
|
202
|
-
# )
|
203
|
-
# ] = None,
|
204
204
|
token_url: Annotated[
|
205
205
|
str,
|
206
206
|
typer.Option(
|
207
207
|
'--token-url',
|
208
208
|
# help='For oauth_auth_on_behalf_of_flow, oauth_auth_code_flow, oauth_auth_password_flow and oauth_auth_client_credentials_flow, the url of the application token server'
|
209
|
-
help='For oauth_auth_on_behalf_of_flow, the url of the application token server'
|
209
|
+
help='For oauth_auth_on_behalf_of_flow and oauth_auth_client_credentials_flow, the url of the application token server'
|
210
|
+
)
|
211
|
+
] = None,
|
212
|
+
auth_url: Annotated[
|
213
|
+
str,
|
214
|
+
typer.Option(
|
215
|
+
'--auth-url',
|
216
|
+
help='For oauth_auth_code_flow, the url of the application token server'
|
210
217
|
)
|
211
218
|
] = None,
|
212
|
-
# auth_url: Annotated[
|
213
|
-
# str,
|
214
|
-
# typer.Option(
|
215
|
-
# '--auth-url',
|
216
|
-
# help='For oauth_auth_code_flow, oauth_auth_implicit_flow and oauth_auth_password_flow, the url of the application token server'
|
217
|
-
# )
|
218
|
-
# ] = None,
|
219
219
|
grant_type: Annotated[
|
220
220
|
str,
|
221
221
|
typer.Option(
|
@@ -223,6 +223,13 @@ def set_credentials_connection_command(
|
|
223
223
|
help='For oauth_auth_on_behalf_of_flow, the grant type used by the application token server'
|
224
224
|
)
|
225
225
|
] = None,
|
226
|
+
scopes: Annotated[
|
227
|
+
List[str],
|
228
|
+
typer.Option(
|
229
|
+
'--scopes',
|
230
|
+
help='For oauth_auth_code_flow and oauth_auth_client_credentials_flow, the optional scopes used by the application token server'
|
231
|
+
)
|
232
|
+
] = None,
|
226
233
|
entries: Annotated[
|
227
234
|
List[str],
|
228
235
|
typer.Option(
|
@@ -239,10 +246,11 @@ def set_credentials_connection_command(
|
|
239
246
|
token=token,
|
240
247
|
api_key=api_key,
|
241
248
|
client_id=client_id,
|
242
|
-
|
249
|
+
client_secret=client_secret,
|
243
250
|
token_url=token_url,
|
244
|
-
|
251
|
+
auth_url=auth_url,
|
245
252
|
grant_type=grant_type,
|
253
|
+
scopes=scopes,
|
246
254
|
entries=entries
|
247
255
|
)
|
248
256
|
|
@@ -15,19 +15,19 @@ from ibm_watsonx_orchestrate.agent_builder.connections.types import (
|
|
15
15
|
ConnectionType,
|
16
16
|
IdpConfigData,
|
17
17
|
IdpConfigDataBody,
|
18
|
-
AppConfigData,
|
18
|
+
AppConfigData,
|
19
19
|
BasicAuthCredentials,
|
20
20
|
BearerTokenAuthCredentials,
|
21
21
|
APIKeyAuthCredentials,
|
22
22
|
# OAuth2AuthCodeCredentials,
|
23
|
-
|
23
|
+
OAuth2ClientCredentials,
|
24
24
|
# OAuth2ImplicitCredentials,
|
25
25
|
# OAuth2PasswordCredentials,
|
26
26
|
OAuthOnBehalfOfCredentials,
|
27
27
|
KeyValueConnectionCredentials,
|
28
28
|
CREDENTIALS,
|
29
29
|
IdentityProviderCredentials,
|
30
|
-
OAUTH_CONNECTION_TYPES
|
30
|
+
OAUTH_CONNECTION_TYPES, OAuth2AuthCodeCredentials
|
31
31
|
|
32
32
|
)
|
33
33
|
|
@@ -136,40 +136,31 @@ def _validate_connection_params(type: ConnectionType, **args) -> None:
|
|
136
136
|
f"Missing flags --api-key is required for type {type}"
|
137
137
|
)
|
138
138
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
# if type in (OAUTH_CONNECTION_TYPES.difference({ConnectionType.OAUTH2_IMPLICIT, ConnectionType.OAUTH_ON_BEHALF_OF_FLOW})) and args.get('client_secret') is None:
|
145
|
-
# raise typer.BadParameter(
|
146
|
-
# f"Missing flags --client-secret is required for type {type}"
|
147
|
-
# )
|
148
|
-
|
149
|
-
# if type in (OAUTH_CONNECTION_TYPES.difference({ConnectionType.OAUTH2_IMPLICIT})) and args.get('token_url') is None:
|
150
|
-
# raise typer.BadParameter(
|
151
|
-
# f"Missing flags --token-url is required for type {type}"
|
152
|
-
# )
|
139
|
+
if type in {ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH2_AUTH_CODE} and args.get('client_secret') is None:
|
140
|
+
raise typer.BadParameter(
|
141
|
+
f"Missing flags --client-secret is required for type {type}"
|
142
|
+
)
|
153
143
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
144
|
+
if type in {ConnectionType.OAUTH2_AUTH_CODE} and args.get('auth_url') is None:
|
145
|
+
raise typer.BadParameter(
|
146
|
+
f"Missing flags --auth-url is required for type {type}"
|
147
|
+
)
|
158
148
|
|
159
|
-
if type
|
149
|
+
if type in {ConnectionType.OAUTH_ON_BEHALF_OF_FLOW, ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH2_AUTH_CODE} and (
|
160
150
|
args.get('client_id') is None
|
161
151
|
):
|
162
152
|
raise typer.BadParameter(
|
163
153
|
f"Missing flags --client-id is required for type {type}"
|
164
154
|
)
|
165
155
|
|
166
|
-
if type
|
156
|
+
if type in {ConnectionType.OAUTH_ON_BEHALF_OF_FLOW, ConnectionType.OAUTH2_CLIENT_CREDS, ConnectionType.OAUTH2_AUTH_CODE} and (
|
167
157
|
args.get('token_url') is None
|
168
158
|
):
|
169
159
|
raise typer.BadParameter(
|
170
160
|
f"Missing flags --token-url is required for type {type}"
|
171
161
|
)
|
172
162
|
|
163
|
+
|
173
164
|
if type == ConnectionType.OAUTH_ON_BEHALF_OF_FLOW and (
|
174
165
|
args.get('grant_type') is None
|
175
166
|
):
|
@@ -200,19 +191,21 @@ def _get_credentials(type: ConnectionType, **kwargs):
|
|
200
191
|
return APIKeyAuthCredentials(
|
201
192
|
api_key=kwargs.get("api_key")
|
202
193
|
)
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
194
|
+
case ConnectionType.OAUTH2_AUTH_CODE:
|
195
|
+
return OAuth2AuthCodeCredentials(
|
196
|
+
authorization_url=kwargs.get("auth_url"),
|
197
|
+
client_id=kwargs.get("client_id"),
|
198
|
+
client_secret=kwargs.get("client_secret"),
|
199
|
+
token_url=kwargs.get("token_url"),
|
200
|
+
scopes=kwargs.get("scopes")
|
201
|
+
)
|
202
|
+
case ConnectionType.OAUTH2_CLIENT_CREDS:
|
203
|
+
return OAuth2ClientCredentials(
|
204
|
+
client_id=kwargs.get("client_id"),
|
205
|
+
client_secret=kwargs.get("client_secret"),
|
206
|
+
token_url=kwargs.get("token_url"),
|
207
|
+
scopes=kwargs.get("scopes")
|
208
|
+
)
|
216
209
|
# case ConnectionType.OAUTH2_IMPLICIT:
|
217
210
|
# return OAuth2ImplicitCredentials(
|
218
211
|
# authorization_url=kwargs.get("auth_url"),
|
@@ -267,11 +260,14 @@ def add_configuration(config: ConnectionConfiguration) -> None:
|
|
267
260
|
logger.warning(f"Detected a change in sso from '{existing_configuration.sso}' to '{config.sso}'. The associated credentials will be removed.")
|
268
261
|
should_delete_credentials = True
|
269
262
|
|
263
|
+
existing_conn_type = get_connection_type(security_scheme=existing_configuration.security_scheme, auth_type=existing_configuration.auth_type)
|
264
|
+
use_app_credentials = existing_conn_type in OAUTH_CONNECTION_TYPES
|
265
|
+
|
270
266
|
if should_delete_credentials:
|
271
267
|
try:
|
272
|
-
existing_credentials = client.get_credentials(app_id=app_id, env=environment,
|
268
|
+
existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials)
|
273
269
|
if existing_credentials:
|
274
|
-
client.delete_credentials(app_id=app_id, env=environment,
|
270
|
+
client.delete_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials)
|
275
271
|
except:
|
276
272
|
logger.error(f"Error removing credentials for connection '{app_id}' in environment '{environment}'. No changes have been made to the configuration.")
|
277
273
|
sys.exit(1)
|
@@ -289,11 +285,11 @@ def add_configuration(config: ConnectionConfiguration) -> None:
|
|
289
285
|
logger.error(response_text)
|
290
286
|
exit(1)
|
291
287
|
|
292
|
-
def add_credentials(app_id: str, environment: ConnectionEnvironment,
|
288
|
+
def add_credentials(app_id: str, environment: ConnectionEnvironment, use_app_credentials: bool, credentials: CREDENTIALS) -> None:
|
293
289
|
client = get_connections_client()
|
294
290
|
try:
|
295
|
-
existing_credentials = client.get_credentials(app_id=app_id, env=environment,
|
296
|
-
if
|
291
|
+
existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials)
|
292
|
+
if use_app_credentials:
|
297
293
|
payload = {
|
298
294
|
"app_credentials": credentials.model_dump(exclude_none=True)
|
299
295
|
}
|
@@ -304,9 +300,9 @@ def add_credentials(app_id: str, environment: ConnectionEnvironment, use_sso: bo
|
|
304
300
|
|
305
301
|
logger.info(f"Setting credentials for environment '{environment}' on connection '{app_id}'")
|
306
302
|
if existing_credentials:
|
307
|
-
client.update_credentials(app_id=app_id, env=environment,
|
303
|
+
client.update_credentials(app_id=app_id, env=environment, use_app_credentials=use_app_credentials, payload=payload)
|
308
304
|
else:
|
309
|
-
client.create_credentials(app_id=app_id,env=environment,
|
305
|
+
client.create_credentials(app_id=app_id,env=environment, use_app_credentials=use_app_credentials, payload=payload)
|
310
306
|
logger.info(f"Credentials successfully set for '{environment}' environment of connection '{app_id}'")
|
311
307
|
except requests.HTTPError as e:
|
312
308
|
response = e.response
|
@@ -318,7 +314,7 @@ def add_identity_provider(app_id: str, environment: ConnectionEnvironment, idp:
|
|
318
314
|
client = get_connections_client()
|
319
315
|
|
320
316
|
try:
|
321
|
-
existing_credentials = client.get_credentials(app_id=app_id, env=environment,
|
317
|
+
existing_credentials = client.get_credentials(app_id=app_id, env=environment, use_app_credentials=True)
|
322
318
|
|
323
319
|
payload = {
|
324
320
|
"idp_credentials": idp.model_dump()
|
@@ -326,9 +322,9 @@ def add_identity_provider(app_id: str, environment: ConnectionEnvironment, idp:
|
|
326
322
|
|
327
323
|
logger.info(f"Setting identity provider for environment '{environment}' on connection '{app_id}'")
|
328
324
|
if existing_credentials:
|
329
|
-
client.update_credentials(app_id=app_id, env=environment,
|
325
|
+
client.update_credentials(app_id=app_id, env=environment, use_app_credentials=True, payload=payload)
|
330
326
|
else:
|
331
|
-
client.create_credentials(app_id=app_id,env=environment,
|
327
|
+
client.create_credentials(app_id=app_id,env=environment, use_app_credentials=True, payload=payload)
|
332
328
|
logger.info(f"Identity provider successfully set for '{environment}' environment of connection '{app_id}'")
|
333
329
|
except requests.HTTPError as e:
|
334
330
|
response = e.response
|
@@ -387,11 +383,17 @@ def list_connections(environment: ConnectionEnvironment | None, verbose: bool =
|
|
387
383
|
non_configured_table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True, title="*Non-Configured")
|
388
384
|
draft_table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True, title="Draft")
|
389
385
|
live_table = rich.table.Table(show_header=True, header_style="bold white", show_lines=True, title="Live")
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
386
|
+
default_args = {"justify": "center", "no_wrap": True}
|
387
|
+
column_args = {
|
388
|
+
"App ID": {"overflow": "fold"},
|
389
|
+
"Auth Type": {},
|
390
|
+
"Type": {},
|
391
|
+
"Credentials Set/ Connected": {}
|
392
|
+
}
|
393
|
+
for column in column_args:
|
394
|
+
draft_table.add_column(column,**default_args, **column_args[column])
|
395
|
+
live_table.add_column(column,**default_args, **column_args[column])
|
396
|
+
non_configured_table.add_column(column,**default_args, **column_args[column])
|
395
397
|
|
396
398
|
for conn in connections:
|
397
399
|
if conn.environment is None:
|
@@ -463,11 +465,6 @@ def configure_connection(**kwargs) -> None:
|
|
463
465
|
|
464
466
|
config = ConnectionConfiguration.model_validate(kwargs)
|
465
467
|
|
466
|
-
# TODO: Remove once Oauth is supported on local
|
467
|
-
if config.security_scheme == ConnectionSecurityScheme.OAUTH2 and is_local_dev():
|
468
|
-
logger.error("Use of OAuth connections unsupported for local development at this time.")
|
469
|
-
sys.exit(1)
|
470
|
-
|
471
468
|
add_configuration(config)
|
472
469
|
|
473
470
|
def set_credentials_connection(
|
@@ -484,11 +481,12 @@ def set_credentials_connection(
|
|
484
481
|
|
485
482
|
sso_enabled = config.sso
|
486
483
|
conn_type = get_connection_type(security_scheme=config.security_scheme, auth_type=config.auth_type)
|
484
|
+
use_app_credentials = conn_type in OAUTH_CONNECTION_TYPES
|
487
485
|
|
488
486
|
_validate_connection_params(type=conn_type, **kwargs)
|
489
487
|
credentials = _get_credentials(type=conn_type, **kwargs)
|
490
488
|
|
491
|
-
add_credentials(app_id=app_id, environment=environment,
|
489
|
+
add_credentials(app_id=app_id, environment=environment, use_app_credentials=use_app_credentials, credentials=credentials)
|
492
490
|
|
493
491
|
def set_identity_provider_connection(
|
494
492
|
app_id: str,
|