diff --git a/.release-please-manifest.json b/.release-please-manifest.json index fe941d15..29fa70ce 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.79.0" + ".": "0.79.1" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index eb9fa743..a3404721 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.79.1 (2024-11-18) + +Full Changelog: [v0.79.0...v0.79.1](https://github.com/lithic-com/lithic-python/compare/v0.79.0...v0.79.1) + +### Bug Fixes + +* **asyncify:** avoid hanging process under certain conditions ([#632](https://github.com/lithic-com/lithic-python/issues/632)) ([a588059](https://github.com/lithic-com/lithic-python/commit/a588059fb8e877c9b174ce665991c5ade57dc49d)) + + +### Chores + +* **tests:** limit array example length ([#630](https://github.com/lithic-com/lithic-python/issues/630)) ([015e1cb](https://github.com/lithic-com/lithic-python/commit/015e1cb414358c2a90a21453d1854328caa0d968)) + ## 0.79.0 (2024-11-14) Full Changelog: [v0.78.1...v0.79.0](https://github.com/lithic-com/lithic-python/compare/v0.78.1...v0.79.0) diff --git a/pyproject.toml b/pyproject.toml index 01ff401c..0957c843 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lithic" -version = "0.79.0" +version = "0.79.1" description = "The official Python library for the lithic API" dynamic = ["readme"] license = "Apache-2.0" @@ -55,6 +55,7 @@ dev-dependencies = [ "dirty-equals>=0.6.0", "importlib-metadata>=6.7.0", "rich>=13.7.1", + "nest_asyncio==1.6.0" ] [tool.rye.scripts] diff --git a/requirements-dev.lock b/requirements-dev.lock index ad69fec0..3b6cb70d 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -51,6 +51,7 @@ mdurl==0.1.2 mypy==1.13.0 mypy-extensions==1.0.0 # via mypy +nest-asyncio==1.6.0 nodeenv==1.8.0 # via pyright nox==2023.4.22 diff --git a/src/lithic/_utils/_sync.py b/src/lithic/_utils/_sync.py index d0d81033..8b3aaf2b 100644 --- a/src/lithic/_utils/_sync.py +++ b/src/lithic/_utils/_sync.py @@ -1,56 +1,62 @@ from __future__ import annotations +import sys +import asyncio import functools -from typing import TypeVar, Callable, Awaitable +import contextvars +from typing import Any, TypeVar, Callable, Awaitable from typing_extensions import ParamSpec -import anyio -import anyio.to_thread - -from ._reflection import function_has_argument - T_Retval = TypeVar("T_Retval") T_ParamSpec = ParamSpec("T_ParamSpec") -# copied from `asyncer`, https://github.com/tiangolo/asyncer -def asyncify( - function: Callable[T_ParamSpec, T_Retval], - *, - cancellable: bool = False, - limiter: anyio.CapacityLimiter | None = None, -) -> Callable[T_ParamSpec, Awaitable[T_Retval]]: +if sys.version_info >= (3, 9): + to_thread = asyncio.to_thread +else: + # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread + # for Python 3.8 support + async def to_thread( + func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs + ) -> Any: + """Asynchronously run function *func* in a separate thread. + + Any *args and **kwargs supplied for this function are directly passed + to *func*. Also, the current :class:`contextvars.Context` is propagated, + allowing context variables from the main thread to be accessed in the + separate thread. + + Returns a coroutine that can be awaited to get the eventual result of *func*. + """ + loop = asyncio.events.get_running_loop() + ctx = contextvars.copy_context() + func_call = functools.partial(ctx.run, func, *args, **kwargs) + return await loop.run_in_executor(None, func_call) + + +# inspired by `asyncer`, https://github.com/tiangolo/asyncer +def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]: """ Take a blocking function and create an async one that receives the same - positional and keyword arguments, and that when called, calls the original function - in a worker thread using `anyio.to_thread.run_sync()`. Internally, - `asyncer.asyncify()` uses the same `anyio.to_thread.run_sync()`, but it supports - keyword arguments additional to positional arguments and it adds better support for - autocompletion and inline errors for the arguments of the function called and the - return value. - - If the `cancellable` option is enabled and the task waiting for its completion is - cancelled, the thread will still run its course but its return value (or any raised - exception) will be ignored. + positional and keyword arguments. For python version 3.9 and above, it uses + asyncio.to_thread to run the function in a separate thread. For python version + 3.8, it uses locally defined copy of the asyncio.to_thread function which was + introduced in python 3.9. - Use it like this: + Usage: - ```Python - def do_work(arg1, arg2, kwarg1="", kwarg2="") -> str: - # Do work - return "Some result" + ```python + def blocking_func(arg1, arg2, kwarg1=None): + # blocking code + return result - result = await to_thread.asyncify(do_work)("spam", "ham", kwarg1="a", kwarg2="b") - print(result) + result = asyncify(blocking_function)(arg1, arg2, kwarg1=value1) ``` ## Arguments `function`: a blocking regular callable (e.g. a function) - `cancellable`: `True` to allow cancellation of the operation - `limiter`: capacity limiter to use to limit the total amount of threads running - (if omitted, the default limiter is used) ## Return @@ -60,22 +66,6 @@ def do_work(arg1, arg2, kwarg1="", kwarg2="") -> str: """ async def wrapper(*args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs) -> T_Retval: - partial_f = functools.partial(function, *args, **kwargs) - - # In `v4.1.0` anyio added the `abandon_on_cancel` argument and deprecated the old - # `cancellable` argument, so we need to use the new `abandon_on_cancel` to avoid - # surfacing deprecation warnings. - if function_has_argument(anyio.to_thread.run_sync, "abandon_on_cancel"): - return await anyio.to_thread.run_sync( - partial_f, - abandon_on_cancel=cancellable, - limiter=limiter, - ) - - return await anyio.to_thread.run_sync( - partial_f, - cancellable=cancellable, - limiter=limiter, - ) + return await to_thread(function, *args, **kwargs) return wrapper diff --git a/src/lithic/_version.py b/src/lithic/_version.py index d3fa5371..d7e9daf8 100644 --- a/src/lithic/_version.py +++ b/src/lithic/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "lithic" -__version__ = "0.79.0" # x-release-please-version +__version__ = "0.79.1" # x-release-please-version diff --git a/tests/api_resources/auth_rules/test_v2.py b/tests/api_resources/auth_rules/test_v2.py index 4685f7d8..9d56c35f 100644 --- a/tests/api_resources/auth_rules/test_v2.py +++ b/tests/api_resources/auth_rules/test_v2.py @@ -30,39 +30,21 @@ class TestV2: @parametrize def test_method_create_overload_1(self, client: Lithic) -> None: v2 = client.auth_rules.v2.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2CreateResponse, v2, path=["response"]) @parametrize def test_method_create_with_all_params_overload_1(self, client: Lithic) -> None: v2 = client.auth_rules.v2.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], parameters={ "conditions": [ { "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, type="CONDITIONAL_BLOCK", @@ -72,11 +54,7 @@ def test_method_create_with_all_params_overload_1(self, client: Lithic) -> None: @parametrize def test_raw_response_create_overload_1(self, client: Lithic) -> None: response = client.auth_rules.v2.with_raw_response.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -87,11 +65,7 @@ def test_raw_response_create_overload_1(self, client: Lithic) -> None: @parametrize def test_streaming_response_create_overload_1(self, client: Lithic) -> None: with client.auth_rules.v2.with_streaming_response.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -104,39 +78,21 @@ def test_streaming_response_create_overload_1(self, client: Lithic) -> None: @parametrize def test_method_create_overload_2(self, client: Lithic) -> None: v2 = client.auth_rules.v2.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2CreateResponse, v2, path=["response"]) @parametrize def test_method_create_with_all_params_overload_2(self, client: Lithic) -> None: v2 = client.auth_rules.v2.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], parameters={ "conditions": [ { "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, type="CONDITIONAL_BLOCK", @@ -146,11 +102,7 @@ def test_method_create_with_all_params_overload_2(self, client: Lithic) -> None: @parametrize def test_raw_response_create_overload_2(self, client: Lithic) -> None: response = client.auth_rules.v2.with_raw_response.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -161,11 +113,7 @@ def test_raw_response_create_overload_2(self, client: Lithic) -> None: @parametrize def test_streaming_response_create_overload_2(self, client: Lithic) -> None: with client.auth_rules.v2.with_streaming_response.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -192,17 +140,7 @@ def test_method_create_with_all_params_overload_3(self, client: Lithic) -> None: "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, type="CONDITIONAL_BLOCK", @@ -357,11 +295,7 @@ def test_streaming_response_list(self, client: Lithic) -> None: def test_method_apply_overload_1(self, client: Lithic) -> None: v2 = client.auth_rules.v2.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2ApplyResponse, v2, path=["response"]) @@ -369,11 +303,7 @@ def test_method_apply_overload_1(self, client: Lithic) -> None: def test_raw_response_apply_overload_1(self, client: Lithic) -> None: response = client.auth_rules.v2.with_raw_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -385,11 +315,7 @@ def test_raw_response_apply_overload_1(self, client: Lithic) -> None: def test_streaming_response_apply_overload_1(self, client: Lithic) -> None: with client.auth_rules.v2.with_streaming_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -404,22 +330,14 @@ def test_path_params_apply_overload_1(self, client: Lithic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `auth_rule_token` but received ''"): client.auth_rules.v2.with_raw_response.apply( auth_rule_token="", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) @parametrize def test_method_apply_overload_2(self, client: Lithic) -> None: v2 = client.auth_rules.v2.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2ApplyResponse, v2, path=["response"]) @@ -427,11 +345,7 @@ def test_method_apply_overload_2(self, client: Lithic) -> None: def test_raw_response_apply_overload_2(self, client: Lithic) -> None: response = client.auth_rules.v2.with_raw_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -443,11 +357,7 @@ def test_raw_response_apply_overload_2(self, client: Lithic) -> None: def test_streaming_response_apply_overload_2(self, client: Lithic) -> None: with client.auth_rules.v2.with_streaming_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -462,11 +372,7 @@ def test_path_params_apply_overload_2(self, client: Lithic) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `auth_rule_token` but received ''"): client.auth_rules.v2.with_raw_response.apply( auth_rule_token="", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) @parametrize @@ -528,17 +434,7 @@ def test_method_draft_with_all_params(self, client: Lithic) -> None: "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, ) @@ -658,39 +554,21 @@ class TestAsyncV2: @parametrize async def test_method_create_overload_1(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2CreateResponse, v2, path=["response"]) @parametrize async def test_method_create_with_all_params_overload_1(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], parameters={ "conditions": [ { "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, type="CONDITIONAL_BLOCK", @@ -700,11 +578,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn @parametrize async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) -> None: response = await async_client.auth_rules.v2.with_raw_response.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -715,11 +589,7 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) - @parametrize async def test_streaming_response_create_overload_1(self, async_client: AsyncLithic) -> None: async with async_client.auth_rules.v2.with_streaming_response.create( - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -732,39 +602,21 @@ async def test_streaming_response_create_overload_1(self, async_client: AsyncLit @parametrize async def test_method_create_overload_2(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2CreateResponse, v2, path=["response"]) @parametrize async def test_method_create_with_all_params_overload_2(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], parameters={ "conditions": [ { "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, type="CONDITIONAL_BLOCK", @@ -774,11 +626,7 @@ async def test_method_create_with_all_params_overload_2(self, async_client: Asyn @parametrize async def test_raw_response_create_overload_2(self, async_client: AsyncLithic) -> None: response = await async_client.auth_rules.v2.with_raw_response.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -789,11 +637,7 @@ async def test_raw_response_create_overload_2(self, async_client: AsyncLithic) - @parametrize async def test_streaming_response_create_overload_2(self, async_client: AsyncLithic) -> None: async with async_client.auth_rules.v2.with_streaming_response.create( - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -820,17 +664,7 @@ async def test_method_create_with_all_params_overload_3(self, async_client: Asyn "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, type="CONDITIONAL_BLOCK", @@ -985,11 +819,7 @@ async def test_streaming_response_list(self, async_client: AsyncLithic) -> None: async def test_method_apply_overload_1(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2ApplyResponse, v2, path=["response"]) @@ -997,11 +827,7 @@ async def test_method_apply_overload_1(self, async_client: AsyncLithic) -> None: async def test_raw_response_apply_overload_1(self, async_client: AsyncLithic) -> None: response = await async_client.auth_rules.v2.with_raw_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -1013,11 +839,7 @@ async def test_raw_response_apply_overload_1(self, async_client: AsyncLithic) -> async def test_streaming_response_apply_overload_1(self, async_client: AsyncLithic) -> None: async with async_client.auth_rules.v2.with_streaming_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1032,22 +854,14 @@ async def test_path_params_apply_overload_1(self, async_client: AsyncLithic) -> with pytest.raises(ValueError, match=r"Expected a non-empty value for `auth_rule_token` but received ''"): await async_client.auth_rules.v2.with_raw_response.apply( auth_rule_token="", - account_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + account_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) @parametrize async def test_method_apply_overload_2(self, async_client: AsyncLithic) -> None: v2 = await async_client.auth_rules.v2.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(V2ApplyResponse, v2, path=["response"]) @@ -1055,11 +869,7 @@ async def test_method_apply_overload_2(self, async_client: AsyncLithic) -> None: async def test_raw_response_apply_overload_2(self, async_client: AsyncLithic) -> None: response = await async_client.auth_rules.v2.with_raw_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert response.is_closed is True @@ -1071,11 +881,7 @@ async def test_raw_response_apply_overload_2(self, async_client: AsyncLithic) -> async def test_streaming_response_apply_overload_2(self, async_client: AsyncLithic) -> None: async with async_client.auth_rules.v2.with_streaming_response.apply( auth_rule_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -1090,11 +896,7 @@ async def test_path_params_apply_overload_2(self, async_client: AsyncLithic) -> with pytest.raises(ValueError, match=r"Expected a non-empty value for `auth_rule_token` but received ''"): await async_client.auth_rules.v2.with_raw_response.apply( auth_rule_token="", - card_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + card_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) @parametrize @@ -1156,17 +958,7 @@ async def test_method_draft_with_all_params(self, async_client: AsyncLithic) -> "attribute": "MCC", "operation": "IS_ONE_OF", "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, - { - "attribute": "MCC", - "operation": "IS_ONE_OF", - "value": "string", - }, + } ] }, ) diff --git a/tests/api_resources/events/test_subscriptions.py b/tests/api_resources/events/test_subscriptions.py index f52e3445..4e9a5c2d 100644 --- a/tests/api_resources/events/test_subscriptions.py +++ b/tests/api_resources/events/test_subscriptions.py @@ -35,7 +35,7 @@ def test_method_create_with_all_params(self, client: Lithic) -> None: url="https://example.com", description="description", disabled=True, - event_types=["account_holder.created", "account_holder.updated", "account_holder.verification"], + event_types=["account_holder.created"], ) assert_matches_type(EventSubscription, subscription, path=["response"]) @@ -118,7 +118,7 @@ def test_method_update_with_all_params(self, client: Lithic) -> None: url="https://example.com", description="description", disabled=True, - event_types=["account_holder.created", "account_holder.updated", "account_holder.verification"], + event_types=["account_holder.created"], ) assert_matches_type(EventSubscription, subscription, path=["response"]) @@ -546,7 +546,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncLithic) -> url="https://example.com", description="description", disabled=True, - event_types=["account_holder.created", "account_holder.updated", "account_holder.verification"], + event_types=["account_holder.created"], ) assert_matches_type(EventSubscription, subscription, path=["response"]) @@ -629,7 +629,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncLithic) -> url="https://example.com", description="description", disabled=True, - event_types=["account_holder.created", "account_holder.updated", "account_holder.verification"], + event_types=["account_holder.created"], ) assert_matches_type(EventSubscription, subscription, path=["response"]) diff --git a/tests/api_resources/test_account_holders.py b/tests/api_resources/test_account_holders.py index bdd1673b..4e918e0a 100644 --- a/tests/api_resources/test_account_holders.py +++ b/tests/api_resources/test_account_holders.py @@ -41,31 +41,7 @@ def test_method_create_overload_1(self, client: Lithic) -> None: "government_id": "114-123-1513", "legal_business_name": "Acme, Inc.", "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, + } ], beneficial_owner_individuals=[ { @@ -81,35 +57,7 @@ def test_method_create_overload_1(self, client: Lithic) -> None: "first_name": "Tom", "government_id": "111-23-1412", "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, + } ], business_entity={ "address": { @@ -161,37 +109,7 @@ def test_method_create_with_all_params_overload_1(self, client: Lithic) -> None: "phone_numbers": ["+12124007676"], "dba_business_name": "dba_business_name", "parent_company": "parent_company", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - "dba_business_name": "dba_business_name", - "parent_company": "parent_company", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - "dba_business_name": "dba_business_name", - "parent_company": "parent_company", - }, + } ], beneficial_owner_individuals=[ { @@ -209,39 +127,7 @@ def test_method_create_with_all_params_overload_1(self, client: Lithic) -> None: "government_id": "111-23-1412", "last_name": "Bombadil", "phone_number": "+12124007676", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - "phone_number": "+12124007676", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - "phone_number": "+12124007676", - }, + } ], business_entity={ "address": { @@ -298,31 +184,7 @@ def test_raw_response_create_overload_1(self, client: Lithic) -> None: "government_id": "114-123-1513", "legal_business_name": "Acme, Inc.", "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, + } ], beneficial_owner_individuals=[ { @@ -338,35 +200,7 @@ def test_raw_response_create_overload_1(self, client: Lithic) -> None: "first_name": "Tom", "government_id": "111-23-1412", "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, + } ], business_entity={ "address": { @@ -419,31 +253,7 @@ def test_streaming_response_create_overload_1(self, client: Lithic) -> None: "government_id": "114-123-1513", "legal_business_name": "Acme, Inc.", "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, + } ], beneficial_owner_individuals=[ { @@ -459,35 +269,7 @@ def test_streaming_response_create_overload_1(self, client: Lithic) -> None: "first_name": "Tom", "government_id": "111-23-1412", "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, + } ], business_entity={ "address": { @@ -1054,7 +836,7 @@ def test_method_simulate_enrollment_document_review_with_all_params(self, client account_holder = client.account_holders.simulate_enrollment_document_review( document_upload_token="b11cd67b-0a52-4180-8365-314f3def5426", status="UPLOADED", - accepted_entity_status_reasons=["string", "string", "string"], + accepted_entity_status_reasons=["string"], status_reason="DOCUMENT_MISSING_REQUIRED_DATA", ) assert_matches_type(Document, account_holder, path=["response"]) @@ -1095,11 +877,7 @@ def test_method_simulate_enrollment_review_with_all_params(self, client: Lithic) account_holder = client.account_holders.simulate_enrollment_review( account_holder_token="1415964d-4400-4d79-9fb3-eee0faaee4e4", status="ACCEPTED", - status_reasons=[ - "PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE", - "PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE", - "PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE", - ], + status_reasons=["PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE"], ) assert_matches_type(AccountHolderSimulateEnrollmentReviewResponse, account_holder, path=["response"]) @@ -1188,31 +966,7 @@ async def test_method_create_overload_1(self, async_client: AsyncLithic) -> None "government_id": "114-123-1513", "legal_business_name": "Acme, Inc.", "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, + } ], beneficial_owner_individuals=[ { @@ -1228,35 +982,7 @@ async def test_method_create_overload_1(self, async_client: AsyncLithic) -> None "first_name": "Tom", "government_id": "111-23-1412", "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, + } ], business_entity={ "address": { @@ -1308,37 +1034,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "phone_numbers": ["+12124007676"], "dba_business_name": "dba_business_name", "parent_company": "parent_company", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - "dba_business_name": "dba_business_name", - "parent_company": "parent_company", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - "dba_business_name": "dba_business_name", - "parent_company": "parent_company", - }, + } ], beneficial_owner_individuals=[ { @@ -1356,39 +1052,7 @@ async def test_method_create_with_all_params_overload_1(self, async_client: Asyn "government_id": "111-23-1412", "last_name": "Bombadil", "phone_number": "+12124007676", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - "phone_number": "+12124007676", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - "address2": "address2", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - "phone_number": "+12124007676", - }, + } ], business_entity={ "address": { @@ -1445,31 +1109,7 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) - "government_id": "114-123-1513", "legal_business_name": "Acme, Inc.", "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, + } ], beneficial_owner_individuals=[ { @@ -1485,35 +1125,7 @@ async def test_raw_response_create_overload_1(self, async_client: AsyncLithic) - "first_name": "Tom", "government_id": "111-23-1412", "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, + } ], business_entity={ "address": { @@ -1566,31 +1178,7 @@ async def test_streaming_response_create_overload_1(self, async_client: AsyncLit "government_id": "114-123-1513", "legal_business_name": "Acme, Inc.", "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "government_id": "114-123-1513", - "legal_business_name": "Acme, Inc.", - "phone_numbers": ["+12124007676"], - }, + } ], beneficial_owner_individuals=[ { @@ -1606,35 +1194,7 @@ async def test_streaming_response_create_overload_1(self, async_client: AsyncLit "first_name": "Tom", "government_id": "111-23-1412", "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, - { - "address": { - "address1": "123 Old Forest Way", - "city": "Omaha", - "country": "USA", - "postal_code": "68022", - "state": "NE", - }, - "dob": "1991-03-08 08:00:00", - "email": "tom@middle-earth.com", - "first_name": "Tom", - "government_id": "111-23-1412", - "last_name": "Bombadil", - }, + } ], business_entity={ "address": { @@ -2201,7 +1761,7 @@ async def test_method_simulate_enrollment_document_review_with_all_params(self, account_holder = await async_client.account_holders.simulate_enrollment_document_review( document_upload_token="b11cd67b-0a52-4180-8365-314f3def5426", status="UPLOADED", - accepted_entity_status_reasons=["string", "string", "string"], + accepted_entity_status_reasons=["string"], status_reason="DOCUMENT_MISSING_REQUIRED_DATA", ) assert_matches_type(Document, account_holder, path=["response"]) @@ -2242,11 +1802,7 @@ async def test_method_simulate_enrollment_review_with_all_params(self, async_cli account_holder = await async_client.account_holders.simulate_enrollment_review( account_holder_token="1415964d-4400-4d79-9fb3-eee0faaee4e4", status="ACCEPTED", - status_reasons=[ - "PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE", - "PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE", - "PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE", - ], + status_reasons=["PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE"], ) assert_matches_type(AccountHolderSimulateEnrollmentReviewResponse, account_holder, path=["response"]) diff --git a/tests/api_resources/test_disputes.py b/tests/api_resources/test_disputes.py index a586b5c9..2104bf81 100644 --- a/tests/api_resources/test_disputes.py +++ b/tests/api_resources/test_disputes.py @@ -171,11 +171,7 @@ def test_method_list_with_all_params(self, client: Lithic) -> None: page_size=1, starting_after="starting_after", status="ARBITRATION", - transaction_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + transaction_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(SyncCursorPage[Dispute], dispute, path=["response"]) @@ -582,11 +578,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> N page_size=1, starting_after="starting_after", status="ARBITRATION", - transaction_tokens=[ - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - ], + transaction_tokens=["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], ) assert_matches_type(AsyncCursorPage[Dispute], dispute, path=["response"]) diff --git a/tests/api_resources/test_events.py b/tests/api_resources/test_events.py index 1c974512..37ad8993 100644 --- a/tests/api_resources/test_events.py +++ b/tests/api_resources/test_events.py @@ -68,7 +68,7 @@ def test_method_list_with_all_params(self, client: Lithic) -> None: begin=parse_datetime("2019-12-27T18:11:19.117Z"), end=parse_datetime("2019-12-27T18:11:19.117Z"), ending_before="ending_before", - event_types=["account_holder.created", "account_holder.updated", "account_holder.verification"], + event_types=["account_holder.created"], page_size=1, starting_after="starting_after", with_content=True, @@ -206,7 +206,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> N begin=parse_datetime("2019-12-27T18:11:19.117Z"), end=parse_datetime("2019-12-27T18:11:19.117Z"), ending_before="ending_before", - event_types=["account_holder.created", "account_holder.updated", "account_holder.verification"], + event_types=["account_holder.created"], page_size=1, starting_after="starting_after", with_content=True, diff --git a/tests/api_resources/test_external_bank_accounts.py b/tests/api_resources/test_external_bank_accounts.py index e975ace4..13c1f515 100644 --- a/tests/api_resources/test_external_bank_accounts.py +++ b/tests/api_resources/test_external_bank_accounts.py @@ -357,14 +357,14 @@ def test_method_list(self, client: Lithic) -> None: def test_method_list_with_all_params(self, client: Lithic) -> None: external_bank_account = client.external_bank_accounts.list( account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_types=["CHECKING", "SAVINGS"], - countries=["string", "string", "string"], + account_types=["CHECKING"], + countries=["string"], ending_before="ending_before", - owner_types=["INDIVIDUAL", "BUSINESS"], + owner_types=["INDIVIDUAL"], page_size=1, starting_after="starting_after", - states=["ENABLED", "CLOSED", "PAUSED"], - verification_states=["PENDING", "ENABLED", "FAILED_VERIFICATION"], + states=["ENABLED"], + verification_states=["PENDING"], ) assert_matches_type(SyncCursorPage[ExternalBankAccountListResponse], external_bank_account, path=["response"]) @@ -821,14 +821,14 @@ async def test_method_list(self, async_client: AsyncLithic) -> None: async def test_method_list_with_all_params(self, async_client: AsyncLithic) -> None: external_bank_account = await async_client.external_bank_accounts.list( account_token="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", - account_types=["CHECKING", "SAVINGS"], - countries=["string", "string", "string"], + account_types=["CHECKING"], + countries=["string"], ending_before="ending_before", - owner_types=["INDIVIDUAL", "BUSINESS"], + owner_types=["INDIVIDUAL"], page_size=1, starting_after="starting_after", - states=["ENABLED", "CLOSED", "PAUSED"], - verification_states=["PENDING", "ENABLED", "FAILED_VERIFICATION"], + states=["ENABLED"], + verification_states=["PENDING"], ) assert_matches_type(AsyncCursorPage[ExternalBankAccountListResponse], external_bank_account, path=["response"]) diff --git a/tests/test_client.py b/tests/test_client.py index 7444cedd..b1551023 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -4,11 +4,14 @@ import gc import os +import sys import json import asyncio import inspect +import subprocess import tracemalloc from typing import Any, Union, cast +from textwrap import dedent from unittest import mock from typing_extensions import Literal @@ -1840,3 +1843,38 @@ def retry_handler(_request: httpx.Request) -> httpx.Response: async with client.cards.with_streaming_response.create(type="MERCHANT_LOCKED") as response: assert response.retries_taken == failures_before_success assert int(response.http_request.headers.get("x-stainless-retry-count")) == failures_before_success + + def test_get_platform(self) -> None: + # A previous implementation of asyncify could leave threads unterminated when + # used with nest_asyncio. + # + # Since nest_asyncio.apply() is global and cannot be un-applied, this + # test is run in a separate process to avoid affecting other tests. + test_code = dedent(""" + import asyncio + import nest_asyncio + import threading + + from lithic._utils import asyncify + from lithic._base_client import get_platform + + async def test_main() -> None: + result = await asyncify(get_platform)() + print(result) + for thread in threading.enumerate(): + print(thread.name) + + nest_asyncio.apply() + asyncio.run(test_main()) + """) + with subprocess.Popen( + [sys.executable, "-c", test_code], + text=True, + ) as process: + try: + process.wait(2) + if process.returncode: + raise AssertionError("calling get_platform using asyncify resulted in a non-zero exit code") + except subprocess.TimeoutExpired as e: + process.kill() + raise AssertionError("calling get_platform using asyncify resulted in a hung process") from e