truefoundry 0.7.3rc1__py3-none-any.whl → 0.9.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/cli/util.py CHANGED
@@ -51,6 +51,9 @@ def handle_exception(exception):
51
51
  title="Command Failed",
52
52
  border_style="red",
53
53
  )
54
+ elif isinstance(exception, KeyError):
55
+ # KeyError messages in Python just suck - they tell you the key that was missing, but not the context
56
+ console.print_exception(show_locals=False, max_frames=1)
54
57
  else:
55
58
  print_dict_as_table_panel(
56
59
  {"Error": str(exception)},
@@ -109,6 +109,9 @@ class PythonSDKConfig(BaseModel):
109
109
  use_sfy_server_auth_apis: Optional[bool] = Field(
110
110
  alias="useSFYServerAuthAPIs", default=False
111
111
  )
112
+ python_build_default_image_tag: str = Field(
113
+ alias="pythonBuildDefaultImageTag", default="3.11"
114
+ )
112
115
 
113
116
 
114
117
  class DeviceCode(BaseModel):
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: application.json
3
- # timestamp: 2025-05-03T01:45:46+00:00
3
+ # timestamp: 2025-05-15T05:28:11+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -360,13 +360,6 @@ class Image(BaseModel):
360
360
  )
361
361
 
362
362
 
363
- class JobEvent(str, Enum):
364
- START = "START"
365
- SUCCEEDED = "SUCCEEDED"
366
- FAILED = "FAILED"
367
- TERMINATED = "TERMINATED"
368
-
369
-
370
363
  class Claim(BaseModel):
371
364
  key: str
372
365
  values: List[str]
@@ -623,9 +616,11 @@ class PythonBuild(BaseModel):
623
616
  """
624
617
 
625
618
  type: Literal["tfy-python-buildpack"] = Field(..., description="")
626
- python_version: constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$") = Field(
627
- "3.11",
628
- description="Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python)",
619
+ python_version: Optional[constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$")] = (
620
+ Field(
621
+ None,
622
+ description="Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python)",
623
+ )
629
624
  )
630
625
  build_context_path: str = Field(
631
626
  "./", description="Build path relative to project root path."
@@ -963,9 +958,11 @@ class TaskPythonBuild(BaseModel):
963
958
  None,
964
959
  description="FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
965
960
  )
966
- python_version: constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$") = Field(
967
- "3.11",
968
- description="Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python)",
961
+ python_version: Optional[constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$")] = (
962
+ Field(
963
+ None,
964
+ description="Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python)",
965
+ )
969
966
  )
970
967
  requirements_path: Optional[str] = Field(
971
968
  None,
@@ -1060,13 +1057,6 @@ class WorkbenchImage(BaseModel):
1060
1057
  )
1061
1058
 
1062
1059
 
1063
- class WorkflowEvent(str, Enum):
1064
- SUCCEEDED = "SUCCEEDED"
1065
- FAILED = "FAILED"
1066
- ABORTED = "ABORTED"
1067
- TIMED_OUT = "TIMED_OUT"
1068
-
1069
-
1070
1060
  class ArtifactsDownload(BaseModel):
1071
1061
  """
1072
1062
  Download and cache models in a volume to enhance loading speeds and reduce costs by avoiding repeated downloads. [Docs](https://docs.truefoundry.com/docs/download-and-cache-models)
@@ -1485,10 +1475,6 @@ class WorkflowAlert(BaseModel):
1485
1475
  """
1486
1476
 
1487
1477
  notification_target: Optional[Union[Email, SlackWebhook, SlackBot]] = None
1488
- events: List[WorkflowEvent] = Field(
1489
- ...,
1490
- description="Specify the events to send alerts for, it should be one of the following: SUCCEEDED, FAILED, ABORTED, TIMED_OUT",
1491
- )
1492
1478
  on_completion: bool = Field(
1493
1479
  False, description="Send an alert when the job completes"
1494
1480
  )
@@ -1556,10 +1542,6 @@ class JobAlert(BaseModel):
1556
1542
  description="List of recipients' email addresses if the notification channel is Email.",
1557
1543
  )
1558
1544
  notification_target: Optional[Union[Email, SlackWebhook, SlackBot]] = None
1559
- events: List[JobEvent] = Field(
1560
- ...,
1561
- description="Specify the events to send alerts for, it should be one of the following: START, SUCCEEDED, FAILED, TERMINATED",
1562
- )
1563
1545
  on_start: bool = Field(False, description="Send an alert when the job starts")
1564
1546
  on_completion: bool = False
1565
1547
  on_failure: bool = Field(True, description="Send an alert when the job fails")
@@ -36,6 +36,10 @@ def build(
36
36
  build_configuration: PythonBuild,
37
37
  extra_opts: Optional[List[str]] = None,
38
38
  ):
39
+ if not build_configuration.python_version:
40
+ raise ValueError(
41
+ "`python_version` is required for `tfy-python-buildpack` builder"
42
+ )
39
43
  mount_python_package_manager_conf_secret = (
40
44
  has_python_package_manager_conf_secret(extra_opts) if extra_opts else False
41
45
  )
@@ -174,6 +174,10 @@ def generate_dockerfile_content(
174
174
  requirements_destination_path = (
175
175
  "/tmp/requirements.txt" if requirements_path else None
176
176
  )
177
+ if not build_configuration.python_version:
178
+ raise ValueError(
179
+ "`python_version` is required for `tfy-python-buildpack` builder"
180
+ )
177
181
  if package_manager == PythonPackageManager.PIP.value:
178
182
  python_packages_install_command = generate_pip_install_command(
179
183
  requirements_path=requirements_destination_path,
@@ -25,6 +25,19 @@ from truefoundry.pydantic_v1 import BaseModel
25
25
  Component = TypeVar("Component", bound=BaseModel)
26
26
 
27
27
 
28
+ def _set_python_version_if_missing(build_spec: autogen_models.PythonBuild) -> None:
29
+ if build_spec.python_version is None:
30
+ client = ServiceFoundryServiceClient()
31
+ server_default_python_version = (
32
+ client.python_sdk_config.python_build_default_image_tag
33
+ )
34
+ logger.warning(
35
+ f"No python version was provided in the spec, "
36
+ f"using the default python version ({server_default_python_version}) from the server."
37
+ )
38
+ build_spec.python_version = server_default_python_version
39
+
40
+
28
41
  def _handle_if_local_source(component: Component, workspace_fqn: str) -> Component:
29
42
  if (
30
43
  hasattr(component, "image")
@@ -33,7 +46,7 @@ def _handle_if_local_source(component: Component, workspace_fqn: str) -> Compone
33
46
  ):
34
47
  new_component = component.copy(deep=True)
35
48
 
36
- if component.image.build_source.local_build:
49
+ if new_component.image.build_source.local_build:
37
50
  if not env_has_docker():
38
51
  logger.warning(
39
52
  "Did not find Docker locally installed on this system, image will be built remotely. "
@@ -64,25 +77,33 @@ def _handle_if_local_source(component: Component, workspace_fqn: str) -> Compone
64
77
  local_build = False
65
78
 
66
79
  if local_build:
80
+ if isinstance(new_component.image.build_spec, autogen_models.PythonBuild):
81
+ _set_python_version_if_missing(new_component.image.build_spec)
67
82
  # We are to build the image locally, push and update `image` in spec
68
- logger.info("Building image for %s '%s'", component.type, component.name)
83
+ logger.info(
84
+ "Building image for %s '%s'", new_component.type, new_component.name
85
+ )
69
86
  new_component.image = local_source_to_image(
70
- build=component.image,
71
- docker_registry_fqn=component.image.docker_registry,
87
+ build=new_component.image,
88
+ docker_registry_fqn=new_component.image.docker_registry,
72
89
  workspace_fqn=workspace_fqn,
73
- component_name=component.name,
90
+ component_name=new_component.name,
74
91
  )
75
92
  else:
76
93
  # We'll build image on TrueFoundry servers, upload the source and update image.build_source
77
- logger.info("Uploading code for %s '%s'", component.type, component.name)
94
+ logger.info(
95
+ "Uploading code for %s '%s'", new_component.type, new_component.name
96
+ )
78
97
  client = ServiceFoundryServiceClient()
79
98
  new_component.image.build_source = local_source_to_remote_source(
80
- local_source=component.image.build_source,
99
+ local_source=new_component.image.build_source,
81
100
  workspace_fqn=workspace_fqn,
82
- component_name=component.name,
101
+ component_name=new_component.name,
83
102
  upload_code_package=client.upload_code_package,
84
103
  )
85
- logger.debug("Uploaded code for %s '%s'", component.type, component.name)
104
+ logger.debug(
105
+ "Uploaded code for %s '%s'", new_component.type, new_component.name
106
+ )
86
107
  return new_component
87
108
  return component
88
109
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: truefoundry
3
- Version: 0.7.3rc1
3
+ Version: 0.9.0rc1
4
4
  Summary: TrueFoundry CLI
5
5
  Author-email: TrueFoundry Team <abhishek@truefoundry.com>
6
6
  Requires-Python: <3.14,>=3.8.1
@@ -31,7 +31,7 @@ Requires-Dist: requirements-parser<0.12.0,>=0.11.0
31
31
  Requires-Dist: rich-click<2.0.0,>=1.2.1
32
32
  Requires-Dist: rich<14.0.0,>=13.7.1
33
33
  Requires-Dist: tqdm<5.0.0,>=4.0.0
34
- Requires-Dist: truefoundry-sdk==0.1.0
34
+ Requires-Dist: truefoundry-sdk<0.2.0,>=0.1.1
35
35
  Requires-Dist: typing-extensions>=4.0
36
36
  Requires-Dist: urllib3<3,>=1.26.18
37
37
  Requires-Dist: yq<4.0.0,>=3.1.0
@@ -33,13 +33,13 @@ truefoundry/cli/config.py,sha256=f7z0_gmYZiNImB7Bxz0AnOlrxY2X4lFnX4jYW1I7NHQ,139
33
33
  truefoundry/cli/console.py,sha256=9-dMy4YPisCJQziRKTg8Qa0UJnOGl1soiUnJjsnLDvE,242
34
34
  truefoundry/cli/const.py,sha256=dVHPo1uAiDSSMXwXoT2mR5kNQjExT98QNVRz98Hz_Ts,510
35
35
  truefoundry/cli/display_util.py,sha256=s0_eWUUAK1dbmqW5h_qAG93roH81dh-g1nLjuQVFm6k,5130
36
- truefoundry/cli/util.py,sha256=BjDUG4WU8iF540YdrBtBQI2WqfNAYyk9iuMiKq7b6jk,3705
36
+ truefoundry/cli/util.py,sha256=7DmKXY5OPslPu2LO6vrUUfDtoHeo12sJTDUA0GOi8IM,3922
37
37
  truefoundry/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
38
  truefoundry/common/auth_service_client.py,sha256=N3YxKlx63r6cPZqbgb2lqBOPI69ShB7D7RCIq4FSCjc,7949
39
39
  truefoundry/common/constants.py,sha256=eWcElAYIVb0jnHUAcsHvgnkdKf2E1nCg_Ybbi8ibxF0,4365
40
40
  truefoundry/common/credential_file_manager.py,sha256=1yEk1Zm2xS4G0VDFwKSZ4w0VUrcPWQ1nJnoBaz9xyKA,4251
41
41
  truefoundry/common/credential_provider.py,sha256=_OhJ2XFlDaVsrUO-FyywxctcGGqDdC2pgcvwEKqQD0Q,4071
42
- truefoundry/common/entities.py,sha256=ko33kesGy3vI9NJ5Ganq8HpnaURTOHictr6h75764no,3893
42
+ truefoundry/common/entities.py,sha256=b4R6ss06-ygDS3C4Tqa_GOq5LFKDYbt7x4Mghnfz6yo,4007
43
43
  truefoundry/common/exceptions.py,sha256=jkU0N7hV_P-EhXeud4I5vuB9glXXZSWPf8LcH04mSbw,459
44
44
  truefoundry/common/request_utils.py,sha256=e9qrAQ1MutU7JALDKcucmNd0KQEVBqgW3yx0w1zeHIU,5700
45
45
  truefoundry/common/servicefoundry_client.py,sha256=2fYhdVPSvLXz5C5tosOq86JD8WM3IRUIy1VO9deDxZI,3340
@@ -50,7 +50,7 @@ truefoundry/common/utils.py,sha256=j3QP0uOsaGD_VmDDR68JTwoYE1okkAq6OqpVkzVf48Q,6
50
50
  truefoundry/common/warnings.py,sha256=rs6BHwk7imQYedo07iwh3TWEOywAR3Lqhj0AY4khByg,504
51
51
  truefoundry/deploy/__init__.py,sha256=6D22iiCgd5xlzBaG34q9Cx4rGgwf5qIAKQrOCgaCXYY,2746
52
52
  truefoundry/deploy/python_deploy_codegen.py,sha256=AainOFR20XvhNeztJkLPWGZ40lAT_nwc-ZmG77Kum4o,6525
53
- truefoundry/deploy/_autogen/models.py,sha256=p6sZVLmrFbzujNW6PzjGbPA1OiNhq5TgX5tH0evJvRE,72038
53
+ truefoundry/deploy/_autogen/models.py,sha256=gGH63evQTTnU0fEjtNgCsD0aqIxhdp316GL3Xb65NJk,71461
54
54
  truefoundry/deploy/builder/__init__.py,sha256=nGQiR3r16iumRy7xbVQ6q-k0EApmijspsfVpXDE-9po,4953
55
55
  truefoundry/deploy/builder/constants.py,sha256=amUkHoHvVKzGv0v_knfiioRuKiJM0V0xW0diERgWiI0,508
56
56
  truefoundry/deploy/builder/docker_service.py,sha256=sm7GWeIqyrKaZpxskdLejZlsxcZnM3BTDJr6orvPN4E,3948
@@ -59,8 +59,8 @@ truefoundry/deploy/builder/builders/__init__.py,sha256=tlFLXqyDaKLd4iZbo4Hcu_8gO
59
59
  truefoundry/deploy/builder/builders/dockerfile.py,sha256=XMbMlPUTMPCyaHl7jJQY1ODtlRkpI61PcvgG6Ck5jNc,1522
60
60
  truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py,sha256=RGWGqY8xOF7vycUPJd10N7ZzahWv24lO0anrOPtLuDU,1796
61
61
  truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py,sha256=rQgdvKmAT9HArVW4TAG5yd2QTKRs3S5LJ9RQbc_EkHE,2518
62
- truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py,sha256=wnPwIIArn1H_g4CeTNl5W7EaqRq5FbWDnJpd6E4RSDY,1864
63
- truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=2KnYTL6yhy0KdiTjSkRfEj_gyCYtmDa2ZsnB06tOpT8,8973
62
+ truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py,sha256=_fjqHKn80qKi68SAMMALge7_A6e1sTsQWichw8uoGIw,2025
63
+ truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=f4l3fH21E2b8W3-JotMKc0AdPcCxV7LRPxxYJa7z_UQ,9134
64
64
  truefoundry/deploy/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  truefoundry/deploy/cli/commands/__init__.py,sha256=f7sXiQK9UuxDJmvBa-QCFNyumUpGGMhZbCxdwJzWXwQ,1116
66
66
  truefoundry/deploy/cli/commands/apply_command.py,sha256=Y2e_C8HVpo8CssVod-3JRz-89qStC5JRaNzJ7O2mRlY,2039
@@ -107,7 +107,7 @@ truefoundry/deploy/lib/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
107
107
  truefoundry/deploy/lib/model/entity.py,sha256=Bp9sLB-M5INCpw5lPmFdygHWS1zvnLicnSiSCi2iqhQ,8591
108
108
  truefoundry/deploy/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  truefoundry/deploy/v2/lib/__init__.py,sha256=WEiVMZXOVljzEE3tpGJil14liIn_PCDoACJ6b3tZ6sI,188
110
- truefoundry/deploy/v2/lib/deploy.py,sha256=EOqVQTCMrvs_Kwp8Ft0FZYlRErPuFq4eDBDR1qEZ7_E,11767
110
+ truefoundry/deploy/v2/lib/deploy.py,sha256=kAnh6RO4ci7AVjlIoN1Sr5FmcOU7nbkwNvbrS802spY,12625
111
111
  truefoundry/deploy/v2/lib/deploy_workflow.py,sha256=G5BzMIbap8pgDX1eY-TITruUxQdkKhYtBmRwLL6lDeY,14342
112
112
  truefoundry/deploy/v2/lib/deployable_patched_models.py,sha256=xbHFD3pURflvCm8EODPvjfvRrv67mlSrjPUknY8SMB8,4060
113
113
  truefoundry/deploy/v2/lib/models.py,sha256=ogc1UYs1Z2nBdGSKCrde9sk8d0GxFKMkem99uqO5CmM,1148
@@ -375,7 +375,7 @@ truefoundry/workflow/remote_filesystem/__init__.py,sha256=LQ95ViEjJ7Ts4JcCGOxMPs
375
375
  truefoundry/workflow/remote_filesystem/logger.py,sha256=em2l7D6sw7xTLDP0kQSLpgfRRCLpN14Qw85TN7ujQcE,1022
376
376
  truefoundry/workflow/remote_filesystem/tfy_signed_url_client.py,sha256=xcT0wQmQlgzcj0nP3tJopyFSVWT1uv3nhiTIuwfXYeg,12342
377
377
  truefoundry/workflow/remote_filesystem/tfy_signed_url_fs.py,sha256=nSGPZu0Gyd_jz0KsEE-7w_BmnTD8CVF1S8cUJoxaCbc,13305
378
- truefoundry-0.7.3rc1.dist-info/METADATA,sha256=lZHcPxXnM4vcAzc06dsU8ssksI2aCkSOoplZR9of_TA,2461
379
- truefoundry-0.7.3rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
380
- truefoundry-0.7.3rc1.dist-info/entry_points.txt,sha256=xVjn7RMN-MW2-9f7YU-bBdlZSvvrwzhpX1zmmRmsNPU,98
381
- truefoundry-0.7.3rc1.dist-info/RECORD,,
378
+ truefoundry-0.9.0rc1.dist-info/METADATA,sha256=Jke--bMLUmA_EhDKqqVyPODCMgbsIHC0W7yH2nRsjqk,2468
379
+ truefoundry-0.9.0rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
380
+ truefoundry-0.9.0rc1.dist-info/entry_points.txt,sha256=xVjn7RMN-MW2-9f7YU-bBdlZSvvrwzhpX1zmmRmsNPU,98
381
+ truefoundry-0.9.0rc1.dist-info/RECORD,,