Skip to content

Commit 06ad627

Browse files
authored
Merge pull request #5639 from webmonch/python-sdk-improvements
2 parents 0eed09b + eb89050 commit 06ad627

File tree

6 files changed

+190
-113
lines changed

6 files changed

+190
-113
lines changed

packages/lambda-python/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
# Python virtual environments
1515
test-env/
1616
remotion-env-lint/
17+
.idea
1718

packages/lambda-python/build.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ if (!hasPython()) {
1919
const commands = [
2020
"python -m venv remotion-env-lint",
2121
". ./remotion-env-lint/bin/activate",
22-
"pip install boto3 pylint",
22+
"pip install boto3 pylint mypy 'boto3-stubs[essential]'",
2323
"pylint ./remotion_lambda",
24+
"mypy ./remotion_lambda",
2425
"deactivate",
2526
"rm -rf remotion-env-lint",
2627
];
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
pytest
2-
dotenv
2+
dotenv
3+
boto3-stubs[essential]
4+
mypy
Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
# pylint: disable=missing-module-docstring
22
from .models import (
3-
RenderMediaParams, RenderMediaProgress,
4-
RenderMediaResponse, RenderProgressParams,
5-
RenderStillParams, RenderStillResponse, CostsInfo,
6-
Privacy, ValidStillImageFormats, LogLevel, OpenGlRenderer,
7-
ChromiumOptions, CustomCredentialsWithoutSensitiveData, CustomCredentials,
8-
OutNameInputObject, PlayInBrowser, ShouldDownload, DeleteAfter,
9-
Webhook
10-
11-
3+
RenderMediaParams,
4+
RenderMediaProgress,
5+
RenderMediaResponse,
6+
RenderProgressParams,
7+
RenderStillParams,
8+
RenderStillResponse,
9+
CostsInfo,
10+
Privacy,
11+
ValidStillImageFormats,
12+
LogLevel,
13+
OpenGlRenderer,
14+
ChromiumOptions,
15+
CustomCredentialsWithoutSensitiveData,
16+
CustomCredentials,
17+
OutNameInputObject,
18+
PlayInBrowser,
19+
ShouldDownload,
20+
DeleteAfter,
21+
Webhook,
1222
)
1323
from .remotionclient import RemotionClient
1424
from .version import VERSION

packages/lambda-python/remotion_lambda/models.py

Lines changed: 73 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# pylint: disable=too-few-public-methods, missing-module-docstring, broad-exception-caught,invalid-name
22

33
from enum import Enum
4-
from typing import Optional, Dict, Any, Union, Literal
4+
from typing import Optional, Dict, Any, Union, Literal, List
55
from dataclasses import dataclass, field
66
from .version import VERSION
77

@@ -10,6 +10,7 @@
1010

1111
RenderType = Union[Literal["video-or-audio"], Literal["still"]]
1212

13+
1314
class ValidStillImageFormats(str, Enum):
1415
"""
1516
Enumeration of valid image formats for still images.
@@ -20,6 +21,7 @@ class ValidStillImageFormats(str, Enum):
2021
PDF: Represents the PDF format for images.
2122
WEBP: Represents the WEBP image format.
2223
"""
24+
2325
PNG = 'png'
2426
JPEG = 'jpeg'
2527
PDF = 'pdf'
@@ -34,6 +36,7 @@ class Privacy(str, Enum):
3436
PUBLIC: Indicates a public setting.
3537
PRIVATE: Indicates a private setting.
3638
"""
39+
3740
PUBLIC = 'public'
3841
PRIVATE = 'private'
3942
NO_ACL = 'no-acl'
@@ -49,6 +52,7 @@ class LogLevel(str, Enum):
4952
WARN: Warning logging level.
5053
ERROR: Error logging level.
5154
"""
55+
5256
VERBOSE = 'verbose'
5357
INFO = 'info'
5458
WARN = 'warn'
@@ -66,6 +70,7 @@ class OpenGlRenderer(str, Enum):
6670
SWIFTSHADER: Represents the SWIFTSHADER OpenGL renderer.
6771
VULKAN: Represents the VULKAN OpenGL renderer.
6872
"""
73+
6974
SWANGLE = 'swangle'
7075
ANGLE = 'angle'
7176
EGL = 'egl'
@@ -84,9 +89,10 @@ class ChromiumOptions:
8489
gl (Optional[OpenGlRenderer]): Specifies the OpenGL renderer to use.
8590
headless (Optional[bool]): If True, runs Chromium in headless mode.
8691
user_agent (Optional[str]): Specifies a custom user agent.
87-
enable_multi_process_on_linux (Optional[bool]):
92+
enable_multi_process_on_linux (Optional[bool]):
8893
If True, enables multi-process mode on Linux.
8994
"""
95+
9096
ignore_certificate_errors: Optional[bool] = None
9197
disable_web_security: Optional[bool] = None
9298
gl: Optional[OpenGlRenderer] = None
@@ -103,18 +109,20 @@ class CustomCredentialsWithoutSensitiveData:
103109
Attributes:
104110
endpoint (str): The endpoint associated with the credentials.
105111
"""
112+
106113
endpoint: str
107114

108115

109116
@dataclass
110117
class CustomCredentials(CustomCredentialsWithoutSensitiveData):
111118
"""
112-
Represents custom credentials, extending credentials without sensitive data.
119+
Represents custom credentials, extending credentials without sensitive data.
120+
121+
Attributes:
122+
access_key_id (Optional[str]): The access key ID.
123+
secret_access_key (Optional[str]): The secret access key.
124+
"""
113125

114-
Attributes:
115-
access_key_id (Optional[str]): The access key ID.
116-
secret_access_key (Optional[str]): The secret access key.
117-
"""
118126
access_key_id: Optional[str] = None
119127
secret_access_key: Optional[str] = None
120128
region: Optional[str] = None
@@ -143,6 +151,7 @@ class OutNameInputObject:
143151
s3_output_provider (Optional[CustomCredentials]):
144152
Optional custom credentials for the S3 output provider.
145153
"""
154+
146155
bucketName: str
147156
key: str
148157
s3_output_provider: Optional[CustomCredentials] = None
@@ -158,6 +167,7 @@ class DeleteAfter(Enum):
158167
SEVEN_DAYS: Represents deletion after seven days.
159168
THIRTY_DAYS: Represents deletion after thirty days.
160169
"""
170+
161171
ONE_DAY = '1-day'
162172
THREE_DAYS = '3-days'
163173
SEVEN_DAYS = '7-days'
@@ -169,6 +179,7 @@ class RenderMediaResponse:
169179
"""
170180
Response data after rendering.
171181
"""
182+
172183
bucket_name: str
173184
render_id: str
174185

@@ -222,6 +233,7 @@ class CostsInfo:
222233
currency (str): The type of currency used for the costs, e.g., 'USD', 'EUR'.
223234
disclaimer (str): Any disclaimer or additional information related to the costs.
224235
"""
236+
225237
accrued_so_far: float
226238
display_cost: str
227239
currency: str
@@ -233,6 +245,7 @@ class PlayInBrowser:
233245
"""
234246
The video should play in the browser when the link is clicked.
235247
"""
248+
236249
type: Literal['play-in-browser']
237250
# You can define additional fields as needed
238251

@@ -242,6 +255,7 @@ class ShouldDownload:
242255
"""
243256
The video should download when the link is clicked.
244257
"""
258+
245259
type: Literal['download']
246260
fileName: str # Additional fields for this type
247261

@@ -251,6 +265,7 @@ class Webhook:
251265
"""
252266
Represents a webhook.
253267
"""
268+
254269
secret: str
255270
url: str
256271
customData: Optional[Dict] = None
@@ -261,6 +276,7 @@ class RenderMediaParams:
261276
"""
262277
Parameters for video rendering.
263278
"""
279+
264280
input_props: Optional[Dict[str, Any]] = None
265281
bucket_name: Optional[str] = None
266282
region: Optional[str] = None
@@ -290,7 +306,8 @@ class RenderMediaParams:
290306
concurrency_per_lambda: Optional[int] = 1
291307
concurrency: Optional[int] = None
292308
download_behavior: Optional[Union[PlayInBrowser, ShouldDownload]] = field(
293-
default_factory=lambda: PlayInBrowser(type='play-in-browser'))
309+
default_factory=lambda: PlayInBrowser(type='play-in-browser')
310+
)
294311
muted: bool = False
295312
overwrite: bool = False
296313
force_path_style: Optional[bool] = None
@@ -337,7 +354,9 @@ def serialize_params(self) -> Dict:
337354
'outName': self.out_name,
338355
'preferLossless': self.prefer_lossless,
339356
'timeoutInMilliseconds': self.timeout_in_milliseconds,
340-
'chromiumOptions': self.chromium_options if self.chromium_options is not None else {},
357+
'chromiumOptions': (
358+
self.chromium_options if self.chromium_options is not None else {}
359+
),
341360
'scale': self.scale,
342361
'everyNthFrame': self.every_nth_frame,
343362
'numberOfGifLoops': self.number_of_gif_loops,
@@ -360,7 +379,7 @@ def serialize_params(self) -> Dict:
360379
'deleteAfter': self.delete_after,
361380
'encodingBufferSize': self.encoding_buffer_size,
362381
'encodingMaxRate': self.encoding_max_rate,
363-
'type': 'start'
382+
'type': 'start',
364383
}
365384

366385
if self.crf is not None:
@@ -399,6 +418,7 @@ class RenderStillParams:
399418
"""
400419
Parameters for video rendering.
401420
"""
421+
402422
composition: str
403423
serve_url: str = ""
404424
input_props: Optional[Dict[str, Any]] = None
@@ -415,7 +435,9 @@ class RenderStillParams:
415435
timeout_in_milliseconds: Optional[int] = 30000
416436
chromium_options: Optional[ChromiumOptions] = None
417437
scale: Optional[float] = 1
418-
download_behavior: Dict = field(default_factory=lambda: PlayInBrowser(type='play-in-browser'))
438+
download_behavior: Union[PlayInBrowser, ShouldDownload] = field(
439+
default_factory=lambda: PlayInBrowser(type='play-in-browser')
440+
)
419441
force_width: Optional[int] = None
420442
api_key: Optional[int] = None
421443
storage_class: Optional[str] = None
@@ -430,21 +452,21 @@ class RenderStillParams:
430452

431453
def serialize_params(self) -> Dict:
432454
"""
433-
Serializes the parameters of the current object into a dictionary.
455+
Serializes the parameters of the current object into a dictionary.
434456
435-
This method consolidates both mandatory and optional attributes of the object
436-
into a single dictionary. Mandatory attributes include region, functionName,
437-
serveUrl, composition, inputProps, imageFormat, and privacy. Optional attributes
438-
are added to the dictionary only if they are not None.
457+
This method consolidates both mandatory and optional attributes of the object
458+
into a single dictionary. Mandatory attributes include region, functionName,
459+
serveUrl, composition, inputProps, imageFormat, and privacy. Optional attributes
460+
are added to the dictionary only if they are not None.
439461
440-
The optional attributes include maxRetries, envVariables, jpegQuality, frame,
441-
logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, downloadBehavior,
442-
forceWidth, forceHeight, forceBucketName, and deleteAfter.
443-
Default values are provided for 'inputProps' (empty dictionary) and 'downloadBehavior'
444-
('type': 'play-in-browser') if they are not explicitly set.
462+
The optional attributes include maxRetries, envVariables, jpegQuality, frame,
463+
logLevel, outName, timeoutInMilliseconds, chromiumOptions, scale, downloadBehavior,
464+
forceWidth, forceHeight, forceBucketName, and deleteAfter.
465+
Default values are provided for 'inputProps' (empty dictionary) and 'downloadBehavior'
466+
('type': 'play-in-browser') if they are not explicitly set.
445467
446-
Returns:
447-
Dict: A dictionary containing all the serialized parameters of the object.
468+
Returns:
469+
Dict: A dictionary containing all the serialized parameters of the object.
448470
"""
449471
parameters = {
450472
'type': 'still',
@@ -456,15 +478,20 @@ def serialize_params(self) -> Dict:
456478
'version': VERSION,
457479
'timeoutInMilliseconds': self.timeout_in_milliseconds,
458480
'maxRetries': self.max_retries,
459-
'envVariables': self.env_variables if self.env_variables is not None else {},
481+
'envVariables': (
482+
self.env_variables if self.env_variables is not None else {}
483+
),
460484
'jpegQuality': self.jpeg_quality,
461485
'storageClass': self.storage_class,
462486
'frame': self.frame,
463487
'logLevel': self.log_level,
464488
'outName': self.out_name,
465-
'chromiumOptions': self.chromium_options if self.chromium_options is not None else {},
489+
'chromiumOptions': (
490+
self.chromium_options if self.chromium_options is not None else {}
491+
),
466492
'scale': self.scale,
467-
'downloadBehavior': self.download_behavior or PlayInBrowser(type='play-in-browser'),
493+
'downloadBehavior': self.download_behavior
494+
or PlayInBrowser(type='play-in-browser'),
468495
'forceWidth': self.force_width,
469496
'apiKey': self.api_key,
470497
'forceHeight': self.force_height,
@@ -490,14 +517,15 @@ class RenderStillResponse:
490517
Represents the output information of a rendering operation performed on AWS Lambda.
491518
492519
Attributes:
493-
estimated_price (CostsInfo):
520+
estimated_price (CostsInfo):
494521
An object containing detailed cost information related to the rendering.
495522
url (str): The URL where the rendered image is stored or can be accessed.
496523
size_in_bytes (int): The size of the rendered image file in bytes.
497524
bucket_name (str): The name of the S3 bucket where the rendered image is stored.
498525
render_id (str): A unique identifier for the rendering operation.
499526
cloud_watch_logs (str): The CloudWatch logs associated with the rendering operation.
500527
"""
528+
501529
estimated_price: CostsInfo
502530
url: str
503531
size_in_bytes: int
@@ -506,26 +534,26 @@ class RenderStillResponse:
506534
outKey: str
507535

508536

537+
@dataclass
509538
class RenderMediaProgress:
510539
"""
511540
Progress of video rendering.
512541
"""
513542

514-
def __init__(self):
515-
self.overallProgress = float()
516-
self.chunks = int()
517-
self.done = bool()
518-
self.encodingStatus = None
519-
self.costs = None
520-
self.renderId = str()
521-
self.renderMetadata = None
522-
self.outputFile = None
523-
self.outKey = None
524-
self.timeToFinish = None
525-
self.errors = []
526-
self.fatalErrorEncountered = bool()
527-
self.currentTime = int()
528-
self.renderSize = int()
529-
self.outputSizeInBytes = None
530-
self.lambdasInvoked = int()
531-
self.framesRendered = None
543+
overallProgress: float = 0.0
544+
chunks: int = 0
545+
done: bool = False
546+
encodingStatus: Optional[Any] = None
547+
costs: Optional[Any] = None
548+
renderId: str = ""
549+
renderMetadata: Optional[Any] = None
550+
outputFile: Optional[Any] = None
551+
outKey: Optional[str] = None
552+
timeToFinish: Optional[float] = None
553+
errors: List[Any] = field(default_factory=list)
554+
fatalErrorEncountered: bool = False
555+
currentTime: int = 0
556+
renderSize: int = 0
557+
outputSizeInBytes: Optional[int] = None
558+
lambdasInvoked: int = 0
559+
framesRendered: Optional[int] = None

0 commit comments

Comments
 (0)