kalbio 0.2.1__py3-none-any.whl → 0.2.3__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.
- kalbio/__init__.py +10 -1
- kalbio/activities.py +7 -8
- kalbio/client.py +114 -19
- kalbio/dashboards.py +2 -2
- kalbio/entity_fields.py +2 -2
- kalbio/exports.py +1 -1
- kalbio/programs.py +4 -4
- kalbio/records.py +3 -2
- {kalbio-0.2.1.dist-info → kalbio-0.2.3.dist-info}/METADATA +8 -6
- kalbio-0.2.3.dist-info/RECORD +19 -0
- kalbio-0.2.1.dist-info/RECORD +0 -19
- {kalbio-0.2.1.dist-info → kalbio-0.2.3.dist-info}/WHEEL +0 -0
kalbio/__init__.py
CHANGED
|
@@ -1 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
2
|
+
|
|
3
|
+
from kalbio.client import KaleidoscopeClient
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
__version__ = version("kalbio")
|
|
7
|
+
except PackageNotFoundError:
|
|
8
|
+
__version__ = "unknown"
|
|
9
|
+
|
|
10
|
+
__all__ = ["KaleidoscopeClient"]
|
kalbio/activities.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Activities Module for Kaleidoscope API Client.
|
|
2
2
|
|
|
3
|
-
This module provides
|
|
3
|
+
This module provides functionality for managing activities (tasks, experiments,
|
|
4
4
|
projects, stages, milestones, and design cycles) within the Kaleidoscope platform. It includes
|
|
5
5
|
models for activities, activity definitions, and properties, as well as service classes for
|
|
6
6
|
performing CRUD operations and managing activity workflows.
|
|
@@ -65,7 +65,7 @@ from kalbio.entity_fields import DataFieldTypeEnum
|
|
|
65
65
|
from kalbio.programs import Program
|
|
66
66
|
from kalbio.labels import Label
|
|
67
67
|
from kalbio.workspace import WorkspaceUser, WorkspaceGroup
|
|
68
|
-
from typing import Any, BinaryIO, List, Literal, Optional, Union
|
|
68
|
+
from typing import Any, BinaryIO, List, Literal, Optional, TypeAlias, Union
|
|
69
69
|
from typing import TYPE_CHECKING
|
|
70
70
|
|
|
71
71
|
if TYPE_CHECKING:
|
|
@@ -153,7 +153,7 @@ class ActivityStatusEnum(str, Enum):
|
|
|
153
153
|
DONE = "done"
|
|
154
154
|
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
ActivityType: TypeAlias = Union[
|
|
157
157
|
Literal["task"],
|
|
158
158
|
Literal["experiment"],
|
|
159
159
|
Literal["project"],
|
|
@@ -671,7 +671,7 @@ class Activity(_KaleidoscopeBaseModel):
|
|
|
671
671
|
setattr(self, k, v)
|
|
672
672
|
|
|
673
673
|
|
|
674
|
-
|
|
674
|
+
ActivityIdentifier: TypeAlias = Union[Activity, str]
|
|
675
675
|
"""Identifier class for Activity
|
|
676
676
|
|
|
677
677
|
Activities are able to be identified by:
|
|
@@ -681,7 +681,7 @@ Activities are able to be identified by:
|
|
|
681
681
|
* UUID
|
|
682
682
|
"""
|
|
683
683
|
|
|
684
|
-
|
|
684
|
+
DefinitionIdentifier: TypeAlias = Union[ActivityDefinition, str]
|
|
685
685
|
"""Identifier class for ActivityDefinition
|
|
686
686
|
|
|
687
687
|
ActivityDefinitions are able to be identified by:
|
|
@@ -876,12 +876,11 @@ class ActivitiesService:
|
|
|
876
876
|
|
|
877
877
|
try:
|
|
878
878
|
payload = {
|
|
879
|
-
"program_ids": program_ids,
|
|
880
879
|
"title": title,
|
|
881
880
|
"activity_type": activity_type,
|
|
882
881
|
"definition_id": self._resolve_definition_id(activity_definition_id),
|
|
883
|
-
"
|
|
884
|
-
"assigned_user_ids": assigned_user_ids,
|
|
882
|
+
"program_ids": program_ids if program_ids else [],
|
|
883
|
+
"assigned_user_ids": assigned_user_ids if assigned_user_ids else [],
|
|
885
884
|
"start_date": start_date.isoformat() if start_date else None,
|
|
886
885
|
"duration": duration,
|
|
887
886
|
}
|
kalbio/client.py
CHANGED
|
@@ -59,8 +59,8 @@ Any file retrieved by the `KaleidoscopeClient` must be of one the above types"""
|
|
|
59
59
|
TIMEOUT_MAXIMUM = 10
|
|
60
60
|
"""Maximum timeout for API requests in seconds."""
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
_env_client_id = os.getenv("KALEIDOSCOPE_API_CLIENT_ID")
|
|
63
|
+
_env_client_secret = os.getenv("KALEIDOSCOPE_API_CLIENT_SECRET")
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
class _TokenResponse(BaseModel):
|
|
@@ -107,21 +107,36 @@ class KaleidoscopeClient:
|
|
|
107
107
|
)
|
|
108
108
|
# Use the client to interact with various services
|
|
109
109
|
programs = client.activities.get_activities()
|
|
110
|
+
|
|
111
|
+
# For applications behind Google Cloud IAP:
|
|
112
|
+
client = KaleidoscopeClient(
|
|
113
|
+
client_id="your_api_client_id",
|
|
114
|
+
client_secret="your_api_client_secret",
|
|
115
|
+
iap_client_id="your_iap_client_id.apps.googleusercontent.com"
|
|
116
|
+
)
|
|
110
117
|
```
|
|
111
118
|
"""
|
|
112
119
|
|
|
113
120
|
_client_id: str
|
|
114
121
|
_client_secret: str
|
|
122
|
+
_additional_headers: dict
|
|
123
|
+
_iap_client_id: Optional[str]
|
|
115
124
|
|
|
116
|
-
_refresh_token: str
|
|
117
|
-
_access_token: str
|
|
118
|
-
|
|
125
|
+
_refresh_token: str = None
|
|
126
|
+
_access_token: str = None
|
|
127
|
+
_auth_refresh_before: Optional[datetime] = None
|
|
128
|
+
|
|
129
|
+
_iap_token: Optional[str] = None
|
|
130
|
+
_iap_refresh_before: Optional[datetime] = None
|
|
119
131
|
|
|
120
132
|
def __init__(
|
|
121
133
|
self,
|
|
122
|
-
client_id: Optional[str] =
|
|
123
|
-
client_secret: Optional[str] =
|
|
134
|
+
client_id: Optional[str] = _env_client_id,
|
|
135
|
+
client_secret: Optional[str] = _env_client_secret,
|
|
124
136
|
url: str = PROD_API_URL,
|
|
137
|
+
additional_headers: dict = {},
|
|
138
|
+
iap_client_id: Optional[str] = None,
|
|
139
|
+
verify_ssl: bool = True,
|
|
125
140
|
):
|
|
126
141
|
"""Initialize the Kaleidoscope API client.
|
|
127
142
|
|
|
@@ -133,6 +148,9 @@ class KaleidoscopeClient:
|
|
|
133
148
|
client_secret (str): The API client secret for authentication.
|
|
134
149
|
url (Optional[str]): The base URL for the API. Defaults to the production
|
|
135
150
|
API URL if not provided.
|
|
151
|
+
iap_client_id (Optional[str]): The OAuth client ID for Google Cloud
|
|
152
|
+
Identity-Aware Proxy. If provided, the client will automatically
|
|
153
|
+
fetch and refresh IAP tokens. Requires the `google-auth` package.
|
|
136
154
|
|
|
137
155
|
Example:
|
|
138
156
|
```python
|
|
@@ -141,6 +159,13 @@ class KaleidoscopeClient:
|
|
|
141
159
|
|
|
142
160
|
# Or rely on environment variables KALEIDOSCOPE_API_CLIENT_ID/SECRET
|
|
143
161
|
client = KaleidoscopeClient()
|
|
162
|
+
|
|
163
|
+
# For applications behind Google Cloud IAP
|
|
164
|
+
client = KaleidoscopeClient(
|
|
165
|
+
client_id="id",
|
|
166
|
+
client_secret="secret",
|
|
167
|
+
iap_client_id="your_iap_client_id.apps.googleusercontent.com"
|
|
168
|
+
)
|
|
144
169
|
```
|
|
145
170
|
"""
|
|
146
171
|
if client_id is None:
|
|
@@ -183,9 +208,35 @@ class KaleidoscopeClient:
|
|
|
183
208
|
|
|
184
209
|
self._client_id = client_id
|
|
185
210
|
self._client_secret = client_secret
|
|
186
|
-
self.
|
|
211
|
+
self.additional_headers = additional_headers
|
|
212
|
+
self._iap_client_id = iap_client_id
|
|
213
|
+
self._verify_ssl = verify_ssl
|
|
214
|
+
|
|
215
|
+
def _refresh_iap_token(self):
|
|
216
|
+
"""Fetch or refresh the IAP ID token.
|
|
217
|
+
|
|
218
|
+
Uses google-auth to obtain an ID token for the configured IAP client ID.
|
|
219
|
+
Supports both service account credentials and user credentials from
|
|
220
|
+
`gcloud auth application-default login`.
|
|
221
|
+
|
|
222
|
+
Raises:
|
|
223
|
+
ImportError: If google-auth is not installed.
|
|
224
|
+
google.auth.exceptions.DefaultCredentialsError: If no valid credentials found.
|
|
225
|
+
"""
|
|
226
|
+
try:
|
|
227
|
+
from google.auth.transport.requests import Request
|
|
228
|
+
from google.oauth2 import id_token
|
|
229
|
+
except ImportError:
|
|
230
|
+
raise ImportError(
|
|
231
|
+
"The 'google-auth' package is required for IAP authentication. "
|
|
232
|
+
"Install it with: pip install google-auth or re-install kalbio with the iap option: "
|
|
233
|
+
"pip install kalbio[iap]"
|
|
234
|
+
)
|
|
235
|
+
self._iap_token = id_token.fetch_id_token(Request(), self._iap_client_id)
|
|
236
|
+
# IAP tokens typically expire in 1 hour; refresh 10 minutes early
|
|
237
|
+
self._iap_refresh_before = datetime.now() + timedelta(minutes=50)
|
|
187
238
|
|
|
188
|
-
def
|
|
239
|
+
def _update_auth_tokens(self, resp: _TokenResponse):
|
|
189
240
|
"""Persist access and refresh tokens and compute the next refresh time.
|
|
190
241
|
|
|
191
242
|
Args:
|
|
@@ -193,7 +244,7 @@ class KaleidoscopeClient:
|
|
|
193
244
|
"""
|
|
194
245
|
self._access_token = resp.access_token
|
|
195
246
|
self._refresh_token = resp.refresh_token
|
|
196
|
-
self.
|
|
247
|
+
self._auth_refresh_before = datetime.now() + timedelta(
|
|
197
248
|
seconds=resp.expires_in - (60 * 10) # add a 10 minute buffer
|
|
198
249
|
)
|
|
199
250
|
|
|
@@ -210,14 +261,16 @@ class KaleidoscopeClient:
|
|
|
210
261
|
"client_id": self._client_id,
|
|
211
262
|
"client_secret": self._client_secret,
|
|
212
263
|
},
|
|
264
|
+
headers={**self._get_iap_headers(), **self.additional_headers},
|
|
213
265
|
timeout=TIMEOUT_MAXIMUM,
|
|
266
|
+
verify=self._verify_ssl,
|
|
214
267
|
)
|
|
215
268
|
if auth_resp.status_code >= 400:
|
|
216
269
|
raise RuntimeError(
|
|
217
270
|
f"Could not connect to server with client_id {self._client_id}: {auth_resp.content}"
|
|
218
271
|
)
|
|
219
272
|
|
|
220
|
-
self.
|
|
273
|
+
self._update_auth_tokens(_TokenResponse.model_validate(auth_resp.json()))
|
|
221
274
|
|
|
222
275
|
def _refresh_auth_token(self):
|
|
223
276
|
"""Refresh the access token using the stored refresh token.
|
|
@@ -234,27 +287,54 @@ class KaleidoscopeClient:
|
|
|
234
287
|
"grant_type": "refresh_token",
|
|
235
288
|
"refresh_token": self._refresh_token,
|
|
236
289
|
},
|
|
290
|
+
headers={**self._get_iap_headers(), **self.additional_headers},
|
|
237
291
|
timeout=TIMEOUT_MAXIMUM,
|
|
292
|
+
verify=self._verify_ssl,
|
|
238
293
|
)
|
|
239
294
|
if auth_resp.status_code >= 400:
|
|
240
295
|
raise RuntimeError(f"Could not refresh access token: {auth_resp.content}")
|
|
241
296
|
|
|
242
|
-
self.
|
|
297
|
+
self._update_auth_tokens(_TokenResponse.model_validate(auth_resp.json()))
|
|
298
|
+
|
|
299
|
+
def _get_iap_headers(self) -> dict:
|
|
300
|
+
"""Build IAP headers, refreshing tokens if needed.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
dict: HTTP header for IAP (Proxy-Authorization)
|
|
304
|
+
"""
|
|
305
|
+
headers = {}
|
|
306
|
+
if self._iap_client_id:
|
|
307
|
+
if (
|
|
308
|
+
self._iap_refresh_before is None
|
|
309
|
+
or datetime.now() > self._iap_refresh_before
|
|
310
|
+
):
|
|
311
|
+
self._refresh_iap_token()
|
|
312
|
+
headers["Authorization"] = f"Bearer {self._iap_token}"
|
|
313
|
+
|
|
314
|
+
return headers
|
|
243
315
|
|
|
244
316
|
def _get_headers(self) -> dict:
|
|
245
317
|
"""Build authorization headers, refreshing tokens if needed.
|
|
246
318
|
|
|
247
319
|
Returns:
|
|
248
|
-
dict: HTTP headers including `Authorization
|
|
320
|
+
dict: HTTP headers including `Authorization`, `Content-Type`,
|
|
321
|
+
and optionally `Proxy-Authorization` for IAP.
|
|
249
322
|
"""
|
|
250
|
-
if
|
|
323
|
+
if (
|
|
324
|
+
self._auth_refresh_before is None
|
|
325
|
+
or datetime.now() > self._auth_refresh_before
|
|
326
|
+
):
|
|
251
327
|
self._refresh_auth_token()
|
|
252
328
|
|
|
253
|
-
|
|
329
|
+
headers = {
|
|
254
330
|
"Content-Type": "application/json",
|
|
255
|
-
"Authorization": f"Bearer {self._access_token}",
|
|
331
|
+
"X-Kal-Authorization": f"Bearer {self._access_token}",
|
|
332
|
+
**self._get_iap_headers(),
|
|
333
|
+
**self.additional_headers,
|
|
256
334
|
}
|
|
257
335
|
|
|
336
|
+
return headers
|
|
337
|
+
|
|
258
338
|
def _post(self, url: str, payload: dict) -> Any:
|
|
259
339
|
"""Send a POST request to the specified URL with the given payload.
|
|
260
340
|
|
|
@@ -277,6 +357,7 @@ class KaleidoscopeClient:
|
|
|
277
357
|
data=json.dumps(payload),
|
|
278
358
|
headers=self._get_headers(),
|
|
279
359
|
timeout=TIMEOUT_MAXIMUM,
|
|
360
|
+
verify=self._verify_ssl,
|
|
280
361
|
)
|
|
281
362
|
if resp.status_code >= 400:
|
|
282
363
|
print(f"POST {url} received {resp.status_code}: ", resp.content)
|
|
@@ -317,6 +398,7 @@ class KaleidoscopeClient:
|
|
|
317
398
|
data=form_data,
|
|
318
399
|
headers=self._get_headers(),
|
|
319
400
|
timeout=TIMEOUT_MAXIMUM,
|
|
401
|
+
verify=self._verify_ssl,
|
|
320
402
|
)
|
|
321
403
|
if resp.status_code >= 400:
|
|
322
404
|
print(f"POST {url} received {resp.status_code}: ", resp.content)
|
|
@@ -346,6 +428,7 @@ class KaleidoscopeClient:
|
|
|
346
428
|
data=json.dumps(payload),
|
|
347
429
|
headers=self._get_headers(),
|
|
348
430
|
timeout=TIMEOUT_MAXIMUM,
|
|
431
|
+
verify=self._verify_ssl,
|
|
349
432
|
)
|
|
350
433
|
if resp.status_code >= 400:
|
|
351
434
|
print(f"PUT {url} received {resp.status_code}: ", resp.content)
|
|
@@ -374,7 +457,12 @@ class KaleidoscopeClient:
|
|
|
374
457
|
if params:
|
|
375
458
|
url += "?" + urllib.parse.urlencode(params)
|
|
376
459
|
|
|
377
|
-
resp = requests.get(
|
|
460
|
+
resp = requests.get(
|
|
461
|
+
url,
|
|
462
|
+
headers=self._get_headers(),
|
|
463
|
+
timeout=TIMEOUT_MAXIMUM,
|
|
464
|
+
verify=self._verify_ssl,
|
|
465
|
+
)
|
|
378
466
|
if resp.status_code >= 400:
|
|
379
467
|
print(f"GET {url} received {resp.status_code}", resp.content)
|
|
380
468
|
return None
|
|
@@ -412,7 +500,11 @@ class KaleidoscopeClient:
|
|
|
412
500
|
url += "?" + urllib.parse.urlencode(params)
|
|
413
501
|
|
|
414
502
|
resp = requests.get(
|
|
415
|
-
url,
|
|
503
|
+
url,
|
|
504
|
+
headers=self._get_headers(),
|
|
505
|
+
stream=True,
|
|
506
|
+
timeout=TIMEOUT_MAXIMUM,
|
|
507
|
+
verify=self._verify_ssl,
|
|
416
508
|
)
|
|
417
509
|
if resp.status_code >= 400:
|
|
418
510
|
print(f"GET {url} received {resp.status_code}", resp.content)
|
|
@@ -452,7 +544,10 @@ class KaleidoscopeClient:
|
|
|
452
544
|
url += "?" + urllib.parse.urlencode(params)
|
|
453
545
|
|
|
454
546
|
resp = requests.delete(
|
|
455
|
-
url,
|
|
547
|
+
url,
|
|
548
|
+
headers=self._get_headers(),
|
|
549
|
+
timeout=TIMEOUT_MAXIMUM,
|
|
550
|
+
verify=self._verify_ssl,
|
|
456
551
|
)
|
|
457
552
|
if resp.status_code >= 400:
|
|
458
553
|
print(f"DELETE {url} received {resp.status_code}", resp.content)
|
kalbio/dashboards.py
CHANGED
|
@@ -21,11 +21,11 @@ from functools import lru_cache
|
|
|
21
21
|
from kalbio._kaleidoscope_model import _KaleidoscopeBaseModel
|
|
22
22
|
from kalbio.client import KaleidoscopeClient
|
|
23
23
|
from pydantic import TypeAdapter
|
|
24
|
-
from typing import List, Literal, Union
|
|
24
|
+
from typing import List, Literal, TypeAlias, Union
|
|
25
25
|
|
|
26
26
|
_logger = logging.getLogger(__name__)
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
DashboardType: TypeAlias = Union[
|
|
29
29
|
Literal["decision"],
|
|
30
30
|
Literal["data"],
|
|
31
31
|
Literal["chart"],
|
kalbio/entity_fields.py
CHANGED
|
@@ -41,7 +41,7 @@ from functools import lru_cache
|
|
|
41
41
|
from kalbio._kaleidoscope_model import _KaleidoscopeBaseModel
|
|
42
42
|
from kalbio.client import KaleidoscopeClient
|
|
43
43
|
from pydantic import TypeAdapter
|
|
44
|
-
from typing import List, Optional, Union
|
|
44
|
+
from typing import List, Optional, TypeAlias, Union
|
|
45
45
|
|
|
46
46
|
_logger = logging.getLogger(__name__)
|
|
47
47
|
|
|
@@ -151,7 +151,7 @@ class EntityField(_KaleidoscopeBaseModel):
|
|
|
151
151
|
return f"{self.field_name}"
|
|
152
152
|
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
EntityFieldIdentifier: TypeAlias = Union[EntityField, str]
|
|
155
155
|
"""An Identifier Type for Entity Fields.
|
|
156
156
|
|
|
157
157
|
An EntityField should be able to be identified by:
|
kalbio/exports.py
CHANGED
kalbio/programs.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"""Programs module for interacting with Kaleidoscope programs
|
|
1
|
+
"""Programs module for interacting with Kaleidoscope programs.
|
|
2
2
|
|
|
3
3
|
The service allows users to retrieve all available programs in a workspace
|
|
4
4
|
and filter programs by specific IDs.
|
|
5
5
|
|
|
6
6
|
Classes:
|
|
7
|
-
Program: Data model for a Kaleidoscope program
|
|
7
|
+
Program: Data model for a Kaleidoscope program.
|
|
8
8
|
ProgramsService: Service for managing program retrieval operations.
|
|
9
9
|
|
|
10
10
|
Example:
|
|
@@ -64,12 +64,12 @@ class ProgramsService:
|
|
|
64
64
|
|
|
65
65
|
@lru_cache
|
|
66
66
|
def get_programs(self) -> List[Program]:
|
|
67
|
-
"""Retrieve all programs
|
|
67
|
+
"""Retrieve all programs available in the workspace.
|
|
68
68
|
|
|
69
69
|
This method caches its values.
|
|
70
70
|
|
|
71
71
|
Returns:
|
|
72
|
-
List[Program]: A list of Program objects
|
|
72
|
+
List[Program]: A list of Program objects in the workspace.
|
|
73
73
|
|
|
74
74
|
Note:
|
|
75
75
|
If an exception occurs during the API request, it logs the error,
|
kalbio/records.py
CHANGED
|
@@ -62,6 +62,7 @@ from typing import (
|
|
|
62
62
|
Dict,
|
|
63
63
|
List,
|
|
64
64
|
Optional,
|
|
65
|
+
TypeAlias,
|
|
65
66
|
TypedDict,
|
|
66
67
|
Union,
|
|
67
68
|
Unpack,
|
|
@@ -631,7 +632,7 @@ class Record(_KaleidoscopeBaseModel):
|
|
|
631
632
|
setattr(self, k, v)
|
|
632
633
|
|
|
633
634
|
|
|
634
|
-
|
|
635
|
+
RecordIdentifier: TypeAlias = Union[Record, str, dict[EntityFieldIdentifier, str]]
|
|
635
636
|
"""Identifier type for Record
|
|
636
637
|
|
|
637
638
|
Record can be identified by:
|
|
@@ -1154,7 +1155,7 @@ class RecordsService:
|
|
|
1154
1155
|
]
|
|
1155
1156
|
# fmt: on
|
|
1156
1157
|
|
|
1157
|
-
resp = self._client._get(f"/records?record_ids={
|
|
1158
|
+
resp = self._client._get(f"/records?record_ids={','.join(to_fetch)}") or []
|
|
1158
1159
|
self._create_record_list(resp)
|
|
1159
1160
|
|
|
1160
1161
|
ordered = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: kalbio
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python client for kaleidoscope.bio
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Ahmed Elnaiem
|
|
@@ -11,6 +11,9 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Provides-Extra: iap
|
|
15
|
+
Requires-Dist: cachetools (>=6.2.5,<7.0.0)
|
|
16
|
+
Requires-Dist: google-auth (>=2.0.0,<3.0.0) ; extra == "iap"
|
|
14
17
|
Requires-Dist: pydantic (>=2.9.2,<3.0.0)
|
|
15
18
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
16
19
|
Project-URL: Documentation, https://api.docs.kaleidoscope.bio
|
|
@@ -32,7 +35,6 @@ Kalbio is a Python Client library for building applications with the Kaleidoscop
|
|
|
32
35
|
- **Intuitive Resource Management**: Clean, object-oriented interface for programs, activities, records, and more
|
|
33
36
|
- **Advanced Search & Filtering**: Powerful query capabilities with type-safe filter operators
|
|
34
37
|
- **File Upload Support**: Direct file upload to record fields with support for multiple file types
|
|
35
|
-
- **Comprehensive Coverage**: Access all Kaleidoscope platform resources through a unified client
|
|
36
38
|
- **Bulk Operations**: Import and export capabilities for efficient data management
|
|
37
39
|
|
|
38
40
|
## Requirements
|
|
@@ -147,13 +149,13 @@ with open("experiment_data.csv", "rb") as file:
|
|
|
147
149
|
)
|
|
148
150
|
```
|
|
149
151
|
|
|
150
|
-
###
|
|
152
|
+
### Resource Management
|
|
151
153
|
|
|
152
|
-
Kalbio provides services for
|
|
154
|
+
Kalbio provides services for the following Kaleidoscope resources:
|
|
153
155
|
|
|
154
156
|
- **Programs**: Organize your work
|
|
155
157
|
- **Activities**: Tasks, experiments, projects, etc.
|
|
156
|
-
- **Records**: Structured
|
|
158
|
+
- **Records**: Structured entity records
|
|
157
159
|
- **Entity Types**: Define your data schemas
|
|
158
160
|
- **Entity Fields**: Manage field definitions
|
|
159
161
|
- **Labels**: Tag and categorize
|
|
@@ -170,7 +172,7 @@ Once you have a client instance, you have access to:
|
|
|
170
172
|
| ---------------------- | ------------------------------------------- |
|
|
171
173
|
| `client.programs` | Program management |
|
|
172
174
|
| `client.activities` | Activities (tasks, experiments, projects) |
|
|
173
|
-
| `client.records` |
|
|
175
|
+
| `client.records` | Entity record CRUD operations |
|
|
174
176
|
| `client.entity_types` | Entity type definitions |
|
|
175
177
|
| `client.entity_fields` | Field definitions (key fields, data fields) |
|
|
176
178
|
| `client.labels` | Label management |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
kalbio/__init__.py,sha256=6Po_T4MM5m2qNTYgLe4E89C57OVwDaRQ9pXTJTuJsM4,240
|
|
2
|
+
kalbio/_kaleidoscope_model.py,sha256=UnSpiubaEkoyOLjAmKzQGZdXOUMthuP0HiYU1Lo2sFM,4465
|
|
3
|
+
kalbio/activities.py,sha256=UBvQGvQpuOirkWNX_3MNxNAstfo500PgJ6oVBf7HTCA,40654
|
|
4
|
+
kalbio/client.py,sha256=C6r-yuHqlk-dAq55Ur9y7FrowhLvGSR2qzb5YPvf09k,20486
|
|
5
|
+
kalbio/dashboards.py,sha256=Hj3mFjIBIualk5FXC1CLyLFbfvqGdYYLfdpFeigk1jw,9351
|
|
6
|
+
kalbio/entity_fields.py,sha256=mqE4VP2g1-XR2vLUt1TIvX9Drv71NCCYPKBh03f0zO0,15201
|
|
7
|
+
kalbio/entity_types.py,sha256=THXGbIV9dFU2DvIuDd7Q29onmEs9KdeqsB_tq6ZXmR4,6527
|
|
8
|
+
kalbio/exports.py,sha256=IiAk4ZnjU59N4lrKeDRD60ZViOigR0QDd3XcNaWq5O0,5236
|
|
9
|
+
kalbio/helpers.py,sha256=TBPVls1GzfUygDAwCldI5sXYTgBC2pEUSEU0OtrQi3I,1955
|
|
10
|
+
kalbio/imports.py,sha256=s7LIETRQtT6MXEmsbIT2FwFJdE3eh25ujbs4ZFbWYns,3523
|
|
11
|
+
kalbio/labels.py,sha256=Vy7PiZ8vFXIBbrCmdHyz7ANooO0-giTvTLH7WwU_Mo8,2704
|
|
12
|
+
kalbio/programs.py,sha256=svYmZLhN2pwT9cAB8IfvyIbUmFnMVxcoUeeUxs_uESs,2951
|
|
13
|
+
kalbio/property_fields.py,sha256=eCYzSnG-HQB6ECHFNpaGkpm3azHe-lDYVNJUpq5TOtc,2763
|
|
14
|
+
kalbio/record_views.py,sha256=M3NEOhnN4JHA8ZO0I91L9pAVdVY0kmqSent3HehzFTI,7208
|
|
15
|
+
kalbio/records.py,sha256=sQiGnXQaiS6VNj0n2mn8tw7u8kquHLhcAI5fpHjYL8U,40501
|
|
16
|
+
kalbio/workspace.py,sha256=YpeLtzo3o8um_CQLyTT8GnvkF6I195y43JhNN2GmM0M,11670
|
|
17
|
+
kalbio-0.2.3.dist-info/METADATA,sha256=VK7xMMAwxXl-v6kOdNMRisHf2hv3t1rrt74XmSCJb6o,7993
|
|
18
|
+
kalbio-0.2.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
19
|
+
kalbio-0.2.3.dist-info/RECORD,,
|
kalbio-0.2.1.dist-info/RECORD
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
kalbio/__init__.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
|
|
2
|
-
kalbio/_kaleidoscope_model.py,sha256=UnSpiubaEkoyOLjAmKzQGZdXOUMthuP0HiYU1Lo2sFM,4465
|
|
3
|
-
kalbio/activities.py,sha256=zvemwfuiPgTjhpMhzsHon7UselKmuqw9tWpM766m5F4,40621
|
|
4
|
-
kalbio/client.py,sha256=a2NP-FfIbIuRXQ-19KSxcbjyvCpfSXdkUiypgp2-jh8,16822
|
|
5
|
-
kalbio/dashboards.py,sha256=0P8lNiTmyaQj0y8B7AKf1VWU0qHuTUGJ_4xDVtr9jXA,9334
|
|
6
|
-
kalbio/entity_fields.py,sha256=HnvOSE9C_UB59ioY5mB5Sn_V3OwnfRuYZ_IJtEw2vUY,15184
|
|
7
|
-
kalbio/entity_types.py,sha256=THXGbIV9dFU2DvIuDd7Q29onmEs9KdeqsB_tq6ZXmR4,6527
|
|
8
|
-
kalbio/exports.py,sha256=xFdNzajrGUlPZx6tNhgqiUg1lVnrayVQW12d-SmKWA4,5236
|
|
9
|
-
kalbio/helpers.py,sha256=TBPVls1GzfUygDAwCldI5sXYTgBC2pEUSEU0OtrQi3I,1955
|
|
10
|
-
kalbio/imports.py,sha256=s7LIETRQtT6MXEmsbIT2FwFJdE3eh25ujbs4ZFbWYns,3523
|
|
11
|
-
kalbio/labels.py,sha256=Vy7PiZ8vFXIBbrCmdHyz7ANooO0-giTvTLH7WwU_Mo8,2704
|
|
12
|
-
kalbio/programs.py,sha256=SKVJbF08Pp4r7dXfy9NNQnJRnSh-kOpDVdib197EWUM,3017
|
|
13
|
-
kalbio/property_fields.py,sha256=eCYzSnG-HQB6ECHFNpaGkpm3azHe-lDYVNJUpq5TOtc,2763
|
|
14
|
-
kalbio/record_views.py,sha256=M3NEOhnN4JHA8ZO0I91L9pAVdVY0kmqSent3HehzFTI,7208
|
|
15
|
-
kalbio/records.py,sha256=BXuFCA90ViSMp_TtnWJYfQnJgH9Hz-5u4iT0wF0B1UM,40480
|
|
16
|
-
kalbio/workspace.py,sha256=YpeLtzo3o8um_CQLyTT8GnvkF6I195y43JhNN2GmM0M,11670
|
|
17
|
-
kalbio-0.2.1.dist-info/METADATA,sha256=hzK2SQ3YjZaTLsATC3a1cg1bGOMpm3ge9vVGNxRK1BU,7969
|
|
18
|
-
kalbio-0.2.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
19
|
-
kalbio-0.2.1.dist-info/RECORD,,
|
|
File without changes
|