Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/together/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Together:
batches: resources.Batches
code_interpreter: CodeInterpreter
evaluation: resources.Evaluation
videos: resources.Videos

# client options
client: TogetherClient
Expand Down Expand Up @@ -94,6 +95,7 @@ def __init__(
self.code_interpreter = CodeInterpreter(self.client)
self.batches = resources.Batches(self.client)
self.evaluation = resources.Evaluation(self.client)
self.videos = resources.Videos(self.client)


class AsyncTogether:
Expand All @@ -109,6 +111,7 @@ class AsyncTogether:
code_interpreter: CodeInterpreter
batches: resources.AsyncBatches
evaluation: resources.AsyncEvaluation
videos: resources.AsyncVideos
# client options
client: TogetherClient

Expand Down Expand Up @@ -175,6 +178,7 @@ def __init__(
self.code_interpreter = CodeInterpreter(self.client)
self.batches = resources.AsyncBatches(self.client)
self.evaluation = resources.AsyncEvaluation(self.client)
self.videos = resources.AsyncVideos(self.client)


Client = Together
Expand Down
3 changes: 3 additions & 0 deletions src/together/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from together.resources.rerank import AsyncRerank, Rerank
from together.resources.batch import Batches, AsyncBatches
from together.resources.evaluation import Evaluation, AsyncEvaluation
from together.resources.videos import AsyncVideos, Videos


__all__ = [
Expand Down Expand Up @@ -37,4 +38,6 @@
"AsyncBatches",
"Evaluation",
"AsyncEvaluation",
"AsyncVideos",
"Videos",
]
303 changes: 303 additions & 0 deletions src/together/resources/videos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
from __future__ import annotations

from typing import Any, Dict, List
import sys

from together.abstract import api_requestor
from together.together_response import TogetherResponse
from together.types import (
TogetherClient,
TogetherRequest,
)
from together.types.videos import (
CreateVideoResponse,
CreateVideoBody,
VideoJob,
)

if sys.version_info >= (3, 8):
from typing import Literal
else:
from typing_extensions import Literal


class Videos:
def __init__(self, client: TogetherClient) -> None:
self._client = client

def create(
self,
*,
model: str,
prompt: str | None = None,
height: int | None = None,
width: int | None = None,
seconds: str | None = None,
fps: int | None = None,
steps: int | None = None,
seed: int | None = None,
guidance_scale: float | None = None,
output_format: Literal["MP4", "WEBM"] | None = None,
output_quality: int | None = None,
negative_prompt: str | None = None,
frame_images: List[Dict[str, Any]] | None = None,
reference_images: List[str] | None = None,
**kwargs: Any,
) -> CreateVideoResponse:
"""
Method to generate videos based on a given prompt using a specified model.

Args:
model (str): The model to use for video generation.

prompt (str): A description of the desired video. Positive prompt for the generation.

height (int, optional): Height of the video to generate in pixels.

width (int, optional): Width of the video to generate in pixels.

seconds (str, optional): Length of generated video in seconds. Min 1 max 10.

fps (int, optional): Frames per second, min 15 max 60. Defaults to 24.

steps (int, optional): The number of denoising steps the model performs during video
generation. More steps typically result in higher quality output but require longer
processing time. Min 10 max 50. Defaults to 20.

seed (int, optional): Seed to use in initializing the video generation. Using the same
seed allows deterministic video generation. If not provided, a random seed is
generated for each request. Note: When requesting multiple videos with the same
seed, the seed will be incremented by 1 (+1) for each video generated.

guidance_scale (float, optional): Controls how closely the video generation follows your
prompt. Higher values make the model adhere more strictly to your text description,
while lower values allow more creative freedom. Recommended range is 6.0-10.0 for
most video models. Values above 12 may cause over-guidance artifacts or unnatural
motion patterns. Defaults to 8.

output_format (str, optional): Specifies the format of the output video. Either "MP4"
or "WEBM". Defaults to "MP4".

output_quality (int, optional): Compression quality. Defaults to 20.

negative_prompt (str, optional): Similar to prompt, but specifies what to avoid instead
of what to include. Defaults to None.

frame_images (List[Dict[str, Any]], optional): Array of images to guide video generation,
like keyframes. If size 1, starting frame; if size 2, starting and ending frame;
if more than 2 then frame must be specified. Defaults to None.

reference_images (List[str], optional): An array containing reference images
used to condition the generation process. These images provide visual guidance to
help the model generate content that aligns with the style, composition, or
characteristics of the reference materials. Defaults to None.

Returns:
CreateVideoResponse: Object containing video generation job id
"""

requestor = api_requestor.APIRequestor(
client=self._client,
)

parameter_payload = CreateVideoBody(
prompt=prompt,
model=model,
height=height,
width=width,
seconds=seconds,
fps=fps,
steps=steps,
seed=seed,
guidance_scale=guidance_scale,
output_format=output_format,
output_quality=output_quality,
negative_prompt=negative_prompt,
frame_images=frame_images,
reference_images=reference_images,
**kwargs,
).model_dump(exclude_none=True)

response, _, _ = requestor.request(
options=TogetherRequest(
method="POST",
url="../v2/videos",
params=parameter_payload,
),
stream=False,
)

assert isinstance(response, TogetherResponse)

return CreateVideoResponse(**response.data)

def retrieve(
self,
id: str,
) -> VideoJob:
"""
Method to retrieve a video creation job.

Args:
id (str): The ID of the video creation job to retrieve.

Returns:
VideoJob: Object containing the current status and details of the video creation job
"""

requestor = api_requestor.APIRequestor(
client=self._client,
)

response, _, _ = requestor.request(
options=TogetherRequest(
method="GET",
url=f"../v2/videos/{id}",
),
stream=False,
)

assert isinstance(response, TogetherResponse)

return VideoJob(**response.data)


class AsyncVideos:
def __init__(self, client: TogetherClient) -> None:
self._client = client

async def create(
self,
*,
prompt: str,
model: str,
height: int | None = None,
width: int | None = None,
seconds: float | None = None,
fps: int | None = None,
steps: int | None = None,
seed: int | None = None,
guidance_scale: float | None = None,
output_format: Literal["MP4", "WEBM"] | None = None,
output_quality: int | None = None,
negative_prompt: str | None = None,
frame_images: List[Dict[str, Any]] | None = None,
reference_images: List[str] | None = None,
**kwargs: Any,
) -> CreateVideoResponse:
"""
Async method to create videos based on a given prompt using a specified model.

Args:
prompt (str): A description of the desired video. Positive prompt for the generation.

model (str): The model to use for video generation.

height (int, optional): Height of the video to generate in pixels.

width (int, optional): Width of the video to generate in pixels.

seconds (float, optional): Length of generated video in seconds. Min 1 max 10.

fps (int, optional): Frames per second, min 15 max 60. Defaults to 24.

steps (int, optional): The number of denoising steps the model performs during video
generation. More steps typically result in higher quality output but require longer
processing time. Min 10 max 50. Defaults to 20.

seed (int, optional): Seed to use in initializing the video generation. Using the same
seed allows deterministic video generation. If not provided, a random seed is
generated for each request. Note: When requesting multiple videos with the same
seed, the seed will be incremented by 1 (+1) for each video generated.

guidance_scale (float, optional): Controls how closely the video generation follows your
prompt. Higher values make the model adhere more strictly to your text description,
while lower values allow more creative freedom. Recommended range is 6.0-10.0 for
most video models. Values above 12 may cause over-guidance artifacts or unnatural
motion patterns. Defaults to 8.

output_format (Literal["MP4", "WEBM"], optional): Specifies the format of the output video. Either "MP4"
or "WEBM". Defaults to "MP4".

output_quality (int, optional): Compression quality. Defaults to 20.

negative_prompt (str, optional): Similar to prompt, but specifies what to avoid instead
of what to include. Defaults to None.

frame_images (List[Dict[str, Any]], optional): Array of images to guide video generation,
like keyframes. If size 1, starting frame; if size 2, starting and ending frame;
if more than 2 then frame must be specified. Defaults to None.

reference_images (List[str], optional): An array containing reference images
used to condition the generation process. These images provide visual guidance to
help the model generate content that aligns with the style, composition, or
characteristics of the reference materials. Defaults to None.

Returns:
CreateVideoResponse: Object containing video creation job id
"""

requestor = api_requestor.APIRequestor(
client=self._client,
)

parameter_payload = CreateVideoBody(
prompt=prompt,
model=model,
height=height,
width=width,
seconds=seconds,
fps=fps,
steps=steps,
seed=seed,
guidance_scale=guidance_scale,
output_format=output_format,
output_quality=output_quality,
negative_prompt=negative_prompt,
frame_images=frame_images,
reference_images=reference_images,
**kwargs,
).model_dump(exclude_none=True)

response, _, _ = await requestor.arequest(
options=TogetherRequest(
method="POST",
url="../v2/videos",
params=parameter_payload,
),
stream=False,
)

assert isinstance(response, TogetherResponse)

return CreateVideoResponse(**response.data)

async def retrieve(
self,
id: str,
) -> VideoJob:
"""
Async method to retrieve a video creation job.

Args:
id (str): The ID of the video creation job to retrieve.

Returns:
VideoJob: Object containing the current status and details of the video creation job
"""

requestor = api_requestor.APIRequestor(
client=self._client,
)

response, _, _ = await requestor.arequest(
options=TogetherRequest(
method="GET",
url=f"../v2/videos/{id}",
),
stream=False,
)

assert isinstance(response, TogetherResponse)

return VideoJob(**response.data)
8 changes: 8 additions & 0 deletions src/together/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
EvaluationJob,
EvaluationStatusResponse,
)
from together.types.videos import (
CreateVideoBody,
CreateVideoResponse,
VideoJob,
)


__all__ = [
Expand Down Expand Up @@ -152,4 +157,7 @@
"EvaluationCreateResponse",
"EvaluationJob",
"EvaluationStatusResponse",
"CreateVideoBody",
"CreateVideoResponse",
"VideoJob",
]
Loading