truefoundry 0.11.11rc1__py3-none-any.whl → 0.12.0rc1__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 truefoundry might be problematic. Click here for more details.
- truefoundry/common/storage_provider_utils.py +35 -10
- truefoundry/deploy/_autogen/models.py +7 -7
- truefoundry/ml/artifact/truefoundry_artifact_repo.py +25 -11
- truefoundry/ml/log_types/artifacts/artifact.py +3 -2
- truefoundry/ml/log_types/artifacts/model.py +1 -0
- {truefoundry-0.11.11rc1.dist-info → truefoundry-0.12.0rc1.dist-info}/METADATA +1 -1
- {truefoundry-0.11.11rc1.dist-info → truefoundry-0.12.0rc1.dist-info}/RECORD +9 -9
- {truefoundry-0.11.11rc1.dist-info → truefoundry-0.12.0rc1.dist-info}/WHEEL +0 -0
- {truefoundry-0.11.11rc1.dist-info → truefoundry-0.12.0rc1.dist-info}/entry_points.txt +0 -0
|
@@ -22,6 +22,23 @@ from truefoundry.pydantic_v1 import BaseModel
|
|
|
22
22
|
logger = logging.getLogger("truefoundry")
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
def truncate_path_for_progress(
|
|
26
|
+
path: str, max_length: int, relpath: bool = False
|
|
27
|
+
) -> str:
|
|
28
|
+
if relpath:
|
|
29
|
+
path = os.path.relpath(path)
|
|
30
|
+
if len(path) <= max_length:
|
|
31
|
+
return path
|
|
32
|
+
parts = path.split(os.sep)
|
|
33
|
+
result = parts[-1] # start with filename
|
|
34
|
+
i = len(parts) - 2
|
|
35
|
+
# keep prepending directories until adding more would exceed max_len - 3
|
|
36
|
+
while i >= 0 and len(result) + len(parts[i]) + 1 <= max_length - 3:
|
|
37
|
+
result = parts[i] + os.sep + result
|
|
38
|
+
i -= 1
|
|
39
|
+
return "..." + os.sep + result
|
|
40
|
+
|
|
41
|
+
|
|
25
42
|
class MultiPartUploadStorageProvider(str, Enum):
|
|
26
43
|
S3_COMPATIBLE = "S3_COMPATIBLE"
|
|
27
44
|
AZURE_BLOB = "AZURE_BLOB"
|
|
@@ -182,7 +199,7 @@ def _file_part_upload(
|
|
|
182
199
|
return response
|
|
183
200
|
|
|
184
201
|
|
|
185
|
-
def s3_compatible_multipart_upload(
|
|
202
|
+
def s3_compatible_multipart_upload( # noqa: C901
|
|
186
203
|
multipart_upload: MultiPartUpload,
|
|
187
204
|
local_file: str,
|
|
188
205
|
multipart_info: _FileMultiPartInfo,
|
|
@@ -190,13 +207,15 @@ def s3_compatible_multipart_upload(
|
|
|
190
207
|
progress_bar: Optional[Progress] = None,
|
|
191
208
|
abort_event: Optional[Event] = None,
|
|
192
209
|
exception_class=HttpRequestException,
|
|
193
|
-
):
|
|
210
|
+
) -> None:
|
|
194
211
|
abort_event = abort_event or Event()
|
|
195
212
|
parts = []
|
|
196
213
|
|
|
197
|
-
if progress_bar:
|
|
214
|
+
if progress_bar is not None:
|
|
198
215
|
multi_part_upload_progress = progress_bar.add_task(
|
|
199
|
-
f"[green]
|
|
216
|
+
f"[green]⬆ {truncate_path_for_progress(local_file, 64, relpath=True)}",
|
|
217
|
+
start=True,
|
|
218
|
+
visible=True,
|
|
200
219
|
)
|
|
201
220
|
|
|
202
221
|
def upload(part_number: int, seek: int) -> None:
|
|
@@ -221,7 +240,7 @@ def s3_compatible_multipart_upload(
|
|
|
221
240
|
multipart_info.num_parts,
|
|
222
241
|
local_file,
|
|
223
242
|
)
|
|
224
|
-
if progress_bar:
|
|
243
|
+
if progress_bar is not None:
|
|
225
244
|
progress_bar.update(
|
|
226
245
|
multi_part_upload_progress,
|
|
227
246
|
advance=multipart_info.part_size,
|
|
@@ -254,10 +273,12 @@ def s3_compatible_multipart_upload(
|
|
|
254
273
|
timeout=2 * 60,
|
|
255
274
|
)
|
|
256
275
|
response.raise_for_status()
|
|
276
|
+
if progress_bar is not None:
|
|
277
|
+
progress_bar.refresh()
|
|
257
278
|
logger.debug("Multipart upload of %s completed", local_file)
|
|
258
279
|
|
|
259
280
|
|
|
260
|
-
def azure_multi_part_upload(
|
|
281
|
+
def azure_multi_part_upload( # noqa: C901
|
|
261
282
|
multipart_upload: MultiPartUpload,
|
|
262
283
|
local_file: str,
|
|
263
284
|
multipart_info: _FileMultiPartInfo,
|
|
@@ -265,12 +286,14 @@ def azure_multi_part_upload(
|
|
|
265
286
|
progress_bar: Optional[Progress] = None,
|
|
266
287
|
abort_event: Optional[Event] = None,
|
|
267
288
|
exception_class=HttpRequestException,
|
|
268
|
-
):
|
|
289
|
+
) -> None:
|
|
269
290
|
abort_event = abort_event or Event()
|
|
270
291
|
|
|
271
|
-
if progress_bar:
|
|
292
|
+
if progress_bar is not None:
|
|
272
293
|
multi_part_upload_progress = progress_bar.add_task(
|
|
273
|
-
f"[green]
|
|
294
|
+
f"[green]⬆ {truncate_path_for_progress(local_file, 64, relpath=True)}",
|
|
295
|
+
start=True,
|
|
296
|
+
visible=True,
|
|
274
297
|
)
|
|
275
298
|
|
|
276
299
|
def upload(part_number: int, seek: int):
|
|
@@ -289,7 +312,7 @@ def azure_multi_part_upload(
|
|
|
289
312
|
abort_event=abort_event,
|
|
290
313
|
exception_class=exception_class,
|
|
291
314
|
)
|
|
292
|
-
if progress_bar:
|
|
315
|
+
if progress_bar is not None:
|
|
293
316
|
progress_bar.update(
|
|
294
317
|
multi_part_upload_progress,
|
|
295
318
|
advance=multipart_info.part_size,
|
|
@@ -328,4 +351,6 @@ def azure_multi_part_upload(
|
|
|
328
351
|
timeout=2 * 60,
|
|
329
352
|
)
|
|
330
353
|
response.raise_for_status()
|
|
354
|
+
if progress_bar is not None:
|
|
355
|
+
progress_bar.refresh()
|
|
331
356
|
logger.debug("Multipart upload of %s completed", local_file)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generated by datamodel-codegen:
|
|
2
2
|
# filename: application.json
|
|
3
|
-
# timestamp: 2025-09-
|
|
3
|
+
# timestamp: 2025-09-10T19:32:14+00:00
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -621,8 +621,8 @@ class Pip(BaseModel):
|
|
|
621
621
|
|
|
622
622
|
class Poetry(BaseModel):
|
|
623
623
|
"""
|
|
624
|
-
Use `poetry` to setup
|
|
625
|
-
Your build context root must contain
|
|
624
|
+
Use `poetry` to setup env
|
|
625
|
+
Your build context root must contain `pyproject.toml` and `poetry.lock
|
|
626
626
|
"""
|
|
627
627
|
|
|
628
628
|
type: Literal["poetry"] = Field(..., description="")
|
|
@@ -1060,7 +1060,7 @@ class TaskPythonBuild(BaseModel):
|
|
|
1060
1060
|
)
|
|
1061
1061
|
cuda_version: Optional[
|
|
1062
1062
|
constr(
|
|
1063
|
-
regex=r"^((\d+\.\d+(\.\d+)?-cudnn\d+-(runtime|devel)-ubuntu\d+\.\d+)|11\.0-cudnn8|11\.1-cudnn8|11\.2-cudnn8|11\.3-cudnn8|11\.4-cudnn8|11\.5-cudnn8|11\.6-cudnn8|11\.7-cudnn8|11\.8-cudnn8|12\.0-cudnn8|12\.1-cudnn8|12\.2-cudnn8|12\.3-cudnn9|12\.4-cudnn9|12\.5-cudnn9|12\.6-cudnn9)$"
|
|
1063
|
+
regex=r"^((\d+\.\d+(\.\d+)?-cudnn\d+-(runtime|devel)-ubuntu\d+\.\d+)|11\.0-cudnn8|11\.1-cudnn8|11\.2-cudnn8|11\.3-cudnn8|11\.4-cudnn8|11\.5-cudnn8|11\.6-cudnn8|11\.7-cudnn8|11\.8-cudnn8|12\.0-cudnn8|12\.1-cudnn8|12\.2-cudnn8|12\.3-cudnn9|12\.4-cudnn9|12\.5-cudnn9|12\.6-cudnn9|12\.8-cudnn9|12\.9-cudnn9)$"
|
|
1064
1064
|
)
|
|
1065
1065
|
] = Field(
|
|
1066
1066
|
None,
|
|
@@ -1094,8 +1094,8 @@ class TrueFoundryInteractiveLogin(BaseModel):
|
|
|
1094
1094
|
|
|
1095
1095
|
class UV(BaseModel):
|
|
1096
1096
|
"""
|
|
1097
|
-
Use `uv` to setup
|
|
1098
|
-
Your build context root must contain
|
|
1097
|
+
Use `uv` to setup env.
|
|
1098
|
+
Your build context root must contain `pyproject.toml` and `uv.lock
|
|
1099
1099
|
"""
|
|
1100
1100
|
|
|
1101
1101
|
type: Literal["uv"] = Field(..., description="")
|
|
@@ -1448,7 +1448,7 @@ class PythonBuild(BaseModel):
|
|
|
1448
1448
|
)
|
|
1449
1449
|
cuda_version: Optional[
|
|
1450
1450
|
constr(
|
|
1451
|
-
regex=r"^((\d+\.\d+(\.\d+)?-cudnn\d+-(runtime|devel)-ubuntu\d+\.\d+)|11\.0-cudnn8|11\.1-cudnn8|11\.2-cudnn8|11\.3-cudnn8|11\.4-cudnn8|11\.5-cudnn8|11\.6-cudnn8|11\.7-cudnn8|11\.8-cudnn8|12\.0-cudnn8|12\.1-cudnn8|12\.2-cudnn8|12\.3-cudnn9|12\.4-cudnn9|12\.5-cudnn9|12\.6-cudnn9)$"
|
|
1451
|
+
regex=r"^((\d+\.\d+(\.\d+)?-cudnn\d+-(runtime|devel)-ubuntu\d+\.\d+)|11\.0-cudnn8|11\.1-cudnn8|11\.2-cudnn8|11\.3-cudnn8|11\.4-cudnn8|11\.5-cudnn8|11\.6-cudnn8|11\.7-cudnn8|11\.8-cudnn8|12\.0-cudnn8|12\.1-cudnn8|12\.2-cudnn8|12\.3-cudnn9|12\.4-cudnn9|12\.5-cudnn9|12\.6-cudnn9|12\.8-cudnn9|12\.9-cudnn9)$"
|
|
1452
1452
|
)
|
|
1453
1453
|
] = Field(
|
|
1454
1454
|
None,
|
|
@@ -40,6 +40,7 @@ from truefoundry.common.storage_provider_utils import (
|
|
|
40
40
|
azure_multi_part_upload,
|
|
41
41
|
decide_file_parts,
|
|
42
42
|
s3_compatible_multipart_upload,
|
|
43
|
+
truncate_path_for_progress,
|
|
43
44
|
)
|
|
44
45
|
from truefoundry.ml._autogen.client import ( # type: ignore[attr-defined]
|
|
45
46
|
ApiClient,
|
|
@@ -125,14 +126,14 @@ def _signed_url_upload_file(
|
|
|
125
126
|
augmented_raise_for_status(response, exception_class=MlFoundryException) # type: ignore
|
|
126
127
|
return
|
|
127
128
|
|
|
128
|
-
|
|
129
|
-
f"[green]
|
|
129
|
+
task_id = progress_bar.add_task(
|
|
130
|
+
f"[green]⬆ {truncate_path_for_progress(local_file, 64, relpath=True)}",
|
|
131
|
+
start=True,
|
|
132
|
+
visible=True,
|
|
130
133
|
)
|
|
131
134
|
|
|
132
135
|
def callback(length):
|
|
133
|
-
progress_bar.update(
|
|
134
|
-
task_progress_bar, advance=length, total=os.stat(local_file).st_size
|
|
135
|
-
)
|
|
136
|
+
progress_bar.update(task_id, advance=length, total=os.stat(local_file).st_size)
|
|
136
137
|
if abort_event and abort_event.is_set():
|
|
137
138
|
raise Exception("aborting upload")
|
|
138
139
|
|
|
@@ -147,6 +148,9 @@ def _signed_url_upload_file(
|
|
|
147
148
|
) as response:
|
|
148
149
|
augmented_raise_for_status(response, exception_class=MlFoundryException) # type: ignore
|
|
149
150
|
|
|
151
|
+
if progress_bar is not None:
|
|
152
|
+
progress_bar.refresh()
|
|
153
|
+
|
|
150
154
|
|
|
151
155
|
def _download_file_using_http_uri(
|
|
152
156
|
http_uri,
|
|
@@ -167,7 +171,11 @@ def _download_file_using_http_uri(
|
|
|
167
171
|
exception_class=MlFoundryException, # type: ignore
|
|
168
172
|
) as response:
|
|
169
173
|
augmented_raise_for_status(response, exception_class=MlFoundryException) # type: ignore
|
|
170
|
-
file_size = int(response.headers.get("Content-Length",
|
|
174
|
+
file_size = int(response.headers.get("Content-Length", -1))
|
|
175
|
+
if file_size == 0 and callback:
|
|
176
|
+
# special case for empty files
|
|
177
|
+
callback(1, 1)
|
|
178
|
+
file_size = file_size if file_size > 0 else 0
|
|
171
179
|
with open(download_path, "wb") as output_file:
|
|
172
180
|
for chunk in response.iter_content(chunk_size=chunk_size):
|
|
173
181
|
if callback:
|
|
@@ -658,15 +666,18 @@ class MlFoundryArtifactsRepository:
|
|
|
658
666
|
logger.info("Downloading %s to %s", remote_file_path, local_path)
|
|
659
667
|
|
|
660
668
|
if progress_bar is not None:
|
|
661
|
-
|
|
662
|
-
f"[green]
|
|
669
|
+
task_id = progress_bar.add_task(
|
|
670
|
+
f"[green]⬇ {truncate_path_for_progress(remote_file_path, 64)}",
|
|
671
|
+
start=True,
|
|
672
|
+
visible=True,
|
|
663
673
|
)
|
|
664
674
|
|
|
665
|
-
def callback(
|
|
675
|
+
def callback(chunk_size: int, total_file_size: int):
|
|
676
|
+
nonlocal task_id
|
|
666
677
|
if progress_bar is not None:
|
|
667
678
|
progress_bar.update(
|
|
668
|
-
|
|
669
|
-
advance=
|
|
679
|
+
task_id,
|
|
680
|
+
advance=chunk_size,
|
|
670
681
|
total=total_file_size,
|
|
671
682
|
)
|
|
672
683
|
if abort_event and abort_event.is_set():
|
|
@@ -677,6 +688,9 @@ class MlFoundryArtifactsRepository:
|
|
|
677
688
|
download_path=local_path,
|
|
678
689
|
callback=callback,
|
|
679
690
|
)
|
|
691
|
+
|
|
692
|
+
if progress_bar is not None:
|
|
693
|
+
progress_bar.refresh()
|
|
680
694
|
logger.debug("Downloaded %s to %s", remote_file_path, local_path)
|
|
681
695
|
|
|
682
696
|
def _download_artifact(
|
|
@@ -347,10 +347,11 @@ class ArtifactVersion:
|
|
|
347
347
|
artifact_version.download(path="<your-desired-download-path>")
|
|
348
348
|
```
|
|
349
349
|
"""
|
|
350
|
-
|
|
350
|
+
download_info = self._download(
|
|
351
351
|
path=path, overwrite=overwrite, progress=progress
|
|
352
352
|
)
|
|
353
|
-
|
|
353
|
+
logger.info("Downloaded artifact contents to %s", download_info.download_dir)
|
|
354
|
+
return download_info.download_dir
|
|
354
355
|
|
|
355
356
|
def delete(self) -> bool:
|
|
356
357
|
"""
|
|
@@ -48,13 +48,13 @@ truefoundry/common/exceptions.py,sha256=jkU0N7hV_P-EhXeud4I5vuB9glXXZSWPf8LcH04m
|
|
|
48
48
|
truefoundry/common/request_utils.py,sha256=e9qrAQ1MutU7JALDKcucmNd0KQEVBqgW3yx0w1zeHIU,5700
|
|
49
49
|
truefoundry/common/servicefoundry_client.py,sha256=2fYhdVPSvLXz5C5tosOq86JD8WM3IRUIy1VO9deDxZI,3340
|
|
50
50
|
truefoundry/common/session.py,sha256=d9l3TEBpqVP4mr4mTGY1qVxc815skzMlNNdw14otg34,2923
|
|
51
|
-
truefoundry/common/storage_provider_utils.py,sha256=
|
|
51
|
+
truefoundry/common/storage_provider_utils.py,sha256=jX9maCtWusZx63324cmPxHiGeIluZZzbDaJ1QYTIhAw,11856
|
|
52
52
|
truefoundry/common/types.py,sha256=BMJFCsR1lPJAw66IQBSvLyV4I6o_x5oj78gVsUa9si8,188
|
|
53
53
|
truefoundry/common/utils.py,sha256=P0FuAadoJGdpieUORLSN-PiFnkyoGO-K2cS4OPITBWg,6714
|
|
54
54
|
truefoundry/common/warnings.py,sha256=xDMhR_-ZGC40Ycaj6nlFb5MYPexn8WbKCHd4FlflTXQ,705
|
|
55
55
|
truefoundry/deploy/__init__.py,sha256=g_g5_XKCZZXL3v_ycQhvn01bkMHweNqhOy1rg6vc5-k,2903
|
|
56
56
|
truefoundry/deploy/python_deploy_codegen.py,sha256=WwP6bIzFoLpF7J2Bgef2HMSIeefJ8TWtSv4hXNycEzQ,8872
|
|
57
|
-
truefoundry/deploy/_autogen/models.py,sha256=
|
|
57
|
+
truefoundry/deploy/_autogen/models.py,sha256=FwhfLrqrjFWY8Mzny2hlL2ksqDfVUMFFJsPb99nJ1Mc,78183
|
|
58
58
|
truefoundry/deploy/builder/__init__.py,sha256=7MEezQzxjrWpbvnONyGMqYNVVonlb8WkARob4dHzAB4,5045
|
|
59
59
|
truefoundry/deploy/builder/constants.py,sha256=aWC94kL8I8Lty9ccJwBVncsNx4ADTgPxyBxk_zur6XM,980
|
|
60
60
|
truefoundry/deploy/builder/docker_service.py,sha256=sm7GWeIqyrKaZpxskdLejZlsxcZnM3BTDJr6orvPN4E,3948
|
|
@@ -349,7 +349,7 @@ truefoundry/ml/_autogen/models/schema.py,sha256=a_bp42MMPUbwO3407m0UW2W8EOhnxZXf
|
|
|
349
349
|
truefoundry/ml/_autogen/models/signature.py,sha256=rBjpxUIsEeWM0sIyYG5uCJB18DKHR4k5yZw8TzuoP48,4987
|
|
350
350
|
truefoundry/ml/_autogen/models/utils.py,sha256=c7RtSLXhOLcP8rjuUtfnMdaKVTZvvbsmw98gPAkAFrs,24371
|
|
351
351
|
truefoundry/ml/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
352
|
-
truefoundry/ml/artifact/truefoundry_artifact_repo.py,sha256=
|
|
352
|
+
truefoundry/ml/artifact/truefoundry_artifact_repo.py,sha256=ksqnveJm_-8l4rny_cCJqAHFIZQDQyv_FSU_GjZFHSY,36136
|
|
353
353
|
truefoundry/ml/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
354
354
|
truefoundry/ml/cli/cli.py,sha256=MwpY7z_NEeJE_XIP7XbZELjNeu2vpMmohttHCKDRk54,335
|
|
355
355
|
truefoundry/ml/cli/utils.py,sha256=j6_mZ4Spn114mz3P4QQ8jx0tmorXIuyQnHXVUSDvZi4,1035
|
|
@@ -365,11 +365,11 @@ truefoundry/ml/log_types/plot.py,sha256=LDh4uy6z2P_a2oPM2lc85c0lt8utVvunohzeMawF
|
|
|
365
365
|
truefoundry/ml/log_types/pydantic_base.py,sha256=eBlw_AEyAz4iJKDP4zgJOCFWcldwQqpf7FADW1jzIQY,272
|
|
366
366
|
truefoundry/ml/log_types/utils.py,sha256=xjJ21jdPScvFmw3TbVh5NCzbzJwaqiXJyiiT4xxX1EI,335
|
|
367
367
|
truefoundry/ml/log_types/artifacts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
368
|
-
truefoundry/ml/log_types/artifacts/artifact.py,sha256=
|
|
368
|
+
truefoundry/ml/log_types/artifacts/artifact.py,sha256=OXJDaJZLGE8jA-6A8pdApfpbz1x3O-8rIMWUkG_8hYA,19940
|
|
369
369
|
truefoundry/ml/log_types/artifacts/constants.py,sha256=7blG13UXSkZVZkN8EDFqaH-a_ZonJA6pI0gwJwkIZ-s,1298
|
|
370
370
|
truefoundry/ml/log_types/artifacts/dataset.py,sha256=OgWIoT59AhMw8P01FfvUKbJ3EL6HQf_Xw8X4E3Ff5Sg,13172
|
|
371
371
|
truefoundry/ml/log_types/artifacts/general_artifact.py,sha256=yr-SQ2fhUR_sE1MB5zoHHYpGC8tizH_-t3lhsxCAULU,2747
|
|
372
|
-
truefoundry/ml/log_types/artifacts/model.py,sha256=
|
|
372
|
+
truefoundry/ml/log_types/artifacts/model.py,sha256=j4Gf0TKpi-JCOBqCdkH40pkpDLwvSk04KgQn2sK5fZI,24911
|
|
373
373
|
truefoundry/ml/log_types/artifacts/utils.py,sha256=INZhhzl6OaD6qFAyxaLJAhXhFd6wKNujMj-lq2v8p4Q,9340
|
|
374
374
|
truefoundry/ml/log_types/image/__init__.py,sha256=fcOq8yQnNj1rkLcPeIjLXBpdA1WIeiPsXOlAAvMxx7M,76
|
|
375
375
|
truefoundry/ml/log_types/image/constants.py,sha256=wLtGEOA4T5fZHSlOXPuNDLX3lpbCtwlvGKPFk_1fah0,255
|
|
@@ -387,7 +387,7 @@ truefoundry/workflow/remote_filesystem/__init__.py,sha256=LQ95ViEjJ7Ts4JcCGOxMPs
|
|
|
387
387
|
truefoundry/workflow/remote_filesystem/logger.py,sha256=em2l7D6sw7xTLDP0kQSLpgfRRCLpN14Qw85TN7ujQcE,1022
|
|
388
388
|
truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py,sha256=xcT0wQmQlgzcj0nP3tJopyFSVWT1uv3nhiTIuwfXYeg,12342
|
|
389
389
|
truefoundry/workflow/remote_filesystem/tfy_signed_url_fs.py,sha256=nSGPZu0Gyd_jz0KsEE-7w_BmnTD8CVF1S8cUJoxaCbc,13305
|
|
390
|
-
truefoundry-0.
|
|
391
|
-
truefoundry-0.
|
|
392
|
-
truefoundry-0.
|
|
393
|
-
truefoundry-0.
|
|
390
|
+
truefoundry-0.12.0rc1.dist-info/METADATA,sha256=NxF_EilSNyo5V3bU2FYER04ratIXGFMzB1tzM5BC6H8,2799
|
|
391
|
+
truefoundry-0.12.0rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
392
|
+
truefoundry-0.12.0rc1.dist-info/entry_points.txt,sha256=xVjn7RMN-MW2-9f7YU-bBdlZSvvrwzhpX1zmmRmsNPU,98
|
|
393
|
+
truefoundry-0.12.0rc1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|