Skip to content

Commit 688b98b

Browse files
authored
Merge pull request #55 from hubmapconsortium/release-please--branches--main--changes--next
release: 1.0.0-alpha.34
2 parents d5418bb + c2475df commit 688b98b

23 files changed

+137
-104
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.0.0-alpha.33"
2+
".": "1.0.0-alpha.34"
33
}

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 1.0.0-alpha.34 (2025-09-20)
4+
5+
Full Changelog: [v1.0.0-alpha.33...v1.0.0-alpha.34](https://github.com/hubmapconsortium/search-python-sdk/compare/v1.0.0-alpha.33...v1.0.0-alpha.34)
6+
7+
### Chores
8+
9+
* do not install brew dependencies in ./scripts/bootstrap by default ([1ac8e1f](https://github.com/hubmapconsortium/search-python-sdk/commit/1ac8e1f01b04dfdde272b9fbe5010cd0be61b53f))
10+
* **types:** change optional parameter type from NotGiven to Omit ([93de837](https://github.com/hubmapconsortium/search-python-sdk/commit/93de8370c188e04899fb9775ab94860fad94278d))
11+
312
## 1.0.0-alpha.33 (2025-09-17)
413

514
Full Changelog: [v1.0.0-alpha.32...v1.0.0-alpha.33](https://github.com/hubmapconsortium/search-python-sdk/compare/v1.0.0-alpha.32...v1.0.0-alpha.33)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "hubmap_search_sdk"
3-
version = "1.0.0-alpha.33"
3+
version = "1.0.0-alpha.34"
44
description = "The official Python library for the hubmap-search-sdk API"
55
dynamic = ["readme"]
66
license = "MIT"

scripts/bootstrap

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@ set -e
44

55
cd "$(dirname "$0")/.."
66

7-
if ! command -v rye >/dev/null 2>&1 && [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
7+
if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
88
brew bundle check >/dev/null 2>&1 || {
9-
echo "==> Installing Homebrew dependencies…"
10-
brew bundle
9+
echo -n "==> Install Homebrew dependencies? (y/N): "
10+
read -r response
11+
case "$response" in
12+
[yY][eE][sS]|[yY])
13+
brew bundle
14+
;;
15+
*)
16+
;;
17+
esac
18+
echo
1119
}
1220
fi
1321

src/hubmap_search_sdk/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import typing as _t
44

55
from . import types
6-
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
6+
from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes, omit, not_given
77
from ._utils import file_from_path
88
from ._client import (
99
Client,
@@ -48,7 +48,9 @@
4848
"ProxiesTypes",
4949
"NotGiven",
5050
"NOT_GIVEN",
51+
"not_given",
5152
"Omit",
53+
"omit",
5254
"HubmapSearchSDKError",
5355
"APIError",
5456
"APIStatusError",

src/hubmap_search_sdk/_base_client.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
from ._qs import Querystring
4343
from ._files import to_httpx_files, async_to_httpx_files
4444
from ._types import (
45-
NOT_GIVEN,
4645
Body,
4746
Omit,
4847
Query,
@@ -57,6 +56,7 @@
5756
RequestOptions,
5857
HttpxRequestFiles,
5958
ModelBuilderProtocol,
59+
not_given,
6060
)
6161
from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping
6262
from ._compat import PYDANTIC_V1, model_copy, model_dump
@@ -145,9 +145,9 @@ def __init__(
145145
def __init__(
146146
self,
147147
*,
148-
url: URL | NotGiven = NOT_GIVEN,
149-
json: Body | NotGiven = NOT_GIVEN,
150-
params: Query | NotGiven = NOT_GIVEN,
148+
url: URL | NotGiven = not_given,
149+
json: Body | NotGiven = not_given,
150+
params: Query | NotGiven = not_given,
151151
) -> None:
152152
self.url = url
153153
self.json = json
@@ -598,7 +598,7 @@ def _maybe_override_cast_to(self, cast_to: type[ResponseT], options: FinalReques
598598
# we internally support defining a temporary header to override the
599599
# default `cast_to` type for use with `.with_raw_response` and `.with_streaming_response`
600600
# see _response.py for implementation details
601-
override_cast_to = headers.pop(OVERRIDE_CAST_TO_HEADER, NOT_GIVEN)
601+
override_cast_to = headers.pop(OVERRIDE_CAST_TO_HEADER, not_given)
602602
if is_given(override_cast_to):
603603
options.headers = headers
604604
return cast(Type[ResponseT], override_cast_to)
@@ -828,7 +828,7 @@ def __init__(
828828
version: str,
829829
base_url: str | URL,
830830
max_retries: int = DEFAULT_MAX_RETRIES,
831-
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
831+
timeout: float | Timeout | None | NotGiven = not_given,
832832
http_client: httpx.Client | None = None,
833833
custom_headers: Mapping[str, str] | None = None,
834834
custom_query: Mapping[str, object] | None = None,
@@ -1368,7 +1368,7 @@ def __init__(
13681368
base_url: str | URL,
13691369
_strict_response_validation: bool,
13701370
max_retries: int = DEFAULT_MAX_RETRIES,
1371-
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
1371+
timeout: float | Timeout | None | NotGiven = not_given,
13721372
http_client: httpx.AsyncClient | None = None,
13731373
custom_headers: Mapping[str, str] | None = None,
13741374
custom_query: Mapping[str, object] | None = None,
@@ -1830,8 +1830,8 @@ def make_request_options(
18301830
extra_query: Query | None = None,
18311831
extra_body: Body | None = None,
18321832
idempotency_key: str | None = None,
1833-
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
1834-
post_parser: PostParser | NotGiven = NOT_GIVEN,
1833+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
1834+
post_parser: PostParser | NotGiven = not_given,
18351835
) -> RequestOptions:
18361836
"""Create a dict of type RequestOptions without keys of NotGiven values."""
18371837
options: RequestOptions = {}

src/hubmap_search_sdk/_client.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
from __future__ import annotations
44

55
import os
6-
from typing import Any, Union, Mapping
6+
from typing import Any, Mapping
77
from typing_extensions import Self, override
88

99
import httpx
1010

1111
from . import _exceptions
1212
from ._qs import Querystring
1313
from ._types import (
14-
NOT_GIVEN,
1514
Omit,
1615
Timeout,
1716
NotGiven,
1817
Transport,
1918
ProxiesTypes,
2019
RequestOptions,
20+
not_given,
2121
)
2222
from ._utils import is_given, get_async_library
2323
from ._version import __version__
@@ -64,7 +64,7 @@ def __init__(
6464
*,
6565
bearer_token: str | None = None,
6666
base_url: str | httpx.URL | None = None,
67-
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
67+
timeout: float | Timeout | None | NotGiven = not_given,
6868
max_retries: int = DEFAULT_MAX_RETRIES,
6969
default_headers: Mapping[str, str] | None = None,
7070
default_query: Mapping[str, object] | None = None,
@@ -141,9 +141,9 @@ def copy(
141141
*,
142142
bearer_token: str | None = None,
143143
base_url: str | httpx.URL | None = None,
144-
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
144+
timeout: float | Timeout | None | NotGiven = not_given,
145145
http_client: httpx.Client | None = None,
146-
max_retries: int | NotGiven = NOT_GIVEN,
146+
max_retries: int | NotGiven = not_given,
147147
default_headers: Mapping[str, str] | None = None,
148148
set_default_headers: Mapping[str, str] | None = None,
149149
default_query: Mapping[str, object] | None = None,
@@ -243,7 +243,7 @@ def __init__(
243243
*,
244244
bearer_token: str | None = None,
245245
base_url: str | httpx.URL | None = None,
246-
timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN,
246+
timeout: float | Timeout | None | NotGiven = not_given,
247247
max_retries: int = DEFAULT_MAX_RETRIES,
248248
default_headers: Mapping[str, str] | None = None,
249249
default_query: Mapping[str, object] | None = None,
@@ -320,9 +320,9 @@ def copy(
320320
*,
321321
bearer_token: str | None = None,
322322
base_url: str | httpx.URL | None = None,
323-
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
323+
timeout: float | Timeout | None | NotGiven = not_given,
324324
http_client: httpx.AsyncClient | None = None,
325-
max_retries: int | NotGiven = NOT_GIVEN,
325+
max_retries: int | NotGiven = not_given,
326326
default_headers: Mapping[str, str] | None = None,
327327
set_default_headers: Mapping[str, str] | None = None,
328328
default_query: Mapping[str, object] | None = None,

src/hubmap_search_sdk/_qs.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from urllib.parse import parse_qs, urlencode
55
from typing_extensions import Literal, get_args
66

7-
from ._types import NOT_GIVEN, NotGiven, NotGivenOr
7+
from ._types import NotGiven, not_given
88
from ._utils import flatten
99

1010
_T = TypeVar("_T")
@@ -41,8 +41,8 @@ def stringify(
4141
self,
4242
params: Params,
4343
*,
44-
array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN,
45-
nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN,
44+
array_format: ArrayFormat | NotGiven = not_given,
45+
nested_format: NestedFormat | NotGiven = not_given,
4646
) -> str:
4747
return urlencode(
4848
self.stringify_items(
@@ -56,8 +56,8 @@ def stringify_items(
5656
self,
5757
params: Params,
5858
*,
59-
array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN,
60-
nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN,
59+
array_format: ArrayFormat | NotGiven = not_given,
60+
nested_format: NestedFormat | NotGiven = not_given,
6161
) -> list[tuple[str, str]]:
6262
opts = Options(
6363
qs=self,
@@ -143,8 +143,8 @@ def __init__(
143143
self,
144144
qs: Querystring = _qs,
145145
*,
146-
array_format: NotGivenOr[ArrayFormat] = NOT_GIVEN,
147-
nested_format: NotGivenOr[NestedFormat] = NOT_GIVEN,
146+
array_format: ArrayFormat | NotGiven = not_given,
147+
nested_format: NestedFormat | NotGiven = not_given,
148148
) -> None:
149149
self.array_format = qs.array_format if isinstance(array_format, NotGiven) else array_format
150150
self.nested_format = qs.nested_format if isinstance(nested_format, NotGiven) else nested_format

src/hubmap_search_sdk/_types.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,21 @@ class RequestOptions(TypedDict, total=False):
117117
# Sentinel class used until PEP 0661 is accepted
118118
class NotGiven:
119119
"""
120-
A sentinel singleton class used to distinguish omitted keyword arguments
121-
from those passed in with the value None (which may have different behavior).
120+
For parameters with a meaningful None value, we need to distinguish between
121+
the user explicitly passing None, and the user not passing the parameter at
122+
all.
123+
124+
User code shouldn't need to use not_given directly.
122125
123126
For example:
124127
125128
```py
126-
def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: ...
129+
def create(timeout: Timeout | None | NotGiven = not_given): ...
127130
128131
129-
get(timeout=1) # 1s timeout
130-
get(timeout=None) # No timeout
131-
get() # Default timeout behavior, which may not be statically known at the method definition.
132+
create(timeout=1) # 1s timeout
133+
create(timeout=None) # No timeout
134+
create() # Default timeout behavior
132135
```
133136
"""
134137

@@ -140,13 +143,14 @@ def __repr__(self) -> str:
140143
return "NOT_GIVEN"
141144

142145

143-
NotGivenOr = Union[_T, NotGiven]
146+
not_given = NotGiven()
147+
# for backwards compatibility:
144148
NOT_GIVEN = NotGiven()
145149

146150

147151
class Omit:
148-
"""In certain situations you need to be able to represent a case where a default value has
149-
to be explicitly removed and `None` is not an appropriate substitute, for example:
152+
"""
153+
To explicitly omit something from being sent in a request, use `omit`.
150154
151155
```py
152156
# as the default `Content-Type` header is `application/json` that will be sent
@@ -156,15 +160,18 @@ class Omit:
156160
# to look something like: 'multipart/form-data; boundary=0d8382fcf5f8c3be01ca2e11002d2983'
157161
client.post(..., headers={"Content-Type": "multipart/form-data"})
158162
159-
# instead you can remove the default `application/json` header by passing Omit
160-
client.post(..., headers={"Content-Type": Omit()})
163+
# instead you can remove the default `application/json` header by passing omit
164+
client.post(..., headers={"Content-Type": omit})
161165
```
162166
"""
163167

164168
def __bool__(self) -> Literal[False]:
165169
return False
166170

167171

172+
omit = Omit()
173+
174+
168175
@runtime_checkable
169176
class ModelBuilderProtocol(Protocol):
170177
@classmethod

src/hubmap_search_sdk/_utils/_transform.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ def _transform_typeddict(
268268
annotations = get_type_hints(expected_type, include_extras=True)
269269
for key, value in data.items():
270270
if not is_given(value):
271-
# we don't need to include `NotGiven` values here as they'll
271+
# we don't need to include omitted values here as they'll
272272
# be stripped out before the request is sent anyway
273273
continue
274274

@@ -434,7 +434,7 @@ async def _async_transform_typeddict(
434434
annotations = get_type_hints(expected_type, include_extras=True)
435435
for key, value in data.items():
436436
if not is_given(value):
437-
# we don't need to include `NotGiven` values here as they'll
437+
# we don't need to include omitted values here as they'll
438438
# be stripped out before the request is sent anyway
439439
continue
440440

0 commit comments

Comments
 (0)