Skip to content

Commit 902ddff

Browse files
Merge pull request #299 from OneBusAway/release-please--branches--main--changes--next
release: 1.12.0
2 parents 3b55217 + 1533b40 commit 902ddff

File tree

9 files changed

+81
-5
lines changed

9 files changed

+81
-5
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.11.1"
2+
".": "1.12.0"
33
}

CHANGELOG.md

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

3+
## 1.12.0 (2025-06-03)
4+
5+
Full Changelog: [v1.11.1...v1.12.0](https://github.com/OneBusAway/python-sdk/compare/v1.11.1...v1.12.0)
6+
7+
### Features
8+
9+
* **client:** add follow_redirects request option ([569c63a](https://github.com/OneBusAway/python-sdk/commit/569c63a79d7d69d4e7f54466860e462114385db9))
10+
11+
12+
### Chores
13+
14+
* **docs:** remove reference to rye shell ([064f5b8](https://github.com/OneBusAway/python-sdk/commit/064f5b86a6b67b49431886f2892cdfb6cd221e8a))
15+
316
## 1.11.1 (2025-05-22)
417

518
Full Changelog: [v1.11.0...v1.11.1](https://github.com/OneBusAway/python-sdk/compare/v1.11.0...v1.11.1)

CONTRIBUTING.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ $ rye sync --all-features
1717
You can then run scripts using `rye run python script.py` or by activating the virtual environment:
1818

1919
```sh
20-
$ rye shell
21-
# or manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work
20+
# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work
2221
$ source .venv/bin/activate
2322

2423
# now you can omit the `rye run` prefix

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.11.1"
3+
version = "1.12.0"
44
description = "The official Python library for the onebusaway-sdk API"
55
dynamic = ["readme"]
66
license = "Apache-2.0"

src/onebusaway/_base_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,9 @@ def request(
960960
if self.custom_auth is not None:
961961
kwargs["auth"] = self.custom_auth
962962

963+
if options.follow_redirects is not None:
964+
kwargs["follow_redirects"] = options.follow_redirects
965+
963966
log.debug("Sending HTTP Request: %s %s", request.method, request.url)
964967

965968
response = None
@@ -1460,6 +1463,9 @@ async def request(
14601463
if self.custom_auth is not None:
14611464
kwargs["auth"] = self.custom_auth
14621465

1466+
if options.follow_redirects is not None:
1467+
kwargs["follow_redirects"] = options.follow_redirects
1468+
14631469
log.debug("Sending HTTP Request: %s %s", request.method, request.url)
14641470

14651471
response = None

src/onebusaway/_models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
737737
idempotency_key: str
738738
json_data: Body
739739
extra_json: AnyMapping
740+
follow_redirects: bool
740741

741742

742743
@final
@@ -750,6 +751,7 @@ class FinalRequestOptions(pydantic.BaseModel):
750751
files: Union[HttpxRequestFiles, None] = None
751752
idempotency_key: Union[str, None] = None
752753
post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
754+
follow_redirects: Union[bool, None] = None
753755

754756
# It should be noted that we cannot use `json` here as that would override
755757
# a BaseModel method in an incompatible fashion.

src/onebusaway/_types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class RequestOptions(TypedDict, total=False):
100100
params: Query
101101
extra_json: AnyMapping
102102
idempotency_key: str
103+
follow_redirects: bool
103104

104105

105106
# Sentinel class used until PEP 0661 is accepted
@@ -215,3 +216,4 @@ class _GenericAlias(Protocol):
215216

216217
class HttpxSendArgs(TypedDict, total=False):
217218
auth: httpx.Auth
219+
follow_redirects: bool

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.11.1" # x-release-please-version
4+
__version__ = "1.12.0" # x-release-please-version

tests/test_client.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,33 @@ def retry_handler(_request: httpx.Request) -> httpx.Response:
818818

819819
assert response.http_request.headers.get("x-stainless-retry-count") == "42"
820820

821+
@pytest.mark.respx(base_url=base_url)
822+
def test_follow_redirects(self, respx_mock: MockRouter) -> None:
823+
# Test that the default follow_redirects=True allows following redirects
824+
respx_mock.post("/redirect").mock(
825+
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
826+
)
827+
respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
828+
829+
response = self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
830+
assert response.status_code == 200
831+
assert response.json() == {"status": "ok"}
832+
833+
@pytest.mark.respx(base_url=base_url)
834+
def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
835+
# Test that follow_redirects=False prevents following redirects
836+
respx_mock.post("/redirect").mock(
837+
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
838+
)
839+
840+
with pytest.raises(APIStatusError) as exc_info:
841+
self.client.post(
842+
"/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
843+
)
844+
845+
assert exc_info.value.response.status_code == 302
846+
assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"
847+
821848

822849
class TestAsyncOnebusawaySDK:
823850
client = AsyncOnebusawaySDK(base_url=base_url, api_key=api_key, _strict_response_validation=True)
@@ -1634,3 +1661,30 @@ async def test_main() -> None:
16341661
raise AssertionError("calling get_platform using asyncify resulted in a hung process")
16351662

16361663
time.sleep(0.1)
1664+
1665+
@pytest.mark.respx(base_url=base_url)
1666+
async def test_follow_redirects(self, respx_mock: MockRouter) -> None:
1667+
# Test that the default follow_redirects=True allows following redirects
1668+
respx_mock.post("/redirect").mock(
1669+
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
1670+
)
1671+
respx_mock.get("/redirected").mock(return_value=httpx.Response(200, json={"status": "ok"}))
1672+
1673+
response = await self.client.post("/redirect", body={"key": "value"}, cast_to=httpx.Response)
1674+
assert response.status_code == 200
1675+
assert response.json() == {"status": "ok"}
1676+
1677+
@pytest.mark.respx(base_url=base_url)
1678+
async def test_follow_redirects_disabled(self, respx_mock: MockRouter) -> None:
1679+
# Test that follow_redirects=False prevents following redirects
1680+
respx_mock.post("/redirect").mock(
1681+
return_value=httpx.Response(302, headers={"Location": f"{base_url}/redirected"})
1682+
)
1683+
1684+
with pytest.raises(APIStatusError) as exc_info:
1685+
await self.client.post(
1686+
"/redirect", body={"key": "value"}, options={"follow_redirects": False}, cast_to=httpx.Response
1687+
)
1688+
1689+
assert exc_info.value.response.status_code == 302
1690+
assert exc_info.value.response.headers["Location"] == f"{base_url}/redirected"

0 commit comments

Comments
 (0)