diff --git a/.release-please-manifest.json b/.release-please-manifest.json index fbd9082d..7deae338 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.5.0" + ".": "1.6.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index ccdf8c03..416903c1 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 37 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-73f8c2f1adc83beed2a8b1dd5d1981b61f94b8d22a7be3778b42084a810ab0e7.yml +configured_endpoints: 39 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-ea62ee98f625bf64ae053b9d966dfd8a62d7dca686f86e3825b117c53e10ad16.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 96322c24..0096da83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,38 @@ # Changelog +## 1.6.0 (2024-09-25) + +Full Changelog: [v1.5.0...v1.6.0](https://github.com/Finch-API/finch-api-python/compare/v1.5.0...v1.6.0) + +### Features + +* **api:** manual updates ([#503](https://github.com/Finch-API/finch-api-python/issues/503)) ([0fd72d8](https://github.com/Finch-API/finch-api-python/commit/0fd72d872880e93a0f925b5d96166cbba09978d5)) +* **api:** manual updates ([#505](https://github.com/Finch-API/finch-api-python/issues/505)) ([5d63f1f](https://github.com/Finch-API/finch-api-python/commit/5d63f1fce9e852260bdbc946fd623ec524bb6dc0)) +* **api:** OpenAPI spec update via Stainless API ([#498](https://github.com/Finch-API/finch-api-python/issues/498)) ([1e0e4a1](https://github.com/Finch-API/finch-api-python/commit/1e0e4a19217910c2e91325b5e25fe7c1d3d53be6)) +* **client:** send retry count header ([#500](https://github.com/Finch-API/finch-api-python/issues/500)) ([a6a35ea](https://github.com/Finch-API/finch-api-python/commit/a6a35eafaef92bfb88834c4d51fe66f6c604c5f5)) + + +### Bug Fixes + +* **client:** handle domains with underscores ([#499](https://github.com/Finch-API/finch-api-python/issues/499)) ([9b3fa1e](https://github.com/Finch-API/finch-api-python/commit/9b3fa1ec8f269762dea5026c202430a8b4a3078a)) +* **internal:** update custom code related tests ([b7287e4](https://github.com/Finch-API/finch-api-python/commit/b7287e4843f047248326020ec187b6bb2a5f0334)) + + +### Chores + +* **internal:** bump pyright / mypy version ([#497](https://github.com/Finch-API/finch-api-python/issues/497)) ([85749d1](https://github.com/Finch-API/finch-api-python/commit/85749d1c2ddf4ea4984b32ea3723a79ad7cc6e99)) +* **internal:** bump ruff ([#496](https://github.com/Finch-API/finch-api-python/issues/496)) ([f1a7d3f](https://github.com/Finch-API/finch-api-python/commit/f1a7d3f788e0202c2094b5e60b089237a765ce5d)) +* **internal:** codegen related update ([#493](https://github.com/Finch-API/finch-api-python/issues/493)) ([590d384](https://github.com/Finch-API/finch-api-python/commit/590d38471e5703f6c17385971a9d9cb7e3d6a857)) +* **internal:** codegen related update ([#501](https://github.com/Finch-API/finch-api-python/issues/501)) ([ea96424](https://github.com/Finch-API/finch-api-python/commit/ea96424a4169593a26176f02a2440d27719e911e)) +* **internal:** codegen related update ([#506](https://github.com/Finch-API/finch-api-python/issues/506)) ([5aff0ca](https://github.com/Finch-API/finch-api-python/commit/5aff0ca1c62ccf162ffcd2e9fe3927eb06622d23)) +* **internal:** skip failing tests ([#502](https://github.com/Finch-API/finch-api-python/issues/502)) ([8d25365](https://github.com/Finch-API/finch-api-python/commit/8d253655360633edda36df8551b41355b6d68773)) +* **internal:** update pydantic v1 compat helpers ([#504](https://github.com/Finch-API/finch-api-python/issues/504)) ([17ba83b](https://github.com/Finch-API/finch-api-python/commit/17ba83b68ce8d0c20239f0388b6f1f9e42ce42f2)) + + +### Documentation + +* update CONTRIBUTING.md ([#495](https://github.com/Finch-API/finch-api-python/issues/495)) ([40d4f67](https://github.com/Finch-API/finch-api-python/commit/40d4f670d89118e1fd7df411ea2b8ecef135988e)) + ## 1.5.0 (2024-09-03) Full Changelog: [v1.4.0...v1.5.0](https://github.com/Finch-API/finch-api-python/compare/v1.4.0...v1.5.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ad92802c..91fc889e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,13 +31,13 @@ $ pip install -r requirements-dev.lock ## Modifying/Adding code -Most of the SDK is generated code, and any modified code will be overridden on the next generation. The -`src/finch/lib/` and `examples/` directories are exceptions and will never be overridden. +Most of the SDK is generated code. Modifications to code will be persisted between generations, but may +result in merge conflicts between manual patches and changes from the generator. The generator will never +modify the contents of the `src/finch/lib/` and `examples/` directories. ## Adding and running examples -All files in the `examples/` directory are not modified by the Stainless generator and can be freely edited or -added to. +All files in the `examples/` directory are not modified by the generator and can be freely edited or added to. ```bash # add an example to examples/.py diff --git a/README.md b/README.md index 697185f7..0f6ca09f 100644 --- a/README.md +++ b/README.md @@ -416,6 +416,17 @@ We take backwards-compatibility seriously and work hard to ensure you can rely o We are keen for your feedback; please open an [issue](https://www.github.com/Finch-API/finch-api-python/issues) with questions, bugs, or suggestions. +### Determining the installed version + +If you've upgraded to the latest version but aren't seeing any new features you were expecting then your python environment is likely still using an older version. + +You can determine the version that is being used at runtime with: + +```py +import finch +print(finch.__version__) +``` + ## Requirements Python 3.7 or higher. diff --git a/api.md b/api.md index 014e49c7..4d4c1c06 100644 --- a/api.md +++ b/api.md @@ -366,3 +366,18 @@ Methods: - client.payroll.pay_groups.retrieve(pay_group_id) -> PayGroupRetrieveResponse - client.payroll.pay_groups.list(\*\*params) -> SyncSinglePage[PayGroupListResponse] + +# Connect + +## Sessions + +Types: + +```python +from finch.types.connect import SessionNewResponse, SessionReauthenticateResponse +``` + +Methods: + +- client.connect.sessions.new(\*\*params) -> SessionNewResponse +- client.connect.sessions.reauthenticate(\*\*params) -> SessionReauthenticateResponse diff --git a/pyproject.toml b/pyproject.toml index ab02cb07..983834bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "finch-api" -version = "1.5.0" +version = "1.6.0" description = "The official Python library for the Finch API" dynamic = ["readme"] license = "Apache-2.0" @@ -15,7 +15,6 @@ dependencies = [ "distro>=1.7.0, <2", "sniffio", "cached-property; python_version < '3.8'", - ] requires-python = ">= 3.7" classifiers = [ @@ -36,8 +35,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License" ] - - [project.urls] Homepage = "https://github.com/Finch-API/finch-api-python" Repository = "https://github.com/Finch-API/finch-api-python" @@ -59,7 +56,6 @@ dev-dependencies = [ "dirty-equals>=0.6.0", "importlib-metadata>=6.7.0", "rich>=13.7.1", - ] [tool.rye.scripts] diff --git a/requirements-dev.lock b/requirements-dev.lock index fefea7e3..53209e90 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -49,7 +49,7 @@ markdown-it-py==3.0.0 # via rich mdurl==0.1.2 # via markdown-it-py -mypy==1.10.1 +mypy==1.11.2 mypy-extensions==1.0.0 # via mypy nodeenv==1.8.0 @@ -70,7 +70,7 @@ pydantic-core==2.18.2 # via pydantic pygments==2.18.0 # via rich -pyright==1.1.374 +pyright==1.1.380 pytest==7.1.1 # via pytest-asyncio pytest-asyncio==0.21.1 @@ -80,7 +80,7 @@ pytz==2023.3.post1 # via dirty-equals respx==0.20.2 rich==13.7.1 -ruff==0.5.6 +ruff==0.6.5 setuptools==68.2.2 # via nodeenv six==1.16.0 diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index 1316a641..5df3d614 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -401,14 +401,7 @@ def _make_status_error( ) -> _exceptions.APIStatusError: raise NotImplementedError() - def _remaining_retries( - self, - remaining_retries: Optional[int], - options: FinalRequestOptions, - ) -> int: - return remaining_retries if remaining_retries is not None else options.get_max_retries(self.max_retries) - - def _build_headers(self, options: FinalRequestOptions) -> httpx.Headers: + def _build_headers(self, options: FinalRequestOptions, *, retries_taken: int = 0) -> httpx.Headers: custom_headers = options.headers or {} headers_dict = _merge_mappings(self.default_headers, custom_headers) self._validate_headers(headers_dict, custom_headers) @@ -420,6 +413,11 @@ def _build_headers(self, options: FinalRequestOptions) -> httpx.Headers: if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers: headers[idempotency_header] = options.idempotency_key or self._idempotency_key() + # Don't set the retry count header if it was already set or removed by the caller. We check + # `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case. + if "x-stainless-retry-count" not in (header.lower() for header in custom_headers): + headers["x-stainless-retry-count"] = str(retries_taken) + return headers def _prepare_url(self, url: str) -> URL: @@ -441,6 +439,8 @@ def _make_sse_decoder(self) -> SSEDecoder | SSEBytesDecoder: def _build_request( self, options: FinalRequestOptions, + *, + retries_taken: int = 0, ) -> httpx.Request: if log.isEnabledFor(logging.DEBUG): log.debug("Request options: %s", model_dump(options, exclude_unset=True)) @@ -456,7 +456,7 @@ def _build_request( else: raise RuntimeError(f"Unexpected JSON data type, {type(json_data)}, cannot merge with `extra_body`") - headers = self._build_headers(options) + headers = self._build_headers(options, retries_taken=retries_taken) params = _merge_mappings(self.default_query, options.params) content_type = headers.get("Content-Type") files = options.files @@ -490,12 +490,17 @@ def _build_request( if not files: files = cast(HttpxRequestFiles, ForceMultipartDict()) + prepared_url = self._prepare_url(options.url) + if "_" in prepared_url.host: + # work around https://github.com/encode/httpx/discussions/2880 + kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} + # TODO: report this error to httpx return self._client.build_request( # pyright: ignore[reportUnknownMemberType] headers=headers, timeout=self.timeout if isinstance(options.timeout, NotGiven) else options.timeout, method=options.method, - url=self._prepare_url(options.url), + url=prepared_url, # the `Query` type that we use is incompatible with qs' # `Params` type as it needs to be typed as `Mapping[str, object]` # so that passing a `TypedDict` doesn't cause an error. @@ -934,12 +939,17 @@ def request( 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, - remaining_retries=remaining_retries, + retries_taken=retries_taken, ) def _request( @@ -947,7 +957,7 @@ def _request( *, cast_to: Type[ResponseT], options: FinalRequestOptions, - remaining_retries: int | None, + retries_taken: int, stream: bool, stream_cls: type[_StreamT] | None, ) -> ResponseT | _StreamT: @@ -959,8 +969,8 @@ def _request( cast_to = self._maybe_override_cast_to(cast_to, options) options = self._prepare_options(options) - retries = self._remaining_retries(remaining_retries, options) - request = self._build_request(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) kwargs: HttpxSendArgs = {} @@ -978,11 +988,11 @@ def _request( except httpx.TimeoutException as err: log.debug("Encountered httpx.TimeoutException", exc_info=True) - if retries > 0: + if remaining_retries > 0: return self._retry_request( input_options, cast_to, - retries, + retries_taken=retries_taken, stream=stream, stream_cls=stream_cls, response_headers=None, @@ -993,11 +1003,11 @@ def _request( except Exception as err: log.debug("Encountered Exception", exc_info=True) - if retries > 0: + if remaining_retries > 0: return self._retry_request( input_options, cast_to, - retries, + retries_taken=retries_taken, stream=stream, stream_cls=stream_cls, response_headers=None, @@ -1020,13 +1030,13 @@ def _request( except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code log.debug("Encountered httpx.HTTPStatusError", exc_info=True) - if retries > 0 and self._should_retry(err.response): + if remaining_retries > 0 and self._should_retry(err.response): err.response.close() return self._retry_request( input_options, cast_to, - retries, - err.response.headers, + retries_taken=retries_taken, + response_headers=err.response.headers, stream=stream, stream_cls=stream_cls, ) @@ -1045,26 +1055,26 @@ def _request( response=response, stream=stream, stream_cls=stream_cls, - retries_taken=options.get_max_retries(self.max_retries) - retries, + retries_taken=retries_taken, ) def _retry_request( self, options: FinalRequestOptions, cast_to: Type[ResponseT], - remaining_retries: int, - response_headers: httpx.Headers | None, *, + retries_taken: int, + response_headers: httpx.Headers | None, stream: bool, stream_cls: type[_StreamT] | None, ) -> ResponseT | _StreamT: - remaining = remaining_retries - 1 - if remaining == 1: + remaining_retries = options.get_max_retries(self.max_retries) - retries_taken + if remaining_retries == 1: log.debug("1 retry left") else: - log.debug("%i retries left", remaining) + log.debug("%i retries left", remaining_retries) - timeout = self._calculate_retry_timeout(remaining, options, response_headers) + timeout = self._calculate_retry_timeout(remaining_retries, options, response_headers) 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 @@ -1074,7 +1084,7 @@ def _retry_request( return self._request( options=options, cast_to=cast_to, - remaining_retries=remaining, + retries_taken=retries_taken + 1, stream=stream, stream_cls=stream_cls, ) @@ -1506,12 +1516,17 @@ async def request( 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, - remaining_retries=remaining_retries, + retries_taken=retries_taken, ) async def _request( @@ -1521,7 +1536,7 @@ async def _request( *, stream: bool, stream_cls: type[_AsyncStreamT] | None, - remaining_retries: int | None, + retries_taken: int, ) -> ResponseT | _AsyncStreamT: if self._platform is None: # `get_platform` can make blocking IO calls so we @@ -1536,8 +1551,8 @@ async def _request( cast_to = self._maybe_override_cast_to(cast_to, options) options = await self._prepare_options(options) - retries = self._remaining_retries(remaining_retries, options) - request = self._build_request(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) kwargs: HttpxSendArgs = {} @@ -1553,11 +1568,11 @@ async def _request( except httpx.TimeoutException as err: log.debug("Encountered httpx.TimeoutException", exc_info=True) - if retries > 0: + if remaining_retries > 0: return await self._retry_request( input_options, cast_to, - retries, + retries_taken=retries_taken, stream=stream, stream_cls=stream_cls, response_headers=None, @@ -1568,11 +1583,11 @@ async def _request( except Exception as err: log.debug("Encountered Exception", exc_info=True) - if retries > 0: + if retries_taken > 0: return await self._retry_request( input_options, cast_to, - retries, + retries_taken=retries_taken, stream=stream, stream_cls=stream_cls, response_headers=None, @@ -1590,13 +1605,13 @@ async def _request( except httpx.HTTPStatusError as err: # thrown on 4xx and 5xx status code log.debug("Encountered httpx.HTTPStatusError", exc_info=True) - if retries > 0 and self._should_retry(err.response): + if remaining_retries > 0 and self._should_retry(err.response): await err.response.aclose() return await self._retry_request( input_options, cast_to, - retries, - err.response.headers, + retries_taken=retries_taken, + response_headers=err.response.headers, stream=stream, stream_cls=stream_cls, ) @@ -1615,26 +1630,26 @@ async def _request( response=response, stream=stream, stream_cls=stream_cls, - retries_taken=options.get_max_retries(self.max_retries) - retries, + retries_taken=retries_taken, ) async def _retry_request( self, options: FinalRequestOptions, cast_to: Type[ResponseT], - remaining_retries: int, - response_headers: httpx.Headers | None, *, + retries_taken: int, + response_headers: httpx.Headers | None, stream: bool, stream_cls: type[_AsyncStreamT] | None, ) -> ResponseT | _AsyncStreamT: - remaining = remaining_retries - 1 - if remaining == 1: + remaining_retries = options.get_max_retries(self.max_retries) - retries_taken + if remaining_retries == 1: log.debug("1 retry left") else: - log.debug("%i retries left", remaining) + log.debug("%i retries left", remaining_retries) - timeout = self._calculate_retry_timeout(remaining, options, response_headers) + timeout = self._calculate_retry_timeout(remaining_retries, options, response_headers) log.info("Retrying request to %s in %f seconds", options.url, timeout) await anyio.sleep(timeout) @@ -1642,7 +1657,7 @@ async def _retry_request( return await self._request( options=options, cast_to=cast_to, - remaining_retries=remaining, + retries_taken=retries_taken + 1, stream=stream, stream_cls=stream_cls, ) diff --git a/src/finch/_client.py b/src/finch/_client.py index 3e9651e6..38117c5d 100644 --- a/src/finch/_client.py +++ b/src/finch/_client.py @@ -61,6 +61,7 @@ class Finch(SyncAPIClient): jobs: resources.Jobs sandbox: resources.Sandbox payroll: resources.Payroll + connect: resources.Connect with_raw_response: FinchWithRawResponse with_streaming_response: FinchWithStreamedResponse @@ -68,8 +69,6 @@ class Finch(SyncAPIClient): access_token: str | None client_id: str | None client_secret: str | None - sandbox_client_id: str | None - sandbox_client_secret: str | None webhook_secret: str | None def __init__( @@ -78,8 +77,6 @@ def __init__( access_token: str | None = None, client_id: str | None = None, client_secret: str | None = None, - sandbox_client_id: str | None = None, - sandbox_client_secret: str | None = None, webhook_secret: str | None = None, base_url: str | httpx.URL | None = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, @@ -111,8 +108,6 @@ def __init__( This automatically infers the following arguments from their corresponding environment variables if they are not provided: - `client_id` from `FINCH_CLIENT_ID` - `client_secret` from `FINCH_CLIENT_SECRET` - - `sandbox_client_id` from `FINCH_SANDBOX_CLIENT_ID` - - `sandbox_client_secret` from `FINCH_SANDBOX_CLIENT_SECRET` - `webhook_secret` from `FINCH_WEBHOOK_SECRET` """ self.access_token = access_token @@ -125,14 +120,6 @@ def __init__( client_secret = os.environ.get("FINCH_CLIENT_SECRET") self.client_secret = client_secret - if sandbox_client_id is None: - sandbox_client_id = os.environ.get("FINCH_SANDBOX_CLIENT_ID") - self.sandbox_client_id = sandbox_client_id - - if sandbox_client_secret is None: - sandbox_client_secret = os.environ.get("FINCH_SANDBOX_CLIENT_SECRET") - self.sandbox_client_secret = sandbox_client_secret - if webhook_secret is None: webhook_secret = os.environ.get("FINCH_WEBHOOK_SECRET") self.webhook_secret = webhook_secret @@ -165,6 +152,7 @@ def __init__( self.jobs = resources.Jobs(self) self.sandbox = resources.Sandbox(self) self.payroll = resources.Payroll(self) + self.connect = resources.Connect(self) self.with_raw_response = FinchWithRawResponse(self) self.with_streaming_response = FinchWithStreamedResponse(self) @@ -191,11 +179,11 @@ def _bearer_auth(self) -> dict[str, str]: @property def _basic_auth(self) -> dict[str, str]: - if self.sandbox_client_id is None: + if self.client_id is None: return {} - if self.sandbox_client_secret is None: + if self.client_secret is None: return {} - credentials = f"{self.sandbox_client_id}:{self.sandbox_client_secret}".encode("ascii") + credentials = f"{self.client_id}:{self.client_secret}".encode("ascii") header = f"Basic {base64.b64encode(credentials).decode('ascii')}" return {"Authorization": header} @@ -216,13 +204,13 @@ def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: if isinstance(custom_headers.get("Authorization"), Omit): return - if self.sandbox_client_id and self.sandbox_client_secret and headers.get("Authorization"): + if self.client_id and self.client_secret and headers.get("Authorization"): return if isinstance(custom_headers.get("Authorization"), Omit): return raise TypeError( - '"Could not resolve authentication method. Expected either access_token, sandbox_client_id or sandbox_client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted"' + '"Could not resolve authentication method. Expected either access_token, client_id or client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted"' ) def copy( @@ -231,8 +219,6 @@ def copy( access_token: str | None = None, client_id: str | None = None, client_secret: str | None = None, - sandbox_client_id: str | None = None, - sandbox_client_secret: str | None = None, webhook_secret: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, @@ -288,8 +274,6 @@ def copy( access_token=access_token or self.access_token, client_id=client_id or self.client_id, client_secret=client_secret or self.client_secret, - sandbox_client_id=sandbox_client_id or self.sandbox_client_id, - sandbox_client_secret=sandbox_client_secret or self.sandbox_client_secret, webhook_secret=webhook_secret or self.webhook_secret, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, @@ -413,6 +397,7 @@ class AsyncFinch(AsyncAPIClient): jobs: resources.AsyncJobs sandbox: resources.AsyncSandbox payroll: resources.AsyncPayroll + connect: resources.AsyncConnect with_raw_response: AsyncFinchWithRawResponse with_streaming_response: AsyncFinchWithStreamedResponse @@ -420,8 +405,6 @@ class AsyncFinch(AsyncAPIClient): access_token: str | None client_id: str | None client_secret: str | None - sandbox_client_id: str | None - sandbox_client_secret: str | None webhook_secret: str | None def __init__( @@ -430,8 +413,6 @@ def __init__( access_token: str | None = None, client_id: str | None = None, client_secret: str | None = None, - sandbox_client_id: str | None = None, - sandbox_client_secret: str | None = None, webhook_secret: str | None = None, base_url: str | httpx.URL | None = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, @@ -463,8 +444,6 @@ def __init__( This automatically infers the following arguments from their corresponding environment variables if they are not provided: - `client_id` from `FINCH_CLIENT_ID` - `client_secret` from `FINCH_CLIENT_SECRET` - - `sandbox_client_id` from `FINCH_SANDBOX_CLIENT_ID` - - `sandbox_client_secret` from `FINCH_SANDBOX_CLIENT_SECRET` - `webhook_secret` from `FINCH_WEBHOOK_SECRET` """ self.access_token = access_token @@ -477,14 +456,6 @@ def __init__( client_secret = os.environ.get("FINCH_CLIENT_SECRET") self.client_secret = client_secret - if sandbox_client_id is None: - sandbox_client_id = os.environ.get("FINCH_SANDBOX_CLIENT_ID") - self.sandbox_client_id = sandbox_client_id - - if sandbox_client_secret is None: - sandbox_client_secret = os.environ.get("FINCH_SANDBOX_CLIENT_SECRET") - self.sandbox_client_secret = sandbox_client_secret - if webhook_secret is None: webhook_secret = os.environ.get("FINCH_WEBHOOK_SECRET") self.webhook_secret = webhook_secret @@ -517,6 +488,7 @@ def __init__( self.jobs = resources.AsyncJobs(self) self.sandbox = resources.AsyncSandbox(self) self.payroll = resources.AsyncPayroll(self) + self.connect = resources.AsyncConnect(self) self.with_raw_response = AsyncFinchWithRawResponse(self) self.with_streaming_response = AsyncFinchWithStreamedResponse(self) @@ -543,11 +515,11 @@ def _bearer_auth(self) -> dict[str, str]: @property def _basic_auth(self) -> dict[str, str]: - if self.sandbox_client_id is None: + if self.client_id is None: return {} - if self.sandbox_client_secret is None: + if self.client_secret is None: return {} - credentials = f"{self.sandbox_client_id}:{self.sandbox_client_secret}".encode("ascii") + credentials = f"{self.client_id}:{self.client_secret}".encode("ascii") header = f"Basic {base64.b64encode(credentials).decode('ascii')}" return {"Authorization": header} @@ -568,13 +540,13 @@ def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: if isinstance(custom_headers.get("Authorization"), Omit): return - if self.sandbox_client_id and self.sandbox_client_secret and headers.get("Authorization"): + if self.client_id and self.client_secret and headers.get("Authorization"): return if isinstance(custom_headers.get("Authorization"), Omit): return raise TypeError( - '"Could not resolve authentication method. Expected either access_token, sandbox_client_id or sandbox_client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted"' + '"Could not resolve authentication method. Expected either access_token, client_id or client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted"' ) def copy( @@ -583,8 +555,6 @@ def copy( access_token: str | None = None, client_id: str | None = None, client_secret: str | None = None, - sandbox_client_id: str | None = None, - sandbox_client_secret: str | None = None, webhook_secret: str | None = None, base_url: str | httpx.URL | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, @@ -640,8 +610,6 @@ def copy( access_token=access_token or self.access_token, client_id=client_id or self.client_id, client_secret=client_secret or self.client_secret, - sandbox_client_id=sandbox_client_id or self.sandbox_client_id, - sandbox_client_secret=sandbox_client_secret or self.sandbox_client_secret, webhook_secret=webhook_secret or self.webhook_secret, base_url=base_url or self.base_url, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, @@ -765,6 +733,7 @@ def __init__(self, client: Finch) -> None: self.jobs = resources.JobsWithRawResponse(client.jobs) self.sandbox = resources.SandboxWithRawResponse(client.sandbox) self.payroll = resources.PayrollWithRawResponse(client.payroll) + self.connect = resources.ConnectWithRawResponse(client.connect) class AsyncFinchWithRawResponse: @@ -777,6 +746,7 @@ def __init__(self, client: AsyncFinch) -> None: self.jobs = resources.AsyncJobsWithRawResponse(client.jobs) self.sandbox = resources.AsyncSandboxWithRawResponse(client.sandbox) self.payroll = resources.AsyncPayrollWithRawResponse(client.payroll) + self.connect = resources.AsyncConnectWithRawResponse(client.connect) class FinchWithStreamedResponse: @@ -789,6 +759,7 @@ def __init__(self, client: Finch) -> None: self.jobs = resources.JobsWithStreamingResponse(client.jobs) self.sandbox = resources.SandboxWithStreamingResponse(client.sandbox) self.payroll = resources.PayrollWithStreamingResponse(client.payroll) + self.connect = resources.ConnectWithStreamingResponse(client.connect) class AsyncFinchWithStreamedResponse: @@ -801,6 +772,7 @@ def __init__(self, client: AsyncFinch) -> None: self.jobs = resources.AsyncJobsWithStreamingResponse(client.jobs) self.sandbox = resources.AsyncSandboxWithStreamingResponse(client.sandbox) self.payroll = resources.AsyncPayrollWithStreamingResponse(client.payroll) + self.connect = resources.AsyncConnectWithStreamingResponse(client.connect) Client = Finch diff --git a/src/finch/_compat.py b/src/finch/_compat.py index 21fe6941..162a6fbe 100644 --- a/src/finch/_compat.py +++ b/src/finch/_compat.py @@ -136,12 +136,14 @@ def model_dump( exclude: IncEx = None, exclude_unset: bool = False, exclude_defaults: bool = False, + warnings: bool = True, ) -> dict[str, Any]: if PYDANTIC_V2: return model.model_dump( exclude=exclude, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults, + warnings=warnings, ) return cast( "dict[str, Any]", diff --git a/src/finch/_utils/_utils.py b/src/finch/_utils/_utils.py index 2fc5a1c6..0bba17ca 100644 --- a/src/finch/_utils/_utils.py +++ b/src/finch/_utils/_utils.py @@ -363,12 +363,13 @@ def file_from_path(path: str) -> FileTypes: def get_required_header(headers: HeadersLike, header: str) -> str: lower_header = header.lower() - if isinstance(headers, Mapping): - for k, v in headers.items(): + if is_mapping_t(headers): + # mypy doesn't understand the type narrowing here + for k, v in headers.items(): # type: ignore if k.lower() == lower_header and isinstance(v, str): return v - """ to deal with the case where the header looks like Stainless-Event-Id """ + # to deal with the case where the header looks like Stainless-Event-Id intercaps_header = re.sub(r"([^\w])(\w)", lambda pat: pat.group(1) + pat.group(2).upper(), header.capitalize()) for normalized_header in [header, lower_header, header.upper(), intercaps_header]: diff --git a/src/finch/_version.py b/src/finch/_version.py index a6406247..b1a448b2 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.5.0" # x-release-please-version +__version__ = "1.6.0" # x-release-please-version diff --git a/src/finch/resources/__init__.py b/src/finch/resources/__init__.py index 6f6a8cdc..542fbfcc 100644 --- a/src/finch/resources/__init__.py +++ b/src/finch/resources/__init__.py @@ -24,6 +24,14 @@ AccountWithStreamingResponse, AsyncAccountWithStreamingResponse, ) +from .connect import ( + Connect, + AsyncConnect, + ConnectWithRawResponse, + AsyncConnectWithRawResponse, + ConnectWithStreamingResponse, + AsyncConnectWithStreamingResponse, +) from .payroll import ( Payroll, AsyncPayroll, @@ -117,4 +125,10 @@ "AsyncPayrollWithRawResponse", "PayrollWithStreamingResponse", "AsyncPayrollWithStreamingResponse", + "Connect", + "AsyncConnect", + "ConnectWithRawResponse", + "AsyncConnectWithRawResponse", + "ConnectWithStreamingResponse", + "AsyncConnectWithStreamingResponse", ] diff --git a/src/finch/resources/access_tokens.py b/src/finch/resources/access_tokens.py index a9cdadb1..6e442cff 100644 --- a/src/finch/resources/access_tokens.py +++ b/src/finch/resources/access_tokens.py @@ -20,10 +20,21 @@ class AccessTokens(SyncAPIResource): @cached_property def with_raw_response(self) -> AccessTokensWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AccessTokensWithRawResponse(self) @cached_property def with_streaming_response(self) -> AccessTokensWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AccessTokensWithStreamingResponse(self) def create( @@ -87,10 +98,21 @@ def create( class AsyncAccessTokens(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncAccessTokensWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncAccessTokensWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncAccessTokensWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncAccessTokensWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/account.py b/src/finch/resources/account.py index 08622c07..4f65a979 100644 --- a/src/finch/resources/account.py +++ b/src/finch/resources/account.py @@ -19,10 +19,21 @@ class Account(SyncAPIResource): @cached_property def with_raw_response(self) -> AccountWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AccountWithRawResponse(self) @cached_property def with_streaming_response(self) -> AccountWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AccountWithStreamingResponse(self) def disconnect( @@ -67,10 +78,21 @@ def introspect( class AsyncAccount(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncAccountWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncAccountWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncAccountWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncAccountWithStreamingResponse(self) async def disconnect( diff --git a/src/finch/resources/connect/__init__.py b/src/finch/resources/connect/__init__.py new file mode 100644 index 00000000..1679749e --- /dev/null +++ b/src/finch/resources/connect/__init__.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from .connect import ( + Connect, + AsyncConnect, + ConnectWithRawResponse, + AsyncConnectWithRawResponse, + ConnectWithStreamingResponse, + AsyncConnectWithStreamingResponse, +) +from .sessions import ( + Sessions, + AsyncSessions, + SessionsWithRawResponse, + AsyncSessionsWithRawResponse, + SessionsWithStreamingResponse, + AsyncSessionsWithStreamingResponse, +) + +__all__ = [ + "Sessions", + "AsyncSessions", + "SessionsWithRawResponse", + "AsyncSessionsWithRawResponse", + "SessionsWithStreamingResponse", + "AsyncSessionsWithStreamingResponse", + "Connect", + "AsyncConnect", + "ConnectWithRawResponse", + "AsyncConnectWithRawResponse", + "ConnectWithStreamingResponse", + "AsyncConnectWithStreamingResponse", +] diff --git a/src/finch/resources/connect/connect.py b/src/finch/resources/connect/connect.py new file mode 100644 index 00000000..a6909d8a --- /dev/null +++ b/src/finch/resources/connect/connect.py @@ -0,0 +1,102 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .sessions import ( + Sessions, + AsyncSessions, + SessionsWithRawResponse, + AsyncSessionsWithRawResponse, + SessionsWithStreamingResponse, + AsyncSessionsWithStreamingResponse, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource + +__all__ = ["Connect", "AsyncConnect"] + + +class Connect(SyncAPIResource): + @cached_property + def sessions(self) -> Sessions: + return Sessions(self._client) + + @cached_property + def with_raw_response(self) -> ConnectWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ + return ConnectWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> ConnectWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ + return ConnectWithStreamingResponse(self) + + +class AsyncConnect(AsyncAPIResource): + @cached_property + def sessions(self) -> AsyncSessions: + return AsyncSessions(self._client) + + @cached_property + def with_raw_response(self) -> AsyncConnectWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncConnectWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncConnectWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ + return AsyncConnectWithStreamingResponse(self) + + +class ConnectWithRawResponse: + def __init__(self, connect: Connect) -> None: + self._connect = connect + + @cached_property + def sessions(self) -> SessionsWithRawResponse: + return SessionsWithRawResponse(self._connect.sessions) + + +class AsyncConnectWithRawResponse: + def __init__(self, connect: AsyncConnect) -> None: + self._connect = connect + + @cached_property + def sessions(self) -> AsyncSessionsWithRawResponse: + return AsyncSessionsWithRawResponse(self._connect.sessions) + + +class ConnectWithStreamingResponse: + def __init__(self, connect: Connect) -> None: + self._connect = connect + + @cached_property + def sessions(self) -> SessionsWithStreamingResponse: + return SessionsWithStreamingResponse(self._connect.sessions) + + +class AsyncConnectWithStreamingResponse: + def __init__(self, connect: AsyncConnect) -> None: + self._connect = connect + + @cached_property + def sessions(self) -> AsyncSessionsWithStreamingResponse: + return AsyncSessionsWithStreamingResponse(self._connect.sessions) diff --git a/src/finch/resources/connect/sessions.py b/src/finch/resources/connect/sessions.py new file mode 100644 index 00000000..7ff62b0e --- /dev/null +++ b/src/finch/resources/connect/sessions.py @@ -0,0 +1,348 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal + +import httpx + +from ... import _legacy_response +from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ..._utils import ( + maybe_transform, + async_maybe_transform, +) +from ..._compat import cached_property +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import to_streamed_response_wrapper, async_to_streamed_response_wrapper +from ..._base_client import make_request_options +from ...types.connect import session_new_params, session_reauthenticate_params +from ...types.connect.session_new_response import SessionNewResponse +from ...types.connect.session_reauthenticate_response import SessionReauthenticateResponse + +__all__ = ["Sessions", "AsyncSessions"] + + +class Sessions(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SessionsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ + return SessionsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SessionsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ + return SessionsWithStreamingResponse(self) + + def new( + self, + *, + customer_id: str, + customer_name: str, + products: List[ + Literal["company", "directory", "individual", "employment", "payment", "pay_statement", "benefits", "ssn"] + ], + customer_email: Optional[str] | NotGiven = NOT_GIVEN, + integration: Optional[session_new_params.Integration] | NotGiven = NOT_GIVEN, + manual: Optional[bool] | NotGiven = NOT_GIVEN, + minutes_to_expire: Optional[float] | NotGiven = NOT_GIVEN, + redirect_uri: Optional[str] | NotGiven = NOT_GIVEN, + sandbox: Optional[Literal["finch", "provider"]] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SessionNewResponse: + """ + Create a new connect session for an employer + + Args: + minutes_to_expire: The number of minutes until the session expires (defaults to 10,080, which is 7 + days) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/connect/sessions", + body=maybe_transform( + { + "customer_id": customer_id, + "customer_name": customer_name, + "products": products, + "customer_email": customer_email, + "integration": integration, + "manual": manual, + "minutes_to_expire": minutes_to_expire, + "redirect_uri": redirect_uri, + "sandbox": sandbox, + }, + session_new_params.SessionNewParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SessionNewResponse, + ) + + def reauthenticate( + self, + *, + connection_id: str, + minutes_to_expire: Optional[int] | NotGiven = NOT_GIVEN, + products: Optional[ + List[ + Literal[ + "company", "directory", "individual", "employment", "payment", "pay_statement", "benefits", "ssn" + ] + ] + ] + | NotGiven = NOT_GIVEN, + redirect_uri: Optional[str] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SessionReauthenticateResponse: + """ + Create a new Connect session for reauthenticating an existing connection + + Args: + connection_id: The ID of the existing connection to reauthenticate + + minutes_to_expire: The number of minutes until the session expires (defaults to 10,080, which is 7 + days) + + products: The products to request access to (optional for reauthentication) + + redirect_uri: The URI to redirect to after the Connect flow is completed + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/connect/sessions/reauthenticate", + body=maybe_transform( + { + "connection_id": connection_id, + "minutes_to_expire": minutes_to_expire, + "products": products, + "redirect_uri": redirect_uri, + }, + session_reauthenticate_params.SessionReauthenticateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SessionReauthenticateResponse, + ) + + +class AsyncSessions(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSessionsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ + return AsyncSessionsWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSessionsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ + return AsyncSessionsWithStreamingResponse(self) + + async def new( + self, + *, + customer_id: str, + customer_name: str, + products: List[ + Literal["company", "directory", "individual", "employment", "payment", "pay_statement", "benefits", "ssn"] + ], + customer_email: Optional[str] | NotGiven = NOT_GIVEN, + integration: Optional[session_new_params.Integration] | NotGiven = NOT_GIVEN, + manual: Optional[bool] | NotGiven = NOT_GIVEN, + minutes_to_expire: Optional[float] | NotGiven = NOT_GIVEN, + redirect_uri: Optional[str] | NotGiven = NOT_GIVEN, + sandbox: Optional[Literal["finch", "provider"]] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SessionNewResponse: + """ + Create a new connect session for an employer + + Args: + minutes_to_expire: The number of minutes until the session expires (defaults to 10,080, which is 7 + days) + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/connect/sessions", + body=await async_maybe_transform( + { + "customer_id": customer_id, + "customer_name": customer_name, + "products": products, + "customer_email": customer_email, + "integration": integration, + "manual": manual, + "minutes_to_expire": minutes_to_expire, + "redirect_uri": redirect_uri, + "sandbox": sandbox, + }, + session_new_params.SessionNewParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SessionNewResponse, + ) + + async def reauthenticate( + self, + *, + connection_id: str, + minutes_to_expire: Optional[int] | NotGiven = NOT_GIVEN, + products: Optional[ + List[ + Literal[ + "company", "directory", "individual", "employment", "payment", "pay_statement", "benefits", "ssn" + ] + ] + ] + | NotGiven = NOT_GIVEN, + redirect_uri: Optional[str] | 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, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN, + ) -> SessionReauthenticateResponse: + """ + Create a new Connect session for reauthenticating an existing connection + + Args: + connection_id: The ID of the existing connection to reauthenticate + + minutes_to_expire: The number of minutes until the session expires (defaults to 10,080, which is 7 + days) + + products: The products to request access to (optional for reauthentication) + + redirect_uri: The URI to redirect to after the Connect flow is completed + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/connect/sessions/reauthenticate", + body=await async_maybe_transform( + { + "connection_id": connection_id, + "minutes_to_expire": minutes_to_expire, + "products": products, + "redirect_uri": redirect_uri, + }, + session_reauthenticate_params.SessionReauthenticateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SessionReauthenticateResponse, + ) + + +class SessionsWithRawResponse: + def __init__(self, sessions: Sessions) -> None: + self._sessions = sessions + + self.new = _legacy_response.to_raw_response_wrapper( + sessions.new, + ) + self.reauthenticate = _legacy_response.to_raw_response_wrapper( + sessions.reauthenticate, + ) + + +class AsyncSessionsWithRawResponse: + def __init__(self, sessions: AsyncSessions) -> None: + self._sessions = sessions + + self.new = _legacy_response.async_to_raw_response_wrapper( + sessions.new, + ) + self.reauthenticate = _legacy_response.async_to_raw_response_wrapper( + sessions.reauthenticate, + ) + + +class SessionsWithStreamingResponse: + def __init__(self, sessions: Sessions) -> None: + self._sessions = sessions + + self.new = to_streamed_response_wrapper( + sessions.new, + ) + self.reauthenticate = to_streamed_response_wrapper( + sessions.reauthenticate, + ) + + +class AsyncSessionsWithStreamingResponse: + def __init__(self, sessions: AsyncSessions) -> None: + self._sessions = sessions + + self.new = async_to_streamed_response_wrapper( + sessions.new, + ) + self.reauthenticate = async_to_streamed_response_wrapper( + sessions.reauthenticate, + ) diff --git a/src/finch/resources/hris/benefits/benefits.py b/src/finch/resources/hris/benefits/benefits.py index be079297..3305930f 100644 --- a/src/finch/resources/hris/benefits/benefits.py +++ b/src/finch/resources/hris/benefits/benefits.py @@ -43,10 +43,21 @@ def individuals(self) -> Individuals: @cached_property def with_raw_response(self) -> BenefitsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return BenefitsWithRawResponse(self) @cached_property def with_streaming_response(self) -> BenefitsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return BenefitsWithStreamingResponse(self) def create( @@ -216,10 +227,21 @@ def individuals(self) -> AsyncIndividuals: @cached_property def with_raw_response(self) -> AsyncBenefitsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncBenefitsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncBenefitsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncBenefitsWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/hris/benefits/individuals.py b/src/finch/resources/hris/benefits/individuals.py index 31d01a9f..3545ee98 100644 --- a/src/finch/resources/hris/benefits/individuals.py +++ b/src/finch/resources/hris/benefits/individuals.py @@ -30,10 +30,21 @@ class Individuals(SyncAPIResource): @cached_property def with_raw_response(self) -> IndividualsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return IndividualsWithRawResponse(self) @cached_property def with_streaming_response(self) -> IndividualsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return IndividualsWithStreamingResponse(self) def enroll_many( @@ -202,10 +213,21 @@ def unenroll_many( class AsyncIndividuals(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncIndividualsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncIndividualsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncIndividualsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncIndividualsWithStreamingResponse(self) def enroll_many( diff --git a/src/finch/resources/hris/company.py b/src/finch/resources/hris/company.py index 0ff218fb..d1eb8491 100644 --- a/src/finch/resources/hris/company.py +++ b/src/finch/resources/hris/company.py @@ -18,10 +18,21 @@ class CompanyResource(SyncAPIResource): @cached_property def with_raw_response(self) -> CompanyResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return CompanyResourceWithRawResponse(self) @cached_property def with_streaming_response(self) -> CompanyResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return CompanyResourceWithStreamingResponse(self) def retrieve( @@ -47,10 +58,21 @@ def retrieve( class AsyncCompanyResource(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncCompanyResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncCompanyResourceWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncCompanyResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncCompanyResourceWithStreamingResponse(self) async def retrieve( diff --git a/src/finch/resources/hris/directory.py b/src/finch/resources/hris/directory.py index 3cb6bcb4..94a4451c 100644 --- a/src/finch/resources/hris/directory.py +++ b/src/finch/resources/hris/directory.py @@ -23,10 +23,21 @@ class Directory(SyncAPIResource): @cached_property def with_raw_response(self) -> DirectoryWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return DirectoryWithRawResponse(self) @cached_property def with_streaming_response(self) -> DirectoryWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return DirectoryWithStreamingResponse(self) def list( @@ -118,10 +129,21 @@ def list_individuals( class AsyncDirectory(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncDirectoryWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncDirectoryWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncDirectoryWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncDirectoryWithStreamingResponse(self) def list( diff --git a/src/finch/resources/hris/employments.py b/src/finch/resources/hris/employments.py index 867fcd20..1a562194 100644 --- a/src/finch/resources/hris/employments.py +++ b/src/finch/resources/hris/employments.py @@ -23,10 +23,21 @@ class Employments(SyncAPIResource): @cached_property def with_raw_response(self) -> EmploymentsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return EmploymentsWithRawResponse(self) @cached_property def with_streaming_response(self) -> EmploymentsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return EmploymentsWithStreamingResponse(self) def retrieve_many( @@ -69,10 +80,21 @@ def retrieve_many( class AsyncEmployments(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncEmploymentsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncEmploymentsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncEmploymentsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncEmploymentsWithStreamingResponse(self) def retrieve_many( diff --git a/src/finch/resources/hris/hris.py b/src/finch/resources/hris/hris.py index 8a49bc85..50c5a621 100644 --- a/src/finch/resources/hris/hris.py +++ b/src/finch/resources/hris/hris.py @@ -96,10 +96,21 @@ def benefits(self) -> Benefits: @cached_property def with_raw_response(self) -> HRISWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return HRISWithRawResponse(self) @cached_property def with_streaming_response(self) -> HRISWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return HRISWithStreamingResponse(self) @@ -134,10 +145,21 @@ def benefits(self) -> AsyncBenefits: @cached_property def with_raw_response(self) -> AsyncHRISWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncHRISWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncHRISWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncHRISWithStreamingResponse(self) diff --git a/src/finch/resources/hris/individuals.py b/src/finch/resources/hris/individuals.py index 705ee584..7bf9b26b 100644 --- a/src/finch/resources/hris/individuals.py +++ b/src/finch/resources/hris/individuals.py @@ -23,10 +23,21 @@ class Individuals(SyncAPIResource): @cached_property def with_raw_response(self) -> IndividualsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return IndividualsWithRawResponse(self) @cached_property def with_streaming_response(self) -> IndividualsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return IndividualsWithStreamingResponse(self) def retrieve_many( @@ -74,10 +85,21 @@ def retrieve_many( class AsyncIndividuals(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncIndividualsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncIndividualsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncIndividualsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncIndividualsWithStreamingResponse(self) def retrieve_many( diff --git a/src/finch/resources/hris/pay_statements.py b/src/finch/resources/hris/pay_statements.py index 0fa29199..818f4655 100644 --- a/src/finch/resources/hris/pay_statements.py +++ b/src/finch/resources/hris/pay_statements.py @@ -23,10 +23,21 @@ class PayStatements(SyncAPIResource): @cached_property def with_raw_response(self) -> PayStatementsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return PayStatementsWithRawResponse(self) @cached_property def with_streaming_response(self) -> PayStatementsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return PayStatementsWithStreamingResponse(self) def retrieve_many( @@ -74,10 +85,21 @@ def retrieve_many( class AsyncPayStatements(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncPayStatementsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncPayStatementsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncPayStatementsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncPayStatementsWithStreamingResponse(self) def retrieve_many( diff --git a/src/finch/resources/hris/payments.py b/src/finch/resources/hris/payments.py index 8e27e735..9f7667eb 100644 --- a/src/finch/resources/hris/payments.py +++ b/src/finch/resources/hris/payments.py @@ -24,10 +24,21 @@ class Payments(SyncAPIResource): @cached_property def with_raw_response(self) -> PaymentsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return PaymentsWithRawResponse(self) @cached_property def with_streaming_response(self) -> PaymentsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return PaymentsWithStreamingResponse(self) def list( @@ -83,10 +94,21 @@ def list( class AsyncPayments(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncPaymentsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncPaymentsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncPaymentsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncPaymentsWithStreamingResponse(self) def list( diff --git a/src/finch/resources/jobs/automated.py b/src/finch/resources/jobs/automated.py index 34cf152c..b8bcb702 100644 --- a/src/finch/resources/jobs/automated.py +++ b/src/finch/resources/jobs/automated.py @@ -27,10 +27,21 @@ class Automated(SyncAPIResource): @cached_property def with_raw_response(self) -> AutomatedWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AutomatedWithRawResponse(self) @cached_property def with_streaming_response(self) -> AutomatedWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AutomatedWithStreamingResponse(self) def create( @@ -164,10 +175,21 @@ def list( class AsyncAutomated(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncAutomatedWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncAutomatedWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncAutomatedWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncAutomatedWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/jobs/jobs.py b/src/finch/resources/jobs/jobs.py index 950f977f..d6da244e 100644 --- a/src/finch/resources/jobs/jobs.py +++ b/src/finch/resources/jobs/jobs.py @@ -35,10 +35,21 @@ def manual(self) -> Manual: @cached_property def with_raw_response(self) -> JobsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return JobsWithRawResponse(self) @cached_property def with_streaming_response(self) -> JobsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return JobsWithStreamingResponse(self) @@ -53,10 +64,21 @@ def manual(self) -> AsyncManual: @cached_property def with_raw_response(self) -> AsyncJobsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncJobsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncJobsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncJobsWithStreamingResponse(self) diff --git a/src/finch/resources/jobs/manual.py b/src/finch/resources/jobs/manual.py index 740131e2..bdc08576 100644 --- a/src/finch/resources/jobs/manual.py +++ b/src/finch/resources/jobs/manual.py @@ -18,10 +18,21 @@ class Manual(SyncAPIResource): @cached_property def with_raw_response(self) -> ManualWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return ManualWithRawResponse(self) @cached_property def with_streaming_response(self) -> ManualWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return ManualWithStreamingResponse(self) def retrieve( @@ -63,10 +74,21 @@ def retrieve( class AsyncManual(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncManualWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncManualWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncManualWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncManualWithStreamingResponse(self) async def retrieve( diff --git a/src/finch/resources/payroll/pay_groups.py b/src/finch/resources/payroll/pay_groups.py index edcf6e8d..5673be66 100644 --- a/src/finch/resources/payroll/pay_groups.py +++ b/src/finch/resources/payroll/pay_groups.py @@ -24,10 +24,21 @@ class PayGroups(SyncAPIResource): @cached_property def with_raw_response(self) -> PayGroupsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return PayGroupsWithRawResponse(self) @cached_property def with_streaming_response(self) -> PayGroupsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return PayGroupsWithStreamingResponse(self) def retrieve( @@ -110,10 +121,21 @@ def list( class AsyncPayGroups(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncPayGroupsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncPayGroupsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncPayGroupsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncPayGroupsWithStreamingResponse(self) async def retrieve( diff --git a/src/finch/resources/payroll/payroll.py b/src/finch/resources/payroll/payroll.py index 01bebaa6..d84fb628 100644 --- a/src/finch/resources/payroll/payroll.py +++ b/src/finch/resources/payroll/payroll.py @@ -23,10 +23,21 @@ def pay_groups(self) -> PayGroups: @cached_property def with_raw_response(self) -> PayrollWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return PayrollWithRawResponse(self) @cached_property def with_streaming_response(self) -> PayrollWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return PayrollWithStreamingResponse(self) @@ -37,10 +48,21 @@ def pay_groups(self) -> AsyncPayGroups: @cached_property def with_raw_response(self) -> AsyncPayrollWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncPayrollWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncPayrollWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncPayrollWithStreamingResponse(self) diff --git a/src/finch/resources/providers.py b/src/finch/resources/providers.py index eabf68d7..bb26ce7d 100644 --- a/src/finch/resources/providers.py +++ b/src/finch/resources/providers.py @@ -19,10 +19,21 @@ class Providers(SyncAPIResource): @cached_property def with_raw_response(self) -> ProvidersWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return ProvidersWithRawResponse(self) @cached_property def with_streaming_response(self) -> ProvidersWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return ProvidersWithStreamingResponse(self) def list( @@ -49,10 +60,21 @@ def list( class AsyncProviders(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncProvidersWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncProvidersWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncProvidersWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncProvidersWithStreamingResponse(self) def list( diff --git a/src/finch/resources/request_forwarding.py b/src/finch/resources/request_forwarding.py index 9e1d314a..578f1f70 100644 --- a/src/finch/resources/request_forwarding.py +++ b/src/finch/resources/request_forwarding.py @@ -25,10 +25,21 @@ class RequestForwarding(SyncAPIResource): @cached_property def with_raw_response(self) -> RequestForwardingWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return RequestForwardingWithRawResponse(self) @cached_property def with_streaming_response(self) -> RequestForwardingWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return RequestForwardingWithStreamingResponse(self) def forward( @@ -101,10 +112,21 @@ def forward( class AsyncRequestForwarding(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncRequestForwardingWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncRequestForwardingWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncRequestForwardingWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncRequestForwardingWithStreamingResponse(self) async def forward( diff --git a/src/finch/resources/sandbox/company.py b/src/finch/resources/sandbox/company.py index c243bfef..12302429 100644 --- a/src/finch/resources/sandbox/company.py +++ b/src/finch/resources/sandbox/company.py @@ -26,10 +26,21 @@ class Company(SyncAPIResource): @cached_property def with_raw_response(self) -> CompanyWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return CompanyWithRawResponse(self) @cached_property def with_streaming_response(self) -> CompanyWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return CompanyWithStreamingResponse(self) def update( @@ -101,10 +112,21 @@ def update( class AsyncCompany(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncCompanyWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncCompanyWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncCompanyWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncCompanyWithStreamingResponse(self) async def update( diff --git a/src/finch/resources/sandbox/connections/accounts.py b/src/finch/resources/sandbox/connections/accounts.py index d7be2e90..8a1d088f 100644 --- a/src/finch/resources/sandbox/connections/accounts.py +++ b/src/finch/resources/sandbox/connections/accounts.py @@ -28,10 +28,21 @@ class Accounts(SyncAPIResource): @cached_property def with_raw_response(self) -> AccountsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AccountsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AccountsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AccountsWithStreamingResponse(self) def create( @@ -120,10 +131,21 @@ def update( class AsyncAccounts(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncAccountsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncAccountsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncAccountsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncAccountsWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/sandbox/connections/connections.py b/src/finch/resources/sandbox/connections/connections.py index 9baae475..dbd2c146 100644 --- a/src/finch/resources/sandbox/connections/connections.py +++ b/src/finch/resources/sandbox/connections/connections.py @@ -38,10 +38,21 @@ def accounts(self) -> Accounts: @cached_property def with_raw_response(self) -> ConnectionsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return ConnectionsWithRawResponse(self) @cached_property def with_streaming_response(self) -> ConnectionsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return ConnectionsWithStreamingResponse(self) def create( @@ -101,10 +112,21 @@ def accounts(self) -> AsyncAccounts: @cached_property def with_raw_response(self) -> AsyncConnectionsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncConnectionsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncConnectionsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncConnectionsWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/sandbox/directory.py b/src/finch/resources/sandbox/directory.py index f6b414ad..0c3a1501 100644 --- a/src/finch/resources/sandbox/directory.py +++ b/src/finch/resources/sandbox/directory.py @@ -25,10 +25,21 @@ class Directory(SyncAPIResource): @cached_property def with_raw_response(self) -> DirectoryWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return DirectoryWithRawResponse(self) @cached_property def with_streaming_response(self) -> DirectoryWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return DirectoryWithStreamingResponse(self) def create( @@ -70,10 +81,21 @@ def create( class AsyncDirectory(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncDirectoryWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncDirectoryWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncDirectoryWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncDirectoryWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/sandbox/employment.py b/src/finch/resources/sandbox/employment.py index 1e3b8c1a..3adb0c1a 100644 --- a/src/finch/resources/sandbox/employment.py +++ b/src/finch/resources/sandbox/employment.py @@ -27,10 +27,21 @@ class Employment(SyncAPIResource): @cached_property def with_raw_response(self) -> EmploymentWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return EmploymentWithRawResponse(self) @cached_property def with_streaming_response(self) -> EmploymentWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return EmploymentWithStreamingResponse(self) def update( @@ -47,6 +58,7 @@ def update( income_history: Optional[Iterable[Optional[IncomeParam]]] | NotGiven = NOT_GIVEN, is_active: Optional[bool] | NotGiven = NOT_GIVEN, last_name: Optional[str] | NotGiven = NOT_GIVEN, + latest_rehire_date: Optional[str] | NotGiven = NOT_GIVEN, location: Optional[LocationParam] | NotGiven = NOT_GIVEN, manager: Optional[employment_update_params.Manager] | NotGiven = NOT_GIVEN, middle_name: Optional[str] | NotGiven = NOT_GIVEN, @@ -120,6 +132,7 @@ def update( "income_history": income_history, "is_active": is_active, "last_name": last_name, + "latest_rehire_date": latest_rehire_date, "location": location, "manager": manager, "middle_name": middle_name, @@ -139,10 +152,21 @@ def update( class AsyncEmployment(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncEmploymentWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncEmploymentWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncEmploymentWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncEmploymentWithStreamingResponse(self) async def update( @@ -159,6 +183,7 @@ async def update( income_history: Optional[Iterable[Optional[IncomeParam]]] | NotGiven = NOT_GIVEN, is_active: Optional[bool] | NotGiven = NOT_GIVEN, last_name: Optional[str] | NotGiven = NOT_GIVEN, + latest_rehire_date: Optional[str] | NotGiven = NOT_GIVEN, location: Optional[LocationParam] | NotGiven = NOT_GIVEN, manager: Optional[employment_update_params.Manager] | NotGiven = NOT_GIVEN, middle_name: Optional[str] | NotGiven = NOT_GIVEN, @@ -232,6 +257,7 @@ async def update( "income_history": income_history, "is_active": is_active, "last_name": last_name, + "latest_rehire_date": latest_rehire_date, "location": location, "manager": manager, "middle_name": middle_name, diff --git a/src/finch/resources/sandbox/individual.py b/src/finch/resources/sandbox/individual.py index d06155b6..a6825c69 100644 --- a/src/finch/resources/sandbox/individual.py +++ b/src/finch/resources/sandbox/individual.py @@ -27,10 +27,21 @@ class Individual(SyncAPIResource): @cached_property def with_raw_response(self) -> IndividualWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return IndividualWithRawResponse(self) @cached_property def with_streaming_response(self) -> IndividualWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return IndividualWithStreamingResponse(self) def update( @@ -134,10 +145,21 @@ def update( class AsyncIndividual(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncIndividualWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncIndividualWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncIndividualWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncIndividualWithStreamingResponse(self) async def update( diff --git a/src/finch/resources/sandbox/jobs/configuration.py b/src/finch/resources/sandbox/jobs/configuration.py index 8aae6f08..6f2b1dd6 100644 --- a/src/finch/resources/sandbox/jobs/configuration.py +++ b/src/finch/resources/sandbox/jobs/configuration.py @@ -26,10 +26,21 @@ class Configuration(SyncAPIResource): @cached_property def with_raw_response(self) -> ConfigurationWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return ConfigurationWithRawResponse(self) @cached_property def with_streaming_response(self) -> ConfigurationWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return ConfigurationWithStreamingResponse(self) def retrieve( @@ -94,10 +105,21 @@ def update( class AsyncConfiguration(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncConfigurationWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncConfigurationWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncConfigurationWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncConfigurationWithStreamingResponse(self) async def retrieve( diff --git a/src/finch/resources/sandbox/jobs/jobs.py b/src/finch/resources/sandbox/jobs/jobs.py index b8c904a7..2a94fa45 100644 --- a/src/finch/resources/sandbox/jobs/jobs.py +++ b/src/finch/resources/sandbox/jobs/jobs.py @@ -37,10 +37,21 @@ def configuration(self) -> Configuration: @cached_property def with_raw_response(self) -> JobsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return JobsWithRawResponse(self) @cached_property def with_streaming_response(self) -> JobsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return JobsWithStreamingResponse(self) def create( @@ -86,10 +97,21 @@ def configuration(self) -> AsyncConfiguration: @cached_property def with_raw_response(self) -> AsyncJobsWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncJobsWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncJobsWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncJobsWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/sandbox/payment.py b/src/finch/resources/sandbox/payment.py index 33b62542..6cd96253 100644 --- a/src/finch/resources/sandbox/payment.py +++ b/src/finch/resources/sandbox/payment.py @@ -25,10 +25,21 @@ class Payment(SyncAPIResource): @cached_property def with_raw_response(self) -> PaymentWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return PaymentWithRawResponse(self) @cached_property def with_streaming_response(self) -> PaymentWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return PaymentWithStreamingResponse(self) def create( @@ -76,10 +87,21 @@ def create( class AsyncPayment(AsyncAPIResource): @cached_property def with_raw_response(self) -> AsyncPaymentWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncPaymentWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncPaymentWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncPaymentWithStreamingResponse(self) async def create( diff --git a/src/finch/resources/sandbox/sandbox.py b/src/finch/resources/sandbox/sandbox.py index d4b5a8d2..33f73435 100644 --- a/src/finch/resources/sandbox/sandbox.py +++ b/src/finch/resources/sandbox/sandbox.py @@ -97,10 +97,21 @@ def jobs(self) -> Jobs: @cached_property def with_raw_response(self) -> SandboxWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return SandboxWithRawResponse(self) @cached_property def with_streaming_response(self) -> SandboxWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return SandboxWithStreamingResponse(self) @@ -135,10 +146,21 @@ def jobs(self) -> AsyncJobs: @cached_property def with_raw_response(self) -> AsyncSandboxWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return the + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/Finch-API/finch-api-python#accessing-raw-response-data-eg-headers + """ return AsyncSandboxWithRawResponse(self) @cached_property def with_streaming_response(self) -> AsyncSandboxWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/Finch-API/finch-api-python#with_streaming_response + """ return AsyncSandboxWithStreamingResponse(self) diff --git a/src/finch/types/connect/__init__.py b/src/finch/types/connect/__init__.py new file mode 100644 index 00000000..fe6954ab --- /dev/null +++ b/src/finch/types/connect/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from .session_new_params import SessionNewParams as SessionNewParams +from .session_new_response import SessionNewResponse as SessionNewResponse +from .session_reauthenticate_params import SessionReauthenticateParams as SessionReauthenticateParams +from .session_reauthenticate_response import SessionReauthenticateResponse as SessionReauthenticateResponse diff --git a/src/finch/types/connect/session_new_params.py b/src/finch/types/connect/session_new_params.py new file mode 100644 index 00000000..4de7c7e6 --- /dev/null +++ b/src/finch/types/connect/session_new_params.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["SessionNewParams", "Integration"] + + +class SessionNewParams(TypedDict, total=False): + customer_id: Required[str] + + customer_name: Required[str] + + products: Required[ + List[Literal["company", "directory", "individual", "employment", "payment", "pay_statement", "benefits", "ssn"]] + ] + + customer_email: Optional[str] + + integration: Optional[Integration] + + manual: Optional[bool] + + minutes_to_expire: Optional[float] + """ + The number of minutes until the session expires (defaults to 10,080, which is 7 + days) + """ + + redirect_uri: Optional[str] + + sandbox: Optional[Literal["finch", "provider"]] + + +class Integration(TypedDict, total=False): + auth_method: Optional[Literal["assisted", "credential", "oauth", "api_token"]] + + provider: Optional[str] diff --git a/src/finch/types/connect/session_new_response.py b/src/finch/types/connect/session_new_response.py new file mode 100644 index 00000000..2faa96c3 --- /dev/null +++ b/src/finch/types/connect/session_new_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + + + +from ..._models import BaseModel + +__all__ = ["SessionNewResponse"] + + +class SessionNewResponse(BaseModel): + connect_url: str + """The Connect URL to redirect the user to for authentication""" + + session_id: str + """The unique identifier for the created connect session""" diff --git a/src/finch/types/connect/session_reauthenticate_params.py b/src/finch/types/connect/session_reauthenticate_params.py new file mode 100644 index 00000000..bb6cfca6 --- /dev/null +++ b/src/finch/types/connect/session_reauthenticate_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["SessionReauthenticateParams"] + + +class SessionReauthenticateParams(TypedDict, total=False): + connection_id: Required[str] + """The ID of the existing connection to reauthenticate""" + + minutes_to_expire: Optional[int] + """ + The number of minutes until the session expires (defaults to 10,080, which is 7 + days) + """ + + products: Optional[ + List[Literal["company", "directory", "individual", "employment", "payment", "pay_statement", "benefits", "ssn"]] + ] + """The products to request access to (optional for reauthentication)""" + + redirect_uri: Optional[str] + """The URI to redirect to after the Connect flow is completed""" diff --git a/src/finch/types/connect/session_reauthenticate_response.py b/src/finch/types/connect/session_reauthenticate_response.py new file mode 100644 index 00000000..1f28765a --- /dev/null +++ b/src/finch/types/connect/session_reauthenticate_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + + + +from ..._models import BaseModel + +__all__ = ["SessionReauthenticateResponse"] + + +class SessionReauthenticateResponse(BaseModel): + connect_url: str + """The Connect URL to redirect the user to for reauthentication""" + + session_id: str + """The unique identifier for the created connect session""" diff --git a/src/finch/types/sandbox/directory_create_params.py b/src/finch/types/sandbox/directory_create_params.py index 2875864b..f8320f44 100644 --- a/src/finch/types/sandbox/directory_create_params.py +++ b/src/finch/types/sandbox/directory_create_params.py @@ -135,6 +135,8 @@ class Body(TypedDict, total=False): last_name: Optional[str] """The legal last name of the individual.""" + latest_rehire_date: Optional[str] + location: Optional[LocationParam] manager: Optional[BodyManager] diff --git a/src/finch/types/sandbox/employment_update_params.py b/src/finch/types/sandbox/employment_update_params.py index fa0bdbe7..0b6382c5 100644 --- a/src/finch/types/sandbox/employment_update_params.py +++ b/src/finch/types/sandbox/employment_update_params.py @@ -49,6 +49,8 @@ class EmploymentUpdateParams(TypedDict, total=False): last_name: Optional[str] """The legal last name of the individual.""" + latest_rehire_date: Optional[str] + location: Optional[LocationParam] manager: Optional[Manager] diff --git a/src/finch/types/sandbox/employment_update_response.py b/src/finch/types/sandbox/employment_update_response.py index 317cd03c..803332ea 100644 --- a/src/finch/types/sandbox/employment_update_response.py +++ b/src/finch/types/sandbox/employment_update_response.py @@ -79,6 +79,8 @@ class EmploymentUpdateResponse(BaseModel): last_name: Optional[str] = None """The legal last name of the individual.""" + latest_rehire_date: Optional[str] = None + location: Optional[Location] = None manager: Optional[Manager] = None diff --git a/tests/api_resources/connect/__init__.py b/tests/api_resources/connect/__init__.py new file mode 100644 index 00000000..fd8019a9 --- /dev/null +++ b/tests/api_resources/connect/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. diff --git a/tests/api_resources/connect/test_sessions.py b/tests/api_resources/connect/test_sessions.py new file mode 100644 index 00000000..6ea14912 --- /dev/null +++ b/tests/api_resources/connect/test_sessions.py @@ -0,0 +1,217 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from finch import Finch, AsyncFinch +from tests.utils import assert_matches_type +from finch.types.connect import ( + SessionNewResponse, + SessionReauthenticateResponse, +) + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSessions: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + def test_method_new(self, client: Finch) -> None: + session = client.connect.sessions.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + ) + assert_matches_type(SessionNewResponse, session, path=["response"]) + + @parametrize + def test_method_new_with_all_params(self, client: Finch) -> None: + session = client.connect.sessions.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + customer_email="dev@stainlessapi.com", + integration={ + "auth_method": "assisted", + "provider": "provider", + }, + manual=True, + minutes_to_expire=1, + redirect_uri="redirect_uri", + sandbox="finch", + ) + assert_matches_type(SessionNewResponse, session, path=["response"]) + + @parametrize + def test_raw_response_new(self, client: Finch) -> None: + response = client.connect.sessions.with_raw_response.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + session = response.parse() + assert_matches_type(SessionNewResponse, session, path=["response"]) + + @parametrize + def test_streaming_response_new(self, client: Finch) -> None: + with client.connect.sessions.with_streaming_response.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + session = response.parse() + assert_matches_type(SessionNewResponse, session, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + def test_method_reauthenticate(self, client: Finch) -> None: + session = client.connect.sessions.reauthenticate( + connection_id="connection_id", + ) + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + @parametrize + def test_method_reauthenticate_with_all_params(self, client: Finch) -> None: + session = client.connect.sessions.reauthenticate( + connection_id="connection_id", + minutes_to_expire=0, + products=["company", "directory", "individual"], + redirect_uri="https://example.com", + ) + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + @parametrize + def test_raw_response_reauthenticate(self, client: Finch) -> None: + response = client.connect.sessions.with_raw_response.reauthenticate( + connection_id="connection_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + session = response.parse() + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + @parametrize + def test_streaming_response_reauthenticate(self, client: Finch) -> None: + with client.connect.sessions.with_streaming_response.reauthenticate( + connection_id="connection_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + session = response.parse() + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncSessions: + parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) + + @parametrize + async def test_method_new(self, async_client: AsyncFinch) -> None: + session = await async_client.connect.sessions.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + ) + assert_matches_type(SessionNewResponse, session, path=["response"]) + + @parametrize + async def test_method_new_with_all_params(self, async_client: AsyncFinch) -> None: + session = await async_client.connect.sessions.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + customer_email="dev@stainlessapi.com", + integration={ + "auth_method": "assisted", + "provider": "provider", + }, + manual=True, + minutes_to_expire=1, + redirect_uri="redirect_uri", + sandbox="finch", + ) + assert_matches_type(SessionNewResponse, session, path=["response"]) + + @parametrize + async def test_raw_response_new(self, async_client: AsyncFinch) -> None: + response = await async_client.connect.sessions.with_raw_response.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + session = response.parse() + assert_matches_type(SessionNewResponse, session, path=["response"]) + + @parametrize + async def test_streaming_response_new(self, async_client: AsyncFinch) -> None: + async with async_client.connect.sessions.with_streaming_response.new( + customer_id="x", + customer_name="x", + products=["company", "directory", "individual"], + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + session = await response.parse() + assert_matches_type(SessionNewResponse, session, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @parametrize + async def test_method_reauthenticate(self, async_client: AsyncFinch) -> None: + session = await async_client.connect.sessions.reauthenticate( + connection_id="connection_id", + ) + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + @parametrize + async def test_method_reauthenticate_with_all_params(self, async_client: AsyncFinch) -> None: + session = await async_client.connect.sessions.reauthenticate( + connection_id="connection_id", + minutes_to_expire=0, + products=["company", "directory", "individual"], + redirect_uri="https://example.com", + ) + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + @parametrize + async def test_raw_response_reauthenticate(self, async_client: AsyncFinch) -> None: + response = await async_client.connect.sessions.with_raw_response.reauthenticate( + connection_id="connection_id", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + session = response.parse() + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + @parametrize + async def test_streaming_response_reauthenticate(self, async_client: AsyncFinch) -> None: + async with async_client.connect.sessions.with_streaming_response.reauthenticate( + connection_id="connection_id", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + session = await response.parse() + assert_matches_type(SessionReauthenticateResponse, session, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/sandbox/connections/test_accounts.py b/tests/api_resources/sandbox/connections/test_accounts.py index 1921e899..ad8027b1 100644 --- a/tests/api_resources/sandbox/connections/test_accounts.py +++ b/tests/api_resources/sandbox/connections/test_accounts.py @@ -20,7 +20,6 @@ class TestAccounts: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_method_create(self, client: Finch) -> None: account = client.sandbox.connections.accounts.create( @@ -29,7 +28,6 @@ def test_method_create(self, client: Finch) -> None: ) assert_matches_type(AccountCreateResponse, account, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_method_create_with_all_params(self, client: Finch) -> None: account = client.sandbox.connections.accounts.create( @@ -40,7 +38,6 @@ def test_method_create_with_all_params(self, client: Finch) -> None: ) assert_matches_type(AccountCreateResponse, account, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_raw_response_create(self, client: Finch) -> None: response = client.sandbox.connections.accounts.with_raw_response.create( @@ -53,7 +50,6 @@ def test_raw_response_create(self, client: Finch) -> None: account = response.parse() assert_matches_type(AccountCreateResponse, account, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_streaming_response_create(self, client: Finch) -> None: with client.sandbox.connections.accounts.with_streaming_response.create( @@ -104,7 +100,6 @@ def test_streaming_response_update(self, client: Finch) -> None: class TestAsyncAccounts: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_method_create(self, async_client: AsyncFinch) -> None: account = await async_client.sandbox.connections.accounts.create( @@ -113,7 +108,6 @@ async def test_method_create(self, async_client: AsyncFinch) -> None: ) assert_matches_type(AccountCreateResponse, account, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> None: account = await async_client.sandbox.connections.accounts.create( @@ -124,7 +118,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> ) assert_matches_type(AccountCreateResponse, account, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_raw_response_create(self, async_client: AsyncFinch) -> None: response = await async_client.sandbox.connections.accounts.with_raw_response.create( @@ -137,7 +130,6 @@ async def test_raw_response_create(self, async_client: AsyncFinch) -> None: account = response.parse() assert_matches_type(AccountCreateResponse, account, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_streaming_response_create(self, async_client: AsyncFinch) -> None: async with async_client.sandbox.connections.accounts.with_streaming_response.create( diff --git a/tests/api_resources/sandbox/test_connections.py b/tests/api_resources/sandbox/test_connections.py index 574747fb..97209c33 100644 --- a/tests/api_resources/sandbox/test_connections.py +++ b/tests/api_resources/sandbox/test_connections.py @@ -17,7 +17,6 @@ class TestConnections: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_method_create(self, client: Finch) -> None: connection = client.sandbox.connections.create( @@ -25,7 +24,6 @@ def test_method_create(self, client: Finch) -> None: ) assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_method_create_with_all_params(self, client: Finch) -> None: connection = client.sandbox.connections.create( @@ -36,7 +34,6 @@ def test_method_create_with_all_params(self, client: Finch) -> None: ) assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_raw_response_create(self, client: Finch) -> None: response = client.sandbox.connections.with_raw_response.create( @@ -48,7 +45,6 @@ def test_raw_response_create(self, client: Finch) -> None: connection = response.parse() assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize def test_streaming_response_create(self, client: Finch) -> None: with client.sandbox.connections.with_streaming_response.create( @@ -66,7 +62,6 @@ def test_streaming_response_create(self, client: Finch) -> None: class TestAsyncConnections: parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_method_create(self, async_client: AsyncFinch) -> None: connection = await async_client.sandbox.connections.create( @@ -74,7 +69,6 @@ async def test_method_create(self, async_client: AsyncFinch) -> None: ) assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> None: connection = await async_client.sandbox.connections.create( @@ -85,7 +79,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncFinch) -> ) assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_raw_response_create(self, async_client: AsyncFinch) -> None: response = await async_client.sandbox.connections.with_raw_response.create( @@ -97,7 +90,6 @@ async def test_raw_response_create(self, async_client: AsyncFinch) -> None: connection = response.parse() assert_matches_type(ConnectionCreateResponse, connection, path=["response"]) - @pytest.mark.skip(reason="Auth isn't setup correctly in this test") @parametrize async def test_streaming_response_create(self, async_client: AsyncFinch) -> None: async with async_client.sandbox.connections.with_streaming_response.create( diff --git a/tests/api_resources/sandbox/test_employment.py b/tests/api_resources/sandbox/test_employment.py index 474c85bd..9d816162 100644 --- a/tests/api_resources/sandbox/test_employment.py +++ b/tests/api_resources/sandbox/test_employment.py @@ -78,6 +78,7 @@ def test_method_update_with_all_params(self, client: Finch) -> None: ], is_active=True, last_name="last_name", + latest_rehire_date="latest_rehire_date", location={ "city": "city", "country": "country", @@ -192,6 +193,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncFinch) -> ], is_active=True, last_name="last_name", + latest_rehire_date="latest_rehire_date", location={ "city": "city", "country": "country", diff --git a/tests/api_resources/test_access_tokens.py b/tests/api_resources/test_access_tokens.py index a4c24782..5eb9ae14 100644 --- a/tests/api_resources/test_access_tokens.py +++ b/tests/api_resources/test_access_tokens.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import Any, cast +from typing import TYPE_CHECKING, Any, Iterator, AsyncIterator, cast import pytest @@ -11,7 +11,36 @@ from finch.types import CreateAccessTokenResponse from tests.utils import assert_matches_type +if TYPE_CHECKING: + from _pytest.fixtures import FixtureRequest + base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +client_id = "00000000-0000-0000-0000-000000000000" +client_secret = "TEST" + + +@pytest.fixture(scope="module") +def client(request: FixtureRequest) -> Iterator[Finch]: + strict = getattr(request, "param", True) + if not isinstance(strict, bool): + raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") + + with Finch( + base_url=base_url, client_id=client_id, client_secret=client_secret, _strict_response_validation=strict + ) as client: + yield client + + +@pytest.fixture(scope="module") +async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncFinch]: + strict = getattr(request, "param", True) + if not isinstance(strict, bool): + raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") + + async with AsyncFinch( + base_url=base_url, client_id=client_id, client_secret=client_secret, _strict_response_validation=strict + ) as client: + yield client class TestAccessTokens: diff --git a/tests/conftest.py b/tests/conftest.py index 6ba51ce7..2c791d06 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,8 +27,6 @@ def event_loop() -> Iterator[asyncio.AbstractEventLoop]: base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") access_token = "My Access Token" -client_id = "4ab15e51-11ad-49f4-acae-f343b7794375" -client_secret = "My Client Secret" @pytest.fixture(scope="session") @@ -37,13 +35,7 @@ def client(request: FixtureRequest) -> Iterator[Finch]: if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") - with Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=strict, - ) as client: + with Finch(base_url=base_url, access_token=access_token, _strict_response_validation=strict) as client: yield client @@ -53,11 +45,5 @@ async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncFinch]: if not isinstance(strict, bool): raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}") - async with AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=strict, - ) as client: + async with AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=strict) as client: yield client diff --git a/tests/test_client.py b/tests/test_client.py index 8c43932a..7c5deac3 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -26,8 +26,6 @@ base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") access_token = "My Access Token" -client_id = "4ab15e51-11ad-49f4-acae-f343b7794375" -client_secret = "My Client Secret" def _get_params(client: BaseClient[Any, Any]) -> dict[str, str]: @@ -41,13 +39,7 @@ def _low_retry_timeout(*_args: Any, **_kwargs: Any) -> float: class TestFinch: - client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) def test_raw_response(self, respx_mock: MockRouter) -> None: @@ -77,14 +69,6 @@ def test_copy(self) -> None: assert copied.access_token == "another My Access Token" assert self.client.access_token == "My Access Token" - copied = self.client.copy(client_id="another 4ab15e51-11ad-49f4-acae-f343b7794375") - assert copied.client_id == "another 4ab15e51-11ad-49f4-acae-f343b7794375" - assert self.client.client_id == "4ab15e51-11ad-49f4-acae-f343b7794375" - - copied = self.client.copy(client_secret="another My Client Secret") - assert copied.client_secret == "another My Client Secret" - assert self.client.client_secret == "My Client Secret" - def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) @@ -105,8 +89,6 @@ def test_copy_default_headers(self) -> None: client = Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_headers={"X-Foo": "bar"}, ) @@ -142,12 +124,7 @@ def test_copy_default_headers(self) -> None: def test_copy_default_query(self) -> None: client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - default_query={"foo": "bar"}, + base_url=base_url, access_token=access_token, _strict_response_validation=True, default_query={"foo": "bar"} ) assert _get_params(client)["foo"] == "bar" @@ -272,12 +249,7 @@ def test_request_timeout(self) -> None: def test_client_timeout_option(self) -> None: client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - timeout=httpx.Timeout(0), + base_url=base_url, access_token=access_token, _strict_response_validation=True, timeout=httpx.Timeout(0) ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -288,12 +260,7 @@ def test_http_client_timeout_option(self) -> None: # custom timeout given to the httpx client should be used with httpx.Client(timeout=None) as http_client: client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - http_client=http_client, + base_url=base_url, access_token=access_token, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -303,12 +270,7 @@ def test_http_client_timeout_option(self) -> None: # no timeout given to the httpx client should not use the httpx default with httpx.Client() as http_client: client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - http_client=http_client, + base_url=base_url, access_token=access_token, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -318,12 +280,7 @@ def test_http_client_timeout_option(self) -> None: # explicitly passing the default timeout currently results in it being ignored with httpx.Client(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client: client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - http_client=http_client, + base_url=base_url, access_token=access_token, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -336,8 +293,6 @@ async def test_invalid_http_client(self) -> None: Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=cast(Any, http_client), ) @@ -346,8 +301,6 @@ def test_default_headers_option(self) -> None: client = Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_headers={"X-Foo": "bar"}, ) @@ -358,8 +311,6 @@ def test_default_headers_option(self) -> None: client2 = Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_headers={ "X-Foo": "stainless", @@ -371,27 +322,15 @@ def test_default_headers_option(self) -> None: assert request.headers.get("x-stainless-lang") == "my-overriding-header" def test_validate_headers(self) -> None: - client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("Authorization") == f"Bearer {access_token}" - client2 = Finch( - base_url=base_url, - access_token=None, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client2 = Finch(base_url=base_url, access_token=None, _strict_response_validation=True) with pytest.raises( TypeError, - match="Could not resolve authentication method. Expected either access_token, sandbox_client_id or sandbox_client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted", + match="Could not resolve authentication method. Expected either access_token, client_id or client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted", ): client2._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -404,8 +343,6 @@ def test_default_query_option(self) -> None: client = Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_query={"query_param": "bar"}, ) @@ -608,11 +545,7 @@ class Model(BaseModel): def test_base_url_setter(self) -> None: client = Finch( - base_url="https://example.com/from_init", - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, + base_url="https://example.com/from_init", access_token=access_token, _strict_response_validation=True ) assert client.base_url == "https://example.com/from_init/" @@ -622,12 +555,7 @@ def test_base_url_setter(self) -> None: def test_base_url_env(self) -> None: with update_env(FINCH_BASE_URL="http://localhost:5000/from/env"): - client = Finch( - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = Finch(access_token=access_token, _strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" @pytest.mark.parametrize( @@ -636,15 +564,11 @@ def test_base_url_env(self) -> None: Finch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, ), Finch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=httpx.Client(), ), @@ -667,15 +591,11 @@ def test_base_url_trailing_slash(self, client: Finch) -> None: Finch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, ), Finch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=httpx.Client(), ), @@ -698,15 +618,11 @@ def test_base_url_no_trailing_slash(self, client: Finch) -> None: Finch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, ), Finch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=httpx.Client(), ), @@ -733,12 +649,7 @@ def test_transport_option_is_deprecated(self) -> None: ) client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - transport=transport, + base_url=base_url, access_token=access_token, _strict_response_validation=True, transport=transport ) assert client._client._transport is transport @@ -750,8 +661,6 @@ def test_transport_option_mutually_exclusive_with_http_client(self) -> None: Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, transport=httpx.MockTransport( lambda: None, # type: ignore @@ -771,8 +680,6 @@ def test_connection_pool_limits_option_is_deprecated(self) -> None: client = Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, connection_pool_limits=connection_pool_limits, ) @@ -791,8 +698,6 @@ def test_connection_pool_limits_option_mutually_exclusive_with_http_client(self) Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, connection_pool_limits=httpx.Limits( max_connections=101, max_keepalive_connections=76, keepalive_expiry=23 @@ -808,12 +713,7 @@ def test_proxies_option_is_deprecated(self) -> None: proxies = "https://www.example.com/proxy" client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - proxies=proxies, + base_url=base_url, access_token=access_token, _strict_response_validation=True, proxies=proxies ) mounts = list(client._client._mounts.keys()) @@ -829,21 +729,13 @@ def test_proxies_option_mutually_exclusive_with_http_client(self) -> None: Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, proxies="https://www.example.com/proxy", http_client=http_client, ) def test_copied_client_does_not_close_http(self) -> None: - client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() @@ -854,13 +746,7 @@ def test_copied_client_does_not_close_http(self) -> None: assert not client.is_closed() def test_client_context_manager(self) -> None: - client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) with client as c2: assert c2 is client assert not c2.is_closed() @@ -884,8 +770,6 @@ def test_client_max_retries_validation(self) -> None: Finch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, max_retries=cast(Any, None), ) @@ -897,24 +781,12 @@ class Model(BaseModel): respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) - strict_client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): strict_client.get("/foo", cast_to=Model) - client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=False, - ) + client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False) response = client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @@ -941,13 +813,7 @@ class Model(BaseModel): ) @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None: - client = Finch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) @@ -974,6 +840,51 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: response = client.hris.directory.with_raw_response.list() assert response.retries_taken == failures_before_success + assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success + + @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) + @mock.patch("finch._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) + @pytest.mark.respx(base_url=base_url) + def test_omit_retry_count_header(self, client: Finch, failures_before_success: int, respx_mock: MockRouter) -> None: + client = client.with_options(max_retries=4) + + nb_retries = 0 + + def retry_handler(_request: httpx.Request) -> httpx.Response: + nonlocal nb_retries + if nb_retries < failures_before_success: + nb_retries += 1 + return httpx.Response(500) + return httpx.Response(200) + + respx_mock.get("/employer/directory").mock(side_effect=retry_handler) + + response = client.hris.directory.with_raw_response.list(extra_headers={"x-stainless-retry-count": Omit()}) + + assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 + + @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) + @mock.patch("finch._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) + @pytest.mark.respx(base_url=base_url) + def test_overwrite_retry_count_header( + self, client: Finch, failures_before_success: int, respx_mock: MockRouter + ) -> None: + client = client.with_options(max_retries=4) + + nb_retries = 0 + + def retry_handler(_request: httpx.Request) -> httpx.Response: + nonlocal nb_retries + if nb_retries < failures_before_success: + nb_retries += 1 + return httpx.Response(500) + return httpx.Response(200) + + respx_mock.get("/employer/directory").mock(side_effect=retry_handler) + + response = client.hris.directory.with_raw_response.list(extra_headers={"x-stainless-retry-count": "42"}) + + assert response.http_request.headers.get("x-stainless-retry-count") == "42" @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("finch._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @@ -996,16 +907,11 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: with client.hris.directory.with_streaming_response.list() as response: assert response.retries_taken == failures_before_success + assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success class TestAsyncFinch: - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) @pytest.mark.respx(base_url=base_url) @pytest.mark.asyncio @@ -1037,14 +943,6 @@ def test_copy(self) -> None: assert copied.access_token == "another My Access Token" assert self.client.access_token == "My Access Token" - copied = self.client.copy(client_id="another 4ab15e51-11ad-49f4-acae-f343b7794375") - assert copied.client_id == "another 4ab15e51-11ad-49f4-acae-f343b7794375" - assert self.client.client_id == "4ab15e51-11ad-49f4-acae-f343b7794375" - - copied = self.client.copy(client_secret="another My Client Secret") - assert copied.client_secret == "another My Client Secret" - assert self.client.client_secret == "My Client Secret" - def test_copy_default_options(self) -> None: # options that have a default are overridden correctly copied = self.client.copy(max_retries=7) @@ -1065,8 +963,6 @@ def test_copy_default_headers(self) -> None: client = AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_headers={"X-Foo": "bar"}, ) @@ -1102,12 +998,7 @@ def test_copy_default_headers(self) -> None: def test_copy_default_query(self) -> None: client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - default_query={"foo": "bar"}, + base_url=base_url, access_token=access_token, _strict_response_validation=True, default_query={"foo": "bar"} ) assert _get_params(client)["foo"] == "bar" @@ -1232,12 +1123,7 @@ async def test_request_timeout(self) -> None: async def test_client_timeout_option(self) -> None: client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - timeout=httpx.Timeout(0), + base_url=base_url, access_token=access_token, _strict_response_validation=True, timeout=httpx.Timeout(0) ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -1248,12 +1134,7 @@ async def test_http_client_timeout_option(self) -> None: # custom timeout given to the httpx client should be used async with httpx.AsyncClient(timeout=None) as http_client: client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - http_client=http_client, + base_url=base_url, access_token=access_token, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -1263,12 +1144,7 @@ async def test_http_client_timeout_option(self) -> None: # no timeout given to the httpx client should not use the httpx default async with httpx.AsyncClient() as http_client: client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - http_client=http_client, + base_url=base_url, access_token=access_token, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -1278,12 +1154,7 @@ async def test_http_client_timeout_option(self) -> None: # explicitly passing the default timeout currently results in it being ignored async with httpx.AsyncClient(timeout=HTTPX_DEFAULT_TIMEOUT) as http_client: client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - http_client=http_client, + base_url=base_url, access_token=access_token, _strict_response_validation=True, http_client=http_client ) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -1296,8 +1167,6 @@ def test_invalid_http_client(self) -> None: AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=cast(Any, http_client), ) @@ -1306,8 +1175,6 @@ def test_default_headers_option(self) -> None: client = AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_headers={"X-Foo": "bar"}, ) @@ -1318,8 +1185,6 @@ def test_default_headers_option(self) -> None: client2 = AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_headers={ "X-Foo": "stainless", @@ -1331,27 +1196,15 @@ def test_default_headers_option(self) -> None: assert request.headers.get("x-stainless-lang") == "my-overriding-header" def test_validate_headers(self) -> None: - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) request = client._build_request(FinalRequestOptions(method="get", url="/foo")) assert request.headers.get("Authorization") == f"Bearer {access_token}" - client2 = AsyncFinch( - base_url=base_url, - access_token=None, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client2 = AsyncFinch(base_url=base_url, access_token=None, _strict_response_validation=True) with pytest.raises( TypeError, - match="Could not resolve authentication method. Expected either access_token, sandbox_client_id or sandbox_client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted", + match="Could not resolve authentication method. Expected either access_token, client_id or client_secret to be set. Or for one of the `Authorization` or `Authorization` headers to be explicitly omitted", ): client2._build_request(FinalRequestOptions(method="get", url="/foo")) @@ -1364,8 +1217,6 @@ def test_default_query_option(self) -> None: client = AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, default_query={"query_param": "bar"}, ) @@ -1568,11 +1419,7 @@ class Model(BaseModel): def test_base_url_setter(self) -> None: client = AsyncFinch( - base_url="https://example.com/from_init", - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, + base_url="https://example.com/from_init", access_token=access_token, _strict_response_validation=True ) assert client.base_url == "https://example.com/from_init/" @@ -1582,12 +1429,7 @@ def test_base_url_setter(self) -> None: def test_base_url_env(self) -> None: with update_env(FINCH_BASE_URL="http://localhost:5000/from/env"): - client = AsyncFinch( - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = AsyncFinch(access_token=access_token, _strict_response_validation=True) assert client.base_url == "http://localhost:5000/from/env/" @pytest.mark.parametrize( @@ -1596,15 +1438,11 @@ def test_base_url_env(self) -> None: AsyncFinch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, ), AsyncFinch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), @@ -1627,15 +1465,11 @@ def test_base_url_trailing_slash(self, client: AsyncFinch) -> None: AsyncFinch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, ), AsyncFinch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), @@ -1658,15 +1492,11 @@ def test_base_url_no_trailing_slash(self, client: AsyncFinch) -> None: AsyncFinch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, ), AsyncFinch( base_url="http://localhost:5000/custom/path/", access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, http_client=httpx.AsyncClient(), ), @@ -1693,12 +1523,7 @@ def test_transport_option_is_deprecated(self) -> None: ) client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - transport=transport, + base_url=base_url, access_token=access_token, _strict_response_validation=True, transport=transport ) assert client._client._transport is transport @@ -1710,8 +1535,6 @@ async def test_transport_option_mutually_exclusive_with_http_client(self) -> Non AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, transport=httpx.MockTransport( lambda: None, # type: ignore @@ -1731,8 +1554,6 @@ def test_connection_pool_limits_option_is_deprecated(self) -> None: client = AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, connection_pool_limits=connection_pool_limits, ) @@ -1751,8 +1572,6 @@ async def test_connection_pool_limits_option_mutually_exclusive_with_http_client AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, connection_pool_limits=httpx.Limits( max_connections=101, max_keepalive_connections=76, keepalive_expiry=23 @@ -1768,12 +1587,7 @@ def test_proxies_option_is_deprecated(self) -> None: proxies = "https://www.example.com/proxy" client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - proxies=proxies, + base_url=base_url, access_token=access_token, _strict_response_validation=True, proxies=proxies ) mounts = list(client._client._mounts.keys()) @@ -1789,21 +1603,13 @@ async def test_proxies_option_mutually_exclusive_with_http_client(self) -> None: AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, proxies="https://www.example.com/proxy", http_client=http_client, ) async def test_copied_client_does_not_close_http(self) -> None: - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) assert not client.is_closed() copied = client.copy() @@ -1815,13 +1621,7 @@ async def test_copied_client_does_not_close_http(self) -> None: assert not client.is_closed() async def test_client_context_manager(self) -> None: - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) async with client as c2: assert c2 is client assert not c2.is_closed() @@ -1846,8 +1646,6 @@ async def test_client_max_retries_validation(self) -> None: AsyncFinch( base_url=base_url, access_token=access_token, - client_id=client_id, - client_secret=client_secret, _strict_response_validation=True, max_retries=cast(Any, None), ) @@ -1860,24 +1658,12 @@ class Model(BaseModel): respx_mock.get("/foo").mock(return_value=httpx.Response(200, text="my-custom-format")) - strict_client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) with pytest.raises(APIResponseValidationError): await strict_client.get("/foo", cast_to=Model) - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=False, - ) + client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False) response = await client.get("/foo", cast_to=Model) assert isinstance(response, str) # type: ignore[unreachable] @@ -1905,13 +1691,7 @@ class Model(BaseModel): @mock.patch("time.time", mock.MagicMock(return_value=1696004797)) @pytest.mark.asyncio async def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str, timeout: float) -> None: - client = AsyncFinch( - base_url=base_url, - access_token=access_token, - client_id=client_id, - client_secret=client_secret, - _strict_response_validation=True, - ) + client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True) headers = httpx.Headers({"retry-after": retry_after}) options = FinalRequestOptions(method="get", url="/foo", max_retries=3) @@ -1941,6 +1721,55 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: response = await client.hris.directory.with_raw_response.list() assert response.retries_taken == failures_before_success + assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success + + @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) + @mock.patch("finch._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) + @pytest.mark.respx(base_url=base_url) + @pytest.mark.asyncio + async def test_omit_retry_count_header( + self, async_client: AsyncFinch, failures_before_success: int, respx_mock: MockRouter + ) -> None: + client = async_client.with_options(max_retries=4) + + nb_retries = 0 + + def retry_handler(_request: httpx.Request) -> httpx.Response: + nonlocal nb_retries + if nb_retries < failures_before_success: + nb_retries += 1 + return httpx.Response(500) + return httpx.Response(200) + + respx_mock.get("/employer/directory").mock(side_effect=retry_handler) + + response = await client.hris.directory.with_raw_response.list(extra_headers={"x-stainless-retry-count": Omit()}) + + assert len(response.http_request.headers.get_list("x-stainless-retry-count")) == 0 + + @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) + @mock.patch("finch._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) + @pytest.mark.respx(base_url=base_url) + @pytest.mark.asyncio + async def test_overwrite_retry_count_header( + self, async_client: AsyncFinch, failures_before_success: int, respx_mock: MockRouter + ) -> None: + client = async_client.with_options(max_retries=4) + + nb_retries = 0 + + def retry_handler(_request: httpx.Request) -> httpx.Response: + nonlocal nb_retries + if nb_retries < failures_before_success: + nb_retries += 1 + return httpx.Response(500) + return httpx.Response(200) + + respx_mock.get("/employer/directory").mock(side_effect=retry_handler) + + response = await client.hris.directory.with_raw_response.list(extra_headers={"x-stainless-retry-count": "42"}) + + assert response.http_request.headers.get("x-stainless-retry-count") == "42" @pytest.mark.parametrize("failures_before_success", [0, 2, 4]) @mock.patch("finch._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout) @@ -1964,3 +1793,4 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: async with client.hris.directory.with_streaming_response.list() as response: assert response.retries_taken == failures_before_success + assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success