fal 1.11.0__py3-none-any.whl → 1.11.1__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.11.0'
21
- __version_tuple__ = version_tuple = (1, 11, 0)
20
+ __version__ = version = '1.11.1'
21
+ __version_tuple__ = version_tuple = (1, 11, 1)
fal/cli/_utils.py CHANGED
@@ -25,7 +25,7 @@ def get_app_data_from_toml(app_name):
25
25
  raise ValueError(f"App {app_name} not found in pyproject.toml")
26
26
 
27
27
  try:
28
- app_ref = app_data["ref"]
28
+ app_ref = app_data.pop("ref")
29
29
  except KeyError:
30
30
  raise ValueError(f"App {app_name} does not have a ref key in pyproject.toml")
31
31
 
@@ -33,8 +33,11 @@ def get_app_data_from_toml(app_name):
33
33
  project_root, _ = find_project_root(None)
34
34
  app_ref = str(project_root / app_ref)
35
35
 
36
- app_auth = app_data.get("auth", "private")
37
- app_deployment_strategy = app_data.get("deployment_strategy", "recreate")
38
- app_no_scale = app_data.get("no_scale", False)
36
+ app_auth = app_data.pop("auth", "private")
37
+ app_deployment_strategy = app_data.pop("deployment_strategy", "recreate")
38
+ app_no_scale = app_data.pop("no_scale", False)
39
+
40
+ if len(app_data) > 0:
41
+ raise ValueError(f"Found unexpected keys in pyproject.toml: {app_data}")
39
42
 
40
43
  return app_ref, app_auth, app_deployment_strategy, app_no_scale
@@ -126,11 +126,12 @@ def download_file(
126
126
  *,
127
127
  force: bool = False,
128
128
  request_headers: dict[str, str] | None = None,
129
+ filesize_limit: int | None = None,
129
130
  ) -> Path:
130
131
  """Downloads a file from the specified URL to the target directory.
131
132
 
132
133
  The function downloads the file from the given URL and saves it in the specified
133
- target directory.
134
+ target directory, provided it is below the given filesize limit.
134
135
 
135
136
  It also checks whether the local file already exists and whether its content length
136
137
  matches the expected content length from the remote file. If the local file already
@@ -151,6 +152,8 @@ def download_file(
151
152
  Defaults to `False`.
152
153
  request_headers: A dictionary containing additional headers to be included in
153
154
  the HTTP request. Defaults to `None`.
155
+ filesize_limit: An integer specifying the maximum downloadable size,
156
+ in megabytes. Defaults to `None`.
154
157
 
155
158
 
156
159
  Returns:
@@ -160,12 +163,22 @@ def download_file(
160
163
  ValueError: If the provided `file_name` contains a forward slash ('/').
161
164
  DownloadError: If an error occurs during the download process.
162
165
  """
166
+ ONE_MB = 1024**2
167
+
163
168
  try:
164
- file_name = _get_remote_file_properties(url, request_headers)[0]
169
+ file_name, expected_filesize = _get_remote_file_properties(url, request_headers)
165
170
  except Exception as e:
166
- print(f"GOt error: {e}")
171
+ print(f"Got error: {e}")
167
172
  raise DownloadError(f"Failed to get remote file properties for {url}") from e
168
173
 
174
+ expected_filesize_mb = expected_filesize / ONE_MB
175
+
176
+ if filesize_limit is not None and expected_filesize_mb > filesize_limit:
177
+ raise DownloadError(
178
+ f"""File to be downloaded is of size {expected_filesize_mb},
179
+ which is over the limit of {filesize_limit}"""
180
+ )
181
+
169
182
  if "/" in file_name:
170
183
  raise ValueError(f"File name '{file_name}' cannot contain a slash.")
171
184
 
@@ -194,7 +207,10 @@ def download_file(
194
207
 
195
208
  try:
196
209
  _download_file_python(
197
- url=url, target_path=target_path, request_headers=request_headers
210
+ url=url,
211
+ target_path=target_path,
212
+ request_headers=request_headers,
213
+ filesize_limit=filesize_limit,
198
214
  )
199
215
  except Exception as e:
200
216
  msg = f"Failed to download {url} to {target_path}"
@@ -207,7 +223,10 @@ def download_file(
207
223
 
208
224
 
209
225
  def _download_file_python(
210
- url: str, target_path: Path | str, request_headers: dict[str, str] | None = None
226
+ url: str,
227
+ target_path: Path | str,
228
+ request_headers: dict[str, str] | None = None,
229
+ filesize_limit: int | None = None,
211
230
  ) -> Path:
212
231
  """Download a file from a given URL and save it to a specified path using a
213
232
  Python interface.
@@ -217,6 +236,8 @@ def _download_file_python(
217
236
  target_path: The path where the downloaded file will be saved.
218
237
  request_headers: A dictionary containing additional headers to be included in
219
238
  the HTTP request. Defaults to `None`.
239
+ filesize_limit: A integer value specifying how many megabytes can be
240
+ downloaded at maximum. Defaults to `None`.
220
241
 
221
242
  Returns:
222
243
  The path where the downloaded file has been saved.
@@ -233,7 +254,10 @@ def _download_file_python(
233
254
  file_path = temp_file.name
234
255
 
235
256
  for progress, total_size in _stream_url_data_to_file(
236
- url, temp_file.name, request_headers=request_headers
257
+ url,
258
+ temp_file.name,
259
+ request_headers=request_headers,
260
+ filesize_limit=filesize_limit,
237
261
  ):
238
262
  if total_size:
239
263
  progress_msg = f"Downloading {url} ... {progress:.2%}"
@@ -261,6 +285,7 @@ def _stream_url_data_to_file(
261
285
  file_path: str,
262
286
  chunk_size_in_mb: int = 64,
263
287
  request_headers: dict[str, str] | None = None,
288
+ filesize_limit: int | None = None,
264
289
  ):
265
290
  """Download data from a URL and stream it to a file.
266
291
 
@@ -277,6 +302,8 @@ def _stream_url_data_to_file(
277
302
  Defaults to 64.
278
303
  request_headers: A dictionary containing additional headers to be included in
279
304
  the HTTP request. Defaults to `None`.
305
+ filesize_limit: An integer specifying how many megabytes can be
306
+ downloaded at maximum. Defaults to `None`.
280
307
 
281
308
  Yields:
282
309
  A tuple containing two elements:
@@ -300,6 +327,11 @@ def _stream_url_data_to_file(
300
327
  f_stream.write(data)
301
328
 
302
329
  received_size = f_stream.tell()
330
+ if filesize_limit is not None and received_size > filesize_limit:
331
+ raise DownloadError(
332
+ f"""Attempted to download more data {received_size}
333
+ than the set limit of {filesize_limit}"""
334
+ )
303
335
 
304
336
  if total_size:
305
337
  progress = received_size / total_size
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fal
3
- Version: 1.11.0
3
+ Version: 1.11.1
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
@@ -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=NYxfUyIQwdONRcmiATXsc3iD0kuKImoMYD3H1Vdv9OM,513
3
+ fal/_fal_version.py,sha256=YfyxoPRBHFNEDWZGG9EWRRtidnKlEjmjHUQe05P3IMI,513
4
4
  fal/_serialization.py,sha256=rD2YiSa8iuzCaZohZwN_MPEB-PpSKbWRDeaIDpTEjyY,7653
5
5
  fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
6
6
  fal/api.py,sha256=jqmQfhRvZMYpWWvbTfARxjywP_72c314pnLPTb5dGwA,44755
@@ -20,7 +20,7 @@ fal/auth/__init__.py,sha256=MXwS5zyY1SYJWEkc6s39et73Dkg3cDJg1ZwxRhXNj4c,4704
20
20
  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
- fal/cli/_utils.py,sha256=45G0LEz2bW-69MUQKPdatVE_CBC2644gC-V0qdNEsco,1252
23
+ fal/cli/_utils.py,sha256=reMvQm4gcDs3mfvFELzFXnsqAjeurfTBuOfKY8M4yGM,1364
24
24
  fal/cli/api.py,sha256=-rl50A00CxqVZtDh0iZmpCHMFY0jZySaumbPCe3MSoQ,2090
25
25
  fal/cli/apps.py,sha256=KhweXdLdd1wZquhAMVwgl38dZAyFns-j3ZdIZLOLGWg,11504
26
26
  fal/cli/auth.py,sha256=--MhfHGwxmtHbRkGioyn1prKn_U-pBzbz0G_QeZou-U,1352
@@ -68,7 +68,7 @@ fal/toolkit/image/nsfw_filter/inference.py,sha256=BhIPF_zxRLetThQYxDDF0sdx9VRwvu
68
68
  fal/toolkit/image/nsfw_filter/model.py,sha256=63mu8D15z_IosoRUagRLGHy6VbLqFmrG-yZqnu2vVm4,457
69
69
  fal/toolkit/image/nsfw_filter/requirements.txt,sha256=3Pmrd0Ny6QAeBqUNHCgffRyfaCARAPJcfSCX5cRYpbM,37
70
70
  fal/toolkit/utils/__init__.py,sha256=CrmM9DyCz5-SmcTzRSm5RaLgxy3kf0ZsSEN9uhnX2Xo,97
71
- fal/toolkit/utils/download_utils.py,sha256=Ju-rvQ0oqFkARONRyrfIGVaqthjlxcFIb-qg5SE7yBw,18419
71
+ fal/toolkit/utils/download_utils.py,sha256=NgOMNs-bQGSg3gWnu123BgZitJgJrvtRexIefTMuylY,19739
72
72
  fal/toolkit/utils/retry.py,sha256=mHcQvvNIpu-Hi29P1HXSZuyvolRd48dMaJToqzlG0NY,1353
73
73
  openapi_fal_rest/__init__.py,sha256=ziculmF_i6trw63LzZGFX-6W3Lwq9mCR8_UpkpvpaHI,152
74
74
  openapi_fal_rest/client.py,sha256=G6BpJg9j7-JsrAUGddYwkzeWRYickBjPdcVgXoPzxuE,2817
@@ -133,8 +133,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
133
133
  openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
134
134
  openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
135
135
  openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
136
- fal-1.11.0.dist-info/METADATA,sha256=gyk3rZlftiD1qXNBRHk5Z_g-CC65Qi9OTS_zuKfQGHE,4043
137
- fal-1.11.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
138
- fal-1.11.0.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
139
- fal-1.11.0.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
140
- fal-1.11.0.dist-info/RECORD,,
136
+ fal-1.11.1.dist-info/METADATA,sha256=vqzL53kDWgyVECQHZe8riqszOL0GALTXa1ztbCSal-Q,4043
137
+ fal-1.11.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
138
+ fal-1.11.1.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
139
+ fal-1.11.1.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
140
+ fal-1.11.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (77.0.3)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5