fal 1.37.0__py3-none-any.whl → 1.38.0__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 +2 -2
- fal/cli/apps.py +27 -2
- fal/cli/parser.py +57 -0
- fal/cli/runners.py +41 -5
- fal/sdk.py +23 -4
- {fal-1.37.0.dist-info → fal-1.38.0.dist-info}/METADATA +4 -2
- {fal-1.37.0.dist-info → fal-1.38.0.dist-info}/RECORD +10 -10
- {fal-1.37.0.dist-info → fal-1.38.0.dist-info}/WHEEL +0 -0
- {fal-1.37.0.dist-info → fal-1.38.0.dist-info}/entry_points.txt +0 -0
- {fal-1.37.0.dist-info → fal-1.38.0.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '1.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.38.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 38, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
fal/cli/apps.py
CHANGED
|
@@ -8,7 +8,7 @@ import fal.cli.runners as runners
|
|
|
8
8
|
from fal.sdk import RunnerState
|
|
9
9
|
|
|
10
10
|
from ._utils import get_client
|
|
11
|
-
from .parser import FalClientParser, get_output_parser
|
|
11
|
+
from .parser import FalClientParser, SinceAction, get_output_parser
|
|
12
12
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
14
|
from fal.sdk import AliasInfo, ApplicationInfo
|
|
@@ -291,7 +291,14 @@ def _add_set_rev_parser(subparsers, parents):
|
|
|
291
291
|
def _runners(args):
|
|
292
292
|
client = get_client(args.host, args.team)
|
|
293
293
|
with client.connect() as connection:
|
|
294
|
-
|
|
294
|
+
start_time = getattr(args, "since", None)
|
|
295
|
+
alias_runners = connection.list_alias_runners(
|
|
296
|
+
alias=args.app_name, start_time=start_time
|
|
297
|
+
)
|
|
298
|
+
if getattr(args, "state", None):
|
|
299
|
+
states = set(args.state)
|
|
300
|
+
if "all" not in states:
|
|
301
|
+
alias_runners = [r for r in alias_runners if r.state.value in states]
|
|
295
302
|
if args.output == "pretty":
|
|
296
303
|
runners_table = runners.runners_table(alias_runners)
|
|
297
304
|
pending_runners = [
|
|
@@ -330,6 +337,24 @@ def _add_runners_parser(subparsers, parents):
|
|
|
330
337
|
"app_name",
|
|
331
338
|
help="Application name.",
|
|
332
339
|
)
|
|
340
|
+
parser.add_argument(
|
|
341
|
+
"--since",
|
|
342
|
+
default=None,
|
|
343
|
+
action=SinceAction,
|
|
344
|
+
limit="1 day",
|
|
345
|
+
help=(
|
|
346
|
+
"Show dead runners since the given time. "
|
|
347
|
+
"Accepts 'now', relative like '30m', '1h', '1d', "
|
|
348
|
+
"or an ISO timestamp. Max 24 hours."
|
|
349
|
+
),
|
|
350
|
+
)
|
|
351
|
+
parser.add_argument(
|
|
352
|
+
"--state",
|
|
353
|
+
choices=["all", "running", "pending", "setup", "dead"],
|
|
354
|
+
nargs="+",
|
|
355
|
+
default=None,
|
|
356
|
+
help=("Filter by runner state(s). Choose one or more, or 'all'(default)."),
|
|
357
|
+
)
|
|
333
358
|
parser.set_defaults(func=_runners)
|
|
334
359
|
|
|
335
360
|
|
fal/cli/parser.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import sys
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
|
+
from typing import Optional
|
|
3
5
|
|
|
4
6
|
import rich_argparse
|
|
5
7
|
|
|
@@ -55,6 +57,61 @@ class DictAction(argparse.Action):
|
|
|
55
57
|
setattr(args, self.dest, d)
|
|
56
58
|
|
|
57
59
|
|
|
60
|
+
class SinceAction(argparse.Action):
|
|
61
|
+
LIMIT_LEEWAY = timedelta(minutes=1)
|
|
62
|
+
|
|
63
|
+
def _parse_since(self, value: str) -> Optional[datetime]:
|
|
64
|
+
import dateparser
|
|
65
|
+
|
|
66
|
+
return dateparser.parse(
|
|
67
|
+
value,
|
|
68
|
+
settings={
|
|
69
|
+
"PREFER_DATES_FROM": "past",
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def __init__(self, *args, **kwargs):
|
|
74
|
+
self._limit = kwargs.pop("limit", None)
|
|
75
|
+
if self._limit:
|
|
76
|
+
if not isinstance(self._limit, str):
|
|
77
|
+
raise ValueError(
|
|
78
|
+
f"Invalid 'limit' value for SinceAction: {self._limit!r}"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
self._limit_dt = self._parse_since(self._limit)
|
|
82
|
+
if not self._limit_dt:
|
|
83
|
+
raise ValueError(
|
|
84
|
+
f"Invalid 'limit' value for SinceAction: {self._limit!r}"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
super().__init__(*args, **kwargs)
|
|
88
|
+
|
|
89
|
+
def __call__(self, parser, args, values, option_string=None): # noqa: ARG002
|
|
90
|
+
if values is None:
|
|
91
|
+
setattr(args, self.dest, None)
|
|
92
|
+
return
|
|
93
|
+
|
|
94
|
+
dt = self._parse_since(values)
|
|
95
|
+
if not dt:
|
|
96
|
+
raise argparse.ArgumentError(
|
|
97
|
+
self,
|
|
98
|
+
(
|
|
99
|
+
f"Invalid since value: {values}. "
|
|
100
|
+
"Use 'now', relative like '15m' or '24h ago', "
|
|
101
|
+
"or an ISO timestamp."
|
|
102
|
+
),
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
if self._limit_dt is not None:
|
|
106
|
+
if dt < self._limit_dt - self.LIMIT_LEEWAY:
|
|
107
|
+
raise argparse.ArgumentError(
|
|
108
|
+
self,
|
|
109
|
+
f"Since value is older than the allowed limit {self._limit}.",
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
setattr(args, self.dest, dt)
|
|
113
|
+
|
|
114
|
+
|
|
58
115
|
def _find_parser(parser, func):
|
|
59
116
|
defaults = parser._defaults
|
|
60
117
|
if not func or func == defaults.get("func"):
|
fal/cli/runners.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
from datetime import timedelta
|
|
4
5
|
from typing import List
|
|
5
6
|
|
|
6
7
|
from fal.sdk import RunnerInfo, RunnerState
|
|
7
8
|
|
|
8
9
|
from ._utils import get_client
|
|
9
|
-
from .parser import FalClientParser, get_output_parser
|
|
10
|
+
from .parser import FalClientParser, SinceAction, get_output_parser
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def runners_table(runners: List[RunnerInfo]):
|
|
@@ -42,17 +43,20 @@ def runners_table(runners: List[RunnerInfo]):
|
|
|
42
43
|
# consistent
|
|
43
44
|
in_flight = f"{in_flight} [dim]({missing_leases})[/]"
|
|
44
45
|
|
|
46
|
+
uptime = timedelta(
|
|
47
|
+
seconds=int(runner.uptime.total_seconds()),
|
|
48
|
+
)
|
|
45
49
|
table.add_row(
|
|
46
50
|
runner.alias,
|
|
47
51
|
# Mark lost runners in red
|
|
48
52
|
runner.runner_id if present else f"[red]{runner.runner_id}[/]",
|
|
49
53
|
in_flight,
|
|
50
54
|
(
|
|
51
|
-
"N/A
|
|
55
|
+
"N/A"
|
|
52
56
|
if runner.expiration_countdown is None
|
|
53
57
|
else f"{runner.expiration_countdown}s"
|
|
54
58
|
),
|
|
55
|
-
f"{
|
|
59
|
+
f"{uptime} ({uptime.total_seconds():.0f}s)",
|
|
56
60
|
runner.revision,
|
|
57
61
|
runner.state.value,
|
|
58
62
|
)
|
|
@@ -111,17 +115,31 @@ def _list_json(args, runners: list[RunnerInfo]):
|
|
|
111
115
|
def _list(args):
|
|
112
116
|
client = get_client(args.host, args.team)
|
|
113
117
|
with client.connect() as connection:
|
|
114
|
-
|
|
118
|
+
start_time = getattr(args, "since", None)
|
|
119
|
+
runners = connection.list_runners(start_time=start_time)
|
|
120
|
+
|
|
121
|
+
if getattr(args, "state", None):
|
|
122
|
+
states = set(args.state)
|
|
123
|
+
if "all" not in states:
|
|
124
|
+
runners = [r for r in runners if r.state.value in states]
|
|
115
125
|
pending_runners = [
|
|
116
126
|
runner for runner in runners if runner.state == RunnerState.PENDING
|
|
117
127
|
]
|
|
118
128
|
setup_runners = [
|
|
119
129
|
runner for runner in runners if runner.state == RunnerState.SETUP
|
|
120
130
|
]
|
|
131
|
+
dead_runners = [
|
|
132
|
+
runner for runner in runners if runner.state == RunnerState.DEAD
|
|
133
|
+
]
|
|
121
134
|
if args.output == "pretty":
|
|
122
135
|
args.console.print(
|
|
123
136
|
"Runners: "
|
|
124
|
-
+ str(
|
|
137
|
+
+ str(
|
|
138
|
+
len(runners)
|
|
139
|
+
- len(pending_runners)
|
|
140
|
+
- len(setup_runners)
|
|
141
|
+
- len(dead_runners)
|
|
142
|
+
)
|
|
125
143
|
)
|
|
126
144
|
args.console.print(f"Runners Pending: {len(pending_runners)}")
|
|
127
145
|
args.console.print(f"Runners Setting Up: {len(setup_runners)}")
|
|
@@ -159,6 +177,24 @@ def _add_list_parser(subparsers, parents):
|
|
|
159
177
|
help=list_help,
|
|
160
178
|
parents=[*parents, get_output_parser()],
|
|
161
179
|
)
|
|
180
|
+
parser.add_argument(
|
|
181
|
+
"--since",
|
|
182
|
+
default=None,
|
|
183
|
+
action=SinceAction,
|
|
184
|
+
limit="1 day",
|
|
185
|
+
help=(
|
|
186
|
+
"Show dead runners since the given time. "
|
|
187
|
+
"Accepts 'now', relative like '30m', '1h', '1d', "
|
|
188
|
+
"or an ISO timestamp. Max 24 hours."
|
|
189
|
+
),
|
|
190
|
+
)
|
|
191
|
+
parser.add_argument(
|
|
192
|
+
"--state",
|
|
193
|
+
choices=["all", "running", "pending", "setup", "dead"],
|
|
194
|
+
nargs="+",
|
|
195
|
+
default=None,
|
|
196
|
+
help=("Filter by runner state(s). Choose one or more, or 'all'(default)."),
|
|
197
|
+
)
|
|
162
198
|
parser.set_defaults(func=_list)
|
|
163
199
|
|
|
164
200
|
|
fal/sdk.py
CHANGED
|
@@ -265,6 +265,7 @@ class RunnerState(Enum):
|
|
|
265
265
|
RUNNING = "running"
|
|
266
266
|
PENDING = "pending"
|
|
267
267
|
SETUP = "setup"
|
|
268
|
+
DEAD = "dead"
|
|
268
269
|
UNKNOWN = "unknown"
|
|
269
270
|
|
|
270
271
|
@staticmethod
|
|
@@ -275,6 +276,8 @@ class RunnerState(Enum):
|
|
|
275
276
|
return RunnerState.PENDING
|
|
276
277
|
elif proto is isolate_proto.RunnerInfo.State.SETUP:
|
|
277
278
|
return RunnerState.SETUP
|
|
279
|
+
elif proto is isolate_proto.RunnerInfo.State.DEAD:
|
|
280
|
+
return RunnerState.DEAD
|
|
278
281
|
else:
|
|
279
282
|
return RunnerState.UNKNOWN
|
|
280
283
|
|
|
@@ -811,8 +814,18 @@ class FalServerlessConnection:
|
|
|
811
814
|
response: isolate_proto.ListAliasesResult = self.stub.ListAliases(request)
|
|
812
815
|
return [from_grpc(alias) for alias in response.aliases]
|
|
813
816
|
|
|
814
|
-
def list_alias_runners(
|
|
815
|
-
|
|
817
|
+
def list_alias_runners(
|
|
818
|
+
self,
|
|
819
|
+
alias: str,
|
|
820
|
+
*,
|
|
821
|
+
list_pending: bool = True,
|
|
822
|
+
start_time: datetime | None = None,
|
|
823
|
+
) -> list[RunnerInfo]:
|
|
824
|
+
kwargs = {"alias": alias, "list_pending": list_pending}
|
|
825
|
+
if start_time:
|
|
826
|
+
kwargs["start_time"] = isolate_proto.timestamp_from_datetime(start_time)
|
|
827
|
+
|
|
828
|
+
request = isolate_proto.ListAliasRunnersRequest(**kwargs)
|
|
816
829
|
response = self.stub.ListAliasRunners(request)
|
|
817
830
|
return [from_grpc(runner) for runner in response.runners]
|
|
818
831
|
|
|
@@ -839,7 +852,13 @@ class FalServerlessConnection:
|
|
|
839
852
|
request = isolate_proto.KillRunnerRequest(runner_id=runner_id)
|
|
840
853
|
self.stub.KillRunner(request)
|
|
841
854
|
|
|
842
|
-
def list_runners(self) -> list[RunnerInfo]:
|
|
843
|
-
|
|
855
|
+
def list_runners(self, start_time: datetime | None = None) -> list[RunnerInfo]:
|
|
856
|
+
kwargs = {
|
|
857
|
+
"list_pending": True,
|
|
858
|
+
}
|
|
859
|
+
if start_time:
|
|
860
|
+
kwargs["start_time"] = isolate_proto.timestamp_from_datetime(start_time)
|
|
861
|
+
|
|
862
|
+
request = isolate_proto.ListRunnersRequest(**kwargs)
|
|
844
863
|
response = self.stub.ListRunners(request)
|
|
845
864
|
return [from_grpc(runner) for runner in response.runners]
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fal
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.38.0
|
|
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.20.0,>=0.18.0
|
|
9
|
-
Requires-Dist: isolate-proto<0.
|
|
9
|
+
Requires-Dist: isolate-proto<0.17.0,>=0.16.0
|
|
10
10
|
Requires-Dist: grpcio<2,>=1.64.0
|
|
11
11
|
Requires-Dist: dill==0.3.7
|
|
12
12
|
Requires-Dist: cloudpickle==3.0.0
|
|
@@ -28,6 +28,8 @@ Requires-Dist: httpx>=0.15.4
|
|
|
28
28
|
Requires-Dist: attrs>=21.3.0
|
|
29
29
|
Requires-Dist: python-dateutil<3,>=2.8.0
|
|
30
30
|
Requires-Dist: types-python-dateutil<3,>=2.8.0
|
|
31
|
+
Requires-Dist: dateparser<2,>=1.2.0
|
|
32
|
+
Requires-Dist: types-dateparser<2,>=1.2.0
|
|
31
33
|
Requires-Dist: importlib-metadata>=4.4; python_version < "3.10"
|
|
32
34
|
Requires-Dist: msgpack<2,>=1.0.7
|
|
33
35
|
Requires-Dist: websockets>=12.0
|
|
@@ -1,6 +1,6 @@
|
|
|
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=
|
|
3
|
+
fal/_fal_version.py,sha256=hpE2QGF6bH9ClanX9-BzRSfKPnmfpMqQOKZnAhdai_o,706
|
|
4
4
|
fal/_serialization.py,sha256=npXNsFJ5G7jzBeBIyVMH01Ww34mGY4XWhHpRbSrTtnQ,7598
|
|
5
5
|
fal/_version.py,sha256=1BbTFnucNC_6ldKJ_ZoC722_UkW4S9aDBSW9L0fkKAw,2315
|
|
6
6
|
fal/api.py,sha256=oWSPxefwyYF93s54mtyYGKWYMax9ll9B-wxijOyARb4,49244
|
|
@@ -13,7 +13,7 @@ fal/flags.py,sha256=QonyDM7R2GqfAB1bJr46oriu-fHJCkpUwXuSdanePWg,987
|
|
|
13
13
|
fal/project.py,sha256=QgfYfMKmNobMPufrAP_ga1FKcIAlSbw18Iar1-0qepo,2650
|
|
14
14
|
fal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
fal/rest_client.py,sha256=kGBGmuyHfX1lR910EoKCYPjsyU8MdXawT_cW2q8Sajc,568
|
|
16
|
-
fal/sdk.py,sha256=
|
|
16
|
+
fal/sdk.py,sha256=iKpyL4RrWCdaFMK4wiIM3zOuM2H0VsN0wv8wF9OBxHM,28099
|
|
17
17
|
fal/sync.py,sha256=ZuIJA2-hTPNANG9B_NNJZUsO68EIdTH0dc9MzeVE2VU,4340
|
|
18
18
|
fal/utils.py,sha256=iQTBG3-i6JZgHkkwbY_I4210g0xoW-as51yrke608u0,2208
|
|
19
19
|
fal/workflows.py,sha256=Zl4f6Bs085hY40zmqScxDUyCu7zXkukDbW02iYOLTTI,14805
|
|
@@ -23,7 +23,7 @@ fal/auth/local.py,sha256=sndkM6vKpeVny6NHTacVlTbiIFqaksOmw0Viqs_RN1U,1790
|
|
|
23
23
|
fal/cli/__init__.py,sha256=padK4o0BFqq61kxAA1qQ0jYr2SuhA2mf90B3AaRkmJA,37
|
|
24
24
|
fal/cli/_utils.py,sha256=ulYezhr3G29nTIF8MDQ6tsW01Oj1zPo-YSqMoBi05Ic,1871
|
|
25
25
|
fal/cli/api.py,sha256=ZuDE_PIC-czzneTAWMwvC7P7WnwIyluNZSuJqzCFhqI,2640
|
|
26
|
-
fal/cli/apps.py,sha256=
|
|
26
|
+
fal/cli/apps.py,sha256=8ChoOYf2GeRSDN0w5VgDnWqdAqROlyDyQunciL-C8z4,12545
|
|
27
27
|
fal/cli/auth.py,sha256=ZLjxuF4LobETJ2CLGMj_QurE0PiJxzKdFJZkux8uLHM,5977
|
|
28
28
|
fal/cli/cli_nested_json.py,sha256=veSZU8_bYV3Iu1PAoxt-4BMBraNIqgH5nughbs2UKvE,13539
|
|
29
29
|
fal/cli/create.py,sha256=a8WDq-nJLFTeoIXqpb5cr7GR7YR9ZZrQCawNm34KXXE,627
|
|
@@ -33,10 +33,10 @@ fal/cli/doctor.py,sha256=8SZrYG9Ku0F6LLUHtFdKopdIgZfFkw5E3Mwrxa9KOSk,1613
|
|
|
33
33
|
fal/cli/files.py,sha256=-j0q4g53A7CWSczGLdfeUCTSd4zXoV3pfZFdman7JOw,3450
|
|
34
34
|
fal/cli/keys.py,sha256=iQVMr3WT8CUqSQT3qeCCiy6rRwoux9F-UEaC4bCwMWo,3754
|
|
35
35
|
fal/cli/main.py,sha256=s_LxEyz9z64dewk3oiGEI33_h3vJ3IVdu8aY3qydkMo,3345
|
|
36
|
-
fal/cli/parser.py,sha256=
|
|
36
|
+
fal/cli/parser.py,sha256=PZi5MWS4Z-3YSPe6np_F87ay4kF6gaYxlP0avByPr-0,5222
|
|
37
37
|
fal/cli/profile.py,sha256=PAY_ffifCT71VJ8VxfDVaXPT0U1oN8drvWZDFRXwvek,6678
|
|
38
38
|
fal/cli/run.py,sha256=nAC12Qss4Fg1XmV0qOS9RdGNLYcdoHeRgQMvbTN4P9I,1202
|
|
39
|
-
fal/cli/runners.py,sha256=
|
|
39
|
+
fal/cli/runners.py,sha256=AXUB2pq9Ot0VU2cOeJydSgmgTlUm4i6iNgJOClO7ZZw,6533
|
|
40
40
|
fal/cli/secrets.py,sha256=HfIeO2IZpCEiBC6Cs5Kpi3zckfDnc7GsLwLdgj3NnPU,3085
|
|
41
41
|
fal/cli/teams.py,sha256=_JcNcf659ZoLBFOxKnVP5A6Pyk1jY1vh4_xzMweYIDo,1285
|
|
42
42
|
fal/console/__init__.py,sha256=lGPUuTqIM9IKTa1cyyA-MA2iZJKVHp2YydsITZVlb6g,148
|
|
@@ -143,8 +143,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
143
143
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
144
144
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
145
145
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
146
|
-
fal-1.
|
|
147
|
-
fal-1.
|
|
148
|
-
fal-1.
|
|
149
|
-
fal-1.
|
|
150
|
-
fal-1.
|
|
146
|
+
fal-1.38.0.dist-info/METADATA,sha256=wvUr3J6wykpTEhwt0fRJEwxB8SaZy4f9AuJ-Mn5FheY,4132
|
|
147
|
+
fal-1.38.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
148
|
+
fal-1.38.0.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
149
|
+
fal-1.38.0.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
150
|
+
fal-1.38.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|