kobai-sdk 0.2.8rc15__tar.gz → 0.3.0rc1__tar.gz

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.

Potentially problematic release.


This version of kobai-sdk might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: kobai-sdk
3
- Version: 0.2.8rc15
3
+ Version: 0.3.0rc1
4
4
  Summary: A package that enables interaction with a Kobai tenant.
5
5
  Author-email: Ryan Oattes <ryan@kobai.io>
6
6
  License: Apache License
@@ -223,12 +223,14 @@ Requires-Dist: langchain-core
223
223
  Requires-Dist: langchain-community
224
224
  Requires-Dist: langchain_openai
225
225
  Requires-Dist: databricks_langchain
226
+ Requires-Dist: sentence-transformers
226
227
  Provides-Extra: dev
227
228
  Requires-Dist: black; extra == "dev"
228
229
  Requires-Dist: bumpver; extra == "dev"
229
230
  Requires-Dist: isort; extra == "dev"
230
231
  Requires-Dist: pip-tools; extra == "dev"
231
232
  Requires-Dist: pytest; extra == "dev"
233
+ Dynamic: license-file
232
234
 
233
235
  # Kobai SDK for Python (Alpha)
234
236
 
@@ -0,0 +1,66 @@
1
+ from azure.identity import DeviceCodeCredential
2
+ from azure.identity import OnBehalfOfCredential
3
+ from azure.core.exceptions import AzureError
4
+
5
+ def get_scope(client_id: str = None, target_client_id: str = None, scope: str = None):
6
+
7
+ """
8
+ Get the default scopes
9
+
10
+ Parameters:
11
+ client_id (str): Client ID or Application ID from app registration with IDM.
12
+ target_client_id (str): Kobai IDM client ID.
13
+ scope (str): Scope to be passed
14
+ """
15
+ if scope is not None:
16
+ return scope
17
+
18
+ if target_client_id is None:
19
+ target_client_id = client_id
20
+
21
+ return f"openid profile offline_access api://{target_client_id}/Kobai.Access"
22
+
23
+ def device_code(tenant_id: str, client_id: str, target_client_id: str = None, scope: str = None):
24
+
25
+ """
26
+ Authenticate using the device code flow and get the access token
27
+
28
+ Parameters:
29
+ tenant_id (str): Tenant ID or Directory ID for IDM.
30
+ client_id (str): Client ID or Application ID from app registration with IDM.
31
+ target_client_id (str): Kobai IDM client ID.
32
+ scope (str): Scope to be passed
33
+ """
34
+ credential = DeviceCodeCredential(client_id=client_id, tenant_id=tenant_id)
35
+
36
+ try:
37
+ token = credential.get_token(get_scope(client_id, target_client_id, scope))
38
+ return token.token
39
+ except AzureError as e:
40
+ return e
41
+
42
+ def onbehalf(tenant_id: str, client_id: str, client_secret: str, access_token: str, target_client_id: str = None, scope: str = None):
43
+
44
+ """
45
+ Authenticate using the onbehalf flow and get the access token
46
+
47
+ Parameters:
48
+ tenant_id (str): Tenant ID or Directory ID for IDM.
49
+ client_id (str): Client ID or Application ID from app registration with IDM.
50
+ client_secret (str): Client secret from app registration with IDM.
51
+ access_token (str): Access token to be exchanged.
52
+ target_client_id (str): Kobai IDM client ID.
53
+ scope (str): Scope to be passed
54
+ """
55
+ credential = OnBehalfOfCredential(
56
+ tenant_id=tenant_id,
57
+ client_id=client_id,
58
+ client_secret=client_secret,
59
+ user_assertion=access_token
60
+ )
61
+
62
+ try:
63
+ token = credential.get_token(get_scope(client_id, target_client_id, scope))
64
+ return token.token
65
+ except AzureError as e:
66
+ return e
@@ -19,7 +19,10 @@ class TenantAPI:
19
19
  self.session = requests.Session()
20
20
 
21
21
  if token is not None:
22
- self.session.headers.update({'Authorization': 'Bearer %s' % self.token})
22
+ if token.startswith('Bearer'):
23
+ self.session.headers.update({'Authorization': '%s' % self.token})
24
+ else:
25
+ self.session.headers.update({'Authorization': 'Bearer %s' % self.token})
23
26
 
24
27
  self.ssl_verify = verify
25
28
  self.session.verify = verify
@@ -112,7 +115,7 @@ class TenantAPI:
112
115
 
113
116
  if op_desc is None:
114
117
  op_desc = "operation"
115
-
118
+
116
119
  response = self.session.get(
117
120
  self.base_uri + uri,
118
121
  params=params,
@@ -3,7 +3,6 @@ import json
3
3
  import urllib
4
4
  import urllib.parse
5
5
 
6
- from azure.identity import DeviceCodeCredential
7
6
  from pyspark.sql import SparkSession
8
7
 
9
8
  from langchain_community.chat_models import ChatDatabricks
@@ -64,84 +63,76 @@ class TenantClient:
64
63
  # MS Entra Auth
65
64
  ########################################
66
65
 
67
- def authenticate(self, client_id: str, tenant_id: str, run_ai_init: bool = True, override_username: str = None):
66
+ def use_browser_token(self, access_token, run_ai_init: bool = True):
68
67
 
69
68
  """
70
69
  Authenticate the TenantClient with the Kobai instance. Returns nothing, but stores bearer token in client.
71
-
72
- Limitations:
73
- Currently supports only authentication via Microsoft Entra (AzureAD) using DecideCode OAuth flow.
70
+ This is a fall-back method for instances not using OAuth. It is inconvenient as a Kobai Bearer Token must be retrieved from the users browser.
74
71
 
75
72
  Parameters:
76
- client_id (str): Client ID or Application ID from app registration with IDM.
77
- tenant_id (str): Tenant ID or Directory ID for IDM.
73
+ access_token (str): Bearer token for Kobai app session.
78
74
  """
75
+ self._init_post_auth_success(access_token, run_ai_init)
79
76
 
80
- credential = DeviceCodeCredential(client_id=client_id, tenant_id=tenant_id)
81
-
82
- access = credential.authenticate()
83
-
84
- oauth_token = access.serialize()
85
- print(oauth_token)
86
- user_name = json.loads(access.serialize())["username"]
77
+ def use_access_token(self, access_token: str, id_token: str = None, tenant_id: str = None, run_ai_init: bool = True):
87
78
 
88
- if override_username is not None:
89
- user_name = override_username
90
-
91
- user_name_query_params={ 'userName' : user_name}
92
- tenants_response = self.api_client._TenantAPI__run_get('/user-mgmt-svcs/auth/tenants?'+urllib.parse.urlencode(user_name_query_params))
93
-
94
-
95
- tenant_list = json.loads(tenants_response.content.decode("utf-8"))
79
+ """
80
+ Authenticate the TenantClient with the Kobai instance. Returns nothing, but stores bearer token in client.
96
81
 
97
- tenant_id = ""
98
- for t in tenant_list:
99
- if t["name"] == self.tenant_name:
100
- tenant_id = t["id"]
82
+ Parameters:
83
+ access_token (str): Access token of the IDM server to be used to obtained the kobai access token.
84
+ id_token (str): ID token of the IDM server to be used to obtained the onbehalf access token.
85
+ tenant_id (str): Kobai tenant id.
86
+ """
101
87
 
102
88
  token_request_payload={
89
+ "tenantName" : self.tenant_name,
103
90
  "tenantId" : tenant_id,
104
- "oauthToken" : oauth_token,
105
- "userName" : user_name
91
+ "idToken" : id_token,
92
+ "accessToken" : access_token
106
93
  }
107
- token_response = self.api_client._TenantAPI__run_post(
108
- '/user-mgmt-svcs/auth/oauth/devicecode',
94
+
95
+ response = self.api_client._TenantAPI__run_post(
96
+ '/user-mgmt-svcs/auth/oauth/external/onbehalf/token',
109
97
  token_request_payload
110
98
  )
111
- access_token = token_response.content.decode()
112
- self.token = access_token
113
-
114
- self.__api_init_session()
115
- self.__set_tenant_solutionid()
116
- if run_ai_init:
117
- self.init_ai_components()
118
-
119
- print("Authentication Successful.")
120
99
 
121
- def authenticate_browser_token(self, access_token, run_ai_init: bool = True):
100
+ kb_access_token = response.headers.get('Authorization')
101
+ self.use_browser_token(kb_access_token, run_ai_init)
102
+
103
+ def get_tenants(self, id_token: str = None):
122
104
 
123
105
  """
124
- Authenticate the TenantClient with the Kobai instance. Returns nothing, but stores bearer token in client.
125
- This is a fall-back method for instances not using OAuth. It is inconvenient as a Kobai Bearer Token must be retrieved from the users browser.
106
+ Get the tenants associated with the given id token of the IDM. Returns tenants list.
126
107
 
127
108
  Parameters:
128
- access_token (str): Bearer token for Kobai app session.
109
+ id_token (str): ID token of the IDM server to be used to obtain user tenants.
129
110
  """
130
111
 
112
+ if (id_token is not None) :
113
+ token_request_payload={
114
+ "idToken" : id_token
115
+ }
116
+
117
+ response = self.api_client._TenantAPI__run_post(
118
+ '/user-mgmt-svcs/auth/oauth/external/token/tenants',
119
+ token_request_payload
120
+ )
121
+
122
+ self.tenant_list = response.json()
123
+ return self.tenant_list
124
+
125
+ def __api_init_session(self):
126
+ self.api_client = tenant_api.TenantAPI(self.token, self.uri, verify=self.ssl_verify, proxies=self.proxies )
127
+
128
+ def _init_post_auth_success(self, access_token, run_ai_init: bool = True):
131
129
  self.token = access_token
132
-
133
130
  self.__api_init_session()
134
131
  self.__set_tenant_solutionid()
135
132
  if run_ai_init:
136
133
  self.init_ai_components()
137
-
138
-
139
134
  print("Authentication Successful.")
140
135
 
141
- def __api_init_session(self):
142
- self.api_client = tenant_api.TenantAPI(self.token, self.uri, verify=self.ssl_verify, proxies=self.proxies )
143
-
144
-
145
136
  ########################################
146
137
  # Basic Config
147
138
  ########################################
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: kobai-sdk
3
- Version: 0.2.8rc15
3
+ Version: 0.3.0rc1
4
4
  Summary: A package that enables interaction with a Kobai tenant.
5
5
  Author-email: Ryan Oattes <ryan@kobai.io>
6
6
  License: Apache License
@@ -223,12 +223,14 @@ Requires-Dist: langchain-core
223
223
  Requires-Dist: langchain-community
224
224
  Requires-Dist: langchain_openai
225
225
  Requires-Dist: databricks_langchain
226
+ Requires-Dist: sentence-transformers
226
227
  Provides-Extra: dev
227
228
  Requires-Dist: black; extra == "dev"
228
229
  Requires-Dist: bumpver; extra == "dev"
229
230
  Requires-Dist: isort; extra == "dev"
230
231
  Requires-Dist: pip-tools; extra == "dev"
231
232
  Requires-Dist: pytest; extra == "dev"
233
+ Dynamic: license-file
232
234
 
233
235
  # Kobai SDK for Python (Alpha)
234
236
 
@@ -7,6 +7,7 @@ kobai/ai_query.py
7
7
  kobai/ai_rag.py
8
8
  kobai/databricks_client.py
9
9
  kobai/demo_tenant_client.py
10
+ kobai/ms_authenticate.py
10
11
  kobai/spark_client.py
11
12
  kobai/tenant_api.py
12
13
  kobai/tenant_client.py
@@ -7,6 +7,7 @@ langchain-core
7
7
  langchain-community
8
8
  langchain_openai
9
9
  databricks_langchain
10
+ sentence-transformers
10
11
 
11
12
  [dev]
12
13
  black
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kobai-sdk"
7
- version = "0.2.8rc15"
7
+ version = "0.3.0rc1"
8
8
  description = "A package that enables interaction with a Kobai tenant."
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Ryan Oattes", email = "ryan@kobai.io" }]
@@ -26,7 +26,8 @@ dependencies = [
26
26
  "langchain-core",
27
27
  "langchain-community",
28
28
  "langchain_openai",
29
- "databricks_langchain"
29
+ "databricks_langchain",
30
+ "sentence-transformers"
30
31
  ]
31
32
  requires-python = ">=3.11"
32
33
 
File without changes
File without changes
File without changes
File without changes