gr4vy 1.7.16__py3-none-any.whl → 1.7.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gr4vy/_version.py +3 -3
- gr4vy/models/capture_transactionop.py +20 -4
- gr4vy/models/cybersourceoptions.py +7 -0
- gr4vy/models/void_transactionop.py +25 -5
- gr4vy/utils/retries.py +69 -5
- {gr4vy-1.7.16.dist-info → gr4vy-1.7.17.dist-info}/METADATA +1 -1
- {gr4vy-1.7.16.dist-info → gr4vy-1.7.17.dist-info}/RECORD +8 -8
- {gr4vy-1.7.16.dist-info → gr4vy-1.7.17.dist-info}/WHEEL +0 -0
gr4vy/_version.py
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import importlib.metadata
|
|
4
4
|
|
|
5
5
|
__title__: str = "gr4vy"
|
|
6
|
-
__version__: str = "1.7.
|
|
6
|
+
__version__: str = "1.7.17"
|
|
7
7
|
__openapi_doc_version__: str = "1.0.0"
|
|
8
|
-
__gen_version__: str = "2.
|
|
9
|
-
__user_agent__: str = "speakeasy-sdk/python 1.7.
|
|
8
|
+
__gen_version__: str = "2.763.2"
|
|
9
|
+
__user_agent__: str = "speakeasy-sdk/python 1.7.17 2.763.2 1.0.0 gr4vy"
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
12
|
if __package__ is not None:
|
|
@@ -16,9 +16,10 @@ from gr4vy.utils import (
|
|
|
16
16
|
HeaderMetadata,
|
|
17
17
|
PathParamMetadata,
|
|
18
18
|
RequestMetadata,
|
|
19
|
+
get_discriminator,
|
|
19
20
|
)
|
|
20
21
|
import pydantic
|
|
21
|
-
from pydantic import model_serializer
|
|
22
|
+
from pydantic import Discriminator, Tag, model_serializer
|
|
22
23
|
from typing import List, Optional, Union
|
|
23
24
|
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
|
|
24
25
|
|
|
@@ -109,7 +110,22 @@ ResponseCaptureTransactionTypedDict = TypeAliasType(
|
|
|
109
110
|
r"""Successful Response"""
|
|
110
111
|
|
|
111
112
|
|
|
112
|
-
ResponseCaptureTransaction =
|
|
113
|
-
|
|
114
|
-
)
|
|
113
|
+
ResponseCaptureTransaction = Annotated[
|
|
114
|
+
Union[
|
|
115
|
+
Annotated[TransactionOutput, Tag("processing")],
|
|
116
|
+
Annotated[TransactionOutput, Tag("authorization_succeeded")],
|
|
117
|
+
Annotated[TransactionOutput, Tag("authorization_declined")],
|
|
118
|
+
Annotated[TransactionOutput, Tag("authorization_failed")],
|
|
119
|
+
Annotated[TransactionOutput, Tag("authorization_voided")],
|
|
120
|
+
Annotated[TransactionOutput, Tag("authorization_void_pending")],
|
|
121
|
+
Annotated[TransactionOutput, Tag("capture_succeeded")],
|
|
122
|
+
Annotated[TransactionOutput, Tag("capture_pending")],
|
|
123
|
+
Annotated[TransactionOutput, Tag("buyer_approval_pending")],
|
|
124
|
+
Annotated[TransactionCaptureOutput, Tag("succeeded")],
|
|
125
|
+
Annotated[TransactionCaptureOutput, Tag("pending")],
|
|
126
|
+
Annotated[TransactionCaptureOutput, Tag("declined")],
|
|
127
|
+
Annotated[TransactionCaptureOutput, Tag("failed")],
|
|
128
|
+
],
|
|
129
|
+
Discriminator(lambda m: get_discriminator(m, "status", "status")),
|
|
130
|
+
]
|
|
115
131
|
r"""Successful Response"""
|
|
@@ -14,6 +14,8 @@ class CybersourceOptionsTypedDict(TypedDict):
|
|
|
14
14
|
r"""A list of merchant defined data to be passed to the Cybersource. Each key needs to be a numeric string."""
|
|
15
15
|
ship_to_method: NotRequired[Nullable[str]]
|
|
16
16
|
r"""The shipping method for this transaction."""
|
|
17
|
+
comments: NotRequired[Nullable[str]]
|
|
18
|
+
r"""Brief description of the order or any comment you wish to add to the order."""
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
class CybersourceOptions(BaseModel):
|
|
@@ -26,17 +28,22 @@ class CybersourceOptions(BaseModel):
|
|
|
26
28
|
ship_to_method: OptionalNullable[str] = UNSET
|
|
27
29
|
r"""The shipping method for this transaction."""
|
|
28
30
|
|
|
31
|
+
comments: OptionalNullable[str] = UNSET
|
|
32
|
+
r"""Brief description of the order or any comment you wish to add to the order."""
|
|
33
|
+
|
|
29
34
|
@model_serializer(mode="wrap")
|
|
30
35
|
def serialize_model(self, handler):
|
|
31
36
|
optional_fields = [
|
|
32
37
|
"meta_key_merchant_id",
|
|
33
38
|
"merchant_defined_information",
|
|
34
39
|
"ship_to_method",
|
|
40
|
+
"comments",
|
|
35
41
|
]
|
|
36
42
|
nullable_fields = [
|
|
37
43
|
"meta_key_merchant_id",
|
|
38
44
|
"merchant_defined_information",
|
|
39
45
|
"ship_to_method",
|
|
46
|
+
"comments",
|
|
40
47
|
]
|
|
41
48
|
null_default_fields = []
|
|
42
49
|
|
|
@@ -7,9 +7,14 @@ from .transactionvoid_output import (
|
|
|
7
7
|
TransactionVoidOutputTypedDict,
|
|
8
8
|
)
|
|
9
9
|
from gr4vy.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL
|
|
10
|
-
from gr4vy.utils import
|
|
10
|
+
from gr4vy.utils import (
|
|
11
|
+
FieldMetadata,
|
|
12
|
+
HeaderMetadata,
|
|
13
|
+
PathParamMetadata,
|
|
14
|
+
get_discriminator,
|
|
15
|
+
)
|
|
11
16
|
import pydantic
|
|
12
|
-
from pydantic import model_serializer
|
|
17
|
+
from pydantic import Discriminator, Tag, model_serializer
|
|
13
18
|
from typing import List, Optional, Union
|
|
14
19
|
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
|
|
15
20
|
|
|
@@ -94,7 +99,22 @@ ResponseVoidTransactionTypedDict = TypeAliasType(
|
|
|
94
99
|
r"""Successful Response"""
|
|
95
100
|
|
|
96
101
|
|
|
97
|
-
ResponseVoidTransaction =
|
|
98
|
-
|
|
99
|
-
)
|
|
102
|
+
ResponseVoidTransaction = Annotated[
|
|
103
|
+
Union[
|
|
104
|
+
Annotated[TransactionOutput, Tag("processing")],
|
|
105
|
+
Annotated[TransactionOutput, Tag("authorization_succeeded")],
|
|
106
|
+
Annotated[TransactionOutput, Tag("authorization_declined")],
|
|
107
|
+
Annotated[TransactionOutput, Tag("authorization_failed")],
|
|
108
|
+
Annotated[TransactionOutput, Tag("authorization_voided")],
|
|
109
|
+
Annotated[TransactionOutput, Tag("authorization_void_pending")],
|
|
110
|
+
Annotated[TransactionOutput, Tag("capture_succeeded")],
|
|
111
|
+
Annotated[TransactionOutput, Tag("capture_pending")],
|
|
112
|
+
Annotated[TransactionOutput, Tag("buyer_approval_pending")],
|
|
113
|
+
Annotated[TransactionVoidOutput, Tag("succeeded")],
|
|
114
|
+
Annotated[TransactionVoidOutput, Tag("pending")],
|
|
115
|
+
Annotated[TransactionVoidOutput, Tag("declined")],
|
|
116
|
+
Annotated[TransactionVoidOutput, Tag("failed")],
|
|
117
|
+
],
|
|
118
|
+
Discriminator(lambda m: get_discriminator(m, "status", "status")),
|
|
119
|
+
]
|
|
100
120
|
r"""Successful Response"""
|
gr4vy/utils/retries.py
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import random
|
|
5
5
|
import time
|
|
6
|
-
from
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from email.utils import parsedate_to_datetime
|
|
8
|
+
from typing import List, Optional
|
|
7
9
|
|
|
8
10
|
import httpx
|
|
9
11
|
|
|
@@ -51,9 +53,11 @@ class Retries:
|
|
|
51
53
|
|
|
52
54
|
class TemporaryError(Exception):
|
|
53
55
|
response: httpx.Response
|
|
56
|
+
retry_after: Optional[int]
|
|
54
57
|
|
|
55
58
|
def __init__(self, response: httpx.Response):
|
|
56
59
|
self.response = response
|
|
60
|
+
self.retry_after = _parse_retry_after_header(response)
|
|
57
61
|
|
|
58
62
|
|
|
59
63
|
class PermanentError(Exception):
|
|
@@ -63,6 +67,62 @@ class PermanentError(Exception):
|
|
|
63
67
|
self.inner = inner
|
|
64
68
|
|
|
65
69
|
|
|
70
|
+
def _parse_retry_after_header(response: httpx.Response) -> Optional[int]:
|
|
71
|
+
"""Parse Retry-After header from response.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Retry interval in milliseconds, or None if header is missing or invalid.
|
|
75
|
+
"""
|
|
76
|
+
retry_after_header = response.headers.get("retry-after")
|
|
77
|
+
if not retry_after_header:
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
seconds = float(retry_after_header)
|
|
82
|
+
return round(seconds * 1000)
|
|
83
|
+
except ValueError:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
retry_date = parsedate_to_datetime(retry_after_header)
|
|
88
|
+
delta = (retry_date - datetime.now(retry_date.tzinfo)).total_seconds()
|
|
89
|
+
return round(max(0, delta) * 1000)
|
|
90
|
+
except (ValueError, TypeError):
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _get_sleep_interval(
|
|
97
|
+
exception: Exception,
|
|
98
|
+
initial_interval: int,
|
|
99
|
+
max_interval: int,
|
|
100
|
+
exponent: float,
|
|
101
|
+
retries: int,
|
|
102
|
+
) -> float:
|
|
103
|
+
"""Get sleep interval for retry with exponential backoff.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
exception: The exception that triggered the retry.
|
|
107
|
+
initial_interval: Initial retry interval in milliseconds.
|
|
108
|
+
max_interval: Maximum retry interval in milliseconds.
|
|
109
|
+
exponent: Base for exponential backoff calculation.
|
|
110
|
+
retries: Current retry attempt count.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Sleep interval in seconds.
|
|
114
|
+
"""
|
|
115
|
+
if (
|
|
116
|
+
isinstance(exception, TemporaryError)
|
|
117
|
+
and exception.retry_after is not None
|
|
118
|
+
and exception.retry_after > 0
|
|
119
|
+
):
|
|
120
|
+
return exception.retry_after / 1000
|
|
121
|
+
|
|
122
|
+
sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1)
|
|
123
|
+
return min(sleep, max_interval / 1000)
|
|
124
|
+
|
|
125
|
+
|
|
66
126
|
def retry(func, retries: Retries):
|
|
67
127
|
if retries.config.strategy == "backoff":
|
|
68
128
|
|
|
@@ -183,8 +243,10 @@ def retry_with_backoff(
|
|
|
183
243
|
return exception.response
|
|
184
244
|
|
|
185
245
|
raise
|
|
186
|
-
|
|
187
|
-
sleep =
|
|
246
|
+
|
|
247
|
+
sleep = _get_sleep_interval(
|
|
248
|
+
exception, initial_interval, max_interval, exponent, retries
|
|
249
|
+
)
|
|
188
250
|
time.sleep(sleep)
|
|
189
251
|
retries += 1
|
|
190
252
|
|
|
@@ -211,7 +273,9 @@ async def retry_with_backoff_async(
|
|
|
211
273
|
return exception.response
|
|
212
274
|
|
|
213
275
|
raise
|
|
214
|
-
|
|
215
|
-
sleep =
|
|
276
|
+
|
|
277
|
+
sleep = _get_sleep_interval(
|
|
278
|
+
exception, initial_interval, max_interval, exponent, retries
|
|
279
|
+
)
|
|
216
280
|
await asyncio.sleep(sleep)
|
|
217
281
|
retries += 1
|
|
@@ -2,7 +2,7 @@ gr4vy/__init__.py,sha256=w2u919V3Tzv4zEPQ-OYJ79gQ_4_SyW7GOFFoHtqXDFA,401
|
|
|
2
2
|
gr4vy/_hooks/__init__.py,sha256=p5J13DeYuISQyQWirjJAObHIf2VtIlOtFqnIpvjjVwk,118
|
|
3
3
|
gr4vy/_hooks/sdkhooks.py,sha256=3jKTs2B1lcAxBMJge9C-qL0RGbKGLcrHvikzi67Tbdo,2493
|
|
4
4
|
gr4vy/_hooks/types.py,sha256=0O7dbbolkiFAnHkNULvwoLsiXJu0_Wmhev163bvZbW8,3039
|
|
5
|
-
gr4vy/_version.py,sha256=
|
|
5
|
+
gr4vy/_version.py,sha256=e74QfN3Lul59RScJDtHmTZInJPHWNoZQJaZVCL4BTD0,454
|
|
6
6
|
gr4vy/account_updater.py,sha256=mmTd25Oap80PBqQ3p4MvZ_buT5VS0zWc8s8cqfI7iyA,607
|
|
7
7
|
gr4vy/all.py,sha256=jZtRqz8D1xGrylI95KA2XNwWLVAID1o_AYxA9wpXTzs,15176
|
|
8
8
|
gr4vy/audit_logs.py,sha256=U16uKNF7H514ZBM0cAeSz2U2JT4P-SPGIJU6d6KOH34,17087
|
|
@@ -83,7 +83,7 @@ gr4vy/models/buyers.py,sha256=QJLFFT-l3RUGww78h-BqYTt7Mr-fLUs9VDrK2wl3naU,2133
|
|
|
83
83
|
gr4vy/models/buyerupdate.py,sha256=tiPp2oKZYemrRp0uCt0sO6x-nlKNmtvIIzTmRCBe_h4,2567
|
|
84
84
|
gr4vy/models/cancel_transactionop.py,sha256=RBsqNruvMIWAHkhPT_s4GPu3pWlf_NfKJWNXc9HrvxI,1511
|
|
85
85
|
gr4vy/models/cancelstatus.py,sha256=9yb-oK8IL6apWdp1wmZBAqP9TYrz8vXG4Bbc3rQrXGE,307
|
|
86
|
-
gr4vy/models/capture_transactionop.py,sha256=
|
|
86
|
+
gr4vy/models/capture_transactionop.py,sha256=KcXJIc7eaHt2GMSWRUCE-r0m1eVS-f9U2yJXowgZ4cY,4688
|
|
87
87
|
gr4vy/models/capturestatus.py,sha256=hyWAsFmt13M-veZi2e44itOuA-1GT3XUw3ybzYANoH0,328
|
|
88
88
|
gr4vy/models/cardpaymentmethodcreate.py,sha256=WQPt3NYDIPV0lCDQ8rB4Tqzu9JNkh0_UrgwJZeCI6SQ,3498
|
|
89
89
|
gr4vy/models/cardscheme.py,sha256=-kRYwYRl4KUkTuUR23IJCOs3EHp35RHryp7769xruvg,698
|
|
@@ -128,7 +128,7 @@ gr4vy/models/cryptogram.py,sha256=dBVn-OSRioaHJMiIfxmBmoVlgWyLc3s30HV6icB0c3o,94
|
|
|
128
128
|
gr4vy/models/cryptogramcreate.py,sha256=pmsbZ39jzdrRAnWR0flBcITzPT9QcIJOYp9k0znxic8,451
|
|
129
129
|
gr4vy/models/cvvresponsecode.py,sha256=SQpPGT-7mO9xwsDiIjGAZ-zQjXvKmH_jfvg0q7RroIU,336
|
|
130
130
|
gr4vy/models/cybersourceantifraudoptions.py,sha256=bIW9BcHTBrRYHwLehdwbIu50x-1ZMfNVkz0D5qevf6A,2622
|
|
131
|
-
gr4vy/models/cybersourceoptions.py,sha256=
|
|
131
|
+
gr4vy/models/cybersourceoptions.py,sha256=gcbFy0IKmu3DB2RYlabsnYhyurCyaWl9P5GREYEdr3Y,2860
|
|
132
132
|
gr4vy/models/definitionfield.py,sha256=qi8JYRDSDgHLz3Hcug0M95ZAvm8SyPT-qldy-YD9MPI,1606
|
|
133
133
|
gr4vy/models/definitionfieldformat.py,sha256=iFx1ro4waAIZtqp_ouwfHVILF1erz_Hh7nzfpeIb4o0,352
|
|
134
134
|
gr4vy/models/delete_buyer_shipping_detailsop.py,sha256=hdFEhMJ-tZGm0y-dcXzFpjq84zoxa728DIgrrji0H6g,1847
|
|
@@ -393,7 +393,7 @@ gr4vy/models/userstatus.py,sha256=bmlF_Mt656z9o2ibhQ5_dohFs6nEKsuAoNdToCe4vE4,30
|
|
|
393
393
|
gr4vy/models/validationerror.py,sha256=4wRWnXDL-O7GxCdKzmEuWyv-xTywx124gpf65A1OyVc,522
|
|
394
394
|
gr4vy/models/verify_payment_service_credentialsop.py,sha256=IEO3QA3Nn6n-EcfuovKKr5Y-WFJfnU0lxRSvwJ-F7Yc,1623
|
|
395
395
|
gr4vy/models/verifycredentials.py,sha256=M4VoMBhJxmtTf9LXiL_7v3K6y5Gte-H3YGGpkIqB_n8,2278
|
|
396
|
-
gr4vy/models/void_transactionop.py,sha256=
|
|
396
|
+
gr4vy/models/void_transactionop.py,sha256=fMhJfpM-xtBBLNTahhf61fD7iWeqvEPY0Fqrt9bd72k,4282
|
|
397
397
|
gr4vy/models/voidablefield.py,sha256=uApDDXV7oryN_PtHh1YH7dhBpFtPF4t5UqYzO4Hf1Sk,316
|
|
398
398
|
gr4vy/models/voidstatus.py,sha256=d1Xfuz1p1H3zCg11TWn-SPHxtULvy8HjmSKbGIHGW78,325
|
|
399
399
|
gr4vy/models/walletpaymentoptioncontext.py,sha256=aQfoRvTnYyNzpJfgpXvkoPbpUZGGEHg0ERjQq3udmCk,422
|
|
@@ -433,13 +433,13 @@ gr4vy/utils/logger.py,sha256=WdT856mADqljmNjIW_Y1ntFJrIWz3CCOowhK8kcGobk,669
|
|
|
433
433
|
gr4vy/utils/metadata.py,sha256=Per2KFXXOqOtoUWXrlIfjrSrBg199KrRW0nKQDgHIBU,3136
|
|
434
434
|
gr4vy/utils/queryparams.py,sha256=MTK6inMS1_WwjmMJEJmAn67tSHHJyarpdGRlorRHEtI,5899
|
|
435
435
|
gr4vy/utils/requestbodies.py,sha256=ySjEyjcLi731LNUahWvLOrES2HihuA8VrOJx4eQ7Qzg,2101
|
|
436
|
-
gr4vy/utils/retries.py,sha256=
|
|
436
|
+
gr4vy/utils/retries.py,sha256=stPJEFtmK8gOM6aT0DpEJp9Z39oXX1-8I69jpa2n3Ww,8130
|
|
437
437
|
gr4vy/utils/security.py,sha256=VfMDCDFcnxNgffthL8icp_bjRV9FxtJbhK2DgNkSZMk,6016
|
|
438
438
|
gr4vy/utils/serializers.py,sha256=Hndks5M_rJXVub_N5lu0gKZQUoEmWrn6PN7R-0HwvOE,5999
|
|
439
439
|
gr4vy/utils/unmarshal_json_response.py,sha256=G4h8gLOK09kjhPiUZjgIMm6zntcbxpvb_mCpMR3mLhQ,870
|
|
440
440
|
gr4vy/utils/url.py,sha256=BgGPgcTA6MRK4bF8fjP2dUopN3NzEzxWMXPBVg8NQUA,5254
|
|
441
441
|
gr4vy/utils/values.py,sha256=CcaCXEa3xHhkUDROyXZocN8f0bdITftv9Y0P9lTf0YM,3517
|
|
442
442
|
gr4vy/webhooks.py,sha256=2L-ZhdK-XU2X0AkVqgZvhfRqDCKUVs7R4UNCmZJR78w,1359
|
|
443
|
-
gr4vy-1.7.
|
|
444
|
-
gr4vy-1.7.
|
|
445
|
-
gr4vy-1.7.
|
|
443
|
+
gr4vy-1.7.17.dist-info/METADATA,sha256=0IgmtxvB_ym5DiJCg36pUvbopC804T9D7rsEZHua2Dg,44093
|
|
444
|
+
gr4vy-1.7.17.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
445
|
+
gr4vy-1.7.17.dist-info/RECORD,,
|
|
File without changes
|