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/.stats.yml b/.stats.yml index 434689b7..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-05a1c7485ea6dd75ad2fb1a0628570d88a3e7c4f1e1ecad433711c78deae50e6.yml -openapi_spec_hash: 6d6014d50e18c98219b496bb2a5dab1d +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/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/_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 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/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 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/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 6b01e3fa..6f0dbebf 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[int] = None + + threshold: Optional[int] = 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 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/hris/individual.py b/src/finch/types/hris/individual.py index 288466ad..926f7c67 100644 --- a/src/finch/types/hris/individual.py +++ b/src/finch/types/hris/individual.py @@ -1,41 +1,32 @@ # 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", "Email", "PhoneNumber"] +__all__ = ["Individual", "UnionMember0", "UnionMember0PhoneNumber", "UnionMember0Email", "BatchError"] -class Email(BaseModel): +class UnionMember0PhoneNumber(BaseModel): data: Optional[str] = None type: Optional[Literal["work", "personal"]] = None -class PhoneNumber(BaseModel): - data: Optional[str] = None +class UnionMember0Email(BaseModel): + data: str type: Optional[Literal["work", "personal"]] = None -class Individual(BaseModel): - id: Optional[str] = None +class UnionMember0(BaseModel): + 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", @@ -62,13 +53,22 @@ 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[UnionMember0Email]] = 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. @@ -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 BatchError(BaseModel): + code: float + + message: str + + name: str + + finch_code: Optional[str] = None + + +Individual: TypeAlias = Union[UnionMember0, BatchError] 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/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 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/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. 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/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/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""" 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/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", 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", ) diff --git a/tests/api_resources/sandbox/test_payment.py b/tests/api_resources/sandbox/test_payment.py index 3b845874..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", @@ -41,7 +41,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "employee_deductions": [ { "amount": 2000, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "usd", "name": "401k test", "pre_tax": True, @@ -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", @@ -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", @@ -133,7 +133,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "employee_deductions": [ { "amount": 2000, - "attributes": {"metadata": {"metadata": {"foo": "bar"}}}, + "attributes": {"metadata": {"metadata": {"foo": {}}}}, "currency": "usd", "name": "401k test", "pre_tax": True, @@ -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", @@ -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", 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)