prelude-python-sdk 0.1.0b1__tar.gz → 0.2.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.
- prelude_python_sdk-0.2.0/.release-please-manifest.json +3 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/CHANGELOG.md +63 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/PKG-INFO +21 -3
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/README.md +20 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/SECURITY.md +2 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/pyproject.toml +3 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/requirements-dev.lock +2 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_base_client.py +18 -100
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_client.py +1 -1
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_constants.py +1 -1
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_models.py +8 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_response.py +9 -3
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_sync.py +17 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_transform.py +11 -1
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_version.py +1 -1
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/resources/transactional.py +16 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/resources/verification.py +14 -8
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/resources/watch.py +10 -6
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/transactional_send_params.py +8 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/verification_check_params.py +8 -4
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/verification_create_params.py +36 -9
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/watch_feed_back_params.py +8 -4
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/watch_predict_params.py +8 -4
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/api_resources/test_transactional.py +2 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/api_resources/test_verification.py +8 -2
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_client.py +52 -27
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_transform.py +10 -1
- prelude_python_sdk-0.1.0b1/.release-please-manifest.json +0 -3
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/.gitignore +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/CONTRIBUTING.md +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/LICENSE +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/api.md +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/bin/check-release-environment +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/bin/publish-pypi +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/examples/.keep +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/mypy.ini +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/noxfile.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/release-please-config.json +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/requirements.lock +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude/lib/.keep +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/__init__.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_compat.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_exceptions.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_files.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_qs.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_resource.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_streaming.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_types.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/__init__.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_logs.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_proxy.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_reflection.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_streams.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_typing.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_utils.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/lib/.keep +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/py.typed +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/resources/__init__.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/__init__.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/transactional_send_response.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/verification_check_response.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/verification_create_response.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/watch_feed_back_response.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/types/watch_predict_response.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_sdk/lib/.keep +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/__init__.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/api_resources/__init__.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/api_resources/test_watch.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/conftest.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/sample_file.txt +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_deepcopy.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_extract_files.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_files.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_models.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_qs.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_required_args.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_response.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_streaming.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_utils/test_proxy.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/test_utils/test_typing.py +0 -0
- {prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/tests/utils.py +0 -0
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 (2025-03-11)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0...v0.2.0](https://github.com/prelude-so/python-sdk/compare/v0.1.0...v0.2.0)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **api:** update via SDK Studio ([#74](https://github.com/prelude-so/python-sdk/issues/74)) ([f9658f1](https://github.com/prelude-so/python-sdk/commit/f9658f1ebacf25f72ae9a8e9076958055c2de570))
|
|
10
|
+
* **client:** allow passing `NotGiven` for body ([#64](https://github.com/prelude-so/python-sdk/issues/64)) ([b32f989](https://github.com/prelude-so/python-sdk/commit/b32f98934973c8c2cfacd3ad9a6c0817405ec3c9))
|
|
11
|
+
* **client:** send `X-Stainless-Read-Timeout` header ([#59](https://github.com/prelude-so/python-sdk/issues/59)) ([6dcc82a](https://github.com/prelude-so/python-sdk/commit/6dcc82a592bdad9316eae8ab7b93095d2176caf3))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **client:** mark some request bodies as optional ([b32f989](https://github.com/prelude-so/python-sdk/commit/b32f98934973c8c2cfacd3ad9a6c0817405ec3c9))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Chores
|
|
20
|
+
|
|
21
|
+
* **docs:** update client docstring ([#70](https://github.com/prelude-so/python-sdk/issues/70)) ([61cec66](https://github.com/prelude-so/python-sdk/commit/61cec666606b1999db0d6c7bc08e77aa2aed869e))
|
|
22
|
+
* **internal:** bummp ruff dependency ([#58](https://github.com/prelude-so/python-sdk/issues/58)) ([2381d4a](https://github.com/prelude-so/python-sdk/commit/2381d4a22cfd032f97470e0d012b6fc8a133305c))
|
|
23
|
+
* **internal:** change default timeout to an int ([#56](https://github.com/prelude-so/python-sdk/issues/56)) ([160f11e](https://github.com/prelude-so/python-sdk/commit/160f11e767ab3d5f7f1fdd8e423a6277a651fc82))
|
|
24
|
+
* **internal:** codegen related update ([#63](https://github.com/prelude-so/python-sdk/issues/63)) ([0516484](https://github.com/prelude-so/python-sdk/commit/05164849027af87dba0911340086b7904a7171f2))
|
|
25
|
+
* **internal:** codegen related update ([#67](https://github.com/prelude-so/python-sdk/issues/67)) ([32798a9](https://github.com/prelude-so/python-sdk/commit/32798a95e57769f4fc29abac8ba2dcd58d55a6ef))
|
|
26
|
+
* **internal:** codegen related update ([#68](https://github.com/prelude-so/python-sdk/issues/68)) ([f921517](https://github.com/prelude-so/python-sdk/commit/f921517c1c0b0c8197886f6948cecf56a1fdea87))
|
|
27
|
+
* **internal:** codegen related update ([#71](https://github.com/prelude-so/python-sdk/issues/71)) ([ec7fd9f](https://github.com/prelude-so/python-sdk/commit/ec7fd9feb6f45caf98d9667072910b6a0ebfc25d))
|
|
28
|
+
* **internal:** fix devcontainers setup ([#65](https://github.com/prelude-so/python-sdk/issues/65)) ([da3f6c6](https://github.com/prelude-so/python-sdk/commit/da3f6c6f48241dfe0909aabeb3eec2ba83c0e8ef))
|
|
29
|
+
* **internal:** fix type traversing dictionary params ([#60](https://github.com/prelude-so/python-sdk/issues/60)) ([9bf6b95](https://github.com/prelude-so/python-sdk/commit/9bf6b958c8b1ac01d191fb3ffdad7beb9ad0f06a))
|
|
30
|
+
* **internal:** minor type handling changes ([#61](https://github.com/prelude-so/python-sdk/issues/61)) ([0639a28](https://github.com/prelude-so/python-sdk/commit/0639a28c925209b6d2adb2d3022f350044bf5995))
|
|
31
|
+
* **internal:** properly set __pydantic_private__ ([#66](https://github.com/prelude-so/python-sdk/issues/66)) ([affe056](https://github.com/prelude-so/python-sdk/commit/affe056afdc01fc46d7dc23a003b69bb8528c16d))
|
|
32
|
+
* **internal:** update client tests ([#62](https://github.com/prelude-so/python-sdk/issues/62)) ([6096c2a](https://github.com/prelude-so/python-sdk/commit/6096c2aff213dca771b4e8f8675569e1bc1d1edf))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Documentation
|
|
36
|
+
|
|
37
|
+
* revise readme docs about nested params ([#72](https://github.com/prelude-so/python-sdk/issues/72)) ([bff24a7](https://github.com/prelude-so/python-sdk/commit/bff24a785fbd56e126249cbfbc8f2af5c179b8a6))
|
|
38
|
+
* update URLs from stainlessapi.com to stainless.com ([#69](https://github.com/prelude-so/python-sdk/issues/69)) ([f3c2dc7](https://github.com/prelude-so/python-sdk/commit/f3c2dc7a219c04490aa22cdab677410136dc09d3))
|
|
39
|
+
|
|
40
|
+
## 0.1.0 (2025-02-05)
|
|
41
|
+
|
|
42
|
+
Full Changelog: [v0.1.0-beta.1...v0.1.0](https://github.com/prelude-so/python-sdk/compare/v0.1.0-beta.1...v0.1.0)
|
|
43
|
+
|
|
44
|
+
### Features
|
|
45
|
+
|
|
46
|
+
* **api:** update via SDK Studio ([#54](https://github.com/prelude-so/python-sdk/issues/54)) ([882a265](https://github.com/prelude-so/python-sdk/commit/882a265dbfd660fa86be9fceafd3bf095f332a7f))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
### Bug Fixes
|
|
50
|
+
|
|
51
|
+
* **tests:** make test_get_platform less flaky ([#50](https://github.com/prelude-so/python-sdk/issues/50)) ([97fe150](https://github.com/prelude-so/python-sdk/commit/97fe150523ae369a3c1729c8a64ddcdbc2660fc6))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
### Chores
|
|
55
|
+
|
|
56
|
+
* **internal:** avoid pytest-asyncio deprecation warning ([#51](https://github.com/prelude-so/python-sdk/issues/51)) ([0730cb0](https://github.com/prelude-so/python-sdk/commit/0730cb06e3db10b3a2ab537a23eafbe469e6b316))
|
|
57
|
+
* **internal:** bump pyright dependency ([#47](https://github.com/prelude-so/python-sdk/issues/47)) ([4fade6c](https://github.com/prelude-so/python-sdk/commit/4fade6ce965301b6fd4285c6192ce81b078296d6))
|
|
58
|
+
* **internal:** minor formatting changes ([#53](https://github.com/prelude-so/python-sdk/issues/53)) ([a2296ef](https://github.com/prelude-so/python-sdk/commit/a2296ef6d9581d4557832e42d683ec6a503b9b2e))
|
|
59
|
+
* **internal:** minor style changes ([#52](https://github.com/prelude-so/python-sdk/issues/52)) ([04f378c](https://github.com/prelude-so/python-sdk/commit/04f378c43cdcc795ca4a4967075db0f1480bf358))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Documentation
|
|
63
|
+
|
|
64
|
+
* **raw responses:** fix duplicate `the` ([#49](https://github.com/prelude-so/python-sdk/issues/49)) ([b76a3a0](https://github.com/prelude-so/python-sdk/commit/b76a3a0e0376777859a1e938015309fc569734b0))
|
|
65
|
+
|
|
3
66
|
## 0.1.0-beta.1 (2025-01-14)
|
|
4
67
|
|
|
5
68
|
Full Changelog: [v0.1.0-alpha.7...v0.1.0-beta.1](https://github.com/prelude-so/python-sdk/compare/v0.1.0-alpha.7...v0.1.0-beta.1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: prelude-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: The official Python library for the Prelude API
|
|
5
5
|
Project-URL: Homepage, https://github.com/prelude-so/python-sdk
|
|
6
6
|
Project-URL: Repository, https://github.com/prelude-so/python-sdk
|
|
@@ -38,7 +38,7 @@ The Prelude Python library provides convenient access to the Prelude REST API fr
|
|
|
38
38
|
application. The library includes type definitions for all request params and response fields,
|
|
39
39
|
and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
|
|
40
40
|
|
|
41
|
-
It is generated with [Stainless](https://www.
|
|
41
|
+
It is generated with [Stainless](https://www.stainless.com/).
|
|
42
42
|
|
|
43
43
|
## Documentation
|
|
44
44
|
|
|
@@ -48,7 +48,7 @@ The REST API documentation can be found on [docs.prelude.so](https://docs.prelud
|
|
|
48
48
|
|
|
49
49
|
```sh
|
|
50
50
|
# install from PyPI
|
|
51
|
-
pip install
|
|
51
|
+
pip install prelude-python-sdk
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
## Usage
|
|
@@ -115,6 +115,24 @@ Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typ
|
|
|
115
115
|
|
|
116
116
|
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`.
|
|
117
117
|
|
|
118
|
+
## Nested params
|
|
119
|
+
|
|
120
|
+
Nested parameters are dictionaries, typed using `TypedDict`, for example:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from prelude_python_sdk import Prelude
|
|
124
|
+
|
|
125
|
+
client = Prelude()
|
|
126
|
+
|
|
127
|
+
verification = client.verification.create(
|
|
128
|
+
target={
|
|
129
|
+
"type": "phone_number",
|
|
130
|
+
"value": "+30123456789",
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
print(verification.target)
|
|
134
|
+
```
|
|
135
|
+
|
|
118
136
|
## Handling errors
|
|
119
137
|
|
|
120
138
|
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `prelude_python_sdk.APIConnectionError` is raised.
|
|
@@ -6,7 +6,7 @@ The Prelude Python library provides convenient access to the Prelude REST API fr
|
|
|
6
6
|
application. The library includes type definitions for all request params and response fields,
|
|
7
7
|
and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
|
|
8
8
|
|
|
9
|
-
It is generated with [Stainless](https://www.
|
|
9
|
+
It is generated with [Stainless](https://www.stainless.com/).
|
|
10
10
|
|
|
11
11
|
## Documentation
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ The REST API documentation can be found on [docs.prelude.so](https://docs.prelud
|
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
18
|
# install from PyPI
|
|
19
|
-
pip install
|
|
19
|
+
pip install prelude-python-sdk
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## Usage
|
|
@@ -83,6 +83,24 @@ Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typ
|
|
|
83
83
|
|
|
84
84
|
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`.
|
|
85
85
|
|
|
86
|
+
## Nested params
|
|
87
|
+
|
|
88
|
+
Nested parameters are dictionaries, typed using `TypedDict`, for example:
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from prelude_python_sdk import Prelude
|
|
92
|
+
|
|
93
|
+
client = Prelude()
|
|
94
|
+
|
|
95
|
+
verification = client.verification.create(
|
|
96
|
+
target={
|
|
97
|
+
"type": "phone_number",
|
|
98
|
+
"value": "+30123456789",
|
|
99
|
+
},
|
|
100
|
+
)
|
|
101
|
+
print(verification.target)
|
|
102
|
+
```
|
|
103
|
+
|
|
86
104
|
## Handling errors
|
|
87
105
|
|
|
88
106
|
When the library is unable to connect to the API (for example, due to network connection problems or a timeout), a subclass of `prelude_python_sdk.APIConnectionError` is raised.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Reporting Security Issues
|
|
4
4
|
|
|
5
|
-
This SDK is generated by [Stainless Software Inc](http://
|
|
5
|
+
This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
|
|
6
6
|
|
|
7
|
-
To report a security issue, please contact the Stainless team at security@
|
|
7
|
+
To report a security issue, please contact the Stainless team at security@stainless.com.
|
|
8
8
|
|
|
9
9
|
## Responsible Disclosure
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "prelude-python-sdk"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0"
|
|
4
4
|
description = "The official Python library for the Prelude API"
|
|
5
5
|
dynamic = ["readme"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -129,6 +129,7 @@ testpaths = ["tests"]
|
|
|
129
129
|
addopts = "--tb=short"
|
|
130
130
|
xfail_strict = true
|
|
131
131
|
asyncio_mode = "auto"
|
|
132
|
+
asyncio_default_fixture_loop_scope = "session"
|
|
132
133
|
filterwarnings = [
|
|
133
134
|
"error"
|
|
134
135
|
]
|
|
@@ -176,7 +177,7 @@ select = [
|
|
|
176
177
|
"T201",
|
|
177
178
|
"T203",
|
|
178
179
|
# misuse of typing.TYPE_CHECKING
|
|
179
|
-
"
|
|
180
|
+
"TC004",
|
|
180
181
|
# import rules
|
|
181
182
|
"TID251",
|
|
182
183
|
]
|
|
@@ -68,7 +68,7 @@ pydantic-core==2.27.1
|
|
|
68
68
|
# via pydantic
|
|
69
69
|
pygments==2.18.0
|
|
70
70
|
# via rich
|
|
71
|
-
pyright==1.1.
|
|
71
|
+
pyright==1.1.392.post0
|
|
72
72
|
pytest==8.3.3
|
|
73
73
|
# via pytest-asyncio
|
|
74
74
|
pytest-asyncio==0.24.0
|
|
@@ -78,7 +78,7 @@ pytz==2023.3.post1
|
|
|
78
78
|
# via dirty-equals
|
|
79
79
|
respx==0.22.0
|
|
80
80
|
rich==13.7.1
|
|
81
|
-
ruff==0.
|
|
81
|
+
ruff==0.9.4
|
|
82
82
|
setuptools==68.2.2
|
|
83
83
|
# via nodeenv
|
|
84
84
|
six==1.16.0
|
{prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_base_client.py
RENAMED
|
@@ -9,7 +9,6 @@ import asyncio
|
|
|
9
9
|
import inspect
|
|
10
10
|
import logging
|
|
11
11
|
import platform
|
|
12
|
-
import warnings
|
|
13
12
|
import email.utils
|
|
14
13
|
from types import TracebackType
|
|
15
14
|
from random import random
|
|
@@ -36,7 +35,7 @@ import anyio
|
|
|
36
35
|
import httpx
|
|
37
36
|
import distro
|
|
38
37
|
import pydantic
|
|
39
|
-
from httpx import URL
|
|
38
|
+
from httpx import URL
|
|
40
39
|
from pydantic import PrivateAttr
|
|
41
40
|
|
|
42
41
|
from . import _exceptions
|
|
@@ -51,19 +50,16 @@ from ._types import (
|
|
|
51
50
|
Timeout,
|
|
52
51
|
NotGiven,
|
|
53
52
|
ResponseT,
|
|
54
|
-
Transport,
|
|
55
53
|
AnyMapping,
|
|
56
54
|
PostParser,
|
|
57
|
-
ProxiesTypes,
|
|
58
55
|
RequestFiles,
|
|
59
56
|
HttpxSendArgs,
|
|
60
|
-
AsyncTransport,
|
|
61
57
|
RequestOptions,
|
|
62
58
|
HttpxRequestFiles,
|
|
63
59
|
ModelBuilderProtocol,
|
|
64
60
|
)
|
|
65
61
|
from ._utils import is_dict, is_list, asyncify, is_given, lru_cache, is_mapping
|
|
66
|
-
from ._compat import model_copy, model_dump
|
|
62
|
+
from ._compat import PYDANTIC_V2, model_copy, model_dump
|
|
67
63
|
from ._models import GenericModel, FinalRequestOptions, validate_type, construct_type
|
|
68
64
|
from ._response import (
|
|
69
65
|
APIResponse,
|
|
@@ -207,6 +203,9 @@ class BaseSyncPage(BasePage[_T], Generic[_T]):
|
|
|
207
203
|
model: Type[_T],
|
|
208
204
|
options: FinalRequestOptions,
|
|
209
205
|
) -> None:
|
|
206
|
+
if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None:
|
|
207
|
+
self.__pydantic_private__ = {}
|
|
208
|
+
|
|
210
209
|
self._model = model
|
|
211
210
|
self._client = client
|
|
212
211
|
self._options = options
|
|
@@ -292,6 +291,9 @@ class BaseAsyncPage(BasePage[_T], Generic[_T]):
|
|
|
292
291
|
client: AsyncAPIClient,
|
|
293
292
|
options: FinalRequestOptions,
|
|
294
293
|
) -> None:
|
|
294
|
+
if PYDANTIC_V2 and getattr(self, "__pydantic_private__", None) is None:
|
|
295
|
+
self.__pydantic_private__ = {}
|
|
296
|
+
|
|
295
297
|
self._model = model
|
|
296
298
|
self._client = client
|
|
297
299
|
self._options = options
|
|
@@ -331,9 +333,6 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
331
333
|
_base_url: URL
|
|
332
334
|
max_retries: int
|
|
333
335
|
timeout: Union[float, Timeout, None]
|
|
334
|
-
_limits: httpx.Limits
|
|
335
|
-
_proxies: ProxiesTypes | None
|
|
336
|
-
_transport: Transport | AsyncTransport | None
|
|
337
336
|
_strict_response_validation: bool
|
|
338
337
|
_idempotency_header: str | None
|
|
339
338
|
_default_stream_cls: type[_DefaultStreamT] | None = None
|
|
@@ -346,9 +345,6 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
346
345
|
_strict_response_validation: bool,
|
|
347
346
|
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
348
347
|
timeout: float | Timeout | None = DEFAULT_TIMEOUT,
|
|
349
|
-
limits: httpx.Limits,
|
|
350
|
-
transport: Transport | AsyncTransport | None,
|
|
351
|
-
proxies: ProxiesTypes | None,
|
|
352
348
|
custom_headers: Mapping[str, str] | None = None,
|
|
353
349
|
custom_query: Mapping[str, object] | None = None,
|
|
354
350
|
) -> None:
|
|
@@ -356,9 +352,6 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
356
352
|
self._base_url = self._enforce_trailing_slash(URL(base_url))
|
|
357
353
|
self.max_retries = max_retries
|
|
358
354
|
self.timeout = timeout
|
|
359
|
-
self._limits = limits
|
|
360
|
-
self._proxies = proxies
|
|
361
|
-
self._transport = transport
|
|
362
355
|
self._custom_headers = custom_headers or {}
|
|
363
356
|
self._custom_query = custom_query or {}
|
|
364
357
|
self._strict_response_validation = _strict_response_validation
|
|
@@ -418,10 +411,17 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
418
411
|
if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers:
|
|
419
412
|
headers[idempotency_header] = options.idempotency_key or self._idempotency_key()
|
|
420
413
|
|
|
421
|
-
# Don't set
|
|
414
|
+
# Don't set these headers if they were already set or removed by the caller. We check
|
|
422
415
|
# `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
|
|
423
|
-
|
|
416
|
+
lower_custom_headers = [header.lower() for header in custom_headers]
|
|
417
|
+
if "x-stainless-retry-count" not in lower_custom_headers:
|
|
424
418
|
headers["x-stainless-retry-count"] = str(retries_taken)
|
|
419
|
+
if "x-stainless-read-timeout" not in lower_custom_headers:
|
|
420
|
+
timeout = self.timeout if isinstance(options.timeout, NotGiven) else options.timeout
|
|
421
|
+
if isinstance(timeout, Timeout):
|
|
422
|
+
timeout = timeout.read
|
|
423
|
+
if timeout is not None:
|
|
424
|
+
headers["x-stainless-read-timeout"] = str(timeout)
|
|
425
425
|
|
|
426
426
|
return headers
|
|
427
427
|
|
|
@@ -511,7 +511,7 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
|
511
511
|
# so that passing a `TypedDict` doesn't cause an error.
|
|
512
512
|
# https://github.com/microsoft/pyright/issues/3526#event-6715453066
|
|
513
513
|
params=self.qs.stringify(cast(Mapping[str, Any], params)) if params else None,
|
|
514
|
-
json=json_data,
|
|
514
|
+
json=json_data if is_given(json_data) else None,
|
|
515
515
|
files=files,
|
|
516
516
|
**kwargs,
|
|
517
517
|
)
|
|
@@ -787,46 +787,11 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
787
787
|
base_url: str | URL,
|
|
788
788
|
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
789
789
|
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
790
|
-
transport: Transport | None = None,
|
|
791
|
-
proxies: ProxiesTypes | None = None,
|
|
792
|
-
limits: Limits | None = None,
|
|
793
790
|
http_client: httpx.Client | None = None,
|
|
794
791
|
custom_headers: Mapping[str, str] | None = None,
|
|
795
792
|
custom_query: Mapping[str, object] | None = None,
|
|
796
793
|
_strict_response_validation: bool,
|
|
797
794
|
) -> None:
|
|
798
|
-
kwargs: dict[str, Any] = {}
|
|
799
|
-
if limits is not None:
|
|
800
|
-
warnings.warn(
|
|
801
|
-
"The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead",
|
|
802
|
-
category=DeprecationWarning,
|
|
803
|
-
stacklevel=3,
|
|
804
|
-
)
|
|
805
|
-
if http_client is not None:
|
|
806
|
-
raise ValueError("The `http_client` argument is mutually exclusive with `connection_pool_limits`")
|
|
807
|
-
else:
|
|
808
|
-
limits = DEFAULT_CONNECTION_LIMITS
|
|
809
|
-
|
|
810
|
-
if transport is not None:
|
|
811
|
-
kwargs["transport"] = transport
|
|
812
|
-
warnings.warn(
|
|
813
|
-
"The `transport` argument is deprecated. The `http_client` argument should be passed instead",
|
|
814
|
-
category=DeprecationWarning,
|
|
815
|
-
stacklevel=3,
|
|
816
|
-
)
|
|
817
|
-
if http_client is not None:
|
|
818
|
-
raise ValueError("The `http_client` argument is mutually exclusive with `transport`")
|
|
819
|
-
|
|
820
|
-
if proxies is not None:
|
|
821
|
-
kwargs["proxies"] = proxies
|
|
822
|
-
warnings.warn(
|
|
823
|
-
"The `proxies` argument is deprecated. The `http_client` argument should be passed instead",
|
|
824
|
-
category=DeprecationWarning,
|
|
825
|
-
stacklevel=3,
|
|
826
|
-
)
|
|
827
|
-
if http_client is not None:
|
|
828
|
-
raise ValueError("The `http_client` argument is mutually exclusive with `proxies`")
|
|
829
|
-
|
|
830
795
|
if not is_given(timeout):
|
|
831
796
|
# if the user passed in a custom http client with a non-default
|
|
832
797
|
# timeout set then we use that timeout.
|
|
@@ -847,12 +812,9 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
847
812
|
|
|
848
813
|
super().__init__(
|
|
849
814
|
version=version,
|
|
850
|
-
limits=limits,
|
|
851
815
|
# cast to a valid type because mypy doesn't understand our type narrowing
|
|
852
816
|
timeout=cast(Timeout, timeout),
|
|
853
|
-
proxies=proxies,
|
|
854
817
|
base_url=base_url,
|
|
855
|
-
transport=transport,
|
|
856
818
|
max_retries=max_retries,
|
|
857
819
|
custom_query=custom_query,
|
|
858
820
|
custom_headers=custom_headers,
|
|
@@ -862,9 +824,6 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
|
862
824
|
base_url=base_url,
|
|
863
825
|
# cast to a valid type because mypy doesn't understand our type narrowing
|
|
864
826
|
timeout=cast(Timeout, timeout),
|
|
865
|
-
limits=limits,
|
|
866
|
-
follow_redirects=True,
|
|
867
|
-
**kwargs, # type: ignore
|
|
868
827
|
)
|
|
869
828
|
|
|
870
829
|
def is_closed(self) -> bool:
|
|
@@ -1359,45 +1318,10 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1359
1318
|
_strict_response_validation: bool,
|
|
1360
1319
|
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1361
1320
|
timeout: float | Timeout | None | NotGiven = NOT_GIVEN,
|
|
1362
|
-
transport: AsyncTransport | None = None,
|
|
1363
|
-
proxies: ProxiesTypes | None = None,
|
|
1364
|
-
limits: Limits | None = None,
|
|
1365
1321
|
http_client: httpx.AsyncClient | None = None,
|
|
1366
1322
|
custom_headers: Mapping[str, str] | None = None,
|
|
1367
1323
|
custom_query: Mapping[str, object] | None = None,
|
|
1368
1324
|
) -> None:
|
|
1369
|
-
kwargs: dict[str, Any] = {}
|
|
1370
|
-
if limits is not None:
|
|
1371
|
-
warnings.warn(
|
|
1372
|
-
"The `connection_pool_limits` argument is deprecated. The `http_client` argument should be passed instead",
|
|
1373
|
-
category=DeprecationWarning,
|
|
1374
|
-
stacklevel=3,
|
|
1375
|
-
)
|
|
1376
|
-
if http_client is not None:
|
|
1377
|
-
raise ValueError("The `http_client` argument is mutually exclusive with `connection_pool_limits`")
|
|
1378
|
-
else:
|
|
1379
|
-
limits = DEFAULT_CONNECTION_LIMITS
|
|
1380
|
-
|
|
1381
|
-
if transport is not None:
|
|
1382
|
-
kwargs["transport"] = transport
|
|
1383
|
-
warnings.warn(
|
|
1384
|
-
"The `transport` argument is deprecated. The `http_client` argument should be passed instead",
|
|
1385
|
-
category=DeprecationWarning,
|
|
1386
|
-
stacklevel=3,
|
|
1387
|
-
)
|
|
1388
|
-
if http_client is not None:
|
|
1389
|
-
raise ValueError("The `http_client` argument is mutually exclusive with `transport`")
|
|
1390
|
-
|
|
1391
|
-
if proxies is not None:
|
|
1392
|
-
kwargs["proxies"] = proxies
|
|
1393
|
-
warnings.warn(
|
|
1394
|
-
"The `proxies` argument is deprecated. The `http_client` argument should be passed instead",
|
|
1395
|
-
category=DeprecationWarning,
|
|
1396
|
-
stacklevel=3,
|
|
1397
|
-
)
|
|
1398
|
-
if http_client is not None:
|
|
1399
|
-
raise ValueError("The `http_client` argument is mutually exclusive with `proxies`")
|
|
1400
|
-
|
|
1401
1325
|
if not is_given(timeout):
|
|
1402
1326
|
# if the user passed in a custom http client with a non-default
|
|
1403
1327
|
# timeout set then we use that timeout.
|
|
@@ -1419,11 +1343,8 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1419
1343
|
super().__init__(
|
|
1420
1344
|
version=version,
|
|
1421
1345
|
base_url=base_url,
|
|
1422
|
-
limits=limits,
|
|
1423
1346
|
# cast to a valid type because mypy doesn't understand our type narrowing
|
|
1424
1347
|
timeout=cast(Timeout, timeout),
|
|
1425
|
-
proxies=proxies,
|
|
1426
|
-
transport=transport,
|
|
1427
1348
|
max_retries=max_retries,
|
|
1428
1349
|
custom_query=custom_query,
|
|
1429
1350
|
custom_headers=custom_headers,
|
|
@@ -1433,9 +1354,6 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
|
1433
1354
|
base_url=base_url,
|
|
1434
1355
|
# cast to a valid type because mypy doesn't understand our type narrowing
|
|
1435
1356
|
timeout=cast(Timeout, timeout),
|
|
1436
|
-
limits=limits,
|
|
1437
|
-
follow_redirects=True,
|
|
1438
|
-
**kwargs, # type: ignore
|
|
1439
1357
|
)
|
|
1440
1358
|
|
|
1441
1359
|
def is_closed(self) -> bool:
|
|
@@ -241,7 +241,7 @@ class AsyncPrelude(AsyncAPIClient):
|
|
|
241
241
|
# part of our public interface in the future.
|
|
242
242
|
_strict_response_validation: bool = False,
|
|
243
243
|
) -> None:
|
|
244
|
-
"""Construct a new async
|
|
244
|
+
"""Construct a new async AsyncPrelude client instance.
|
|
245
245
|
|
|
246
246
|
This automatically infers the `api_token` argument from the `API_TOKEN` environment variable if it is not provided.
|
|
247
247
|
"""
|
{prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_constants.py
RENAMED
|
@@ -6,7 +6,7 @@ RAW_RESPONSE_HEADER = "X-Stainless-Raw-Response"
|
|
|
6
6
|
OVERRIDE_CAST_TO_HEADER = "____stainless_override_cast_to"
|
|
7
7
|
|
|
8
8
|
# default timeout is 1 minute
|
|
9
|
-
DEFAULT_TIMEOUT = httpx.Timeout(timeout=60
|
|
9
|
+
DEFAULT_TIMEOUT = httpx.Timeout(timeout=60, connect=5.0)
|
|
10
10
|
DEFAULT_MAX_RETRIES = 2
|
|
11
11
|
DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20)
|
|
12
12
|
|
|
@@ -172,7 +172,7 @@ class BaseModel(pydantic.BaseModel):
|
|
|
172
172
|
@override
|
|
173
173
|
def __str__(self) -> str:
|
|
174
174
|
# mypy complains about an invalid self arg
|
|
175
|
-
return f
|
|
175
|
+
return f"{self.__repr_name__()}({self.__repr_str__(', ')})" # type: ignore[misc]
|
|
176
176
|
|
|
177
177
|
# Override the 'construct' method in a way that supports recursive parsing without validation.
|
|
178
178
|
# Based on https://github.com/samuelcolvin/pydantic/issues/1168#issuecomment-817742836.
|
|
@@ -426,10 +426,16 @@ def construct_type(*, value: object, type_: object) -> object:
|
|
|
426
426
|
|
|
427
427
|
If the given value does not match the expected type then it is returned as-is.
|
|
428
428
|
"""
|
|
429
|
+
|
|
430
|
+
# store a reference to the original type we were given before we extract any inner
|
|
431
|
+
# types so that we can properly resolve forward references in `TypeAliasType` annotations
|
|
432
|
+
original_type = None
|
|
433
|
+
|
|
429
434
|
# we allow `object` as the input type because otherwise, passing things like
|
|
430
435
|
# `Literal['value']` will be reported as a type error by type checkers
|
|
431
436
|
type_ = cast("type[object]", type_)
|
|
432
437
|
if is_type_alias_type(type_):
|
|
438
|
+
original_type = type_ # type: ignore[unreachable]
|
|
433
439
|
type_ = type_.__value__ # type: ignore[unreachable]
|
|
434
440
|
|
|
435
441
|
# unwrap `Annotated[T, ...]` -> `T`
|
|
@@ -446,7 +452,7 @@ def construct_type(*, value: object, type_: object) -> object:
|
|
|
446
452
|
|
|
447
453
|
if is_union(origin):
|
|
448
454
|
try:
|
|
449
|
-
return validate_type(type_=cast("type[object]", type_), value=value)
|
|
455
|
+
return validate_type(type_=cast("type[object]", original_type or type_), value=value)
|
|
450
456
|
except Exception:
|
|
451
457
|
pass
|
|
452
458
|
|
|
@@ -136,6 +136,8 @@ class BaseAPIResponse(Generic[R]):
|
|
|
136
136
|
if cast_to and is_annotated_type(cast_to):
|
|
137
137
|
cast_to = extract_type_arg(cast_to, 0)
|
|
138
138
|
|
|
139
|
+
origin = get_origin(cast_to) or cast_to
|
|
140
|
+
|
|
139
141
|
if self._is_sse_stream:
|
|
140
142
|
if to:
|
|
141
143
|
if not is_stream_class_type(to):
|
|
@@ -195,8 +197,6 @@ class BaseAPIResponse(Generic[R]):
|
|
|
195
197
|
if cast_to == bool:
|
|
196
198
|
return cast(R, response.text.lower() == "true")
|
|
197
199
|
|
|
198
|
-
origin = get_origin(cast_to) or cast_to
|
|
199
|
-
|
|
200
200
|
if origin == APIResponse:
|
|
201
201
|
raise RuntimeError("Unexpected state - cast_to is `APIResponse`")
|
|
202
202
|
|
|
@@ -210,7 +210,13 @@ class BaseAPIResponse(Generic[R]):
|
|
|
210
210
|
raise ValueError(f"Subclasses of httpx.Response cannot be passed to `cast_to`")
|
|
211
211
|
return cast(R, response)
|
|
212
212
|
|
|
213
|
-
if
|
|
213
|
+
if (
|
|
214
|
+
inspect.isclass(
|
|
215
|
+
origin # pyright: ignore[reportUnknownArgumentType]
|
|
216
|
+
)
|
|
217
|
+
and not issubclass(origin, BaseModel)
|
|
218
|
+
and issubclass(origin, pydantic.BaseModel)
|
|
219
|
+
):
|
|
214
220
|
raise TypeError(
|
|
215
221
|
"Pydantic models must subclass our base model type, e.g. `from prelude_python_sdk import BaseModel`"
|
|
216
222
|
)
|
{prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_sync.py
RENAMED
|
@@ -7,16 +7,20 @@ import contextvars
|
|
|
7
7
|
from typing import Any, TypeVar, Callable, Awaitable
|
|
8
8
|
from typing_extensions import ParamSpec
|
|
9
9
|
|
|
10
|
+
import anyio
|
|
11
|
+
import sniffio
|
|
12
|
+
import anyio.to_thread
|
|
13
|
+
|
|
10
14
|
T_Retval = TypeVar("T_Retval")
|
|
11
15
|
T_ParamSpec = ParamSpec("T_ParamSpec")
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
if sys.version_info >= (3, 9):
|
|
15
|
-
|
|
19
|
+
_asyncio_to_thread = asyncio.to_thread
|
|
16
20
|
else:
|
|
17
21
|
# backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread
|
|
18
22
|
# for Python 3.8 support
|
|
19
|
-
async def
|
|
23
|
+
async def _asyncio_to_thread(
|
|
20
24
|
func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
|
|
21
25
|
) -> Any:
|
|
22
26
|
"""Asynchronously run function *func* in a separate thread.
|
|
@@ -34,6 +38,17 @@ else:
|
|
|
34
38
|
return await loop.run_in_executor(None, func_call)
|
|
35
39
|
|
|
36
40
|
|
|
41
|
+
async def to_thread(
|
|
42
|
+
func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
|
|
43
|
+
) -> T_Retval:
|
|
44
|
+
if sniffio.current_async_library() == "asyncio":
|
|
45
|
+
return await _asyncio_to_thread(func, *args, **kwargs)
|
|
46
|
+
|
|
47
|
+
return await anyio.to_thread.run_sync(
|
|
48
|
+
functools.partial(func, *args, **kwargs),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
37
52
|
# inspired by `asyncer`, https://github.com/tiangolo/asyncer
|
|
38
53
|
def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]:
|
|
39
54
|
"""
|
{prelude_python_sdk-0.1.0b1 → prelude_python_sdk-0.2.0}/src/prelude_python_sdk/_utils/_transform.py
RENAMED
|
@@ -25,7 +25,7 @@ from ._typing import (
|
|
|
25
25
|
is_annotated_type,
|
|
26
26
|
strip_annotated_type,
|
|
27
27
|
)
|
|
28
|
-
from .._compat import model_dump, is_typeddict
|
|
28
|
+
from .._compat import get_origin, model_dump, is_typeddict
|
|
29
29
|
|
|
30
30
|
_T = TypeVar("_T")
|
|
31
31
|
|
|
@@ -164,9 +164,14 @@ def _transform_recursive(
|
|
|
164
164
|
inner_type = annotation
|
|
165
165
|
|
|
166
166
|
stripped_type = strip_annotated_type(inner_type)
|
|
167
|
+
origin = get_origin(stripped_type) or stripped_type
|
|
167
168
|
if is_typeddict(stripped_type) and is_mapping(data):
|
|
168
169
|
return _transform_typeddict(data, stripped_type)
|
|
169
170
|
|
|
171
|
+
if origin == dict and is_mapping(data):
|
|
172
|
+
items_type = get_args(stripped_type)[1]
|
|
173
|
+
return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()}
|
|
174
|
+
|
|
170
175
|
if (
|
|
171
176
|
# List[T]
|
|
172
177
|
(is_list_type(stripped_type) and is_list(data))
|
|
@@ -307,9 +312,14 @@ async def _async_transform_recursive(
|
|
|
307
312
|
inner_type = annotation
|
|
308
313
|
|
|
309
314
|
stripped_type = strip_annotated_type(inner_type)
|
|
315
|
+
origin = get_origin(stripped_type) or stripped_type
|
|
310
316
|
if is_typeddict(stripped_type) and is_mapping(data):
|
|
311
317
|
return await _async_transform_typeddict(data, stripped_type)
|
|
312
318
|
|
|
319
|
+
if origin == dict and is_mapping(data):
|
|
320
|
+
items_type = get_args(stripped_type)[1]
|
|
321
|
+
return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()}
|
|
322
|
+
|
|
313
323
|
if (
|
|
314
324
|
# List[T]
|
|
315
325
|
(is_list_type(stripped_type) and is_list(data))
|