checkout-intents 0.1.0__tar.gz → 0.3.0__tar.gz
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.
- checkout_intents-0.3.0/.release-please-manifest.json +3 -0
- checkout_intents-0.3.0/CHANGELOG.md +61 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/CONTRIBUTING.md +12 -12
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/PKG-INFO +199 -11
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/README.md +198 -10
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/api.md +1 -0
- checkout_intents-0.3.0/examples/complete-checkout-intent.py +78 -0
- checkout_intents-0.3.0/examples/error-handling.py +83 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/pyproject.toml +10 -33
- checkout_intents-0.3.0/requirements-dev.lock +144 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/__init__.py +2 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_client.py +65 -14
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_exceptions.py +34 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_models.py +31 -14
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_compat.py +1 -1
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_utils.py +3 -3
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_version.py +1 -1
- checkout_intents-0.3.0/src/checkout_intents/pagination.py +89 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/resources/brands.py +4 -4
- checkout_intents-0.3.0/src/checkout_intents/resources/checkout_intents.py +1378 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/__init__.py +1 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/checkout_intent.py +5 -0
- checkout_intents-0.3.0/src/checkout_intents/types/checkout_intent_list_params.py +22 -0
- checkout_intents-0.3.0/src/checkout_intents/types/payment_method.py +34 -0
- checkout_intents-0.3.0/src/checkout_intents/types/payment_method_param.py +34 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/variant_selection.py +0 -8
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/variant_selection_param.py +0 -8
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/api_resources/test_checkout_intents.py +145 -16
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_client.py +20 -20
- checkout_intents-0.3.0/tests/test_environment_inference.py +163 -0
- checkout_intents-0.3.0/tests/test_polling.py +695 -0
- checkout_intents-0.3.0/uv.lock +1808 -0
- checkout_intents-0.1.0/.release-please-manifest.json +0 -3
- checkout_intents-0.1.0/CHANGELOG.md +0 -17
- checkout_intents-0.1.0/requirements-dev.lock +0 -137
- checkout_intents-0.1.0/src/checkout_intents/resources/checkout_intents.py +0 -480
- checkout_intents-0.1.0/src/checkout_intents/types/payment_method.py +0 -15
- checkout_intents-0.1.0/src/checkout_intents/types/payment_method_param.py +0 -15
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/.gitignore +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/LICENSE +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/SECURITY.md +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/bin/check-release-environment +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/bin/publish-pypi +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/examples/.keep +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/noxfile.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/release-please-config.json +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/requirements.lock +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_base_client.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_compat.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_constants.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_files.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_qs.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_resource.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_response.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_streaming.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_types.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/__init__.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_datetime_parse.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_logs.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_proxy.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_reflection.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_resources_proxy.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_streams.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_sync.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_transform.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/_utils/_typing.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/lib/.keep +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/py.typed +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/resources/__init__.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/base_checkout_intent.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/brand_retrieve_response.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/buyer.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/buyer_param.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/checkout_intent_add_payment_params.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/checkout_intent_confirm_params.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/checkout_intent_create_params.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/money.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/src/checkout_intents/types/offer.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/__init__.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/api_resources/__init__.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/api_resources/test_brands.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/conftest.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/sample_file.txt +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_deepcopy.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_extract_files.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_files.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_models.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_qs.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_required_args.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_response.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_streaming.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_transform.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_utils/test_datetime_parse.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_utils/test_proxy.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/test_utils/test_typing.py +0 -0
- {checkout_intents-0.1.0 → checkout_intents-0.3.0}/tests/utils.py +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0 (2025-11-18)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.2.0...v0.3.0](https://github.com/rye-com/checkout-intents-python/compare/v0.2.0...v0.3.0)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* Add python sdk target to stainless config ([eea256f](https://github.com/rye-com/checkout-intents-python/commit/eea256fef46bb35554488dba5a0818345096a66a))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* **docs:** supply valid buyer details ([12d25b1](https://github.com/rye-com/checkout-intents-python/commit/12d25b12808a05aaedcf48fc97384b5da40ca7e4))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Chores
|
|
18
|
+
|
|
19
|
+
* **internal:** format code ([445dea0](https://github.com/rye-com/checkout-intents-python/commit/445dea070ddcc8574d0304001e79bd25ca2f9de7))
|
|
20
|
+
|
|
21
|
+
## 0.2.0 (2025-11-13)
|
|
22
|
+
|
|
23
|
+
Full Changelog: [v0.1.0...v0.2.0](https://github.com/rye-com/checkout-intents-python/compare/v0.1.0...v0.2.0)
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* **api:** add polling helpers ([35dfc75](https://github.com/rye-com/checkout-intents-python/commit/35dfc75a2335fabb2ad1bab4b14f3f231deca600))
|
|
28
|
+
* **api:** infer environment from api key ([341d678](https://github.com/rye-com/checkout-intents-python/commit/341d6781d5275abec09fcc6d4634d3725f096674))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* **compat:** update signatures of `model_dump` and `model_dump_json` for Pydantic v1 ([004dd94](https://github.com/rye-com/checkout-intents-python/commit/004dd94cb5ec8647b21ba2568744bbb3e850c132))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Chores
|
|
37
|
+
|
|
38
|
+
* **internal:** add type ignore annotations ([0d0990e](https://github.com/rye-com/checkout-intents-python/commit/0d0990e8b9f83614725366b69df65ca2c9aec402))
|
|
39
|
+
* **internal:** replace rye with uv ([6cc9fcc](https://github.com/rye-com/checkout-intents-python/commit/6cc9fcc05af9040b863187affc79323812af3d83))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Documentation
|
|
43
|
+
|
|
44
|
+
* **api:** add polling helpers ([7bd9f19](https://github.com/rye-com/checkout-intents-python/commit/7bd9f19fbec2bdc289cc3ace4edfa10e0914b3a2))
|
|
45
|
+
* **internal:** replace rye with uv ([7fbabe6](https://github.com/rye-com/checkout-intents-python/commit/7fbabe69d822fc3577a1762804dae36e9ea7385a))
|
|
46
|
+
|
|
47
|
+
## 0.1.0 (2025-11-11)
|
|
48
|
+
|
|
49
|
+
Full Changelog: [v0.0.1...v0.1.0](https://github.com/rye-com/checkout-intents-python/compare/v0.0.1...v0.1.0)
|
|
50
|
+
|
|
51
|
+
### Features
|
|
52
|
+
|
|
53
|
+
* **api:** api update ([e4a0e20](https://github.com/rye-com/checkout-intents-python/commit/e4a0e206d7566f904ac22caea8954990ad5c7271))
|
|
54
|
+
* **api:** api update ([7d95f0d](https://github.com/rye-com/checkout-intents-python/commit/7d95f0db63098d4edf209c7291959eb5f08df44b))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
### Chores
|
|
58
|
+
|
|
59
|
+
* configure new SDK language ([a8f36d4](https://github.com/rye-com/checkout-intents-python/commit/a8f36d46dc5c0d3e868d289132bb83465736d0f5))
|
|
60
|
+
* update SDK settings ([5271e8a](https://github.com/rye-com/checkout-intents-python/commit/5271e8aa9f149e67b203919039afb2f61deca5e2))
|
|
61
|
+
* update SDK settings ([949efc6](https://github.com/rye-com/checkout-intents-python/commit/949efc6b67a53d856d11214bc6a924d879c2dfab))
|
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
## Setting up the environment
|
|
2
2
|
|
|
3
|
-
### With
|
|
3
|
+
### With `uv`
|
|
4
4
|
|
|
5
|
-
We use [
|
|
5
|
+
We use [uv](https://docs.astral.sh/uv/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run:
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
$ ./scripts/bootstrap
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Or [install
|
|
11
|
+
Or [install uv manually](https://docs.astral.sh/uv/getting-started/installation/) and run:
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
$
|
|
14
|
+
$ uv sync --all-extras
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
You can then run scripts using `
|
|
17
|
+
You can then run scripts using `uv run python script.py` or by manually activating the virtual environment:
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
#
|
|
20
|
+
# manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work
|
|
21
21
|
$ source .venv/bin/activate
|
|
22
22
|
|
|
23
|
-
# now you can omit the `
|
|
23
|
+
# now you can omit the `uv run` prefix
|
|
24
24
|
$ python script.py
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
### Without
|
|
27
|
+
### Without `uv`
|
|
28
28
|
|
|
29
|
-
Alternatively if you don't want to install `
|
|
29
|
+
Alternatively if you don't want to install `uv`, you can stick with the standard `pip` setup by ensuring you have the Python version specified in `.python-version`, create a virtual environment however you desire and then install dependencies using this command:
|
|
30
30
|
|
|
31
31
|
```sh
|
|
32
32
|
$ pip install -r requirements-dev.lock
|
|
@@ -45,7 +45,7 @@ All files in the `examples/` directory are not modified by the generator and can
|
|
|
45
45
|
```py
|
|
46
46
|
# add an example to examples/<your-example>.py
|
|
47
47
|
|
|
48
|
-
#!/usr/bin/env -S
|
|
48
|
+
#!/usr/bin/env -S uv run python
|
|
49
49
|
…
|
|
50
50
|
```
|
|
51
51
|
|
|
@@ -57,7 +57,7 @@ $ ./examples/<your-example>.py
|
|
|
57
57
|
|
|
58
58
|
## Using the repository from source
|
|
59
59
|
|
|
60
|
-
If you
|
|
60
|
+
If you'd like to use the repository from source, you can either install from git or link to a cloned repository:
|
|
61
61
|
|
|
62
62
|
To install via git:
|
|
63
63
|
|
|
@@ -72,7 +72,7 @@ Building this package will create two files in the `dist/` directory, a `.tar.gz
|
|
|
72
72
|
To create a distributable version of the library, all you have to do is run this command:
|
|
73
73
|
|
|
74
74
|
```sh
|
|
75
|
-
$
|
|
75
|
+
$ uv build
|
|
76
76
|
# or
|
|
77
77
|
$ python -m build
|
|
78
78
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: checkout-intents
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: The official Python library for the Checkout Intents API
|
|
5
5
|
Project-URL: Homepage, https://github.com/rye-com/checkout-intents-python
|
|
6
6
|
Project-URL: Repository, https://github.com/rye-com/checkout-intents-python
|
|
@@ -59,9 +59,11 @@ pip install checkout-intents
|
|
|
59
59
|
The full API of this library can be found in [api.md](https://github.com/rye-com/checkout-intents-python/tree/main/api.md).
|
|
60
60
|
|
|
61
61
|
```python
|
|
62
|
+
import os
|
|
62
63
|
from checkout_intents import CheckoutIntents
|
|
63
64
|
|
|
64
65
|
client = CheckoutIntents(
|
|
66
|
+
api_key=os.environ.get("CHECKOUT_INTENTS_API_KEY"), # This is the default and can be omitted
|
|
65
67
|
# defaults to "staging".
|
|
66
68
|
environment="production",
|
|
67
69
|
)
|
|
@@ -74,7 +76,7 @@ checkout_intent = client.checkout_intents.create(
|
|
|
74
76
|
"email": "john.doe@example.com",
|
|
75
77
|
"first_name": "John",
|
|
76
78
|
"last_name": "Doe",
|
|
77
|
-
"phone": "
|
|
79
|
+
"phone": "1234567890",
|
|
78
80
|
"postal_code": "10001",
|
|
79
81
|
"province": "NY",
|
|
80
82
|
},
|
|
@@ -88,15 +90,109 @@ we recommend using [python-dotenv](https://pypi.org/project/python-dotenv/)
|
|
|
88
90
|
to add `CHECKOUT_INTENTS_API_KEY="My API Key"` to your `.env` file
|
|
89
91
|
so that your API Key is not stored in source control.
|
|
90
92
|
|
|
93
|
+
### Polling Helpers
|
|
94
|
+
|
|
95
|
+
This SDK includes helper methods for the asynchronous checkout flow. The recommended pattern follows Rye's two-phase checkout:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from checkout_intents import CheckoutIntents
|
|
99
|
+
|
|
100
|
+
client = CheckoutIntents()
|
|
101
|
+
|
|
102
|
+
# Phase 1: Create and wait for offer
|
|
103
|
+
intent = client.checkout_intents.create_and_poll(
|
|
104
|
+
buyer={
|
|
105
|
+
"address1": "123 Main St",
|
|
106
|
+
"city": "New York",
|
|
107
|
+
"country": "US",
|
|
108
|
+
"email": "john.doe@example.com",
|
|
109
|
+
"first_name": "John",
|
|
110
|
+
"last_name": "Doe",
|
|
111
|
+
"phone": "1234567890",
|
|
112
|
+
"postal_code": "10001",
|
|
113
|
+
"province": "NY",
|
|
114
|
+
},
|
|
115
|
+
product_url="https://example.com/product",
|
|
116
|
+
quantity=1,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Handle failure during offer retrieval
|
|
120
|
+
if intent.state == "failed":
|
|
121
|
+
print(f"Failed: {intent.failure_reason}")
|
|
122
|
+
else:
|
|
123
|
+
# Review pricing with user
|
|
124
|
+
print(f"Total: {intent.offer.cost.total}")
|
|
125
|
+
|
|
126
|
+
# Phase 2: Confirm and wait for completion
|
|
127
|
+
completed = client.checkout_intents.confirm_and_poll(
|
|
128
|
+
intent.id,
|
|
129
|
+
payment_method={
|
|
130
|
+
"type": "stripe_token",
|
|
131
|
+
"stripe_token": "tok_visa",
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
print(f"Status: {completed.state}")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
For more examples, see the [`examples/`](https://github.com/rye-com/checkout-intents-python/tree/main/./examples) directory:
|
|
139
|
+
|
|
140
|
+
- [`complete-checkout-intent.py`](https://github.com/rye-com/checkout-intents-python/tree/main/./examples/complete-checkout-intent.py) - Recommended two-phase flow
|
|
141
|
+
- [`error-handling.py`](https://github.com/rye-com/checkout-intents-python/tree/main/./examples/error-handling.py) - Timeout and error handling with `PollTimeoutError`
|
|
142
|
+
|
|
143
|
+
Available polling methods:
|
|
144
|
+
|
|
145
|
+
- `create_and_poll()` - Create and poll until offer is ready (awaiting_confirmation or failed)
|
|
146
|
+
- `confirm_and_poll()` - Confirm and poll until completion (completed or failed)
|
|
147
|
+
- `poll_until_completed()` - Poll until completed or failed
|
|
148
|
+
- `poll_until_awaiting_confirmation()` - Poll until offer is ready or failed
|
|
149
|
+
|
|
150
|
+
All polling methods support customizable timeouts:
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
# Configure polling behavior
|
|
154
|
+
intent = client.checkout_intents.poll_until_completed(
|
|
155
|
+
intent_id,
|
|
156
|
+
poll_interval=5.0, # Poll every 5 seconds (default)
|
|
157
|
+
max_attempts=120, # Try up to 120 times, ~10 minutes (default)
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Handling Polling Timeouts
|
|
162
|
+
|
|
163
|
+
When polling operations exceed `max_attempts`, a `PollTimeoutError` is raised with helpful context:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from checkout_intents import CheckoutIntents, PollTimeoutError
|
|
167
|
+
|
|
168
|
+
client = CheckoutIntents()
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
intent = client.checkout_intents.poll_until_completed(
|
|
172
|
+
intent_id,
|
|
173
|
+
poll_interval=5.0,
|
|
174
|
+
max_attempts=60,
|
|
175
|
+
)
|
|
176
|
+
except PollTimeoutError as e:
|
|
177
|
+
print(f"Polling timed out for intent: {e.intent_id}")
|
|
178
|
+
print(f"Attempted {e.attempts} times over {(e.attempts * e.poll_interval) / 1000}s")
|
|
179
|
+
|
|
180
|
+
# You can retrieve the current state manually
|
|
181
|
+
current_intent = client.checkout_intents.retrieve(e.intent_id)
|
|
182
|
+
print(f"Current state: {current_intent.state}")
|
|
183
|
+
```
|
|
184
|
+
|
|
91
185
|
## Async usage
|
|
92
186
|
|
|
93
187
|
Simply import `AsyncCheckoutIntents` instead of `CheckoutIntents` and use `await` with each API call:
|
|
94
188
|
|
|
95
189
|
```python
|
|
190
|
+
import os
|
|
96
191
|
import asyncio
|
|
97
192
|
from checkout_intents import AsyncCheckoutIntents
|
|
98
193
|
|
|
99
194
|
client = AsyncCheckoutIntents(
|
|
195
|
+
api_key=os.environ.get("CHECKOUT_INTENTS_API_KEY"), # This is the default and can be omitted
|
|
100
196
|
# defaults to "staging".
|
|
101
197
|
environment="production",
|
|
102
198
|
)
|
|
@@ -111,7 +207,7 @@ async def main() -> None:
|
|
|
111
207
|
"email": "john.doe@example.com",
|
|
112
208
|
"first_name": "John",
|
|
113
209
|
"last_name": "Doe",
|
|
114
|
-
"phone": "
|
|
210
|
+
"phone": "1234567890",
|
|
115
211
|
"postal_code": "10001",
|
|
116
212
|
"province": "NY",
|
|
117
213
|
},
|
|
@@ -146,6 +242,7 @@ from checkout_intents import AsyncCheckoutIntents
|
|
|
146
242
|
|
|
147
243
|
async def main() -> None:
|
|
148
244
|
async with AsyncCheckoutIntents(
|
|
245
|
+
api_key="My API Key",
|
|
149
246
|
http_client=DefaultAioHttpClient(),
|
|
150
247
|
) as client:
|
|
151
248
|
checkout_intent = await client.checkout_intents.create(
|
|
@@ -156,7 +253,7 @@ async def main() -> None:
|
|
|
156
253
|
"email": "john.doe@example.com",
|
|
157
254
|
"first_name": "John",
|
|
158
255
|
"last_name": "Doe",
|
|
159
|
-
"phone": "
|
|
256
|
+
"phone": "1234567890",
|
|
160
257
|
"postal_code": "10001",
|
|
161
258
|
"province": "NY",
|
|
162
259
|
},
|
|
@@ -177,6 +274,77 @@ Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typ
|
|
|
177
274
|
|
|
178
275
|
Typed requests and responses provide autocomplete and documentation within your editor. If you would like to see type errors in VS Code to help catch bugs earlier, set `python.analysis.typeCheckingMode` to `basic`.
|
|
179
276
|
|
|
277
|
+
## Pagination
|
|
278
|
+
|
|
279
|
+
List methods in the Checkout Intents API are paginated.
|
|
280
|
+
|
|
281
|
+
This library provides auto-paginating iterators with each list response, so you do not have to request successive pages manually:
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
from checkout_intents import CheckoutIntents
|
|
285
|
+
|
|
286
|
+
client = CheckoutIntents()
|
|
287
|
+
|
|
288
|
+
all_checkout_intents = []
|
|
289
|
+
# Automatically fetches more pages as needed.
|
|
290
|
+
for checkout_intent in client.checkout_intents.list(
|
|
291
|
+
limit=20,
|
|
292
|
+
):
|
|
293
|
+
# Do something with checkout_intent here
|
|
294
|
+
all_checkout_intents.append(checkout_intent)
|
|
295
|
+
print(all_checkout_intents)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Or, asynchronously:
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
import asyncio
|
|
302
|
+
from checkout_intents import AsyncCheckoutIntents
|
|
303
|
+
|
|
304
|
+
client = AsyncCheckoutIntents()
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
async def main() -> None:
|
|
308
|
+
all_checkout_intents = []
|
|
309
|
+
# Iterate through items across all pages, issuing requests as needed.
|
|
310
|
+
async for checkout_intent in client.checkout_intents.list(
|
|
311
|
+
limit=20,
|
|
312
|
+
):
|
|
313
|
+
all_checkout_intents.append(checkout_intent)
|
|
314
|
+
print(all_checkout_intents)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
asyncio.run(main())
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Alternatively, you can use the `.has_next_page()`, `.next_page_info()`, or `.get_next_page()` methods for more granular control working with pages:
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
first_page = await client.checkout_intents.list(
|
|
324
|
+
limit=20,
|
|
325
|
+
)
|
|
326
|
+
if first_page.has_next_page():
|
|
327
|
+
print(f"will fetch next page using these details: {first_page.next_page_info()}")
|
|
328
|
+
next_page = await first_page.get_next_page()
|
|
329
|
+
print(f"number of items we just fetched: {len(next_page.data)}")
|
|
330
|
+
|
|
331
|
+
# Remove `await` for non-async usage.
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Or just work directly with the returned data:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
first_page = await client.checkout_intents.list(
|
|
338
|
+
limit=20,
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
print(f"next page cursor: {first_page.page_info.end_cursor}") # => "next page cursor: ..."
|
|
342
|
+
for checkout_intent in first_page.data:
|
|
343
|
+
print(checkout_intent)
|
|
344
|
+
|
|
345
|
+
# Remove `await` for non-async usage.
|
|
346
|
+
```
|
|
347
|
+
|
|
180
348
|
## Nested params
|
|
181
349
|
|
|
182
350
|
Nested parameters are dictionaries, typed using `TypedDict`, for example:
|
|
@@ -194,12 +362,12 @@ checkout_intent = client.checkout_intents.create(
|
|
|
194
362
|
"email": "john.doe@example.com",
|
|
195
363
|
"first_name": "John",
|
|
196
364
|
"last_name": "Doe",
|
|
197
|
-
"phone": "
|
|
365
|
+
"phone": "1234567890",
|
|
198
366
|
"postal_code": "10001",
|
|
199
367
|
"province": "NY",
|
|
200
368
|
},
|
|
201
369
|
product_url="productUrl",
|
|
202
|
-
quantity=
|
|
370
|
+
quantity=1,
|
|
203
371
|
)
|
|
204
372
|
print(checkout_intent.buyer)
|
|
205
373
|
```
|
|
@@ -228,7 +396,7 @@ try:
|
|
|
228
396
|
"email": "john.doe@example.com",
|
|
229
397
|
"first_name": "John",
|
|
230
398
|
"last_name": "Doe",
|
|
231
|
-
"phone": "
|
|
399
|
+
"phone": "1234567890",
|
|
232
400
|
"postal_code": "10001",
|
|
233
401
|
"province": "NY",
|
|
234
402
|
},
|
|
@@ -258,6 +426,26 @@ Error codes are as follows:
|
|
|
258
426
|
| 429 | `RateLimitError` |
|
|
259
427
|
| >=500 | `InternalServerError` |
|
|
260
428
|
| N/A | `APIConnectionError` |
|
|
429
|
+
| N/A | `PollTimeoutError` |
|
|
430
|
+
|
|
431
|
+
### Polling Timeout Errors
|
|
432
|
+
|
|
433
|
+
When using polling helper methods, if the operation exceeds the configured `max_attempts`, a `PollTimeoutError` is raised. This error includes detailed context about the timeout:
|
|
434
|
+
|
|
435
|
+
```python
|
|
436
|
+
from checkout_intents import CheckoutIntents, PollTimeoutError
|
|
437
|
+
|
|
438
|
+
try:
|
|
439
|
+
intent = client.checkout_intents.poll_until_completed("intent_id")
|
|
440
|
+
except PollTimeoutError as e:
|
|
441
|
+
# Access timeout details
|
|
442
|
+
print(f"Intent ID: {e.intent_id}")
|
|
443
|
+
print(f"Attempts: {e.attempts}")
|
|
444
|
+
print(f"Poll interval: {e.poll_interval}s")
|
|
445
|
+
print(f"Max attempts: {e.max_attempts}")
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
See the [error-handling.py example](https://github.com/rye-com/checkout-intents-python/tree/main/./examples/error-handling.py) for more detailed timeout handling patterns.
|
|
261
449
|
|
|
262
450
|
### Retries
|
|
263
451
|
|
|
@@ -285,7 +473,7 @@ client.with_options(max_retries=5).checkout_intents.create(
|
|
|
285
473
|
"email": "john.doe@example.com",
|
|
286
474
|
"first_name": "John",
|
|
287
475
|
"last_name": "Doe",
|
|
288
|
-
"phone": "
|
|
476
|
+
"phone": "1234567890",
|
|
289
477
|
"postal_code": "10001",
|
|
290
478
|
"province": "NY",
|
|
291
479
|
},
|
|
@@ -322,7 +510,7 @@ client.with_options(timeout=5.0).checkout_intents.create(
|
|
|
322
510
|
"email": "john.doe@example.com",
|
|
323
511
|
"first_name": "John",
|
|
324
512
|
"last_name": "Doe",
|
|
325
|
-
"phone": "
|
|
513
|
+
"phone": "1234567890",
|
|
326
514
|
"postal_code": "10001",
|
|
327
515
|
"province": "NY",
|
|
328
516
|
},
|
|
@@ -377,7 +565,7 @@ response = client.checkout_intents.with_raw_response.create(
|
|
|
377
565
|
"email": "john.doe@example.com",
|
|
378
566
|
"first_name": "John",
|
|
379
567
|
"last_name": "Doe",
|
|
380
|
-
"phone": "
|
|
568
|
+
"phone": "1234567890",
|
|
381
569
|
"postal_code": "10001",
|
|
382
570
|
"province": "NY",
|
|
383
571
|
},
|
|
@@ -409,7 +597,7 @@ with client.checkout_intents.with_streaming_response.create(
|
|
|
409
597
|
"email": "john.doe@example.com",
|
|
410
598
|
"first_name": "John",
|
|
411
599
|
"last_name": "Doe",
|
|
412
|
-
"phone": "
|
|
600
|
+
"phone": "1234567890",
|
|
413
601
|
"postal_code": "10001",
|
|
414
602
|
"province": "NY",
|
|
415
603
|
},
|