aiinbx 0.5.0__tar.gz → 0.7.1__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.

Potentially problematic release.


This version of aiinbx might be problematic. Click here for more details.

Files changed (102) hide show
  1. aiinbx-0.7.1/.release-please-manifest.json +3 -0
  2. {aiinbx-0.5.0 → aiinbx-0.7.1}/CHANGELOG.md +52 -0
  3. {aiinbx-0.5.0 → aiinbx-0.7.1}/PKG-INFO +5 -6
  4. {aiinbx-0.5.0 → aiinbx-0.7.1}/README.md +2 -2
  5. {aiinbx-0.5.0 → aiinbx-0.7.1}/pyproject.toml +4 -5
  6. {aiinbx-0.5.0 → aiinbx-0.7.1}/requirements-dev.lock +1 -1
  7. {aiinbx-0.5.0 → aiinbx-0.7.1}/requirements.lock +1 -1
  8. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_models.py +8 -3
  9. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_streaming.py +4 -6
  10. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_sync.py +3 -31
  11. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_utils.py +1 -1
  12. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_version.py +1 -1
  13. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/resources/emails.py +9 -1
  14. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/resources/threads.py +5 -1
  15. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/domain_list_response.py +2 -0
  16. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/domain_retrieve_response.py +2 -0
  17. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/domain_verify_response.py +2 -0
  18. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/email_reply_params.py +17 -3
  19. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/email_send_params.py +17 -3
  20. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/thread_forward_params.py +17 -3
  21. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/api_resources/test_emails.py +36 -0
  22. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/api_resources/test_threads.py +18 -0
  23. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_client.py +198 -164
  24. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_models.py +4 -4
  25. aiinbx-0.5.0/.release-please-manifest.json +0 -3
  26. {aiinbx-0.5.0 → aiinbx-0.7.1}/.gitignore +0 -0
  27. {aiinbx-0.5.0 → aiinbx-0.7.1}/CONTRIBUTING.md +0 -0
  28. {aiinbx-0.5.0 → aiinbx-0.7.1}/LICENSE +0 -0
  29. {aiinbx-0.5.0 → aiinbx-0.7.1}/SECURITY.md +0 -0
  30. {aiinbx-0.5.0 → aiinbx-0.7.1}/api.md +0 -0
  31. {aiinbx-0.5.0 → aiinbx-0.7.1}/bin/check-release-environment +0 -0
  32. {aiinbx-0.5.0 → aiinbx-0.7.1}/bin/publish-pypi +0 -0
  33. {aiinbx-0.5.0 → aiinbx-0.7.1}/examples/.keep +0 -0
  34. {aiinbx-0.5.0 → aiinbx-0.7.1}/noxfile.py +0 -0
  35. {aiinbx-0.5.0 → aiinbx-0.7.1}/release-please-config.json +0 -0
  36. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/ai_inbx/lib/.keep +0 -0
  37. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/__init__.py +0 -0
  38. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_base_client.py +0 -0
  39. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_client.py +0 -0
  40. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_compat.py +0 -0
  41. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_constants.py +0 -0
  42. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_exceptions.py +0 -0
  43. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_files.py +0 -0
  44. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_qs.py +0 -0
  45. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_resource.py +0 -0
  46. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_response.py +0 -0
  47. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_types.py +0 -0
  48. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/__init__.py +0 -0
  49. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_compat.py +0 -0
  50. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_datetime_parse.py +0 -0
  51. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_logs.py +0 -0
  52. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_proxy.py +0 -0
  53. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_reflection.py +0 -0
  54. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_resources_proxy.py +0 -0
  55. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_streams.py +0 -0
  56. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_transform.py +0 -0
  57. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/_utils/_typing.py +0 -0
  58. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/lib/.keep +0 -0
  59. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/py.typed +0 -0
  60. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/resources/__init__.py +0 -0
  61. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/resources/domains.py +0 -0
  62. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/resources/meta.py +0 -0
  63. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/resources/webhooks.py +0 -0
  64. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/__init__.py +0 -0
  65. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/domain_create_params.py +0 -0
  66. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/domain_create_response.py +0 -0
  67. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/domain_delete_response.py +0 -0
  68. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/email_reply_response.py +0 -0
  69. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/email_retrieve_response.py +0 -0
  70. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/email_send_response.py +0 -0
  71. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/inbound_email_received_webhook_event.py +0 -0
  72. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/meta_webhooks_schema_response.py +0 -0
  73. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/outbound_email_bounced_webhook_event.py +0 -0
  74. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/outbound_email_clicked_webhook_event.py +0 -0
  75. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/outbound_email_complained_webhook_event.py +0 -0
  76. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/outbound_email_delivered_webhook_event.py +0 -0
  77. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/outbound_email_opened_webhook_event.py +0 -0
  78. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/outbound_email_rejected_webhook_event.py +0 -0
  79. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/thread_forward_response.py +0 -0
  80. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/thread_retrieve_response.py +0 -0
  81. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/thread_search_params.py +0 -0
  82. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/thread_search_response.py +0 -0
  83. {aiinbx-0.5.0 → aiinbx-0.7.1}/src/aiinbx/types/unwrap_webhook_event.py +0 -0
  84. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/__init__.py +0 -0
  85. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/api_resources/__init__.py +0 -0
  86. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/api_resources/test_domains.py +0 -0
  87. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/api_resources/test_meta.py +0 -0
  88. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/api_resources/test_webhooks.py +0 -0
  89. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/conftest.py +0 -0
  90. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/sample_file.txt +0 -0
  91. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_deepcopy.py +0 -0
  92. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_extract_files.py +0 -0
  93. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_files.py +0 -0
  94. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_qs.py +0 -0
  95. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_required_args.py +0 -0
  96. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_response.py +0 -0
  97. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_streaming.py +0 -0
  98. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_transform.py +0 -0
  99. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_utils/test_datetime_parse.py +0 -0
  100. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_utils/test_proxy.py +0 -0
  101. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/test_utils/test_typing.py +0 -0
  102. {aiinbx-0.5.0 → aiinbx-0.7.1}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.7.1"
3
+ }
@@ -1,5 +1,57 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.1 (2025-11-11)
4
+
5
+ Full Changelog: [v0.7.0...v0.7.1](https://github.com/aiinbx/aiinbx-py/compare/v0.7.0...v0.7.1)
6
+
7
+ ### Bug Fixes
8
+
9
+ * compat with Python 3.14 ([17da3dd](https://github.com/aiinbx/aiinbx-py/commit/17da3dd00711f92f515ab05562b79eb784d0ce24))
10
+
11
+
12
+ ### Chores
13
+
14
+ * **internal:** codegen related update ([2976852](https://github.com/aiinbx/aiinbx-py/commit/2976852cdedba8ffdaed6879fd51d87708419503))
15
+
16
+ ## 0.7.0 (2025-11-04)
17
+
18
+ Full Changelog: [v0.6.0...v0.7.0](https://github.com/aiinbx/aiinbx-py/compare/v0.6.0...v0.7.0)
19
+
20
+ ### Features
21
+
22
+ * **api:** api update ([0f82ed1](https://github.com/aiinbx/aiinbx-py/commit/0f82ed1bf1a6d34c2e63ecbc9cf0a5b43f53e89a))
23
+
24
+
25
+ ### Chores
26
+
27
+ * **internal:** grammar fix (it's -> its) ([4398c76](https://github.com/aiinbx/aiinbx-py/commit/4398c76c2f4f5cd115df6f40f9948dc9d439a9b6))
28
+
29
+ ## 0.6.0 (2025-10-31)
30
+
31
+ Full Changelog: [v0.5.1...v0.6.0](https://github.com/aiinbx/aiinbx-py/compare/v0.5.1...v0.6.0)
32
+
33
+ ### Features
34
+
35
+ * **api:** api update ([e0ee97a](https://github.com/aiinbx/aiinbx-py/commit/e0ee97a7568dc6839f1c011b5312ec34ce3d9f7d))
36
+
37
+
38
+ ### Chores
39
+
40
+ * **internal/tests:** avoid race condition with implicit client cleanup ([4cf6938](https://github.com/aiinbx/aiinbx-py/commit/4cf6938564097419455a6219e0b217e7921a9ea2))
41
+
42
+ ## 0.5.1 (2025-10-30)
43
+
44
+ Full Changelog: [v0.5.0...v0.5.1](https://github.com/aiinbx/aiinbx-py/compare/v0.5.0...v0.5.1)
45
+
46
+ ### Bug Fixes
47
+
48
+ * **client:** close streams without requiring full consumption ([d824bbb](https://github.com/aiinbx/aiinbx-py/commit/d824bbbd517355748039bf7f5edfbee0e802a606))
49
+
50
+
51
+ ### Chores
52
+
53
+ * bump `httpx-aiohttp` version to 0.1.9 ([8c932fb](https://github.com/aiinbx/aiinbx-py/commit/8c932fb49aa74fe9174deb5c7b4e71cccd41f119))
54
+
3
55
  ## 0.5.0 (2025-10-15)
4
56
 
5
57
  Full Changelog: [v0.4.0...v0.5.0](https://github.com/aiinbx/aiinbx-py/compare/v0.4.0...v0.5.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aiinbx
3
- Version: 0.5.0
3
+ Version: 0.7.1
4
4
  Summary: The official Python library for the AIInbx API
5
5
  Project-URL: Homepage, https://github.com/aiinbx/aiinbx-py
6
6
  Project-URL: Repository, https://github.com/aiinbx/aiinbx-py
@@ -13,7 +13,6 @@ Classifier: Operating System :: Microsoft :: Windows
13
13
  Classifier: Operating System :: OS Independent
14
14
  Classifier: Operating System :: POSIX
15
15
  Classifier: Operating System :: POSIX :: Linux
16
- Classifier: Programming Language :: Python :: 3.8
17
16
  Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
@@ -21,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
22
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
22
  Classifier: Typing :: Typed
24
- Requires-Python: >=3.8
23
+ Requires-Python: >=3.9
25
24
  Requires-Dist: anyio<5,>=3.5.0
26
25
  Requires-Dist: distro<2,>=1.7.0
27
26
  Requires-Dist: httpx<1,>=0.23.0
@@ -30,7 +29,7 @@ Requires-Dist: sniffio
30
29
  Requires-Dist: typing-extensions<5,>=4.10
31
30
  Provides-Extra: aiohttp
32
31
  Requires-Dist: aiohttp; extra == 'aiohttp'
33
- Requires-Dist: httpx-aiohttp>=0.1.8; extra == 'aiohttp'
32
+ Requires-Dist: httpx-aiohttp>=0.1.9; extra == 'aiohttp'
34
33
  Description-Content-Type: text/markdown
35
34
 
36
35
  # AI Inbx Python API library
@@ -38,7 +37,7 @@ Description-Content-Type: text/markdown
38
37
  <!-- prettier-ignore -->
39
38
  [![PyPI version](https://img.shields.io/pypi/v/aiinbx.svg?label=pypi%20(stable))](https://pypi.org/project/aiinbx/)
40
39
 
41
- The AI Inbx Python library provides convenient access to the AI Inbx REST API from any Python 3.8+
40
+ The AI Inbx Python library provides convenient access to the AI Inbx REST API from any Python 3.9+
42
41
  application. The library includes type definitions for all request params and response fields,
43
42
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
44
43
 
@@ -391,7 +390,7 @@ print(aiinbx.__version__)
391
390
 
392
391
  ## Requirements
393
392
 
394
- Python 3.8 or higher.
393
+ Python 3.9 or higher.
395
394
 
396
395
  ## Contributing
397
396
 
@@ -3,7 +3,7 @@
3
3
  <!-- prettier-ignore -->
4
4
  [![PyPI version](https://img.shields.io/pypi/v/aiinbx.svg?label=pypi%20(stable))](https://pypi.org/project/aiinbx/)
5
5
 
6
- The AI Inbx Python library provides convenient access to the AI Inbx REST API from any Python 3.8+
6
+ The AI Inbx Python library provides convenient access to the AI Inbx REST API from any Python 3.9+
7
7
  application. The library includes type definitions for all request params and response fields,
8
8
  and offers both synchronous and asynchronous clients powered by [httpx](https://github.com/encode/httpx).
9
9
 
@@ -356,7 +356,7 @@ print(aiinbx.__version__)
356
356
 
357
357
  ## Requirements
358
358
 
359
- Python 3.8 or higher.
359
+ Python 3.9 or higher.
360
360
 
361
361
  ## Contributing
362
362
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aiinbx"
3
- version = "0.5.0"
3
+ version = "0.7.1"
4
4
  description = "The official Python library for the AIInbx API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -15,11 +15,10 @@ dependencies = [
15
15
  "distro>=1.7.0, <2",
16
16
  "sniffio",
17
17
  ]
18
- requires-python = ">= 3.8"
18
+ requires-python = ">= 3.9"
19
19
  classifiers = [
20
20
  "Typing :: Typed",
21
21
  "Intended Audience :: Developers",
22
- "Programming Language :: Python :: 3.8",
23
22
  "Programming Language :: Python :: 3.9",
24
23
  "Programming Language :: Python :: 3.10",
25
24
  "Programming Language :: Python :: 3.11",
@@ -39,7 +38,7 @@ Homepage = "https://github.com/aiinbx/aiinbx-py"
39
38
  Repository = "https://github.com/aiinbx/aiinbx-py"
40
39
 
41
40
  [project.optional-dependencies]
42
- aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"]
41
+ aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.9"]
43
42
 
44
43
  [tool.rye]
45
44
  managed = true
@@ -141,7 +140,7 @@ filterwarnings = [
141
140
  # there are a couple of flags that are still disabled by
142
141
  # default in strict mode as they are experimental and niche.
143
142
  typeCheckingMode = "strict"
144
- pythonVersion = "3.8"
143
+ pythonVersion = "3.9"
145
144
 
146
145
  exclude = [
147
146
  "_dev",
@@ -56,7 +56,7 @@ httpx==0.28.1
56
56
  # via aiinbx
57
57
  # via httpx-aiohttp
58
58
  # via respx
59
- httpx-aiohttp==0.1.8
59
+ httpx-aiohttp==0.1.9
60
60
  # via aiinbx
61
61
  idna==3.4
62
62
  # via anyio
@@ -43,7 +43,7 @@ httpcore==1.0.9
43
43
  httpx==0.28.1
44
44
  # via aiinbx
45
45
  # via httpx-aiohttp
46
- httpx-aiohttp==0.1.8
46
+ httpx-aiohttp==0.1.9
47
47
  # via aiinbx
48
48
  idna==3.4
49
49
  # via anyio
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
  import inspect
5
+ import weakref
5
6
  from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
6
7
  from datetime import date, datetime
7
8
  from typing_extensions import (
@@ -573,6 +574,9 @@ class CachedDiscriminatorType(Protocol):
573
574
  __discriminator__: DiscriminatorDetails
574
575
 
575
576
 
577
+ DISCRIMINATOR_CACHE: weakref.WeakKeyDictionary[type, DiscriminatorDetails] = weakref.WeakKeyDictionary()
578
+
579
+
576
580
  class DiscriminatorDetails:
577
581
  field_name: str
578
582
  """The name of the discriminator field in the variant class, e.g.
@@ -615,8 +619,9 @@ class DiscriminatorDetails:
615
619
 
616
620
 
617
621
  def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None:
618
- if isinstance(union, CachedDiscriminatorType):
619
- return union.__discriminator__
622
+ cached = DISCRIMINATOR_CACHE.get(union)
623
+ if cached is not None:
624
+ return cached
620
625
 
621
626
  discriminator_field_name: str | None = None
622
627
 
@@ -669,7 +674,7 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
669
674
  discriminator_field=discriminator_field_name,
670
675
  discriminator_alias=discriminator_alias,
671
676
  )
672
- cast(CachedDiscriminatorType, union).__discriminator__ = details
677
+ DISCRIMINATOR_CACHE.setdefault(union, details)
673
678
  return details
674
679
 
675
680
 
@@ -57,9 +57,8 @@ class Stream(Generic[_T]):
57
57
  for sse in iterator:
58
58
  yield process_data(data=sse.json(), cast_to=cast_to, response=response)
59
59
 
60
- # Ensure the entire stream is consumed
61
- for _sse in iterator:
62
- ...
60
+ # As we might not fully consume the response stream, we need to close it explicitly
61
+ response.close()
63
62
 
64
63
  def __enter__(self) -> Self:
65
64
  return self
@@ -121,9 +120,8 @@ class AsyncStream(Generic[_T]):
121
120
  async for sse in iterator:
122
121
  yield process_data(data=sse.json(), cast_to=cast_to, response=response)
123
122
 
124
- # Ensure the entire stream is consumed
125
- async for _sse in iterator:
126
- ...
123
+ # As we might not fully consume the response stream, we need to close it explicitly
124
+ await response.aclose()
127
125
 
128
126
  async def __aenter__(self) -> Self:
129
127
  return self
@@ -1,10 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
- import sys
4
3
  import asyncio
5
4
  import functools
6
- import contextvars
7
- from typing import Any, TypeVar, Callable, Awaitable
5
+ from typing import TypeVar, Callable, Awaitable
8
6
  from typing_extensions import ParamSpec
9
7
 
10
8
  import anyio
@@ -15,34 +13,11 @@ T_Retval = TypeVar("T_Retval")
15
13
  T_ParamSpec = ParamSpec("T_ParamSpec")
16
14
 
17
15
 
18
- if sys.version_info >= (3, 9):
19
- _asyncio_to_thread = asyncio.to_thread
20
- else:
21
- # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread
22
- # for Python 3.8 support
23
- async def _asyncio_to_thread(
24
- func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
25
- ) -> Any:
26
- """Asynchronously run function *func* in a separate thread.
27
-
28
- Any *args and **kwargs supplied for this function are directly passed
29
- to *func*. Also, the current :class:`contextvars.Context` is propagated,
30
- allowing context variables from the main thread to be accessed in the
31
- separate thread.
32
-
33
- Returns a coroutine that can be awaited to get the eventual result of *func*.
34
- """
35
- loop = asyncio.events.get_running_loop()
36
- ctx = contextvars.copy_context()
37
- func_call = functools.partial(ctx.run, func, *args, **kwargs)
38
- return await loop.run_in_executor(None, func_call)
39
-
40
-
41
16
  async def to_thread(
42
17
  func: Callable[T_ParamSpec, T_Retval], /, *args: T_ParamSpec.args, **kwargs: T_ParamSpec.kwargs
43
18
  ) -> T_Retval:
44
19
  if sniffio.current_async_library() == "asyncio":
45
- return await _asyncio_to_thread(func, *args, **kwargs)
20
+ return await asyncio.to_thread(func, *args, **kwargs)
46
21
 
47
22
  return await anyio.to_thread.run_sync(
48
23
  functools.partial(func, *args, **kwargs),
@@ -53,10 +28,7 @@ async def to_thread(
53
28
  def asyncify(function: Callable[T_ParamSpec, T_Retval]) -> Callable[T_ParamSpec, Awaitable[T_Retval]]:
54
29
  """
55
30
  Take a blocking function and create an async one that receives the same
56
- positional and keyword arguments. For python version 3.9 and above, it uses
57
- asyncio.to_thread to run the function in a separate thread. For python version
58
- 3.8, it uses locally defined copy of the asyncio.to_thread function which was
59
- introduced in python 3.9.
31
+ positional and keyword arguments.
60
32
 
61
33
  Usage:
62
34
 
@@ -133,7 +133,7 @@ def is_given(obj: _T | NotGiven | Omit) -> TypeGuard[_T]:
133
133
  # Type safe methods for narrowing types with TypeVars.
134
134
  # The default narrowing for isinstance(obj, dict) is dict[unknown, unknown],
135
135
  # however this cause Pyright to rightfully report errors. As we know we don't
136
- # care about the contained types we can safely use `object` in it's place.
136
+ # care about the contained types we can safely use `object` in its place.
137
137
  #
138
138
  # There are two separate functions defined, `is_*` and `is_*_t` for different use cases.
139
139
  # `is_*` is for when you're dealing with an unknown input
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "aiinbx"
4
- __version__ = "0.5.0" # x-release-please-version
4
+ __version__ = "0.7.1" # x-release-please-version
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Union
5
+ from typing import Union, Iterable
6
6
 
7
7
  import httpx
8
8
 
@@ -84,6 +84,7 @@ class EmailsResource(SyncAPIResource):
84
84
  *,
85
85
  from_: str,
86
86
  html: str,
87
+ attachments: Iterable[email_reply_params.Attachment] | Omit = omit,
87
88
  bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
88
89
  cc: Union[str, SequenceNotStr[str]] | Omit = omit,
89
90
  from_name: str | Omit = omit,
@@ -122,6 +123,7 @@ class EmailsResource(SyncAPIResource):
122
123
  {
123
124
  "from_": from_,
124
125
  "html": html,
126
+ "attachments": attachments,
125
127
  "bcc": bcc,
126
128
  "cc": cc,
127
129
  "from_name": from_name,
@@ -146,6 +148,7 @@ class EmailsResource(SyncAPIResource):
146
148
  html: str,
147
149
  subject: str,
148
150
  to: Union[str, SequenceNotStr[str]],
151
+ attachments: Iterable[email_send_params.Attachment] | Omit = omit,
149
152
  bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
150
153
  cc: Union[str, SequenceNotStr[str]] | Omit = omit,
151
154
  from_name: str | Omit = omit,
@@ -185,6 +188,7 @@ class EmailsResource(SyncAPIResource):
185
188
  "html": html,
186
189
  "subject": subject,
187
190
  "to": to,
191
+ "attachments": attachments,
188
192
  "bcc": bcc,
189
193
  "cc": cc,
190
194
  "from_name": from_name,
@@ -263,6 +267,7 @@ class AsyncEmailsResource(AsyncAPIResource):
263
267
  *,
264
268
  from_: str,
265
269
  html: str,
270
+ attachments: Iterable[email_reply_params.Attachment] | Omit = omit,
266
271
  bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
267
272
  cc: Union[str, SequenceNotStr[str]] | Omit = omit,
268
273
  from_name: str | Omit = omit,
@@ -301,6 +306,7 @@ class AsyncEmailsResource(AsyncAPIResource):
301
306
  {
302
307
  "from_": from_,
303
308
  "html": html,
309
+ "attachments": attachments,
304
310
  "bcc": bcc,
305
311
  "cc": cc,
306
312
  "from_name": from_name,
@@ -325,6 +331,7 @@ class AsyncEmailsResource(AsyncAPIResource):
325
331
  html: str,
326
332
  subject: str,
327
333
  to: Union[str, SequenceNotStr[str]],
334
+ attachments: Iterable[email_send_params.Attachment] | Omit = omit,
328
335
  bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
329
336
  cc: Union[str, SequenceNotStr[str]] | Omit = omit,
330
337
  from_name: str | Omit = omit,
@@ -364,6 +371,7 @@ class AsyncEmailsResource(AsyncAPIResource):
364
371
  "html": html,
365
372
  "subject": subject,
366
373
  "to": to,
374
+ "attachments": attachments,
367
375
  "bcc": bcc,
368
376
  "cc": cc,
369
377
  "from_name": from_name,
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Union
5
+ from typing import Union, Iterable
6
6
  from typing_extensions import Literal
7
7
 
8
8
  import httpx
@@ -85,6 +85,7 @@ class ThreadsResource(SyncAPIResource):
85
85
  thread_id: str,
86
86
  *,
87
87
  to: Union[str, SequenceNotStr[str]],
88
+ attachments: Iterable[thread_forward_params.Attachment] | Omit = omit,
88
89
  bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
89
90
  cc: Union[str, SequenceNotStr[str]] | Omit = omit,
90
91
  from_: str | Omit = omit,
@@ -118,6 +119,7 @@ class ThreadsResource(SyncAPIResource):
118
119
  body=maybe_transform(
119
120
  {
120
121
  "to": to,
122
+ "attachments": attachments,
121
123
  "bcc": bcc,
122
124
  "cc": cc,
123
125
  "from_": from_,
@@ -274,6 +276,7 @@ class AsyncThreadsResource(AsyncAPIResource):
274
276
  thread_id: str,
275
277
  *,
276
278
  to: Union[str, SequenceNotStr[str]],
279
+ attachments: Iterable[thread_forward_params.Attachment] | Omit = omit,
277
280
  bcc: Union[str, SequenceNotStr[str]] | Omit = omit,
278
281
  cc: Union[str, SequenceNotStr[str]] | Omit = omit,
279
282
  from_: str | Omit = omit,
@@ -307,6 +310,7 @@ class AsyncThreadsResource(AsyncAPIResource):
307
310
  body=await async_maybe_transform(
308
311
  {
309
312
  "to": to,
313
+ "attachments": attachments,
310
314
  "bcc": bcc,
311
315
  "cc": cc,
312
316
  "from_": from_,
@@ -35,6 +35,8 @@ class Domain(BaseModel):
35
35
 
36
36
  domain: str
37
37
 
38
+ is_managed_default: bool = FieldInfo(alias="isManagedDefault")
39
+
38
40
  status: Literal["VERIFIED", "PENDING_VERIFICATION", "NOT_REGISTERED"]
39
41
 
40
42
  updated_at: str = FieldInfo(alias="updatedAt")
@@ -35,6 +35,8 @@ class DomainRetrieveResponse(BaseModel):
35
35
 
36
36
  domain: str
37
37
 
38
+ is_managed_default: bool = FieldInfo(alias="isManagedDefault")
39
+
38
40
  status: Literal["VERIFIED", "PENDING_VERIFICATION", "NOT_REGISTERED"]
39
41
 
40
42
  updated_at: str = FieldInfo(alias="updatedAt")
@@ -48,6 +48,8 @@ class Domain(BaseModel):
48
48
 
49
49
  domain: str
50
50
 
51
+ is_managed_default: bool = FieldInfo(alias="isManagedDefault")
52
+
51
53
  status: Literal["VERIFIED", "PENDING_VERIFICATION", "NOT_REGISTERED"]
52
54
 
53
55
  updated_at: str = FieldInfo(alias="updatedAt")
@@ -2,13 +2,13 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Union
6
- from typing_extensions import Required, Annotated, TypedDict
5
+ from typing import Union, Iterable
6
+ from typing_extensions import Literal, Required, Annotated, TypedDict
7
7
 
8
8
  from .._types import SequenceNotStr
9
9
  from .._utils import PropertyInfo
10
10
 
11
- __all__ = ["EmailReplyParams"]
11
+ __all__ = ["EmailReplyParams", "Attachment"]
12
12
 
13
13
 
14
14
  class EmailReplyParams(TypedDict, total=False):
@@ -16,6 +16,8 @@ class EmailReplyParams(TypedDict, total=False):
16
16
 
17
17
  html: Required[str]
18
18
 
19
+ attachments: Iterable[Attachment]
20
+
19
21
  bcc: Union[str, SequenceNotStr[str]]
20
22
 
21
23
  cc: Union[str, SequenceNotStr[str]]
@@ -31,3 +33,15 @@ class EmailReplyParams(TypedDict, total=False):
31
33
  text: str
32
34
 
33
35
  to: Union[str, SequenceNotStr[str]]
36
+
37
+
38
+ class Attachment(TypedDict, total=False):
39
+ content: Required[str]
40
+
41
+ file_name: Required[str]
42
+
43
+ cid: str
44
+
45
+ content_type: str
46
+
47
+ disposition: Literal["attachment", "inline"]
@@ -2,13 +2,13 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Union
6
- from typing_extensions import Required, Annotated, TypedDict
5
+ from typing import Union, Iterable
6
+ from typing_extensions import Literal, Required, Annotated, TypedDict
7
7
 
8
8
  from .._types import SequenceNotStr
9
9
  from .._utils import PropertyInfo
10
10
 
11
- __all__ = ["EmailSendParams"]
11
+ __all__ = ["EmailSendParams", "Attachment"]
12
12
 
13
13
 
14
14
  class EmailSendParams(TypedDict, total=False):
@@ -20,6 +20,8 @@ class EmailSendParams(TypedDict, total=False):
20
20
 
21
21
  to: Required[Union[str, SequenceNotStr[str]]]
22
22
 
23
+ attachments: Iterable[Attachment]
24
+
23
25
  bcc: Union[str, SequenceNotStr[str]]
24
26
 
25
27
  cc: Union[str, SequenceNotStr[str]]
@@ -37,3 +39,15 @@ class EmailSendParams(TypedDict, total=False):
37
39
  text: str
38
40
 
39
41
  thread_id: Annotated[str, PropertyInfo(alias="threadId")]
42
+
43
+
44
+ class Attachment(TypedDict, total=False):
45
+ content: Required[str]
46
+
47
+ file_name: Required[str]
48
+
49
+ cid: str
50
+
51
+ content_type: str
52
+
53
+ disposition: Literal["attachment", "inline"]
@@ -2,18 +2,20 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Union
6
- from typing_extensions import Required, Annotated, TypedDict
5
+ from typing import Union, Iterable
6
+ from typing_extensions import Literal, Required, Annotated, TypedDict
7
7
 
8
8
  from .._types import SequenceNotStr
9
9
  from .._utils import PropertyInfo
10
10
 
11
- __all__ = ["ThreadForwardParams"]
11
+ __all__ = ["ThreadForwardParams", "Attachment"]
12
12
 
13
13
 
14
14
  class ThreadForwardParams(TypedDict, total=False):
15
15
  to: Required[Union[str, SequenceNotStr[str]]]
16
16
 
17
+ attachments: Iterable[Attachment]
18
+
17
19
  bcc: Union[str, SequenceNotStr[str]]
18
20
 
19
21
  cc: Union[str, SequenceNotStr[str]]
@@ -27,3 +29,15 @@ class ThreadForwardParams(TypedDict, total=False):
27
29
  is_draft: bool
28
30
 
29
31
  note: str
32
+
33
+
34
+ class Attachment(TypedDict, total=False):
35
+ content: Required[str]
36
+
37
+ file_name: Required[str]
38
+
39
+ cid: str
40
+
41
+ content_type: str
42
+
43
+ disposition: Literal["attachment", "inline"]
@@ -80,6 +80,15 @@ class TestEmails:
80
80
  email_id="emailId",
81
81
  from_="dev@stainless.com",
82
82
  html="html",
83
+ attachments=[
84
+ {
85
+ "content": "content",
86
+ "file_name": "file_name",
87
+ "cid": "cid",
88
+ "content_type": "content_type",
89
+ "disposition": "attachment",
90
+ }
91
+ ],
83
92
  bcc="dev@stainless.com",
84
93
  cc="dev@stainless.com",
85
94
  from_name="from_name",
@@ -150,6 +159,15 @@ class TestEmails:
150
159
  html="html",
151
160
  subject="subject",
152
161
  to="dev@stainless.com",
162
+ attachments=[
163
+ {
164
+ "content": "content",
165
+ "file_name": "file_name",
166
+ "cid": "cid",
167
+ "content_type": "content_type",
168
+ "disposition": "attachment",
169
+ }
170
+ ],
153
171
  bcc="dev@stainless.com",
154
172
  cc="dev@stainless.com",
155
173
  from_name="from_name",
@@ -259,6 +277,15 @@ class TestAsyncEmails:
259
277
  email_id="emailId",
260
278
  from_="dev@stainless.com",
261
279
  html="html",
280
+ attachments=[
281
+ {
282
+ "content": "content",
283
+ "file_name": "file_name",
284
+ "cid": "cid",
285
+ "content_type": "content_type",
286
+ "disposition": "attachment",
287
+ }
288
+ ],
262
289
  bcc="dev@stainless.com",
263
290
  cc="dev@stainless.com",
264
291
  from_name="from_name",
@@ -329,6 +356,15 @@ class TestAsyncEmails:
329
356
  html="html",
330
357
  subject="subject",
331
358
  to="dev@stainless.com",
359
+ attachments=[
360
+ {
361
+ "content": "content",
362
+ "file_name": "file_name",
363
+ "cid": "cid",
364
+ "content_type": "content_type",
365
+ "disposition": "attachment",
366
+ }
367
+ ],
332
368
  bcc="dev@stainless.com",
333
369
  cc="dev@stainless.com",
334
370
  from_name="from_name",