hubmap-search-sdk 1.0.0a12__py3-none-any.whl → 1.0.0a14__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.
@@ -36,7 +36,7 @@ from ._exceptions import (
36
36
  UnprocessableEntityError,
37
37
  APIResponseValidationError,
38
38
  )
39
- from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
39
+ from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
40
40
  from ._utils._logs import setup_logging as _setup_logging
41
41
 
42
42
  __all__ = [
@@ -78,6 +78,7 @@ __all__ = [
78
78
  "DEFAULT_CONNECTION_LIMITS",
79
79
  "DefaultHttpxClient",
80
80
  "DefaultAsyncHttpxClient",
81
+ "DefaultAioHttpClient",
81
82
  ]
82
83
 
83
84
  if not _t.TYPE_CHECKING:
@@ -963,6 +963,9 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
963
963
  if self.custom_auth is not None:
964
964
  kwargs["auth"] = self.custom_auth
965
965
 
966
+ if options.follow_redirects is not None:
967
+ kwargs["follow_redirects"] = options.follow_redirects
968
+
966
969
  log.debug("Sending HTTP Request: %s %s", request.method, request.url)
967
970
 
968
971
  response = None
@@ -1080,7 +1083,14 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1080
1083
  ) -> ResponseT:
1081
1084
  origin = get_origin(cast_to) or cast_to
1082
1085
 
1083
- if inspect.isclass(origin) and issubclass(origin, BaseAPIResponse):
1086
+ if (
1087
+ inspect.isclass(origin)
1088
+ and issubclass(origin, BaseAPIResponse)
1089
+ # we only want to actually return the custom BaseAPIResponse class if we're
1090
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
1091
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
1092
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
1093
+ ):
1084
1094
  if not issubclass(origin, APIResponse):
1085
1095
  raise TypeError(f"API Response types must subclass {APIResponse}; Received {origin}")
1086
1096
 
@@ -1291,6 +1301,24 @@ class _DefaultAsyncHttpxClient(httpx.AsyncClient):
1291
1301
  super().__init__(**kwargs)
1292
1302
 
1293
1303
 
1304
+ try:
1305
+ import httpx_aiohttp
1306
+ except ImportError:
1307
+
1308
+ class _DefaultAioHttpClient(httpx.AsyncClient):
1309
+ def __init__(self, **_kwargs: Any) -> None:
1310
+ raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra")
1311
+ else:
1312
+
1313
+ class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
1314
+ def __init__(self, **kwargs: Any) -> None:
1315
+ kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
1316
+ kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
1317
+ kwargs.setdefault("follow_redirects", True)
1318
+
1319
+ super().__init__(**kwargs)
1320
+
1321
+
1294
1322
  if TYPE_CHECKING:
1295
1323
  DefaultAsyncHttpxClient = httpx.AsyncClient
1296
1324
  """An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
@@ -1299,8 +1327,12 @@ if TYPE_CHECKING:
1299
1327
  This is useful because overriding the `http_client` with your own instance of
1300
1328
  `httpx.AsyncClient` will result in httpx's defaults being used, not ours.
1301
1329
  """
1330
+
1331
+ DefaultAioHttpClient = httpx.AsyncClient
1332
+ """An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`."""
1302
1333
  else:
1303
1334
  DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
1335
+ DefaultAioHttpClient = _DefaultAioHttpClient
1304
1336
 
1305
1337
 
1306
1338
  class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
@@ -1472,6 +1504,9 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1472
1504
  if self.custom_auth is not None:
1473
1505
  kwargs["auth"] = self.custom_auth
1474
1506
 
1507
+ if options.follow_redirects is not None:
1508
+ kwargs["follow_redirects"] = options.follow_redirects
1509
+
1475
1510
  log.debug("Sending HTTP Request: %s %s", request.method, request.url)
1476
1511
 
1477
1512
  response = None
@@ -1580,7 +1615,14 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1580
1615
  ) -> ResponseT:
1581
1616
  origin = get_origin(cast_to) or cast_to
1582
1617
 
1583
- if inspect.isclass(origin) and issubclass(origin, BaseAPIResponse):
1618
+ if (
1619
+ inspect.isclass(origin)
1620
+ and issubclass(origin, BaseAPIResponse)
1621
+ # we only want to actually return the custom BaseAPIResponse class if we're
1622
+ # returning the raw response, or if we're not streaming SSE, as if we're streaming
1623
+ # SSE then `cast_to` doesn't actively reflect the type we need to parse into
1624
+ and (not stream or bool(response.request.headers.get(RAW_RESPONSE_HEADER)))
1625
+ ):
1584
1626
  if not issubclass(origin, AsyncAPIResponse):
1585
1627
  raise TypeError(f"API Response types must subclass {AsyncAPIResponse}; Received {origin}")
1586
1628
 
@@ -737,6 +737,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
737
737
  idempotency_key: str
738
738
  json_data: Body
739
739
  extra_json: AnyMapping
740
+ follow_redirects: bool
740
741
 
741
742
 
742
743
  @final
@@ -750,6 +751,7 @@ class FinalRequestOptions(pydantic.BaseModel):
750
751
  files: Union[HttpxRequestFiles, None] = None
751
752
  idempotency_key: Union[str, None] = None
752
753
  post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
754
+ follow_redirects: Union[bool, None] = None
753
755
 
754
756
  # It should be noted that we cannot use `json` here as that would override
755
757
  # a BaseModel method in an incompatible fashion.
@@ -100,6 +100,7 @@ class RequestOptions(TypedDict, total=False):
100
100
  params: Query
101
101
  extra_json: AnyMapping
102
102
  idempotency_key: str
103
+ follow_redirects: bool
103
104
 
104
105
 
105
106
  # Sentinel class used until PEP 0661 is accepted
@@ -215,3 +216,4 @@ class _GenericAlias(Protocol):
215
216
 
216
217
  class HttpxSendArgs(TypedDict, total=False):
217
218
  auth: httpx.Auth
219
+ follow_redirects: bool
@@ -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.12" # x-release-please-version
4
+ __version__ = "1.0.0-alpha.14" # x-release-please-version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hubmap_search_sdk
3
- Version: 1.0.0a12
3
+ Version: 1.0.0a14
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
@@ -27,11 +27,14 @@ Requires-Dist: httpx<1,>=0.23.0
27
27
  Requires-Dist: pydantic<3,>=1.9.0
28
28
  Requires-Dist: sniffio
29
29
  Requires-Dist: typing-extensions<5,>=4.10
30
+ Provides-Extra: aiohttp
31
+ Requires-Dist: aiohttp; extra == 'aiohttp'
32
+ Requires-Dist: httpx-aiohttp>=0.1.6; extra == 'aiohttp'
30
33
  Description-Content-Type: text/markdown
31
34
 
32
35
  # HuBMAP Search SDK Python API Library
33
36
 
34
- [![PyPI version](https://img.shields.io/pypi/v/hubmap_search_sdk.svg)](https://pypi.org/project/hubmap_search_sdk/)
37
+ [![PyPI version](https://github.com/hubmapconsortium/search-python-sdk/tree/main/<https://img.shields.io/pypi/v/hubmap_search_sdk.svg?label=pypi%20(stable)>)](https://pypi.org/project/hubmap_search_sdk/)
35
38
 
36
39
  The HuBMAP Search SDK Python library provides convenient access to the HuBMAP Search REST API from any Python 3.8+
37
40
  application. The library includes type definitions for all request params and response fields,
@@ -88,6 +91,37 @@ asyncio.run(main())
88
91
 
89
92
  Functionality between the synchronous and asynchronous clients is otherwise identical.
90
93
 
94
+ ### With aiohttp
95
+
96
+ By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.
97
+
98
+ You can enable this by installing `aiohttp`:
99
+
100
+ ```sh
101
+ # install from PyPI
102
+ pip install --pre hubmap_search_sdk[aiohttp]
103
+ ```
104
+
105
+ Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
106
+
107
+ ```python
108
+ import asyncio
109
+ from hubmap_search_sdk import DefaultAioHttpClient
110
+ from hubmap_search_sdk import AsyncHubmapSearchSDK
111
+
112
+
113
+ async def main() -> None:
114
+ async with AsyncHubmapSearchSDK(
115
+ bearer_token="My Bearer Token",
116
+ http_client=DefaultAioHttpClient(),
117
+ ) as client:
118
+ indices = await client.indices.list()
119
+ print(indices.indices)
120
+
121
+
122
+ asyncio.run(main())
123
+ ```
124
+
91
125
  ## Using types
92
126
 
93
127
  Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:
@@ -162,7 +196,7 @@ client.with_options(max_retries=5).indices.list()
162
196
  ### Timeouts
163
197
 
164
198
  By default requests time out after 1 minute. You can configure this with a `timeout` option,
165
- which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
199
+ which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
166
200
 
167
201
  ```python
168
202
  from hubmap_search_sdk import HubmapSearchSDK
@@ -1,17 +1,17 @@
1
- hubmap_search_sdk/__init__.py,sha256=F9AFX-xgr865PCE_yad1n59k0nNhFEqyFYhCvskIKVU,2656
2
- hubmap_search_sdk/_base_client.py,sha256=ywGk1oJ4Qw4KWt3l-GiSZ6WRoKwb4yus6rHuk1pHOcE,65470
1
+ hubmap_search_sdk/__init__.py,sha256=tY_1lV72SdiJjDLUaCt4vdgy4u4POqKNgAUTAdj0r6w,2706
2
+ hubmap_search_sdk/_base_client.py,sha256=jVZiiAsOtKUaa90IzHzgqKgZhqHFDAJN0_gXuSDu7Kg,67341
3
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=mB2r2VWQq49jG-F0RIXDrBxPp3v-Eg12wMOtVTNxtv4,29057
8
+ hubmap_search_sdk/_models.py,sha256=G1vczEodX0vUySeVKbF-mbzlaObNL1oVAYH4c65agRk,29131
9
9
  hubmap_search_sdk/_qs.py,sha256=AOkSz4rHtK4YI3ZU_kzea-zpwBUgEY8WniGmTPyEimc,4846
10
10
  hubmap_search_sdk/_resource.py,sha256=z9CsPEtCJP9np1GfCrGKkqUmlGd10QdY9ZtINq4vyIs,1154
11
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
- hubmap_search_sdk/_types.py,sha256=Xxqpn7vIdO1HG3-TJaQdHFEI1etNZxdSS3QOOeakw0A,6154
14
- hubmap_search_sdk/_version.py,sha256=UfgHcATjLxAH4FQ5E-8CJLIsMGxqWUPorkG8_UFnbnA,178
13
+ hubmap_search_sdk/_types.py,sha256=uzIgOEhrXbR5HcQM1_gpNmRW2kcNYrgJ-WoYfU4e4_Q,6208
14
+ hubmap_search_sdk/_version.py,sha256=S5UBh_tpHB0Xw2O2aN72WtfQF7ltUZFQGwIp7oT19qM,178
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
@@ -49,7 +49,7 @@ hubmap_search_sdk/types/search_execute_query_params.py,sha256=La2udYbqLYPTzIRJtt
49
49
  hubmap_search_sdk/types/update_update_document_at_index_params.py,sha256=F6bL-5xzqfI1ClajCan9M2pWhKyP2qFENNXHE1unj54,341
50
50
  hubmap_search_sdk/types/update_update_document_params.py,sha256=LM65ha6n6USOen2DqlL8R0N8APX9uAduWzqReXqJWOI,302
51
51
  hubmap_search_sdk/types/update_update_document_with_scope_params.py,sha256=3Se48DT25C8gP_yvEoYWMg0whAD9qWPWMQH1rpvg8Zc,371
52
- hubmap_search_sdk-1.0.0a12.dist-info/METADATA,sha256=iQlnHgEcliUBALg0QXoqHQTM_kkpf5cWC1A8mo22vH0,12670
53
- hubmap_search_sdk-1.0.0a12.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
54
- hubmap_search_sdk-1.0.0a12.dist-info/licenses/LICENSE,sha256=lLxIB8m5gVPdScdg81tBYiNbRkVgIBWcmAN1yJwrOME,1057
55
- hubmap_search_sdk-1.0.0a12.dist-info/RECORD,,
52
+ hubmap_search_sdk-1.0.0a14.dist-info/METADATA,sha256=NWzANRQU9b5TiTKDULUdQ1c0VT33AhyyRqz1med4szo,13678
53
+ hubmap_search_sdk-1.0.0a14.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
54
+ hubmap_search_sdk-1.0.0a14.dist-info/licenses/LICENSE,sha256=lLxIB8m5gVPdScdg81tBYiNbRkVgIBWcmAN1yJwrOME,1057
55
+ hubmap_search_sdk-1.0.0a14.dist-info/RECORD,,