fal 1.9.2__py3-none-any.whl → 1.9.3__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 fal might be problematic. Click here for more details.

fal/_fal_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.9.2'
21
- __version_tuple__ = version_tuple = (1, 9, 2)
20
+ __version__ = version = '1.9.3'
21
+ __version_tuple__ = version_tuple = (1, 9, 3)
fal/api.py CHANGED
@@ -78,6 +78,7 @@ SERVE_REQUIREMENTS = [
78
78
  "starlette_exporter",
79
79
  "structlog",
80
80
  "tomli",
81
+ "tomli-w",
81
82
  ]
82
83
 
83
84
 
fal/app.py CHANGED
@@ -9,7 +9,7 @@ import re
9
9
  import threading
10
10
  import time
11
11
  import typing
12
- from contextlib import AsyncExitStack, asynccontextmanager, contextmanager
12
+ from contextlib import asynccontextmanager, contextmanager
13
13
  from dataclasses import dataclass
14
14
  from typing import Any, Callable, ClassVar, Literal, TypeVar
15
15
 
@@ -40,27 +40,26 @@ async def _call_any_fn(fn, *args, **kwargs):
40
40
  return fn(*args, **kwargs)
41
41
 
42
42
 
43
- async def open_isolate_channel(address: str) -> async_grpc.Channel:
44
- _stack = AsyncExitStack()
45
- channel = await _stack.enter_async_context(
46
- async_grpc.insecure_channel(
47
- address,
48
- options=[
49
- ("grpc.max_send_message_length", -1),
50
- ("grpc.max_receive_message_length", -1),
51
- ("grpc.min_reconnect_backoff_ms", 0),
52
- ("grpc.max_reconnect_backoff_ms", 100),
53
- ("grpc.dns_min_time_between_resolutions_ms", 100),
54
- ],
55
- )
43
+ async def open_isolate_channel(address: str) -> async_grpc.Channel | None:
44
+ channel = async_grpc.insecure_channel(
45
+ address,
46
+ options=[
47
+ ("grpc.max_send_message_length", -1),
48
+ ("grpc.max_receive_message_length", -1),
49
+ ("grpc.min_reconnect_backoff_ms", 0),
50
+ ("grpc.max_reconnect_backoff_ms", 100),
51
+ ("grpc.dns_min_time_between_resolutions_ms", 100),
52
+ ],
56
53
  )
57
54
 
58
- channel_status = channel.channel_ready()
59
55
  try:
56
+ channel_status = channel.channel_ready()
57
+
60
58
  await asyncio.wait_for(channel_status, timeout=1)
61
59
  except asyncio.TimeoutError:
62
- await _stack.aclose()
63
- raise Exception("Timed out trying to connect to local isolate")
60
+ await channel.close(None)
61
+ print("[DEBUG] Timed out trying to connect to local isolate")
62
+ return None
64
63
 
65
64
  return channel
66
65
 
@@ -390,9 +389,11 @@ class App(fal.api.BaseServable):
390
389
  f"localhost:{grpc_port}"
391
390
  )
392
391
 
392
+ if self.isolate_channel is None:
393
+ return await call_next(request)
394
+
393
395
  request_id = request.headers.get(REQUEST_ID_KEY)
394
396
  if request_id is None:
395
- # Cut it short
396
397
  return await call_next(request)
397
398
 
398
399
  await _set_logger_labels(
fal/cli/apps.py CHANGED
@@ -22,7 +22,8 @@ def _apps_table(apps: list[AliasInfo]):
22
22
  table.add_column("Request Timeout")
23
23
  table.add_column("Startup Timeout")
24
24
  table.add_column("Machine Type")
25
- table.add_column("Active Workers")
25
+ table.add_column("Runners")
26
+ table.add_column("Regions")
26
27
 
27
28
  for app in apps:
28
29
  table.add_row(
@@ -37,6 +38,7 @@ def _apps_table(apps: list[AliasInfo]):
37
38
  str(app.startup_timeout),
38
39
  " ".join(app.machine_types),
39
40
  str(app.active_runners),
41
+ " ".join(app.valid_regions),
40
42
  )
41
43
 
42
44
  return table
@@ -76,7 +78,8 @@ def _app_rev_table(revs: list[ApplicationInfo]):
76
78
  table.add_column("Request Timeout")
77
79
  table.add_column("Startup Timeout")
78
80
  table.add_column("Machine Type")
79
- table.add_column("Active Workers")
81
+ table.add_column("Runners")
82
+ table.add_column("Regions")
80
83
 
81
84
  for rev in revs:
82
85
  table.add_row(
@@ -89,6 +92,7 @@ def _app_rev_table(revs: list[ApplicationInfo]):
89
92
  str(rev.startup_timeout),
90
93
  " ".join(rev.machine_types),
91
94
  str(rev.active_runners),
95
+ " ".join(rev.valid_regions),
92
96
  )
93
97
 
94
98
  return table
@@ -129,6 +133,7 @@ def _scale(args):
129
133
  and args.request_timeout is None
130
134
  and args.startup_timeout is None
131
135
  and args.machine_types is None
136
+ and args.regions is None
132
137
  ):
133
138
  args.console.log("No parameters for update were provided, ignoring.")
134
139
  return
@@ -142,6 +147,7 @@ def _scale(args):
142
147
  request_timeout=args.request_timeout,
143
148
  startup_timeout=args.startup_timeout,
144
149
  machine_types=args.machine_types,
150
+ valid_regions=args.regions,
145
151
  )
146
152
  table = _apps_table([alias_info])
147
153
 
@@ -191,11 +197,16 @@ def _add_scale_parser(subparsers, parents):
191
197
  help="Startup timeout (seconds).",
192
198
  )
193
199
  parser.add_argument(
194
- "--machine-type",
200
+ "--machine-types",
195
201
  type=str,
196
- action="append",
202
+ nargs="+",
197
203
  dest="machine_types",
198
- help="Machine type.",
204
+ help="Machine types (pass several items to set multiple).",
205
+ )
206
+ parser.add_argument(
207
+ "--regions",
208
+ nargs="+",
209
+ help="Valid regions (pass several items to set multiple).",
199
210
  )
200
211
  parser.set_defaults(func=_scale)
201
212
 
@@ -262,6 +273,7 @@ def _runners(args):
262
273
  f"{runner.uptime} ({runner.uptime.total_seconds()}s)",
263
274
  )
264
275
 
276
+ args.console.print(f"Runners: {len(runners)}")
265
277
  args.console.print(table)
266
278
 
267
279
  requests_table = Table()
@@ -280,6 +292,7 @@ def _runners(args):
280
292
  lease.get("caller_user_id") or "",
281
293
  )
282
294
 
295
+ args.console.print(f"Requests: {len(requests_table.rows)}")
283
296
  args.console.print(requests_table)
284
297
 
285
298
 
fal/cli/main.py CHANGED
@@ -6,7 +6,7 @@ from fal import __version__
6
6
  from fal.console import console
7
7
  from fal.console.icons import CROSS_ICON
8
8
 
9
- from . import apps, auth, create, deploy, doctor, keys, run, runners, secrets
9
+ from . import apps, auth, create, deploy, doctor, keys, profile, run, runners, secrets
10
10
  from .debug import debugtools, get_debug_parser
11
11
  from .parser import FalParser, FalParserExit
12
12
 
@@ -31,7 +31,18 @@ def _get_main_parser() -> argparse.ArgumentParser:
31
31
  required=True,
32
32
  )
33
33
 
34
- for cmd in [auth, apps, deploy, run, keys, secrets, doctor, create, runners]:
34
+ for cmd in [
35
+ auth,
36
+ apps,
37
+ deploy,
38
+ run,
39
+ keys,
40
+ profile,
41
+ secrets,
42
+ doctor,
43
+ create,
44
+ runners,
45
+ ]:
35
46
  cmd.add_parser(subparsers, parents)
36
47
 
37
48
  return parser
fal/cli/profile.py ADDED
@@ -0,0 +1,129 @@
1
+ from rich.table import Table
2
+
3
+ from fal.config import Config
4
+
5
+
6
+ def _list(args):
7
+ config = Config()
8
+
9
+ table = Table()
10
+ table.add_column("Default")
11
+ table.add_column("Profile")
12
+ table.add_column("Settings")
13
+
14
+ for profile in config.profiles():
15
+ table.add_row(
16
+ "*" if profile == config._profile else "",
17
+ profile,
18
+ ", ".join(key for key in config._config[profile]),
19
+ )
20
+
21
+ args.console.print(table)
22
+
23
+
24
+ def _set(args):
25
+ config = Config()
26
+ config.set_internal("profile", args.PROFILE)
27
+ args.console.print(f"Default profile set to [cyan]{args.PROFILE}[/].")
28
+ config.profile = args.PROFILE
29
+ config.save()
30
+
31
+
32
+ def _unset(args):
33
+ config = Config()
34
+ config.set_internal("profile", None)
35
+ args.console.print("Default profile unset.")
36
+ config.profile = None
37
+ config.save()
38
+
39
+
40
+ def _key_set(args):
41
+ config = Config()
42
+ key_id, key_secret = args.KEY.split(":", 1)
43
+ config.set("key", f"{key_id}:{key_secret}")
44
+ args.console.print(f"Key set for profile [cyan]{config.profile}[/].")
45
+ config.save()
46
+
47
+
48
+ def _delete(args):
49
+ config = Config()
50
+ if config.profile == args.PROFILE:
51
+ config.set_internal("profile", None)
52
+
53
+ config.delete(args.PROFILE)
54
+ args.console.print(f"Profile [cyan]{args.PROFILE}[/] deleted.")
55
+ config.save()
56
+
57
+
58
+ def add_parser(main_subparsers, parents):
59
+ auth_help = "Profile management."
60
+ parser = main_subparsers.add_parser(
61
+ "profile",
62
+ description=auth_help,
63
+ help=auth_help,
64
+ parents=parents,
65
+ )
66
+
67
+ subparsers = parser.add_subparsers(
68
+ title="Commands",
69
+ metavar="command",
70
+ dest="cmd",
71
+ required=True,
72
+ )
73
+
74
+ list_help = "List all profiles."
75
+ list_parser = subparsers.add_parser(
76
+ "list",
77
+ description=list_help,
78
+ help=list_help,
79
+ parents=parents,
80
+ )
81
+ list_parser.set_defaults(func=_list)
82
+
83
+ set_help = "Set default profile."
84
+ set_parser = subparsers.add_parser(
85
+ "set",
86
+ description=set_help,
87
+ help=set_help,
88
+ parents=parents,
89
+ )
90
+ set_parser.add_argument(
91
+ "PROFILE",
92
+ help="Profile name.",
93
+ )
94
+ set_parser.set_defaults(func=_set)
95
+
96
+ unset_help = "Unset default profile."
97
+ unset_parser = subparsers.add_parser(
98
+ "unset",
99
+ description=unset_help,
100
+ help=unset_help,
101
+ parents=parents,
102
+ )
103
+ unset_parser.set_defaults(func=_unset)
104
+
105
+ key_set_help = "Set key for profile."
106
+ key_set_parser = subparsers.add_parser(
107
+ "key",
108
+ description=key_set_help,
109
+ help=key_set_help,
110
+ parents=parents,
111
+ )
112
+ key_set_parser.add_argument(
113
+ "KEY",
114
+ help="Key ID and secret separated by a colon.",
115
+ )
116
+ key_set_parser.set_defaults(func=_key_set)
117
+
118
+ delete_help = "Delete profile."
119
+ delete_parser = subparsers.add_parser(
120
+ "delete",
121
+ description=delete_help,
122
+ help=delete_help,
123
+ parents=parents,
124
+ )
125
+ delete_parser.add_argument(
126
+ "PROFILE",
127
+ help="Profile name.",
128
+ )
129
+ delete_parser.set_defaults(func=_delete)
fal/config.py CHANGED
@@ -1,23 +1,85 @@
1
1
  import os
2
+ from typing import Dict, List, Optional
2
3
 
3
- import tomli
4
+ SETTINGS_SECTION = "__internal__"
4
5
 
5
6
 
6
7
  class Config:
8
+ _config: Dict[str, Dict[str, str]]
9
+ _profile: Optional[str]
10
+
7
11
  DEFAULT_CONFIG_PATH = "~/.fal/config.toml"
8
- DEFAULT_PROFILE = "default"
9
12
 
10
13
  def __init__(self):
14
+ import tomli
15
+
11
16
  self.config_path = os.path.expanduser(
12
17
  os.getenv("FAL_CONFIG_PATH", self.DEFAULT_CONFIG_PATH)
13
18
  )
14
- self.profile = os.getenv("FAL_PROFILE", self.DEFAULT_PROFILE)
15
19
 
16
20
  try:
17
21
  with open(self.config_path, "rb") as file:
18
- self.config = tomli.load(file)
22
+ self._config = tomli.load(file)
19
23
  except FileNotFoundError:
20
- self.config = {}
24
+ self._config = {}
25
+
26
+ profile = os.getenv("FAL_PROFILE")
27
+ if not profile:
28
+ profile = self.get_internal("profile")
29
+
30
+ self.profile = profile
31
+
32
+ @property
33
+ def profile(self) -> Optional[str]:
34
+ return self._profile
35
+
36
+ @profile.setter
37
+ def profile(self, value: Optional[str]) -> None:
38
+ if value and value not in self._config:
39
+ self._config[value] = {}
40
+
41
+ self._profile = value
42
+
43
+ def profiles(self) -> List[str]:
44
+ keys = []
45
+ for key in self._config:
46
+ if key != SETTINGS_SECTION:
47
+ keys.append(key)
48
+
49
+ return keys
50
+
51
+ def save(self) -> None:
52
+ import tomli_w
53
+
54
+ with open(self.config_path, "wb") as file:
55
+ tomli_w.dump(self._config, file)
56
+
57
+ def get(self, key: str) -> Optional[str]:
58
+ if not self.profile:
59
+ return None
60
+
61
+ return self._config.get(self.profile, {}).get(key)
62
+
63
+ def set(self, key: str, value: str) -> None:
64
+ if not self.profile:
65
+ raise ValueError("No profile set.")
66
+
67
+ self._config[self.profile][key] = value
68
+
69
+ def get_internal(self, key: str) -> Optional[str]:
70
+ if SETTINGS_SECTION not in self._config:
71
+ self._config[SETTINGS_SECTION] = {}
72
+
73
+ return self._config[SETTINGS_SECTION].get(key)
74
+
75
+ def set_internal(self, key: str, value: Optional[str]) -> None:
76
+ if SETTINGS_SECTION not in self._config:
77
+ self._config[SETTINGS_SECTION] = {}
78
+
79
+ if value is None:
80
+ del self._config[SETTINGS_SECTION][key]
81
+ else:
82
+ self._config[SETTINGS_SECTION][key] = value
21
83
 
22
- def get(self, key):
23
- return self.config.get(self.profile, {}).get(key)
84
+ def delete(self, profile: str) -> None:
85
+ del self._config[profile]
fal/sdk.py CHANGED
@@ -200,6 +200,7 @@ class ApplicationInfo:
200
200
  machine_types: list[str]
201
201
  request_timeout: int
202
202
  startup_timeout: int
203
+ valid_regions: list[str]
203
204
 
204
205
 
205
206
  @dataclass
@@ -215,6 +216,7 @@ class AliasInfo:
215
216
  machine_types: list[str]
216
217
  request_timeout: int
217
218
  startup_timeout: int
219
+ valid_regions: list[str]
218
220
 
219
221
 
220
222
  @dataclass
@@ -321,9 +323,10 @@ def _from_grpc_application_info(
321
323
  max_multiplexing=message.max_multiplexing,
322
324
  active_runners=message.active_runners,
323
325
  min_concurrency=message.min_concurrency,
324
- machine_types=message.machine_types,
326
+ machine_types=list(message.machine_types),
325
327
  request_timeout=message.request_timeout,
326
328
  startup_timeout=message.startup_timeout,
329
+ valid_regions=list(message.valid_regions),
327
330
  )
328
331
 
329
332
 
@@ -347,9 +350,10 @@ def _from_grpc_alias_info(message: isolate_proto.AliasInfo) -> AliasInfo:
347
350
  max_multiplexing=message.max_multiplexing,
348
351
  active_runners=message.active_runners,
349
352
  min_concurrency=message.min_concurrency,
350
- machine_types=message.machine_types,
353
+ machine_types=list(message.machine_types),
351
354
  request_timeout=message.request_timeout,
352
355
  startup_timeout=message.startup_timeout,
356
+ valid_regions=list(message.valid_regions),
353
357
  )
354
358
 
355
359
 
@@ -359,9 +363,11 @@ def _from_grpc_runner_info(message: isolate_proto.RunnerInfo) -> RunnerInfo:
359
363
  return RunnerInfo(
360
364
  runner_id=message.runner_id,
361
365
  in_flight_requests=message.in_flight_requests,
362
- expiration_countdown=message.expiration_countdown
363
- if message.HasField("expiration_countdown")
364
- else None,
366
+ expiration_countdown=(
367
+ message.expiration_countdown
368
+ if message.HasField("expiration_countdown")
369
+ else None
370
+ ),
365
371
  uptime=timedelta(seconds=message.uptime),
366
372
  external_metadata=external_metadata,
367
373
  )
@@ -582,9 +588,9 @@ class FalServerlessConnection:
582
588
  min_concurrency: int | None = None,
583
589
  request_timeout: int | None = None,
584
590
  startup_timeout: int | None = None,
591
+ valid_regions: list[str] | None = None,
585
592
  machine_types: list[str] | None = None,
586
593
  ) -> AliasInfo:
587
- print(machine_types)
588
594
  request = isolate_proto.UpdateApplicationRequest(
589
595
  application_name=application_name,
590
596
  keep_alive=keep_alive,
@@ -593,6 +599,7 @@ class FalServerlessConnection:
593
599
  min_concurrency=min_concurrency,
594
600
  request_timeout=request_timeout,
595
601
  startup_timeout=startup_timeout,
602
+ valid_regions=valid_regions,
596
603
  machine_types=machine_types,
597
604
  )
598
605
  res: isolate_proto.UpdateApplicationResult = self.stub.UpdateApplication(
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: fal
3
- Version: 1.9.2
3
+ Version: 1.9.3
4
4
  Summary: fal is an easy-to-use Serverless Python Framework
5
5
  Author: Features & Labels <support@fal.ai>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: isolate[build]<0.17.0,>=0.16.1
9
- Requires-Dist: isolate-proto<0.7.0,>=0.6.6
9
+ Requires-Dist: isolate-proto<0.7.0,>=0.6.7
10
10
  Requires-Dist: grpcio==1.64.0
11
11
  Requires-Dist: dill==0.3.7
12
12
  Requires-Dist: cloudpickle==3.0.0
@@ -37,7 +37,8 @@ Requires-Dist: pillow<11,>=10.2.0
37
37
  Requires-Dist: pyjwt[crypto]<3,>=2.8.0
38
38
  Requires-Dist: uvicorn<1,>=0.29.0
39
39
  Requires-Dist: cookiecutter
40
- Requires-Dist: tomli
40
+ Requires-Dist: tomli<3,>2
41
+ Requires-Dist: tomli-w<2,>=1
41
42
  Provides-Extra: docs
42
43
  Requires-Dist: sphinx<8.2.0; extra == "docs"
43
44
  Requires-Dist: sphinx-rtd-theme; extra == "docs"
@@ -1,18 +1,18 @@
1
1
  fal/__init__.py,sha256=wXs1G0gSc7ZK60-bHe-B2m0l_sA6TrFk4BxY0tMoLe8,784
2
2
  fal/__main__.py,sha256=4JMK66Wj4uLZTKbF-sT3LAxOsr6buig77PmOkJCRRxw,83
3
- fal/_fal_version.py,sha256=Bx58trLhK_vl5EzDfK18POHZa_BoHwqv52T5hR9tbaA,511
3
+ fal/_fal_version.py,sha256=9iRyJjXIu4ospHHgY6jThnBbx_i0E46WrhiFzzJdLrE,511
4
4
  fal/_serialization.py,sha256=rD2YiSa8iuzCaZohZwN_MPEB-PpSKbWRDeaIDpTEjyY,7653
5
5
  fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
6
- fal/api.py,sha256=ZbUoe12y6sVg5-bPbzFtqHTqZoQonVDaZRjlGNaHbcs,43983
7
- fal/app.py,sha256=hk3rT-3fZY7jsgK270JPC26Wnc2GhhtrDcjRCUQRr6Q,23341
6
+ fal/api.py,sha256=i6HnL4sJtwv34N9T5uzXSgwetBLMVJye57CHmdq5m78,43998
7
+ fal/app.py,sha256=3WhjRgJdJ2ajAeZ3IeFb20_Zm6EH19a_WIuDtanaMHE,23308
8
8
  fal/apps.py,sha256=RpmElElJnDYjsTRQOdNYiJwd74GEOGYA38L5O5GzNEg,11068
9
- fal/config.py,sha256=hgI3kW4_2NoFsrYEiPss0mnDTr8_Td2z0pVgm93wi9o,600
9
+ fal/config.py,sha256=aVv0k2fxMZurlra4c7ZIKQQCNPI-Dm_Mns6PsYWdh-c,2264
10
10
  fal/container.py,sha256=9XslBET-NCG2V3-Wmof8c7eHrRoxCye88Ym7CskqCk0,1639
11
11
  fal/files.py,sha256=QgfYfMKmNobMPufrAP_ga1FKcIAlSbw18Iar1-0qepo,2650
12
12
  fal/flags.py,sha256=oWN_eidSUOcE9wdPK_77si3A1fpgOC0UEERPsvNLIMc,842
13
13
  fal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  fal/rest_client.py,sha256=kGBGmuyHfX1lR910EoKCYPjsyU8MdXawT_cW2q8Sajc,568
15
- fal/sdk.py,sha256=Pjj9RZ6unEUnrj9JwDq6K4dzNoG9e0wYLwcNAbblnWw,23712
15
+ fal/sdk.py,sha256=SRJ4zp0TAvHmfGPsMtYUoMPaw9yj-qKY1RkzqCcZxWo,23976
16
16
  fal/sync.py,sha256=ZuIJA2-hTPNANG9B_NNJZUsO68EIdTH0dc9MzeVE2VU,4340
17
17
  fal/utils.py,sha256=9q_QrQBlQN3nZYA1kEGRfhJWi4RjnO4H1uQswfaei9w,2146
18
18
  fal/workflows.py,sha256=Zl4f6Bs085hY40zmqScxDUyCu7zXkukDbW02iYOLTTI,14805
@@ -21,15 +21,16 @@ fal/auth/auth0.py,sha256=rSG1mgH-QGyKfzd7XyAaj1AYsWt-ho8Y_LZ-FUVWzh4,5421
21
21
  fal/auth/local.py,sha256=sndkM6vKpeVny6NHTacVlTbiIFqaksOmw0Viqs_RN1U,1790
22
22
  fal/cli/__init__.py,sha256=padK4o0BFqq61kxAA1qQ0jYr2SuhA2mf90B3AaRkmJA,37
23
23
  fal/cli/_utils.py,sha256=45G0LEz2bW-69MUQKPdatVE_CBC2644gC-V0qdNEsco,1252
24
- fal/cli/apps.py,sha256=fsDL9mypSEME-6UxN1S1vIu-e0ij6tEBfk-7PDRVG5A,9862
24
+ fal/cli/apps.py,sha256=KVi_sZQPvznrTtbOHnkbTGH9KUjYqp_b-uXLvFyjKgY,10358
25
25
  fal/cli/auth.py,sha256=--MhfHGwxmtHbRkGioyn1prKn_U-pBzbz0G_QeZou-U,1352
26
26
  fal/cli/create.py,sha256=a8WDq-nJLFTeoIXqpb5cr7GR7YR9ZZrQCawNm34KXXE,627
27
27
  fal/cli/debug.py,sha256=u_urnyFzSlNnrq93zz_GXE9FX4VyVxDoamJJyrZpFI0,1312
28
28
  fal/cli/deploy.py,sha256=Wu8wxR72od2GAp1OF-FYO6WSWt4umaHysL3HrO_bzEo,7764
29
29
  fal/cli/doctor.py,sha256=U4ne9LX5gQwNblsYQ27XdO8AYDgbYjTO39EtxhwexRM,983
30
30
  fal/cli/keys.py,sha256=trDpA3LJu9S27qE_K8Hr6fKLK4vwVzbxUHq8TFrV4pw,3157
31
- fal/cli/main.py,sha256=O0i9wdLPxcd1u4CvXit-ufkT_UnON-baTN6v9HaHPmw,2027
31
+ fal/cli/main.py,sha256=EPqG-Pp71RKkPUHv5QSb8_gWQ1DT8-OdUDNSN1h-TSk,2132
32
32
  fal/cli/parser.py,sha256=edCqFWYAQSOhrxeEK9BtFRlTEUAlG2JUDjS_vhZ_nHE,2868
33
+ fal/cli/profile.py,sha256=16uwIHlWLa8G89GDaEUQ9-Y9ao7YQCtjLhGrkh94M_k,3129
33
34
  fal/cli/run.py,sha256=nAC12Qss4Fg1XmV0qOS9RdGNLYcdoHeRgQMvbTN4P9I,1202
34
35
  fal/cli/runners.py,sha256=5pXuKq7nSkf0VpnppNnvxwP8XDq0SWkc6mkfizDwWMQ,1046
35
36
  fal/cli/secrets.py,sha256=740msFm7d41HruudlcfqUXlFl53N-WmChsQP9B9M9Po,2572
@@ -130,8 +131,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
130
131
  openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
131
132
  openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
132
133
  openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
133
- fal-1.9.2.dist-info/METADATA,sha256=LfRaoFY5K14zwiBWrcTM4GgD2bMUFsLlDWk8sGOtU-A,4008
134
- fal-1.9.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
135
- fal-1.9.2.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
136
- fal-1.9.2.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
137
- fal-1.9.2.dist-info/RECORD,,
134
+ fal-1.9.3.dist-info/METADATA,sha256=5y7_V3EqnNBq7z7JTsctaIxwmSV8baUclYoqTh2Cb8U,4042
135
+ fal-1.9.3.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
136
+ fal-1.9.3.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
137
+ fal-1.9.3.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
138
+ fal-1.9.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5