fal 1.26.4__py3-none-any.whl → 1.26.6__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 +4 -1
- fal/files.py +33 -10
- fal/sdk.py +3 -2
- fal/toolkit/file/file.py +56 -43
- {fal-1.26.4.dist-info → fal-1.26.6.dist-info}/METADATA +2 -2
- {fal-1.26.4.dist-info → fal-1.26.6.dist-info}/RECORD +10 -10
- {fal-1.26.4.dist-info → fal-1.26.6.dist-info}/WHEEL +0 -0
- {fal-1.26.4.dist-info → fal-1.26.6.dist-info}/entry_points.txt +0 -0
- {fal-1.26.4.dist-info → fal-1.26.6.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
fal/cli/apps.py
CHANGED
|
@@ -246,7 +246,10 @@ def _add_scale_parser(subparsers, parents):
|
|
|
246
246
|
def _set_rev(args):
|
|
247
247
|
client = get_client(args.host, args.team)
|
|
248
248
|
with client.connect() as connection:
|
|
249
|
-
connection.create_alias(args.app_name, args.app_rev, args.auth)
|
|
249
|
+
alias_info = connection.create_alias(args.app_name, args.app_rev, args.auth)
|
|
250
|
+
table = _apps_table([alias_info])
|
|
251
|
+
|
|
252
|
+
args.console.print(table)
|
|
250
253
|
|
|
251
254
|
|
|
252
255
|
def _add_set_rev_parser(subparsers, parents):
|
fal/files.py
CHANGED
|
@@ -56,6 +56,16 @@ class FalFileSystem(AbstractFileSystem):
|
|
|
56
56
|
raise FalServerlessException(detail)
|
|
57
57
|
return response
|
|
58
58
|
|
|
59
|
+
def _abspath(self, rpath):
|
|
60
|
+
if rpath.startswith("/"):
|
|
61
|
+
return rpath
|
|
62
|
+
|
|
63
|
+
cwd = "/data"
|
|
64
|
+
if rpath in [".", ""]:
|
|
65
|
+
return cwd
|
|
66
|
+
|
|
67
|
+
return posixpath.join(cwd, rpath)
|
|
68
|
+
|
|
59
69
|
def _ls(self, path):
|
|
60
70
|
response = self._request("GET", f"/files/list/{path}")
|
|
61
71
|
files = response.json()
|
|
@@ -73,7 +83,7 @@ class FalFileSystem(AbstractFileSystem):
|
|
|
73
83
|
)
|
|
74
84
|
|
|
75
85
|
def ls(self, path, detail=True, **kwargs):
|
|
76
|
-
abs_path =
|
|
86
|
+
abs_path = self._abspath(path)
|
|
77
87
|
if abs_path in self.dircache:
|
|
78
88
|
entries = self.dircache[abs_path]
|
|
79
89
|
elif abs_path in ["/", "", "."]:
|
|
@@ -95,20 +105,29 @@ class FalFileSystem(AbstractFileSystem):
|
|
|
95
105
|
return [entry["name"] for entry in entries]
|
|
96
106
|
|
|
97
107
|
def info(self, path, **kwargs):
|
|
98
|
-
|
|
108
|
+
abs_path = self._abspath(path)
|
|
109
|
+
if abs_path == "/":
|
|
110
|
+
return {
|
|
111
|
+
"name": "/",
|
|
112
|
+
"size": 0,
|
|
113
|
+
"type": "directory",
|
|
114
|
+
"mtime": 0,
|
|
115
|
+
}
|
|
116
|
+
parent = posixpath.dirname(abs_path)
|
|
99
117
|
entries = self.ls(parent, detail=True)
|
|
100
118
|
for entry in entries:
|
|
101
|
-
if entry["name"] ==
|
|
119
|
+
if entry["name"] == abs_path:
|
|
102
120
|
return entry
|
|
103
|
-
raise FileNotFoundError(f"File not found: {
|
|
121
|
+
raise FileNotFoundError(f"File not found: {abs_path}")
|
|
104
122
|
|
|
105
123
|
def get_file(self, rpath, lpath, **kwargs):
|
|
106
|
-
|
|
124
|
+
abs_rpath = self._abspath(rpath)
|
|
125
|
+
if self.isdir(abs_rpath):
|
|
107
126
|
os.makedirs(lpath, exist_ok=True)
|
|
108
127
|
return
|
|
109
128
|
|
|
110
129
|
with open(lpath, "wb") as fobj:
|
|
111
|
-
response = self._request("GET", f"/files/file/{
|
|
130
|
+
response = self._request("GET", f"/files/file/{abs_rpath}")
|
|
112
131
|
fobj.write(response.content)
|
|
113
132
|
|
|
114
133
|
def _put_file_part(self, rpath, lpath, upload_id, part_number, chunk_size):
|
|
@@ -177,6 +196,8 @@ class FalFileSystem(AbstractFileSystem):
|
|
|
177
196
|
if os.path.isdir(lpath):
|
|
178
197
|
return
|
|
179
198
|
|
|
199
|
+
abs_rpath = self._abspath(rpath)
|
|
200
|
+
|
|
180
201
|
size = os.path.getsize(lpath)
|
|
181
202
|
with Progress(
|
|
182
203
|
SpinnerColumn(),
|
|
@@ -185,29 +206,31 @@ class FalFileSystem(AbstractFileSystem):
|
|
|
185
206
|
TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
|
|
186
207
|
) as progress:
|
|
187
208
|
if size > MULTIPART_THRESHOLD:
|
|
188
|
-
self._put_file_multipart(lpath,
|
|
209
|
+
self._put_file_multipart(lpath, abs_rpath, size, progress)
|
|
189
210
|
else:
|
|
190
211
|
task = progress.add_task(f"{os.path.basename(lpath)}", total=1)
|
|
191
212
|
with open(lpath, "rb") as fobj:
|
|
192
213
|
self._request(
|
|
193
214
|
"POST",
|
|
194
|
-
f"/files/file/local/{
|
|
215
|
+
f"/files/file/local/{abs_rpath}",
|
|
195
216
|
files={"file_upload": (posixpath.basename(lpath), fobj)},
|
|
196
217
|
)
|
|
197
218
|
progress.advance(task)
|
|
198
219
|
self.dircache.clear()
|
|
199
220
|
|
|
200
221
|
def put_file_from_url(self, url, rpath, mode="overwrite", **kwargs):
|
|
222
|
+
abs_rpath = self._abspath(rpath)
|
|
201
223
|
self._request(
|
|
202
224
|
"POST",
|
|
203
|
-
f"/files/file/url/{
|
|
225
|
+
f"/files/file/url/{abs_rpath}",
|
|
204
226
|
json={"url": url},
|
|
205
227
|
)
|
|
206
228
|
self.dircache.clear()
|
|
207
229
|
|
|
208
230
|
def rm(self, path, **kwargs):
|
|
231
|
+
abs_path = self._abspath(path)
|
|
209
232
|
self._request(
|
|
210
233
|
"DELETE",
|
|
211
|
-
f"/files/file/{
|
|
234
|
+
f"/files/file/{abs_path}",
|
|
212
235
|
)
|
|
213
236
|
self.dircache.clear()
|
fal/sdk.py
CHANGED
|
@@ -735,7 +735,7 @@ class FalServerlessConnection:
|
|
|
735
735
|
alias: str,
|
|
736
736
|
revision: str,
|
|
737
737
|
auth_mode: AuthMode,
|
|
738
|
-
):
|
|
738
|
+
) -> AliasInfo:
|
|
739
739
|
if auth_mode == "public":
|
|
740
740
|
auth = isolate_proto.ApplicationAuthMode.PUBLIC
|
|
741
741
|
elif auth_mode == "shared":
|
|
@@ -750,7 +750,8 @@ class FalServerlessConnection:
|
|
|
750
750
|
revision=revision,
|
|
751
751
|
auth_mode=auth,
|
|
752
752
|
)
|
|
753
|
-
self.stub.SetAlias(request)
|
|
753
|
+
res = self.stub.SetAlias(request)
|
|
754
|
+
return from_grpc(res.alias_info)
|
|
754
755
|
|
|
755
756
|
def delete_alias(self, alias: str) -> str | None:
|
|
756
757
|
request = isolate_proto.DeleteAliasRequest(alias=alias)
|
fal/toolkit/file/file.py
CHANGED
|
@@ -73,6 +73,42 @@ def FileField(*args, **kwargs):
|
|
|
73
73
|
return Field(*args, **kwargs)
|
|
74
74
|
|
|
75
75
|
|
|
76
|
+
def _try_with_fallback(
|
|
77
|
+
func: str,
|
|
78
|
+
args: list[Any],
|
|
79
|
+
repository: FileRepository | RepositoryId,
|
|
80
|
+
fallback_repository: Optional[
|
|
81
|
+
FileRepository | RepositoryId | list[FileRepository | RepositoryId]
|
|
82
|
+
],
|
|
83
|
+
save_kwargs: dict,
|
|
84
|
+
fallback_save_kwargs: dict,
|
|
85
|
+
) -> Any:
|
|
86
|
+
if fallback_repository is None:
|
|
87
|
+
fallback_repositories = []
|
|
88
|
+
elif isinstance(fallback_repository, list):
|
|
89
|
+
fallback_repositories = fallback_repository
|
|
90
|
+
else:
|
|
91
|
+
fallback_repositories = [fallback_repository]
|
|
92
|
+
|
|
93
|
+
attempts = [
|
|
94
|
+
(repository, save_kwargs),
|
|
95
|
+
*((fallback, fallback_save_kwargs) for fallback in fallback_repositories),
|
|
96
|
+
]
|
|
97
|
+
for idx, (repo, kwargs) in enumerate(attempts):
|
|
98
|
+
repo_obj = get_builtin_repository(repo)
|
|
99
|
+
try:
|
|
100
|
+
return getattr(repo_obj, func)(*args, **kwargs)
|
|
101
|
+
except Exception as exc:
|
|
102
|
+
if idx >= len(attempts) - 1:
|
|
103
|
+
raise
|
|
104
|
+
|
|
105
|
+
traceback.print_exc()
|
|
106
|
+
print(
|
|
107
|
+
f"Failed to {func} to repository {repo}: {exc}, "
|
|
108
|
+
f"falling back to {attempts[idx + 1][0]}"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
76
112
|
class File(BaseModel):
|
|
77
113
|
# public properties
|
|
78
114
|
url: str = Field(
|
|
@@ -154,14 +190,12 @@ class File(BaseModel):
|
|
|
154
190
|
file_name: Optional[str] = None,
|
|
155
191
|
repository: FileRepository | RepositoryId = DEFAULT_REPOSITORY,
|
|
156
192
|
fallback_repository: Optional[
|
|
157
|
-
FileRepository | RepositoryId
|
|
193
|
+
FileRepository | RepositoryId | list[FileRepository | RepositoryId]
|
|
158
194
|
] = FALLBACK_REPOSITORY,
|
|
159
195
|
request: Optional[Request] = None,
|
|
160
196
|
save_kwargs: Optional[dict] = None,
|
|
161
197
|
fallback_save_kwargs: Optional[dict] = None,
|
|
162
198
|
) -> File:
|
|
163
|
-
repo = get_builtin_repository(repository)
|
|
164
|
-
|
|
165
199
|
save_kwargs = save_kwargs or {}
|
|
166
200
|
fallback_save_kwargs = fallback_save_kwargs or {}
|
|
167
201
|
|
|
@@ -177,21 +211,14 @@ class File(BaseModel):
|
|
|
177
211
|
"object_lifecycle_preference", object_lifecycle_preference
|
|
178
212
|
)
|
|
179
213
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
f"Failed to save bytes to repository {repository}: {exc}, "
|
|
189
|
-
f"falling back to {fallback_repository}"
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
fallback_repo = get_builtin_repository(fallback_repository)
|
|
193
|
-
|
|
194
|
-
url = fallback_repo.save(fdata, **fallback_save_kwargs)
|
|
214
|
+
url = _try_with_fallback(
|
|
215
|
+
"save",
|
|
216
|
+
[fdata],
|
|
217
|
+
repository=repository,
|
|
218
|
+
fallback_repository=fallback_repository,
|
|
219
|
+
save_kwargs=save_kwargs,
|
|
220
|
+
fallback_save_kwargs=fallback_save_kwargs,
|
|
221
|
+
)
|
|
195
222
|
|
|
196
223
|
return cls(
|
|
197
224
|
url=url,
|
|
@@ -209,7 +236,7 @@ class File(BaseModel):
|
|
|
209
236
|
repository: FileRepository | RepositoryId = DEFAULT_REPOSITORY,
|
|
210
237
|
multipart: bool | None = None,
|
|
211
238
|
fallback_repository: Optional[
|
|
212
|
-
FileRepository | RepositoryId
|
|
239
|
+
FileRepository | RepositoryId | list[FileRepository | RepositoryId]
|
|
213
240
|
] = FALLBACK_REPOSITORY,
|
|
214
241
|
request: Optional[Request] = None,
|
|
215
242
|
save_kwargs: Optional[dict] = None,
|
|
@@ -219,8 +246,6 @@ class File(BaseModel):
|
|
|
219
246
|
if not file_path.exists():
|
|
220
247
|
raise FileNotFoundError(f"File {file_path} does not exist")
|
|
221
248
|
|
|
222
|
-
repo = get_builtin_repository(repository)
|
|
223
|
-
|
|
224
249
|
save_kwargs = save_kwargs or {}
|
|
225
250
|
fallback_save_kwargs = fallback_save_kwargs or {}
|
|
226
251
|
|
|
@@ -238,29 +263,17 @@ class File(BaseModel):
|
|
|
238
263
|
save_kwargs.setdefault("multipart", multipart)
|
|
239
264
|
fallback_save_kwargs.setdefault("multipart", multipart)
|
|
240
265
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
file_path,
|
|
244
|
-
content_type=content_type,
|
|
245
|
-
**save_kwargs,
|
|
246
|
-
)
|
|
247
|
-
except Exception as exc:
|
|
248
|
-
if not fallback_repository:
|
|
249
|
-
raise
|
|
250
|
-
|
|
251
|
-
traceback.print_exc()
|
|
252
|
-
print(
|
|
253
|
-
f"Failed to save file to repository {repository}: {exc}, "
|
|
254
|
-
f"falling back to {fallback_repository}"
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
fallback_repo = get_builtin_repository(fallback_repository)
|
|
266
|
+
save_kwargs.setdefault("content_type", content_type)
|
|
267
|
+
fallback_save_kwargs.setdefault("content_type", content_type)
|
|
258
268
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
269
|
+
url, data = _try_with_fallback(
|
|
270
|
+
"save_file",
|
|
271
|
+
[file_path],
|
|
272
|
+
repository=repository,
|
|
273
|
+
fallback_repository=fallback_repository,
|
|
274
|
+
save_kwargs=save_kwargs,
|
|
275
|
+
fallback_save_kwargs=fallback_save_kwargs,
|
|
276
|
+
)
|
|
264
277
|
|
|
265
278
|
return cls(
|
|
266
279
|
url=url,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fal
|
|
3
|
-
Version: 1.26.
|
|
3
|
+
Version: 1.26.6
|
|
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.19.0,>=0.18.0
|
|
9
|
-
Requires-Dist: isolate-proto<0.11.0,>=0.10.
|
|
9
|
+
Requires-Dist: isolate-proto<0.11.0,>=0.10.2
|
|
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
|
|
@@ -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=ki20SEr4F9ZxFRNziosQqt1wqRI1HwXbMEH1XL5Oq2M,513
|
|
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=wIEt21P1C7U-dYQEcyHUxxuuTnvzFyTpWDoHoaxq7tg,47385
|
|
@@ -8,12 +8,12 @@ fal/app.py,sha256=3RDFV6JUiUk8b3WJanKQYA-kW74t5bqaNy8OYuUH5-Q,25491
|
|
|
8
8
|
fal/apps.py,sha256=pzCd2mrKl5J_4oVc40_pggvPtFahXBCdrZXWpnaEJVs,12130
|
|
9
9
|
fal/config.py,sha256=G3IOTLQuu_VAvzPFdx9v22NpJ9m4gU8qEHic7e7-WwU,3511
|
|
10
10
|
fal/container.py,sha256=FTsa5hOW4ars-yV1lUoc0BNeIIvAZcpw7Ftyt3A4m_w,2000
|
|
11
|
-
fal/files.py,sha256=
|
|
11
|
+
fal/files.py,sha256=iWkOqCtdoz7_V-wOvV1iB1zg9x7fdGRcmGGyBkCuFXI,7449
|
|
12
12
|
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=tUrwEohQz2B3LN-troH5FcON4VwRnV0zFjB0FRctDBA,26218
|
|
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=anFfy6qouB8QzH0Yho41GulGiJu3q1KKIwgyVQCzgRQ,1593
|
|
25
25
|
fal/cli/api.py,sha256=ZuDE_PIC-czzneTAWMwvC7P7WnwIyluNZSuJqzCFhqI,2640
|
|
26
|
-
fal/cli/apps.py,sha256=
|
|
26
|
+
fal/cli/apps.py,sha256=q0uxuD4h_5tft77QfyFbDz0kGmM51JT39du_OeFytPA,10565
|
|
27
27
|
fal/cli/auth.py,sha256=Qe-Z3ycXJnOzHimz5PjCQYoni8MF4csmdL19yGN7a1o,5171
|
|
28
28
|
fal/cli/cli_nested_json.py,sha256=veSZU8_bYV3Iu1PAoxt-4BMBraNIqgH5nughbs2UKvE,13539
|
|
29
29
|
fal/cli/create.py,sha256=a8WDq-nJLFTeoIXqpb5cr7GR7YR9ZZrQCawNm34KXXE,627
|
|
@@ -59,7 +59,7 @@ fal/toolkit/types.py,sha256=kkbOsDKj1qPGb1UARTBp7yuJ5JUuyy7XQurYUBCdti8,4064
|
|
|
59
59
|
fal/toolkit/audio/__init__.py,sha256=sqNVfrKbppWlIGLoFTaaNTxLpVXsFHxOSHLA5VG547A,35
|
|
60
60
|
fal/toolkit/audio/audio.py,sha256=gt458h989iQ-EhQSH-mCuJuPBY4RneLJE05f_QWU1E0,572
|
|
61
61
|
fal/toolkit/file/__init__.py,sha256=FbNl6wD-P0aSSTUwzHt4HujBXrbC3ABmaigPQA4hRfg,70
|
|
62
|
-
fal/toolkit/file/file.py,sha256=
|
|
62
|
+
fal/toolkit/file/file.py,sha256=goiz5o3Wb7hcyFiolL4a4dANOmv3NJnet4Da50Pm6sI,10767
|
|
63
63
|
fal/toolkit/file/types.py,sha256=MMAH_AyLOhowQPesOv1V25wB4qgbJ3vYNlnTPbdSv1M,2304
|
|
64
64
|
fal/toolkit/file/providers/fal.py,sha256=Ph8v3Cm_eFu1b1AXiPKZQ5r8AWUALD3Wk18uw3z8RDQ,46910
|
|
65
65
|
fal/toolkit/file/providers/gcp.py,sha256=DKeZpm1MjwbvEsYvkdXUtuLIJDr_UNbqXj_Mfv3NTeo,2437
|
|
@@ -142,8 +142,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
142
142
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
143
143
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
144
144
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
145
|
-
fal-1.26.
|
|
146
|
-
fal-1.26.
|
|
147
|
-
fal-1.26.
|
|
148
|
-
fal-1.26.
|
|
149
|
-
fal-1.26.
|
|
145
|
+
fal-1.26.6.dist-info/METADATA,sha256=g4I367Dy6AaujQfb-0jcU_YK-Vg1iTY-Jx0kMICfih4,4089
|
|
146
|
+
fal-1.26.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
147
|
+
fal-1.26.6.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
148
|
+
fal-1.26.6.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
149
|
+
fal-1.26.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|