truefoundry 0.4.6__py3-none-any.whl → 0.4.7__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.

@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: application.json
3
- # timestamp: 2024-10-16T17:06:03+00:00
3
+ # timestamp: 2024-11-04T08:35:21+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -315,7 +315,7 @@ class GitHelmRepo(BaseModel):
315
315
  regex=r"^(((https?|wss):\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*))$"
316
316
  ) = Field(
317
317
  ...,
318
- description="+label=Git repository URL\n+sort=1\n+message=Needs to be a valid URL.\nTODO: Check this regex and add guidelines",
318
+ description="TODO: Check this regex and add guidelines\n+label=Git repository URL\n+sort=1\n+message=Needs to be a valid URL.",
319
319
  )
320
320
  revision: str = Field(
321
321
  ...,
@@ -1151,7 +1151,7 @@ class VolumeMount(BaseModel):
1151
1151
  ...,
1152
1152
  description="+label=Volume mount path\n+usage=Absolute file path where the volume will be mounted.\n+message=Please enter a valid mount path",
1153
1153
  )
1154
- sub_path: Optional[str] = Field(
1154
+ sub_path: Optional[constr(regex=r"^(?:[^/\n]+/*)*[^/\n]+(\.[^/\n]+)?$")] = Field(
1155
1155
  None,
1156
1156
  description="+label=Sub Path\n+usage=Sub path within the volume to mount. Defaults to root of the volume.",
1157
1157
  )
@@ -1285,7 +1285,7 @@ class Codeserver(BaseWorkbenchInput):
1285
1285
 
1286
1286
 
1287
1287
  class ContainerTaskConfig(BaseModel):
1288
- type: constr(regex=r"^container-task-config$") = Field(
1288
+ type: Literal["container-task-config"] = Field(
1289
1289
  ..., description="+value=container-task-config"
1290
1290
  )
1291
1291
  image: Union[Build, Image] = Field(
@@ -1301,7 +1301,9 @@ class ContainerTaskConfig(BaseModel):
1301
1301
  None,
1302
1302
  description="+usage=Configure data to be mounted to Workflow pod(s) as a volume.\n+sort=400",
1303
1303
  )
1304
- service_account: str = Field(..., description="+label=Service Account\n+sort=500")
1304
+ service_account: Optional[str] = Field(
1305
+ None, description="+label=Service Account\n+sort=500"
1306
+ )
1305
1307
 
1306
1308
 
1307
1309
  class CoreNATSOutputConfig(BaseModel):
@@ -1559,7 +1561,7 @@ class PythonTaskConfig(BaseModel):
1559
1561
  +docs=Describes the configuration for the python function task
1560
1562
  """
1561
1563
 
1562
- type: constr(regex=r"^python-task-config$") = Field(
1564
+ type: Literal["python-task-config"] = Field(
1563
1565
  ..., description="+value=python-task-config"
1564
1566
  )
1565
1567
  image: Union[TaskPythonBuild, TaskDockerFileBuild] = Field(
@@ -1575,7 +1577,9 @@ class PythonTaskConfig(BaseModel):
1575
1577
  None,
1576
1578
  description="+usage=Configure data to be mounted to Workflow pod(s) as a volume.\n+sort=400",
1577
1579
  )
1578
- service_account: str = Field(..., description="+label=Service Account\n+sort=500")
1580
+ service_account: Optional[str] = Field(
1581
+ None, description="+label=Service Account\n+sort=500"
1582
+ )
1579
1583
 
1580
1584
 
1581
1585
  class SSHServer(BaseWorkbenchInput):
@@ -1722,7 +1726,7 @@ class Workflow(BaseModel):
1722
1726
  +docs=Describes the configuration for the worflow
1723
1727
  """
1724
1728
 
1725
- type: constr(regex=r"^workflow$") = Field(..., description="+value=workflow")
1729
+ type: Literal["workflow"] = Field(..., description="+value=workflow")
1726
1730
  name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1727
1731
  ...,
1728
1732
  description="+usage=Name of the workflow\n+sort=1\n+message=3 to 32 lower case characters long alphanumeric word, may contain - in between, cannot start with a number",
@@ -111,6 +111,7 @@ def convert_deployment_config_to_python(workspace_fqn: str, application_spec: di
111
111
  application_type = application_obj.type
112
112
  if (
113
113
  hasattr(application_obj, "image")
114
+ and hasattr(application_obj.image, "type")
114
115
  and application_obj.image.type == "build"
115
116
  and application_obj.image.build_source.type == "remote"
116
117
  ):
@@ -1,4 +1,6 @@
1
1
  # file: client.py
2
+ import io
3
+ import os
2
4
  from enum import Enum
3
5
  from typing import Any, Dict, List, Optional, Union
4
6
  from urllib.parse import urlencode, urljoin
@@ -125,7 +127,12 @@ class SignedURLClient:
125
127
  )
126
128
 
127
129
  @log_time(prefix=LOG_PREFIX)
128
- def _upload_data(self, signed_url: str, data: Any) -> None:
130
+ def _upload_data(
131
+ self,
132
+ signed_url: str,
133
+ data: Union[bytes, io.BufferedReader],
134
+ headers: Optional[Dict] = None,
135
+ ) -> None:
129
136
  """
130
137
  Upload data to the specified storage path using a signed URL.
131
138
 
@@ -133,10 +140,15 @@ class SignedURLClient:
133
140
  signed_url: str: The signed URL to upload the data to.
134
141
  data: Bytes or IO: The data to upload.
135
142
  """
143
+ if isinstance(data, io.BufferedReader):
144
+ if os.fstat(data.fileno()).st_size == 0:
145
+ data = b""
136
146
  try:
147
+ headers = headers or {}
148
+ headers["Content-Type"] = "application/octet-stream"
137
149
  response = self.session.put(
138
150
  url=signed_url,
139
- headers={"Content-Type": "application/octet-stream"},
151
+ headers=headers,
140
152
  data=data,
141
153
  timeout=REQUEST_TIMEOUT,
142
154
  )
@@ -153,7 +165,11 @@ class SignedURLClient:
153
165
  headers=self.signed_url_server_headers,
154
166
  )
155
167
  pre_signed_object_dto = SignedURLAPIResponseDto.parse_obj(signed_object)
156
- self._upload_data(pre_signed_object_dto.signed_url, data)
168
+ self._upload_data(
169
+ signed_url=pre_signed_object_dto.signed_url,
170
+ data=data,
171
+ headers=pre_signed_object_dto.headers,
172
+ )
157
173
  return storage_uri
158
174
 
159
175
  @log_time(prefix=LOG_PREFIX)
@@ -167,19 +183,30 @@ class SignedURLClient:
167
183
  )
168
184
  pre_signed_object_dto = SignedURLAPIResponseDto.parse_obj(response)
169
185
  with open(file_path, "rb") as file:
170
- self._upload_data(pre_signed_object_dto.signed_url, file)
186
+ self._upload_data(
187
+ signed_url=pre_signed_object_dto.signed_url,
188
+ data=file,
189
+ headers=pre_signed_object_dto.headers,
190
+ )
171
191
  return storage_uri
172
192
 
173
193
  @log_time(prefix=LOG_PREFIX)
174
194
  def _download_file(
175
- self, signed_url: str, local_path: Optional[str] = None
195
+ self,
196
+ signed_url: str,
197
+ local_path: Optional[str] = None,
198
+ headers: Optional[Dict] = None,
176
199
  ) -> Optional[bytes]:
177
200
  """Common method to download a file using a signed URL."""
178
201
  try:
202
+ if headers is None:
203
+ headers = {"Content-Type": "application/octet-stream"}
204
+ else:
205
+ headers["Content-Type"] = "application/octet-stream"
179
206
  response = self.session.get(
180
207
  signed_url,
181
208
  stream=True,
182
- headers={"Content-Type": "application/octet-stream"},
209
+ headers=headers,
183
210
  timeout=REQUEST_TIMEOUT,
184
211
  )
185
212
  response.raise_for_status()
@@ -202,7 +229,11 @@ class SignedURLClient:
202
229
  headers=self.signed_url_server_headers,
203
230
  )
204
231
  presigned_object = SignedURLAPIResponseDto.parse_obj(response)
205
- self._download_file(presigned_object.signed_url, local_path)
232
+ self._download_file(
233
+ signed_url=presigned_object.signed_url,
234
+ local_path=local_path,
235
+ headers=presigned_object.headers,
236
+ )
206
237
  return local_path
207
238
 
208
239
  @log_time(prefix=LOG_PREFIX)
@@ -214,7 +245,9 @@ class SignedURLClient:
214
245
  headers=self.signed_url_server_headers,
215
246
  )
216
247
  presigned_object = SignedURLAPIResponseDto.parse_obj(response)
217
- return self._download_file(presigned_object.signed_url)
248
+ return self._download_file(
249
+ signed_url=presigned_object.signed_url, headers=presigned_object.headers
250
+ )
218
251
 
219
252
  @log_time(prefix=LOG_PREFIX)
220
253
  def exists(self, uri: str) -> bool:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: truefoundry
3
- Version: 0.4.6
3
+ Version: 0.4.7
4
4
  Summary: Truefoundry CLI
5
5
  Author: Abhishek Choudhary
6
6
  Author-email: abhishek@truefoundry.com
@@ -36,7 +36,7 @@ truefoundry/common/request_utils.py,sha256=5xw4YGUcMf71Ncal3OfFCa-PoWDIvG3hYGCDa
36
36
  truefoundry/common/servicefoundry_client.py,sha256=2fxmgCM-ckFHpnm6n_mL-5Z8RWN_q-dYVvFC29bkYSg,3120
37
37
  truefoundry/common/utils.py,sha256=MYFjNtHGqauqhj9tmbdErCJR49AfXDwg-5kYbBh8HpI,3258
38
38
  truefoundry/deploy/__init__.py,sha256=ugawKF2G02EmEXX35oZ2tec12d9oWN28Sf6mtGGIERY,2281
39
- truefoundry/deploy/auto_gen/models.py,sha256=4MaxkG2_5Wg6avaZRlK0D4JiVEM5rk3NU0BCiTx8VyU,82477
39
+ truefoundry/deploy/auto_gen/models.py,sha256=8848BDbq2hO8Y75LsBH3cS0vi8qEOKU5x6oBtVmYorE,82552
40
40
  truefoundry/deploy/builder/__init__.py,sha256=1qjHMNBE1poRCZW0WrG46dFM1f1IlivD5352qzsioMU,4953
41
41
  truefoundry/deploy/builder/builders/__init__.py,sha256=tlFLXqyDaKLd4iZbo4Hcu_8gOmgtL6drnXpbmQ6x1P8,636
42
42
  truefoundry/deploy/builder/builders/dockerfile.py,sha256=AXXTziCkaqIhuM_bwyD1vT1znOwemN1TKgU7eyo-KuM,1522
@@ -107,7 +107,7 @@ truefoundry/deploy/lib/model/entity.py,sha256=fq8hvdJQgQn4uZqxpKrzmaoJhQG53_EbDo
107
107
  truefoundry/deploy/lib/session.py,sha256=Vg6rCA315T0yS0xG4ayJ84Ia_9ZfibH8utOSwPBMAmw,4953
108
108
  truefoundry/deploy/lib/util.py,sha256=3TapV7yczkheC1MMMfmJDGGzTl2l6e4jCYd_Rr5aoQ8,1330
109
109
  truefoundry/deploy/lib/win32.py,sha256=1RcvPTdlOAJ48rt8rCbE2Ufha2ztRqBAE9dueNXArrY,5009
110
- truefoundry/deploy/python_deploy_codegen.py,sha256=z9VSETb3Lrqn7sUD75EksbmA1vRiEl0LNnz9PTqF8ZM,6462
110
+ truefoundry/deploy/python_deploy_codegen.py,sha256=qJHH1BJQII9e6PhkcRFYiE_3De7_VMMm8nM4AX5Eq1o,6513
111
111
  truefoundry/deploy/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
112
  truefoundry/deploy/v2/lib/__init__.py,sha256=WEiVMZXOVljzEE3tpGJil14liIn_PCDoACJ6b3tZ6sI,188
113
113
  truefoundry/deploy/v2/lib/deploy.py,sha256=HIcY3SzQ5lWl7avuuKi3J0Z-PBES6Sf4hgMK-m6_53U,11990
@@ -351,11 +351,11 @@ truefoundry/workflow/map_task.py,sha256=2m3qGXQ90k9LdS45q8dqCCECc3qr8t2m_LMCVd1m
351
351
  truefoundry/workflow/python_task.py,sha256=SRXRLC4vdBqGjhkwuaY39LEWN6iPCpJAuW17URRdWTY,1128
352
352
  truefoundry/workflow/remote_filesystem/__init__.py,sha256=LQ95ViEjJ7Ts4JcCGOxMPs7NZmQdZ4bTiq6qXtsjUhE,206
353
353
  truefoundry/workflow/remote_filesystem/logger.py,sha256=em2l7D6sw7xTLDP0kQSLpgfRRCLpN14Qw85TN7ujQcE,1022
354
- truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py,sha256=ln3zx72jMElZQIVbPRHVd0OfmsLnDbnrntfJ6g1WdfE,10174
354
+ truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py,sha256=5mBCIc-ON7VSTzdyczeADgqSX5oJgso5gq2yT2AQqTY,11085
355
355
  truefoundry/workflow/remote_filesystem/tfy_signed_url_fs.py,sha256=Hf6Dk6Fu6P7DqsK5ULgraf9DStjgigf-kjaRAMBW-RU,8680
356
356
  truefoundry/workflow/task.py,sha256=ToitYiKcNzFCtOVQwz1W8sRjbR97eVS7vQBdbgUQtKg,1779
357
357
  truefoundry/workflow/workflow.py,sha256=WaTqUjhwfAXDWu4E5ehuwAxrCbDJkoAf1oWmR2E9Qy0,4575
358
- truefoundry-0.4.6.dist-info/METADATA,sha256=xMHeMDZtsbcVayGsYdRaNH6uMXROl-lx1759kIXYwS8,3098
359
- truefoundry-0.4.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
360
- truefoundry-0.4.6.dist-info/entry_points.txt,sha256=TXvUxQkI6zmqJuycPsyxEIMr3oqfDjgrWj0m_9X12x4,95
361
- truefoundry-0.4.6.dist-info/RECORD,,
358
+ truefoundry-0.4.7.dist-info/METADATA,sha256=L-O9o1NRO2dM02aod9MzXzuAcSBp_IfpEAl8Zp5tmUc,3098
359
+ truefoundry-0.4.7.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
360
+ truefoundry-0.4.7.dist-info/entry_points.txt,sha256=TXvUxQkI6zmqJuycPsyxEIMr3oqfDjgrWj0m_9X12x4,95
361
+ truefoundry-0.4.7.dist-info/RECORD,,