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.

Files changed (119) hide show
  1. universal_mcp/applications/BEST_PRACTICES.md +1 -1
  2. universal_mcp/applications/ahrefs/app.py +92 -238
  3. universal_mcp/applications/airtable/app.py +36 -135
  4. universal_mcp/applications/apollo/app.py +124 -477
  5. universal_mcp/applications/asana/app.py +605 -1755
  6. universal_mcp/applications/aws_s3/app.py +63 -119
  7. universal_mcp/applications/bill/app.py +644 -2055
  8. universal_mcp/applications/box/app.py +1246 -4159
  9. universal_mcp/applications/braze/app.py +410 -1476
  10. universal_mcp/applications/browser_use/README.md +15 -1
  11. universal_mcp/applications/browser_use/__init__.py +1 -0
  12. universal_mcp/applications/browser_use/app.py +91 -26
  13. universal_mcp/applications/cal_com_v2/app.py +207 -625
  14. universal_mcp/applications/calendly/app.py +103 -242
  15. universal_mcp/applications/canva/app.py +75 -140
  16. universal_mcp/applications/clickup/app.py +331 -798
  17. universal_mcp/applications/coda/app.py +240 -520
  18. universal_mcp/applications/confluence/app.py +497 -1285
  19. universal_mcp/applications/contentful/app.py +40 -155
  20. universal_mcp/applications/crustdata/app.py +44 -123
  21. universal_mcp/applications/dialpad/app.py +451 -924
  22. universal_mcp/applications/digitalocean/app.py +2071 -6082
  23. universal_mcp/applications/domain_checker/app.py +3 -54
  24. universal_mcp/applications/e2b/app.py +17 -68
  25. universal_mcp/applications/elevenlabs/README.md +27 -3
  26. universal_mcp/applications/elevenlabs/app.py +741 -74
  27. universal_mcp/applications/exa/README.md +8 -4
  28. universal_mcp/applications/exa/app.py +415 -186
  29. universal_mcp/applications/falai/README.md +5 -7
  30. universal_mcp/applications/falai/app.py +156 -232
  31. universal_mcp/applications/figma/app.py +91 -175
  32. universal_mcp/applications/file_system/app.py +2 -13
  33. universal_mcp/applications/firecrawl/app.py +198 -176
  34. universal_mcp/applications/fireflies/app.py +59 -281
  35. universal_mcp/applications/fpl/app.py +92 -529
  36. universal_mcp/applications/fpl/utils/fixtures.py +15 -49
  37. universal_mcp/applications/fpl/utils/helper.py +25 -89
  38. universal_mcp/applications/fpl/utils/league_utils.py +20 -64
  39. universal_mcp/applications/ghost_content/app.py +70 -179
  40. universal_mcp/applications/github/app.py +30 -67
  41. universal_mcp/applications/gong/app.py +142 -302
  42. universal_mcp/applications/google_calendar/app.py +26 -78
  43. universal_mcp/applications/google_docs/README.md +15 -14
  44. universal_mcp/applications/google_docs/app.py +103 -206
  45. universal_mcp/applications/google_drive/app.py +194 -793
  46. universal_mcp/applications/google_gemini/app.py +68 -59
  47. universal_mcp/applications/google_mail/README.md +1 -0
  48. universal_mcp/applications/google_mail/app.py +93 -214
  49. universal_mcp/applications/google_searchconsole/app.py +25 -58
  50. universal_mcp/applications/google_sheet/README.md +2 -1
  51. universal_mcp/applications/google_sheet/app.py +226 -624
  52. universal_mcp/applications/google_sheet/helper.py +26 -53
  53. universal_mcp/applications/hashnode/app.py +57 -269
  54. universal_mcp/applications/heygen/README.md +10 -32
  55. universal_mcp/applications/heygen/app.py +339 -811
  56. universal_mcp/applications/http_tools/app.py +10 -32
  57. universal_mcp/applications/hubspot/README.md +1 -1
  58. universal_mcp/applications/hubspot/app.py +7508 -99
  59. universal_mcp/applications/jira/app.py +2419 -8334
  60. universal_mcp/applications/klaviyo/app.py +739 -1621
  61. universal_mcp/applications/linkedin/README.md +18 -1
  62. universal_mcp/applications/linkedin/app.py +729 -251
  63. universal_mcp/applications/mailchimp/app.py +696 -1851
  64. universal_mcp/applications/markitdown/app.py +8 -20
  65. universal_mcp/applications/miro/app.py +333 -815
  66. universal_mcp/applications/ms_teams/app.py +420 -1407
  67. universal_mcp/applications/neon/app.py +144 -250
  68. universal_mcp/applications/notion/app.py +38 -53
  69. universal_mcp/applications/onedrive/app.py +26 -48
  70. universal_mcp/applications/openai/app.py +43 -166
  71. universal_mcp/applications/outlook/README.md +22 -9
  72. universal_mcp/applications/outlook/app.py +403 -141
  73. universal_mcp/applications/perplexity/README.md +2 -1
  74. universal_mcp/applications/perplexity/app.py +161 -20
  75. universal_mcp/applications/pipedrive/app.py +1021 -3331
  76. universal_mcp/applications/posthog/app.py +272 -541
  77. universal_mcp/applications/reddit/app.py +65 -164
  78. universal_mcp/applications/resend/app.py +72 -139
  79. universal_mcp/applications/retell/app.py +23 -50
  80. universal_mcp/applications/rocketlane/app.py +252 -965
  81. universal_mcp/applications/scraper/app.py +114 -142
  82. universal_mcp/applications/semanticscholar/app.py +36 -78
  83. universal_mcp/applications/semrush/app.py +44 -78
  84. universal_mcp/applications/sendgrid/app.py +826 -1576
  85. universal_mcp/applications/sentry/app.py +444 -1079
  86. universal_mcp/applications/serpapi/app.py +44 -146
  87. universal_mcp/applications/sharepoint/app.py +27 -49
  88. universal_mcp/applications/shopify/app.py +1748 -4486
  89. universal_mcp/applications/shortcut/app.py +275 -536
  90. universal_mcp/applications/slack/app.py +43 -125
  91. universal_mcp/applications/spotify/app.py +206 -405
  92. universal_mcp/applications/supabase/app.py +174 -283
  93. universal_mcp/applications/tavily/app.py +2 -2
  94. universal_mcp/applications/trello/app.py +853 -2816
  95. universal_mcp/applications/twilio/app.py +27 -62
  96. universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
  97. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
  98. universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
  99. universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
  100. universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
  101. universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
  102. universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
  103. universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
  104. universal_mcp/applications/whatsapp/app.py +35 -186
  105. universal_mcp/applications/whatsapp/audio.py +2 -6
  106. universal_mcp/applications/whatsapp/whatsapp.py +17 -51
  107. universal_mcp/applications/whatsapp_business/app.py +86 -299
  108. universal_mcp/applications/wrike/app.py +80 -153
  109. universal_mcp/applications/yahoo_finance/app.py +19 -65
  110. universal_mcp/applications/youtube/app.py +120 -306
  111. universal_mcp/applications/zenquotes/app.py +3 -3
  112. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/METADATA +4 -2
  113. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/RECORD +115 -119
  114. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/WHEEL +1 -1
  115. universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
  116. universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -54
  117. universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -7337
  118. universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -1467
  119. {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
- | `run` | Executes a Fal AI application synchronously, waiting for completion and returning the result directly. This method is suited for short-running tasks, unlike `submit` which queues a job for asynchronous processing and returns a request ID instead of the final output. |
13
- | `submit` | Submits a job to the Fal AI queue for asynchronous processing, immediately returning a request ID. This contrasts with the `run` method, which waits for completion. The returned ID is used by `check_status`, `get_result`, and `cancel` to manage the job's lifecycle. |
14
- | `check_status` | Checks the execution state (e.g., Queued, InProgress) of an asynchronous Fal AI job using its request ID. It provides a non-blocking way to monitor jobs initiated via `submit` without fetching the final `result`, and can optionally include logs. |
15
- | `get_result` | Retrieves the final result of an asynchronous job, identified by its `request_id`. This function waits for the job, initiated via `submit`, to complete. Unlike the non-blocking `check_status`, this method blocks execution to fetch and return the job's actual output upon completion. |
16
- | `cancel` | 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. |
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
- @property
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.get_credentials()
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
- f"Integration {type(self.integration).__name__} returned credentials in unexpected format."
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 run(
37
+ async def generate_image(
52
38
  self,
53
- arguments: Any,
54
- application: str = "fal-ai/flux/dev",
55
- path: str = "",
56
- timeout: float | None = None,
57
- hint: str | None = None,
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
- Executes a Fal AI application synchronously, waiting for completion and returning the result directly. This method is suited for short-running tasks, unlike `submit` which queues a job for asynchronous processing and returns a request ID instead of the final output.
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
- arguments: A dictionary of arguments for the application
64
- application: The name or ID of the Fal application (defaults to 'fal-ai/flux/dev')
65
- path: Optional subpath for the application endpoint
66
- timeout: Optional timeout in seconds for the request
67
- hint: Optional hint for runner selection
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
- The result of the application execution as a Python object (converted from JSON response)
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
- run, execute, ai, synchronous, fal, important
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
- result = await self.fal_client.run(
80
- application=application,
81
- arguments=arguments,
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
- f"Error running Fal application {application}: {e}", exc_info=True
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 submit(
100
+ async def submit_video_generation(
94
101
  self,
95
- arguments: Any,
96
- application: str = "fal-ai/flux/dev",
97
- path: str = "",
98
- hint: str | None = None,
99
- webhook_url: str | None = None,
100
- priority: Priority | None = None,
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 job to the Fal AI queue for asynchronous processing, immediately returning a request ID. This contrasts with the `run` method, which waits for completion. The returned ID is used by `check_status`, `get_result`, and `cancel` to manage the job's lifecycle.
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
- arguments: A dictionary of arguments for the application
107
- application: The name or ID of the Fal application, defaulting to 'fal-ai/flux/dev'
108
- path: Optional subpath for the application endpoint
109
- hint: Optional hint for runner selection
110
- webhook_url: Optional URL to receive a webhook when the request completes
111
- priority: Optional queue priority ('normal' or 'low')
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) of the submitted asynchronous job
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, async_job, start, ai, queue
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
- handle: AsyncRequestHandle = await self.fal_client.submit(
124
- application=application,
125
- arguments=arguments,
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
- f"Error submitting Fal application {application}: {e}", exc_info=True
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 check_status(
152
+ async def get_generation_status(
142
153
  self,
143
154
  request_id: str,
144
- application: str = "fal-ai/flux/dev",
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 execution state (e.g., Queued, InProgress) of an asynchronous Fal AI job using its request ID. It provides a non-blocking way to monitor jobs initiated via `submit` without fetching the final `result`, and can optionally include logs.
163
+ Checks the status of a video generation task.
149
164
 
150
165
  Args:
151
- request_id: The unique identifier of the submitted request, obtained from a previous submit operation
152
- application: The name or ID of the Fal application (defaults to 'fal-ai/flux/dev')
153
- with_logs: Boolean flag to include execution logs in the status response (defaults to False)
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 containing the current state of the request (Queued, InProgress, or Completed)
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
- status, check, async_job, monitoring, ai
174
+ check, status, video, async, important
163
175
  """
164
176
  try:
165
- handle = self.fal_client.get_handle(
166
- application=application, request_id=request_id
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
- f"Error getting status for Fal request_id {request_id}: {e}",
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 get_result(
180
- self, request_id: str, application: str = "fal-ai/flux/dev"
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 final result of an asynchronous job, identified by its `request_id`. This function waits for the job, initiated via `submit`, to complete. Unlike the non-blocking `check_status`, this method blocks execution to fetch and return the job's actual output upon completion.
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 unique identifier of the submitted Fal AI request to cancel
221
- application: The name or ID of the Fal application (defaults to 'fal-ai/flux/dev')
198
+ request_id: The ID of the request.
199
+ model: The model used for the request.
222
200
 
223
201
  Returns:
224
- None. The function doesn't return any value.
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
- cancel, async_job, ai, fal, management
205
+ result, get, video, async, important
231
206
  """
232
207
  try:
233
- handle = self.fal_client.get_handle(
234
- application=application, request_id=request_id
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
- f"Error cancelling Fal request_id {request_id}: {e}", exc_info=True
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
- Raises:
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
- prompt: str,
273
- seed: int | None = 6252023,
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
- 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.
222
+ Converts speech to text from an audio file URL using Fal AI models.
283
223
 
284
224
  Args:
285
- prompt: The text prompt used to guide the image generation
286
- seed: Random seed for reproducible image generation (default: 6252023)
287
- image_size: Dimensions of the generated image (default: 'landscape_4_3')
288
- num_images: Number of images to generate in one request (default: 1)
289
- extra_arguments: Additional arguments dictionary to pass to the application, can override defaults
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 generated image URLs and related metadata
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
- generate, image, ai, async, important, flux, customizable, default
235
+ transcribe, audio, speech-to-text, ai, whisper
302
236
  """
303
- application = "fal-ai/flux/dev"
304
- arguments = {
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
- result = await self.run(
315
- application=application,
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
- raise
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) -> list[callable]:
251
+ def list_tools(self):
326
252
  return [
327
- self.run,
328
- self.submit,
329
- self.check_status,
330
- self.get_result,
331
- self.cancel,
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
  ]