fal 0.12.7__tar.gz → 0.14.0__tar.gz

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 fal might be problematic. Click here for more details.

Files changed (89) hide show
  1. {fal-0.12.7 → fal-0.14.0}/PKG-INFO +1 -1
  2. {fal-0.12.7 → fal-0.14.0}/pyproject.toml +1 -1
  3. {fal-0.12.7 → fal-0.14.0}/src/fal/__init__.py +4 -4
  4. {fal-0.12.7 → fal-0.14.0}/src/fal/_serialization.py +27 -0
  5. {fal-0.12.7 → fal-0.14.0}/src/fal/api.py +31 -12
  6. {fal-0.12.7 → fal-0.14.0}/src/fal/app.py +1 -1
  7. {fal-0.12.7 → fal-0.14.0}/src/fal/auth/__init__.py +1 -1
  8. {fal-0.12.7 → fal-0.14.0}/src/fal/cli.py +1 -2
  9. {fal-0.12.7 → fal-0.14.0}/src/fal/logging/isolate.py +8 -19
  10. {fal-0.12.7 → fal-0.14.0}/src/fal/logging/user.py +1 -1
  11. {fal-0.12.7 → fal-0.14.0}/src/fal/sdk.py +2 -1
  12. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/file/__init__.py +1 -1
  13. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/file/file.py +1 -1
  14. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/file/providers/fal.py +2 -2
  15. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/image/__init__.py +1 -1
  16. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/image/image.py +1 -1
  17. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/optimize.py +1 -1
  18. fal-0.14.0/src/fal/toolkit/utils/__init__.py +3 -0
  19. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/utils/download_utils.py +1 -1
  20. {fal-0.12.7 → fal-0.14.0}/src/fal/workflows.py +1 -1
  21. fal-0.12.7/src/fal/toolkit/utils/__init__.py +0 -3
  22. {fal-0.12.7 → fal-0.14.0}/README.md +0 -0
  23. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
  24. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
  25. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
  26. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
  27. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
  28. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
  29. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
  30. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
  31. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
  32. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
  33. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_or_update_workflow_workflows_post.py +0 -0
  34. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow_workflows_user_id_workflow_name_delete.py +0 -0
  35. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/execute_workflow_workflows_user_id_workflow_name_post.py +0 -0
  36. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow_workflows_user_id_workflow_name_get.py +0 -0
  37. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflows_workflows_get.py +0 -0
  38. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
  39. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
  40. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
  41. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
  42. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
  43. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
  44. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/execute_workflow_workflows_user_id_workflow_name_post_json_body_type_0.py +0 -0
  45. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/execute_workflow_workflows_user_id_workflow_name_post_response_200_type_0.py +0 -0
  46. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
  47. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
  48. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
  49. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
  50. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
  51. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
  52. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
  53. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
  54. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
  55. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
  56. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents_type_0.py +0 -0
  57. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
  58. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
  59. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
  60. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
  61. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
  62. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
  63. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
  64. {fal-0.12.7 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
  65. {fal-0.12.7 → fal-0.14.0}/src/fal/__main__.py +0 -0
  66. {fal-0.12.7 → fal-0.14.0}/src/fal/apps.py +0 -0
  67. {fal-0.12.7 → fal-0.14.0}/src/fal/auth/auth0.py +0 -0
  68. {fal-0.12.7 → fal-0.14.0}/src/fal/auth/local.py +0 -0
  69. {fal-0.12.7 → fal-0.14.0}/src/fal/console/__init__.py +0 -0
  70. {fal-0.12.7 → fal-0.14.0}/src/fal/console/icons.py +0 -0
  71. {fal-0.12.7 → fal-0.14.0}/src/fal/console/ux.py +0 -0
  72. {fal-0.12.7 → fal-0.14.0}/src/fal/env.py +0 -0
  73. {fal-0.12.7 → fal-0.14.0}/src/fal/exceptions/__init__.py +0 -0
  74. {fal-0.12.7 → fal-0.14.0}/src/fal/exceptions/_base.py +0 -0
  75. {fal-0.12.7 → fal-0.14.0}/src/fal/exceptions/auth.py +0 -0
  76. {fal-0.12.7 → fal-0.14.0}/src/fal/exceptions/handlers.py +0 -0
  77. {fal-0.12.7 → fal-0.14.0}/src/fal/flags.py +0 -0
  78. {fal-0.12.7 → fal-0.14.0}/src/fal/logging/__init__.py +0 -0
  79. {fal-0.12.7 → fal-0.14.0}/src/fal/logging/style.py +0 -0
  80. {fal-0.12.7 → fal-0.14.0}/src/fal/logging/trace.py +0 -0
  81. {fal-0.12.7 → fal-0.14.0}/src/fal/py.typed +0 -0
  82. {fal-0.12.7 → fal-0.14.0}/src/fal/rest_client.py +0 -0
  83. {fal-0.12.7 → fal-0.14.0}/src/fal/sync.py +0 -0
  84. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/__init__.py +0 -0
  85. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/exceptions.py +0 -0
  86. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
  87. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/file/providers/r2.py +0 -0
  88. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/file/types.py +0 -0
  89. {fal-0.12.7 → fal-0.14.0}/src/fal/toolkit/mainify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fal
3
- Version: 0.12.7
3
+ Version: 0.14.0
4
4
  Summary: fal is an easy-to-use Serverless Python Framework
5
5
  Author: Features & Labels
6
6
  Author-email: hello@fal.ai
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "fal"
3
- version = "0.12.7"
3
+ version = "0.14.0"
4
4
  description = "fal is an easy-to-use Serverless Python Framework"
5
5
  authors = ["Features & Labels <hello@fal.ai>"]
6
6
  readme = "README.md"
@@ -1,10 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
- from fal import apps
3
+ from fal import apps # noqa: F401
4
4
  from fal.api import FalServerlessHost, LocalHost, cached
5
5
  from fal.api import function
6
- from fal.api import function as isolated
7
- from fal.app import App, endpoint, realtime, wrap_app
6
+ from fal.api import function as isolated # noqa: F401
7
+ from fal.app import App, endpoint, realtime, wrap_app # noqa: F401
8
8
  from fal.sdk import FalServerlessKeyCredentials
9
9
  from fal.sync import sync_dir
10
10
 
@@ -32,6 +32,6 @@ __all__ = [
32
32
  # This will add to the package’s __path__ all subdirectories of directories on sys.path named after the package which effectively combines both modules into a single namespace (dbt.adapters)
33
33
  # The matching statement is in plugins/postgres/dbt/adapters/__init__.py
34
34
 
35
- from pkgutil import extend_path
35
+ from pkgutil import extend_path # noqa: E402
36
36
 
37
37
  __path__ = extend_path(__path__, __name__)
@@ -163,6 +163,25 @@ def patch_exceptions():
163
163
  dill.pickle(exception_cls, save_exception)
164
164
 
165
165
 
166
+ @mainify
167
+ def _patch_console_thread_locals() -> None:
168
+ # NOTE: we __sometimes__ might have to serialize these
169
+ from rich.console import ConsoleThreadLocals
170
+
171
+ @dill.register(ConsoleThreadLocals)
172
+ def save_console_thread_locals(pickler, obj):
173
+ args = {
174
+ "theme_stack": obj.theme_stack,
175
+ "buffer": obj.buffer,
176
+ "buffer_index": obj.buffer_index,
177
+ }
178
+
179
+ def unpickle(kwargs):
180
+ return ConsoleThreadLocals(**kwargs)
181
+
182
+ pickler.save_reduce(unpickle, (args,), obj=obj)
183
+
184
+
166
185
  @mainify
167
186
  def patch_dill():
168
187
  import dill
@@ -172,3 +191,11 @@ def patch_dill():
172
191
  patch_exceptions()
173
192
  patch_pydantic_class_attributes()
174
193
  patch_pydantic_field_serialization()
194
+ _patch_console_thread_locals()
195
+
196
+
197
+ @mainify
198
+ def patch_pickle():
199
+ from tblib import pickling_support
200
+
201
+ pickling_support.install()
@@ -2,11 +2,12 @@ from __future__ import annotations
2
2
 
3
3
  import inspect
4
4
  import sys
5
+ import threading
5
6
  from collections import defaultdict
6
7
  from concurrent.futures import ThreadPoolExecutor
7
8
  from contextlib import asynccontextmanager, suppress
8
9
  from dataclasses import dataclass, field, replace
9
- from functools import partial, wraps
10
+ from functools import wraps
10
11
  from os import PathLike
11
12
  from typing import (
12
13
  Any,
@@ -26,6 +27,7 @@ import dill
26
27
  import dill.detect
27
28
  import grpc
28
29
  import isolate
30
+ import tblib
29
31
  import yaml
30
32
  from fastapi import FastAPI
31
33
  from isolate.backends.common import active_python
@@ -36,7 +38,7 @@ from packaging.utils import canonicalize_name
36
38
  from typing_extensions import Concatenate, ParamSpec
37
39
 
38
40
  import fal.flags as flags
39
- from fal._serialization import add_serialization_listeners_for, patch_dill
41
+ from fal._serialization import add_serialization_listeners_for, patch_dill, patch_pickle
40
42
  from fal.logging.isolate import IsolateLogPrinter
41
43
  from fal.sdk import (
42
44
  FAL_SERVERLESS_DEFAULT_KEEP_ALIVE,
@@ -192,10 +194,11 @@ def match_class(obj, cls):
192
194
 
193
195
  def _prepare_partial_func(
194
196
  func: Callable[ArgsT, ReturnT],
197
+ patch_func: Callable[[], None],
195
198
  *args: ArgsT.args,
196
199
  **kwargs: ArgsT.kwargs,
197
200
  ) -> Callable[ArgsT, ReturnT]:
198
- """Prepare the given function for execution on the remote isolate workers."""
201
+ """Prepare the given function for execution on isolate workers."""
199
202
 
200
203
  @wraps(func)
201
204
  def wrapper(*remote_args: ArgsT.args, **remote_kwargs: ArgsT.kwargs) -> ReturnT:
@@ -211,20 +214,39 @@ def _prepare_partial_func(
211
214
  ) from exc.with_traceback(tb)
212
215
  finally:
213
216
  with suppress(Exception):
214
- patch_dill()
217
+ patch_func()
215
218
  return result
216
219
 
217
220
  return wrapper
218
221
 
219
222
 
223
+ def _prepare_local_partial_func(
224
+ func: Callable[ArgsT, ReturnT],
225
+ *args: ArgsT.args,
226
+ **kwargs: ArgsT.kwargs,
227
+ ) -> Callable[ArgsT, ReturnT]:
228
+
229
+ return _prepare_partial_func(func, patch_pickle, *args, **kwargs)
230
+
231
+
232
+ def _prepare_remote_partial_func(
233
+ func: Callable[ArgsT, ReturnT],
234
+ *args: ArgsT.args,
235
+ **kwargs: ArgsT.kwargs,
236
+ ) -> Callable[ArgsT, ReturnT]:
237
+
238
+ return _prepare_partial_func(func, patch_dill, *args, **kwargs)
239
+
240
+
220
241
  @dataclass
221
242
  class LocalHost(Host):
222
243
  # The environment which provides the default set of
223
244
  # packages for isolate agent to run.
224
245
  _AGENT_ENVIRONMENT = isolate.prepare_environment(
225
246
  "virtualenv",
226
- requirements=[f"dill=={dill.__version__}"],
247
+ requirements=[f"dill=={dill.__version__}", f"tblib=={tblib.__version__}"],
227
248
  )
249
+ _log_printer = IsolateLogPrinter(debug=flags.DEBUG)
228
250
 
229
251
  def run(
230
252
  self,
@@ -233,7 +255,7 @@ class LocalHost(Host):
233
255
  args: tuple[Any, ...],
234
256
  kwargs: dict[str, Any],
235
257
  ) -> ReturnT:
236
- settings = replace(DEFAULT_SETTINGS, serialization_method="dill")
258
+ settings = replace(DEFAULT_SETTINGS, serialization_method="dill", log_hook=self._log_printer.print)
237
259
  environment = isolate.prepare_environment(
238
260
  **options.environment,
239
261
  context=settings,
@@ -243,7 +265,7 @@ class LocalHost(Host):
243
265
  environment.create(),
244
266
  extra_inheritance_paths=[self._AGENT_ENVIRONMENT.create()],
245
267
  ) as connection:
246
- executable = partial(func, *args, **kwargs)
268
+ executable = _prepare_local_partial_func(func, *args, **kwargs)
247
269
  return connection.run(executable)
248
270
 
249
271
 
@@ -251,9 +273,6 @@ FAL_SERVERLESS_DEFAULT_URL = flags.GRPC_HOST
251
273
  FAL_SERVERLESS_DEFAULT_MACHINE_TYPE = "XS"
252
274
 
253
275
 
254
- import threading
255
-
256
-
257
276
  def _handle_grpc_error():
258
277
  def decorator(fn):
259
278
  @wraps(fn)
@@ -403,7 +422,7 @@ class FalServerlessHost(Host):
403
422
  min_concurrency=min_concurrency,
404
423
  )
405
424
 
406
- partial_func = _prepare_partial_func(func)
425
+ partial_func = _prepare_remote_partial_func(func)
407
426
 
408
427
  if metadata is None:
409
428
  metadata = {}
@@ -473,7 +492,7 @@ class FalServerlessHost(Host):
473
492
  return_value = _UNSET
474
493
  # Allow isolate provided arguments (such as setup function) to take
475
494
  # precedence over the ones provided by the user.
476
- partial_func = _prepare_partial_func(func, *args, **kwargs)
495
+ partial_func = _prepare_remote_partial_func(func, *args, **kwargs)
477
496
  for partial_result in self._connection.run(
478
497
  partial_func,
479
498
  environments,
@@ -39,7 +39,7 @@ def wrap_app(cls: type[App], **kwargs) -> fal.api.IsolatedFunction:
39
39
  try:
40
40
  app = cls(_allow_init=True)
41
41
  metadata["openapi"] = app.openapi()
42
- except Exception as exc:
42
+ except Exception:
43
43
  logger.warning("Failed to build OpenAPI specification for %s", cls.__name__)
44
44
  realtime_app = False
45
45
  else:
@@ -64,7 +64,7 @@ def _fetch_access_token() -> str:
64
64
  try:
65
65
  auth0.verify_access_token_expiration(access_token)
66
66
  return access_token
67
- except:
67
+ except Exception:
68
68
  # access_token expired, will refresh
69
69
  pass
70
70
 
@@ -113,7 +113,6 @@ class MainGroup(RichGroup):
113
113
 
114
114
  if aliases:
115
115
  # Add aliases to the help text
116
- aliases_str = "Alias: " + ", ".join([name, *aliases])
117
116
  cmd.help = (cmd.help or "") + "\n\nAlias: " + ", ".join([name, *aliases])
118
117
  cmd.short_help = (
119
118
  (cmd.short_help or "") + "(Alias: " + ", ".join(aliases) + ")"
@@ -603,7 +602,7 @@ def _get_user_id() -> str:
603
602
  if user_details_response.status_code != HTTPStatus.OK:
604
603
  try:
605
604
  content = json.loads(user_details_response.content.decode("utf8"))
606
- except:
605
+ except Exception:
607
606
  raise api.FalServerlessError(
608
607
  f"Error fetching user details: {user_details_response}"
609
608
  )
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import sys
3
4
  from datetime import datetime, timezone
4
5
 
5
- from isolate.logs import Log, LogLevel
6
+ from isolate.logs import Log, LogLevel, LogSource
6
7
  from structlog.dev import ConsoleRenderer
7
8
  from structlog.typing import EventDict
8
9
 
@@ -21,6 +22,12 @@ class IsolateLogPrinter:
21
22
  def print(self, log: Log):
22
23
  if log.level < LogLevel.INFO and not self.debug:
23
24
  return
25
+
26
+ if log.source == LogSource.USER:
27
+ stream = sys.stderr if log.level == LogLevel.STDERR else sys.stdout
28
+ print(log.message, file=stream)
29
+ return
30
+
24
31
  level = str(log.level)
25
32
 
26
33
  if hasattr(log, "timestamp"):
@@ -44,21 +51,3 @@ class IsolateLogPrinter:
44
51
  # Use structlog processors to get consistent output with local logs
45
52
  message = _renderer.__call__(logger={}, name=level, event_dict=event)
46
53
  print(message)
47
-
48
- def print_dict(self, log: dict):
49
- level = LogLevel[log["level"]]
50
- if level < LogLevel.INFO and not self.debug:
51
- return
52
- if "timestamp" in log.keys():
53
- timestamp = log["timestamp"]
54
- else:
55
- timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S.%f")
56
-
57
- event: EventDict = {
58
- "event": log["message"],
59
- "level": log["level"],
60
- "timestamp": timestamp[:-3],
61
- }
62
-
63
- message = _renderer.__call__(logger={}, name=log["level"], event_dict=event)
64
- print(message)
@@ -12,7 +12,7 @@ def add_user_id(
12
12
  user_id: str | None = None
13
13
  try:
14
14
  user_id = USER.info.get("sub")
15
- except:
15
+ except Exception:
16
16
  # logs are fail-safe, so any exception is safe to ignore
17
17
  # this is expected to happen only when user is logged out
18
18
  # or there's no internet connection
@@ -14,7 +14,7 @@ from isolate.server.interface import from_grpc, to_serialized_object, to_struct
14
14
 
15
15
  import isolate_proto
16
16
  from fal import flags
17
- from fal._serialization import patch_dill
17
+ from fal._serialization import patch_dill, patch_pickle
18
18
  from fal.auth import USER, key_credentials
19
19
  from fal.logging import get_logger
20
20
  from fal.logging.trace import TraceContextInterceptor
@@ -32,6 +32,7 @@ FAL_SERVERLESS_DEFAULT_MIN_CONCURRENCY = 0
32
32
  logger = get_logger(__name__)
33
33
 
34
34
  patch_dill()
35
+ patch_pickle()
35
36
 
36
37
 
37
38
  class ServerCredentials:
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- from .file import *
3
+ from .file import * # noqa: F403
@@ -94,7 +94,7 @@ class File(BaseModel):
94
94
  if isinstance(value, str):
95
95
  parsed_url = urlparse(value)
96
96
  if parsed_url.scheme not in ["http", "https", "data"]:
97
- raise ValueError(f"value must be a valid URL")
97
+ raise ValueError("value must be a valid URL")
98
98
  return cls._from_url(parsed_url.geturl())
99
99
 
100
100
  return value
@@ -12,7 +12,7 @@ from fal.toolkit.exceptions import FileUploadException
12
12
  from fal.toolkit.file.types import FileData, FileRepository
13
13
  from fal.toolkit.mainify import mainify
14
14
 
15
- _FAL_CDN = "https://fal-cdn.batuhan-941.workers.dev"
15
+ _FAL_CDN = "https://fal.media"
16
16
 
17
17
 
18
18
  @mainify
@@ -27,7 +27,7 @@ class FalFileRepository(FileRepository):
27
27
  headers = {
28
28
  "Authorization": f"Key {key_id}:{key_secret}",
29
29
  "Accept": "application/json",
30
- "Content-Type": f"application/json",
30
+ "Content-Type": "application/json",
31
31
  }
32
32
 
33
33
  grpc_host = os.environ.get("FAL_HOST", "api.alpha.fal.ai")
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- from .image import *
3
+ from .image import * # noqa: F403
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import io
4
4
  from tempfile import NamedTemporaryFile
5
- from typing import TYPE_CHECKING, Literal, Optional, Union
5
+ from typing import TYPE_CHECKING, Literal, Union, Optional
6
6
 
7
7
  from pydantic import BaseModel, Field
8
8
 
@@ -41,7 +41,7 @@ def optimize(
41
41
  module,
42
42
  optimization_config=optimization_config,
43
43
  )
44
- except Exception as e:
44
+ except Exception:
45
45
  print(
46
46
  "[WARNING] Failed to optimize module, falling back "
47
47
  "to default torch execution."
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+
3
+ from fal.toolkit.utils.download_utils import * # noqa: F403
@@ -42,7 +42,7 @@ def _hash_url(url: str) -> str:
42
42
 
43
43
 
44
44
  @mainify
45
- @lru_cache()
45
+ @lru_cache
46
46
  def _get_remote_file_properties(url: str) -> tuple[str, int]:
47
47
  """Retrieves the file name and content length of a remote file.
48
48
 
@@ -471,7 +471,7 @@ def main() -> None:
471
471
  context.vars[node_id] = node.execute(context)
472
472
 
473
473
  console.print(
474
- f"🎉 Execution complete!",
474
+ "🎉 Execution complete!",
475
475
  style="bold green",
476
476
  )
477
477
  output = context.hydrate(workflow.output)
@@ -1,3 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from fal.toolkit.utils.download_utils import *
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes