sapiopycommons 2025.2.20a442__py3-none-any.whl → 2025.2.20a444__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.

Potentially problematic release.


This version of sapiopycommons might be problematic. Click here for more details.

@@ -2,7 +2,7 @@ import base64
2
2
  import io
3
3
  import math
4
4
  import re
5
- from typing import Final, Mapping, Any
5
+ from typing import Final, Mapping, Any, cast
6
6
 
7
7
  import requests
8
8
  from pandas import DataFrame
@@ -18,7 +18,8 @@ from sapiopylib.rest.pojo.chartdata.DashboardEnums import ChartGroupingType, Cha
18
18
  from sapiopylib.rest.pojo.chartdata.DashboardSeries import GaugeChartSeries
19
19
  from sapiopylib.rest.pojo.datatype.DataType import DataTypeDefinition
20
20
  from sapiopylib.rest.pojo.datatype.DataTypeLayout import DataTypeLayout, TableLayout
21
- from sapiopylib.rest.pojo.datatype.FieldDefinition import AbstractVeloxFieldDefinition, FieldType
21
+ from sapiopylib.rest.pojo.datatype.FieldDefinition import AbstractVeloxFieldDefinition, FieldType, \
22
+ VeloxStringFieldDefinition
22
23
  from sapiopylib.rest.pojo.eln.ElnEntryPosition import ElnEntryPosition
23
24
  from sapiopylib.rest.pojo.eln.ElnExperiment import ElnExperiment
24
25
  from sapiopylib.rest.pojo.eln.ExperimentEntry import ExperimentEntry
@@ -207,7 +208,7 @@ class AiHelper:
207
208
  self.eln_man = ElnManager(self.user)
208
209
  self.dt_man = DataTypeManager(self.user)
209
210
 
210
- def call_endpoint(self, url: str, payload: Any, tab_prefix: str = "") -> Response:
211
+ def call_post_endpoint(self, url: str, payload: Any, tab_prefix: str = "") -> Response:
211
212
  """
212
213
  Call a tool endpoint. Constructs the tool headers and checks the response for errors for the caller.
213
214
 
@@ -221,6 +222,20 @@ class AiHelper:
221
222
  response.raise_for_status()
222
223
  return response
223
224
 
225
+ def call_get_endpoint(self, url: str, params: Any, tab_prefix: str = "") -> Response:
226
+ """
227
+ Call a tool endpoint. Constructs the tool headers and checks the response for errors for the caller.
228
+
229
+ :param url: The URL of the endpoint to call.
230
+ :param params: The query parameters to send to the endpoint.
231
+ :param tab_prefix: The prefix to use for the tab name that will be created by the tool.
232
+ :return: The Response object returned by the endpoint.
233
+ """
234
+ headers = create_tot_headers(self.user.url, self.user.username, self.user.password, self.exp_id, tab_prefix)
235
+ response = requests.get(url, params=params, headers=headers)
236
+ response.raise_for_status()
237
+ return response
238
+
224
239
  @property
225
240
  def protocol(self) -> ElnExperimentProtocol:
226
241
  """
@@ -310,17 +325,39 @@ class AiHelper:
310
325
  # Determine which fields in the JSON can be used to create field definitions.
311
326
  fb = FieldBuilder()
312
327
  fields: list[AbstractVeloxFieldDefinition] = []
313
- fields_by_name: dict[str, AbstractVeloxFieldDefinition] = {}
328
+ fields_by_json_key: dict[str, AbstractVeloxFieldDefinition] = {}
329
+ string_field_lengths: dict[str, int] = {}
314
330
  for key, value in json_list[0].items():
315
- field_name: str = key.replace(" ", "_")
331
+ # The field name is the JSON key name, but with spaces and dashes replaced by underscores and with a leading
332
+ # underscore added if the field name starts with a number.
333
+ field_name: str = key.strip()
334
+ if " " in field_name:
335
+ field_name = field_name.replace(" ", "_")
336
+ if "-" in field_name:
337
+ field_name = field_name.replace("-", "_")
338
+ if field_name[0].isnumeric():
339
+ field_name = "_" + field_name
340
+
316
341
  if isinstance(value, str):
317
342
  field = fb.string_field(field_name, display_name=key)
318
343
  fields.append(field)
319
- fields_by_name[key] = field
344
+ fields_by_json_key[key] = field
345
+ string_field_lengths[key] = 100
320
346
  elif isinstance(value, (int, float)):
321
347
  field = fb.double_field(field_name, display_name=key, precision=3)
322
348
  fields.append(field)
323
- fields_by_name[key] = field
349
+ fields_by_json_key[key] = field
350
+
351
+ # Determine the max length of each string field.
352
+ for values in json_list:
353
+ for key in string_field_lengths:
354
+ length: int = len(values.get(key)) if values.get(key) else 0
355
+ string_field_lengths[key] = max(string_field_lengths[key], length)
356
+
357
+ # Update the max length of each string field.
358
+ for key in string_field_lengths:
359
+ field = cast(VeloxStringFieldDefinition, fields_by_json_key[key])
360
+ field.max_length = string_field_lengths[key]
324
361
 
325
362
  # Sort the JSON list if requested.
326
363
  if sort_field and sort_direction != SortDirection.NONE:
@@ -340,7 +377,7 @@ class AiHelper:
340
377
  field_maps: list[dict[str, Any]] = []
341
378
  for json_dict in json_list:
342
379
  field_map: dict[str, Any] = {}
343
- for key, field in fields_by_name.items():
380
+ for key, field in fields_by_json_key.items():
344
381
  # Watch out for NaN values or other special values in numeric columns.
345
382
  val: Any = json_dict.get(key)
346
383
  if (field.data_field_type == FieldType.DOUBLE
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sapiopycommons
3
- Version: 2025.2.20a442
3
+ Version: 2025.2.20a444
4
4
  Summary: Official Sapio Python API Utilities Package
5
5
  Project-URL: Homepage, https://github.com/sapiosciences
6
6
  Author-email: Jonathan Steck <jsteck@sapiosciences.com>, Yechen Qiao <yqiao@sapiosciences.com>
@@ -1,6 +1,6 @@
1
1
  sapiopycommons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  sapiopycommons/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- sapiopycommons/ai/tool_of_tools.py,sha256=m3SBGqJhL2oBg6aPMV8XjUgizKR_S8TwfySQVOlzKC0,39090
3
+ sapiopycommons/ai/tool_of_tools.py,sha256=iy1Hgr1DkaMZ443JynUxZFo8VJA6V6vd7R5oEwNGOIk,40983
4
4
  sapiopycommons/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sapiopycommons/callbacks/callback_util.py,sha256=68lPK8GtE6zd8C0fQaMLxT57PtU-6HnO37Zk-u56Mrs,129933
6
6
  sapiopycommons/callbacks/field_builder.py,sha256=p2XacN99MuKk3ite8GAqstUMpixqugul2CsC4gB83-o,38620
@@ -58,7 +58,7 @@ sapiopycommons/webhook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
58
58
  sapiopycommons/webhook/webhook_context.py,sha256=D793uLsb1691SalaPnBUk3rOSxn_hYLhdvkaIxjNXss,1909
59
59
  sapiopycommons/webhook/webhook_handlers.py,sha256=L0HetSm43NvA5KyW3xbLpGFh2DbAaeZJVtXIEl2fvV8,39689
60
60
  sapiopycommons/webhook/webservice_handlers.py,sha256=Y5dHx_UFWFuSqaoPL6Re-fsKYRuxvCWZ8bj6KSZ3jfM,14285
61
- sapiopycommons-2025.2.20a442.dist-info/METADATA,sha256=3tHm4JcRFFFg41wg_HYTp6xHGi60K96ACnEFsm6ZSEE,3143
62
- sapiopycommons-2025.2.20a442.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
63
- sapiopycommons-2025.2.20a442.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
64
- sapiopycommons-2025.2.20a442.dist-info/RECORD,,
61
+ sapiopycommons-2025.2.20a444.dist-info/METADATA,sha256=X6G7jM0WYEoYCvzkn_boiU4vWWlDGmnZSflU9RaZ5w4,3143
62
+ sapiopycommons-2025.2.20a444.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
63
+ sapiopycommons-2025.2.20a444.dist-info/licenses/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
64
+ sapiopycommons-2025.2.20a444.dist-info/RECORD,,