fal 0.13.0__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.
- {fal-0.13.0 → fal-0.14.0}/PKG-INFO +1 -1
- {fal-0.13.0 → fal-0.14.0}/pyproject.toml +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/__init__.py +4 -4
- {fal-0.13.0 → fal-0.14.0}/src/fal/_serialization.py +27 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/api.py +31 -12
- {fal-0.13.0 → fal-0.14.0}/src/fal/app.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/auth/__init__.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/cli.py +1 -2
- {fal-0.13.0 → fal-0.14.0}/src/fal/logging/isolate.py +8 -19
- {fal-0.13.0 → fal-0.14.0}/src/fal/logging/user.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/sdk.py +2 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/file/__init__.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/file/file.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/file/providers/fal.py +2 -2
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/image/__init__.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/image/image.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/optimize.py +1 -1
- fal-0.14.0/src/fal/toolkit/utils/__init__.py +3 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/utils/download_utils.py +1 -1
- {fal-0.13.0 → fal-0.14.0}/src/fal/workflows.py +1 -1
- fal-0.13.0/src/fal/toolkit/utils/__init__.py +0 -3
- {fal-0.13.0 → fal-0.14.0}/README.md +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/applications/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/billing/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/billing/get_user_details.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/files/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/files/check_dir_hash.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/files/upload_local_file.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/create_or_update_workflow_workflows_post.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/delete_workflow_workflows_user_id_workflow_name_delete.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/execute_workflow_workflows_user_id_workflow_name_post.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflow_workflows_user_id_workflow_name_get.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/workflows/get_workflows_workflows_get.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/client.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/errors.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/app_metadata_response_app_metadata.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/customer_details.py +0 -0
- {fal-0.13.0 → 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
- {fal-0.13.0 → 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
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/hash_check.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/http_validation_error.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/lock_reason.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/page_workflow_item.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/typed_workflow.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/validation_error.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_detail_contents_type_0.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_item.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_node_type.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_input.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/py.typed +0 -0
- {fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/types.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/__main__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/apps.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/auth/auth0.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/auth/local.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/console/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/console/icons.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/console/ux.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/env.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/exceptions/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/exceptions/_base.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/exceptions/auth.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/exceptions/handlers.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/flags.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/logging/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/logging/style.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/logging/trace.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/py.typed +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/rest_client.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/sync.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/__init__.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/exceptions.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/file/providers/gcp.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/file/providers/r2.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/file/types.py +0 -0
- {fal-0.13.0 → fal-0.14.0}/src/fal/toolkit/mainify.py +0 -0
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
42
|
+
except Exception:
|
|
43
43
|
logger.warning("Failed to build OpenAPI specification for %s", cls.__name__)
|
|
44
44
|
realtime_app = False
|
|
45
45
|
else:
|
|
@@ -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:
|
|
@@ -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(
|
|
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
|
|
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":
|
|
30
|
+
"Content-Type": "application/json",
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
grpc_host = os.environ.get("FAL_HOST", "api.alpha.fal.ai")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/api/applications/app_metadata.py
RENAMED
|
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
|
{fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/body_upload_local_file.py
RENAMED
|
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
|
{fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_nodes.py
RENAMED
|
File without changes
|
{fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_contents_output.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fal-0.13.0 → fal-0.14.0}/openapi-fal-rest/openapi_fal_rest/models/workflow_schema_output.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|