diff --git a/README.md b/README.md index 6b330f26..605cb23f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ The full API of this library can be found in [api.md](https://www.github.com/Fin from finch import Finch client = Finch( - access_token="my access token", + access_token="My Access Token", ) page = client.hris.directory.list( @@ -42,7 +42,7 @@ Simply import `AsyncFinch` instead of `Finch` and use `await` with each API call from finch import AsyncFinch client = AsyncFinch( - access_token="my access token", + access_token="My Access Token", ) diff --git a/src/finch/_base_client.py b/src/finch/_base_client.py index 1ef2efa0..e72ead11 100644 --- a/src/finch/_base_client.py +++ b/src/finch/_base_client.py @@ -811,7 +811,10 @@ def close(self) -> None: The client will *not* be usable after this. """ - self._client.close() + # If an error is thrown while constructing a client, self._client + # may not be present + if hasattr(self, "_client"): + self._client.close() def __enter__(self: _T) -> _T: return self diff --git a/src/finch/_client.py b/src/finch/_client.py index 864333ee..80eaa1b4 100644 --- a/src/finch/_client.py +++ b/src/finch/_client.py @@ -62,11 +62,11 @@ class Finch(SyncAPIClient): def __init__( self, *, - client_id: str | None = None, - client_secret: str | None = None, - webhook_secret: str | None = None, + access_token: str | None = None, + client_id: str | None = os.environ.get("FINCH_CLIENT_ID", None), + client_secret: str | None = os.environ.get("FINCH_CLIENT_SECRET", None), + webhook_secret: str | None = os.environ.get("FINCH_WEBHOOK_SECRET", None), base_url: Optional[str] = None, - access_token: Optional[str] = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, @@ -98,14 +98,11 @@ def __init__( """ self.access_token = access_token - client_id_envvar = os.environ.get("FINCH_CLIENT_ID", None) - self.client_id = client_id or client_id_envvar or None + self.client_id = client_id - client_secret_envvar = os.environ.get("FINCH_CLIENT_SECRET", None) - self.client_secret = client_secret or client_secret_envvar or None + self.client_secret = client_secret - webhook_secret_envvar = os.environ.get("FINCH_WEBHOOK_SECRET", None) - self.webhook_secret = webhook_secret or webhook_secret_envvar or None + self.webhook_secret = webhook_secret if base_url is None: base_url = f"https://api.tryfinch.com" @@ -162,10 +159,10 @@ def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: def copy( self, *, + access_token: str | None = None, client_id: str | None = None, client_secret: str | None = None, webhook_secret: str | None = None, - access_token: str | None = None, base_url: str | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.Client | None = None, @@ -219,11 +216,11 @@ def copy( http_client = http_client or self._client return self.__class__( + access_token=access_token or self.access_token, client_id=client_id or self.client_id, client_secret=client_secret or self.client_secret, webhook_secret=webhook_secret or self.webhook_secret, base_url=base_url or str(self.base_url), - access_token=access_token or self.access_token, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, connection_pool_limits=connection_pool_limits, @@ -354,11 +351,11 @@ class AsyncFinch(AsyncAPIClient): def __init__( self, *, - client_id: str | None = None, - client_secret: str | None = None, - webhook_secret: str | None = None, + access_token: str | None = None, + client_id: str | None = os.environ.get("FINCH_CLIENT_ID", None), + client_secret: str | None = os.environ.get("FINCH_CLIENT_SECRET", None), + webhook_secret: str | None = os.environ.get("FINCH_WEBHOOK_SECRET", None), base_url: Optional[str] = None, - access_token: Optional[str] = None, timeout: Union[float, Timeout, None, NotGiven] = NOT_GIVEN, max_retries: int = DEFAULT_MAX_RETRIES, default_headers: Mapping[str, str] | None = None, @@ -390,14 +387,11 @@ def __init__( """ self.access_token = access_token - client_id_envvar = os.environ.get("FINCH_CLIENT_ID", None) - self.client_id = client_id or client_id_envvar or None + self.client_id = client_id - client_secret_envvar = os.environ.get("FINCH_CLIENT_SECRET", None) - self.client_secret = client_secret or client_secret_envvar or None + self.client_secret = client_secret - webhook_secret_envvar = os.environ.get("FINCH_WEBHOOK_SECRET", None) - self.webhook_secret = webhook_secret or webhook_secret_envvar or None + self.webhook_secret = webhook_secret if base_url is None: base_url = f"https://api.tryfinch.com" @@ -454,10 +448,10 @@ def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None: def copy( self, *, + access_token: str | None = None, client_id: str | None = None, client_secret: str | None = None, webhook_secret: str | None = None, - access_token: str | None = None, base_url: str | None = None, timeout: float | Timeout | None | NotGiven = NOT_GIVEN, http_client: httpx.AsyncClient | None = None, @@ -511,11 +505,11 @@ def copy( http_client = http_client or self._client return self.__class__( + access_token=access_token or self.access_token, client_id=client_id or self.client_id, client_secret=client_secret or self.client_secret, webhook_secret=webhook_secret or self.webhook_secret, base_url=base_url or str(self.base_url), - access_token=access_token or self.access_token, timeout=self.timeout if isinstance(timeout, NotGiven) else timeout, http_client=http_client, connection_pool_limits=connection_pool_limits, diff --git a/src/finch/_utils/__init__.py b/src/finch/_utils/__init__.py index 679193bd..6d13a362 100644 --- a/src/finch/_utils/__init__.py +++ b/src/finch/_utils/__init__.py @@ -21,6 +21,9 @@ from ._utils import extract_type_arg as extract_type_arg from ._utils import is_required_type as is_required_type from ._utils import is_annotated_type as is_annotated_type +from ._utils import maybe_coerce_float as maybe_coerce_float +from ._utils import maybe_coerce_boolean as maybe_coerce_boolean +from ._utils import maybe_coerce_integer as maybe_coerce_integer from ._utils import strip_annotated_type as strip_annotated_type from ._transform import PropertyInfo as PropertyInfo from ._transform import transform as transform diff --git a/src/finch/_utils/_utils.py b/src/finch/_utils/_utils.py index 603f7c10..e43ef6f8 100644 --- a/src/finch/_utils/_utils.py +++ b/src/finch/_utils/_utils.py @@ -309,6 +309,24 @@ def coerce_boolean(val: str) -> bool: return val == "true" or val == "1" or val == "on" +def maybe_coerce_integer(val: str | None) -> int | None: + if val is None: + return None + return coerce_integer(val) + + +def maybe_coerce_float(val: str | None) -> float | None: + if val is None: + return None + return coerce_float(val) + + +def maybe_coerce_boolean(val: str | None) -> bool | None: + if val is None: + return None + return coerce_boolean(val) + + def removeprefix(string: str, prefix: str) -> str: """Remove a prefix from a string. diff --git a/tests/api_resources/hris/benefits/test_individuals.py b/tests/api_resources/hris/benefits/test_individuals.py index bc2fa85d..2d37e28f 100644 --- a/tests/api_resources/hris/benefits/test_individuals.py +++ b/tests/api_resources/hris/benefits/test_individuals.py @@ -17,7 +17,7 @@ ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestIndividuals: diff --git a/tests/api_resources/hris/test_benefits.py b/tests/api_resources/hris/test_benefits.py index 5b378abd..3d464f66 100644 --- a/tests/api_resources/hris/test_benefits.py +++ b/tests/api_resources/hris/test_benefits.py @@ -17,7 +17,7 @@ ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestBenefits: diff --git a/tests/api_resources/hris/test_company.py b/tests/api_resources/hris/test_company.py index 4e789441..9ded6c88 100644 --- a/tests/api_resources/hris/test_company.py +++ b/tests/api_resources/hris/test_company.py @@ -11,7 +11,7 @@ from finch.types.hris import Company base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestCompany: diff --git a/tests/api_resources/hris/test_directory.py b/tests/api_resources/hris/test_directory.py index 3bafc55f..5b4b3ff6 100644 --- a/tests/api_resources/hris/test_directory.py +++ b/tests/api_resources/hris/test_directory.py @@ -12,7 +12,7 @@ from finch.types.hris import IndividualInDirectory base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestDirectory: diff --git a/tests/api_resources/hris/test_employments.py b/tests/api_resources/hris/test_employments.py index 07e36b69..b86990aa 100644 --- a/tests/api_resources/hris/test_employments.py +++ b/tests/api_resources/hris/test_employments.py @@ -12,7 +12,7 @@ from finch.types.hris import EmploymentDataResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestEmployments: diff --git a/tests/api_resources/hris/test_individuals.py b/tests/api_resources/hris/test_individuals.py index 2868e86f..6c910950 100644 --- a/tests/api_resources/hris/test_individuals.py +++ b/tests/api_resources/hris/test_individuals.py @@ -12,7 +12,7 @@ from finch.types.hris import IndividualResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestIndividuals: diff --git a/tests/api_resources/hris/test_pay_statements.py b/tests/api_resources/hris/test_pay_statements.py index 617ea142..cc536268 100644 --- a/tests/api_resources/hris/test_pay_statements.py +++ b/tests/api_resources/hris/test_pay_statements.py @@ -12,7 +12,7 @@ from finch.types.hris import PayStatementResponse base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestPayStatements: diff --git a/tests/api_resources/hris/test_payments.py b/tests/api_resources/hris/test_payments.py index 3c1d61a8..7680f63f 100644 --- a/tests/api_resources/hris/test_payments.py +++ b/tests/api_resources/hris/test_payments.py @@ -13,7 +13,7 @@ from finch.types.hris import Payment base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestPayments: diff --git a/tests/api_resources/test_account.py b/tests/api_resources/test_account.py index c5172b9a..246afef3 100644 --- a/tests/api_resources/test_account.py +++ b/tests/api_resources/test_account.py @@ -11,7 +11,7 @@ from tests.utils import assert_matches_type base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestAccount: diff --git a/tests/api_resources/test_providers.py b/tests/api_resources/test_providers.py index 47e2dc8b..6229d747 100644 --- a/tests/api_resources/test_providers.py +++ b/tests/api_resources/test_providers.py @@ -12,7 +12,7 @@ from finch.pagination import SyncSinglePage, AsyncSinglePage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestProviders: diff --git a/tests/api_resources/test_request_forwarding.py b/tests/api_resources/test_request_forwarding.py index 3a259596..754acda9 100644 --- a/tests/api_resources/test_request_forwarding.py +++ b/tests/api_resources/test_request_forwarding.py @@ -11,7 +11,7 @@ from tests.utils import assert_matches_type base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestRequestForwarding: diff --git a/tests/api_resources/test_top_level.py b/tests/api_resources/test_top_level.py index daf3c42c..9809a202 100644 --- a/tests/api_resources/test_top_level.py +++ b/tests/api_resources/test_top_level.py @@ -9,7 +9,7 @@ from finch import Finch, AsyncFinch base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestTopLevel: diff --git a/tests/api_resources/test_webhooks.py b/tests/api_resources/test_webhooks.py index 8d3c87e3..4496ea58 100644 --- a/tests/api_resources/test_webhooks.py +++ b/tests/api_resources/test_webhooks.py @@ -13,7 +13,7 @@ from finch import Finch, AsyncFinch base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" class TestWebhooks: diff --git a/tests/test_client.py b/tests/test_client.py index a8d86ce4..762e7bc8 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -26,7 +26,7 @@ ) base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") -access_token = os.environ.get("API_KEY", "something1234") +access_token = "My Access Token" def _get_params(client: BaseClient) -> dict[str, str]: @@ -51,9 +51,9 @@ def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) - copied = self.client.copy(access_token="my new access token") - assert copied.access_token == "my new access token" - assert self.client.access_token == access_token + copied = self.client.copy(access_token="another My Access Token") + assert copied.access_token == "another My Access Token" + assert self.client.access_token == "My Access Token" def test_copy_default_options(self) -> None: # options that have a default are overridden correctly @@ -680,9 +680,9 @@ def test_copy(self) -> None: copied = self.client.copy() assert id(copied) != id(self.client) - copied = self.client.copy(access_token="my new access token") - assert copied.access_token == "my new access token" - assert self.client.access_token == access_token + copied = self.client.copy(access_token="another My Access Token") + assert copied.access_token == "another My Access Token" + assert self.client.access_token == "My Access Token" def test_copy_default_options(self) -> None: # options that have a default are overridden correctly