VibesAI-api 1.3.2__py3-none-any.whl
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.
- server/__init__.py +3 -0
- server/app.py +332 -0
- vibes_api/__init__.py +121 -0
- vibes_api/cli.py +852 -0
- vibes_api/client.py +3972 -0
- vibes_api/composition.py +852 -0
- vibes_api/ingredients.py +206 -0
- vibes_api/models.py +165 -0
- vibesai_api-1.3.2.dist-info/METADATA +600 -0
- vibesai_api-1.3.2.dist-info/RECORD +14 -0
- vibesai_api-1.3.2.dist-info/WHEEL +5 -0
- vibesai_api-1.3.2.dist-info/entry_points.txt +2 -0
- vibesai_api-1.3.2.dist-info/licenses/LICENSE +28 -0
- vibesai_api-1.3.2.dist-info/top_level.txt +2 -0
vibes_api/ingredients.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ingredient helpers — build the payload objects that the Vibes generation
|
|
3
|
+
endpoints expect for applying (or inline-creating) characters, styles,
|
|
4
|
+
and scenes.
|
|
5
|
+
|
|
6
|
+
There are three ingredient types in Vibes:
|
|
7
|
+
|
|
8
|
+
- CHARACTER (UI label: "Character") → attaches via ``orefImageHandle``
|
|
9
|
+
- STYLE (UI label: "Style") → attaches via ``srefImageHandle``
|
|
10
|
+
- SETTING (UI label: "Scene") → attaches via ``settingImageHandles``
|
|
11
|
+
|
|
12
|
+
For each, there are three ways to reference the ingredient in a generation:
|
|
13
|
+
|
|
14
|
+
1. By existing ingredient ID (use ``IngredientRef.by_id()``).
|
|
15
|
+
→ goes in the ``ingredients`` array on the request body.
|
|
16
|
+
|
|
17
|
+
2. By image entity ID of an uploaded image (use ``CreateIngredient.by_image_ent_id()``).
|
|
18
|
+
→ goes in the ``createIngredients`` array. The server creates a new
|
|
19
|
+
ingredient record on the fly and attaches it.
|
|
20
|
+
|
|
21
|
+
3. By name only (use ``CreateIngredient.by_name()``).
|
|
22
|
+
→ also goes in ``createIngredients``. The server uses the prompt-
|
|
23
|
+
generated image as the ingredient image.
|
|
24
|
+
|
|
25
|
+
These helpers build the correct dict shape so you don't have to remember
|
|
26
|
+
the snake_case / camelCase quirks of the API.
|
|
27
|
+
|
|
28
|
+
Example
|
|
29
|
+
-------
|
|
30
|
+
from vibes_api import VibesClient, IngredientType
|
|
31
|
+
from vibes_api.ingredients import IngredientRef, CreateIngredient
|
|
32
|
+
|
|
33
|
+
client = VibesClient(meta_session="...")
|
|
34
|
+
|
|
35
|
+
# Use an existing character from your library
|
|
36
|
+
character = IngredientRef.by_id(
|
|
37
|
+
ingredient_id="800957099700717",
|
|
38
|
+
ingredient_type=IngredientType.CHARACTER,
|
|
39
|
+
name="Valdrin",
|
|
40
|
+
image_url="https://...",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Create a new style on-the-fly from an uploaded image
|
|
44
|
+
style = CreateIngredient.by_image_ent_id(
|
|
45
|
+
image_ent_id="1177...",
|
|
46
|
+
ingredient_type=IngredientType.STYLE,
|
|
47
|
+
name="Cyberpunk neon",
|
|
48
|
+
image_url="https://...",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
batch = client.generate_video(
|
|
52
|
+
project_id=project["id"],
|
|
53
|
+
prompt="...",
|
|
54
|
+
ingredients=[character],
|
|
55
|
+
create_ingredients=[style],
|
|
56
|
+
)
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
from __future__ import annotations
|
|
60
|
+
|
|
61
|
+
from typing import Optional, Union
|
|
62
|
+
|
|
63
|
+
from .models import IngredientType
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _coerce_type(t: Union[str, IngredientType]) -> str:
|
|
67
|
+
"""Coerce IngredientType enum to its string value."""
|
|
68
|
+
if hasattr(t, "value"):
|
|
69
|
+
return t.value
|
|
70
|
+
return str(t)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class IngredientRef:
|
|
74
|
+
"""Builder for an EXISTING ingredient reference (by ingredientId).
|
|
75
|
+
|
|
76
|
+
Use this when you've already saved an ingredient in your library
|
|
77
|
+
(via the Vibes UI or via ``client.create_ingredient()``).
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def by_id(
|
|
82
|
+
*,
|
|
83
|
+
ingredient_id: str,
|
|
84
|
+
ingredient_type: Union[str, IngredientType],
|
|
85
|
+
name: str,
|
|
86
|
+
image_url: str,
|
|
87
|
+
) -> dict:
|
|
88
|
+
"""Reference an existing ingredient by its ID.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
ingredient_id : str
|
|
93
|
+
The ``ingredientId`` from ``client.list_ingredients()``.
|
|
94
|
+
ingredient_type : str | IngredientType
|
|
95
|
+
One of CHARACTER, STYLE, SETTING.
|
|
96
|
+
name : str
|
|
97
|
+
Display name (matches the ingredient's name in the library).
|
|
98
|
+
image_url : str
|
|
99
|
+
URL of the ingredient's image. Used as a thumbnail.
|
|
100
|
+
"""
|
|
101
|
+
return {
|
|
102
|
+
"ingredientId": ingredient_id,
|
|
103
|
+
"ingredientType": _coerce_type(ingredient_type),
|
|
104
|
+
"name": name,
|
|
105
|
+
"imageUrl": image_url,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class CreateIngredient:
|
|
110
|
+
"""Builder for an INLINE ingredient creation (no pre-existing ingredient).
|
|
111
|
+
|
|
112
|
+
Use this when you want the server to create a new ingredient on-the-fly
|
|
113
|
+
during generation. There are two flavors:
|
|
114
|
+
|
|
115
|
+
- ``by_image_ent_id()`` — create from an already-uploaded image
|
|
116
|
+
(you've called ``client.upload_image()`` first).
|
|
117
|
+
- ``by_name()`` — create by name only; the server uses the prompt-
|
|
118
|
+
generated image as the ingredient image.
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def by_image_ent_id(
|
|
123
|
+
*,
|
|
124
|
+
image_ent_id: str,
|
|
125
|
+
ingredient_type: Union[str, IngredientType],
|
|
126
|
+
name: str,
|
|
127
|
+
image_url: str,
|
|
128
|
+
) -> dict:
|
|
129
|
+
"""Create a new ingredient from an uploaded image.
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
image_ent_id : str
|
|
134
|
+
The ``imageEntId`` from ``client.upload_image()`` or
|
|
135
|
+
``client.upload_image_file()``.
|
|
136
|
+
ingredient_type : str | IngredientType
|
|
137
|
+
CHARACTER, STYLE, or SETTING.
|
|
138
|
+
name : str
|
|
139
|
+
Display name for the new ingredient.
|
|
140
|
+
image_url : str
|
|
141
|
+
URL of the uploaded image (returned alongside imageEntId).
|
|
142
|
+
"""
|
|
143
|
+
return {
|
|
144
|
+
"sourceImageEntId": image_ent_id,
|
|
145
|
+
"ingredientType": _coerce_type(ingredient_type),
|
|
146
|
+
"name": name,
|
|
147
|
+
"imageUrl": image_url,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@staticmethod
|
|
151
|
+
def by_name(
|
|
152
|
+
*,
|
|
153
|
+
ingredient_type: Union[str, IngredientType],
|
|
154
|
+
name: str,
|
|
155
|
+
) -> dict:
|
|
156
|
+
"""Create a new ingredient by name only.
|
|
157
|
+
|
|
158
|
+
The server will use the image generated by the prompt as the
|
|
159
|
+
ingredient image. This is the simplest form — useful for the
|
|
160
|
+
timeline chat assistant.
|
|
161
|
+
"""
|
|
162
|
+
return {
|
|
163
|
+
"ingredientType": _coerce_type(ingredient_type),
|
|
164
|
+
"name": name,
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def build_ingredient_payload(
|
|
169
|
+
*,
|
|
170
|
+
ingredients: Optional[list] = None,
|
|
171
|
+
create_ingredients: Optional[list] = None,
|
|
172
|
+
character: Optional[dict] = None,
|
|
173
|
+
style: Optional[dict] = None,
|
|
174
|
+
scene: Optional[dict] = None,
|
|
175
|
+
) -> dict:
|
|
176
|
+
"""Convenience builder: combine character/style/scene refs into a payload.
|
|
177
|
+
|
|
178
|
+
Pass either ``ingredients=[...]`` and ``create_ingredients=[...]``
|
|
179
|
+
(already-built payload dicts), or the convenience parameters
|
|
180
|
+
``character=...``, ``style=...``, ``scene=...`` (each can be either
|
|
181
|
+
an ``IngredientRef`` or ``CreateIngredient`` dict — this function
|
|
182
|
+
will route it to the correct array based on its keys).
|
|
183
|
+
|
|
184
|
+
Returns
|
|
185
|
+
-------
|
|
186
|
+
dict
|
|
187
|
+
``{"ingredients": [...], "createIngredients": [...]}`` —
|
|
188
|
+
ready to spread into a generation request body.
|
|
189
|
+
"""
|
|
190
|
+
final_ingredients = list(ingredients or [])
|
|
191
|
+
final_create = list(create_ingredients or [])
|
|
192
|
+
|
|
193
|
+
for ing in (character, style, scene):
|
|
194
|
+
if ing is None:
|
|
195
|
+
continue
|
|
196
|
+
if "ingredientId" in ing:
|
|
197
|
+
final_ingredients.append(ing)
|
|
198
|
+
else:
|
|
199
|
+
final_create.append(ing)
|
|
200
|
+
|
|
201
|
+
payload: dict = {}
|
|
202
|
+
if final_ingredients:
|
|
203
|
+
payload["ingredients"] = final_ingredients
|
|
204
|
+
if final_create:
|
|
205
|
+
payload["createIngredients"] = final_create
|
|
206
|
+
return payload
|
vibes_api/models.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enums and constants for the Vibes API client.
|
|
3
|
+
|
|
4
|
+
All values are taken directly from the vibes.ai Next.js bundles.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from enum import Enum
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AspectRatio(str, Enum):
|
|
11
|
+
"""Supported aspect ratios for image / video generation.
|
|
12
|
+
|
|
13
|
+
Only three ratios are actually supported by the server (verified live):
|
|
14
|
+
1:1, 9:16, and 16:9. Other values will be rejected with
|
|
15
|
+
``GENERATION_FAILED``.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
SQUARE = "1:1" # 1280x1280 for images
|
|
19
|
+
PORTRAIT = "9:16" # 720x1280 (default in UI)
|
|
20
|
+
LANDSCAPE = "16:9" # 1280x720
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Resolution(str, Enum):
|
|
24
|
+
"""Supported output resolutions (shown under "Advanced" in the UI)."""
|
|
25
|
+
|
|
26
|
+
P480 = "480p"
|
|
27
|
+
P720 = "720p"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class VideoModel(str, Enum):
|
|
31
|
+
"""Available video generation models.
|
|
32
|
+
|
|
33
|
+
Selecting the right model is important — different generation types
|
|
34
|
+
require different models:
|
|
35
|
+
|
|
36
|
+
- ``midjen-short`` → text-to-video (t2v) and image-to-video (i2v)
|
|
37
|
+
- ``midjen-extend`` → video extension (auto/manual extend)
|
|
38
|
+
- ``midjen-video-edit`` → video-to-video editing (v2v)
|
|
39
|
+
- ``lipsync`` family → lip-sync generation
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
SHORT = "midjen-short"
|
|
43
|
+
EXTEND = "midjen-extend"
|
|
44
|
+
VIDEO_EDIT = "midjen-video-edit"
|
|
45
|
+
LIPSYNC = "lipsync"
|
|
46
|
+
LIPSYNC_ASYNC = "midjen-lipsync-async"
|
|
47
|
+
LIPSYNC_EXP = "midjen-lipsync-exp"
|
|
48
|
+
LIPSYNC_DIRECT = "midjen-lipsync-direct"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ImageModel(str, Enum):
|
|
52
|
+
"""Available image generation models."""
|
|
53
|
+
|
|
54
|
+
BASE = "midjen-base"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class PromptModel(str, Enum):
|
|
58
|
+
"""LLM used for prompt enhancement / parsing."""
|
|
59
|
+
|
|
60
|
+
GEMINI_FLASH = "gemini-2.5-flash"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GenerationType(str, Enum):
|
|
64
|
+
"""Generation type discriminator (sent in the ``config.generationType`` field).
|
|
65
|
+
|
|
66
|
+
The server uses this to route the request to the correct pipeline:
|
|
67
|
+
|
|
68
|
+
- ``t2v`` → text-to-video
|
|
69
|
+
- ``t2i`` → text-to-image
|
|
70
|
+
- ``i2v`` → image-to-video (start frame uploaded or selected)
|
|
71
|
+
- ``extend`` → extend an existing video clip (auto or manual)
|
|
72
|
+
- ``v2v`` → video-to-video editing
|
|
73
|
+
- ``lipsync`` → lip-sync generation
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
TEXT_TO_VIDEO = "t2v"
|
|
77
|
+
TEXT_TO_IMAGE = "t2i"
|
|
78
|
+
IMAGE_TO_VIDEO = "i2v"
|
|
79
|
+
EXTEND = "extend"
|
|
80
|
+
VIDEO_TO_VIDEO = "v2v"
|
|
81
|
+
LIPSYNC = "lipsync"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class IngredientType(str, Enum):
|
|
85
|
+
"""Type of studio ingredient.
|
|
86
|
+
|
|
87
|
+
The three types map to UI sections in the Ingredients panel:
|
|
88
|
+
Characters, Styles, Scenes (internally "SETTING").
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
CHARACTER = "CHARACTER"
|
|
92
|
+
STYLE = "STYLE"
|
|
93
|
+
SETTING = "SETTING" # "Scene" in the UI
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class OwnerFilter(str, Enum):
|
|
97
|
+
"""Filter for /api/studio/ingredients."""
|
|
98
|
+
|
|
99
|
+
LIBRARY = "LIBRARY" # User's saved ingredients
|
|
100
|
+
VIEWER = "VIEWER" # Ingredients visible to current viewer
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class VoicePreset(str, Enum):
|
|
104
|
+
"""Built-in TTS voices.
|
|
105
|
+
|
|
106
|
+
41 voices are available — these are the most common. Use
|
|
107
|
+
``client.list_voices()`` to get the full up-to-date list.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
MARISOL = "play_ai_Marisol"
|
|
111
|
+
GEORGE_WASHINGTON = "play_ai_1P_George_Washington"
|
|
112
|
+
ABRAHAM_LINCOLN = "play_ai_1P_Abraham_Lincoln"
|
|
113
|
+
JANE_AUSTEN = "play_ai_1P_Jane_Austen"
|
|
114
|
+
SERAPHINE = "play_ai_1P_Seraphine"
|
|
115
|
+
CELESTE = "play_ai_Celeste"
|
|
116
|
+
NIGEL = "play_ai_Nigel"
|
|
117
|
+
CONOR = "play_ai_Conor"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class TextOverlayPreset(str, Enum):
|
|
121
|
+
"""Effect presets for text overlays on the timeline."""
|
|
122
|
+
|
|
123
|
+
FADE = "fade"
|
|
124
|
+
SLIDE_UP = "slide-up"
|
|
125
|
+
SURROUND = "surround"
|
|
126
|
+
STRANGE = "strange"
|
|
127
|
+
FLASH = "flash"
|
|
128
|
+
SLIDE = "slide"
|
|
129
|
+
CINEFADE = "cinefade"
|
|
130
|
+
GLOW = "glow"
|
|
131
|
+
TYPEWRITER = "typewriter"
|
|
132
|
+
HIGHLIGHT = "highlight"
|
|
133
|
+
GLITCH = "glitch"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TextOverlayPosition(str, Enum):
|
|
137
|
+
"""Position presets for text overlays on the timeline."""
|
|
138
|
+
|
|
139
|
+
CENTER = "center"
|
|
140
|
+
TOP = "top"
|
|
141
|
+
BOTTOM = "bottom"
|
|
142
|
+
LEFT = "left"
|
|
143
|
+
RIGHT = "right"
|
|
144
|
+
TOP_LEFT = "top-left"
|
|
145
|
+
TOP_RIGHT = "top-right"
|
|
146
|
+
BOTTOM_LEFT = "bottom-left"
|
|
147
|
+
BOTTOM_RIGHT = "bottom-right"
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class SyncMode(str, Enum):
|
|
151
|
+
"""Modes used by the /api/sync endpoint (server-sent events).
|
|
152
|
+
|
|
153
|
+
The UI uses these to coordinate real-time collaboration. ``polling``
|
|
154
|
+
falls back to GET requests; ``sse`` opens an EventSource stream.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
POLLING = "polling"
|
|
158
|
+
SSE = "sse"
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class EntityType(str, Enum):
|
|
162
|
+
"""Entity types accepted by /api/share-links, /api/sync, /api/collaborators."""
|
|
163
|
+
|
|
164
|
+
PROJECT = "project"
|
|
165
|
+
CONTENT_ITEM = "content-item"
|