@@ -36,6 +36,10 @@ def _get_params(client: BaseClient[Any, Any]) -> dict[str, str]:
36
36
return dict (url .params )
37
37
38
38
39
+ def _low_retry_timeout (* _args : Any , ** _kwargs : Any ) -> float :
40
+ return 0.1
41
+
42
+
39
43
class TestFinch :
40
44
client = Finch (
41
45
base_url = base_url ,
@@ -950,6 +954,49 @@ def test_parse_retry_after_header(self, remaining_retries: int, retry_after: str
950
954
calculated = client ._calculate_retry_timeout (remaining_retries , options , headers )
951
955
assert calculated == pytest .approx (timeout , 0.5 * 0.875 ) # pyright: ignore[reportUnknownMemberType]
952
956
957
+ @pytest .mark .parametrize ("failures_before_success" , [0 , 2 , 4 ])
958
+ @mock .patch ("finch._base_client.BaseClient._calculate_retry_timeout" , _low_retry_timeout )
959
+ @pytest .mark .respx (base_url = base_url )
960
+ def test_retries_taken (self , client : Finch , failures_before_success : int , respx_mock : MockRouter ) -> None :
961
+ client = client .with_options (max_retries = 4 )
962
+
963
+ nb_retries = 0
964
+
965
+ def retry_handler (_request : httpx .Request ) -> httpx .Response :
966
+ nonlocal nb_retries
967
+ if nb_retries < failures_before_success :
968
+ nb_retries += 1
969
+ return httpx .Response (500 )
970
+ return httpx .Response (200 )
971
+
972
+ respx_mock .get ("/employer/directory" ).mock (side_effect = retry_handler )
973
+
974
+ response = client .hris .directory .with_raw_response .list ()
975
+
976
+ assert response .retries_taken == failures_before_success
977
+
978
+ @pytest .mark .parametrize ("failures_before_success" , [0 , 2 , 4 ])
979
+ @mock .patch ("finch._base_client.BaseClient._calculate_retry_timeout" , _low_retry_timeout )
980
+ @pytest .mark .respx (base_url = base_url )
981
+ def test_retries_taken_new_response_class (
982
+ self , client : Finch , failures_before_success : int , respx_mock : MockRouter
983
+ ) -> None :
984
+ client = client .with_options (max_retries = 4 )
985
+
986
+ nb_retries = 0
987
+
988
+ def retry_handler (_request : httpx .Request ) -> httpx .Response :
989
+ nonlocal nb_retries
990
+ if nb_retries < failures_before_success :
991
+ nb_retries += 1
992
+ return httpx .Response (500 )
993
+ return httpx .Response (200 )
994
+
995
+ respx_mock .get ("/employer/directory" ).mock (side_effect = retry_handler )
996
+
997
+ with client .hris .directory .with_streaming_response .list () as response :
998
+ assert response .retries_taken == failures_before_success
999
+
953
1000
954
1001
class TestAsyncFinch :
955
1002
client = AsyncFinch (
@@ -1870,3 +1917,50 @@ async def test_parse_retry_after_header(self, remaining_retries: int, retry_afte
1870
1917
options = FinalRequestOptions (method = "get" , url = "/foo" , max_retries = 3 )
1871
1918
calculated = client ._calculate_retry_timeout (remaining_retries , options , headers )
1872
1919
assert calculated == pytest .approx (timeout , 0.5 * 0.875 ) # pyright: ignore[reportUnknownMemberType]
1920
+
1921
+ @pytest .mark .parametrize ("failures_before_success" , [0 , 2 , 4 ])
1922
+ @mock .patch ("finch._base_client.BaseClient._calculate_retry_timeout" , _low_retry_timeout )
1923
+ @pytest .mark .respx (base_url = base_url )
1924
+ @pytest .mark .asyncio
1925
+ async def test_retries_taken (
1926
+ self , async_client : AsyncFinch , failures_before_success : int , respx_mock : MockRouter
1927
+ ) -> None :
1928
+ client = async_client .with_options (max_retries = 4 )
1929
+
1930
+ nb_retries = 0
1931
+
1932
+ def retry_handler (_request : httpx .Request ) -> httpx .Response :
1933
+ nonlocal nb_retries
1934
+ if nb_retries < failures_before_success :
1935
+ nb_retries += 1
1936
+ return httpx .Response (500 )
1937
+ return httpx .Response (200 )
1938
+
1939
+ respx_mock .get ("/employer/directory" ).mock (side_effect = retry_handler )
1940
+
1941
+ response = await client .hris .directory .with_raw_response .list ()
1942
+
1943
+ assert response .retries_taken == failures_before_success
1944
+
1945
+ @pytest .mark .parametrize ("failures_before_success" , [0 , 2 , 4 ])
1946
+ @mock .patch ("finch._base_client.BaseClient._calculate_retry_timeout" , _low_retry_timeout )
1947
+ @pytest .mark .respx (base_url = base_url )
1948
+ @pytest .mark .asyncio
1949
+ async def test_retries_taken_new_response_class (
1950
+ self , async_client : AsyncFinch , failures_before_success : int , respx_mock : MockRouter
1951
+ ) -> None :
1952
+ client = async_client .with_options (max_retries = 4 )
1953
+
1954
+ nb_retries = 0
1955
+
1956
+ def retry_handler (_request : httpx .Request ) -> httpx .Response :
1957
+ nonlocal nb_retries
1958
+ if nb_retries < failures_before_success :
1959
+ nb_retries += 1
1960
+ return httpx .Response (500 )
1961
+ return httpx .Response (200 )
1962
+
1963
+ respx_mock .get ("/employer/directory" ).mock (side_effect = retry_handler )
1964
+
1965
+ async with client .hris .directory .with_streaming_response .list () as response :
1966
+ assert response .retries_taken == failures_before_success
0 commit comments