From f6afe91e8079395b6644573908397bf66696af1b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 21:20:20 +0000 Subject: [PATCH 01/30] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index a17fa159..c5637e41 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-a9dc15ba77c4c6e40c8f2429b1d614e7fe6888910579b54002fb90d418682d09.yml -openapi_spec_hash: be98b11d320aa0a1f3443650ce1b5b90 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-18b03a9c4c43831116acdf6b551d1c469efb6f645b16f406ad8647e4aee2ff39.yml +openapi_spec_hash: 8ef2bb08a7710a32a4fe509af458e7ac config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From 42ed0b1e0e0e5791b90f5ca9c09fd3614bf86067 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 22:02:34 +0000 Subject: [PATCH 02/30] chore(internal): fix list file params --- src/finch/_utils/_utils.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/finch/_utils/_utils.py b/src/finch/_utils/_utils.py index e5811bba..ea3cf3f2 100644 --- a/src/finch/_utils/_utils.py +++ b/src/finch/_utils/_utils.py @@ -72,8 +72,16 @@ def _extract_items( from .._files import assert_is_file_content # We have exhausted the path, return the entry we found. - assert_is_file_content(obj, key=flattened_key) assert flattened_key is not None + + if is_list(obj): + files: list[tuple[str, FileTypes]] = [] + for entry in obj: + assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "") + files.append((flattened_key + "[]", cast(FileTypes, entry))) + return files + + assert_is_file_content(obj, key=flattened_key) return [(flattened_key, cast(FileTypes, obj))] index += 1 From 64f01072073a9ffc71e2fe274179df4f372953f0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 22:54:58 +0000 Subject: [PATCH 03/30] chore(internal): refactor retries to not use recursion --- src/finch/_base_client.py | 414 ++++++++++++++++---------------------- 1 file changed, 175 insertions(+), 239 deletions(-) diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index 71df4c6c..c46eaebc 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -438,8 +438,7 @@ def _build_headers(self, options: FinalRequestOptions, *, retries_taken: int = 0 headers = httpx.Headers(headers_dict) idempotency_header = self._idempotency_header - if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers: - options.idempotency_key = options.idempotency_key or self._idempotency_key() + if idempotency_header and options.idempotency_key and idempotency_header not in headers: headers[idempotency_header] = options.idempotency_key # Don't set these headers if they were already set or removed by the caller. We check @@ -904,7 +903,6 @@ def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, - remaining_retries: Optional[int] = None, *, stream: Literal[True], stream_cls: Type[_StreamT], @@ -915,7 +913,6 @@ def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, - remaining_retries: Optional[int] = None, *, stream: Literal[False] = False, ) -> ResponseT: ... @@ -925,7 +922,6 @@ def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, - remaining_retries: Optional[int] = None, *, stream: bool = False, stream_cls: Type[_StreamT] | None = None, @@ -935,125 +931,109 @@ def request( self, cast_to: Type[ResponseT], options: FinalRequestOptions, - remaining_retries: Optional[int] = None, *, stream: bool = False, stream_cls: type[_StreamT] | None = None, ) -> ResponseT | _StreamT: - if remaining_retries is not None: - retries_taken = options.get_max_retries(self.max_retries) - remaining_retries - else: - retries_taken = 0 - - return self._request( - cast_to=cast_to, - options=options, - stream=stream, - stream_cls=stream_cls, - retries_taken=retries_taken, - ) + cast_to = self._maybe_override_cast_to(cast_to, options) - def _request( - self, - *, - cast_to: Type[ResponseT], - options: FinalRequestOptions, - retries_taken: int, - stream: bool, - stream_cls: type[_StreamT] | None, - ) -> ResponseT | _StreamT: # create a copy of the options we were given so that if the # options are mutated later & we then retry, the retries are # given the original options input_options = model_copy(options) - - cast_to = self._maybe_override_cast_to(cast_to, options) - options = self._prepare_options(options) - - remaining_retries = options.get_max_retries(self.max_retries) - retries_taken - request = self._build_request(options, retries_taken=retries_taken) - self._prepare_request(request) - - if options.idempotency_key: + if input_options.idempotency_key is None and input_options.method.lower() != "get": # ensure the idempotency key is reused between requests - input_options.idempotency_key = options.idempotency_key + input_options.idempotency_key = self._idempotency_key() - kwargs: HttpxSendArgs = {} - if self.custom_auth is not None: - kwargs["auth"] = self.custom_auth + response: httpx.Response | None = None + max_retries = input_options.get_max_retries(self.max_retries) - log.debug("Sending HTTP Request: %s %s", request.method, request.url) + retries_taken = 0 + for retries_taken in range(max_retries + 1): + options = model_copy(input_options) + options = self._prepare_options(options) - try: - response = self._client.send( - request, - stream=stream or self._should_stream_response_body(request=request), - **kwargs, - ) - except httpx.TimeoutException as err: - log.debug("Encountered httpx.TimeoutException", exc_info=True) + remaining_retries = max_retries - retries_taken + request = self._build_request(options, retries_taken=retries_taken) + self._prepare_request(request) - if remaining_retries > 0: - return self._retry_request( - input_options, - cast_to, - retries_taken=retries_taken, - stream=stream, - stream_cls=stream_cls, - response_headers=None, - ) + kwargs: HttpxSendArgs = {} + if self.custom_auth is not None: + kwargs["auth"] = self.custom_auth - log.debug("Raising timeout error") - raise APITimeoutError(request=request) from err - except Exception as err: - log.debug("Encountered Exception", exc_info=True) + log.debug("Sending HTTP Request: %s %s", request.method, request.url) - if remaining_retries > 0: - return self._retry_request( - input_options, - cast_to, - retries_taken=retries_taken, - stream=stream, - stream_cls=stream_cls, - response_headers=None, + response = None + try: + response = self._client.send( + request, + stream=stream or self._should_stream_response_body(request=request), + **kwargs, ) + except httpx.TimeoutException as err: + log.debug("Encountered httpx.TimeoutException", exc_info=True) + + if remaining_retries > 0: + self._sleep_for_retry( + retries_taken=retries_taken, + max_retries=max_retries, + options=input_options, + response=None, + ) + continue + + log.debug("Raising timeout error") + raise APITimeoutError(request=request) from err + except Exception as err: + log.debug("Encountered Exception", exc_info=True) + + if remaining_retries > 0: + self._sleep_for_retry( + retries_taken=retries_taken, + max_retries=max_retries, + options=input_options, + response=None, + ) + continue + + log.debug("Raising connection error") + raise APIConnectionError(request=request) from err + + log.debug( + 'HTTP Response: %s %s "%i %s" %s', + request.method, + request.url, + response.status_code, + response.reason_phrase, + response.headers, + ) - log.debug("Raising connection error") - raise APIConnectionError(request=request) from err - - log.debug( - 'HTTP Response: %s %s "%i %s" %s', - request.method, - request.url, - response.status_code, - response.reason_phrase, - response.headers, - ) + try: + response.raise_for_status() + except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code + log.debug("Encountered httpx.HTTPStatusError", exc_info=True) + + if remaining_retries > 0 and self._should_retry(err.response): + err.response.close() + self._sleep_for_retry( + retries_taken=retries_taken, + max_retries=max_retries, + options=input_options, + response=response, + ) + continue - try: - response.raise_for_status() - except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code - log.debug("Encountered httpx.HTTPStatusError", exc_info=True) - - if remaining_retries > 0 and self._should_retry(err.response): - err.response.close() - return self._retry_request( - input_options, - cast_to, - retries_taken=retries_taken, - response_headers=err.response.headers, - stream=stream, - stream_cls=stream_cls, - ) + # If the response is streamed then we need to explicitly read the response + # to completion before attempting to access the response text. + if not err.response.is_closed: + err.response.read() - # If the response is streamed then we need to explicitly read the response - # to completion before attempting to access the response text. - if not err.response.is_closed: - err.response.read() + log.debug("Re-raising status error") + raise self._make_status_error_from_response(err.response) from None - log.debug("Re-raising status error") - raise self._make_status_error_from_response(err.response) from None + break + assert response is not None, "could not resolve response (should never happen)" return self._process_response( cast_to=cast_to, options=options, @@ -1063,37 +1043,20 @@ def _request( retries_taken=retries_taken, ) - def _retry_request( - self, - options: FinalRequestOptions, - cast_to: Type[ResponseT], - *, - retries_taken: int, - response_headers: httpx.Headers | None, - stream: bool, - stream_cls: type[_StreamT] | None, - ) -> ResponseT | _StreamT: - remaining_retries = options.get_max_retries(self.max_retries) - retries_taken + def _sleep_for_retry( + self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None + ) -> None: + remaining_retries = max_retries - retries_taken if remaining_retries == 1: log.debug("1 retry left") else: log.debug("%i retries left", remaining_retries) - timeout = self._calculate_retry_timeout(remaining_retries, options, response_headers) + timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None) log.info("Retrying request to %s in %f seconds", options.url, timeout) - # In a synchronous context we are blocking the entire thread. Up to the library user to run the client in a - # different thread if necessary. time.sleep(timeout) - return self._request( - options=options, - cast_to=cast_to, - retries_taken=retries_taken + 1, - stream=stream, - stream_cls=stream_cls, - ) - def _process_response( self, *, @@ -1451,7 +1414,6 @@ async def request( options: FinalRequestOptions, *, stream: Literal[False] = False, - remaining_retries: Optional[int] = None, ) -> ResponseT: ... @overload @@ -1462,7 +1424,6 @@ async def request( *, stream: Literal[True], stream_cls: type[_AsyncStreamT], - remaining_retries: Optional[int] = None, ) -> _AsyncStreamT: ... @overload @@ -1473,7 +1434,6 @@ async def request( *, stream: bool, stream_cls: type[_AsyncStreamT] | None = None, - remaining_retries: Optional[int] = None, ) -> ResponseT | _AsyncStreamT: ... async def request( @@ -1483,120 +1443,111 @@ async def request( *, stream: bool = False, stream_cls: type[_AsyncStreamT] | None = None, - remaining_retries: Optional[int] = None, - ) -> ResponseT | _AsyncStreamT: - if remaining_retries is not None: - retries_taken = options.get_max_retries(self.max_retries) - remaining_retries - else: - retries_taken = 0 - - return await self._request( - cast_to=cast_to, - options=options, - stream=stream, - stream_cls=stream_cls, - retries_taken=retries_taken, - ) - - async def _request( - self, - cast_to: Type[ResponseT], - options: FinalRequestOptions, - *, - stream: bool, - stream_cls: type[_AsyncStreamT] | None, - retries_taken: int, ) -> ResponseT | _AsyncStreamT: if self._platform is None: # `get_platform` can make blocking IO calls so we # execute it earlier while we are in an async context self._platform = await asyncify(get_platform)() + cast_to = self._maybe_override_cast_to(cast_to, options) + # create a copy of the options we were given so that if the # options are mutated later & we then retry, the retries are # given the original options input_options = model_copy(options) - - cast_to = self._maybe_override_cast_to(cast_to, options) - options = await self._prepare_options(options) - - remaining_retries = options.get_max_retries(self.max_retries) - retries_taken - request = self._build_request(options, retries_taken=retries_taken) - await self._prepare_request(request) - - if options.idempotency_key: + if input_options.idempotency_key is None and input_options.method.lower() != "get": # ensure the idempotency key is reused between requests - input_options.idempotency_key = options.idempotency_key + input_options.idempotency_key = self._idempotency_key() - kwargs: HttpxSendArgs = {} - if self.custom_auth is not None: - kwargs["auth"] = self.custom_auth + response: httpx.Response | None = None + max_retries = input_options.get_max_retries(self.max_retries) - try: - response = await self._client.send( - request, - stream=stream or self._should_stream_response_body(request=request), - **kwargs, - ) - except httpx.TimeoutException as err: - log.debug("Encountered httpx.TimeoutException", exc_info=True) + retries_taken = 0 + for retries_taken in range(max_retries + 1): + options = model_copy(input_options) + options = await self._prepare_options(options) - if remaining_retries > 0: - return await self._retry_request( - input_options, - cast_to, - retries_taken=retries_taken, - stream=stream, - stream_cls=stream_cls, - response_headers=None, - ) + remaining_retries = max_retries - retries_taken + request = self._build_request(options, retries_taken=retries_taken) + await self._prepare_request(request) - log.debug("Raising timeout error") - raise APITimeoutError(request=request) from err - except Exception as err: - log.debug("Encountered Exception", exc_info=True) + kwargs: HttpxSendArgs = {} + if self.custom_auth is not None: + kwargs["auth"] = self.custom_auth - if remaining_retries > 0: - return await self._retry_request( - input_options, - cast_to, - retries_taken=retries_taken, - stream=stream, - stream_cls=stream_cls, - response_headers=None, - ) + log.debug("Sending HTTP Request: %s %s", request.method, request.url) - log.debug("Raising connection error") - raise APIConnectionError(request=request) from err + response = None + try: + response = await self._client.send( + request, + stream=stream or self._should_stream_response_body(request=request), + **kwargs, + ) + except httpx.TimeoutException as err: + log.debug("Encountered httpx.TimeoutException", exc_info=True) + + if remaining_retries > 0: + await self._sleep_for_retry( + retries_taken=retries_taken, + max_retries=max_retries, + options=input_options, + response=None, + ) + continue + + log.debug("Raising timeout error") + raise APITimeoutError(request=request) from err + except Exception as err: + log.debug("Encountered Exception", exc_info=True) + + if remaining_retries > 0: + await self._sleep_for_retry( + retries_taken=retries_taken, + max_retries=max_retries, + options=input_options, + response=None, + ) + continue + + log.debug("Raising connection error") + raise APIConnectionError(request=request) from err + + log.debug( + 'HTTP Response: %s %s "%i %s" %s', + request.method, + request.url, + response.status_code, + response.reason_phrase, + response.headers, + ) - log.debug( - 'HTTP Request: %s %s "%i %s"', request.method, request.url, response.status_code, response.reason_phrase - ) + try: + response.raise_for_status() + except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code + log.debug("Encountered httpx.HTTPStatusError", exc_info=True) + + if remaining_retries > 0 and self._should_retry(err.response): + await err.response.aclose() + await self._sleep_for_retry( + retries_taken=retries_taken, + max_retries=max_retries, + options=input_options, + response=response, + ) + continue - try: - response.raise_for_status() - except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code - log.debug("Encountered httpx.HTTPStatusError", exc_info=True) - - if remaining_retries > 0 and self._should_retry(err.response): - await err.response.aclose() - return await self._retry_request( - input_options, - cast_to, - retries_taken=retries_taken, - response_headers=err.response.headers, - stream=stream, - stream_cls=stream_cls, - ) + # If the response is streamed then we need to explicitly read the response + # to completion before attempting to access the response text. + if not err.response.is_closed: + await err.response.aread() - # If the response is streamed then we need to explicitly read the response - # to completion before attempting to access the response text. - if not err.response.is_closed: - await err.response.aread() + log.debug("Re-raising status error") + raise self._make_status_error_from_response(err.response) from None - log.debug("Re-raising status error") - raise self._make_status_error_from_response(err.response) from None + break + assert response is not None, "could not resolve response (should never happen)" return await self._process_response( cast_to=cast_to, options=options, @@ -1606,35 +1557,20 @@ async def _request( retries_taken=retries_taken, ) - async def _retry_request( - self, - options: FinalRequestOptions, - cast_to: Type[ResponseT], - *, - retries_taken: int, - response_headers: httpx.Headers | None, - stream: bool, - stream_cls: type[_AsyncStreamT] | None, - ) -> ResponseT | _AsyncStreamT: - remaining_retries = options.get_max_retries(self.max_retries) - retries_taken + async def _sleep_for_retry( + self, *, retries_taken: int, max_retries: int, options: FinalRequestOptions, response: httpx.Response | None + ) -> None: + remaining_retries = max_retries - retries_taken if remaining_retries == 1: log.debug("1 retry left") else: log.debug("%i retries left", remaining_retries) - timeout = self._calculate_retry_timeout(remaining_retries, options, response_headers) + timeout = self._calculate_retry_timeout(remaining_retries, options, response.headers if response else None) log.info("Retrying request to %s in %f seconds", options.url, timeout) await anyio.sleep(timeout) - return await self._request( - options=options, - cast_to=cast_to, - retries_taken=retries_taken + 1, - stream=stream, - stream_cls=stream_cls, - ) - async def _process_response( self, *, From 579eeddd1fcbbe147add3aa929ee4767e2b43e83 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 22 Apr 2025 23:27:33 +0000 Subject: [PATCH 04/30] fix(pydantic v1): more robust ModelField.annotation check --- src/finch/_models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/finch/_models.py b/src/finch/_models.py index 58b9263e..798956f1 100644 --- a/src/finch/_models.py +++ b/src/finch/_models.py @@ -626,8 +626,8 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, # Note: if one variant defines an alias then they all should discriminator_alias = field_info.alias - if field_info.annotation and is_literal_type(field_info.annotation): - for entry in get_args(field_info.annotation): + if (annotation := getattr(field_info, "annotation", None)) and is_literal_type(annotation): + for entry in get_args(annotation): if isinstance(entry, str): mapping[entry] = variant From f5173692369bdbf1223d2b89be54cc43fe95e50a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:21:11 +0000 Subject: [PATCH 05/30] chore(internal): minor formatting changes --- src/finch/types/connect/session_new_response.py | 1 - src/finch/types/connect/session_reauthenticate_response.py | 1 - src/finch/types/disconnect_response.py | 1 - .../types/hris/benefits/enrolled_individual_benefit_response.py | 1 - .../hris/benefits/unenrolled_individual_benefit_response.py | 1 - src/finch/types/hris/benfit_contribution.py | 1 - src/finch/types/hris/create_company_benefits_response.py | 1 - src/finch/types/hris/update_company_benefit_response.py | 1 - src/finch/types/jobs/automated_create_response.py | 1 - src/finch/types/sandbox/job_create_response.py | 1 - src/finch/types/sandbox/payment_create_response.py | 1 - 11 files changed, 11 deletions(-) diff --git a/src/finch/types/connect/session_new_response.py b/src/finch/types/connect/session_new_response.py index cf343973..6789fe28 100644 --- a/src/finch/types/connect/session_new_response.py +++ b/src/finch/types/connect/session_new_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["SessionNewResponse"] diff --git a/src/finch/types/connect/session_reauthenticate_response.py b/src/finch/types/connect/session_reauthenticate_response.py index 323ebf71..01ea0552 100644 --- a/src/finch/types/connect/session_reauthenticate_response.py +++ b/src/finch/types/connect/session_reauthenticate_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["SessionReauthenticateResponse"] diff --git a/src/finch/types/disconnect_response.py b/src/finch/types/disconnect_response.py index ae2efc6d..2d128175 100644 --- a/src/finch/types/disconnect_response.py +++ b/src/finch/types/disconnect_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from .._models import BaseModel __all__ = ["DisconnectResponse"] diff --git a/src/finch/types/hris/benefits/enrolled_individual_benefit_response.py b/src/finch/types/hris/benefits/enrolled_individual_benefit_response.py index 0b42e9b4..86b76bb9 100644 --- a/src/finch/types/hris/benefits/enrolled_individual_benefit_response.py +++ b/src/finch/types/hris/benefits/enrolled_individual_benefit_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ...._models import BaseModel __all__ = ["EnrolledIndividualBenefitResponse"] diff --git a/src/finch/types/hris/benefits/unenrolled_individual_benefit_response.py b/src/finch/types/hris/benefits/unenrolled_individual_benefit_response.py index aa539f3f..69156881 100644 --- a/src/finch/types/hris/benefits/unenrolled_individual_benefit_response.py +++ b/src/finch/types/hris/benefits/unenrolled_individual_benefit_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ...._models import BaseModel __all__ = ["UnenrolledIndividualBenefitResponse"] diff --git a/src/finch/types/hris/benfit_contribution.py b/src/finch/types/hris/benfit_contribution.py index 9a07b032..1e864568 100644 --- a/src/finch/types/hris/benfit_contribution.py +++ b/src/finch/types/hris/benfit_contribution.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from .benefit_contribution import BenefitContribution __all__ = ["BenfitContribution"] diff --git a/src/finch/types/hris/create_company_benefits_response.py b/src/finch/types/hris/create_company_benefits_response.py index 092bf5c9..4510c33e 100644 --- a/src/finch/types/hris/create_company_benefits_response.py +++ b/src/finch/types/hris/create_company_benefits_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["CreateCompanyBenefitsResponse"] diff --git a/src/finch/types/hris/update_company_benefit_response.py b/src/finch/types/hris/update_company_benefit_response.py index 8f6506e3..d6863975 100644 --- a/src/finch/types/hris/update_company_benefit_response.py +++ b/src/finch/types/hris/update_company_benefit_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["UpdateCompanyBenefitResponse"] diff --git a/src/finch/types/jobs/automated_create_response.py b/src/finch/types/jobs/automated_create_response.py index 8ff5d991..9d53fb1c 100644 --- a/src/finch/types/jobs/automated_create_response.py +++ b/src/finch/types/jobs/automated_create_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["AutomatedCreateResponse"] diff --git a/src/finch/types/sandbox/job_create_response.py b/src/finch/types/sandbox/job_create_response.py index f8e39f16..0c085dfc 100644 --- a/src/finch/types/sandbox/job_create_response.py +++ b/src/finch/types/sandbox/job_create_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["JobCreateResponse"] diff --git a/src/finch/types/sandbox/payment_create_response.py b/src/finch/types/sandbox/payment_create_response.py index 028bbde5..17cdaa8a 100644 --- a/src/finch/types/sandbox/payment_create_response.py +++ b/src/finch/types/sandbox/payment_create_response.py @@ -1,6 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - from ..._models import BaseModel __all__ = ["PaymentCreateResponse"] From d5b591c9cd8d905eab54c91ad66fd6303b2222bc Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:55:15 +0000 Subject: [PATCH 06/30] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index c5637e41..3fb1bf39 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-18b03a9c4c43831116acdf6b551d1c469efb6f645b16f406ad8647e4aee2ff39.yml -openapi_spec_hash: 8ef2bb08a7710a32a4fe509af458e7ac +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-e33325fb830bdd979e9067a492968e5318a5b520572308a5331acb91274735ac.yml +openapi_spec_hash: 0b203de65d7fd1c68f2d81f02849a803 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From 5203afee32ed62d01217ee6bddc41770fb1deccd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 17:58:05 +0000 Subject: [PATCH 07/30] chore(ci): run on more branches and use depot runners --- .github/workflows/ci.yml | 16 ++++++++-------- .github/workflows/publish-pypi.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04b083ca..33820422 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,18 @@ name: CI on: push: - branches: - - main - pull_request: - branches: - - main - - next + branches-ignore: + - 'generated' + - 'codegen/**' + - 'integrated/**' + - 'stl-preview-head/**' + - 'stl-preview-base/**' jobs: lint: timeout-minutes: 10 name: lint - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 @@ -33,7 +33,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index e35862a0..e2bd5137 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -11,7 +11,7 @@ on: jobs: publish: name: publish - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 16734a67..7973ac2b 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -8,7 +8,7 @@ on: jobs: release_doctor: name: release doctor - runs-on: ubuntu-latest + runs-on: depot-ubuntu-24.04 if: github.repository == 'Finch-API/finch-api-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: From e8a6836f06bd970a5ac10189753aa1778feea6ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 19:59:55 +0000 Subject: [PATCH 08/30] chore(ci): only use depot for staging repos --- .github/workflows/ci.yml | 4 ++-- .github/workflows/publish-pypi.yml | 2 +- .github/workflows/release-doctor.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33820422..a843e036 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/finch-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 @@ -33,7 +33,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: depot-ubuntu-24.04 + runs-on: ${{ github.repository == 'stainless-sdks/finch-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index e2bd5137..e35862a0 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -11,7 +11,7 @@ on: jobs: publish: name: publish - runs-on: depot-ubuntu-24.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 7973ac2b..16734a67 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -8,7 +8,7 @@ on: jobs: release_doctor: name: release doctor - runs-on: depot-ubuntu-24.04 + runs-on: ubuntu-latest if: github.repository == 'Finch-API/finch-api-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: From 2864fa89555340d8e654cd17bdc3ee089eaee3a3 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 22:10:44 +0000 Subject: [PATCH 09/30] chore: broadly detect json family of content-type headers --- src/finch/_legacy_response.py | 2 +- src/finch/_response.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/finch/_legacy_response.py b/src/finch/_legacy_response.py index 5f1c724a..24d12a21 100644 --- a/src/finch/_legacy_response.py +++ b/src/finch/_legacy_response.py @@ -297,7 +297,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: # split is required to handle cases where additional information is included # in the response, e.g. application/json; charset=utf-8 content_type, *_ = response.headers.get("content-type", "*").split(";") - if content_type != "application/json": + if not content_type.endswith("json"): if is_basemodel(cast_to): try: data = response.json() diff --git a/src/finch/_response.py b/src/finch/_response.py index a1ed6798..3828f2a2 100644 --- a/src/finch/_response.py +++ b/src/finch/_response.py @@ -237,7 +237,7 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T: # split is required to handle cases where additional information is included # in the response, e.g. application/json; charset=utf-8 content_type, *_ = response.headers.get("content-type", "*").split(";") - if content_type != "application/json": + if not content_type.endswith("json"): if is_basemodel(cast_to): try: data = response.json() From 176d774f1ae10f0b37dd430c7f51cff4dd664db0 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 23:46:33 +0000 Subject: [PATCH 10/30] feat(api): api update --- .stats.yml | 4 ++-- .../types/hris/company/pay_statement_item_list_response.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index 3fb1bf39..434689b7 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-e33325fb830bdd979e9067a492968e5318a5b520572308a5331acb91274735ac.yml -openapi_spec_hash: 0b203de65d7fd1c68f2d81f02849a803 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-05a1c7485ea6dd75ad2fb1a0628570d88a3e7c4f1e1ecad433711c78deae50e6.yml +openapi_spec_hash: 6d6014d50e18c98219b496bb2a5dab1d config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/company/pay_statement_item_list_response.py b/src/finch/types/hris/company/pay_statement_item_list_response.py index 48a0cb0f..31e9cf16 100644 --- a/src/finch/types/hris/company/pay_statement_item_list_response.py +++ b/src/finch/types/hris/company/pay_statement_item_list_response.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import Dict, Optional from typing_extensions import Literal from ...._models import BaseModel @@ -15,7 +15,7 @@ class Attributes(BaseModel): This field is only available for taxes. """ - metadata: Optional[object] = None + metadata: Optional[Dict[str, Optional[object]]] = None """The metadata of the pay statement item derived by the rules engine if available. Each attribute will be a key-value pair defined by a rule. From 21a0e160732aa8524f8a086314e9ab2297f08843 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 19:11:11 +0000 Subject: [PATCH 11/30] feat(api): api update --- .stats.yml | 4 +- src/finch/types/location.py | 8 +- src/finch/types/location_param.py | 22 +++--- .../hris/benefits/test_individuals.py | 28 +++---- tests/api_resources/sandbox/test_company.py | 74 ++++++++++++++++--- tests/api_resources/sandbox/test_directory.py | 16 ++-- .../api_resources/sandbox/test_employment.py | 8 +- .../api_resources/sandbox/test_individual.py | 8 +- 8 files changed, 111 insertions(+), 57 deletions(-) diff --git a/.stats.yml b/.stats.yml index 434689b7..8cc2e0d1 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-05a1c7485ea6dd75ad2fb1a0628570d88a3e7c4f1e1ecad433711c78deae50e6.yml -openapi_spec_hash: 6d6014d50e18c98219b496bb2a5dab1d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-3003136d45e38172828b1eb62bf9d3c876140355b4b1271559108f3df2c87208.yml +openapi_spec_hash: 29a85aba1eec35434ba1db898ea18b0b config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/location.py b/src/finch/types/location.py index fd0d0fab..ba7b2e62 100644 --- a/src/finch/types/location.py +++ b/src/finch/types/location.py @@ -20,12 +20,12 @@ class Location(BaseModel): line2: Optional[str] = None """Apartment, suite, unit, or building.""" - name: Optional[str] = None - postal_code: Optional[str] = None """The postal code or zip code.""" - source_id: Optional[str] = None - state: Optional[str] = None """The state code.""" + + name: Optional[str] = None + + source_id: Optional[str] = None diff --git a/src/finch/types/location_param.py b/src/finch/types/location_param.py index 3bbcab82..541600c0 100644 --- a/src/finch/types/location_param.py +++ b/src/finch/types/location_param.py @@ -3,30 +3,30 @@ from __future__ import annotations from typing import Optional -from typing_extensions import TypedDict +from typing_extensions import Required, TypedDict __all__ = ["LocationParam"] class LocationParam(TypedDict, total=False): - city: Optional[str] + city: Required[Optional[str]] """City, district, suburb, town, or village.""" - country: Optional[str] + country: Required[Optional[str]] """The 2-letter ISO 3166 country code.""" - line1: Optional[str] + line1: Required[Optional[str]] """Street address or PO box.""" - line2: Optional[str] + line2: Required[Optional[str]] """Apartment, suite, unit, or building.""" - name: Optional[str] - - postal_code: Optional[str] + postal_code: Required[Optional[str]] """The postal code or zip code.""" - source_id: Optional[str] - - state: Optional[str] + state: Required[Optional[str]] """The state code.""" + + name: Optional[str] + + source_id: Optional[str] diff --git a/tests/api_resources/hris/benefits/test_individuals.py b/tests/api_resources/hris/benefits/test_individuals.py index 0800ed21..865bfff0 100644 --- a/tests/api_resources/hris/benefits/test_individuals.py +++ b/tests/api_resources/hris/benefits/test_individuals.py @@ -39,16 +39,16 @@ def test_method_enroll_many_with_all_params(self, client: Finch) -> None: { "configuration": { "annual_contribution_limit": "individual", - "annual_maximum": 500000, - "catch_up": False, + "annual_maximum": None, + "catch_up": True, "company_contribution": { - "amount": 400, - "type": "percent", + "amount": 0, + "type": "fixed", }, - "effective_date": parse_date("2025-01-01"), + "effective_date": parse_date("2019-12-27"), "employee_deduction": { - "amount": 1000, - "type": "percent", + "amount": 10000, + "type": "fixed", }, }, "individual_id": "d02a6346-1f08-4312-a064-49ff3cafaa7a", @@ -237,16 +237,16 @@ async def test_method_enroll_many_with_all_params(self, async_client: AsyncFinch { "configuration": { "annual_contribution_limit": "individual", - "annual_maximum": 500000, - "catch_up": False, + "annual_maximum": None, + "catch_up": True, "company_contribution": { - "amount": 400, - "type": "percent", + "amount": 0, + "type": "fixed", }, - "effective_date": parse_date("2025-01-01"), + "effective_date": parse_date("2019-12-27"), "employee_deduction": { - "amount": 1000, - "type": "percent", + "amount": 10000, + "type": "fixed", }, }, "individual_id": "d02a6346-1f08-4312-a064-49ff3cafaa7a", diff --git a/tests/api_resources/sandbox/test_company.py b/tests/api_resources/sandbox/test_company.py index aa0e957f..12b02136 100644 --- a/tests/api_resources/sandbox/test_company.py +++ b/tests/api_resources/sandbox/test_company.py @@ -25,7 +25,16 @@ def test_method_update(self, client: Finch) -> None: ein="ein", entity={}, legal_name="legal_name", - locations=[{}], + locations=[ + { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "postal_code": "postal_code", + "state": "state", + } + ], primary_email="dev@stainless.com", primary_phone_number="primary_phone_number", ) @@ -61,10 +70,10 @@ def test_method_update_with_all_params(self, client: Finch) -> None: "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", } ], primary_email="dev@stainless.com", @@ -80,7 +89,16 @@ def test_raw_response_update(self, client: Finch) -> None: ein="ein", entity={}, legal_name="legal_name", - locations=[{}], + locations=[ + { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "postal_code": "postal_code", + "state": "state", + } + ], primary_email="dev@stainless.com", primary_phone_number="primary_phone_number", ) @@ -98,7 +116,16 @@ def test_streaming_response_update(self, client: Finch) -> None: ein="ein", entity={}, legal_name="legal_name", - locations=[{}], + locations=[ + { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "postal_code": "postal_code", + "state": "state", + } + ], primary_email="dev@stainless.com", primary_phone_number="primary_phone_number", ) as response: @@ -122,7 +149,16 @@ async def test_method_update(self, async_client: AsyncFinch) -> None: ein="ein", entity={}, legal_name="legal_name", - locations=[{}], + locations=[ + { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "postal_code": "postal_code", + "state": "state", + } + ], primary_email="dev@stainless.com", primary_phone_number="primary_phone_number", ) @@ -158,10 +194,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncFinch) -> "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", } ], primary_email="dev@stainless.com", @@ -177,7 +213,16 @@ async def test_raw_response_update(self, async_client: AsyncFinch) -> None: ein="ein", entity={}, legal_name="legal_name", - locations=[{}], + locations=[ + { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "postal_code": "postal_code", + "state": "state", + } + ], primary_email="dev@stainless.com", primary_phone_number="primary_phone_number", ) @@ -195,7 +240,16 @@ async def test_streaming_response_update(self, async_client: AsyncFinch) -> None ein="ein", entity={}, legal_name="legal_name", - locations=[{}], + locations=[ + { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "postal_code": "postal_code", + "state": "state", + } + ], primary_email="dev@stainless.com", primary_phone_number="primary_phone_number", ) as response: diff --git a/tests/api_resources/sandbox/test_directory.py b/tests/api_resources/sandbox/test_directory.py index c7adaf51..20154dec 100644 --- a/tests/api_resources/sandbox/test_directory.py +++ b/tests/api_resources/sandbox/test_directory.py @@ -74,10 +74,10 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, "manager": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}, "middle_name": "middle_name", @@ -93,10 +93,10 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, "source_id": "source_id", "ssn": "ssn", @@ -188,10 +188,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, "manager": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}, "middle_name": "middle_name", @@ -207,10 +207,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, "source_id": "source_id", "ssn": "ssn", diff --git a/tests/api_resources/sandbox/test_employment.py b/tests/api_resources/sandbox/test_employment.py index 0dc28f1e..40e5ffc5 100644 --- a/tests/api_resources/sandbox/test_employment.py +++ b/tests/api_resources/sandbox/test_employment.py @@ -65,10 +65,10 @@ def test_method_update_with_all_params(self, client: Finch) -> None: "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, manager={"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}, middle_name="middle_name", @@ -161,10 +161,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncFinch) -> "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, manager={"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}, middle_name="middle_name", diff --git a/tests/api_resources/sandbox/test_individual.py b/tests/api_resources/sandbox/test_individual.py index 23239fc2..31b04012 100644 --- a/tests/api_resources/sandbox/test_individual.py +++ b/tests/api_resources/sandbox/test_individual.py @@ -53,10 +53,10 @@ def test_method_update_with_all_params(self, client: Finch) -> None: "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, ssn="ssn", ) @@ -133,10 +133,10 @@ async def test_method_update_with_all_params(self, async_client: AsyncFinch) -> "country": "country", "line1": "line1", "line2": "line2", - "name": "name", "postal_code": "postal_code", - "source_id": "source_id", "state": "state", + "name": "name", + "source_id": "source_id", }, ssn="ssn", ) From 55b0723e8791d0ef8414c30443946920e8e54c9b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 20:36:44 +0000 Subject: [PATCH 12/30] feat(api): api update --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8cc2e0d1..b55ccbfc 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-3003136d45e38172828b1eb62bf9d3c876140355b4b1271559108f3df2c87208.yml -openapi_spec_hash: 29a85aba1eec35434ba1db898ea18b0b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-d31af54a2b29a3535df6342584c2511b59a10a7c11c9c983f1cf209199c6ed0e.yml +openapi_spec_hash: 6643320491f28a8bca49846e1b718c70 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From 2954f3ef8117a57b656ce493806c906d91f86c43 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 16:00:05 +0000 Subject: [PATCH 13/30] feat(api): api update --- .stats.yml | 4 ++-- src/finch/pagination.py | 16 ++++------------ src/finch/types/hris/individual_in_directory.py | 4 ++-- src/finch/types/shared/paging.py | 6 +++--- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/.stats.yml b/.stats.yml index b55ccbfc..eb504590 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-d31af54a2b29a3535df6342584c2511b59a10a7c11c9c983f1cf209199c6ed0e.yml -openapi_spec_hash: 6643320491f28a8bca49846e1b718c70 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-47c01c819b97af4a1a342357c958d7072f88f43bfdc5885462f9330dcf99773c.yml +openapi_spec_hash: 15b236a1f536d8fb2e4356ea57de0836 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/pagination.py b/src/finch/pagination.py index dedacd1c..53b07949 100644 --- a/src/finch/pagination.py +++ b/src/finch/pagination.py @@ -136,10 +136,8 @@ def _get_page_items(self) -> List[_T]: def next_page_info(self) -> Optional[PageInfo]: offset = None if self.paging is not None: # pyright: ignore[reportUnnecessaryComparison] - if self.paging.offset is not None: + if self.paging.offset is not None: # pyright: ignore[reportUnnecessaryComparison] offset = self.paging.offset - if offset is None: - return None length = len(self._get_page_items()) current_count = offset + length @@ -173,10 +171,8 @@ def _get_page_items(self) -> List[_T]: def next_page_info(self) -> Optional[PageInfo]: offset = None if self.paging is not None: # pyright: ignore[reportUnnecessaryComparison] - if self.paging.offset is not None: + if self.paging.offset is not None: # pyright: ignore[reportUnnecessaryComparison] offset = self.paging.offset - if offset is None: - return None length = len(self._get_page_items()) current_count = offset + length @@ -209,10 +205,8 @@ def _get_page_items(self) -> List[_T]: def next_page_info(self) -> Optional[PageInfo]: offset = None if self.paging is not None: # pyright: ignore[reportUnnecessaryComparison] - if self.paging.offset is not None: + if self.paging.offset is not None: # pyright: ignore[reportUnnecessaryComparison] offset = self.paging.offset - if offset is None: - return None length = len(self._get_page_items()) current_count = offset + length @@ -245,10 +239,8 @@ def _get_page_items(self) -> List[_T]: def next_page_info(self) -> Optional[PageInfo]: offset = None if self.paging is not None: # pyright: ignore[reportUnnecessaryComparison] - if self.paging.offset is not None: + if self.paging.offset is not None: # pyright: ignore[reportUnnecessaryComparison] offset = self.paging.offset - if offset is None: - return None length = len(self._get_page_items()) current_count = offset + length diff --git a/src/finch/types/hris/individual_in_directory.py b/src/finch/types/hris/individual_in_directory.py index 6918c744..820bc540 100644 --- a/src/finch/types/hris/individual_in_directory.py +++ b/src/finch/types/hris/individual_in_directory.py @@ -13,12 +13,12 @@ class Department(BaseModel): class Manager(BaseModel): - id: Optional[str] = None + id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" class IndividualInDirectory(BaseModel): - id: Optional[str] = None + id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" department: Optional[Department] = None diff --git a/src/finch/types/shared/paging.py b/src/finch/types/shared/paging.py index 418c49b6..40b3fce6 100644 --- a/src/finch/types/shared/paging.py +++ b/src/finch/types/shared/paging.py @@ -8,8 +8,8 @@ class Paging(BaseModel): + offset: int + """The current start index of the returned list of elements""" + count: Optional[int] = None """The total number of elements for the entire query (not just the given page)""" - - offset: Optional[int] = None - """The current start index of the returned list of elements""" From 53a339f1f21f456dbfd5d94337cf8c5f710cd80f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 17:33:18 +0000 Subject: [PATCH 14/30] feat(api): api update --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index eb504590..fc6f01e4 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-47c01c819b97af4a1a342357c958d7072f88f43bfdc5885462f9330dcf99773c.yml -openapi_spec_hash: 15b236a1f536d8fb2e4356ea57de0836 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-18aa62b45276cc7202c0dd786f514671b30e3d5bfc761986c4ca6b587436f935.yml +openapi_spec_hash: c0722ad9e1e066d79b661f5e955dbf64 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From 8a699b4a44565c24703ea63f7be16a1f50fea188 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 19:32:46 +0000 Subject: [PATCH 15/30] feat(api): api update --- .stats.yml | 4 +-- src/finch/types/hris/individual.py | 28 ++++++++++----------- src/finch/types/hris/individual_response.py | 8 +++--- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/.stats.yml b/.stats.yml index fc6f01e4..ecb78f18 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-18aa62b45276cc7202c0dd786f514671b30e3d5bfc761986c4ca6b587436f935.yml -openapi_spec_hash: c0722ad9e1e066d79b661f5e955dbf64 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-ebcacef9e289357a2688343001fd928ada6811c88b841cd738a9a09178b1991c.yml +openapi_spec_hash: 2d9c296dca75299fd6565aafc4875f19 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/individual.py b/src/finch/types/hris/individual.py index 288466ad..3be360ef 100644 --- a/src/finch/types/hris/individual.py +++ b/src/finch/types/hris/individual.py @@ -6,36 +6,27 @@ from ..._models import BaseModel from ..location import Location -__all__ = ["Individual", "Email", "PhoneNumber"] +__all__ = ["Individual", "PhoneNumber", "Email"] -class Email(BaseModel): +class PhoneNumber(BaseModel): data: Optional[str] = None type: Optional[Literal["work", "personal"]] = None -class PhoneNumber(BaseModel): - data: Optional[str] = None +class Email(BaseModel): + data: str type: Optional[Literal["work", "personal"]] = None class Individual(BaseModel): - id: Optional[str] = None + id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" dob: Optional[str] = None - emails: Optional[List[Email]] = None - - encrypted_ssn: Optional[str] = None - """Social Security Number of the individual in **encrypted** format. - - This field is only available with the `ssn` scope enabled and the - `options: { include: ['ssn'] }` param set in the body. - """ - ethnicity: Optional[ Literal[ "asian", @@ -69,6 +60,15 @@ class Individual(BaseModel): residence: Optional[Location] = None + emails: Optional[List[Email]] = None + + encrypted_ssn: Optional[str] = None + """Social Security Number of the individual in **encrypted** format. + + This field is only available with the `ssn` scope enabled and the + `options: { include: ['ssn'] }` param set in the body. + """ + ssn: Optional[str] = None """Social Security Number of the individual. diff --git a/src/finch/types/hris/individual_response.py b/src/finch/types/hris/individual_response.py index e9c80a47..1b6fd4f7 100644 --- a/src/finch/types/hris/individual_response.py +++ b/src/finch/types/hris/individual_response.py @@ -1,7 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional - from ..._models import BaseModel from .individual import Individual @@ -9,8 +7,8 @@ class IndividualResponse(BaseModel): - body: Optional[Individual] = None + body: Individual - code: Optional[int] = None + code: int - individual_id: Optional[str] = None + individual_id: str From f07e754efdb1eade0ec73525e1f49db5e65eded6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 20:53:24 +0000 Subject: [PATCH 16/30] feat(api): api update --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ecb78f18..bb6ae817 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-ebcacef9e289357a2688343001fd928ada6811c88b841cd738a9a09178b1991c.yml -openapi_spec_hash: 2d9c296dca75299fd6565aafc4875f19 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-c2370afb40b9a600e92693131137b40faa9e40e844239205fd075ca3ecdd1483.yml +openapi_spec_hash: 5fb5b714cb5dcb048e4e0e2b7a1e2e8d config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From 61ef4565dfd90805361c46842bf0a41eb69b0aef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 28 Apr 2025 22:18:47 +0000 Subject: [PATCH 17/30] feat(api): api update --- .stats.yml | 4 ++-- src/finch/types/hris/company_benefit.py | 20 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.stats.yml b/.stats.yml index bb6ae817..815a053b 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-c2370afb40b9a600e92693131137b40faa9e40e844239205fd075ca3ecdd1483.yml -openapi_spec_hash: 5fb5b714cb5dcb048e4e0e2b7a1e2e8d +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-93c2fbc3e83e40488eb98b3a725ff189f13d8f71c0835ecfa32b0263985291e4.yml +openapi_spec_hash: e9893a65174ade751b2e63f6e5fa0936 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/company_benefit.py b/src/finch/types/hris/company_benefit.py index 6b01e3fa..67711d37 100644 --- a/src/finch/types/hris/company_benefit.py +++ b/src/finch/types/hris/company_benefit.py @@ -1,18 +1,34 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional +from typing_extensions import Literal from ..._models import BaseModel from .benefit_type import BenefitType from .benefit_frequency import BenefitFrequency -__all__ = ["CompanyBenefit"] +__all__ = ["CompanyBenefit", "CompanyContribution", "CompanyContributionTier"] + + +class CompanyContributionTier(BaseModel): + match: Optional[float] = None + + threshold: Optional[float] = None + + +class CompanyContribution(BaseModel): + tiers: Optional[List[CompanyContributionTier]] = None + + type: Optional[Literal["match"]] = None class CompanyBenefit(BaseModel): benefit_id: str """The id of the benefit.""" + company_contribution: Optional[CompanyContribution] = None + """The company match for this benefit.""" + description: Optional[str] = None frequency: Optional[BenefitFrequency] = None From 4cd4be9d82bfd0faea1fe30aac7dbbb9d54ac76b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 02:29:02 +0000 Subject: [PATCH 18/30] feat(api): api update --- .stats.yml | 4 ++-- src/finch/types/hris/individual.py | 29 +++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.stats.yml b/.stats.yml index 815a053b..2a055f58 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-93c2fbc3e83e40488eb98b3a725ff189f13d8f71c0835ecfa32b0263985291e4.yml -openapi_spec_hash: e9893a65174ade751b2e63f6e5fa0936 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-639dd4ab9ac2acad21a6764fda369a1d189a3e64bf71a65db36daf0f32d98242.yml +openapi_spec_hash: c148f859bdd0b723c856bd472f115f1f config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/individual.py b/src/finch/types/hris/individual.py index 3be360ef..0ce9e3d4 100644 --- a/src/finch/types/hris/individual.py +++ b/src/finch/types/hris/individual.py @@ -1,27 +1,27 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional -from typing_extensions import Literal +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias from ..._models import BaseModel from ..location import Location -__all__ = ["Individual", "PhoneNumber", "Email"] +__all__ = ["Individual", "UnionMember0", "UnionMember0PhoneNumber", "UnionMember0Email", "UnionMember1"] -class PhoneNumber(BaseModel): +class UnionMember0PhoneNumber(BaseModel): data: Optional[str] = None type: Optional[Literal["work", "personal"]] = None -class Email(BaseModel): +class UnionMember0Email(BaseModel): data: str type: Optional[Literal["work", "personal"]] = None -class Individual(BaseModel): +class UnionMember0(BaseModel): id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" @@ -53,14 +53,14 @@ class Individual(BaseModel): middle_name: Optional[str] = None """The legal middle name of the individual.""" - phone_numbers: Optional[List[Optional[PhoneNumber]]] = None + phone_numbers: Optional[List[Optional[UnionMember0PhoneNumber]]] = None preferred_name: Optional[str] = None """The preferred name of the individual.""" residence: Optional[Location] = None - emails: Optional[List[Email]] = None + emails: Optional[List[UnionMember0Email]] = None encrypted_ssn: Optional[str] = None """Social Security Number of the individual in **encrypted** format. @@ -76,3 +76,16 @@ class Individual(BaseModel): `options: { include: ['ssn'] }` param set in the body. [Click here to learn more about enabling the SSN field](/developer-resources/Enable-SSN-Field). """ + + +class UnionMember1(BaseModel): + code: float + + message: str + + name: str + + finch_code: Optional[str] = None + + +Individual: TypeAlias = Union[UnionMember0, UnionMember1] From f4f6ed4f068f0e46f2f5b62e70c021bfb43e22f5 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 10:48:04 +0000 Subject: [PATCH 19/30] feat(api): api update --- .stats.yml | 4 ++-- src/finch/resources/hris/benefits/benefits.py | 8 +++++++ src/finch/types/hris/benefit_create_params.py | 21 ++++++++++++++++--- src/finch/types/hris/company_benefit.py | 4 ++-- tests/api_resources/hris/test_benefits.py | 18 ++++++++++++++++ 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/.stats.yml b/.stats.yml index 2a055f58..ba2c2cba 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-639dd4ab9ac2acad21a6764fda369a1d189a3e64bf71a65db36daf0f32d98242.yml -openapi_spec_hash: c148f859bdd0b723c856bd472f115f1f +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-0583a6e86a80bc62551727b12c37e02a9b4e4ac5bce822b2e2c1cade3588a6f4.yml +openapi_spec_hash: 53783b6cc1f63d9fb5d3a4dba7b0a806 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/resources/hris/benefits/benefits.py b/src/finch/resources/hris/benefits/benefits.py index 472ee4ab..ed4dbe08 100644 --- a/src/finch/resources/hris/benefits/benefits.py +++ b/src/finch/resources/hris/benefits/benefits.py @@ -60,6 +60,7 @@ def with_streaming_response(self) -> BenefitsWithStreamingResponse: def create( self, *, + company_contribution: Optional[benefit_create_params.CompanyContribution] | NotGiven = NOT_GIVEN, description: str | NotGiven = NOT_GIVEN, frequency: Optional[BenefitFrequency] | NotGiven = NOT_GIVEN, type: Optional[BenefitType] | NotGiven = NOT_GIVEN, @@ -76,6 +77,8 @@ def create( `/providers` endpoint to view available types for each provider. Args: + company_contribution: The company match for this benefit. + description: Name of the benefit as it appears in the provider and pay statements. Recommend limiting this to <30 characters due to limitations in specific providers (e.g. Justworks). @@ -96,6 +99,7 @@ def create( "/employer/benefits", body=maybe_transform( { + "company_contribution": company_contribution, "description": description, "frequency": frequency, "type": type, @@ -246,6 +250,7 @@ def with_streaming_response(self) -> AsyncBenefitsWithStreamingResponse: async def create( self, *, + company_contribution: Optional[benefit_create_params.CompanyContribution] | NotGiven = NOT_GIVEN, description: str | NotGiven = NOT_GIVEN, frequency: Optional[BenefitFrequency] | NotGiven = NOT_GIVEN, type: Optional[BenefitType] | NotGiven = NOT_GIVEN, @@ -262,6 +267,8 @@ async def create( `/providers` endpoint to view available types for each provider. Args: + company_contribution: The company match for this benefit. + description: Name of the benefit as it appears in the provider and pay statements. Recommend limiting this to <30 characters due to limitations in specific providers (e.g. Justworks). @@ -282,6 +289,7 @@ async def create( "/employer/benefits", body=await async_maybe_transform( { + "company_contribution": company_contribution, "description": description, "frequency": frequency, "type": type, diff --git a/src/finch/types/hris/benefit_create_params.py b/src/finch/types/hris/benefit_create_params.py index 34e62b09..c964336b 100644 --- a/src/finch/types/hris/benefit_create_params.py +++ b/src/finch/types/hris/benefit_create_params.py @@ -2,16 +2,19 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import TypedDict +from typing import Iterable, Optional +from typing_extensions import Literal, TypedDict from .benefit_type import BenefitType from .benefit_frequency import BenefitFrequency -__all__ = ["BenefitCreateParams"] +__all__ = ["BenefitCreateParams", "CompanyContribution", "CompanyContributionTier"] class BenefitCreateParams(TypedDict, total=False): + company_contribution: Optional[CompanyContribution] + """The company match for this benefit.""" + description: str """Name of the benefit as it appears in the provider and pay statements. @@ -24,3 +27,15 @@ class BenefitCreateParams(TypedDict, total=False): type: Optional[BenefitType] """Type of benefit.""" + + +class CompanyContributionTier(TypedDict, total=False): + match: int + + threshold: int + + +class CompanyContribution(TypedDict, total=False): + tiers: Iterable[CompanyContributionTier] + + type: Literal["match"] diff --git a/src/finch/types/hris/company_benefit.py b/src/finch/types/hris/company_benefit.py index 67711d37..6f0dbebf 100644 --- a/src/finch/types/hris/company_benefit.py +++ b/src/finch/types/hris/company_benefit.py @@ -11,9 +11,9 @@ class CompanyContributionTier(BaseModel): - match: Optional[float] = None + match: Optional[int] = None - threshold: Optional[float] = None + threshold: Optional[int] = None class CompanyContribution(BaseModel): diff --git a/tests/api_resources/hris/test_benefits.py b/tests/api_resources/hris/test_benefits.py index 8d6507f9..9a55c13c 100644 --- a/tests/api_resources/hris/test_benefits.py +++ b/tests/api_resources/hris/test_benefits.py @@ -31,6 +31,15 @@ def test_method_create(self, client: Finch) -> None: @parametrize def test_method_create_with_all_params(self, client: Finch) -> None: benefit = client.hris.benefits.create( + company_contribution={ + "tiers": [ + { + "match": 1, + "threshold": 1, + } + ], + "type": "match", + }, description="description", frequency="one_time", type="401k", @@ -203,6 +212,15 @@ async def test_method_create(self, async_client: AsyncFinch) -> None: @parametrize async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> None: benefit = await async_client.hris.benefits.create( + company_contribution={ + "tiers": [ + { + "match": 1, + "threshold": 1, + } + ], + "type": "match", + }, description="description", frequency="one_time", type="401k", From 388e39c6adc5a39690220b7be5b8a754a845c4ca Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 13:30:36 +0000 Subject: [PATCH 20/30] feat(api): api update --- .stats.yml | 4 ++-- src/finch/types/hris/individual.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.stats.yml b/.stats.yml index ba2c2cba..135a4574 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-0583a6e86a80bc62551727b12c37e02a9b4e4ac5bce822b2e2c1cade3588a6f4.yml -openapi_spec_hash: 53783b6cc1f63d9fb5d3a4dba7b0a806 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-e5ab676f0996530fe4c702d8cbb88862ab8382792d01197a9576e06f5a359d00.yml +openapi_spec_hash: d5d110fa239579917a521521145c1264 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/individual.py b/src/finch/types/hris/individual.py index 0ce9e3d4..926f7c67 100644 --- a/src/finch/types/hris/individual.py +++ b/src/finch/types/hris/individual.py @@ -6,7 +6,7 @@ from ..._models import BaseModel from ..location import Location -__all__ = ["Individual", "UnionMember0", "UnionMember0PhoneNumber", "UnionMember0Email", "UnionMember1"] +__all__ = ["Individual", "UnionMember0", "UnionMember0PhoneNumber", "UnionMember0Email", "BatchError"] class UnionMember0PhoneNumber(BaseModel): @@ -78,7 +78,7 @@ class UnionMember0(BaseModel): """ -class UnionMember1(BaseModel): +class BatchError(BaseModel): code: float message: str @@ -88,4 +88,4 @@ class UnionMember1(BaseModel): finch_code: Optional[str] = None -Individual: TypeAlias = Union[UnionMember0, UnionMember1] +Individual: TypeAlias = Union[UnionMember0, BatchError] From 24da06a214b10d46594f6256c538d39ceca8352f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 22:30:25 +0000 Subject: [PATCH 21/30] feat(api): api update --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 135a4574..eae7b08e 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-e5ab676f0996530fe4c702d8cbb88862ab8382792d01197a9576e06f5a359d00.yml -openapi_spec_hash: d5d110fa239579917a521521145c1264 +openapi_spec_hash: 5c0dec3d2e1fea26d5f99560b226aedd config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From d47842a1a0fe6524649c6f159a23a5679a840c19 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 16:14:16 +0000 Subject: [PATCH 22/30] feat(api): api update --- .stats.yml | 4 +- src/finch/types/hris/employment_data.py | 71 ++++++++++++------- .../types/hris/employment_data_response.py | 8 +-- src/finch/types/income_param.py | 14 ++-- 4 files changed, 59 insertions(+), 38 deletions(-) diff --git a/.stats.yml b/.stats.yml index eae7b08e..005e81a0 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-e5ab676f0996530fe4c702d8cbb88862ab8382792d01197a9576e06f5a359d00.yml -openapi_spec_hash: 5c0dec3d2e1fea26d5f99560b226aedd +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-9810fd8ae1eed14c34c83de1ac110dbfb8cc23d2ac930b641cb0ad40f327ecb8.yml +openapi_spec_hash: e0d44a94626fd6208a0d585ce93d7e89 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/employment_data.py b/src/finch/types/hris/employment_data.py index d05d7c18..140f2274 100644 --- a/src/finch/types/hris/employment_data.py +++ b/src/finch/types/hris/employment_data.py @@ -1,27 +1,35 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional -from typing_extensions import Literal +from typing import List, Union, Optional +from typing_extensions import Literal, TypeAlias from ..income import Income from ..._models import BaseModel from ..location import Location -__all__ = ["EmploymentData", "CustomField", "Department", "Employment", "Manager"] +__all__ = [ + "EmploymentData", + "UnionMember0", + "UnionMember0CustomField", + "UnionMember0Department", + "UnionMember0Employment", + "UnionMember0Manager", + "BatchError", +] -class CustomField(BaseModel): +class UnionMember0CustomField(BaseModel): name: Optional[str] = None - value: Optional[object] = None + value: Union[str, List[object], float, bool, object, None] = None -class Department(BaseModel): +class UnionMember0Department(BaseModel): name: Optional[str] = None """The name of the department associated with the individual.""" -class Employment(BaseModel): +class UnionMember0Employment(BaseModel): subtype: Optional[Literal["full_time", "intern", "part_time", "temp", "seasonal", "individual_contractor"]] = None """The secondary employment type of the individual. @@ -33,28 +41,28 @@ class Employment(BaseModel): """The main employment type of the individual.""" -class Manager(BaseModel): - id: Optional[str] = None +class UnionMember0Manager(BaseModel): + id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" -class EmploymentData(BaseModel): - id: Optional[str] = None +class UnionMember0(BaseModel): + id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" class_code: Optional[str] = None """Worker's compensation classification code for this employee""" - custom_fields: Optional[List[CustomField]] = None + custom_fields: Optional[List[UnionMember0CustomField]] = None """Custom fields for the individual. These are fields which are defined by the employer in the system. """ - department: Optional[Department] = None + department: Optional[UnionMember0Department] = None """The department object.""" - employment: Optional[Employment] = None + employment: Optional[UnionMember0Employment] = None """The employment object.""" employment_status: Optional[ @@ -71,16 +79,6 @@ class EmploymentData(BaseModel): first_name: Optional[str] = None """The legal first name of the individual.""" - income_history: Optional[List[Optional[Income]]] = None - """The array of income history.""" - - income: Optional[Income] = None - """The employee's income as reported by the provider. - - This may not always be annualized income, but may be in units of bi-weekly, - semi-monthly, daily, etc, depending on what information the provider returns. - """ - is_active: Optional[bool] = None """`true` if the individual an an active employee or contractor at the company.""" @@ -91,7 +89,7 @@ class EmploymentData(BaseModel): location: Optional[Location] = None - manager: Optional[Manager] = None + manager: Optional[UnionMember0Manager] = None """The manager object representing the manager of the individual within the org.""" middle_name: Optional[str] = None @@ -107,3 +105,26 @@ class EmploymentData(BaseModel): work_id: Optional[str] = None """This field is deprecated in favour of `source_id`""" + + income_history: Optional[List[Optional[Income]]] = None + """The array of income history.""" + + income: Optional[Income] = None + """The employee's income as reported by the provider. + + This may not always be annualized income, but may be in units of bi-weekly, + semi-monthly, daily, etc, depending on what information the provider returns. + """ + + +class BatchError(BaseModel): + code: float + + message: str + + name: str + + finch_code: Optional[str] = None + + +EmploymentData: TypeAlias = Union[UnionMember0, BatchError] diff --git a/src/finch/types/hris/employment_data_response.py b/src/finch/types/hris/employment_data_response.py index 54f62a6d..656a765a 100644 --- a/src/finch/types/hris/employment_data_response.py +++ b/src/finch/types/hris/employment_data_response.py @@ -1,7 +1,5 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional - from ..._models import BaseModel from .employment_data import EmploymentData @@ -9,9 +7,9 @@ class EmploymentDataResponse(BaseModel): - body: Optional[EmploymentData] = None + body: EmploymentData - code: Optional[int] = None + code: int - individual_id: Optional[str] = None + individual_id: str """A stable Finch `id` (UUID v4) for an individual in the company.""" diff --git a/src/finch/types/income_param.py b/src/finch/types/income_param.py index 4348d5be..d27b1f8b 100644 --- a/src/finch/types/income_param.py +++ b/src/finch/types/income_param.py @@ -3,23 +3,25 @@ from __future__ import annotations from typing import Optional -from typing_extensions import Literal, TypedDict +from typing_extensions import Literal, Required, TypedDict __all__ = ["IncomeParam"] class IncomeParam(TypedDict, total=False): - amount: Optional[int] + amount: Required[Optional[int]] """The income amount in cents.""" - currency: Optional[str] + currency: Required[Optional[str]] """The currency code.""" - effective_date: Optional[str] + effective_date: Required[Optional[str]] """The date the income amount went into effect.""" - unit: Optional[ - Literal["yearly", "quarterly", "monthly", "semi_monthly", "bi_weekly", "weekly", "daily", "hourly", "fixed"] + unit: Required[ + Optional[ + Literal["yearly", "quarterly", "monthly", "semi_monthly", "bi_weekly", "weekly", "daily", "hourly", "fixed"] + ] ] """The income unit of payment. From ebbed03e8849ea81a316fdf22cacbf048e4acc99 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 1 May 2025 17:01:54 +0000 Subject: [PATCH 23/30] feat(api): api update --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 005e81a0..990d63e4 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-9810fd8ae1eed14c34c83de1ac110dbfb8cc23d2ac930b641cb0ad40f327ecb8.yml -openapi_spec_hash: e0d44a94626fd6208a0d585ce93d7e89 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-670346966a2922b17f8aeaa07166171719883a30abbc97ba62da2312c9979076.yml +openapi_spec_hash: 34c486a4a71a90b6fec4e7b5c6e48e70 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From a6df7d18bd6f1bf7333c12f4ab6da43c1a2d9a7e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 17:58:54 +0000 Subject: [PATCH 24/30] feat(api): api update --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 990d63e4..14d9ccd7 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-670346966a2922b17f8aeaa07166171719883a30abbc97ba62da2312c9979076.yml -openapi_spec_hash: 34c486a4a71a90b6fec4e7b5c6e48e70 +openapi_spec_hash: 9dae98ca7e7e2e3b848f70973767cde2 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From 1279854fd435932e1e52c8106f11f8440c8ffb48 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 13:25:50 +0000 Subject: [PATCH 25/30] chore: use lazy imports for resources --- src/finch/_client.py | 471 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 376 insertions(+), 95 deletions(-) diff --git a/src/finch/_client.py b/src/finch/_client.py index 2e8731e8..de8bcd6d 100644 --- a/src/finch/_client.py +++ b/src/finch/_client.py @@ -4,7 +4,7 @@ import os import base64 -from typing import Any, Union, Mapping +from typing import TYPE_CHECKING, Any, Union, Mapping from typing_extensions import Self, override import httpx @@ -22,8 +22,8 @@ RequestOptions, ) from ._utils import is_given, get_async_library +from ._compat import cached_property from ._version import __version__ -from .resources import account, webhooks, providers, access_tokens, request_forwarding from ._streaming import Stream as Stream, AsyncStream as AsyncStream from ._exceptions import APIStatusError from ._base_client import ( @@ -31,29 +31,23 @@ SyncAPIClient, AsyncAPIClient, ) -from .resources.hris import hris -from .resources.jobs import jobs -from .resources.connect import connect -from .resources.payroll import payroll -from .resources.sandbox import sandbox + +if TYPE_CHECKING: + from .resources import hris, jobs, webhooks, account, connect, payroll, sandbox, providers, access_tokens, request_forwarding + from .resources.account import Account, AsyncAccount + from .resources.hris.hris import HRIS, AsyncHRIS + from .resources.jobs.jobs import Jobs, AsyncJobs + from .resources.providers import Providers, AsyncProviders + from .resources.access_tokens import AccessTokens, AsyncAccessTokens + from .resources.connect.connect import Connect, AsyncConnect + from .resources.payroll.payroll import Payroll, AsyncPayroll + from .resources.sandbox.sandbox import Sandbox, AsyncSandbox + from .resources.request_forwarding import RequestForwarding, AsyncRequestForwarding __all__ = ["Timeout", "Transport", "ProxiesTypes", "RequestOptions", "Finch", "AsyncFinch", "Client", "AsyncClient"] class Finch(SyncAPIClient): - access_tokens: access_tokens.AccessTokens - hris: hris.HRIS - providers: providers.Providers - account: account.Account - webhooks: webhooks.Webhooks - request_forwarding: request_forwarding.RequestForwarding - jobs: jobs.Jobs - sandbox: sandbox.Sandbox - payroll: payroll.Payroll - connect: connect.Connect - with_raw_response: FinchWithRawResponse - with_streaming_response: FinchWithStreamedResponse - # client options access_token: str | None client_id: str | None @@ -123,18 +117,73 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.access_tokens = access_tokens.AccessTokens(self) - self.hris = hris.HRIS(self) - self.providers = providers.Providers(self) - self.account = account.Account(self) - self.webhooks = webhooks.Webhooks(self) - self.request_forwarding = request_forwarding.RequestForwarding(self) - self.jobs = jobs.Jobs(self) - self.sandbox = sandbox.Sandbox(self) - self.payroll = payroll.Payroll(self) - self.connect = connect.Connect(self) - self.with_raw_response = FinchWithRawResponse(self) - self.with_streaming_response = FinchWithStreamedResponse(self) + @cached_property + def access_tokens(self) -> AccessTokens: + from .resources.access_tokens import AccessTokens + + return AccessTokens(self) + + @cached_property + def hris(self) -> HRIS: + from .resources.hris import HRIS + + return HRIS(self) + + @cached_property + def providers(self) -> Providers: + from .resources.providers import Providers + + return Providers(self) + + @cached_property + def account(self) -> Account: + from .resources.account import Account + + return Account(self) + + @cached_property + def request_forwarding(self) -> RequestForwarding: + from .resources.request_forwarding import RequestForwarding + + return RequestForwarding(self) + + @cached_property + def jobs(self) -> Jobs: + from .resources.jobs import Jobs + + return Jobs(self) + + @cached_property + def sandbox(self) -> Sandbox: + from .resources.sandbox import Sandbox + + return Sandbox(self) + + @cached_property + def payroll(self) -> Payroll: + from .resources.payroll import Payroll + + return Payroll(self) + + @cached_property + def connect(self) -> Connect: + from .resources.connect import Connect + + return Connect(self) + + @cached_property + def webhooks(self) -> webhooks.Webhooks: + from .resources.webhooks import Webhooks + + return Webhooks(self) + + @cached_property + def with_raw_response(self) -> FinchWithRawResponse: + return FinchWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> FinchWithStreamedResponse: + return FinchWithStreamedResponse(self) @property @override @@ -349,19 +398,6 @@ def _make_status_error( class AsyncFinch(AsyncAPIClient): - access_tokens: access_tokens.AsyncAccessTokens - hris: hris.AsyncHRIS - providers: providers.AsyncProviders - account: account.AsyncAccount - webhooks: webhooks.AsyncWebhooks - request_forwarding: request_forwarding.AsyncRequestForwarding - jobs: jobs.AsyncJobs - sandbox: sandbox.AsyncSandbox - payroll: payroll.AsyncPayroll - connect: connect.AsyncConnect - with_raw_response: AsyncFinchWithRawResponse - with_streaming_response: AsyncFinchWithStreamedResponse - # client options access_token: str | None client_id: str | None @@ -431,18 +467,73 @@ def __init__( _strict_response_validation=_strict_response_validation, ) - self.access_tokens = access_tokens.AsyncAccessTokens(self) - self.hris = hris.AsyncHRIS(self) - self.providers = providers.AsyncProviders(self) - self.account = account.AsyncAccount(self) - self.webhooks = webhooks.AsyncWebhooks(self) - self.request_forwarding = request_forwarding.AsyncRequestForwarding(self) - self.jobs = jobs.AsyncJobs(self) - self.sandbox = sandbox.AsyncSandbox(self) - self.payroll = payroll.AsyncPayroll(self) - self.connect = connect.AsyncConnect(self) - self.with_raw_response = AsyncFinchWithRawResponse(self) - self.with_streaming_response = AsyncFinchWithStreamedResponse(self) + @cached_property + def access_tokens(self) -> AsyncAccessTokens: + from .resources.access_tokens import AsyncAccessTokens + + return AsyncAccessTokens(self) + + @cached_property + def hris(self) -> AsyncHRIS: + from .resources.hris import AsyncHRIS + + return AsyncHRIS(self) + + @cached_property + def providers(self) -> AsyncProviders: + from .resources.providers import AsyncProviders + + return AsyncProviders(self) + + @cached_property + def account(self) -> AsyncAccount: + from .resources.account import AsyncAccount + + return AsyncAccount(self) + + @cached_property + def request_forwarding(self) -> AsyncRequestForwarding: + from .resources.request_forwarding import AsyncRequestForwarding + + return AsyncRequestForwarding(self) + + @cached_property + def jobs(self) -> AsyncJobs: + from .resources.jobs import AsyncJobs + + return AsyncJobs(self) + + @cached_property + def sandbox(self) -> AsyncSandbox: + from .resources.sandbox import AsyncSandbox + + return AsyncSandbox(self) + + @cached_property + def payroll(self) -> AsyncPayroll: + from .resources.payroll import AsyncPayroll + + return AsyncPayroll(self) + + @cached_property + def connect(self) -> AsyncConnect: + from .resources.connect import AsyncConnect + + return AsyncConnect(self) + + @cached_property + def webhooks(self) -> webhooks.AsyncWebhooks: + from .resources.webhooks import AsyncWebhooks + + return AsyncWebhooks(self) + + @cached_property + def with_raw_response(self) -> AsyncFinchWithRawResponse: + return AsyncFinchWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncFinchWithStreamedResponse: + return AsyncFinchWithStreamedResponse(self) @property @override @@ -657,57 +748,247 @@ def _make_status_error( class FinchWithRawResponse: + _client: Finch + def __init__(self, client: Finch) -> None: - self.access_tokens = access_tokens.AccessTokensWithRawResponse(client.access_tokens) - self.hris = hris.HRISWithRawResponse(client.hris) - self.providers = providers.ProvidersWithRawResponse(client.providers) - self.account = account.AccountWithRawResponse(client.account) - self.request_forwarding = request_forwarding.RequestForwardingWithRawResponse(client.request_forwarding) - self.jobs = jobs.JobsWithRawResponse(client.jobs) - self.sandbox = sandbox.SandboxWithRawResponse(client.sandbox) - self.payroll = payroll.PayrollWithRawResponse(client.payroll) - self.connect = connect.ConnectWithRawResponse(client.connect) + self._client = client + + @cached_property + def access_tokens(self) -> access_tokens.AccessTokensWithRawResponse: + from .resources.access_tokens import AccessTokensWithRawResponse + + return AccessTokensWithRawResponse(self._client.access_tokens) + + @cached_property + def hris(self) -> hris.HRISWithRawResponse: + from .resources.hris import HRISWithRawResponse + + return HRISWithRawResponse(self._client.hris) + + @cached_property + def providers(self) -> providers.ProvidersWithRawResponse: + from .resources.providers import ProvidersWithRawResponse + + return ProvidersWithRawResponse(self._client.providers) + + @cached_property + def account(self) -> account.AccountWithRawResponse: + from .resources.account import AccountWithRawResponse + + return AccountWithRawResponse(self._client.account) + + @cached_property + def request_forwarding(self) -> request_forwarding.RequestForwardingWithRawResponse: + from .resources.request_forwarding import RequestForwardingWithRawResponse + + return RequestForwardingWithRawResponse(self._client.request_forwarding) + + @cached_property + def jobs(self) -> jobs.JobsWithRawResponse: + from .resources.jobs import JobsWithRawResponse + + return JobsWithRawResponse(self._client.jobs) + + @cached_property + def sandbox(self) -> sandbox.SandboxWithRawResponse: + from .resources.sandbox import SandboxWithRawResponse + + return SandboxWithRawResponse(self._client.sandbox) + + @cached_property + def payroll(self) -> payroll.PayrollWithRawResponse: + from .resources.payroll import PayrollWithRawResponse + + return PayrollWithRawResponse(self._client.payroll) + + @cached_property + def connect(self) -> connect.ConnectWithRawResponse: + from .resources.connect import ConnectWithRawResponse + + return ConnectWithRawResponse(self._client.connect) class AsyncFinchWithRawResponse: + _client: AsyncFinch + def __init__(self, client: AsyncFinch) -> None: - self.access_tokens = access_tokens.AsyncAccessTokensWithRawResponse(client.access_tokens) - self.hris = hris.AsyncHRISWithRawResponse(client.hris) - self.providers = providers.AsyncProvidersWithRawResponse(client.providers) - self.account = account.AsyncAccountWithRawResponse(client.account) - self.request_forwarding = request_forwarding.AsyncRequestForwardingWithRawResponse(client.request_forwarding) - self.jobs = jobs.AsyncJobsWithRawResponse(client.jobs) - self.sandbox = sandbox.AsyncSandboxWithRawResponse(client.sandbox) - self.payroll = payroll.AsyncPayrollWithRawResponse(client.payroll) - self.connect = connect.AsyncConnectWithRawResponse(client.connect) + self._client = client + + @cached_property + def access_tokens(self) -> access_tokens.AsyncAccessTokensWithRawResponse: + from .resources.access_tokens import AsyncAccessTokensWithRawResponse + + return AsyncAccessTokensWithRawResponse(self._client.access_tokens) + + @cached_property + def hris(self) -> hris.AsyncHRISWithRawResponse: + from .resources.hris import AsyncHRISWithRawResponse + + return AsyncHRISWithRawResponse(self._client.hris) + + @cached_property + def providers(self) -> providers.AsyncProvidersWithRawResponse: + from .resources.providers import AsyncProvidersWithRawResponse + + return AsyncProvidersWithRawResponse(self._client.providers) + + @cached_property + def account(self) -> account.AsyncAccountWithRawResponse: + from .resources.account import AsyncAccountWithRawResponse + + return AsyncAccountWithRawResponse(self._client.account) + + @cached_property + def request_forwarding(self) -> request_forwarding.AsyncRequestForwardingWithRawResponse: + from .resources.request_forwarding import AsyncRequestForwardingWithRawResponse + + return AsyncRequestForwardingWithRawResponse(self._client.request_forwarding) + + @cached_property + def jobs(self) -> jobs.AsyncJobsWithRawResponse: + from .resources.jobs import AsyncJobsWithRawResponse + + return AsyncJobsWithRawResponse(self._client.jobs) + + @cached_property + def sandbox(self) -> sandbox.AsyncSandboxWithRawResponse: + from .resources.sandbox import AsyncSandboxWithRawResponse + + return AsyncSandboxWithRawResponse(self._client.sandbox) + + @cached_property + def payroll(self) -> payroll.AsyncPayrollWithRawResponse: + from .resources.payroll import AsyncPayrollWithRawResponse + + return AsyncPayrollWithRawResponse(self._client.payroll) + + @cached_property + def connect(self) -> connect.AsyncConnectWithRawResponse: + from .resources.connect import AsyncConnectWithRawResponse + + return AsyncConnectWithRawResponse(self._client.connect) class FinchWithStreamedResponse: + _client: Finch + def __init__(self, client: Finch) -> None: - self.access_tokens = access_tokens.AccessTokensWithStreamingResponse(client.access_tokens) - self.hris = hris.HRISWithStreamingResponse(client.hris) - self.providers = providers.ProvidersWithStreamingResponse(client.providers) - self.account = account.AccountWithStreamingResponse(client.account) - self.request_forwarding = request_forwarding.RequestForwardingWithStreamingResponse(client.request_forwarding) - self.jobs = jobs.JobsWithStreamingResponse(client.jobs) - self.sandbox = sandbox.SandboxWithStreamingResponse(client.sandbox) - self.payroll = payroll.PayrollWithStreamingResponse(client.payroll) - self.connect = connect.ConnectWithStreamingResponse(client.connect) + self._client = client + + @cached_property + def access_tokens(self) -> access_tokens.AccessTokensWithStreamingResponse: + from .resources.access_tokens import AccessTokensWithStreamingResponse + + return AccessTokensWithStreamingResponse(self._client.access_tokens) + + @cached_property + def hris(self) -> hris.HRISWithStreamingResponse: + from .resources.hris import HRISWithStreamingResponse + + return HRISWithStreamingResponse(self._client.hris) + + @cached_property + def providers(self) -> providers.ProvidersWithStreamingResponse: + from .resources.providers import ProvidersWithStreamingResponse + + return ProvidersWithStreamingResponse(self._client.providers) + + @cached_property + def account(self) -> account.AccountWithStreamingResponse: + from .resources.account import AccountWithStreamingResponse + + return AccountWithStreamingResponse(self._client.account) + + @cached_property + def request_forwarding(self) -> request_forwarding.RequestForwardingWithStreamingResponse: + from .resources.request_forwarding import RequestForwardingWithStreamingResponse + + return RequestForwardingWithStreamingResponse(self._client.request_forwarding) + + @cached_property + def jobs(self) -> jobs.JobsWithStreamingResponse: + from .resources.jobs import JobsWithStreamingResponse + + return JobsWithStreamingResponse(self._client.jobs) + + @cached_property + def sandbox(self) -> sandbox.SandboxWithStreamingResponse: + from .resources.sandbox import SandboxWithStreamingResponse + + return SandboxWithStreamingResponse(self._client.sandbox) + + @cached_property + def payroll(self) -> payroll.PayrollWithStreamingResponse: + from .resources.payroll import PayrollWithStreamingResponse + + return PayrollWithStreamingResponse(self._client.payroll) + + @cached_property + def connect(self) -> connect.ConnectWithStreamingResponse: + from .resources.connect import ConnectWithStreamingResponse + + return ConnectWithStreamingResponse(self._client.connect) class AsyncFinchWithStreamedResponse: + _client: AsyncFinch + def __init__(self, client: AsyncFinch) -> None: - self.access_tokens = access_tokens.AsyncAccessTokensWithStreamingResponse(client.access_tokens) - self.hris = hris.AsyncHRISWithStreamingResponse(client.hris) - self.providers = providers.AsyncProvidersWithStreamingResponse(client.providers) - self.account = account.AsyncAccountWithStreamingResponse(client.account) - self.request_forwarding = request_forwarding.AsyncRequestForwardingWithStreamingResponse( - client.request_forwarding - ) - self.jobs = jobs.AsyncJobsWithStreamingResponse(client.jobs) - self.sandbox = sandbox.AsyncSandboxWithStreamingResponse(client.sandbox) - self.payroll = payroll.AsyncPayrollWithStreamingResponse(client.payroll) - self.connect = connect.AsyncConnectWithStreamingResponse(client.connect) + self._client = client + + @cached_property + def access_tokens(self) -> access_tokens.AsyncAccessTokensWithStreamingResponse: + from .resources.access_tokens import AsyncAccessTokensWithStreamingResponse + + return AsyncAccessTokensWithStreamingResponse(self._client.access_tokens) + + @cached_property + def hris(self) -> hris.AsyncHRISWithStreamingResponse: + from .resources.hris import AsyncHRISWithStreamingResponse + + return AsyncHRISWithStreamingResponse(self._client.hris) + + @cached_property + def providers(self) -> providers.AsyncProvidersWithStreamingResponse: + from .resources.providers import AsyncProvidersWithStreamingResponse + + return AsyncProvidersWithStreamingResponse(self._client.providers) + + @cached_property + def account(self) -> account.AsyncAccountWithStreamingResponse: + from .resources.account import AsyncAccountWithStreamingResponse + + return AsyncAccountWithStreamingResponse(self._client.account) + + @cached_property + def request_forwarding(self) -> request_forwarding.AsyncRequestForwardingWithStreamingResponse: + from .resources.request_forwarding import AsyncRequestForwardingWithStreamingResponse + + return AsyncRequestForwardingWithStreamingResponse(self._client.request_forwarding) + + @cached_property + def jobs(self) -> jobs.AsyncJobsWithStreamingResponse: + from .resources.jobs import AsyncJobsWithStreamingResponse + + return AsyncJobsWithStreamingResponse(self._client.jobs) + + @cached_property + def sandbox(self) -> sandbox.AsyncSandboxWithStreamingResponse: + from .resources.sandbox import AsyncSandboxWithStreamingResponse + + return AsyncSandboxWithStreamingResponse(self._client.sandbox) + + @cached_property + def payroll(self) -> payroll.AsyncPayrollWithStreamingResponse: + from .resources.payroll import AsyncPayrollWithStreamingResponse + + return AsyncPayrollWithStreamingResponse(self._client.payroll) + + @cached_property + def connect(self) -> connect.AsyncConnectWithStreamingResponse: + from .resources.connect import AsyncConnectWithStreamingResponse + + return AsyncConnectWithStreamingResponse(self._client.connect) Client = Finch From 1fbbcfadaf74e098cca60988083ffb341a35d26b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 14:18:18 +0000 Subject: [PATCH 26/30] feat(api): api update --- .stats.yml | 4 ++-- src/finch/types/hris/pay_statement.py | 8 ++++---- src/finch/types/sandbox/payment_create_params.py | 8 ++++---- tests/api_resources/sandbox/test_payment.py | 16 ++++++++-------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.stats.yml b/.stats.yml index 14d9ccd7..e8926c4e 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-670346966a2922b17f8aeaa07166171719883a30abbc97ba62da2312c9979076.yml -openapi_spec_hash: 9dae98ca7e7e2e3b848f70973767cde2 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-09c5188f5c6dd563b943cad60f5896331ef5fc06e4a699700578f0bc60bd62a1.yml +openapi_spec_hash: 9283951c1a0b3fd41a5e38b647649da6 config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/src/finch/types/hris/pay_statement.py b/src/finch/types/hris/pay_statement.py index b96210e5..24f97b56 100644 --- a/src/finch/types/hris/pay_statement.py +++ b/src/finch/types/hris/pay_statement.py @@ -25,7 +25,7 @@ class EarningAttributesMetadata(BaseModel): - metadata: Optional[Dict[str, object]] = None + metadata: Optional[Dict[str, Optional[object]]] = None """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, @@ -77,7 +77,7 @@ class Earning(BaseModel): class EmployeeDeductionAttributesMetadata(BaseModel): - metadata: Optional[Dict[str, object]] = None + metadata: Optional[Dict[str, Optional[object]]] = None """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, @@ -109,7 +109,7 @@ class EmployeeDeduction(BaseModel): class EmployerContributionAttributesMetadata(BaseModel): - metadata: Optional[Dict[str, object]] = None + metadata: Optional[Dict[str, Optional[object]]] = None """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, @@ -138,7 +138,7 @@ class EmployerContribution(BaseModel): class TaxAttributesMetadata(BaseModel): - metadata: Optional[Dict[str, object]] = None + metadata: Optional[Dict[str, Optional[object]]] = None """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, diff --git a/src/finch/types/sandbox/payment_create_params.py b/src/finch/types/sandbox/payment_create_params.py index 9c606070..f8744ec1 100644 --- a/src/finch/types/sandbox/payment_create_params.py +++ b/src/finch/types/sandbox/payment_create_params.py @@ -35,7 +35,7 @@ class PaymentCreateParams(TypedDict, total=False): class PayStatementEarningAttributesMetadata(TypedDict, total=False): - metadata: Dict[str, object] + metadata: Dict[str, Optional[object]] """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, @@ -87,7 +87,7 @@ class PayStatementEarning(TypedDict, total=False): class PayStatementEmployeeDeductionAttributesMetadata(TypedDict, total=False): - metadata: Dict[str, object] + metadata: Dict[str, Optional[object]] """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, @@ -119,7 +119,7 @@ class PayStatementEmployeeDeduction(TypedDict, total=False): class PayStatementEmployerContributionAttributesMetadata(TypedDict, total=False): - metadata: Dict[str, object] + metadata: Dict[str, Optional[object]] """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, @@ -148,7 +148,7 @@ class PayStatementEmployerContribution(TypedDict, total=False): class PayStatementTaxAttributesMetadata(TypedDict, total=False): - metadata: Dict[str, object] + metadata: Dict[str, Optional[object]] """The metadata to be attached to the entity by existing rules. It is a key-value pairs where the values can be of any type (string, number, diff --git a/tests/api_resources/sandbox/test_payment.py b/tests/api_resources/sandbox/test_payment.py index 3b845874..bd512158 100644 --- a/tests/api_resources/sandbox/test_payment.py +++ b/tests/api_resources/sandbox/test_payment.py @@ -40,10 +40,10 @@ def test_method_create_with_all_params(self, client: Finch) -> None: ], "employee_deductions": [ { - "amount": 2000, + "amount": 0, "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, - "currency": "usd", - "name": "401k test", + "currency": "currency", + "name": "name", "pre_tax": True, "type": "401k", } @@ -61,7 +61,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "amount": 0, "currency": "currency", }, - "individual_id": "b2338cfb-472f-4f72-9faa-e028c083144a", + "individual_id": "individual_id", "net_pay": { "amount": 0, "currency": "currency", @@ -132,10 +132,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> ], "employee_deductions": [ { - "amount": 2000, + "amount": 0, "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, - "currency": "usd", - "name": "401k test", + "currency": "currency", + "name": "name", "pre_tax": True, "type": "401k", } @@ -153,7 +153,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "amount": 0, "currency": "currency", }, - "individual_id": "b2338cfb-472f-4f72-9faa-e028c083144a", + "individual_id": "individual_id", "net_pay": { "amount": 0, "currency": "currency", From 435d47510c5746b63fa7693e1b844a010655e58d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 16:06:02 +0000 Subject: [PATCH 27/30] feat(api): api update --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index e8926c4e..e5cb94c0 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-09c5188f5c6dd563b943cad60f5896331ef5fc06e4a699700578f0bc60bd62a1.yml -openapi_spec_hash: 9283951c1a0b3fd41a5e38b647649da6 +openapi_spec_hash: b1ba73565832de570a90329cb4aab18b config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 From bbaa0656797f95c979a20dfeeaf0a36eec93c72b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 13:33:37 +0000 Subject: [PATCH 28/30] feat(api): api update --- .stats.yml | 4 +-- tests/api_resources/sandbox/test_payment.py | 32 ++++++++++----------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.stats.yml b/.stats.yml index e5cb94c0..ac3940f3 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-09c5188f5c6dd563b943cad60f5896331ef5fc06e4a699700578f0bc60bd62a1.yml -openapi_spec_hash: b1ba73565832de570a90329cb4aab18b +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-f09e5f2c555d7ee764478b7bc73e92cd21f403d6ec189be14574c8367bc131ce.yml +openapi_spec_hash: bd0a8e001f14132c105992d40149909a config_hash: 53778a0b839c4f6ad34fbba051f5e8a6 diff --git a/tests/api_resources/sandbox/test_payment.py b/tests/api_resources/sandbox/test_payment.py index bd512158..49482a0f 100644 --- a/tests/api_resources/sandbox/test_payment.py +++ b/tests/api_resources/sandbox/test_payment.py @@ -31,7 +31,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "earnings": [ { "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "currency", "hours": 0, "name": "name", @@ -40,10 +40,10 @@ def test_method_create_with_all_params(self, client: Finch) -> None: ], "employee_deductions": [ { - "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, - "currency": "currency", - "name": "name", + "amount": 2000, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, + "currency": "usd", + "name": "401k test", "pre_tax": True, "type": "401k", } @@ -51,7 +51,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "employer_contributions": [ { "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "currency", "name": "name", "type": "401k", @@ -61,7 +61,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "amount": 0, "currency": "currency", }, - "individual_id": "individual_id", + "individual_id": "b2338cfb-472f-4f72-9faa-e028c083144a", "net_pay": { "amount": 0, "currency": "currency", @@ -70,7 +70,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "taxes": [ { "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "currency", "employer": True, "name": "name", @@ -123,7 +123,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "earnings": [ { "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "currency", "hours": 0, "name": "name", @@ -132,10 +132,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> ], "employee_deductions": [ { - "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, - "currency": "currency", - "name": "name", + "amount": 2000, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, + "currency": "usd", + "name": "401k test", "pre_tax": True, "type": "401k", } @@ -143,7 +143,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "employer_contributions": [ { "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "currency", "name": "name", "type": "401k", @@ -153,7 +153,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "amount": 0, "currency": "currency", }, - "individual_id": "individual_id", + "individual_id": "b2338cfb-472f-4f72-9faa-e028c083144a", "net_pay": { "amount": 0, "currency": "currency", @@ -162,7 +162,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "taxes": [ { "amount": 0, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "currency", "employer": True, "name": "name", From 9fb0e3875bfc23d6a26ee0dbaf58049c4ee09b37 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 12:42:12 +0000 Subject: [PATCH 29/30] chore(internal): avoid errors for isinstance checks on proxies --- src/finch/_utils/_proxy.py | 5 ++++- tests/test_utils/test_proxy.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/finch/_utils/_proxy.py b/src/finch/_utils/_proxy.py index ffd883e9..0f239a33 100644 --- a/src/finch/_utils/_proxy.py +++ b/src/finch/_utils/_proxy.py @@ -46,7 +46,10 @@ def __dir__(self) -> Iterable[str]: @property # type: ignore @override def __class__(self) -> type: # pyright: ignore - proxied = self.__get_proxied__() + try: + proxied = self.__get_proxied__() + except Exception: + return type(self) if issubclass(type(proxied), LazyProxy): return type(proxied) return proxied.__class__ diff --git a/tests/test_utils/test_proxy.py b/tests/test_utils/test_proxy.py index f5a7028d..5390187d 100644 --- a/tests/test_utils/test_proxy.py +++ b/tests/test_utils/test_proxy.py @@ -21,3 +21,14 @@ def test_recursive_proxy() -> None: assert dir(proxy) == [] assert type(proxy).__name__ == "RecursiveLazyProxy" assert type(operator.attrgetter("name.foo.bar.baz")(proxy)).__name__ == "RecursiveLazyProxy" + + +def test_isinstance_does_not_error() -> None: + class AlwaysErrorProxy(LazyProxy[Any]): + @override + def __load__(self) -> Any: + raise RuntimeError("Mocking missing dependency") + + proxy = AlwaysErrorProxy() + assert not isinstance(proxy, dict) + assert isinstance(proxy, LazyProxy) From 60db95f5486652df571c1bc7f990e52b7b778001 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 8 May 2025 12:42:35 +0000 Subject: [PATCH 30/30] release: 1.26.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ pyproject.toml | 2 +- src/finch/_version.py | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 0c0c0c35..f3dbfd2a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.25.0" + ".": "1.26.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 670b7160..f6c389e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## 1.26.0 (2025-05-08) + +Full Changelog: [v1.25.0...v1.26.0](https://github.com/Finch-API/finch-api-python/compare/v1.25.0...v1.26.0) + +### Features + +* **api:** api update ([bbaa065](https://github.com/Finch-API/finch-api-python/commit/bbaa0656797f95c979a20dfeeaf0a36eec93c72b)) +* **api:** api update ([435d475](https://github.com/Finch-API/finch-api-python/commit/435d47510c5746b63fa7693e1b844a010655e58d)) +* **api:** api update ([1fbbcfa](https://github.com/Finch-API/finch-api-python/commit/1fbbcfadaf74e098cca60988083ffb341a35d26b)) +* **api:** api update ([a6df7d1](https://github.com/Finch-API/finch-api-python/commit/a6df7d18bd6f1bf7333c12f4ab6da43c1a2d9a7e)) +* **api:** api update ([ebbed03](https://github.com/Finch-API/finch-api-python/commit/ebbed03e8849ea81a316fdf22cacbf048e4acc99)) +* **api:** api update ([d47842a](https://github.com/Finch-API/finch-api-python/commit/d47842a1a0fe6524649c6f159a23a5679a840c19)) +* **api:** api update ([24da06a](https://github.com/Finch-API/finch-api-python/commit/24da06a214b10d46594f6256c538d39ceca8352f)) +* **api:** api update ([388e39c](https://github.com/Finch-API/finch-api-python/commit/388e39c6adc5a39690220b7be5b8a754a845c4ca)) +* **api:** api update ([f4f6ed4](https://github.com/Finch-API/finch-api-python/commit/f4f6ed4f068f0e46f2f5b62e70c021bfb43e22f5)) +* **api:** api update ([4cd4be9](https://github.com/Finch-API/finch-api-python/commit/4cd4be9d82bfd0faea1fe30aac7dbbb9d54ac76b)) +* **api:** api update ([61ef456](https://github.com/Finch-API/finch-api-python/commit/61ef4565dfd90805361c46842bf0a41eb69b0aef)) +* **api:** api update ([f07e754](https://github.com/Finch-API/finch-api-python/commit/f07e754efdb1eade0ec73525e1f49db5e65eded6)) +* **api:** api update ([8a699b4](https://github.com/Finch-API/finch-api-python/commit/8a699b4a44565c24703ea63f7be16a1f50fea188)) +* **api:** api update ([53a339f](https://github.com/Finch-API/finch-api-python/commit/53a339f1f21f456dbfd5d94337cf8c5f710cd80f)) +* **api:** api update ([2954f3e](https://github.com/Finch-API/finch-api-python/commit/2954f3ef8117a57b656ce493806c906d91f86c43)) +* **api:** api update ([55b0723](https://github.com/Finch-API/finch-api-python/commit/55b0723e8791d0ef8414c30443946920e8e54c9b)) +* **api:** api update ([21a0e16](https://github.com/Finch-API/finch-api-python/commit/21a0e160732aa8524f8a086314e9ab2297f08843)) + + +### Chores + +* **internal:** avoid errors for isinstance checks on proxies ([9fb0e38](https://github.com/Finch-API/finch-api-python/commit/9fb0e3875bfc23d6a26ee0dbaf58049c4ee09b37)) +* use lazy imports for resources ([1279854](https://github.com/Finch-API/finch-api-python/commit/1279854fd435932e1e52c8106f11f8440c8ffb48)) + ## 1.25.0 (2025-04-23) Full Changelog: [v1.24.0...v1.25.0](https://github.com/Finch-API/finch-api-python/compare/v1.24.0...v1.25.0) diff --git a/pyproject.toml b/pyproject.toml index 4db7e201..a7b77913 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "finch-api" -version = "1.25.0" +version = "1.26.0" description = "The official Python library for the Finch API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/finch/_version.py b/src/finch/_version.py index fa182f4f..4d845766 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.25.0" # x-release-please-version +__version__ = "1.26.0" # x-release-please-version