hubmap-search-sdk 1.0.0a6__py3-none-any.whl → 1.0.0a8__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.
@@ -437,8 +437,7 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
437
437
  headers = httpx.Headers(headers_dict)
438
438
 
439
439
  idempotency_header = self._idempotency_header
440
- if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers:
441
- options.idempotency_key = options.idempotency_key or self._idempotency_key()
440
+ if idempotency_header and options.idempotency_key and idempotency_header not in headers:
442
441
  headers[idempotency_header] = options.idempotency_key
443
442
 
444
443
  # Don't set these headers if they were already set or removed by the caller. We check
@@ -906,7 +905,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
906
905
  self,
907
906
  cast_to: Type[ResponseT],
908
907
  options: FinalRequestOptions,
909
- remaining_retries: Optional[int] = None,
910
908
  *,
911
909
  stream: Literal[True],
912
910
  stream_cls: Type[_StreamT],
@@ -917,7 +915,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
917
915
  self,
918
916
  cast_to: Type[ResponseT],
919
917
  options: FinalRequestOptions,
920
- remaining_retries: Optional[int] = None,
921
918
  *,
922
919
  stream: Literal[False] = False,
923
920
  ) -> ResponseT: ...
@@ -927,7 +924,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
927
924
  self,
928
925
  cast_to: Type[ResponseT],
929
926
  options: FinalRequestOptions,
930
- remaining_retries: Optional[int] = None,
931
927
  *,
932
928
  stream: bool = False,
933
929
  stream_cls: Type[_StreamT] | None = None,
@@ -937,134 +933,118 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
937
933
  self,
938
934
  cast_to: Type[ResponseT],
939
935
  options: FinalRequestOptions,
940
- remaining_retries: Optional[int] = None,
941
936
  *,
942
937
  stream: bool = False,
943
938
  stream_cls: type[_StreamT] | None = None,
944
939
  ) -> ResponseT | _StreamT:
945
- if remaining_retries is not None:
946
- retries_taken = options.get_max_retries(self.max_retries) - remaining_retries
947
- else:
948
- retries_taken = 0
949
-
950
- return self._request(
951
- cast_to=cast_to,
952
- options=options,
953
- stream=stream,
954
- stream_cls=stream_cls,
955
- retries_taken=retries_taken,
956
- )
940
+ cast_to = self._maybe_override_cast_to(cast_to, options)
957
941
 
958
- def _request(
959
- self,
960
- *,
961
- cast_to: Type[ResponseT],
962
- options: FinalRequestOptions,
963
- retries_taken: int,
964
- stream: bool,
965
- stream_cls: type[_StreamT] | None,
966
- ) -> ResponseT | _StreamT:
967
942
  # create a copy of the options we were given so that if the
968
943
  # options are mutated later & we then retry, the retries are
969
944
  # given the original options
970
945
  input_options = model_copy(options)
971
-
972
- cast_to = self._maybe_override_cast_to(cast_to, options)
973
- options = self._prepare_options(options)
974
-
975
- remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
976
- request = self._build_request(options, retries_taken=retries_taken)
977
- self._prepare_request(request)
978
-
979
- if options.idempotency_key:
946
+ if input_options.idempotency_key is None and input_options.method.lower() != "get":
980
947
  # ensure the idempotency key is reused between requests
981
- input_options.idempotency_key = options.idempotency_key
948
+ input_options.idempotency_key = self._idempotency_key()
982
949
 
983
- kwargs: HttpxSendArgs = {}
984
- if self.custom_auth is not None:
985
- kwargs["auth"] = self.custom_auth
950
+ response: httpx.Response | None = None
951
+ max_retries = input_options.get_max_retries(self.max_retries)
986
952
 
987
- log.debug("Sending HTTP Request: %s %s", request.method, request.url)
953
+ retries_taken = 0
954
+ for retries_taken in range(max_retries + 1):
955
+ options = model_copy(input_options)
956
+ options = self._prepare_options(options)
988
957
 
989
- try:
990
- response = self._client.send(
991
- request,
992
- stream=stream or self._should_stream_response_body(request=request),
993
- **kwargs,
994
- )
995
- except httpx.TimeoutException as err:
996
- log.debug("Encountered httpx.TimeoutException", exc_info=True)
958
+ remaining_retries = max_retries - retries_taken
959
+ request = self._build_request(options, retries_taken=retries_taken)
960
+ self._prepare_request(request)
997
961
 
998
- if remaining_retries > 0:
999
- return self._retry_request(
1000
- input_options,
1001
- cast_to,
1002
- retries_taken=retries_taken,
1003
- stream=stream,
1004
- stream_cls=stream_cls,
1005
- response_headers=None,
1006
- )
962
+ kwargs: HttpxSendArgs = {}
963
+ if self.custom_auth is not None:
964
+ kwargs["auth"] = self.custom_auth
1007
965
 
1008
- log.debug("Raising timeout error")
1009
- raise APITimeoutError(request=request) from err
1010
- except Exception as err:
1011
- log.debug("Encountered Exception", exc_info=True)
966
+ log.debug("Sending HTTP Request: %s %s", request.method, request.url)
1012
967
 
1013
- if remaining_retries > 0:
1014
- return self._retry_request(
1015
- input_options,
1016
- cast_to,
1017
- retries_taken=retries_taken,
1018
- stream=stream,
1019
- stream_cls=stream_cls,
1020
- response_headers=None,
968
+ response = None
969
+ try:
970
+ response = self._client.send(
971
+ request,
972
+ stream=stream or self._should_stream_response_body(request=request),
973
+ **kwargs,
1021
974
  )
975
+ except httpx.TimeoutException as err:
976
+ log.debug("Encountered httpx.TimeoutException", exc_info=True)
977
+
978
+ if remaining_retries > 0:
979
+ self._sleep_for_retry(
980
+ retries_taken=retries_taken,
981
+ max_retries=max_retries,
982
+ options=input_options,
983
+ response=None,
984
+ )
985
+ continue
986
+
987
+ log.debug("Raising timeout error")
988
+ raise APITimeoutError(request=request) from err
989
+ except Exception as err:
990
+ log.debug("Encountered Exception", exc_info=True)
991
+
992
+ if remaining_retries > 0:
993
+ self._sleep_for_retry(
994
+ retries_taken=retries_taken,
995
+ max_retries=max_retries,
996
+ options=input_options,
997
+ response=None,
998
+ )
999
+ continue
1000
+
1001
+ log.debug("Raising connection error")
1002
+ raise APIConnectionError(request=request) from err
1003
+
1004
+ log.debug(
1005
+ 'HTTP Response: %s %s "%i %s" %s',
1006
+ request.method,
1007
+ request.url,
1008
+ response.status_code,
1009
+ response.reason_phrase,
1010
+ response.headers,
1011
+ )
1022
1012
 
1023
- log.debug("Raising connection error")
1024
- raise APIConnectionError(request=request) from err
1025
-
1026
- log.debug(
1027
- 'HTTP Response: %s %s "%i %s" %s',
1028
- request.method,
1029
- request.url,
1030
- response.status_code,
1031
- response.reason_phrase,
1032
- response.headers,
1033
- )
1013
+ try:
1014
+ response.raise_for_status()
1015
+ except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
1016
+ log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
1017
+ if response.status_code in (301, 302, 303, 307, 308):
1018
+ return self._process_response(
1019
+ cast_to=cast_to,
1020
+ options=options,
1021
+ response=response,
1022
+ stream=stream,
1023
+ stream_cls=stream_cls,
1024
+ retries_taken=retries_taken,
1025
+ )
1034
1026
 
1035
- try:
1036
- response.raise_for_status()
1037
- except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
1038
- log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
1039
- if response.status_code in (301, 302, 303, 307, 308):
1040
- return self._process_response(
1041
- cast_to=cast_to,
1042
- options=options,
1043
- response=response,
1044
- stream=stream,
1045
- stream_cls=stream_cls,
1046
- retries_taken=retries_taken,
1047
- )
1027
+ if remaining_retries > 0 and self._should_retry(err.response):
1028
+ err.response.close()
1029
+ self._sleep_for_retry(
1030
+ retries_taken=retries_taken,
1031
+ max_retries=max_retries,
1032
+ options=input_options,
1033
+ response=response,
1034
+ )
1035
+ continue
1048
1036
 
1049
- if remaining_retries > 0 and self._should_retry(err.response):
1050
- err.response.close()
1051
- return self._retry_request(
1052
- input_options,
1053
- cast_to,
1054
- retries_taken=retries_taken,
1055
- response_headers=err.response.headers,
1056
- stream=stream,
1057
- stream_cls=stream_cls,
1058
- )
1037
+ # If the response is streamed then we need to explicitly read the response
1038
+ # to completion before attempting to access the response text.
1039
+ if not err.response.is_closed:
1040
+ err.response.read()
1059
1041
 
1060
- # If the response is streamed then we need to explicitly read the response
1061
- # to completion before attempting to access the response text.
1062
- if not err.response.is_closed:
1063
- err.response.read()
1042
+ log.debug("Re-raising status error")
1043
+ raise self._make_status_error_from_response(err.response) from None
1064
1044
 
1065
- log.debug("Re-raising status error")
1066
- raise self._make_status_error_from_response(err.response) from None
1045
+ break
1067
1046
 
1047
+ assert response is not None, "could not resolve response (should never happen)"
1068
1048
  return self._process_response(
1069
1049
  cast_to=cast_to,
1070
1050
  options=options,
@@ -1074,37 +1054,20 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1074
1054
  retries_taken=retries_taken,
1075
1055
  )
1076
1056
 
1077
- def _retry_request(
1078
- self,
1079
- options: FinalRequestOptions,
1080
- cast_to: Type[ResponseT],
1081
- *,
1082
- retries_taken: int,
1083
- response_headers: httpx.Headers | None,
1084
- stream: bool,
1085
- stream_cls: type[_StreamT] | None,
1086
- ) -> ResponseT | _StreamT:
1087
- remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
1057
+ def _sleep_for_retry(
1058
+ self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None
1059
+ ) -> None:
1060
+ remaining_retries = max_retries - retries_taken
1088
1061
  if remaining_retries == 1:
1089
1062
  log.debug("1 retry left")
1090
1063
  else:
1091
1064
  log.debug("%i retries left", remaining_retries)
1092
1065
 
1093
- timeout = self._calculate_retry_timeout(remaining_retries, options, response_headers)
1066
+ timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None)
1094
1067
  log.info("Retrying request to %s in %f seconds", options.url, timeout)
1095
1068
 
1096
- # In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a
1097
- # different thread if necessary.
1098
1069
  time.sleep(timeout)
1099
1070
 
1100
- return self._request(
1101
- options=options,
1102
- cast_to=cast_to,
1103
- retries_taken=retries_taken + 1,
1104
- stream=stream,
1105
- stream_cls=stream_cls,
1106
- )
1107
-
1108
1071
  def _process_response(
1109
1072
  self,
1110
1073
  *,
@@ -1448,7 +1411,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1448
1411
  options: FinalRequestOptions,
1449
1412
  *,
1450
1413
  stream: Literal[False] = False,
1451
- remaining_retries: Optional[int] = None,
1452
1414
  ) -> ResponseT: ...
1453
1415
 
1454
1416
  @overload
@@ -1459,7 +1421,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1459
1421
  *,
1460
1422
  stream: Literal[True],
1461
1423
  stream_cls: type[_AsyncStreamT],
1462
- remaining_retries: Optional[int] = None,
1463
1424
  ) -> _AsyncStreamT: ...
1464
1425
 
1465
1426
  @overload
@@ -1470,7 +1431,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1470
1431
  *,
1471
1432
  stream: bool,
1472
1433
  stream_cls: type[_AsyncStreamT] | None = None,
1473
- remaining_retries: Optional[int] = None,
1474
1434
  ) -> ResponseT | _AsyncStreamT: ...
1475
1435
 
1476
1436
  async def request(
@@ -1480,120 +1440,111 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1480
1440
  *,
1481
1441
  stream: bool = False,
1482
1442
  stream_cls: type[_AsyncStreamT] | None = None,
1483
- remaining_retries: Optional[int] = None,
1484
- ) -> ResponseT | _AsyncStreamT:
1485
- if remaining_retries is not None:
1486
- retries_taken = options.get_max_retries(self.max_retries) - remaining_retries
1487
- else:
1488
- retries_taken = 0
1489
-
1490
- return await self._request(
1491
- cast_to=cast_to,
1492
- options=options,
1493
- stream=stream,
1494
- stream_cls=stream_cls,
1495
- retries_taken=retries_taken,
1496
- )
1497
-
1498
- async def _request(
1499
- self,
1500
- cast_to: Type[ResponseT],
1501
- options: FinalRequestOptions,
1502
- *,
1503
- stream: bool,
1504
- stream_cls: type[_AsyncStreamT] | None,
1505
- retries_taken: int,
1506
1443
  ) -> ResponseT | _AsyncStreamT:
1507
1444
  if self._platform is None:
1508
1445
  # `get_platform` can make blocking IO calls so we
1509
1446
  # execute it earlier while we are in an async context
1510
1447
  self._platform = await asyncify(get_platform)()
1511
1448
 
1449
+ cast_to = self._maybe_override_cast_to(cast_to, options)
1450
+
1512
1451
  # create a copy of the options we were given so that if the
1513
1452
  # options are mutated later & we then retry, the retries are
1514
1453
  # given the original options
1515
1454
  input_options = model_copy(options)
1516
-
1517
- cast_to = self._maybe_override_cast_to(cast_to, options)
1518
- options = await self._prepare_options(options)
1519
-
1520
- remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
1521
- request = self._build_request(options, retries_taken=retries_taken)
1522
- await self._prepare_request(request)
1523
-
1524
- if options.idempotency_key:
1455
+ if input_options.idempotency_key is None and input_options.method.lower() != "get":
1525
1456
  # ensure the idempotency key is reused between requests
1526
- input_options.idempotency_key = options.idempotency_key
1457
+ input_options.idempotency_key = self._idempotency_key()
1527
1458
 
1528
- kwargs: HttpxSendArgs = {}
1529
- if self.custom_auth is not None:
1530
- kwargs["auth"] = self.custom_auth
1459
+ response: httpx.Response | None = None
1460
+ max_retries = input_options.get_max_retries(self.max_retries)
1531
1461
 
1532
- try:
1533
- response = await self._client.send(
1534
- request,
1535
- stream=stream or self._should_stream_response_body(request=request),
1536
- **kwargs,
1537
- )
1538
- except httpx.TimeoutException as err:
1539
- log.debug("Encountered httpx.TimeoutException", exc_info=True)
1462
+ retries_taken = 0
1463
+ for retries_taken in range(max_retries + 1):
1464
+ options = model_copy(input_options)
1465
+ options = await self._prepare_options(options)
1540
1466
 
1541
- if remaining_retries > 0:
1542
- return await self._retry_request(
1543
- input_options,
1544
- cast_to,
1545
- retries_taken=retries_taken,
1546
- stream=stream,
1547
- stream_cls=stream_cls,
1548
- response_headers=None,
1549
- )
1467
+ remaining_retries = max_retries - retries_taken
1468
+ request = self._build_request(options, retries_taken=retries_taken)
1469
+ await self._prepare_request(request)
1550
1470
 
1551
- log.debug("Raising timeout error")
1552
- raise APITimeoutError(request=request) from err
1553
- except Exception as err:
1554
- log.debug("Encountered Exception", exc_info=True)
1471
+ kwargs: HttpxSendArgs = {}
1472
+ if self.custom_auth is not None:
1473
+ kwargs["auth"] = self.custom_auth
1555
1474
 
1556
- if remaining_retries > 0:
1557
- return await self._retry_request(
1558
- input_options,
1559
- cast_to,
1560
- retries_taken=retries_taken,
1561
- stream=stream,
1562
- stream_cls=stream_cls,
1563
- response_headers=None,
1475
+ log.debug("Sending HTTP Request: %s %s", request.method, request.url)
1476
+
1477
+ response = None
1478
+ try:
1479
+ response = await self._client.send(
1480
+ request,
1481
+ stream=stream or self._should_stream_response_body(request=request),
1482
+ **kwargs,
1564
1483
  )
1484
+ except httpx.TimeoutException as err:
1485
+ log.debug("Encountered httpx.TimeoutException", exc_info=True)
1486
+
1487
+ if remaining_retries > 0:
1488
+ await self._sleep_for_retry(
1489
+ retries_taken=retries_taken,
1490
+ max_retries=max_retries,
1491
+ options=input_options,
1492
+ response=None,
1493
+ )
1494
+ continue
1495
+
1496
+ log.debug("Raising timeout error")
1497
+ raise APITimeoutError(request=request) from err
1498
+ except Exception as err:
1499
+ log.debug("Encountered Exception", exc_info=True)
1500
+
1501
+ if remaining_retries > 0:
1502
+ await self._sleep_for_retry(
1503
+ retries_taken=retries_taken,
1504
+ max_retries=max_retries,
1505
+ options=input_options,
1506
+ response=None,
1507
+ )
1508
+ continue
1509
+
1510
+ log.debug("Raising connection error")
1511
+ raise APIConnectionError(request=request) from err
1512
+
1513
+ log.debug(
1514
+ 'HTTP Response: %s %s "%i %s" %s',
1515
+ request.method,
1516
+ request.url,
1517
+ response.status_code,
1518
+ response.reason_phrase,
1519
+ response.headers,
1520
+ )
1565
1521
 
1566
- log.debug("Raising connection error")
1567
- raise APIConnectionError(request=request) from err
1522
+ try:
1523
+ response.raise_for_status()
1524
+ except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
1525
+ log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
1526
+
1527
+ if remaining_retries > 0 and self._should_retry(err.response):
1528
+ await err.response.aclose()
1529
+ await self._sleep_for_retry(
1530
+ retries_taken=retries_taken,
1531
+ max_retries=max_retries,
1532
+ options=input_options,
1533
+ response=response,
1534
+ )
1535
+ continue
1568
1536
 
1569
- log.debug(
1570
- 'HTTP Request: %s %s "%i %s"', request.method, request.url, response.status_code, response.reason_phrase
1571
- )
1537
+ # If the response is streamed then we need to explicitly read the response
1538
+ # to completion before attempting to access the response text.
1539
+ if not err.response.is_closed:
1540
+ await err.response.aread()
1572
1541
 
1573
- try:
1574
- response.raise_for_status()
1575
- except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code
1576
- log.debug("Encountered httpx.HTTPStatusError", exc_info=True)
1577
-
1578
- if remaining_retries > 0 and self._should_retry(err.response):
1579
- await err.response.aclose()
1580
- return await self._retry_request(
1581
- input_options,
1582
- cast_to,
1583
- retries_taken=retries_taken,
1584
- response_headers=err.response.headers,
1585
- stream=stream,
1586
- stream_cls=stream_cls,
1587
- )
1542
+ log.debug("Re-raising status error")
1543
+ raise self._make_status_error_from_response(err.response) from None
1588
1544
 
1589
- # If the response is streamed then we need to explicitly read the response
1590
- # to completion before attempting to access the response text.
1591
- if not err.response.is_closed:
1592
- await err.response.aread()
1593
-
1594
- log.debug("Re-raising status error")
1595
- raise self._make_status_error_from_response(err.response) from None
1545
+ break
1596
1546
 
1547
+ assert response is not None, "could not resolve response (should never happen)"
1597
1548
  return await self._process_response(
1598
1549
  cast_to=cast_to,
1599
1550
  options=options,
@@ -1603,35 +1554,20 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1603
1554
  retries_taken=retries_taken,
1604
1555
  )
1605
1556
 
1606
- async def _retry_request(
1607
- self,
1608
- options: FinalRequestOptions,
1609
- cast_to: Type[ResponseT],
1610
- *,
1611
- retries_taken: int,
1612
- response_headers: httpx.Headers | None,
1613
- stream: bool,
1614
- stream_cls: type[_AsyncStreamT] | None,
1615
- ) -> ResponseT | _AsyncStreamT:
1616
- remaining_retries = options.get_max_retries(self.max_retries) - retries_taken
1557
+ async def _sleep_for_retry(
1558
+ self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None
1559
+ ) -> None:
1560
+ remaining_retries = max_retries - retries_taken
1617
1561
  if remaining_retries == 1:
1618
1562
  log.debug("1 retry left")
1619
1563
  else:
1620
1564
  log.debug("%i retries left", remaining_retries)
1621
1565
 
1622
- timeout = self._calculate_retry_timeout(remaining_retries, options, response_headers)
1566
+ timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None)
1623
1567
  log.info("Retrying request to %s in %f seconds", options.url, timeout)
1624
1568
 
1625
1569
  await anyio.sleep(timeout)
1626
1570
 
1627
- return await self._request(
1628
- options=options,
1629
- cast_to=cast_to,
1630
- retries_taken=retries_taken + 1,
1631
- stream=stream,
1632
- stream_cls=stream_cls,
1633
- )
1634
-
1635
1571
  async def _process_response(
1636
1572
  self,
1637
1573
  *,
@@ -19,10 +19,7 @@ from ._types import (
19
19
  ProxiesTypes,
20
20
  RequestOptions,
21
21
  )
22
- from ._utils import (
23
- is_given,
24
- get_async_library,
25
- )
22
+ from ._utils import is_given, get_async_library
26
23
  from ._version import __version__
27
24
  from .resources import add, mget, search, update, indices, mapping, reindex, clear_docs, param_search, scroll_search
28
25
  from ._streaming import Stream as Stream, AsyncStream as AsyncStream
@@ -626,8 +626,8 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
626
626
  # Note: if one variant defines an alias then they all should
627
627
  discriminator_alias = field_info.alias
628
628
 
629
- if field_info.annotation and is_literal_type(field_info.annotation):
630
- for entry in get_args(field_info.annotation):
629
+ if (annotation := getattr(field_info, "annotation", None)) and is_literal_type(annotation):
630
+ for entry in get_args(annotation):
631
631
  if isinstance(entry, str):
632
632
  mapping[entry] = variant
633
633
 
@@ -235,7 +235,7 @@ class BaseAPIResponse(Generic[R]):
235
235
  # split is required to handle cases where additional information is included
236
236
  # in the response, e.g. application/json; charset=utf-8
237
237
  content_type, *_ = response.headers.get("content-type", "*").split(";")
238
- if content_type != "application/json":
238
+ if not content_type.endswith("json"):
239
239
  if is_basemodel(cast_to):
240
240
  try:
241
241
  data = response.json()
@@ -72,8 +72,16 @@ def _extract_items(
72
72
  from .._files import assert_is_file_content
73
73
 
74
74
  # We have exhausted the path, return the entry we found.
75
- assert_is_file_content(obj, key=flattened_key)
76
75
  assert flattened_key is not None
76
+
77
+ if is_list(obj):
78
+ files: list[tuple[str, FileTypes]] = []
79
+ for entry in obj:
80
+ assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "")
81
+ files.append((flattened_key + "[]", cast(FileTypes, entry)))
82
+ return files
83
+
84
+ assert_is_file_content(obj, key=flattened_key)
77
85
  return [(flattened_key, cast(FileTypes, obj))]
78
86
 
79
87
  index += 1
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "hubmap_search_sdk"
4
- __version__ = "1.0.0-alpha.6" # x-release-please-version
4
+ __version__ = "1.0.0-alpha.8" # x-release-please-version
@@ -10,10 +10,7 @@ from ..types import (
10
10
  add_update_document_with_scope_params,
11
11
  )
12
12
  from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
13
- from .._utils import (
14
- maybe_transform,
15
- async_maybe_transform,
16
- )
13
+ from .._utils import maybe_transform, async_maybe_transform
17
14
  from .._compat import cached_property
18
15
  from .._resource import SyncAPIResource, AsyncAPIResource
19
16
  from .._response import (
@@ -6,10 +6,7 @@ import httpx
6
6
 
7
7
  from ..types import mget_retrieve_multiple_params, mget_retrieve_multiple_by_index_params
8
8
  from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
9
- from .._utils import (
10
- maybe_transform,
11
- async_maybe_transform,
12
- )
9
+ from .._utils import maybe_transform, async_maybe_transform
13
10
  from .._compat import cached_property
14
11
  from .._resource import SyncAPIResource, AsyncAPIResource
15
12
  from .._response import (
@@ -6,10 +6,7 @@ import httpx
6
6
 
7
7
  from ..types import param_search_execute_params
8
8
  from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
9
- from .._utils import (
10
- maybe_transform,
11
- async_maybe_transform,
12
- )
9
+ from .._utils import maybe_transform, async_maybe_transform
13
10
  from .._compat import cached_property
14
11
  from .._resource import SyncAPIResource, AsyncAPIResource
15
12
  from .._response import (
@@ -6,10 +6,7 @@ import httpx
6
6
 
7
7
  from ..types import scroll_search_create_params
8
8
  from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
9
- from .._utils import (
10
- maybe_transform,
11
- async_maybe_transform,
12
- )
9
+ from .._utils import maybe_transform, async_maybe_transform
13
10
  from .._compat import cached_property
14
11
  from .._resource import SyncAPIResource, AsyncAPIResource
15
12
  from .._response import (
@@ -6,10 +6,7 @@ import httpx
6
6
 
7
7
  from ..types import search_execute_query_params, search_execute_index_query_params
8
8
  from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
9
- from .._utils import (
10
- maybe_transform,
11
- async_maybe_transform,
12
- )
9
+ from .._utils import maybe_transform, async_maybe_transform
13
10
  from .._compat import cached_property
14
11
  from .._resource import SyncAPIResource, AsyncAPIResource
15
12
  from .._response import (
@@ -10,10 +10,7 @@ from ..types import (
10
10
  update_update_document_with_scope_params,
11
11
  )
12
12
  from .._types import NOT_GIVEN, Body, Query, Headers, NoneType, NotGiven
13
- from .._utils import (
14
- maybe_transform,
15
- async_maybe_transform,
16
- )
13
+ from .._utils import maybe_transform, async_maybe_transform
17
14
  from .._compat import cached_property
18
15
  from .._resource import SyncAPIResource, AsyncAPIResource
19
16
  from .._response import (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hubmap_search_sdk
3
- Version: 1.0.0a6
3
+ Version: 1.0.0a8
4
4
  Summary: The official Python library for the hubmap-search-sdk API
5
5
  Project-URL: Homepage, https://github.com/hubmapconsortium/search-python-sdk
6
6
  Project-URL: Repository, https://github.com/hubmapconsortium/search-python-sdk
@@ -1,17 +1,17 @@
1
1
  hubmap_search_sdk/__init__.py,sha256=eUNBFfdHquxHRjxdtY6YQ0pw-jeQuVT7fm5mtYzB8hY,2545
2
- hubmap_search_sdk/_base_client.py,sha256=1RF00QWO49UDc_IWrsy44ksRIs9IY1xJ6PZ_r4EMq_4,66834
3
- hubmap_search_sdk/_client.py,sha256=_B5lY2StPqLRgECImsspnws_3o0WbTfeMwZvhZTLRfo,19485
2
+ hubmap_search_sdk/_base_client.py,sha256=ywGk1oJ4Qw4KWt3l-GiSZ6WRoKwb4yus6rHuk1pHOcE,65470
3
+ hubmap_search_sdk/_client.py,sha256=gnLifq83f2jJq2Fy1EUYjEdaJDLpTNEcOeSKw7bTn6c,19472
4
4
  hubmap_search_sdk/_compat.py,sha256=VWemUKbj6DDkQ-O4baSpHVLJafotzeXmCQGJugfVTIw,6580
5
5
  hubmap_search_sdk/_constants.py,sha256=S14PFzyN9-I31wiV7SmIlL5Ga0MLHxdvegInGdXH7tM,462
6
6
  hubmap_search_sdk/_exceptions.py,sha256=TSu_vsDWiUzuD0Dfn2RJxjxeGl4RJBR2Sblmd-0cGho,3238
7
7
  hubmap_search_sdk/_files.py,sha256=mf4dOgL4b0ryyZlbqLhggD3GVgDf6XxdGFAgce01ugE,3549
8
- hubmap_search_sdk/_models.py,sha256=q-l1tes71l6z-D5ffu9-G4UigTVVeJwiwIzA_gO4RFo,29045
8
+ hubmap_search_sdk/_models.py,sha256=mB2r2VWQq49jG-F0RIXDrBxPp3v-Eg12wMOtVTNxtv4,29057
9
9
  hubmap_search_sdk/_qs.py,sha256=AOkSz4rHtK4YI3ZU_kzea-zpwBUgEY8WniGmTPyEimc,4846
10
10
  hubmap_search_sdk/_resource.py,sha256=z9CsPEtCJP9np1GfCrGKkqUmlGd10QdY9ZtINq4vyIs,1154
11
- hubmap_search_sdk/_response.py,sha256=V9jyjwgBvmdB9MqltIZFs4gLcdbj1MmLdhwS-ILkBSk,28881
11
+ hubmap_search_sdk/_response.py,sha256=CVvIUr5-53j-by8NnuhWKh7QkOIxs5Ipwko_cayfE9o,28880
12
12
  hubmap_search_sdk/_streaming.py,sha256=Anm1GDFtbRi3IL4NaaajTXDlwv75_Rm-bi6TD_0tSxU,10136
13
13
  hubmap_search_sdk/_types.py,sha256=Xxqpn7vIdO1HG3-TJaQdHFEI1etNZxdSS3QOOeakw0A,6154
14
- hubmap_search_sdk/_version.py,sha256=YKtL7InDmy5Rszgk7kf-NQ_QF-cHcWsjvspK_V5MDpk,177
14
+ hubmap_search_sdk/_version.py,sha256=3OvS7i8w8GZPCyA0XOT5xgmtBISApFo65Ao94xkR_Wg,177
15
15
  hubmap_search_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  hubmap_search_sdk/_utils/__init__.py,sha256=PNZ_QJuzZEgyYXqkO1HVhGkj5IU9bglVUcw7H-Knjzw,2062
17
17
  hubmap_search_sdk/_utils/_logs.py,sha256=vEolshfk2D36E9yV2JC0vIbMfBmiM-lIAw-ledyLVVI,807
@@ -21,19 +21,19 @@ hubmap_search_sdk/_utils/_streams.py,sha256=SMC90diFFecpEg_zgDRVbdR3hSEIgVVij4ta
21
21
  hubmap_search_sdk/_utils/_sync.py,sha256=TpGLrrhRNWTJtODNE6Fup3_k7zrWm1j2RlirzBwre-0,2862
22
22
  hubmap_search_sdk/_utils/_transform.py,sha256=n7kskEWz6o__aoNvhFoGVyDoalNe6mJwp-g7BWkdj88,15617
23
23
  hubmap_search_sdk/_utils/_typing.py,sha256=D0DbbNu8GnYQTSICnTSHDGsYXj8TcAKyhejb0XcnjtY,4602
24
- hubmap_search_sdk/_utils/_utils.py,sha256=8UmbPOy_AAr2uUjjFui-VZSrVBHRj6bfNEKRp5YZP2A,12004
24
+ hubmap_search_sdk/_utils/_utils.py,sha256=ts4CiiuNpFiGB6YMdkQRh2SZvYvsl7mAF-JWHCcLDf4,12312
25
25
  hubmap_search_sdk/lib/.keep,sha256=wuNrz-5SXo3jJaJOJgz4vFHM41YH_g20F5cRQo0vLes,224
26
26
  hubmap_search_sdk/resources/__init__.py,sha256=in53qeBTsjQ4j4Gy2lRL9ptQbjduHnnROAmu6IbragQ,4761
27
- hubmap_search_sdk/resources/add.py,sha256=PYknHcgJRZTfwB4DVu2EmOreQ6TtdAX37vDYwnRQASc,14304
27
+ hubmap_search_sdk/resources/add.py,sha256=38lYOJLyYVBA7Lqb8wOmeuAwHDV6g89aT9AFHwsiAPc,14291
28
28
  hubmap_search_sdk/resources/clear_docs.py,sha256=AVGciD1yMMzVFl6qhClqRQ577KqWMaGpvgFoKXF4nYI,13287
29
29
  hubmap_search_sdk/resources/indices.py,sha256=-MvJfXZX7LGDJA1IR_zZwYgssbETKd0lCTP8ujsQifI,5347
30
30
  hubmap_search_sdk/resources/mapping.py,sha256=awjJkfSAiGA5U4HvQKTtlTk2C12wAHGnZT0ACsWLK7w,8095
31
- hubmap_search_sdk/resources/mget.py,sha256=iCrx34QHJqSZg74k94Wmf38jBTUkZ6SN4xjusRA_Gkc,10636
32
- hubmap_search_sdk/resources/param_search.py,sha256=SEEmGM2DrUhL7yGucxqOo-LeBbzHBlTu6UhGq4BkLmE,7984
31
+ hubmap_search_sdk/resources/mget.py,sha256=CN1tcC8XgBXLonksG8b1Dp2k5IKYvQqBM4xXC51JmcY,10623
32
+ hubmap_search_sdk/resources/param_search.py,sha256=MPPC7XK6RtUxiprSwNDkhj1-DTlaglABwKkUG5iGHXQ,7971
33
33
  hubmap_search_sdk/resources/reindex.py,sha256=lNCNQkvzyvENMMCxQzmn8Dy-d364tN7KIahfv0KhnQM,5971
34
- hubmap_search_sdk/resources/scroll_search.py,sha256=xC_hZRlqYDgH310I_sSGnduEw7IBL1OE5Xy88NMlUxk,7064
35
- hubmap_search_sdk/resources/search.py,sha256=FJguv91ED8igVa87r_yG5UJ6HXV6eKcm8tgI65kOT_Q,13071
36
- hubmap_search_sdk/resources/update.py,sha256=tQ4CRYi_lvZ4kihDaHKAKdym4iRiigW2AYawReYGfP0,14469
34
+ hubmap_search_sdk/resources/scroll_search.py,sha256=zYUwVBeUMjXLQbj9p65LmIAC-s1bf9Xgd-hR5xJMzCY,7051
35
+ hubmap_search_sdk/resources/search.py,sha256=s8-4WuodKR_nnSV9_sXRs9EEgM7kN5AX2a8UslOBj7I,13058
36
+ hubmap_search_sdk/resources/update.py,sha256=1I3qDDwuRkVIEwrai90rABKoXX2TrrkdQx5JwO5zMtE,14456
37
37
  hubmap_search_sdk/types/__init__.py,sha256=ZdTuvNr3rYL5PZq_w2tTDI2KmPsFRGRBWg09qNhdFAA,1520
38
38
  hubmap_search_sdk/types/add_create_document_params.py,sha256=8xti5XGKIJOMavBOjlI1qvl0E75CC-9YvMPIqnmBANk,296
39
39
  hubmap_search_sdk/types/add_create_document_with_index_params.py,sha256=Ge4KWrTOw3i0cHGWPRY3uaKnIlF5OQawUq8asZJhigI,339
@@ -48,7 +48,7 @@ hubmap_search_sdk/types/search_execute_query_params.py,sha256=La2udYbqLYPTzIRJtt
48
48
  hubmap_search_sdk/types/update_update_document_at_index_params.py,sha256=F6bL-5xzqfI1ClajCan9M2pWhKyP2qFENNXHE1unj54,341
49
49
  hubmap_search_sdk/types/update_update_document_params.py,sha256=LM65ha6n6USOen2DqlL8R0N8APX9uAduWzqReXqJWOI,302
50
50
  hubmap_search_sdk/types/update_update_document_with_scope_params.py,sha256=3Se48DT25C8gP_yvEoYWMg0whAD9qWPWMQH1rpvg8Zc,371
51
- hubmap_search_sdk-1.0.0a6.dist-info/METADATA,sha256=1Jtlnr6BVfoXcrGKLY_FS2vh_deuoTAroBb_Duocgh0,12669
52
- hubmap_search_sdk-1.0.0a6.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
53
- hubmap_search_sdk-1.0.0a6.dist-info/licenses/LICENSE,sha256=lLxIB8m5gVPdScdg81tBYiNbRkVgIBWcmAN1yJwrOME,1057
54
- hubmap_search_sdk-1.0.0a6.dist-info/RECORD,,
51
+ hubmap_search_sdk-1.0.0a8.dist-info/METADATA,sha256=T7nwtx9wbua5gYQlHaryP0EpH7ghnLY-aFSrd6zXE0U,12669
52
+ hubmap_search_sdk-1.0.0a8.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
53
+ hubmap_search_sdk-1.0.0a8.dist-info/licenses/LICENSE,sha256=lLxIB8m5gVPdScdg81tBYiNbRkVgIBWcmAN1yJwrOME,1057
54
+ hubmap_search_sdk-1.0.0a8.dist-info/RECORD,,