diff --git a/.stats.yml b/.stats.yml
index c125dfb2..e16f1ad2 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 23
+configured_endpoints: 24
diff --git a/api.md b/api.md
index 6207a701..b920447c 100644
--- a/api.md
+++ b/api.md
@@ -10,6 +10,19 @@ Methods:
- client.get_access_token(\*args) -> str
- client.get_auth_url(\*args) -> str
+- client.with_access_token(\*args) -> Self
+
+# AccessTokens
+
+Types:
+
+```python
+from finch.types import CreateAccessTokenResponse
+```
+
+Methods:
+
+- client.access_tokens.create(\*\*params) -> CreateAccessTokenResponse
# HRIS
diff --git a/src/finch/_client.py b/src/finch/_client.py
index f11a51ed..d6e88d57 100644
--- a/src/finch/_client.py
+++ b/src/finch/_client.py
@@ -51,6 +51,7 @@
class Finch(SyncAPIClient):
+ access_tokens: resources.AccessTokens
hris: resources.HRIS
providers: resources.Providers
account: resources.Account
@@ -135,6 +136,7 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
+ self.access_tokens = resources.AccessTokens(self)
self.hris = resources.HRIS(self)
self.providers = resources.Providers(self)
self.account = resources.Account(self)
@@ -311,6 +313,16 @@ def get_auth_url(
)
)
+ def with_access_token(
+ self,
+ access_token: str,
+ ) -> Self:
+ """
+ Returns a copy of the current Finch client with the given access token for
+ authentication.
+ """
+ return self.with_options(access_token=access_token)
+
@override
def _make_status_error(
self,
@@ -346,6 +358,7 @@ def _make_status_error(
class AsyncFinch(AsyncAPIClient):
+ access_tokens: resources.AsyncAccessTokens
hris: resources.AsyncHRIS
providers: resources.AsyncProviders
account: resources.AsyncAccount
@@ -430,6 +443,7 @@ def __init__(
_strict_response_validation=_strict_response_validation,
)
+ self.access_tokens = resources.AsyncAccessTokens(self)
self.hris = resources.AsyncHRIS(self)
self.providers = resources.AsyncProviders(self)
self.account = resources.AsyncAccount(self)
@@ -606,6 +620,16 @@ def get_auth_url(
)
)
+ def with_access_token(
+ self,
+ access_token: str,
+ ) -> Self:
+ """
+ Returns a copy of the current Finch client with the given access token for
+ authentication.
+ """
+ return self.with_options(access_token=access_token)
+
@override
def _make_status_error(
self,
@@ -642,6 +666,7 @@ def _make_status_error(
class FinchWithRawResponse:
def __init__(self, client: Finch) -> None:
+ self.access_tokens = resources.AccessTokensWithRawResponse(client.access_tokens)
self.hris = resources.HRISWithRawResponse(client.hris)
self.providers = resources.ProvidersWithRawResponse(client.providers)
self.account = resources.AccountWithRawResponse(client.account)
@@ -651,6 +676,7 @@ def __init__(self, client: Finch) -> None:
class AsyncFinchWithRawResponse:
def __init__(self, client: AsyncFinch) -> None:
+ self.access_tokens = resources.AsyncAccessTokensWithRawResponse(client.access_tokens)
self.hris = resources.AsyncHRISWithRawResponse(client.hris)
self.providers = resources.AsyncProvidersWithRawResponse(client.providers)
self.account = resources.AsyncAccountWithRawResponse(client.account)
diff --git a/src/finch/resources/__init__.py b/src/finch/resources/__init__.py
index 32d0cf28..152e5776 100644
--- a/src/finch/resources/__init__.py
+++ b/src/finch/resources/__init__.py
@@ -5,6 +5,12 @@
from .account import Account, AsyncAccount, AccountWithRawResponse, AsyncAccountWithRawResponse
from .webhooks import Webhooks, AsyncWebhooks
from .providers import Providers, AsyncProviders, ProvidersWithRawResponse, AsyncProvidersWithRawResponse
+from .access_tokens import (
+ AccessTokens,
+ AsyncAccessTokens,
+ AccessTokensWithRawResponse,
+ AsyncAccessTokensWithRawResponse,
+)
from .request_forwarding import (
RequestForwarding,
AsyncRequestForwarding,
@@ -13,6 +19,10 @@
)
__all__ = [
+ "AccessTokens",
+ "AsyncAccessTokens",
+ "AccessTokensWithRawResponse",
+ "AsyncAccessTokensWithRawResponse",
"HRIS",
"AsyncHRIS",
"HRISWithRawResponse",
diff --git a/src/finch/resources/access_tokens.py b/src/finch/resources/access_tokens.py
new file mode 100644
index 00000000..161da255
--- /dev/null
+++ b/src/finch/resources/access_tokens.py
@@ -0,0 +1,129 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import httpx
+
+from ..types import CreateAccessTokenResponse, access_token_create_params
+from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from .._utils import maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from .._base_client import (
+ make_request_options,
+)
+
+__all__ = ["AccessTokens", "AsyncAccessTokens"]
+
+
+class AccessTokens(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AccessTokensWithRawResponse:
+ return AccessTokensWithRawResponse(self)
+
+ def create(
+ self,
+ *,
+ client_id: str,
+ client_secret: str,
+ code: str,
+ redirect_uri: str,
+ # 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,
+ ) -> CreateAccessTokenResponse:
+ """
+ Exchange the authorization code for an access token
+
+ Args:
+ 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(
+ "/auth/token",
+ body=maybe_transform(
+ {
+ "client_id": client_id,
+ "client_secret": client_secret,
+ "code": code,
+ "redirect_uri": redirect_uri,
+ },
+ access_token_create_params.AccessTokenCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CreateAccessTokenResponse,
+ )
+
+
+class AsyncAccessTokens(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAccessTokensWithRawResponse:
+ return AsyncAccessTokensWithRawResponse(self)
+
+ async def create(
+ self,
+ *,
+ client_id: str,
+ client_secret: str,
+ code: str,
+ redirect_uri: str,
+ # 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,
+ ) -> CreateAccessTokenResponse:
+ """
+ Exchange the authorization code for an access token
+
+ Args:
+ 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(
+ "/auth/token",
+ body=maybe_transform(
+ {
+ "client_id": client_id,
+ "client_secret": client_secret,
+ "code": code,
+ "redirect_uri": redirect_uri,
+ },
+ access_token_create_params.AccessTokenCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CreateAccessTokenResponse,
+ )
+
+
+class AccessTokensWithRawResponse:
+ def __init__(self, access_tokens: AccessTokens) -> None:
+ self.create = to_raw_response_wrapper(
+ access_tokens.create,
+ )
+
+
+class AsyncAccessTokensWithRawResponse:
+ def __init__(self, access_tokens: AsyncAccessTokens) -> None:
+ self.create = async_to_raw_response_wrapper(
+ access_tokens.create,
+ )
diff --git a/src/finch/types/__init__.py b/src/finch/types/__init__.py
index ece2573d..e8b6a6dd 100644
--- a/src/finch/types/__init__.py
+++ b/src/finch/types/__init__.py
@@ -13,5 +13,7 @@
from .provider import Provider as Provider
from .introspection import Introspection as Introspection
from .disconnect_response import DisconnectResponse as DisconnectResponse
+from .access_token_create_params import AccessTokenCreateParams as AccessTokenCreateParams
+from .create_access_token_response import CreateAccessTokenResponse as CreateAccessTokenResponse
from .request_forwarding_forward_params import RequestForwardingForwardParams as RequestForwardingForwardParams
from .request_forwarding_forward_response import RequestForwardingForwardResponse as RequestForwardingForwardResponse
diff --git a/src/finch/types/access_token_create_params.py b/src/finch/types/access_token_create_params.py
new file mode 100644
index 00000000..2fc25749
--- /dev/null
+++ b/src/finch/types/access_token_create_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AccessTokenCreateParams"]
+
+
+class AccessTokenCreateParams(TypedDict, total=False):
+ client_id: Required[str]
+
+ client_secret: Required[str]
+
+ code: Required[str]
+
+ redirect_uri: Required[str]
diff --git a/src/finch/types/create_access_token_response.py b/src/finch/types/create_access_token_response.py
new file mode 100644
index 00000000..5b017fc2
--- /dev/null
+++ b/src/finch/types/create_access_token_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from .._models import BaseModel
+
+__all__ = ["CreateAccessTokenResponse"]
+
+
+class CreateAccessTokenResponse(BaseModel):
+ access_token: str
diff --git a/tests/api_resources/test_access_tokens.py b/tests/api_resources/test_access_tokens.py
new file mode 100644
index 00000000..4a89d515
--- /dev/null
+++ b/tests/api_resources/test_access_tokens.py
@@ -0,0 +1,71 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from finch.types import CreateAccessTokenResponse
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestAccessTokens:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create(self, client: Finch) -> None:
+ access_token = client.access_tokens.create(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert_matches_type(CreateAccessTokenResponse, access_token, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Finch) -> None:
+ response = client.access_tokens.with_raw_response.create(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ access_token = response.parse()
+ assert_matches_type(CreateAccessTokenResponse, access_token, path=["response"])
+
+
+class TestAsyncAccessTokens:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create(self, client: AsyncFinch) -> None:
+ access_token = await client.access_tokens.create(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert_matches_type(CreateAccessTokenResponse, access_token, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, client: AsyncFinch) -> None:
+ response = await client.access_tokens.with_raw_response.create(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ access_token = response.parse()
+ assert_matches_type(CreateAccessTokenResponse, access_token, path=["response"])