runwayml 3.5.0__tar.gz → 3.6.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.
Files changed (84) hide show
  1. runwayml-3.6.1/.release-please-manifest.json +3 -0
  2. {runwayml-3.5.0 → runwayml-3.6.1}/CHANGELOG.md +31 -0
  3. {runwayml-3.5.0 → runwayml-3.6.1}/PKG-INFO +43 -3
  4. {runwayml-3.5.0 → runwayml-3.6.1}/README.md +39 -2
  5. {runwayml-3.5.0 → runwayml-3.6.1}/pyproject.toml +3 -1
  6. {runwayml-3.5.0 → runwayml-3.6.1}/requirements-dev.lock +27 -0
  7. {runwayml-3.5.0 → runwayml-3.6.1}/requirements.lock +27 -0
  8. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/__init__.py +2 -1
  9. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_base_client.py +22 -0
  10. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_version.py +1 -1
  11. {runwayml-3.5.0 → runwayml-3.6.1}/tests/api_resources/test_image_to_video.py +3 -1
  12. {runwayml-3.5.0 → runwayml-3.6.1}/tests/api_resources/test_organization.py +3 -1
  13. {runwayml-3.5.0 → runwayml-3.6.1}/tests/api_resources/test_tasks.py +3 -1
  14. {runwayml-3.5.0 → runwayml-3.6.1}/tests/api_resources/test_text_to_image.py +3 -1
  15. {runwayml-3.5.0 → runwayml-3.6.1}/tests/api_resources/test_video_upscale.py +3 -1
  16. {runwayml-3.5.0 → runwayml-3.6.1}/tests/conftest.py +37 -6
  17. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_client.py +22 -77
  18. runwayml-3.5.0/.release-please-manifest.json +0 -3
  19. {runwayml-3.5.0 → runwayml-3.6.1}/.gitignore +0 -0
  20. {runwayml-3.5.0 → runwayml-3.6.1}/CONTRIBUTING.md +0 -0
  21. {runwayml-3.5.0 → runwayml-3.6.1}/LICENSE +0 -0
  22. {runwayml-3.5.0 → runwayml-3.6.1}/SECURITY.md +0 -0
  23. {runwayml-3.5.0 → runwayml-3.6.1}/api.md +0 -0
  24. {runwayml-3.5.0 → runwayml-3.6.1}/bin/check-release-environment +0 -0
  25. {runwayml-3.5.0 → runwayml-3.6.1}/bin/publish-pypi +0 -0
  26. {runwayml-3.5.0 → runwayml-3.6.1}/examples/.keep +0 -0
  27. {runwayml-3.5.0 → runwayml-3.6.1}/examples/generate_image.py +0 -0
  28. {runwayml-3.5.0 → runwayml-3.6.1}/mypy.ini +0 -0
  29. {runwayml-3.5.0 → runwayml-3.6.1}/noxfile.py +0 -0
  30. {runwayml-3.5.0 → runwayml-3.6.1}/release-please-config.json +0 -0
  31. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_client.py +0 -0
  32. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_compat.py +0 -0
  33. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_constants.py +0 -0
  34. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_exceptions.py +0 -0
  35. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_files.py +0 -0
  36. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_models.py +0 -0
  37. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_qs.py +0 -0
  38. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_resource.py +0 -0
  39. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_response.py +0 -0
  40. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_streaming.py +0 -0
  41. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_types.py +0 -0
  42. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/__init__.py +0 -0
  43. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_logs.py +0 -0
  44. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_proxy.py +0 -0
  45. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_reflection.py +0 -0
  46. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_resources_proxy.py +0 -0
  47. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_streams.py +0 -0
  48. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_sync.py +0 -0
  49. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_transform.py +0 -0
  50. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_typing.py +0 -0
  51. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/_utils/_utils.py +0 -0
  52. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/lib/.keep +0 -0
  53. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/lib/polling.py +0 -0
  54. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/py.typed +0 -0
  55. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/resources/__init__.py +0 -0
  56. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/resources/image_to_video.py +0 -0
  57. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/resources/organization.py +0 -0
  58. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/resources/tasks.py +0 -0
  59. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/resources/text_to_image.py +0 -0
  60. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/resources/video_upscale.py +0 -0
  61. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/__init__.py +0 -0
  62. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/image_to_video_create_params.py +0 -0
  63. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/image_to_video_create_response.py +0 -0
  64. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/organization_retrieve_response.py +0 -0
  65. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/task_retrieve_response.py +0 -0
  66. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/text_to_image_create_params.py +0 -0
  67. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/text_to_image_create_response.py +0 -0
  68. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/video_upscale_create_params.py +0 -0
  69. {runwayml-3.5.0 → runwayml-3.6.1}/src/runwayml/types/video_upscale_create_response.py +0 -0
  70. {runwayml-3.5.0 → runwayml-3.6.1}/tests/__init__.py +0 -0
  71. {runwayml-3.5.0 → runwayml-3.6.1}/tests/api_resources/__init__.py +0 -0
  72. {runwayml-3.5.0 → runwayml-3.6.1}/tests/sample_file.txt +0 -0
  73. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_deepcopy.py +0 -0
  74. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_extract_files.py +0 -0
  75. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_files.py +0 -0
  76. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_models.py +0 -0
  77. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_qs.py +0 -0
  78. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_required_args.py +0 -0
  79. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_response.py +0 -0
  80. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_streaming.py +0 -0
  81. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_transform.py +0 -0
  82. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_utils/test_proxy.py +0 -0
  83. {runwayml-3.5.0 → runwayml-3.6.1}/tests/test_utils/test_typing.py +0 -0
  84. {runwayml-3.5.0 → runwayml-3.6.1}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "3.6.1"
3
+ }
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.6.1 (2025-06-24)
4
+
5
+ Full Changelog: [v3.6.0...v3.6.1](https://github.com/runwayml/sdk-python/compare/v3.6.0...v3.6.1)
6
+
7
+ ### Chores
8
+
9
+ * **tests:** skip some failing tests on the latest python versions ([732236d](https://github.com/runwayml/sdk-python/commit/732236d2ced9511c21179e9850bafcaf0b0a4edf))
10
+
11
+ ## 3.6.0 (2025-06-23)
12
+
13
+ Full Changelog: [v3.5.0...v3.6.0](https://github.com/runwayml/sdk-python/compare/v3.5.0...v3.6.0)
14
+
15
+ ### Features
16
+
17
+ * **client:** add support for aiohttp ([7d5490c](https://github.com/runwayml/sdk-python/commit/7d5490ca015dd0ff55789889036cc1bd32a58c43))
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **tests:** fix: tests which call HTTP endpoints directly with the example parameters ([33301dd](https://github.com/runwayml/sdk-python/commit/33301ddf84cc64581d715d6b8ce1eda48ff66ed5))
23
+
24
+
25
+ ### Chores
26
+
27
+ * **readme:** update badges ([147dc95](https://github.com/runwayml/sdk-python/commit/147dc95f9ab390065ab96403a88ca5a87e59f597))
28
+
29
+
30
+ ### Documentation
31
+
32
+ * **client:** fix httpx.Timeout documentation reference ([af9fecb](https://github.com/runwayml/sdk-python/commit/af9fecb38a4075fcc8f7687f2ef130ad8c813389))
33
+
3
34
  ## 3.5.0 (2025-06-17)
4
35
 
5
36
  Full Changelog: [v3.4.0...v3.5.0](https://github.com/runwayml/sdk-python/compare/v3.4.0...v3.5.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: runwayml
3
- Version: 3.5.0
3
+ Version: 3.6.1
4
4
  Summary: The official Python library for the runwayml API
5
5
  Project-URL: Homepage, https://github.com/runwayml/sdk-python
6
6
  Project-URL: Repository, https://github.com/runwayml/sdk-python
@@ -27,11 +27,14 @@ Requires-Dist: httpx<1,>=0.23.0
27
27
  Requires-Dist: pydantic<3,>=1.9.0
28
28
  Requires-Dist: sniffio
29
29
  Requires-Dist: typing-extensions<5,>=4.10
30
+ Provides-Extra: aiohttp
31
+ Requires-Dist: aiohttp; extra == 'aiohttp'
32
+ Requires-Dist: httpx-aiohttp>=0.1.6; extra == 'aiohttp'
30
33
  Description-Content-Type: text/markdown
31
34
 
32
35
  # RunwayML Python API library
33
36
 
34
- [![PyPI version](https://img.shields.io/pypi/v/runwayml.svg)](https://pypi.org/project/runwayml/)
37
+ [![PyPI version](https://github.com/runwayml/sdk-python/tree/main/<https://img.shields.io/pypi/v/runwayml.svg?label=pypi%20(stable)>)](https://pypi.org/project/runwayml/)
35
38
 
36
39
  The RunwayML Python library provides convenient access to the RunwayML REST API from any Python 3.8+
37
40
  application. The library includes type definitions for all request params and response fields,
@@ -105,6 +108,43 @@ asyncio.run(main())
105
108
 
106
109
  Functionality between the synchronous and asynchronous clients is otherwise identical.
107
110
 
111
+ ### With aiohttp
112
+
113
+ By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.
114
+
115
+ You can enable this by installing `aiohttp`:
116
+
117
+ ```sh
118
+ # install from PyPI
119
+ pip install runwayml[aiohttp]
120
+ ```
121
+
122
+ Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
123
+
124
+ ```python
125
+ import os
126
+ import asyncio
127
+ from runwayml import DefaultAioHttpClient
128
+ from runwayml import AsyncRunwayML
129
+
130
+
131
+ async def main() -> None:
132
+ async with AsyncRunwayML(
133
+ api_key=os.environ.get("RUNWAYML_API_SECRET"), # This is the default and can be omitted
134
+ http_client=DefaultAioHttpClient(),
135
+ ) as client:
136
+ image_to_video = await client.image_to_video.create(
137
+ model="gen4_turbo",
138
+ prompt_image="https://example.com/assets/bunny.jpg",
139
+ ratio="1280:720",
140
+ prompt_text="The bunny is eating a carrot",
141
+ )
142
+ print(image_to_video.id)
143
+
144
+
145
+ asyncio.run(main())
146
+ ```
147
+
108
148
  ## Using types
109
149
 
110
150
  Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:
@@ -206,7 +246,7 @@ client.with_options(max_retries=5).image_to_video.create(
206
246
  ### Timeouts
207
247
 
208
248
  By default requests time out after 1 minute. You can configure this with a `timeout` option,
209
- which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
249
+ which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
210
250
 
211
251
  ```python
212
252
  from runwayml import RunwayML
@@ -1,6 +1,6 @@
1
1
  # RunwayML Python API library
2
2
 
3
- [![PyPI version](https://img.shields.io/pypi/v/runwayml.svg)](https://pypi.org/project/runwayml/)
3
+ [![PyPI version](<https://img.shields.io/pypi/v/runwayml.svg?label=pypi%20(stable)>)](https://pypi.org/project/runwayml/)
4
4
 
5
5
  The RunwayML Python library provides convenient access to the RunwayML REST API from any Python 3.8+
6
6
  application. The library includes type definitions for all request params and response fields,
@@ -74,6 +74,43 @@ asyncio.run(main())
74
74
 
75
75
  Functionality between the synchronous and asynchronous clients is otherwise identical.
76
76
 
77
+ ### With aiohttp
78
+
79
+ By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.
80
+
81
+ You can enable this by installing `aiohttp`:
82
+
83
+ ```sh
84
+ # install from PyPI
85
+ pip install runwayml[aiohttp]
86
+ ```
87
+
88
+ Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:
89
+
90
+ ```python
91
+ import os
92
+ import asyncio
93
+ from runwayml import DefaultAioHttpClient
94
+ from runwayml import AsyncRunwayML
95
+
96
+
97
+ async def main() -> None:
98
+ async with AsyncRunwayML(
99
+ api_key=os.environ.get("RUNWAYML_API_SECRET"), # This is the default and can be omitted
100
+ http_client=DefaultAioHttpClient(),
101
+ ) as client:
102
+ image_to_video = await client.image_to_video.create(
103
+ model="gen4_turbo",
104
+ prompt_image="https://example.com/assets/bunny.jpg",
105
+ ratio="1280:720",
106
+ prompt_text="The bunny is eating a carrot",
107
+ )
108
+ print(image_to_video.id)
109
+
110
+
111
+ asyncio.run(main())
112
+ ```
113
+
77
114
  ## Using types
78
115
 
79
116
  Nested request parameters are [TypedDicts](https://docs.python.org/3/library/typing.html#typing.TypedDict). Responses are [Pydantic models](https://docs.pydantic.dev) which also provide helper methods for things like:
@@ -175,7 +212,7 @@ client.with_options(max_retries=5).image_to_video.create(
175
212
  ### Timeouts
176
213
 
177
214
  By default requests time out after 1 minute. You can configure this with a `timeout` option,
178
- which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
215
+ which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:
179
216
 
180
217
  ```python
181
218
  from runwayml import RunwayML
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "runwayml"
3
- version = "3.5.0"
3
+ version = "3.6.1"
4
4
  description = "The official Python library for the runwayml API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -37,6 +37,8 @@ classifiers = [
37
37
  Homepage = "https://github.com/runwayml/sdk-python"
38
38
  Repository = "https://github.com/runwayml/sdk-python"
39
39
 
40
+ [project.optional-dependencies]
41
+ aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.6"]
40
42
 
41
43
  [tool.rye]
42
44
  managed = true
@@ -10,6 +10,13 @@
10
10
  # universal: false
11
11
 
12
12
  -e file:.
13
+ aiohappyeyeballs==2.6.1
14
+ # via aiohttp
15
+ aiohttp==3.12.8
16
+ # via httpx-aiohttp
17
+ # via runwayml
18
+ aiosignal==1.3.2
19
+ # via aiohttp
13
20
  annotated-types==0.6.0
14
21
  # via pydantic
15
22
  anyio==4.4.0
@@ -17,6 +24,10 @@ anyio==4.4.0
17
24
  # via runwayml
18
25
  argcomplete==3.1.2
19
26
  # via nox
27
+ async-timeout==5.0.1
28
+ # via aiohttp
29
+ attrs==25.3.0
30
+ # via aiohttp
20
31
  certifi==2023.7.22
21
32
  # via httpcore
22
33
  # via httpx
@@ -34,16 +45,23 @@ execnet==2.1.1
34
45
  # via pytest-xdist
35
46
  filelock==3.12.4
36
47
  # via virtualenv
48
+ frozenlist==1.6.2
49
+ # via aiohttp
50
+ # via aiosignal
37
51
  h11==0.14.0
38
52
  # via httpcore
39
53
  httpcore==1.0.2
40
54
  # via httpx
41
55
  httpx==0.28.1
56
+ # via httpx-aiohttp
42
57
  # via respx
43
58
  # via runwayml
59
+ httpx-aiohttp==0.1.6
60
+ # via runwayml
44
61
  idna==3.4
45
62
  # via anyio
46
63
  # via httpx
64
+ # via yarl
47
65
  importlib-metadata==7.0.0
48
66
  iniconfig==2.0.0
49
67
  # via pytest
@@ -51,6 +69,9 @@ markdown-it-py==3.0.0
51
69
  # via rich
52
70
  mdurl==0.1.2
53
71
  # via markdown-it-py
72
+ multidict==6.4.4
73
+ # via aiohttp
74
+ # via yarl
54
75
  mypy==1.14.1
55
76
  mypy-extensions==1.0.0
56
77
  # via mypy
@@ -65,6 +86,9 @@ platformdirs==3.11.0
65
86
  # via virtualenv
66
87
  pluggy==1.5.0
67
88
  # via pytest
89
+ propcache==0.3.1
90
+ # via aiohttp
91
+ # via yarl
68
92
  pydantic==2.10.3
69
93
  # via runwayml
70
94
  pydantic-core==2.27.1
@@ -97,6 +121,7 @@ tomli==2.0.2
97
121
  # via pytest
98
122
  typing-extensions==4.12.2
99
123
  # via anyio
124
+ # via multidict
100
125
  # via mypy
101
126
  # via pydantic
102
127
  # via pydantic-core
@@ -104,5 +129,7 @@ typing-extensions==4.12.2
104
129
  # via runwayml
105
130
  virtualenv==20.24.5
106
131
  # via nox
132
+ yarl==1.20.0
133
+ # via aiohttp
107
134
  zipp==3.17.0
108
135
  # via importlib-metadata
@@ -10,11 +10,22 @@
10
10
  # universal: false
11
11
 
12
12
  -e file:.
13
+ aiohappyeyeballs==2.6.1
14
+ # via aiohttp
15
+ aiohttp==3.12.8
16
+ # via httpx-aiohttp
17
+ # via runwayml
18
+ aiosignal==1.3.2
19
+ # via aiohttp
13
20
  annotated-types==0.6.0
14
21
  # via pydantic
15
22
  anyio==4.4.0
16
23
  # via httpx
17
24
  # via runwayml
25
+ async-timeout==5.0.1
26
+ # via aiohttp
27
+ attrs==25.3.0
28
+ # via aiohttp
18
29
  certifi==2023.7.22
19
30
  # via httpcore
20
31
  # via httpx
@@ -22,15 +33,28 @@ distro==1.8.0
22
33
  # via runwayml
23
34
  exceptiongroup==1.2.2
24
35
  # via anyio
36
+ frozenlist==1.6.2
37
+ # via aiohttp
38
+ # via aiosignal
25
39
  h11==0.14.0
26
40
  # via httpcore
27
41
  httpcore==1.0.2
28
42
  # via httpx
29
43
  httpx==0.28.1
44
+ # via httpx-aiohttp
45
+ # via runwayml
46
+ httpx-aiohttp==0.1.6
30
47
  # via runwayml
31
48
  idna==3.4
32
49
  # via anyio
33
50
  # via httpx
51
+ # via yarl
52
+ multidict==6.4.4
53
+ # via aiohttp
54
+ # via yarl
55
+ propcache==0.3.1
56
+ # via aiohttp
57
+ # via yarl
34
58
  pydantic==2.10.3
35
59
  # via runwayml
36
60
  pydantic-core==2.27.1
@@ -40,6 +64,9 @@ sniffio==1.3.0
40
64
  # via runwayml
41
65
  typing-extensions==4.12.2
42
66
  # via anyio
67
+ # via multidict
43
68
  # via pydantic
44
69
  # via pydantic-core
45
70
  # via runwayml
71
+ yarl==1.20.0
72
+ # via aiohttp
@@ -37,7 +37,7 @@ from ._exceptions import (
37
37
  APIResponseValidationError,
38
38
  )
39
39
  from .lib.polling import TaskFailedError, TaskTimeoutError
40
- from ._base_client import DefaultHttpxClient, DefaultAsyncHttpxClient
40
+ from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
41
41
  from ._utils._logs import setup_logging as _setup_logging
42
42
 
43
43
  __all__ = [
@@ -79,6 +79,7 @@ __all__ = [
79
79
  "DEFAULT_CONNECTION_LIMITS",
80
80
  "DefaultHttpxClient",
81
81
  "DefaultAsyncHttpxClient",
82
+ "DefaultAioHttpClient",
82
83
  "TaskFailedError",
83
84
  "TaskTimeoutError",
84
85
  ]
@@ -1289,6 +1289,24 @@ class _DefaultAsyncHttpxClient(httpx.AsyncClient):
1289
1289
  super().__init__(**kwargs)
1290
1290
 
1291
1291
 
1292
+ try:
1293
+ import httpx_aiohttp
1294
+ except ImportError:
1295
+
1296
+ class _DefaultAioHttpClient(httpx.AsyncClient):
1297
+ def __init__(self, **_kwargs: Any) -> None:
1298
+ raise RuntimeError("To use the aiohttp client you must have installed the package with the `aiohttp` extra")
1299
+ else:
1300
+
1301
+ class _DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
1302
+ def __init__(self, **kwargs: Any) -> None:
1303
+ kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
1304
+ kwargs.setdefault("limits", DEFAULT_CONNECTION_LIMITS)
1305
+ kwargs.setdefault("follow_redirects", True)
1306
+
1307
+ super().__init__(**kwargs)
1308
+
1309
+
1292
1310
  if TYPE_CHECKING:
1293
1311
  DefaultAsyncHttpxClient = httpx.AsyncClient
1294
1312
  """An alias to `httpx.AsyncClient` that provides the same defaults that this SDK
@@ -1297,8 +1315,12 @@ if TYPE_CHECKING:
1297
1315
  This is useful because overriding the `http_client` with your own instance of
1298
1316
  `httpx.AsyncClient` will result in httpx's defaults being used, not ours.
1299
1317
  """
1318
+
1319
+ DefaultAioHttpClient = httpx.AsyncClient
1320
+ """An alias to `httpx.AsyncClient` that changes the default HTTP transport to `aiohttp`."""
1300
1321
  else:
1301
1322
  DefaultAsyncHttpxClient = _DefaultAsyncHttpxClient
1323
+ DefaultAioHttpClient = _DefaultAioHttpClient
1302
1324
 
1303
1325
 
1304
1326
  class AsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "runwayml"
4
- __version__ = "3.5.0" # x-release-please-version
4
+ __version__ = "3.6.1" # x-release-please-version
@@ -69,7 +69,9 @@ class TestImageToVideo:
69
69
 
70
70
 
71
71
  class TestAsyncImageToVideo:
72
- parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
72
+ parametrize = pytest.mark.parametrize(
73
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
74
+ )
73
75
 
74
76
  @parametrize
75
77
  async def test_method_create(self, async_client: AsyncRunwayML) -> None:
@@ -44,7 +44,9 @@ class TestOrganization:
44
44
 
45
45
 
46
46
  class TestAsyncOrganization:
47
- parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
47
+ parametrize = pytest.mark.parametrize(
48
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
49
+ )
48
50
 
49
51
  @parametrize
50
52
  async def test_method_retrieve(self, async_client: AsyncRunwayML) -> None:
@@ -95,7 +95,9 @@ class TestTasks:
95
95
 
96
96
 
97
97
  class TestAsyncTasks:
98
- parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
98
+ parametrize = pytest.mark.parametrize(
99
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
100
+ )
99
101
 
100
102
  @parametrize
101
103
  async def test_method_retrieve(self, async_client: AsyncRunwayML) -> None:
@@ -73,7 +73,9 @@ class TestTextToImage:
73
73
 
74
74
 
75
75
  class TestAsyncTextToImage:
76
- parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
76
+ parametrize = pytest.mark.parametrize(
77
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
78
+ )
77
79
 
78
80
  @parametrize
79
81
  async def test_method_create(self, async_client: AsyncRunwayML) -> None:
@@ -53,7 +53,9 @@ class TestVideoUpscale:
53
53
 
54
54
 
55
55
  class TestAsyncVideoUpscale:
56
- parametrize = pytest.mark.parametrize("async_client", [False, True], indirect=True, ids=["loose", "strict"])
56
+ parametrize = pytest.mark.parametrize(
57
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
58
+ )
57
59
 
58
60
  @parametrize
59
61
  async def test_method_create(self, async_client: AsyncRunwayML) -> None:
@@ -6,10 +6,12 @@ import os
6
6
  import logging
7
7
  from typing import TYPE_CHECKING, Iterator, AsyncIterator
8
8
 
9
+ import httpx
9
10
  import pytest
10
11
  from pytest_asyncio import is_async_test
11
12
 
12
- from runwayml import RunwayML, AsyncRunwayML
13
+ from runwayml import RunwayML, AsyncRunwayML, DefaultAioHttpClient
14
+ from runwayml._utils import is_dict
13
15
 
14
16
  if TYPE_CHECKING:
15
17
  from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
@@ -27,6 +29,19 @@ def pytest_collection_modifyitems(items: list[pytest.Function]) -> None:
27
29
  for async_test in pytest_asyncio_tests:
28
30
  async_test.add_marker(session_scope_marker, append=False)
29
31
 
32
+ # We skip tests that use both the aiohttp client and respx_mock as respx_mock
33
+ # doesn't support custom transports.
34
+ for item in items:
35
+ if "async_client" not in item.fixturenames or "respx_mock" not in item.fixturenames:
36
+ continue
37
+
38
+ if not hasattr(item, "callspec"):
39
+ continue
40
+
41
+ async_client_param = item.callspec.params.get("async_client")
42
+ if is_dict(async_client_param) and async_client_param.get("http_client") == "aiohttp":
43
+ item.add_marker(pytest.mark.skip(reason="aiohttp client is not compatible with respx_mock"))
44
+
30
45
 
31
46
  base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
32
47
 
@@ -45,9 +60,25 @@ def client(request: FixtureRequest) -> Iterator[RunwayML]:
45
60
 
46
61
  @pytest.fixture(scope="session")
47
62
  async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncRunwayML]:
48
- strict = getattr(request, "param", True)
49
- if not isinstance(strict, bool):
50
- raise TypeError(f"Unexpected fixture parameter type {type(strict)}, expected {bool}")
51
-
52
- async with AsyncRunwayML(base_url=base_url, api_key=api_key, _strict_response_validation=strict) as client:
63
+ param = getattr(request, "param", True)
64
+
65
+ # defaults
66
+ strict = True
67
+ http_client: None | httpx.AsyncClient = None
68
+
69
+ if isinstance(param, bool):
70
+ strict = param
71
+ elif is_dict(param):
72
+ strict = param.get("strict", True)
73
+ assert isinstance(strict, bool)
74
+
75
+ http_client_type = param.get("http_client", "httpx")
76
+ if http_client_type == "aiohttp":
77
+ http_client = DefaultAioHttpClient()
78
+ else:
79
+ raise TypeError(f"Unexpected fixture parameter type {type(param)}, expected bool or dict")
80
+
81
+ async with AsyncRunwayML(
82
+ base_url=base_url, api_key=api_key, _strict_response_validation=strict, http_client=http_client
83
+ ) as client:
53
84
  yield client
@@ -23,9 +23,7 @@ from pydantic import ValidationError
23
23
 
24
24
  from runwayml import RunwayML, AsyncRunwayML, APIResponseValidationError
25
25
  from runwayml._types import Omit
26
- from runwayml._utils import maybe_transform
27
26
  from runwayml._models import BaseModel, FinalRequestOptions
28
- from runwayml._constants import RAW_RESPONSE_HEADER
29
27
  from runwayml._exceptions import RunwayMLError, APIStatusError, APITimeoutError, APIResponseValidationError
30
28
  from runwayml._base_client import (
31
29
  DEFAULT_TIMEOUT,
@@ -35,7 +33,6 @@ from runwayml._base_client import (
35
33
  DefaultAsyncHttpxClient,
36
34
  make_request_options,
37
35
  )
38
- from runwayml.types.image_to_video_create_params import ImageToVideoCreateParams
39
36
 
40
37
  from .utils import update_env
41
38
 
@@ -194,6 +191,7 @@ class TestRunwayML:
194
191
  copy_param = copy_signature.parameters.get(name)
195
192
  assert copy_param is not None, f"copy() signature is missing the {name} param"
196
193
 
194
+ @pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12")
197
195
  def test_copy_build_request(self) -> None:
198
196
  options = FinalRequestOptions(method="get", url="/foo")
199
197
 
@@ -715,54 +713,25 @@ class TestRunwayML:
715
713
 
716
714
  @mock.patch("runwayml._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
717
715
  @pytest.mark.respx(base_url=base_url)
718
- def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> None:
716
+ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter, client: RunwayML) -> None:
719
717
  respx_mock.post("/v1/image_to_video").mock(side_effect=httpx.TimeoutException("Test timeout error"))
720
718
 
721
719
  with pytest.raises(APITimeoutError):
722
- self.client.post(
723
- "/v1/image_to_video",
724
- body=cast(
725
- object,
726
- maybe_transform(
727
- dict(
728
- model="gen4_turbo",
729
- prompt_image="https://example.com/assets/bunny.jpg",
730
- ratio="1280:720",
731
- prompt_text="The bunny is eating a carrot",
732
- ),
733
- ImageToVideoCreateParams,
734
- ),
735
- ),
736
- cast_to=httpx.Response,
737
- options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
738
- )
720
+ client.image_to_video.with_streaming_response.create(
721
+ model="gen3a_turbo", prompt_image="https://example.com", ratio="1280:720"
722
+ ).__enter__()
739
723
 
740
724
  assert _get_open_connections(self.client) == 0
741
725
 
742
726
  @mock.patch("runwayml._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
743
727
  @pytest.mark.respx(base_url=base_url)
744
- def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) -> None:
728
+ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter, client: RunwayML) -> None:
745
729
  respx_mock.post("/v1/image_to_video").mock(return_value=httpx.Response(500))
746
730
 
747
731
  with pytest.raises(APIStatusError):
748
- self.client.post(
749
- "/v1/image_to_video",
750
- body=cast(
751
- object,
752
- maybe_transform(
753
- dict(
754
- model="gen4_turbo",
755
- prompt_image="https://example.com/assets/bunny.jpg",
756
- ratio="1280:720",
757
- prompt_text="The bunny is eating a carrot",
758
- ),
759
- ImageToVideoCreateParams,
760
- ),
761
- ),
762
- cast_to=httpx.Response,
763
- options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
764
- )
765
-
732
+ client.image_to_video.with_streaming_response.create(
733
+ model="gen3a_turbo", prompt_image="https://example.com", ratio="1280:720"
734
+ ).__enter__()
766
735
  assert _get_open_connections(self.client) == 0
767
736
 
768
737
  @pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1039,6 +1008,7 @@ class TestAsyncRunwayML:
1039
1008
  copy_param = copy_signature.parameters.get(name)
1040
1009
  assert copy_param is not None, f"copy() signature is missing the {name} param"
1041
1010
 
1011
+ @pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12")
1042
1012
  def test_copy_build_request(self) -> None:
1043
1013
  options = FinalRequestOptions(method="get", url="/foo")
1044
1014
 
@@ -1574,54 +1544,29 @@ class TestAsyncRunwayML:
1574
1544
 
1575
1545
  @mock.patch("runwayml._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
1576
1546
  @pytest.mark.respx(base_url=base_url)
1577
- async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> None:
1547
+ async def test_retrying_timeout_errors_doesnt_leak(
1548
+ self, respx_mock: MockRouter, async_client: AsyncRunwayML
1549
+ ) -> None:
1578
1550
  respx_mock.post("/v1/image_to_video").mock(side_effect=httpx.TimeoutException("Test timeout error"))
1579
1551
 
1580
1552
  with pytest.raises(APITimeoutError):
1581
- await self.client.post(
1582
- "/v1/image_to_video",
1583
- body=cast(
1584
- object,
1585
- maybe_transform(
1586
- dict(
1587
- model="gen4_turbo",
1588
- prompt_image="https://example.com/assets/bunny.jpg",
1589
- ratio="1280:720",
1590
- prompt_text="The bunny is eating a carrot",
1591
- ),
1592
- ImageToVideoCreateParams,
1593
- ),
1594
- ),
1595
- cast_to=httpx.Response,
1596
- options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
1597
- )
1553
+ await async_client.image_to_video.with_streaming_response.create(
1554
+ model="gen3a_turbo", prompt_image="https://example.com", ratio="1280:720"
1555
+ ).__aenter__()
1598
1556
 
1599
1557
  assert _get_open_connections(self.client) == 0
1600
1558
 
1601
1559
  @mock.patch("runwayml._base_client.BaseClient._calculate_retry_timeout", _low_retry_timeout)
1602
1560
  @pytest.mark.respx(base_url=base_url)
1603
- async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) -> None:
1561
+ async def test_retrying_status_errors_doesnt_leak(
1562
+ self, respx_mock: MockRouter, async_client: AsyncRunwayML
1563
+ ) -> None:
1604
1564
  respx_mock.post("/v1/image_to_video").mock(return_value=httpx.Response(500))
1605
1565
 
1606
1566
  with pytest.raises(APIStatusError):
1607
- await self.client.post(
1608
- "/v1/image_to_video",
1609
- body=cast(
1610
- object,
1611
- maybe_transform(
1612
- dict(
1613
- model="gen4_turbo",
1614
- prompt_image="https://example.com/assets/bunny.jpg",
1615
- ratio="1280:720",
1616
- prompt_text="The bunny is eating a carrot",
1617
- ),
1618
- ImageToVideoCreateParams,
1619
- ),
1620
- ),
1621
- cast_to=httpx.Response,
1622
- options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
1623
- )
1624
-
1567
+ await async_client.image_to_video.with_streaming_response.create(
1568
+ model="gen3a_turbo", prompt_image="https://example.com", ratio="1280:720"
1569
+ ).__aenter__()
1625
1570
  assert _get_open_connections(self.client) == 0
1626
1571
 
1627
1572
  @pytest.mark.parametrize("failures_before_success", [0, 2, 4])
@@ -1,3 +0,0 @@
1
- {
2
- ".": "3.5.0"
3
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes