diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ac9a2e75..55d20255 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,4 +6,4 @@ USER vscode RUN curl -sSf https://rye.astral.sh/get | RYE_VERSION="0.35.0" RYE_INSTALL_OPTION="--yes" bash ENV PATH=/home/vscode/.rye/shims:$PATH -RUN echo "[[ -d .venv ]] && source .venv/bin/activate" >> /home/vscode/.bashrc +RUN echo "[[ -d .venv ]] && source .venv/bin/activate || export PATH=\$PATH" >> /home/vscode/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bbeb30b1..c17fdc16 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,6 +24,9 @@ } } } + }, + "features": { + "ghcr.io/devcontainers/features/node:1": {} } // Features to add to the dev container. More info: https://containers.dev/features. diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 19cc6edc..7ccfe12c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.14.2" + ".": "1.15.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 4068fd94..d401388d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 41 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-97bf4795deec23d1bfd3b0b5fd77c2a93c87f10e5fa3375ab30f4a877be97f53.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-57fcc886b05984f78d7e68e9b2494af925f1b104e3475ed5281fde6c728a8518.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2da92f..7bc7115a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Changelog +## 1.15.0 (2025-02-26) + +Full Changelog: [v1.14.2...v1.15.0](https://github.com/Finch-API/finch-api-python/compare/v1.14.2...v1.15.0) + +### Features + +* **api:** api update ([#602](https://github.com/Finch-API/finch-api-python/issues/602)) ([7b60c37](https://github.com/Finch-API/finch-api-python/commit/7b60c3799d7e28af677d7f040563f011acc8475b)) +* **client:** allow passing `NotGiven` for body ([#600](https://github.com/Finch-API/finch-api-python/issues/600)) ([29b8a08](https://github.com/Finch-API/finch-api-python/commit/29b8a08066e6f35ebde9625debb18ed91733618c)) + + +### Bug Fixes + +* **client:** mark some request bodies as optional ([29b8a08](https://github.com/Finch-API/finch-api-python/commit/29b8a08066e6f35ebde9625debb18ed91733618c)) + + +### Chores + +* **internal:** codegen related update ([#598](https://github.com/Finch-API/finch-api-python/issues/598)) ([065fc91](https://github.com/Finch-API/finch-api-python/commit/065fc914bcbb3848fbdf62083d289e168f782acd)) +* **internal:** fix devcontainers setup ([#601](https://github.com/Finch-API/finch-api-python/issues/601)) ([c1c9f5a](https://github.com/Finch-API/finch-api-python/commit/c1c9f5a17fb7094d0f4c198473b7788089e08750)) +* **internal:** properly set __pydantic_private__ ([#603](https://github.com/Finch-API/finch-api-python/issues/603)) ([0119042](https://github.com/Finch-API/finch-api-python/commit/0119042284b4d0fbf4205f41eb8e08cece7889b6)) + ## 1.14.2 (2025-02-11) Full Changelog: [v1.14.1...v1.14.2](https://github.com/Finch-API/finch-api-python/compare/v1.14.1...v1.14.2) diff --git a/pyproject.toml b/pyproject.toml index 7e931aeb..12abc6e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "finch-api" -version = "1.14.2" +version = "1.15.0" description = "The official Python library for the Finch API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index d9300541..992b035c 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -63,7 +63,7 @@ ModelBuilderProtocol, ) from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping -from ._compat import model_copy, model_dump +from ._compat import PYDANTIC_V2, model_copy, model_dump from ._models import GenericModel, FinalRequestOptions, validate_type, construct_type from ._response import ( APIResponse, @@ -208,6 +208,9 @@ def _set_private_attributes( model: Type[_T], options: FinalRequestOptions, ) -> None: + if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None: + self.__pydantic_private__ = {} + self._model = model self._client = client self._options = options @@ -293,6 +296,9 @@ def _set_private_attributes( client: AsyncAPIClient, options: FinalRequestOptions, ) -> None: + if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None: + self.__pydantic_private__ = {} + self._model = model self._client = client self._options = options @@ -519,7 +525,7 @@ def _build_request( # so that passing a `TypedDict` doesn't cause an error. # https://github.com/microsoft/pyright/issues/3526#event-6715453066 params=self.qs.stringify(cast(Mapping[str, Any], params)) if params else None, - json=json_data, + json=json_data if is_given(json_data) else None, files=files, **kwargs, ) diff --git a/src/finch/_utils/_sync.py b/src/finch/_utils/_sync.py index 8b3aaf2b..ad7ec71b 100644 --- a/src/finch/_utils/_sync.py +++ b/src/finch/_utils/_sync.py @@ -7,16 +7,20 @@ from typing import Any, TypeVar, Callable, Awaitable from typing_extensions import ParamSpec +import anyio +import sniffio +import anyio.to_thread + T_Retval = TypeVar("T_Retval") T_ParamSpec = ParamSpec("T_ParamSpec") if sys.version_info >= (3, 9): - to_thread = asyncio.to_thread + _asyncio_to_thread = asyncio.to_thread else: # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread # for Python 3.8 support - async def to_thread( + async def _asyncio_to_thread( func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs ) -> Any: """Asynchronously run function *func* in a separate thread. @@ -34,6 +38,17 @@ async def to_thread( return await loop.run_in_executor(None, func_call) +async def to_thread( + func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs +) -> T_Retval: + if sniffio.current_async_library() == "asyncio": + return await _asyncio_to_thread(func, *args, **kwargs) + + return await anyio.to_thread.run_sync( + functools.partial(func, *args, **kwargs), + ) + + # inspired by `asyncer`, https://github.com/tiangolo/asyncer def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]: """ diff --git a/src/finch/_version.py b/src/finch/_version.py index 4b2efd49..6f0b3869 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.14.2" # x-release-please-version +__version__ = "1.15.0" # x-release-please-version diff --git a/src/finch/resources/hris/benefits/individuals.py b/src/finch/resources/hris/benefits/individuals.py index 19ab83a7..c6e472cf 100644 --- a/src/finch/resources/hris/benefits/individuals.py +++ b/src/finch/resources/hris/benefits/individuals.py @@ -51,7 +51,7 @@ def enroll_many( self, benefit_id: str, *, - individuals: Iterable[individual_enroll_many_params.Individual], + individuals: Iterable[individual_enroll_many_params.Individual] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -234,7 +234,7 @@ def enroll_many( self, benefit_id: str, *, - individuals: Iterable[individual_enroll_many_params.Individual], + individuals: Iterable[individual_enroll_many_params.Individual] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, diff --git a/src/finch/resources/sandbox/directory.py b/src/finch/resources/sandbox/directory.py index 6d2d4cb1..0cb518ab 100644 --- a/src/finch/resources/sandbox/directory.py +++ b/src/finch/resources/sandbox/directory.py @@ -45,7 +45,7 @@ def with_streaming_response(self) -> DirectoryWithStreamingResponse: def create( self, *, - body: Iterable[directory_create_params.Body], + body: Iterable[directory_create_params.Body] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -101,7 +101,7 @@ def with_streaming_response(self) -> AsyncDirectoryWithStreamingResponse: async def create( self, *, - body: Iterable[directory_create_params.Body], + body: Iterable[directory_create_params.Body] | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, diff --git a/src/finch/types/hris/benefits/individual_enroll_many_params.py b/src/finch/types/hris/benefits/individual_enroll_many_params.py index 95164f87..b5358caf 100644 --- a/src/finch/types/hris/benefits/individual_enroll_many_params.py +++ b/src/finch/types/hris/benefits/individual_enroll_many_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Iterable, Optional -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, TypedDict __all__ = [ "IndividualEnrollManyParams", @@ -15,7 +15,7 @@ class IndividualEnrollManyParams(TypedDict, total=False): - individuals: Required[Iterable[Individual]] + individuals: Iterable[Individual] """Array of the individual_id to enroll and a configuration object.""" diff --git a/src/finch/types/hris/pay_statement.py b/src/finch/types/hris/pay_statement.py index dc3b1aba..8921c03b 100644 --- a/src/finch/types/hris/pay_statement.py +++ b/src/finch/types/hris/pay_statement.py @@ -1,19 +1,40 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Dict, List, Optional from typing_extensions import Literal from ..money import Money from ..._models import BaseModel from .benefit_type import BenefitType -__all__ = ["PayStatement", "Earning", "EmployeeDeduction", "EmployerContribution", "Tax"] +__all__ = [ + "PayStatement", + "Earning", + "EarningAttributes", + "EmployeeDeduction", + "EmployeeDeductionAttributes", + "EmployerContribution", + "EmployerContributionAttributes", + "Tax", + "TaxAttributes", +] + + +class EarningAttributes(BaseModel): + metadata: Optional[Dict[str, 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, + boolean, object, array, etc.). + """ class Earning(BaseModel): amount: Optional[int] = None """The earnings amount in cents.""" + attributes: Optional[EarningAttributes] = None + currency: Optional[str] = None """The earnings currency code.""" @@ -47,10 +68,21 @@ class Earning(BaseModel): """The type of earning.""" +class EmployeeDeductionAttributes(BaseModel): + metadata: Optional[Dict[str, 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, + boolean, object, array, etc.). + """ + + class EmployeeDeduction(BaseModel): amount: Optional[int] = None """The deduction amount in cents.""" + attributes: Optional[EmployeeDeductionAttributes] = None + currency: Optional[str] = None """The deduction currency.""" @@ -64,10 +96,21 @@ class EmployeeDeduction(BaseModel): """Type of benefit.""" +class EmployerContributionAttributes(BaseModel): + metadata: Optional[Dict[str, 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, + boolean, object, array, etc.). + """ + + class EmployerContribution(BaseModel): amount: Optional[int] = None """The contribution amount in cents.""" + attributes: Optional[EmployerContributionAttributes] = None + currency: Optional[str] = None """The contribution currency.""" @@ -78,10 +121,21 @@ class EmployerContribution(BaseModel): """Type of benefit.""" +class TaxAttributes(BaseModel): + metadata: Optional[Dict[str, 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, + boolean, object, array, etc.). + """ + + class Tax(BaseModel): amount: Optional[int] = None """The tax amount in cents.""" + attributes: Optional[TaxAttributes] = None + currency: Optional[str] = None """The currency code.""" diff --git a/src/finch/types/sandbox/directory_create_params.py b/src/finch/types/sandbox/directory_create_params.py index 1684d178..939c3170 100644 --- a/src/finch/types/sandbox/directory_create_params.py +++ b/src/finch/types/sandbox/directory_create_params.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Iterable, Optional -from typing_extensions import Literal, Required, TypedDict +from typing_extensions import Literal, TypedDict from ..income_param import IncomeParam from ..location_param import LocationParam @@ -21,7 +21,7 @@ class DirectoryCreateParams(TypedDict, total=False): - body: Required[Iterable[Body]] + body: Iterable[Body] """Array of individuals to create. Takes all combined fields from `/individual` and `/employment` endpoints. All diff --git a/src/finch/types/sandbox/payment_create_params.py b/src/finch/types/sandbox/payment_create_params.py index 202ab8c9..d1691443 100644 --- a/src/finch/types/sandbox/payment_create_params.py +++ b/src/finch/types/sandbox/payment_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Iterable, Optional +from typing import Dict, Iterable, Optional from typing_extensions import Literal, TypedDict from ..money_param import MoneyParam @@ -12,9 +12,13 @@ "PaymentCreateParams", "PayStatement", "PayStatementEarning", + "PayStatementEarningAttributes", "PayStatementEmployeeDeduction", + "PayStatementEmployeeDeductionAttributes", "PayStatementEmployerContribution", + "PayStatementEmployerContributionAttributes", "PayStatementTax", + "PayStatementTaxAttributes", ] @@ -26,10 +30,21 @@ class PaymentCreateParams(TypedDict, total=False): start_date: str +class PayStatementEarningAttributes(TypedDict, total=False): + metadata: Dict[str, 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, + boolean, object, array, etc.). + """ + + class PayStatementEarning(TypedDict, total=False): amount: Optional[int] """The earnings amount in cents.""" + attributes: Optional[PayStatementEarningAttributes] + currency: Optional[str] """The earnings currency code.""" @@ -63,10 +78,21 @@ class PayStatementEarning(TypedDict, total=False): """The type of earning.""" +class PayStatementEmployeeDeductionAttributes(TypedDict, total=False): + metadata: Dict[str, 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, + boolean, object, array, etc.). + """ + + class PayStatementEmployeeDeduction(TypedDict, total=False): amount: Optional[int] """The deduction amount in cents.""" + attributes: Optional[PayStatementEmployeeDeductionAttributes] + currency: Optional[str] """The deduction currency.""" @@ -80,10 +106,21 @@ class PayStatementEmployeeDeduction(TypedDict, total=False): """Type of benefit.""" +class PayStatementEmployerContributionAttributes(TypedDict, total=False): + metadata: Dict[str, 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, + boolean, object, array, etc.). + """ + + class PayStatementEmployerContribution(TypedDict, total=False): amount: Optional[int] """The contribution amount in cents.""" + attributes: Optional[PayStatementEmployerContributionAttributes] + currency: Optional[str] """The contribution currency.""" @@ -94,10 +131,21 @@ class PayStatementEmployerContribution(TypedDict, total=False): """Type of benefit.""" +class PayStatementTaxAttributes(TypedDict, total=False): + metadata: Dict[str, 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, + boolean, object, array, etc.). + """ + + class PayStatementTax(TypedDict, total=False): amount: Optional[int] """The tax amount in cents.""" + attributes: Optional[PayStatementTaxAttributes] + currency: Optional[str] """The currency code.""" diff --git a/tests/api_resources/hris/benefits/test_individuals.py b/tests/api_resources/hris/benefits/test_individuals.py index 29438100..6fe22b42 100644 --- a/tests/api_resources/hris/benefits/test_individuals.py +++ b/tests/api_resources/hris/benefits/test_individuals.py @@ -27,7 +27,31 @@ class TestIndividuals: def test_method_enroll_many(self, client: Finch) -> None: individual = client.hris.benefits.individuals.enroll_many( benefit_id="benefit_id", - individuals=[{}], + ) + assert_matches_type(SyncSinglePage[EnrolledIndividual], individual, path=["response"]) + + @parametrize + def test_method_enroll_many_with_all_params(self, client: Finch) -> None: + individual = client.hris.benefits.individuals.enroll_many( + benefit_id="benefit_id", + individuals=[ + { + "configuration": { + "annual_contribution_limit": "individual", + "annual_maximum": 500000, + "catch_up": False, + "company_contribution": { + "amount": 400, + "type": "fixed", + }, + "employee_deduction": { + "amount": 1000, + "type": "fixed", + }, + }, + "individual_id": "d02a6346-1f08-4312-a064-49ff3cafaa7a", + } + ], ) assert_matches_type(SyncSinglePage[EnrolledIndividual], individual, path=["response"]) @@ -35,7 +59,6 @@ def test_method_enroll_many(self, client: Finch) -> None: def test_raw_response_enroll_many(self, client: Finch) -> None: response = client.hris.benefits.individuals.with_raw_response.enroll_many( benefit_id="benefit_id", - individuals=[{}], ) assert response.is_closed is True @@ -47,7 +70,6 @@ def test_raw_response_enroll_many(self, client: Finch) -> None: def test_streaming_response_enroll_many(self, client: Finch) -> None: with client.hris.benefits.individuals.with_streaming_response.enroll_many( benefit_id="benefit_id", - individuals=[{}], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -62,7 +84,6 @@ def test_path_params_enroll_many(self, client: Finch) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `benefit_id` but received ''"): client.hris.benefits.individuals.with_raw_response.enroll_many( benefit_id="", - individuals=[{}], ) @parametrize @@ -203,7 +224,31 @@ class TestAsyncIndividuals: async def test_method_enroll_many(self, async_client: AsyncFinch) -> None: individual = await async_client.hris.benefits.individuals.enroll_many( benefit_id="benefit_id", - individuals=[{}], + ) + assert_matches_type(AsyncSinglePage[EnrolledIndividual], individual, path=["response"]) + + @parametrize + async def test_method_enroll_many_with_all_params(self, async_client: AsyncFinch) -> None: + individual = await async_client.hris.benefits.individuals.enroll_many( + benefit_id="benefit_id", + individuals=[ + { + "configuration": { + "annual_contribution_limit": "individual", + "annual_maximum": 500000, + "catch_up": False, + "company_contribution": { + "amount": 400, + "type": "fixed", + }, + "employee_deduction": { + "amount": 1000, + "type": "fixed", + }, + }, + "individual_id": "d02a6346-1f08-4312-a064-49ff3cafaa7a", + } + ], ) assert_matches_type(AsyncSinglePage[EnrolledIndividual], individual, path=["response"]) @@ -211,7 +256,6 @@ async def test_method_enroll_many(self, async_client: AsyncFinch) -> None: async def test_raw_response_enroll_many(self, async_client: AsyncFinch) -> None: response = await async_client.hris.benefits.individuals.with_raw_response.enroll_many( benefit_id="benefit_id", - individuals=[{}], ) assert response.is_closed is True @@ -223,7 +267,6 @@ async def test_raw_response_enroll_many(self, async_client: AsyncFinch) -> None: async def test_streaming_response_enroll_many(self, async_client: AsyncFinch) -> None: async with async_client.hris.benefits.individuals.with_streaming_response.enroll_many( benefit_id="benefit_id", - individuals=[{}], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -238,7 +281,6 @@ async def test_path_params_enroll_many(self, async_client: AsyncFinch) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `benefit_id` but received ''"): await async_client.hris.benefits.individuals.with_raw_response.enroll_many( benefit_id="", - individuals=[{}], ) @parametrize diff --git a/tests/api_resources/sandbox/test_directory.py b/tests/api_resources/sandbox/test_directory.py index a42d4fcb..104e1a24 100644 --- a/tests/api_resources/sandbox/test_directory.py +++ b/tests/api_resources/sandbox/test_directory.py @@ -19,16 +19,97 @@ class TestDirectory: @parametrize def test_method_create(self, client: Finch) -> None: + directory = client.sandbox.directory.create() + assert_matches_type(DirectoryCreateResponse, directory, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: Finch) -> None: directory = client.sandbox.directory.create( - body=[{}], + body=[ + { + "class_code": "class_code", + "custom_fields": [ + { + "name": "name", + "value": {}, + } + ], + "department": {"name": "name"}, + "dob": "dob", + "emails": [ + { + "data": "data", + "type": "work", + } + ], + "employment": { + "subtype": "full_time", + "type": "employee", + }, + "employment_status": "active", + "encrypted_ssn": "encrypted_ssn", + "end_date": "end_date", + "ethnicity": "asian", + "first_name": "first_name", + "gender": "female", + "income": { + "amount": 0, + "currency": "currency", + "effective_date": "effective_date", + "unit": "yearly", + }, + "income_history": [ + { + "amount": 0, + "currency": "currency", + "effective_date": "effective_date", + "unit": "yearly", + } + ], + "is_active": True, + "last_name": "last_name", + "latest_rehire_date": "latest_rehire_date", + "location": { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "postal_code": "postal_code", + "source_id": "source_id", + "state": "state", + }, + "manager": {"id": "id"}, + "middle_name": "middle_name", + "phone_numbers": [ + { + "data": "data", + "type": "work", + } + ], + "preferred_name": "preferred_name", + "residence": { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "postal_code": "postal_code", + "source_id": "source_id", + "state": "state", + }, + "source_id": "source_id", + "ssn": "ssn", + "start_date": "start_date", + "title": "title", + } + ], ) assert_matches_type(DirectoryCreateResponse, directory, path=["response"]) @parametrize def test_raw_response_create(self, client: Finch) -> None: - response = client.sandbox.directory.with_raw_response.create( - body=[{}], - ) + response = client.sandbox.directory.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -37,9 +118,7 @@ def test_raw_response_create(self, client: Finch) -> None: @parametrize def test_streaming_response_create(self, client: Finch) -> None: - with client.sandbox.directory.with_streaming_response.create( - body=[{}], - ) as response: + with client.sandbox.directory.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -54,16 +133,97 @@ class TestAsyncDirectory: @parametrize async def test_method_create(self, async_client: AsyncFinch) -> None: + directory = await async_client.sandbox.directory.create() + assert_matches_type(DirectoryCreateResponse, directory, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> None: directory = await async_client.sandbox.directory.create( - body=[{}], + body=[ + { + "class_code": "class_code", + "custom_fields": [ + { + "name": "name", + "value": {}, + } + ], + "department": {"name": "name"}, + "dob": "dob", + "emails": [ + { + "data": "data", + "type": "work", + } + ], + "employment": { + "subtype": "full_time", + "type": "employee", + }, + "employment_status": "active", + "encrypted_ssn": "encrypted_ssn", + "end_date": "end_date", + "ethnicity": "asian", + "first_name": "first_name", + "gender": "female", + "income": { + "amount": 0, + "currency": "currency", + "effective_date": "effective_date", + "unit": "yearly", + }, + "income_history": [ + { + "amount": 0, + "currency": "currency", + "effective_date": "effective_date", + "unit": "yearly", + } + ], + "is_active": True, + "last_name": "last_name", + "latest_rehire_date": "latest_rehire_date", + "location": { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "postal_code": "postal_code", + "source_id": "source_id", + "state": "state", + }, + "manager": {"id": "id"}, + "middle_name": "middle_name", + "phone_numbers": [ + { + "data": "data", + "type": "work", + } + ], + "preferred_name": "preferred_name", + "residence": { + "city": "city", + "country": "country", + "line1": "line1", + "line2": "line2", + "name": "name", + "postal_code": "postal_code", + "source_id": "source_id", + "state": "state", + }, + "source_id": "source_id", + "ssn": "ssn", + "start_date": "start_date", + "title": "title", + } + ], ) assert_matches_type(DirectoryCreateResponse, directory, path=["response"]) @parametrize async def test_raw_response_create(self, async_client: AsyncFinch) -> None: - response = await async_client.sandbox.directory.with_raw_response.create( - body=[{}], - ) + response = await async_client.sandbox.directory.with_raw_response.create() assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -72,9 +232,7 @@ async def test_raw_response_create(self, async_client: AsyncFinch) -> None: @parametrize async def test_streaming_response_create(self, async_client: AsyncFinch) -> None: - async with async_client.sandbox.directory.with_streaming_response.create( - body=[{}], - ) as response: + async with async_client.sandbox.directory.with_streaming_response.create() as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" diff --git a/tests/api_resources/sandbox/test_employment.py b/tests/api_resources/sandbox/test_employment.py index 677cbc8e..368ae958 100644 --- a/tests/api_resources/sandbox/test_employment.py +++ b/tests/api_resources/sandbox/test_employment.py @@ -73,7 +73,7 @@ def test_method_update_with_all_params(self, client: Finch) -> None: manager={"id": "id"}, middle_name="middle_name", source_id="source_id", - start_date="3/4/2020", + start_date="start_date", title="title", ) assert_matches_type(EmploymentUpdateResponse, employment, path=["response"]) @@ -169,7 +169,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncFinch) -> manager={"id": "id"}, middle_name="middle_name", source_id="source_id", - start_date="3/4/2020", + start_date="start_date", title="title", ) assert_matches_type(EmploymentUpdateResponse, employment, path=["response"]) diff --git a/tests/api_resources/sandbox/test_individual.py b/tests/api_resources/sandbox/test_individual.py index 1f2e1ca3..23239fc2 100644 --- a/tests/api_resources/sandbox/test_individual.py +++ b/tests/api_resources/sandbox/test_individual.py @@ -28,7 +28,7 @@ def test_method_update(self, client: Finch) -> None: def test_method_update_with_all_params(self, client: Finch) -> None: individual = client.sandbox.individual.update( individual_id="individual_id", - dob="12/20/1989", + dob="dob", emails=[ { "data": "data", @@ -108,7 +108,7 @@ async def test_method_update(self, async_client: AsyncFinch) -> None: async def test_method_update_with_all_params(self, async_client: AsyncFinch) -> None: individual = await async_client.sandbox.individual.update( individual_id="individual_id", - dob="12/20/1989", + dob="dob", emails=[ { "data": "data", diff --git a/tests/api_resources/sandbox/test_payment.py b/tests/api_resources/sandbox/test_payment.py index 60fea177..0330db40 100644 --- a/tests/api_resources/sandbox/test_payment.py +++ b/tests/api_resources/sandbox/test_payment.py @@ -31,6 +31,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "earnings": [ { "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, "currency": "currency", "hours": 0, "name": "name", @@ -39,9 +40,10 @@ def test_method_create_with_all_params(self, client: Finch) -> None: ], "employee_deductions": [ { - "amount": 2000, - "currency": "usd", - "name": "401k test", + "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, + "currency": "currency", + "name": "name", "pre_tax": True, "type": "401k", } @@ -49,6 +51,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "employer_contributions": [ { "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, "currency": "currency", "name": "name", "type": "401k", @@ -58,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", @@ -67,6 +70,7 @@ def test_method_create_with_all_params(self, client: Finch) -> None: "taxes": [ { "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, "currency": "currency", "employer": True, "name": "name", @@ -119,6 +123,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "earnings": [ { "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, "currency": "currency", "hours": 0, "name": "name", @@ -127,9 +132,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> ], "employee_deductions": [ { - "amount": 2000, - "currency": "usd", - "name": "401k test", + "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, + "currency": "currency", + "name": "name", "pre_tax": True, "type": "401k", } @@ -137,6 +143,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "employer_contributions": [ { "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, "currency": "currency", "name": "name", "type": "401k", @@ -146,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", @@ -155,6 +162,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> "taxes": [ { "amount": 0, + "attributes": {"metadata": {"foo": "bar"}}, "currency": "currency", "employer": True, "name": "name",