remotion-lambda 4.0.347__tar.gz → 4.0.351__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.
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/PKG-INFO +1 -1
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda/remotionclient.py +60 -43
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda/version.py +1 -1
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda.egg-info/PKG-INFO +1 -1
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda.egg-info/SOURCES.txt +3 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/tests/__init__.py +2 -3
- remotion_lambda-4.0.351/tests/conftest.py +33 -0
- remotion_lambda-4.0.351/tests/constants.py +5 -0
- remotion_lambda-4.0.351/tests/test_get_render_progress_client.py +23 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/tests/test_large_payload_compression.py +34 -29
- remotion_lambda-4.0.351/tests/test_remotion_client.py +176 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/tests/test_render_client_render_media.py +12 -12
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/tests/test_render_client_render_still.py +9 -8
- remotion_lambda-4.0.347/tests/test_get_render_progress_client.py +0 -22
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/LICENSE +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/README.md +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda/__init__.py +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda/models.py +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda.egg-info/dependency_links.txt +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda.egg-info/requires.txt +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda.egg-info/top_level.txt +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/setup.cfg +0 -0
- {remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/setup.py +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# pylint: disable=too-few-public-methods, missing-module-docstring, broad-exception-caught
|
|
2
|
+
import logging
|
|
2
3
|
from dataclasses import asdict
|
|
3
4
|
import random
|
|
4
5
|
import json
|
|
5
6
|
import hashlib
|
|
6
7
|
from math import ceil
|
|
7
|
-
from typing import Optional, Union
|
|
8
|
+
from typing import Optional, Union, List
|
|
8
9
|
from enum import Enum
|
|
9
10
|
import boto3
|
|
10
11
|
from botocore.exceptions import ClientError
|
|
@@ -22,17 +23,23 @@ from .models import (
|
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
BUCKET_NAME_PREFIX = 'remotionlambda-'
|
|
29
|
+
REGION_US_EAST = 'us-east-1'
|
|
30
|
+
|
|
31
|
+
|
|
25
32
|
class RemotionClient:
|
|
26
33
|
"""A client for interacting with the Remotion service."""
|
|
27
34
|
|
|
28
35
|
# pylint: disable=too-many-arguments
|
|
29
36
|
def __init__(
|
|
30
37
|
self,
|
|
31
|
-
region,
|
|
32
|
-
serve_url,
|
|
33
|
-
function_name,
|
|
34
|
-
access_key=None,
|
|
35
|
-
secret_key=None,
|
|
38
|
+
region: str,
|
|
39
|
+
serve_url: str,
|
|
40
|
+
function_name: str,
|
|
41
|
+
access_key: Optional[str] = None,
|
|
42
|
+
secret_key: Optional[str] = None,
|
|
36
43
|
force_path_style=False,
|
|
37
44
|
):
|
|
38
45
|
"""
|
|
@@ -67,7 +74,7 @@ class RemotionClient:
|
|
|
67
74
|
# Use the same logic as JS SDK: prefix + region without dashes + random hash
|
|
68
75
|
region_no_dashes = self.region.replace('-', '')
|
|
69
76
|
random_suffix = self._generate_random_hash()
|
|
70
|
-
return f"
|
|
77
|
+
return f"{BUCKET_NAME_PREFIX}{region_no_dashes}-{random_suffix}"
|
|
71
78
|
|
|
72
79
|
def _input_props_key(self, hash_value):
|
|
73
80
|
"""Generate S3 key for input props."""
|
|
@@ -75,47 +82,56 @@ class RemotionClient:
|
|
|
75
82
|
|
|
76
83
|
def _create_s3_client(self):
|
|
77
84
|
"""Create S3 client with appropriate credentials."""
|
|
78
|
-
|
|
85
|
+
kwargs = {'region_name': self.region}
|
|
86
|
+
|
|
79
87
|
if self.force_path_style:
|
|
80
|
-
config = Config(s3={'addressing_style': 'path'})
|
|
88
|
+
kwargs['config'] = Config(s3={'addressing_style': 'path'})
|
|
81
89
|
|
|
82
90
|
if self.access_key and self.secret_key:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
config=config,
|
|
91
|
+
kwargs.update(
|
|
92
|
+
{
|
|
93
|
+
'aws_access_key_id': self.access_key,
|
|
94
|
+
'aws_secret_access_key': self.secret_key,
|
|
95
|
+
}
|
|
89
96
|
)
|
|
90
|
-
return boto3.client('s3', region_name=self.region, config=config)
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
return boto3.client('s3', **kwargs)
|
|
99
|
+
|
|
100
|
+
def _get_remotion_buckets(self) -> List[str]:
|
|
94
101
|
s3_client = self._create_s3_client()
|
|
102
|
+
|
|
95
103
|
try:
|
|
96
104
|
response = s3_client.list_buckets()
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
bucket_name = bucket['Name']
|
|
100
|
-
if bucket_name.startswith('remotionlambda-'):
|
|
101
|
-
# Check if bucket is in the correct region
|
|
102
|
-
try:
|
|
103
|
-
bucket_region = s3_client.get_bucket_location(
|
|
104
|
-
Bucket=bucket_name
|
|
105
|
-
)
|
|
106
|
-
location = bucket_region.get('LocationConstraint')
|
|
107
|
-
# us-east-1 returns None for LocationConstraint
|
|
108
|
-
if location == self.region or (
|
|
109
|
-
location is None and self.region == 'us-east-1'
|
|
110
|
-
):
|
|
111
|
-
buckets.append(bucket_name)
|
|
112
|
-
except ClientError:
|
|
113
|
-
# Ignore buckets we can't access
|
|
114
|
-
continue
|
|
115
|
-
return buckets
|
|
116
|
-
except ClientError:
|
|
105
|
+
except ClientError as e:
|
|
106
|
+
logger.warning("Could not list S3 buckets: %s", e)
|
|
117
107
|
return []
|
|
118
108
|
|
|
109
|
+
remotion_buckets = []
|
|
110
|
+
|
|
111
|
+
for bucket in response.get('Buckets', []):
|
|
112
|
+
bucket_name = bucket['Name']
|
|
113
|
+
|
|
114
|
+
if not bucket_name.startswith(BUCKET_NAME_PREFIX):
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
if self._is_bucket_in_current_region(s3_client, bucket_name):
|
|
118
|
+
remotion_buckets.append(bucket_name)
|
|
119
|
+
|
|
120
|
+
return remotion_buckets
|
|
121
|
+
|
|
122
|
+
def _is_bucket_in_current_region(self, s3_client, bucket_name: str) -> bool:
|
|
123
|
+
try:
|
|
124
|
+
bucket_region = s3_client.get_bucket_location(Bucket=bucket_name)
|
|
125
|
+
location = bucket_region.get('LocationConstraint')
|
|
126
|
+
|
|
127
|
+
# us-east-1 returns None for LocationConstraint
|
|
128
|
+
return location == self.region or (
|
|
129
|
+
location is None and self.region == REGION_US_EAST
|
|
130
|
+
)
|
|
131
|
+
except ClientError:
|
|
132
|
+
# Ignore buckets we can't access (permission issues, etc.)
|
|
133
|
+
return False
|
|
134
|
+
|
|
119
135
|
def _get_or_create_bucket(self):
|
|
120
136
|
"""Get existing bucket or create a new one following JS SDK logic."""
|
|
121
137
|
buckets = self._get_remotion_buckets()
|
|
@@ -136,7 +152,7 @@ class RemotionClient:
|
|
|
136
152
|
s3_client = self._create_s3_client()
|
|
137
153
|
|
|
138
154
|
try:
|
|
139
|
-
if self.region ==
|
|
155
|
+
if self.region == REGION_US_EAST:
|
|
140
156
|
s3_client.create_bucket(Bucket=bucket_name)
|
|
141
157
|
else:
|
|
142
158
|
s3_client.create_bucket(
|
|
@@ -173,10 +189,11 @@ class RemotionClient:
|
|
|
173
189
|
|
|
174
190
|
if payload_size > max_size:
|
|
175
191
|
# Log warning similar to JavaScript implementation
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
192
|
+
logger.warning(
|
|
193
|
+
"Warning: The props are over %sKB (%sKB) in size. Uploading them to S3 to "
|
|
194
|
+
"circumvent AWS Lambda payload size, which may lead to slowdown.",
|
|
195
|
+
round(max_size / 1000),
|
|
196
|
+
ceil(payload_size / 1024),
|
|
180
197
|
)
|
|
181
198
|
return True
|
|
182
199
|
return False
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# pylint: disable=missing-module-docstring, missing-final-newline
|
|
2
|
-
VERSION = "4.0.
|
|
2
|
+
VERSION = "4.0.351"
|
|
@@ -11,7 +11,10 @@ remotion_lambda.egg-info/dependency_links.txt
|
|
|
11
11
|
remotion_lambda.egg-info/requires.txt
|
|
12
12
|
remotion_lambda.egg-info/top_level.txt
|
|
13
13
|
tests/__init__.py
|
|
14
|
+
tests/conftest.py
|
|
15
|
+
tests/constants.py
|
|
14
16
|
tests/test_get_render_progress_client.py
|
|
15
17
|
tests/test_large_payload_compression.py
|
|
18
|
+
tests/test_remotion_client.py
|
|
16
19
|
tests/test_render_client_render_media.py
|
|
17
20
|
tests/test_render_client_render_still.py
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from remotion_lambda.remotionclient import RemotionClient
|
|
3
|
+
from tests.constants import (
|
|
4
|
+
TEST_FUNCTION_NAME,
|
|
5
|
+
TEST_REGION,
|
|
6
|
+
TEST_SERVE_URL,
|
|
7
|
+
TEST_AWS_ACCESS_KEY,
|
|
8
|
+
TEST_AWS_SECRET_KEY,
|
|
9
|
+
)
|
|
10
|
+
from unittest.mock import Mock
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@pytest.fixture
|
|
14
|
+
def remotion_client():
|
|
15
|
+
return RemotionClient(
|
|
16
|
+
region=TEST_REGION, serve_url=TEST_SERVE_URL, function_name=TEST_FUNCTION_NAME
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.fixture
|
|
21
|
+
def remotion_client_with_creds():
|
|
22
|
+
return RemotionClient(
|
|
23
|
+
region=TEST_REGION,
|
|
24
|
+
serve_url=TEST_SERVE_URL,
|
|
25
|
+
function_name=TEST_FUNCTION_NAME,
|
|
26
|
+
access_key=TEST_AWS_ACCESS_KEY,
|
|
27
|
+
secret_key=TEST_AWS_SECRET_KEY,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def mock_s3_client():
|
|
33
|
+
return Mock()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from unittest import TestCase
|
|
2
|
+
|
|
3
|
+
from remotion_lambda.remotionclient import RemotionClient, CustomCredentials
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestRemotionClient(TestCase):
|
|
7
|
+
def test_remotionprogress_construct_request(self):
|
|
8
|
+
client = RemotionClient(
|
|
9
|
+
region="us-east-1", serve_url="testbed", function_name="remotion-render"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
print(
|
|
13
|
+
client.construct_render_progress_request(
|
|
14
|
+
render_id="abcdef",
|
|
15
|
+
bucket_name="remotion-render",
|
|
16
|
+
s3_output_provider=CustomCredentials(
|
|
17
|
+
endpoint="https://s3.us-east-1.amazonaws.com",
|
|
18
|
+
access_key_id="accessKeyId",
|
|
19
|
+
secret_access_key="secretAccessKey",
|
|
20
|
+
region="us-east-1",
|
|
21
|
+
),
|
|
22
|
+
)
|
|
23
|
+
)
|
|
@@ -5,106 +5,111 @@ from remotion_lambda.remotionclient import RemotionClient
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class TestLargePayloadCompression(unittest.TestCase):
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
def setUp(self):
|
|
10
10
|
self.client = RemotionClient(
|
|
11
|
-
region="us-east-1",
|
|
12
|
-
serve_url="testbed",
|
|
13
|
-
function_name="remotion-render"
|
|
11
|
+
region="us-east-1", serve_url="testbed", function_name="remotion-render"
|
|
14
12
|
)
|
|
15
|
-
|
|
13
|
+
|
|
16
14
|
def test_small_payload_uses_payload_format(self):
|
|
17
15
|
"""Test that small payloads use the payload format."""
|
|
18
16
|
small_props = {'message': 'small'}
|
|
19
17
|
result = self.client._serialize_input_props(small_props, 'video-or-audio')
|
|
20
|
-
|
|
18
|
+
|
|
21
19
|
self.assertEqual(result['type'], 'payload')
|
|
22
20
|
self.assertIn('payload', result)
|
|
23
21
|
self.assertNotIn('hash', result)
|
|
24
22
|
self.assertNotIn('bucketName', result)
|
|
25
|
-
|
|
23
|
+
|
|
26
24
|
@patch('remotion_lambda.remotionclient.RemotionClient._upload_to_s3')
|
|
27
25
|
@patch('remotion_lambda.remotionclient.RemotionClient._get_or_create_bucket')
|
|
28
26
|
def test_large_payload_uses_bucket_format(self, mock_get_bucket, mock_upload):
|
|
29
27
|
"""Test that large payloads use the bucket-url format."""
|
|
30
28
|
mock_get_bucket.return_value = 'remotionlambda-useast1-testbucket'
|
|
31
|
-
|
|
29
|
+
|
|
32
30
|
# Create a large payload that exceeds the limit for video-or-audio (200KB - margin)
|
|
33
31
|
large_data = 'x' * 200000 # 200KB of data
|
|
34
32
|
large_props = {'data': large_data}
|
|
35
|
-
|
|
33
|
+
|
|
36
34
|
result = self.client._serialize_input_props(large_props, 'video-or-audio')
|
|
37
|
-
|
|
35
|
+
|
|
38
36
|
self.assertEqual(result['type'], 'bucket-url')
|
|
39
37
|
self.assertIn('hash', result)
|
|
40
38
|
self.assertIn('bucketName', result)
|
|
41
39
|
self.assertEqual(result['bucketName'], 'remotionlambda-useast1-testbucket')
|
|
42
|
-
|
|
40
|
+
|
|
43
41
|
# Verify S3 upload was called
|
|
44
42
|
mock_upload.assert_called_once()
|
|
45
|
-
|
|
43
|
+
|
|
46
44
|
def test_needs_upload_logic(self):
|
|
47
45
|
"""Test the logic for determining when upload is needed."""
|
|
48
46
|
# Small payload should not need upload
|
|
49
47
|
self.assertFalse(self.client._needs_upload(1000, 'video-or-audio'))
|
|
50
48
|
self.assertFalse(self.client._needs_upload(1000, 'still'))
|
|
51
|
-
|
|
49
|
+
|
|
52
50
|
# Large payload for video should need upload
|
|
53
51
|
self.assertTrue(self.client._needs_upload(200000, 'video-or-audio'))
|
|
54
|
-
|
|
52
|
+
|
|
55
53
|
# Large payload for still should need upload (over 5MB)
|
|
56
54
|
self.assertTrue(self.client._needs_upload(5000000, 'still'))
|
|
57
|
-
|
|
55
|
+
|
|
58
56
|
# Medium payload for still should not need upload
|
|
59
57
|
self.assertFalse(self.client._needs_upload(1000000, 'still'))
|
|
60
|
-
|
|
58
|
+
|
|
61
59
|
def test_hash_generation(self):
|
|
62
60
|
"""Test that hash generation is consistent."""
|
|
63
61
|
payload = '{"test": "data"}'
|
|
64
62
|
hash1 = self.client._generate_hash(payload)
|
|
65
63
|
hash2 = self.client._generate_hash(payload)
|
|
66
|
-
|
|
64
|
+
|
|
67
65
|
self.assertEqual(hash1, hash2)
|
|
68
66
|
self.assertIsInstance(hash1, str)
|
|
69
67
|
self.assertEqual(len(hash1), 64) # SHA256 hex string length
|
|
70
|
-
|
|
68
|
+
|
|
71
69
|
def test_input_props_key_generation(self):
|
|
72
70
|
"""Test S3 key generation for input props."""
|
|
73
71
|
hash_value = 'test123'
|
|
74
72
|
key = self.client._input_props_key(hash_value)
|
|
75
73
|
self.assertEqual(key, 'input-props/test123.json')
|
|
76
|
-
|
|
74
|
+
|
|
77
75
|
def test_bucket_name_generation(self):
|
|
78
76
|
"""Test bucket name generation following JS SDK conventions."""
|
|
79
77
|
bucket_name = self.client._make_bucket_name()
|
|
80
|
-
|
|
78
|
+
|
|
81
79
|
# Should start with remotionlambda- prefix
|
|
82
80
|
self.assertTrue(bucket_name.startswith('remotionlambda-'))
|
|
83
|
-
|
|
81
|
+
|
|
84
82
|
# Should contain region without dashes
|
|
85
83
|
expected_region = self.client.region.replace('-', '')
|
|
86
84
|
self.assertIn(expected_region, bucket_name)
|
|
87
|
-
|
|
85
|
+
|
|
88
86
|
# Should be in format: remotionlambda-{region-no-dashes}-{random-hash}
|
|
89
87
|
parts = bucket_name.split('-')
|
|
90
88
|
self.assertEqual(len(parts), 3) # remotionlambda, region, hash
|
|
91
89
|
self.assertEqual(parts[0], 'remotionlambda')
|
|
92
90
|
self.assertEqual(parts[1], expected_region)
|
|
93
91
|
self.assertEqual(len(parts[2]), 10) # random hash should be 10 chars
|
|
94
|
-
|
|
92
|
+
|
|
95
93
|
@patch('remotion_lambda.remotionclient.RemotionClient._get_remotion_buckets')
|
|
96
|
-
def test_get_or_create_bucket_with_multiple_buckets_raises_error(
|
|
94
|
+
def test_get_or_create_bucket_with_multiple_buckets_raises_error(
|
|
95
|
+
self, mock_get_buckets
|
|
96
|
+
):
|
|
97
97
|
"""Test that multiple buckets raises the correct error."""
|
|
98
|
-
mock_get_buckets.return_value = [
|
|
99
|
-
|
|
98
|
+
mock_get_buckets.return_value = [
|
|
99
|
+
'remotionlambda-useast1-abc123',
|
|
100
|
+
'remotionlambda-useast1-def456',
|
|
101
|
+
]
|
|
102
|
+
|
|
100
103
|
with self.assertRaises(ValueError) as context:
|
|
101
104
|
self.client._get_or_create_bucket()
|
|
102
|
-
|
|
105
|
+
|
|
103
106
|
error_message = str(context.exception)
|
|
104
107
|
self.assertIn('multiple buckets', error_message)
|
|
105
108
|
self.assertIn('remotionlambda-', error_message)
|
|
106
|
-
self.assertIn(
|
|
109
|
+
self.assertIn(
|
|
110
|
+
'https://remotion.dev/docs/lambda/multiple-buckets', error_message
|
|
111
|
+
)
|
|
107
112
|
|
|
108
113
|
|
|
109
114
|
if __name__ == '__main__':
|
|
110
|
-
unittest.main()
|
|
115
|
+
unittest.main()
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
from tests.conftest import remotion_client, mock_s3_client, remotion_client_with_creds
|
|
2
|
+
from remotion_lambda.remotionclient import RemotionClient
|
|
3
|
+
import pytest
|
|
4
|
+
from tests.constants import (
|
|
5
|
+
TEST_FUNCTION_NAME,
|
|
6
|
+
TEST_REGION,
|
|
7
|
+
TEST_SERVE_URL,
|
|
8
|
+
TEST_AWS_SECRET_KEY,
|
|
9
|
+
TEST_AWS_ACCESS_KEY,
|
|
10
|
+
)
|
|
11
|
+
from unittest.mock import patch, Mock
|
|
12
|
+
from botocore.config import Config
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_bucket_name_format(remotion_client: RemotionClient):
|
|
16
|
+
bucket_name = remotion_client._make_bucket_name()
|
|
17
|
+
assert bucket_name.startswith("remotionlambda-useast1-")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_client_config(remotion_client: RemotionClient):
|
|
21
|
+
assert remotion_client.function_name == TEST_FUNCTION_NAME
|
|
22
|
+
assert remotion_client.region == TEST_REGION
|
|
23
|
+
assert remotion_client.serve_url == TEST_SERVE_URL
|
|
24
|
+
assert not remotion_client.access_key
|
|
25
|
+
assert not remotion_client.secret_key
|
|
26
|
+
assert not remotion_client.force_path_style
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_client_config_with_creds(remotion_client_with_creds: RemotionClient):
|
|
30
|
+
remotion_client = remotion_client_with_creds
|
|
31
|
+
assert remotion_client.function_name == TEST_FUNCTION_NAME
|
|
32
|
+
assert remotion_client.region == TEST_REGION
|
|
33
|
+
assert remotion_client.serve_url == TEST_SERVE_URL
|
|
34
|
+
assert remotion_client.access_key == TEST_AWS_ACCESS_KEY
|
|
35
|
+
assert remotion_client.secret_key == TEST_AWS_SECRET_KEY
|
|
36
|
+
assert not remotion_client.force_path_style
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.mark.parametrize(
|
|
40
|
+
"hash_value,expected",
|
|
41
|
+
[
|
|
42
|
+
("a1b2c3", "input-props/a1b2c3.json"),
|
|
43
|
+
(
|
|
44
|
+
"very_long_hash_value_123456789",
|
|
45
|
+
"input-props/very_long_hash_value_123456789.json",
|
|
46
|
+
),
|
|
47
|
+
],
|
|
48
|
+
)
|
|
49
|
+
def test_input_props_key_multiple_values(remotion_client, hash_value, expected):
|
|
50
|
+
result = remotion_client._input_props_key(hash_value)
|
|
51
|
+
assert result == expected
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_generate_hash_basic_string(remotion_client: RemotionClient):
|
|
55
|
+
payload = "test payload"
|
|
56
|
+
result = remotion_client._generate_hash(payload)
|
|
57
|
+
|
|
58
|
+
assert len(result) == 64
|
|
59
|
+
assert all(c in '0123456789abcdef' for c in result)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@patch('boto3.client')
|
|
63
|
+
def test_create_s3_client_default(
|
|
64
|
+
mock_boto_client, mock_s3_client, remotion_client: RemotionClient
|
|
65
|
+
):
|
|
66
|
+
mock_boto_client.return_value = mock_s3_client
|
|
67
|
+
result = remotion_client._create_s3_client()
|
|
68
|
+
|
|
69
|
+
mock_boto_client.assert_called_once_with('s3', region_name=TEST_REGION)
|
|
70
|
+
assert result == mock_s3_client
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@patch('boto3.client')
|
|
74
|
+
def test_create_s3_client_partial_creds(mock_boto_client, mock_s3_client):
|
|
75
|
+
remotion_client = RemotionClient(
|
|
76
|
+
region=TEST_REGION,
|
|
77
|
+
serve_url=TEST_SERVE_URL,
|
|
78
|
+
function_name=TEST_FUNCTION_NAME,
|
|
79
|
+
secret_key=TEST_AWS_SECRET_KEY,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
mock_boto_client.return_value = mock_s3_client
|
|
83
|
+
result = remotion_client._create_s3_client()
|
|
84
|
+
|
|
85
|
+
mock_boto_client.assert_called_once_with('s3', region_name=TEST_REGION)
|
|
86
|
+
assert result == mock_s3_client
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@patch('boto3.client')
|
|
90
|
+
def test_create_s3_client_creds(
|
|
91
|
+
mock_boto_client, mock_s3_client, remotion_client_with_creds
|
|
92
|
+
):
|
|
93
|
+
mock_boto_client.return_value = mock_s3_client
|
|
94
|
+
result = remotion_client_with_creds._create_s3_client()
|
|
95
|
+
|
|
96
|
+
mock_boto_client.assert_called_once_with(
|
|
97
|
+
's3',
|
|
98
|
+
region_name=TEST_REGION,
|
|
99
|
+
aws_access_key_id=TEST_AWS_ACCESS_KEY,
|
|
100
|
+
aws_secret_access_key=TEST_AWS_SECRET_KEY,
|
|
101
|
+
)
|
|
102
|
+
assert result == mock_s3_client
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@patch('boto3.client')
|
|
106
|
+
def test_create_s3_client_with_path_style(mock_boto_client, mock_s3_client):
|
|
107
|
+
remotion_client = RemotionClient(
|
|
108
|
+
region=TEST_REGION,
|
|
109
|
+
serve_url=TEST_SERVE_URL,
|
|
110
|
+
function_name=TEST_FUNCTION_NAME,
|
|
111
|
+
force_path_style=True,
|
|
112
|
+
)
|
|
113
|
+
mock_boto_client.return_value = mock_s3_client
|
|
114
|
+
result = remotion_client._create_s3_client()
|
|
115
|
+
|
|
116
|
+
mock_boto_client.assert_called_once()
|
|
117
|
+
|
|
118
|
+
call_args = mock_boto_client.call_args
|
|
119
|
+
assert 'config' in call_args[1]
|
|
120
|
+
config = call_args[1]['config']
|
|
121
|
+
assert isinstance(config, Config)
|
|
122
|
+
assert config.s3['addressing_style'] == 'path'
|
|
123
|
+
assert result == mock_s3_client
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@patch.object(RemotionClient, '_create_s3_client')
|
|
127
|
+
def test_get_remotion_buckets_empty_response(
|
|
128
|
+
mock_create_client, mock_s3_client, remotion_client
|
|
129
|
+
):
|
|
130
|
+
mock_s3_client.list_buckets.return_value = {'Buckets': []}
|
|
131
|
+
mock_create_client.return_value = mock_s3_client
|
|
132
|
+
|
|
133
|
+
result = remotion_client._get_remotion_buckets()
|
|
134
|
+
|
|
135
|
+
assert result == []
|
|
136
|
+
mock_s3_client.list_buckets.assert_called_once()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@patch.object(RemotionClient, '_create_s3_client')
|
|
140
|
+
def test_get_remotion_buckets_no_remotion_buckets(
|
|
141
|
+
mock_create_client, mock_s3_client, remotion_client
|
|
142
|
+
):
|
|
143
|
+
mock_s3_client.list_buckets.return_value = {
|
|
144
|
+
'Buckets': [
|
|
145
|
+
{'Name': 'my-app-bucket'},
|
|
146
|
+
{'Name': 'some-other-bucket'},
|
|
147
|
+
{'Name': 'user-data-bucket'},
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
mock_create_client.return_value = mock_s3_client
|
|
151
|
+
|
|
152
|
+
result = remotion_client._get_remotion_buckets()
|
|
153
|
+
|
|
154
|
+
assert result == []
|
|
155
|
+
mock_s3_client.list_buckets.assert_called_once()
|
|
156
|
+
mock_s3_client.get_bucket_location.assert_not_called()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@patch.object(RemotionClient, '_create_s3_client')
|
|
160
|
+
def test_get_remotion_buckets_single_match_us_east_1(
|
|
161
|
+
mock_create_client, mock_s3_client, remotion_client
|
|
162
|
+
):
|
|
163
|
+
test_bucket_name = 'remotionlambda-useast1-abc123'
|
|
164
|
+
mock_s3_client.list_buckets.return_value = {
|
|
165
|
+
'Buckets': [
|
|
166
|
+
{'Name': test_bucket_name},
|
|
167
|
+
{'Name': 'other-bucket'},
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
mock_s3_client.get_bucket_location.return_value = {'LocationConstraint': None}
|
|
171
|
+
mock_create_client.return_value = mock_s3_client
|
|
172
|
+
|
|
173
|
+
result = remotion_client._get_remotion_buckets()
|
|
174
|
+
|
|
175
|
+
assert result == [test_bucket_name]
|
|
176
|
+
mock_s3_client.get_bucket_location.assert_called_once_with(Bucket=test_bucket_name)
|
{remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/tests/test_render_client_render_media.py
RENAMED
|
@@ -6,24 +6,24 @@ from remotion_lambda.remotionclient import RemotionClient
|
|
|
6
6
|
|
|
7
7
|
class TestRemotionClient(TestCase):
|
|
8
8
|
def test_remotion_construct_request(self):
|
|
9
|
-
client = RemotionClient(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
client = RemotionClient(
|
|
10
|
+
region="us-east-1", serve_url="testbed", function_name="remotion-render"
|
|
11
|
+
)
|
|
12
12
|
render_params = RenderMediaParams(
|
|
13
13
|
composition="react-svg",
|
|
14
|
-
input_props={
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
metadata={
|
|
18
|
-
"Author": "Lunar"
|
|
19
|
-
},
|
|
14
|
+
input_props={'hi': 'there'},
|
|
15
|
+
metadata={"Author": "Lunar"},
|
|
20
16
|
download_behavior=ShouldDownload(type="download", fileName="hi"),
|
|
21
17
|
webhook=Webhook(
|
|
22
|
-
url="https://example.com", secret="abc", customData=dict(hi="there")
|
|
18
|
+
url="https://example.com", secret="abc", customData=dict(hi="there")
|
|
19
|
+
),
|
|
23
20
|
)
|
|
24
21
|
|
|
25
22
|
self.assertEqual(client.region, "us-east-1")
|
|
26
23
|
self.assertIsNotNone(render_params)
|
|
27
24
|
self.assertIsNotNone(render_params.input_props)
|
|
28
|
-
print(
|
|
29
|
-
|
|
25
|
+
print(
|
|
26
|
+
client.construct_render_request(
|
|
27
|
+
render_params=render_params, render_type="video-or-audio"
|
|
28
|
+
)
|
|
29
|
+
)
|
{remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/tests/test_render_client_render_still.py
RENAMED
|
@@ -6,18 +6,19 @@ from remotion_lambda.remotionclient import RemotionClient
|
|
|
6
6
|
|
|
7
7
|
class TestRemotionClient(TestCase):
|
|
8
8
|
def test_remotion_construct_request(self):
|
|
9
|
-
client = RemotionClient(
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
client = RemotionClient(
|
|
10
|
+
region="us-east-1", serve_url="testbed", function_name="remotion-render"
|
|
11
|
+
)
|
|
12
12
|
render_still_params = RenderStillParams(
|
|
13
13
|
composition="still-helloworld",
|
|
14
|
-
input_props={
|
|
15
|
-
'message': 'Hello from props!'
|
|
16
|
-
},
|
|
14
|
+
input_props={'message': 'Hello from props!'},
|
|
17
15
|
)
|
|
18
16
|
|
|
19
17
|
self.assertEqual(client.region, "us-east-1")
|
|
20
18
|
self.assertIsNotNone(render_still_params)
|
|
21
19
|
self.assertIsNotNone(render_still_params.input_props)
|
|
22
|
-
print(
|
|
23
|
-
|
|
20
|
+
print(
|
|
21
|
+
client.construct_render_request(
|
|
22
|
+
render_params=render_still_params, render_type='still'
|
|
23
|
+
)
|
|
24
|
+
)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from unittest import TestCase
|
|
2
|
-
|
|
3
|
-
from remotion_lambda.remotionclient import RemotionClient, CustomCredentials
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class TestRemotionClient(TestCase):
|
|
7
|
-
def test_remotionprogress_construct_request(self):
|
|
8
|
-
client = RemotionClient(region="us-east-1",
|
|
9
|
-
serve_url="testbed",
|
|
10
|
-
function_name="remotion-render")
|
|
11
|
-
|
|
12
|
-
print(client.construct_render_progress_request(
|
|
13
|
-
render_id="abcdef",
|
|
14
|
-
bucket_name="remotion-render",
|
|
15
|
-
s3_output_provider=CustomCredentials(
|
|
16
|
-
endpoint="https://s3.us-east-1.amazonaws.com",
|
|
17
|
-
access_key_id="accessKeyId",
|
|
18
|
-
secret_access_key="secretAccessKey",
|
|
19
|
-
region="us-east-1"
|
|
20
|
-
)
|
|
21
|
-
)
|
|
22
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remotion_lambda-4.0.347 → remotion_lambda-4.0.351}/remotion_lambda.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|