runwayml 3.0.0__tar.gz → 3.0.2__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.
- runwayml-3.0.2/.release-please-manifest.json +3 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/CHANGELOG.md +26 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/PKG-INFO +1 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/pyproject.toml +3 -2
- {runwayml-3.0.0 → runwayml-3.0.2}/requirements-dev.lock +1 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_base_client.py +40 -2
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_models.py +0 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_transform.py +24 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_typing.py +3 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_version.py +1 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/conftest.py +1 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_models.py +1 -1
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_transform.py +8 -1
- runwayml-3.0.0/.release-please-manifest.json +0 -3
- {runwayml-3.0.0 → runwayml-3.0.2}/.gitignore +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/CONTRIBUTING.md +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/LICENSE +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/README.md +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/SECURITY.md +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/api.md +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/bin/check-release-environment +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/bin/publish-pypi +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/examples/.keep +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/mypy.ini +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/noxfile.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/release-please-config.json +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/requirements.lock +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/__init__.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_client.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_compat.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_constants.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_exceptions.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_files.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_qs.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_resource.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_response.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_streaming.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_types.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/__init__.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_logs.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_proxy.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_reflection.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_streams.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_sync.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/_utils/_utils.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/lib/.keep +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/py.typed +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/resources/__init__.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/resources/image_to_video.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/resources/organization.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/resources/tasks.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/types/__init__.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/types/image_to_video_create_params.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/types/image_to_video_create_response.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/types/organization_retrieve_response.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/src/runwayml/types/task_retrieve_response.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/__init__.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/api_resources/__init__.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/api_resources/test_image_to_video.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/api_resources/test_organization.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/api_resources/test_tasks.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/sample_file.txt +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_client.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_deepcopy.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_extract_files.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_files.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_qs.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_required_args.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_response.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_streaming.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_utils/test_proxy.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/test_utils/test_typing.py +0 -0
- {runwayml-3.0.0 → runwayml-3.0.2}/tests/utils.py +0 -0
@@ -1,5 +1,31 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.0.2 (2025-04-17)
|
4
|
+
|
5
|
+
Full Changelog: [v3.0.1...v3.0.2](https://github.com/runwayml/sdk-python/compare/v3.0.1...v3.0.2)
|
6
|
+
|
7
|
+
### Chores
|
8
|
+
|
9
|
+
* **internal:** base client updates ([6d4d8bb](https://github.com/runwayml/sdk-python/commit/6d4d8bb73df9c0985d12d349d783188de0cd7d7d))
|
10
|
+
* **internal:** bump pyright version ([5693e26](https://github.com/runwayml/sdk-python/commit/5693e261dcbc21f6a900c514ba8e6659e0a2cd4f))
|
11
|
+
|
12
|
+
## 3.0.1 (2025-04-15)
|
13
|
+
|
14
|
+
Full Changelog: [v3.0.0...v3.0.1](https://github.com/runwayml/sdk-python/compare/v3.0.0...v3.0.1)
|
15
|
+
|
16
|
+
### Bug Fixes
|
17
|
+
|
18
|
+
* **perf:** optimize some hot paths ([0c187d1](https://github.com/runwayml/sdk-python/commit/0c187d1c445dd39661ec91f809ba1e51a9b5f0f2))
|
19
|
+
* **perf:** skip traversing types for NotGiven values ([a65d4b0](https://github.com/runwayml/sdk-python/commit/a65d4b0375c412d1b707550a8e1b1d9ba9319130))
|
20
|
+
|
21
|
+
|
22
|
+
### Chores
|
23
|
+
|
24
|
+
* **client:** minor internal fixes ([09dd17f](https://github.com/runwayml/sdk-python/commit/09dd17fc639bc5c9aadfc033c131b133764d4e5b))
|
25
|
+
* **internal:** expand CI branch coverage ([8bde5ff](https://github.com/runwayml/sdk-python/commit/8bde5ff981d4acd0696ad3b7ac778ca21a49a8ac))
|
26
|
+
* **internal:** reduce CI branch coverage ([5892e7a](https://github.com/runwayml/sdk-python/commit/5892e7aa93fa9e091f111fd0590b239487ba61eb))
|
27
|
+
* **internal:** update pyright settings ([8b3a8ae](https://github.com/runwayml/sdk-python/commit/8b3a8ae32a589680549054328996ae7314be3033))
|
28
|
+
|
3
29
|
## 3.0.0 (2025-04-09)
|
4
30
|
|
5
31
|
Full Changelog: [v2.3.8...v3.0.0](https://github.com/runwayml/sdk-python/compare/v2.3.8...v3.0.0)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "runwayml"
|
3
|
-
version = "3.0.
|
3
|
+
version = "3.0.2"
|
4
4
|
description = "The official Python library for the runwayml API"
|
5
5
|
dynamic = ["readme"]
|
6
6
|
license = "Apache-2.0"
|
@@ -42,7 +42,7 @@ Repository = "https://github.com/runwayml/sdk-python"
|
|
42
42
|
managed = true
|
43
43
|
# version pins are in requirements-dev.lock
|
44
44
|
dev-dependencies = [
|
45
|
-
"pyright
|
45
|
+
"pyright==1.1.399",
|
46
46
|
"mypy",
|
47
47
|
"respx",
|
48
48
|
"pytest",
|
@@ -147,6 +147,7 @@ exclude = [
|
|
147
147
|
]
|
148
148
|
|
149
149
|
reportImplicitOverride = true
|
150
|
+
reportOverlappingOverload = false
|
150
151
|
|
151
152
|
reportImportCycles = false
|
152
153
|
reportPrivateUsage = false
|
@@ -98,7 +98,11 @@ _StreamT = TypeVar("_StreamT", bound=Stream[Any])
|
|
98
98
|
_AsyncStreamT = TypeVar("_AsyncStreamT", bound=AsyncStream[Any])
|
99
99
|
|
100
100
|
if TYPE_CHECKING:
|
101
|
-
from httpx._config import
|
101
|
+
from httpx._config import (
|
102
|
+
DEFAULT_TIMEOUT_CONFIG, # pyright: ignore[reportPrivateImportUsage]
|
103
|
+
)
|
104
|
+
|
105
|
+
HTTPX_DEFAULT_TIMEOUT = DEFAULT_TIMEOUT_CONFIG
|
102
106
|
else:
|
103
107
|
try:
|
104
108
|
from httpx._config import DEFAULT_TIMEOUT_CONFIG as HTTPX_DEFAULT_TIMEOUT
|
@@ -115,6 +119,7 @@ class PageInfo:
|
|
115
119
|
|
116
120
|
url: URL | NotGiven
|
117
121
|
params: Query | NotGiven
|
122
|
+
json: Body | NotGiven
|
118
123
|
|
119
124
|
@overload
|
120
125
|
def __init__(
|
@@ -130,19 +135,30 @@ class PageInfo:
|
|
130
135
|
params: Query,
|
131
136
|
) -> None: ...
|
132
137
|
|
138
|
+
@overload
|
139
|
+
def __init__(
|
140
|
+
self,
|
141
|
+
*,
|
142
|
+
json: Body,
|
143
|
+
) -> None: ...
|
144
|
+
|
133
145
|
def __init__(
|
134
146
|
self,
|
135
147
|
*,
|
136
148
|
url: URL | NotGiven = NOT_GIVEN,
|
149
|
+
json: Body | NotGiven = NOT_GIVEN,
|
137
150
|
params: Query | NotGiven = NOT_GIVEN,
|
138
151
|
) -> None:
|
139
152
|
self.url = url
|
153
|
+
self.json = json
|
140
154
|
self.params = params
|
141
155
|
|
142
156
|
@override
|
143
157
|
def __repr__(self) -> str:
|
144
158
|
if self.url:
|
145
159
|
return f"{self.__class__.__name__}(url={self.url})"
|
160
|
+
if self.json:
|
161
|
+
return f"{self.__class__.__name__}(json={self.json})"
|
146
162
|
return f"{self.__class__.__name__}(params={self.params})"
|
147
163
|
|
148
164
|
|
@@ -191,6 +207,19 @@ class BasePage(GenericModel, Generic[_T]):
|
|
191
207
|
options.url = str(url)
|
192
208
|
return options
|
193
209
|
|
210
|
+
if not isinstance(info.json, NotGiven):
|
211
|
+
if not is_mapping(info.json):
|
212
|
+
raise TypeError("Pagination is only supported with mappings")
|
213
|
+
|
214
|
+
if not options.json_data:
|
215
|
+
options.json_data = {**info.json}
|
216
|
+
else:
|
217
|
+
if not is_mapping(options.json_data):
|
218
|
+
raise TypeError("Pagination is only supported with mappings")
|
219
|
+
|
220
|
+
options.json_data = {**options.json_data, **info.json}
|
221
|
+
return options
|
222
|
+
|
194
223
|
raise ValueError("Unexpected PageInfo state")
|
195
224
|
|
196
225
|
|
@@ -409,7 +438,8 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
|
|
409
438
|
|
410
439
|
idempotency_header = self._idempotency_header
|
411
440
|
if idempotency_header and options.method.lower() != "get" and idempotency_header not in headers:
|
412
|
-
|
441
|
+
options.idempotency_key = options.idempotency_key or self._idempotency_key()
|
442
|
+
headers[idempotency_header] = options.idempotency_key
|
413
443
|
|
414
444
|
# Don't set these headers if they were already set or removed by the caller. We check
|
415
445
|
# `custom_headers`, which can contain `Omit()`, instead of `headers` to account for the removal case.
|
@@ -943,6 +973,10 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
|
|
943
973
|
request = self._build_request(options, retries_taken=retries_taken)
|
944
974
|
self._prepare_request(request)
|
945
975
|
|
976
|
+
if options.idempotency_key:
|
977
|
+
# ensure the idempotency key is reused between requests
|
978
|
+
input_options.idempotency_key = options.idempotency_key
|
979
|
+
|
946
980
|
kwargs: HttpxSendArgs = {}
|
947
981
|
if self.custom_auth is not None:
|
948
982
|
kwargs["auth"] = self.custom_auth
|
@@ -1475,6 +1509,10 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
|
|
1475
1509
|
request = self._build_request(options, retries_taken=retries_taken)
|
1476
1510
|
await self._prepare_request(request)
|
1477
1511
|
|
1512
|
+
if options.idempotency_key:
|
1513
|
+
# ensure the idempotency key is reused between requests
|
1514
|
+
input_options.idempotency_key = options.idempotency_key
|
1515
|
+
|
1478
1516
|
kwargs: HttpxSendArgs = {}
|
1479
1517
|
if self.custom_auth is not None:
|
1480
1518
|
kwargs["auth"] = self.custom_auth
|
@@ -5,13 +5,15 @@ import base64
|
|
5
5
|
import pathlib
|
6
6
|
from typing import Any, Mapping, TypeVar, cast
|
7
7
|
from datetime import date, datetime
|
8
|
-
from typing_extensions import Literal, get_args, override, get_type_hints
|
8
|
+
from typing_extensions import Literal, get_args, override, get_type_hints as _get_type_hints
|
9
9
|
|
10
10
|
import anyio
|
11
11
|
import pydantic
|
12
12
|
|
13
13
|
from ._utils import (
|
14
14
|
is_list,
|
15
|
+
is_given,
|
16
|
+
lru_cache,
|
15
17
|
is_mapping,
|
16
18
|
is_iterable,
|
17
19
|
)
|
@@ -108,6 +110,7 @@ def transform(
|
|
108
110
|
return cast(_T, transformed)
|
109
111
|
|
110
112
|
|
113
|
+
@lru_cache(maxsize=8096)
|
111
114
|
def _get_annotated_type(type_: type) -> type | None:
|
112
115
|
"""If the given type is an `Annotated` type then it is returned, if not `None` is returned.
|
113
116
|
|
@@ -258,6 +261,11 @@ def _transform_typeddict(
|
|
258
261
|
result: dict[str, object] = {}
|
259
262
|
annotations = get_type_hints(expected_type, include_extras=True)
|
260
263
|
for key, value in data.items():
|
264
|
+
if not is_given(value):
|
265
|
+
# we don't need to include `NotGiven` values here as they'll
|
266
|
+
# be stripped out before the request is sent anyway
|
267
|
+
continue
|
268
|
+
|
261
269
|
type_ = annotations.get(key)
|
262
270
|
if type_ is None:
|
263
271
|
# we do not have a type annotation for this field, leave it as is
|
@@ -415,6 +423,11 @@ async def _async_transform_typeddict(
|
|
415
423
|
result: dict[str, object] = {}
|
416
424
|
annotations = get_type_hints(expected_type, include_extras=True)
|
417
425
|
for key, value in data.items():
|
426
|
+
if not is_given(value):
|
427
|
+
# we don't need to include `NotGiven` values here as they'll
|
428
|
+
# be stripped out before the request is sent anyway
|
429
|
+
continue
|
430
|
+
|
418
431
|
type_ = annotations.get(key)
|
419
432
|
if type_ is None:
|
420
433
|
# we do not have a type annotation for this field, leave it as is
|
@@ -422,3 +435,13 @@ async def _async_transform_typeddict(
|
|
422
435
|
else:
|
423
436
|
result[_maybe_transform_key(key, type_)] = await _async_transform_recursive(value, annotation=type_)
|
424
437
|
return result
|
438
|
+
|
439
|
+
|
440
|
+
@lru_cache(maxsize=8096)
|
441
|
+
def get_type_hints(
|
442
|
+
obj: Any,
|
443
|
+
globalns: dict[str, Any] | None = None,
|
444
|
+
localns: Mapping[str, Any] | None = None,
|
445
|
+
include_extras: bool = False,
|
446
|
+
) -> dict[str, Any]:
|
447
|
+
return _get_type_hints(obj, globalns=globalns, localns=localns, include_extras=include_extras)
|
@@ -13,6 +13,7 @@ from typing_extensions import (
|
|
13
13
|
get_origin,
|
14
14
|
)
|
15
15
|
|
16
|
+
from ._utils import lru_cache
|
16
17
|
from .._types import InheritsGeneric
|
17
18
|
from .._compat import is_union as _is_union
|
18
19
|
|
@@ -66,6 +67,7 @@ def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]:
|
|
66
67
|
|
67
68
|
|
68
69
|
# Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]]
|
70
|
+
@lru_cache(maxsize=8096)
|
69
71
|
def strip_annotated_type(typ: type) -> type:
|
70
72
|
if is_required_type(typ) or is_annotated_type(typ):
|
71
73
|
return strip_annotated_type(cast(type, get_args(typ)[0]))
|
@@ -108,7 +110,7 @@ def extract_type_var_from_base(
|
|
108
110
|
```
|
109
111
|
"""
|
110
112
|
cls = cast(object, get_origin(typ) or typ)
|
111
|
-
if cls in generic_bases:
|
113
|
+
if cls in generic_bases: # pyright: ignore[reportUnnecessaryContains]
|
112
114
|
# we're given the class directly
|
113
115
|
return extract_type_arg(typ, index)
|
114
116
|
|
@@ -10,7 +10,7 @@ from pytest_asyncio import is_async_test
|
|
10
10
|
from runwayml import RunwayML, AsyncRunwayML
|
11
11
|
|
12
12
|
if TYPE_CHECKING:
|
13
|
-
from _pytest.fixtures import FixtureRequest
|
13
|
+
from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
|
14
14
|
|
15
15
|
pytest.register_assert_rewrite("tests.utils")
|
16
16
|
|
@@ -832,7 +832,7 @@ def test_discriminated_unions_invalid_data_uses_cache() -> None:
|
|
832
832
|
|
833
833
|
@pytest.mark.skipif(not PYDANTIC_V2, reason="TypeAliasType is not supported in Pydantic v1")
|
834
834
|
def test_type_alias_type() -> None:
|
835
|
-
Alias = TypeAliasType("Alias", str)
|
835
|
+
Alias = TypeAliasType("Alias", str) # pyright: ignore
|
836
836
|
|
837
837
|
class Model(BaseModel):
|
838
838
|
alias: Alias
|
@@ -8,7 +8,7 @@ from typing_extensions import Required, Annotated, TypedDict
|
|
8
8
|
|
9
9
|
import pytest
|
10
10
|
|
11
|
-
from runwayml._types import Base64FileInput
|
11
|
+
from runwayml._types import NOT_GIVEN, Base64FileInput
|
12
12
|
from runwayml._utils import (
|
13
13
|
PropertyInfo,
|
14
14
|
transform as _transform,
|
@@ -444,3 +444,10 @@ async def test_transform_skipping(use_async: bool) -> None:
|
|
444
444
|
# iterables of ints are converted to a list
|
445
445
|
data = iter([1, 2, 3])
|
446
446
|
assert await transform(data, Iterable[int], use_async) == [1, 2, 3]
|
447
|
+
|
448
|
+
|
449
|
+
@parametrize
|
450
|
+
@pytest.mark.asyncio
|
451
|
+
async def test_strips_notgiven(use_async: bool) -> None:
|
452
|
+
assert await transform({"foo_bar": "bar"}, Foo1, use_async) == {"fooBar": "bar"}
|
453
|
+
assert await transform({"foo_bar": NOT_GIVEN}, Foo1, use_async) == {}
|
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
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|