diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 397c4203..cdcf20eb 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.22.0" + ".": "1.23.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 4ba48165..b6f7c20d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 46 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-ff61a38530dfae03860bceb49379e84bfc7434eeb5d2f1dc9677cb162014faf1.yml -openapi_spec_hash: df3bdaf4acf575bb07767cae7ca24d69 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-46640c1b468813b828be61b1af5cb5450f9555c4c757c5a740189906a8d56672.yml +openapi_spec_hash: 1d5845ae61d2c0a143db43d579b048c5 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f38ffed..b790daab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Changelog +## 1.23.0 (2025-04-21) + +Full Changelog: [v1.22.0...v1.23.0](https://github.com/Finch-API/finch-api-python/compare/v1.22.0...v1.23.0) + +### Features + +* **api:** api update ([6355866](https://github.com/Finch-API/finch-api-python/commit/6355866b36eba70636f458528a9db94d24b38998)) + + +### Bug Fixes + +* **internal:** fix fixture import lint ([a4d1919](https://github.com/Finch-API/finch-api-python/commit/a4d19190d65a235e57eb1895645059b01df3332b)) + + +### Chores + +* **internal:** base client updates ([dd645de](https://github.com/Finch-API/finch-api-python/commit/dd645de5788da66d69a639904ab95c72eae09a48)) +* **internal:** bump pyright version ([9a19507](https://github.com/Finch-API/finch-api-python/commit/9a1950770cb00259bf703f270065252b2a5858b6)) +* **internal:** update models test ([8fca672](https://github.com/Finch-API/finch-api-python/commit/8fca67214e73ed85bb66e9fbec2dd2e9454538ac)) + ## 1.22.0 (2025-04-14) Full Changelog: [v1.21.1...v1.22.0](https://github.com/Finch-API/finch-api-python/compare/v1.21.1...v1.22.0) diff --git a/pyproject.toml b/pyproject.toml index 13ce2cb5..af1a9495 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "finch-api" -version = "1.22.0" +version = "1.23.0" description = "The official Python library for the Finch API" dynamic = ["readme"] license = "Apache-2.0" @@ -42,7 +42,7 @@ Repository = "https://github.com/Finch-API/finch-api-python" managed = true # version pins are in requirements-dev.lock dev-dependencies = [ - "pyright>=1.1.359", + "pyright==1.1.399", "mypy", "respx", "pytest", diff --git a/requirements-dev.lock b/requirements-dev.lock index b2e2daa3..6ef50771 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -69,7 +69,7 @@ pydantic-core==2.27.1 # via pydantic pygments==2.18.0 # via rich -pyright==1.1.392.post0 +pyright==1.1.399 pytest==8.3.3 # via pytest-asyncio pytest-asyncio==0.24.0 diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index 07f92a0c..71df4c6c 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -99,7 +99,11 @@ _AsyncStreamT = TypeVar("_AsyncStreamT", bound=AsyncStream[Any]) if TYPE_CHECKING: - from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT + from httpx._config import ( + DEFAULT_TIMEOUT_CONFIG, # pyright: ignore[reportPrivateImportUsage] + ) + + HTTPX_DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_CONFIG else: try: from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT @@ -116,6 +120,7 @@ class PageInfo: url: URL | NotGiven params: Query | NotGiven + json: Body | NotGiven @overload def __init__( @@ -131,19 +136,30 @@ def __init__( params: Query, ) -> None: ... + @overload + def __init__( + self, + *, + json: Body, + ) -> None: ... + def __init__( self, *, url: URL | NotGiven = NOT_GIVEN, + json: Body | NotGiven = NOT_GIVEN, params: Query | NotGiven = NOT_GIVEN, ) -> None: self.url = url + self.json = json self.params = params @override def __repr__(self) -> str: if self.url: return f"{self.__class__.__name__}(url={self.url})" + if self.json: + return f"{self.__class__.__name__}(json={self.json})" return f"{self.__class__.__name__}(params={self.params})" @@ -192,6 +208,19 @@ def _info_to_options(self, info: PageInfo) -> FinalRequestOptions: options.url = str(url) return options + if not isinstance(info.json, NotGiven): + if not is_mapping(info.json): + raise TypeError("Pagination is only supported with mappings") + + if not options.json_data: + options.json_data = {**info.json} + else: + if not is_mapping(options.json_data): + raise TypeError("Pagination is only supported with mappings") + + options.json_data = {**options.json_data, **info.json} + return options + raise ValueError("Unexpected PageInfo state") diff --git a/src/finch/_models.py b/src/finch/_models.py index 34935716..58b9263e 100644 --- a/src/finch/_models.py +++ b/src/finch/_models.py @@ -19,7 +19,6 @@ ) import pydantic -import pydantic.generics from pydantic.fields import FieldInfo from ._types import ( diff --git a/src/finch/_utils/_typing.py b/src/finch/_utils/_typing.py index 1958820f..1bac9542 100644 --- a/src/finch/_utils/_typing.py +++ b/src/finch/_utils/_typing.py @@ -110,7 +110,7 @@ class MyResponse(Foo[_T]): ``` """ cls = cast(object, get_origin(typ) or typ) - if cls in generic_bases: + if cls in generic_bases: # pyright: ignore[reportUnnecessaryContains] # we're given the class directly return extract_type_arg(typ, index) diff --git a/src/finch/_version.py b/src/finch/_version.py index 34bdbea5..ef8bd37d 100644 --- a/src/finch/_version.py +++ b/src/finch/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "finch" -__version__ = "1.22.0" # x-release-please-version +__version__ = "1.23.0" # x-release-please-version diff --git a/src/finch/resources/sandbox/company.py b/src/finch/resources/sandbox/company.py index b48d3d1d..f69851f3 100644 --- a/src/finch/resources/sandbox/company.py +++ b/src/finch/resources/sandbox/company.py @@ -77,7 +77,8 @@ def update( primary_email: The email of the main administrator on the account. - primary_phone_number: The phone number of the main administrator on the account. Format: `XXXXXXXXXX` + primary_phone_number: The phone number of the main administrator on the account. Format: E.164, with + extension where applicable, e.g. `+NNNNNNNNNNN xExtension` extra_headers: Send extra headers @@ -163,7 +164,8 @@ async def update( primary_email: The email of the main administrator on the account. - primary_phone_number: The phone number of the main administrator on the account. Format: `XXXXXXXXXX` + primary_phone_number: The phone number of the main administrator on the account. Format: E.164, with + extension where applicable, e.g. `+NNNNNNNNNNN xExtension` extra_headers: Send extra headers diff --git a/src/finch/types/hris/company/company.py b/src/finch/types/hris/company/company.py index 0b4a14ae..5fefe32f 100644 --- a/src/finch/types/hris/company/company.py +++ b/src/finch/types/hris/company/company.py @@ -77,4 +77,7 @@ class Company(BaseModel): """The email of the main administrator on the account.""" primary_phone_number: Optional[str] = None - """The phone number of the main administrator on the account. Format: `XXXXXXXXXX`""" + """The phone number of the main administrator on the account. + + Format: E.164, with extension where applicable, e.g. `+NNNNNNNNNNN xExtension` + """ diff --git a/src/finch/types/sandbox/company_update_params.py b/src/finch/types/sandbox/company_update_params.py index 542a8b53..1337ed21 100644 --- a/src/finch/types/sandbox/company_update_params.py +++ b/src/finch/types/sandbox/company_update_params.py @@ -32,7 +32,10 @@ class CompanyUpdateParams(TypedDict, total=False): """The email of the main administrator on the account.""" primary_phone_number: Required[Optional[str]] - """The phone number of the main administrator on the account. Format: `XXXXXXXXXX`""" + """The phone number of the main administrator on the account. + + Format: E.164, with extension where applicable, e.g. `+NNNNNNNNNNN xExtension` + """ class Account(TypedDict, total=False): diff --git a/src/finch/types/sandbox/company_update_response.py b/src/finch/types/sandbox/company_update_response.py index 8f0eb852..b45e36e5 100644 --- a/src/finch/types/sandbox/company_update_response.py +++ b/src/finch/types/sandbox/company_update_response.py @@ -74,4 +74,7 @@ class CompanyUpdateResponse(BaseModel): """The email of the main administrator on the account.""" primary_phone_number: Optional[str] = None - """The phone number of the main administrator on the account. Format: `XXXXXXXXXX`""" + """The phone number of the main administrator on the account. + + Format: E.164, with extension where applicable, e.g. `+NNNNNNNNNNN xExtension` + """ diff --git a/tests/api_resources/test_access_tokens.py b/tests/api_resources/test_access_tokens.py index 5eb9ae14..ad26c0d4 100644 --- a/tests/api_resources/test_access_tokens.py +++ b/tests/api_resources/test_access_tokens.py @@ -12,7 +12,8 @@ from tests.utils import assert_matches_type if TYPE_CHECKING: - from _pytest.fixtures import FixtureRequest + + from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage] base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") client_id = "00000000-0000-0000-0000-000000000000" diff --git a/tests/conftest.py b/tests/conftest.py index 6736c763..2aaf6585 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ from finch import Finch, AsyncFinch if TYPE_CHECKING: - from _pytest.fixtures import FixtureRequest + from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage] pytest.register_assert_rewrite("tests.utils") diff --git a/tests/test_models.py b/tests/test_models.py index ee0f1618..0021e331 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -492,12 +492,15 @@ class Model(BaseModel): resource_id: Optional[str] = None m = Model.construct() + assert m.resource_id is None assert "resource_id" not in m.model_fields_set m = Model.construct(resource_id=None) + assert m.resource_id is None assert "resource_id" in m.model_fields_set m = Model.construct(resource_id="foo") + assert m.resource_id == "foo" assert "resource_id" in m.model_fields_set @@ -832,7 +835,7 @@ class B(BaseModel): @pytest.mark.skipif(not PYDANTIC_V2, reason="TypeAliasType is not supported in Pydantic v1") def test_type_alias_type() -> None: - Alias = TypeAliasType("Alias", str) + Alias = TypeAliasType("Alias", str) # pyright: ignore class Model(BaseModel): alias: Alias