Skip to content

Commit 08d92fb

Browse files
Merge pull request #353 from OneBusAway/release-please--branches--main--changes--next
release: 1.26.0
2 parents c4ce16d + fa59ef6 commit 08d92fb

15 files changed

Lines changed: 172 additions & 14 deletions

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
runs-on: ${{ github.repository == 'stainless-sdks/open-transit-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
2222
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
2323
steps:
24-
- uses: actions/checkout@v6
24+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2525

2626
- name: Install Rye
2727
run: |
@@ -46,7 +46,7 @@ jobs:
4646
id-token: write
4747
runs-on: ${{ github.repository == 'stainless-sdks/open-transit-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
4848
steps:
49-
- uses: actions/checkout@v6
49+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
5050

5151
- name: Install Rye
5252
run: |
@@ -67,7 +67,7 @@ jobs:
6767
github.repository == 'stainless-sdks/open-transit-python' &&
6868
!startsWith(github.ref, 'refs/heads/stl/')
6969
id: github-oidc
70-
uses: actions/github-script@v8
70+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
7171
with:
7272
script: core.setOutput('github_token', await core.getIDToken());
7373

@@ -87,7 +87,7 @@ jobs:
8787
runs-on: ${{ github.repository == 'stainless-sdks/open-transit-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
8888
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
8989
steps:
90-
- uses: actions/checkout@v6
90+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
9191

9292
- name: Install Rye
9393
run: |

.github/workflows/publish-pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515

1616
steps:
17-
- uses: actions/checkout@v6
17+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1818

1919
- name: Install Rye
2020
run: |

.github/workflows/release-doctor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
if: github.repository == 'OneBusAway/python-sdk' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
1313

1414
steps:
15-
- uses: actions/checkout@v6
15+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1616

1717
- name: Check release environment
1818
run: |

.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.25.2"
2+
".": "1.26.0"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 30
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/open-transit/open-transit-b625345de7b9c51744ddc6c75b8c37a159a536204481404cca91d7d6a859149d.yml
3-
openapi_spec_hash: 9bf1e5bf00ef9936a9181ebd0956d5b8
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/open-transit/open-transit-4a35fd1e705bc2b75f44e2fd82144b95eeb56f329e4e05bbede7e6bc8adc479e.yml
3+
openapi_spec_hash: bc73be5518578c9ad8e878b82c540691
44
config_hash: c28ddf5b7754155603d9fd1c5fcaeeff

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.26.0 (2026-05-20)
4+
5+
Full Changelog: [v1.25.2...v1.26.0](https://github.com/OneBusAway/python-sdk/compare/v1.25.2...v1.26.0)
6+
7+
### Features
8+
9+
* **api:** api update ([7f9712d](https://github.com/OneBusAway/python-sdk/commit/7f9712d23e5ddecb310ae8138b5a8357e69eafd4))
10+
* **internal/types:** support eagerly validating pydantic iterators ([48a9039](https://github.com/OneBusAway/python-sdk/commit/48a9039f0f206e11ad85df3bbe6487c1a95186aa))
11+
312
## 1.25.2 (2026-05-09)
413

514
Full Changelog: [v1.25.1...v1.25.2](https://github.com/OneBusAway/python-sdk/compare/v1.25.1...v1.25.2)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "onebusaway"
3-
version = "1.25.2"
3+
version = "1.26.0"
44
description = "The official Python library for the onebusaway-sdk API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/onebusaway/_models.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
ClassVar,
2626
Protocol,
2727
Required,
28+
Annotated,
2829
ParamSpec,
30+
TypeAlias,
2931
TypedDict,
3032
TypeGuard,
3133
final,
@@ -79,7 +81,15 @@
7981
from ._constants import RAW_RESPONSE_HEADER
8082

8183
if TYPE_CHECKING:
84+
from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler
85+
from pydantic_core import CoreSchema, core_schema
8286
from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema
87+
else:
88+
try:
89+
from pydantic_core import CoreSchema, core_schema
90+
except ImportError:
91+
CoreSchema = None
92+
core_schema = None
8393

8494
__all__ = ["BaseModel", "GenericModel"]
8595

@@ -396,6 +406,76 @@ def model_dump_json(
396406
)
397407

398408

409+
class _EagerIterable(list[_T], Generic[_T]):
410+
"""
411+
Accepts any Iterable[T] input (including generators), consumes it
412+
eagerly, and validates all items upfront.
413+
414+
Validation preserves the original container type where possible
415+
(e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON)
416+
always emits a list — round-tripping through model_dump() will not
417+
restore the original container type.
418+
"""
419+
420+
@classmethod
421+
def __get_pydantic_core_schema__(
422+
cls,
423+
source_type: Any,
424+
handler: GetCoreSchemaHandler,
425+
) -> CoreSchema:
426+
(item_type,) = get_args(source_type) or (Any,)
427+
item_schema: CoreSchema = handler.generate_schema(item_type)
428+
list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema)
429+
430+
return core_schema.no_info_wrap_validator_function(
431+
cls._validate,
432+
list_of_items_schema,
433+
serialization=core_schema.plain_serializer_function_ser_schema(
434+
cls._serialize,
435+
info_arg=False,
436+
),
437+
)
438+
439+
@staticmethod
440+
def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any:
441+
original_type: type[Any] = type(v)
442+
443+
# Normalize to list so list_schema can validate each item
444+
if isinstance(v, list):
445+
items: list[_T] = v
446+
else:
447+
try:
448+
items = list(v)
449+
except TypeError as e:
450+
raise TypeError("Value is not iterable") from e
451+
452+
# Validate items against the inner schema
453+
validated: list[_T] = handler(items)
454+
455+
# Reconstruct original container type
456+
if original_type is list:
457+
return validated
458+
# str(list) produces the list's repr, not a string built from items,
459+
# so skip reconstruction for str and its subclasses.
460+
if issubclass(original_type, str):
461+
return validated
462+
try:
463+
return original_type(validated)
464+
except (TypeError, ValueError):
465+
# If the type cannot be reconstructed, just return the validated list
466+
return validated
467+
468+
@staticmethod
469+
def _serialize(v: Iterable[_T]) -> list[_T]:
470+
"""Always serialize as a list so Pydantic's JSON encoder is happy."""
471+
if isinstance(v, list):
472+
return v
473+
return list(v)
474+
475+
476+
EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable]
477+
478+
399479
def _construct_field(value: object, field: FieldInfo, key: str) -> object:
400480
if value is None:
401481
return field_get_default(field)

src/onebusaway/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
22

33
__title__ = "onebusaway"
4-
__version__ = "1.25.2" # x-release-please-version
4+
__version__ = "1.26.0" # x-release-please-version

src/onebusaway/types/trip_detail_retrieve_response.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class TripDetailRetrieveResponseDataEntryStatusPosition(BaseModel):
6767

6868

6969
class TripDetailRetrieveResponseDataEntryStatus(BaseModel):
70+
"""Trip-specific status for the arriving transit vehicle."""
71+
7072
active_trip_id: str = FieldInfo(alias="activeTripId")
7173
"""Trip ID of the trip the vehicle is actively serving."""
7274

@@ -178,6 +180,7 @@ class TripDetailRetrieveResponseDataEntry(BaseModel):
178180
situation_ids: Optional[List[str]] = FieldInfo(alias="situationIds", default=None)
179181

180182
status: Optional[TripDetailRetrieveResponseDataEntryStatus] = None
183+
"""Trip-specific status for the arriving transit vehicle."""
181184

182185

183186
class TripDetailRetrieveResponseData(BaseModel):

0 commit comments

Comments
 (0)