universal-mcp-applications 0.1.33__py3-none-any.whl → 0.1.39rc16__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.
Potentially problematic release.
This version of universal-mcp-applications might be problematic. Click here for more details.
- universal_mcp/applications/BEST_PRACTICES.md +1 -1
- universal_mcp/applications/ahrefs/app.py +92 -238
- universal_mcp/applications/airtable/app.py +36 -135
- universal_mcp/applications/apollo/app.py +124 -477
- universal_mcp/applications/asana/app.py +605 -1755
- universal_mcp/applications/aws_s3/app.py +63 -119
- universal_mcp/applications/bill/app.py +644 -2055
- universal_mcp/applications/box/app.py +1246 -4159
- universal_mcp/applications/braze/app.py +410 -1476
- universal_mcp/applications/browser_use/README.md +15 -1
- universal_mcp/applications/browser_use/__init__.py +1 -0
- universal_mcp/applications/browser_use/app.py +91 -26
- universal_mcp/applications/cal_com_v2/app.py +207 -625
- universal_mcp/applications/calendly/app.py +103 -242
- universal_mcp/applications/canva/app.py +75 -140
- universal_mcp/applications/clickup/app.py +331 -798
- universal_mcp/applications/coda/app.py +240 -520
- universal_mcp/applications/confluence/app.py +497 -1285
- universal_mcp/applications/contentful/app.py +40 -155
- universal_mcp/applications/crustdata/app.py +44 -123
- universal_mcp/applications/dialpad/app.py +451 -924
- universal_mcp/applications/digitalocean/app.py +2071 -6082
- universal_mcp/applications/domain_checker/app.py +3 -54
- universal_mcp/applications/e2b/app.py +17 -68
- universal_mcp/applications/elevenlabs/README.md +27 -3
- universal_mcp/applications/elevenlabs/app.py +741 -74
- universal_mcp/applications/exa/README.md +8 -4
- universal_mcp/applications/exa/app.py +415 -186
- universal_mcp/applications/falai/README.md +5 -7
- universal_mcp/applications/falai/app.py +156 -232
- universal_mcp/applications/figma/app.py +91 -175
- universal_mcp/applications/file_system/app.py +2 -13
- universal_mcp/applications/firecrawl/app.py +198 -176
- universal_mcp/applications/fireflies/app.py +59 -281
- universal_mcp/applications/fpl/app.py +92 -529
- universal_mcp/applications/fpl/utils/fixtures.py +15 -49
- universal_mcp/applications/fpl/utils/helper.py +25 -89
- universal_mcp/applications/fpl/utils/league_utils.py +20 -64
- universal_mcp/applications/ghost_content/app.py +70 -179
- universal_mcp/applications/github/app.py +30 -67
- universal_mcp/applications/gong/app.py +142 -302
- universal_mcp/applications/google_calendar/app.py +26 -78
- universal_mcp/applications/google_docs/README.md +15 -14
- universal_mcp/applications/google_docs/app.py +103 -206
- universal_mcp/applications/google_drive/app.py +194 -793
- universal_mcp/applications/google_gemini/app.py +68 -59
- universal_mcp/applications/google_mail/README.md +1 -0
- universal_mcp/applications/google_mail/app.py +93 -214
- universal_mcp/applications/google_searchconsole/app.py +25 -58
- universal_mcp/applications/google_sheet/README.md +2 -1
- universal_mcp/applications/google_sheet/app.py +226 -624
- universal_mcp/applications/google_sheet/helper.py +26 -53
- universal_mcp/applications/hashnode/app.py +57 -269
- universal_mcp/applications/heygen/README.md +10 -32
- universal_mcp/applications/heygen/app.py +339 -811
- universal_mcp/applications/http_tools/app.py +10 -32
- universal_mcp/applications/hubspot/README.md +1 -1
- universal_mcp/applications/hubspot/app.py +7508 -99
- universal_mcp/applications/jira/app.py +2419 -8334
- universal_mcp/applications/klaviyo/app.py +739 -1621
- universal_mcp/applications/linkedin/README.md +18 -1
- universal_mcp/applications/linkedin/app.py +729 -251
- universal_mcp/applications/mailchimp/app.py +696 -1851
- universal_mcp/applications/markitdown/app.py +8 -20
- universal_mcp/applications/miro/app.py +333 -815
- universal_mcp/applications/ms_teams/app.py +420 -1407
- universal_mcp/applications/neon/app.py +144 -250
- universal_mcp/applications/notion/app.py +38 -53
- universal_mcp/applications/onedrive/app.py +26 -48
- universal_mcp/applications/openai/app.py +43 -166
- universal_mcp/applications/outlook/README.md +22 -9
- universal_mcp/applications/outlook/app.py +403 -141
- universal_mcp/applications/perplexity/README.md +2 -1
- universal_mcp/applications/perplexity/app.py +161 -20
- universal_mcp/applications/pipedrive/app.py +1021 -3331
- universal_mcp/applications/posthog/app.py +272 -541
- universal_mcp/applications/reddit/app.py +65 -164
- universal_mcp/applications/resend/app.py +72 -139
- universal_mcp/applications/retell/app.py +23 -50
- universal_mcp/applications/rocketlane/app.py +252 -965
- universal_mcp/applications/scraper/app.py +114 -142
- universal_mcp/applications/semanticscholar/app.py +36 -78
- universal_mcp/applications/semrush/app.py +44 -78
- universal_mcp/applications/sendgrid/app.py +826 -1576
- universal_mcp/applications/sentry/app.py +444 -1079
- universal_mcp/applications/serpapi/app.py +44 -146
- universal_mcp/applications/sharepoint/app.py +27 -49
- universal_mcp/applications/shopify/app.py +1748 -4486
- universal_mcp/applications/shortcut/app.py +275 -536
- universal_mcp/applications/slack/app.py +43 -125
- universal_mcp/applications/spotify/app.py +206 -405
- universal_mcp/applications/supabase/app.py +174 -283
- universal_mcp/applications/tavily/app.py +2 -2
- universal_mcp/applications/trello/app.py +853 -2816
- universal_mcp/applications/twilio/app.py +27 -62
- universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
- universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
- universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
- universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
- universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
- universal_mcp/applications/whatsapp/app.py +35 -186
- universal_mcp/applications/whatsapp/audio.py +2 -6
- universal_mcp/applications/whatsapp/whatsapp.py +17 -51
- universal_mcp/applications/whatsapp_business/app.py +86 -299
- universal_mcp/applications/wrike/app.py +80 -153
- universal_mcp/applications/yahoo_finance/app.py +19 -65
- universal_mcp/applications/youtube/app.py +120 -306
- universal_mcp/applications/zenquotes/app.py +3 -3
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/METADATA +4 -2
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/RECORD +115 -119
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/WHEEL +1 -1
- universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
- universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -54
- universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -7337
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -1467
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/licenses/LICENSE +0 -0
|
@@ -9,10 +9,8 @@ This is automatically generated from OpenAPI schema for the FalaiApp API.
|
|
|
9
9
|
|
|
10
10
|
| Tool | Description |
|
|
11
11
|
|------|-------------|
|
|
12
|
-
| `
|
|
13
|
-
| `
|
|
14
|
-
| `
|
|
15
|
-
| `
|
|
16
|
-
| `
|
|
17
|
-
| `upload_file` | Asynchronously uploads a local file to the Fal Content Delivery Network (CDN), returning a public URL. This URL makes the file accessible for use as input in other Fal AI job execution methods like `run` or `submit`. A `ToolError` is raised if the upload fails. |
|
|
18
|
-
| `run_image_generation` | A specialized wrapper for the `run` method that synchronously generates images using the 'fal-ai/flux/dev' model. It simplifies image creation with common parameters like `prompt` and `seed`, waits for the task to complete, and directly returns the result containing image URLs and metadata. |
|
|
12
|
+
| `generate_image` | Generates an image from a text prompt using specified Fal AI models. |
|
|
13
|
+
| `submit_video_generation` | Submits a video generation task using Fal AI models and returns a request ID. |
|
|
14
|
+
| `get_generation_status` | Checks the status of a video generation task. |
|
|
15
|
+
| `get_generation_result` | Retrieves the result of a completed video generation task. |
|
|
16
|
+
| `transcribe_audio` | Converts speech to text from an audio file URL using Fal AI models. |
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
1
|
from typing import Any, Literal
|
|
3
|
-
|
|
4
2
|
from fal_client import AsyncClient, AsyncRequestHandle, Status
|
|
5
3
|
from loguru import logger
|
|
6
4
|
from universal_mcp.applications.application import APIApplication
|
|
7
5
|
from universal_mcp.exceptions import NotAuthorizedError, ToolError
|
|
8
6
|
from universal_mcp.integrations import Integration
|
|
9
7
|
|
|
10
|
-
Priority = Literal["normal", "low"]
|
|
11
|
-
|
|
12
|
-
|
|
13
8
|
class FalaiApp(APIApplication):
|
|
14
9
|
"""
|
|
15
10
|
Application for interacting with the Fal AI platform.
|
|
@@ -25,310 +20,239 @@ class FalaiApp(APIApplication):
|
|
|
25
20
|
super().__init__(name="falai", integration=integration, **kwargs)
|
|
26
21
|
self._fal_client = None
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
def fal_client(self) -> AsyncClient:
|
|
23
|
+
async def get_fal_client(self) -> AsyncClient:
|
|
30
24
|
"""
|
|
31
25
|
A cached property that lazily initializes an `AsyncClient` instance. It retrieves the API key from the configured integration, providing a single, centralized authentication point for all methods that interact with the Fal AI API. Raises `NotAuthorizedError` if credentials are not found.
|
|
32
26
|
"""
|
|
33
27
|
if self._fal_client is None:
|
|
34
|
-
credentials = self.integration.
|
|
28
|
+
credentials = await self.integration.get_credentials_async()
|
|
35
29
|
logger.info(f"Credentials: {credentials}")
|
|
36
|
-
api_key = (
|
|
37
|
-
credentials.get("api_key")
|
|
38
|
-
or credentials.get("API_KEY")
|
|
39
|
-
or credentials.get("apiKey")
|
|
40
|
-
)
|
|
30
|
+
api_key = credentials.get("api_key") or credentials.get("API_KEY") or credentials.get("apiKey")
|
|
41
31
|
if not api_key:
|
|
42
|
-
logger.error(
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
raise NotAuthorizedError(
|
|
46
|
-
"Integration returned empty or invalid API key."
|
|
47
|
-
)
|
|
32
|
+
logger.error(f"Integration {type(self.integration).__name__} returned credentials in unexpected format.")
|
|
33
|
+
raise NotAuthorizedError("Integration returned empty or invalid API key.")
|
|
48
34
|
self._fal_client = AsyncClient(key=api_key)
|
|
49
35
|
return self._fal_client
|
|
50
36
|
|
|
51
|
-
async def
|
|
37
|
+
async def generate_image(
|
|
52
38
|
self,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
39
|
+
prompt: str,
|
|
40
|
+
model: Literal[
|
|
41
|
+
"fal-ai/flux/dev", "fal-ai/recraft-v3", "fal-ai/stable-diffusion-v35-large"
|
|
42
|
+
] = "fal-ai/flux/dev",
|
|
43
|
+
image_size: Literal[
|
|
44
|
+
"square_hd", "square", "portrait_4_3", "portrait_16_9", "landscape_4_3", "landscape_16_9"
|
|
45
|
+
]
|
|
46
|
+
| None = "landscape_4_3",
|
|
47
|
+
num_images: int | None = 1,
|
|
48
|
+
seed: int | None = None,
|
|
49
|
+
safety_tolerance: str | None = None,
|
|
50
|
+
extra_arguments: dict[str, Any] | None = None,
|
|
58
51
|
) -> Any:
|
|
59
52
|
"""
|
|
60
|
-
|
|
53
|
+
Generates an image from a text prompt using specified Fal AI models.
|
|
54
|
+
This tool supports state-of-the-art models like Flux, Recraft V3, and Stable Diffusion 3.5.
|
|
61
55
|
|
|
62
56
|
Args:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
prompt: The text description of the image to generate.
|
|
58
|
+
model: The model to use for generation. Options:
|
|
59
|
+
- 'fal-ai/flux/dev': High-quality, 12B param flow transformer.
|
|
60
|
+
- 'fal-ai/recraft-v3': SOTA model, great for text, vector art, and brand styles.
|
|
61
|
+
- 'fal-ai/stable-diffusion-v35-large': MMDiT model, excellent typography and complex prompts.
|
|
62
|
+
Defaults to 'fal-ai/flux/dev'.
|
|
63
|
+
image_size: The size/aspect ratio of the generated image. Common values: 'landscape_4_3', 'square_hd'.
|
|
64
|
+
num_images: Number of images to generate (default: 1).
|
|
65
|
+
seed: Optional random seed for reproducibility.
|
|
66
|
+
safety_tolerance: Optional safety filter level (if supported by model).
|
|
67
|
+
extra_arguments: Additional model-specific parameters to pass in the request.
|
|
68
68
|
|
|
69
69
|
Returns:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Raises:
|
|
73
|
-
ToolError: Raised when the Fal API request fails, wrapping the original exception
|
|
70
|
+
A dictionary containing the generated image URLs and metadata.
|
|
74
71
|
|
|
75
72
|
Tags:
|
|
76
|
-
|
|
73
|
+
generate, image, text-to-image, ai, flux, recraft, stable-diffusion, important
|
|
77
74
|
"""
|
|
75
|
+
arguments = {"prompt": prompt}
|
|
76
|
+
|
|
77
|
+
# Common arguments that most models support
|
|
78
|
+
if image_size:
|
|
79
|
+
arguments["image_size"] = image_size
|
|
80
|
+
if num_images:
|
|
81
|
+
arguments["num_images"] = num_images
|
|
82
|
+
if seed is not None:
|
|
83
|
+
arguments["seed"] = seed
|
|
84
|
+
if safety_tolerance:
|
|
85
|
+
arguments["safety_tolerance"] = safety_tolerance
|
|
86
|
+
|
|
87
|
+
if extra_arguments:
|
|
88
|
+
arguments.update(extra_arguments)
|
|
89
|
+
logger.debug(f"Merged extra_arguments. Final arguments: {arguments}")
|
|
90
|
+
|
|
78
91
|
try:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
path=path,
|
|
83
|
-
timeout=timeout,
|
|
84
|
-
hint=hint,
|
|
85
|
-
)
|
|
92
|
+
client = await self.get_fal_client()
|
|
93
|
+
# The run method is equivalent to subscribe() in the JS SDK - it submits and waits for the result.
|
|
94
|
+
result = await client.run(application=model, arguments=arguments)
|
|
86
95
|
return result
|
|
87
96
|
except Exception as e:
|
|
88
|
-
logger.error(
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
-
raise ToolError(f"Failed to run Fal application {application}: {e}") from e
|
|
97
|
+
logger.error(f"Error generating image with model {model}: {e}", exc_info=True)
|
|
98
|
+
raise ToolError(f"Failed to generate image with {model}: {e}") from e
|
|
92
99
|
|
|
93
|
-
async def
|
|
100
|
+
async def submit_video_generation(
|
|
94
101
|
self,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
image_url: str,
|
|
103
|
+
prompt: str = "",
|
|
104
|
+
model: Literal[
|
|
105
|
+
"fal-ai/minimax-video/image-to-video",
|
|
106
|
+
"fal-ai/luma-dream-machine/image-to-video",
|
|
107
|
+
"fal-ai/kling-video/v1/standard/image-to-video",
|
|
108
|
+
] = "fal-ai/minimax-video/image-to-video",
|
|
109
|
+
duration: Literal["5", "10"] | None = None,
|
|
110
|
+
aspect_ratio: Literal["16:9", "9:16", "1:1"] | None = None,
|
|
111
|
+
extra_arguments: dict[str, Any] | None = None,
|
|
101
112
|
) -> str:
|
|
102
113
|
"""
|
|
103
|
-
Submits a
|
|
114
|
+
Submits a video generation task using Fal AI models and returns a request ID.
|
|
115
|
+
This is an asynchronous operation. Use `get_generation_status` and `get_generation_result` with the returned ID.
|
|
104
116
|
|
|
105
117
|
Args:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
118
|
+
image_url: URL of the input image.
|
|
119
|
+
prompt: Text prompt to guide the video generation.
|
|
120
|
+
model: The video generation model to use.
|
|
121
|
+
duration: Duration of the video in seconds (supported by some models like Kling).
|
|
122
|
+
aspect_ratio: Aspect ratio of the generated video (supported by some models like Kling).
|
|
123
|
+
extra_arguments: Additional model-specific parameters.
|
|
112
124
|
|
|
113
125
|
Returns:
|
|
114
|
-
The request ID (str)
|
|
115
|
-
|
|
116
|
-
Raises:
|
|
117
|
-
ToolError: Raised when the Fal API request fails, wrapping the original exception
|
|
126
|
+
The request ID (str) for the submitted task.
|
|
118
127
|
|
|
119
128
|
Tags:
|
|
120
|
-
submit,
|
|
129
|
+
submit, video, async, ai, minimax, luma, kling, important
|
|
121
130
|
"""
|
|
131
|
+
arguments = {"image_url": image_url}
|
|
132
|
+
if prompt:
|
|
133
|
+
arguments["prompt"] = prompt
|
|
134
|
+
|
|
135
|
+
if duration:
|
|
136
|
+
arguments["duration"] = duration
|
|
137
|
+
if aspect_ratio:
|
|
138
|
+
arguments["aspect_ratio"] = aspect_ratio
|
|
139
|
+
|
|
140
|
+
if extra_arguments:
|
|
141
|
+
arguments.update(extra_arguments)
|
|
142
|
+
logger.debug(f"Merged extra_arguments for video generation. Final arguments: {arguments}")
|
|
143
|
+
|
|
122
144
|
try:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
path=path,
|
|
127
|
-
hint=hint,
|
|
128
|
-
webhook_url=webhook_url,
|
|
129
|
-
priority=priority,
|
|
130
|
-
)
|
|
131
|
-
request_id = handle.request_id
|
|
132
|
-
return request_id
|
|
145
|
+
client = await self.get_fal_client()
|
|
146
|
+
handle = await client.submit(application=model, arguments=arguments)
|
|
147
|
+
return handle.request_id
|
|
133
148
|
except Exception as e:
|
|
134
|
-
logger.error(
|
|
135
|
-
|
|
136
|
-
)
|
|
137
|
-
raise ToolError(
|
|
138
|
-
f"Failed to submit Fal application {application}: {e}"
|
|
139
|
-
) from e
|
|
149
|
+
logger.error(f"Error submitting video generation with model {model}: {e}", exc_info=True)
|
|
150
|
+
raise ToolError(f"Failed to submit video generation with {model}: {e}") from e
|
|
140
151
|
|
|
141
|
-
async def
|
|
152
|
+
async def get_generation_status(
|
|
142
153
|
self,
|
|
143
154
|
request_id: str,
|
|
144
|
-
|
|
155
|
+
model: Literal[
|
|
156
|
+
"fal-ai/minimax-video/image-to-video",
|
|
157
|
+
"fal-ai/luma-dream-machine/image-to-video",
|
|
158
|
+
"fal-ai/kling-video/v1/standard/image-to-video",
|
|
159
|
+
] = "fal-ai/minimax-video/image-to-video",
|
|
145
160
|
with_logs: bool = False,
|
|
146
161
|
) -> Status:
|
|
147
162
|
"""
|
|
148
|
-
Checks the
|
|
163
|
+
Checks the status of a video generation task.
|
|
149
164
|
|
|
150
165
|
Args:
|
|
151
|
-
request_id: The
|
|
152
|
-
|
|
153
|
-
with_logs:
|
|
166
|
+
request_id: The ID of the request to check.
|
|
167
|
+
model: The model used for the request (must match the submission).
|
|
168
|
+
with_logs: Whether to include logs in the status.
|
|
154
169
|
|
|
155
170
|
Returns:
|
|
156
|
-
A Status object
|
|
157
|
-
|
|
158
|
-
Raises:
|
|
159
|
-
ToolError: Raised when the Fal API request fails or when the provided request ID is invalid
|
|
160
|
-
|
|
171
|
+
A Status object (Queued, InProgress, Completed, or Failed).
|
|
172
|
+
|
|
161
173
|
Tags:
|
|
162
|
-
|
|
174
|
+
check, status, video, async, important
|
|
163
175
|
"""
|
|
164
176
|
try:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
168
|
-
status = await handle.status(with_logs=with_logs)
|
|
169
|
-
return status
|
|
177
|
+
client = await self.get_fal_client()
|
|
178
|
+
handle = client.get_handle(application=model, request_id=request_id)
|
|
179
|
+
return await handle.status(with_logs=with_logs)
|
|
170
180
|
except Exception as e:
|
|
171
|
-
logger.error(
|
|
172
|
-
|
|
173
|
-
exc_info=True,
|
|
174
|
-
)
|
|
175
|
-
raise ToolError(
|
|
176
|
-
f"Failed to get status for Fal request_id {request_id}: {e}"
|
|
177
|
-
) from e
|
|
181
|
+
logger.error(f"Error getting status for request {request_id}: {e}", exc_info=True)
|
|
182
|
+
raise ToolError(f"Failed to get status for {request_id}: {e}") from e
|
|
178
183
|
|
|
179
|
-
async def
|
|
180
|
-
self,
|
|
184
|
+
async def get_generation_result(
|
|
185
|
+
self,
|
|
186
|
+
request_id: str,
|
|
187
|
+
model: Literal[
|
|
188
|
+
"fal-ai/minimax-video/image-to-video",
|
|
189
|
+
"fal-ai/luma-dream-machine/image-to-video",
|
|
190
|
+
"fal-ai/kling-video/v1/standard/image-to-video",
|
|
191
|
+
] = "fal-ai/minimax-video/image-to-video",
|
|
181
192
|
) -> Any:
|
|
182
193
|
"""
|
|
183
|
-
Retrieves the
|
|
184
|
-
|
|
185
|
-
Args:
|
|
186
|
-
request_id: The unique identifier of the submitted request
|
|
187
|
-
application: The name or ID of the Fal application (defaults to 'fal-ai/flux/dev')
|
|
188
|
-
|
|
189
|
-
Returns:
|
|
190
|
-
The result of the application execution, converted from JSON response to Python data structures (dict/list)
|
|
191
|
-
|
|
192
|
-
Raises:
|
|
193
|
-
ToolError: When the Fal API request fails or the request does not complete successfully
|
|
194
|
-
|
|
195
|
-
Tags:
|
|
196
|
-
result, async-job, status, wait, ai
|
|
197
|
-
"""
|
|
198
|
-
try:
|
|
199
|
-
handle = self.fal_client.get_handle(
|
|
200
|
-
application=application, request_id=request_id
|
|
201
|
-
)
|
|
202
|
-
result = await handle.get()
|
|
203
|
-
return result
|
|
204
|
-
except Exception as e:
|
|
205
|
-
logger.error(
|
|
206
|
-
f"Error getting result for Fal request_id {request_id}: {e}",
|
|
207
|
-
exc_info=True,
|
|
208
|
-
)
|
|
209
|
-
raise ToolError(
|
|
210
|
-
f"Failed to get result for Fal request_id {request_id}: {e}"
|
|
211
|
-
) from e
|
|
212
|
-
|
|
213
|
-
async def cancel(
|
|
214
|
-
self, request_id: str, application: str = "fal-ai/flux/dev"
|
|
215
|
-
) -> None:
|
|
216
|
-
"""
|
|
217
|
-
Asynchronously cancels a running or queued Fal AI job using its `request_id`. This function complements the `submit` method, providing a way to terminate asynchronous tasks before completion. It raises a `ToolError` if the cancellation request fails.
|
|
194
|
+
Retrieves the result of a completed video generation task.
|
|
195
|
+
This method will block until the task is complete if it is not already.
|
|
218
196
|
|
|
219
197
|
Args:
|
|
220
|
-
request_id: The
|
|
221
|
-
|
|
198
|
+
request_id: The ID of the request.
|
|
199
|
+
model: The model used for the request.
|
|
222
200
|
|
|
223
201
|
Returns:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
Raises:
|
|
227
|
-
ToolError: Raised when the cancellation request fails due to API errors or if the request cannot be cancelled
|
|
202
|
+
The final result of the generation (video URL and metadata).
|
|
228
203
|
|
|
229
204
|
Tags:
|
|
230
|
-
|
|
205
|
+
result, get, video, async, important
|
|
231
206
|
"""
|
|
232
207
|
try:
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)
|
|
236
|
-
await handle.cancel()
|
|
237
|
-
return None
|
|
208
|
+
client = await self.get_fal_client()
|
|
209
|
+
handle = client.get_handle(application=model, request_id=request_id)
|
|
210
|
+
return await handle.get()
|
|
238
211
|
except Exception as e:
|
|
239
|
-
logger.error(
|
|
240
|
-
|
|
241
|
-
)
|
|
242
|
-
raise ToolError(f"Failed to cancel Fal request_id {request_id}: {e}") from e
|
|
243
|
-
|
|
244
|
-
async def upload_file(self, path: str) -> str:
|
|
245
|
-
"""
|
|
246
|
-
Asynchronously uploads a local file to the Fal Content Delivery Network (CDN), returning a public URL. This URL makes the file accessible for use as input in other Fal AI job execution methods like `run` or `submit`. A `ToolError` is raised if the upload fails.
|
|
247
|
-
|
|
248
|
-
Args:
|
|
249
|
-
path: The absolute or relative path to the local file
|
|
250
|
-
|
|
251
|
-
Returns:
|
|
252
|
-
A string containing the public URL of the uploaded file on the CDN
|
|
212
|
+
logger.error(f"Error getting result for request {request_id}: {e}", exc_info=True)
|
|
213
|
+
raise ToolError(f"Failed to get result for {request_id}: {e}") from e
|
|
253
214
|
|
|
254
|
-
|
|
255
|
-
ToolError: If the file is not found or if the upload operation fails
|
|
256
|
-
|
|
257
|
-
Tags:
|
|
258
|
-
upload, file, cdn, storage, async, important
|
|
259
|
-
"""
|
|
260
|
-
try:
|
|
261
|
-
file_url = await self.fal_client.upload_file(Path(path))
|
|
262
|
-
return file_url
|
|
263
|
-
except FileNotFoundError as e:
|
|
264
|
-
logger.error(f"File not found for upload: {path}", exc_info=True)
|
|
265
|
-
raise ToolError(f"File not found: {path}") from e
|
|
266
|
-
except Exception as e:
|
|
267
|
-
logger.error(f"Error uploading file {path} to Fal CDN: {e}", exc_info=True)
|
|
268
|
-
raise ToolError(f"Failed to upload file {path}: {e}") from e
|
|
269
|
-
|
|
270
|
-
async def run_image_generation(
|
|
215
|
+
async def transcribe_audio(
|
|
271
216
|
self,
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
image_size: str | None = "landscape_4_3",
|
|
275
|
-
num_images: int | None = 1,
|
|
217
|
+
audio_url: str,
|
|
218
|
+
model: Literal["fal-ai/whisper"] = "fal-ai/whisper",
|
|
276
219
|
extra_arguments: dict[str, Any] | None = None,
|
|
277
|
-
path: str = "",
|
|
278
|
-
timeout: float | None = None,
|
|
279
|
-
hint: str | None = None,
|
|
280
220
|
) -> Any:
|
|
281
221
|
"""
|
|
282
|
-
|
|
222
|
+
Converts speech to text from an audio file URL using Fal AI models.
|
|
283
223
|
|
|
284
224
|
Args:
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
extra_arguments: Additional
|
|
290
|
-
path: Subpath for the application endpoint (rarely used)
|
|
291
|
-
timeout: Maximum time in seconds to wait for the request to complete
|
|
292
|
-
hint: Hint string for runner selection
|
|
225
|
+
audio_url: URL of the audio file to transcribe.
|
|
226
|
+
model: The speech-to-text model to use. Options:
|
|
227
|
+
- 'fal-ai/whisper': Standard Whisper model.
|
|
228
|
+
Defaults to 'fal-ai/whisper'.
|
|
229
|
+
extra_arguments: Additional model-specific parameters.
|
|
293
230
|
|
|
294
231
|
Returns:
|
|
295
|
-
A dictionary containing the
|
|
296
|
-
|
|
297
|
-
Raises:
|
|
298
|
-
ToolError: When the image generation request fails or encounters an error
|
|
232
|
+
A dictionary containing the transcription text and metadata.
|
|
299
233
|
|
|
300
234
|
Tags:
|
|
301
|
-
|
|
235
|
+
transcribe, audio, speech-to-text, ai, whisper
|
|
302
236
|
"""
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
"prompt": prompt,
|
|
306
|
-
"seed": seed,
|
|
307
|
-
"image_size": image_size,
|
|
308
|
-
"num_images": num_images,
|
|
309
|
-
}
|
|
237
|
+
arguments = {"audio_url": audio_url}
|
|
238
|
+
|
|
310
239
|
if extra_arguments:
|
|
311
240
|
arguments.update(extra_arguments)
|
|
312
|
-
logger.debug(f"Merged extra_arguments. Final arguments: {arguments}")
|
|
241
|
+
logger.debug(f"Merged extra_arguments for transcription. Final arguments: {arguments}")
|
|
242
|
+
|
|
313
243
|
try:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
arguments=arguments,
|
|
317
|
-
path=path,
|
|
318
|
-
timeout=timeout,
|
|
319
|
-
hint=hint,
|
|
320
|
-
)
|
|
244
|
+
client = await self.get_fal_client()
|
|
245
|
+
result = await client.run(application=model, arguments=arguments)
|
|
321
246
|
return result
|
|
322
|
-
except Exception:
|
|
323
|
-
|
|
247
|
+
except Exception as e:
|
|
248
|
+
logger.error(f"Error transcribing audio with model {model}: {e}", exc_info=True)
|
|
249
|
+
raise ToolError(f"Failed to transcribe audio with {model}: {e}") from e
|
|
324
250
|
|
|
325
|
-
def list_tools(self)
|
|
251
|
+
def list_tools(self):
|
|
326
252
|
return [
|
|
327
|
-
self.
|
|
328
|
-
self.
|
|
329
|
-
self.
|
|
330
|
-
self.
|
|
331
|
-
self.
|
|
332
|
-
self.upload_file,
|
|
333
|
-
self.run_image_generation,
|
|
253
|
+
self.generate_image,
|
|
254
|
+
self.submit_video_generation,
|
|
255
|
+
self.get_generation_status,
|
|
256
|
+
self.get_generation_result,
|
|
257
|
+
self.transcribe_audio
|
|
334
258
|
]
|