truefoundry 0.4.3__py3-none-any.whl → 0.4.4rc1__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,14 +1,32 @@
1
+ import os
1
2
  from pathlib import Path
3
+ from typing import Optional
4
+
5
+ from truefoundry.pydantic_v1 import BaseSettings, Field, SecretStr
2
6
 
3
7
  TFY_CONFIG_DIR = Path.home() / ".truefoundry"
4
8
  CREDENTIAL_FILEPATH = TFY_CONFIG_DIR / "credentials.json"
5
9
 
10
+ # These keys are kept separately because we use them in error messages and some checks
6
11
  TFY_HOST_ENV_KEY = "TFY_HOST"
7
12
  TFY_API_KEY_ENV_KEY = "TFY_API_KEY"
8
- TFY_CLI_LOCAL_DEV_MODE_ENV_KEY = "TFY_CLI_LOCAL_DEV_MODE"
9
- TFY_CLI_PYTHONBUILD_PYTHON_IMAGE_REPO_ENV_KEY = "TFY_CLI_PYTHONBUILD_PYTHON_IMAGE_REPO"
10
13
 
11
14
 
15
+ class TrueFoundrySdkEnv(BaseSettings):
16
+ # Note: Every field in this class should have a default value
17
+ # Never expect the user to set these values
18
+ TFY_HOST: Optional[str] = Field(default=None, env=TFY_HOST_ENV_KEY)
19
+ TFY_API_KEY: Optional[SecretStr] = Field(default=None, env=TFY_API_KEY_ENV_KEY)
20
+ TFY_ARTIFACTS_DOWNLOAD_CHUNK_SIZE_BYTES: int = 100 * 1000 * 1000
21
+ TFY_ARTIFACTS_DOWNLOAD_MAX_WORKERS: int = max(min(32, (os.cpu_count() or 2) * 2), 4)
22
+ TFY_ARTIFACTS_UPLOAD_MAX_WORKERS: int = max(min(32, (os.cpu_count() or 2) * 2), 4)
23
+ TFY_ARTIFACTS_DISABLE_MULTIPART_UPLOAD: bool = False
24
+ TFY_ARTIFACTS_DOWNLOAD_FSYNC_CHUNKS: bool = False
25
+ TFY_CLI_LOCAL_DEV_MODE: bool = False
26
+ TFY_PYTHONBUILD_PYTHON_IMAGE_REPO: str = "public.ecr.aws/docker/library/python"
27
+
28
+
29
+ ENV_VARS = TrueFoundrySdkEnv()
12
30
  API_SERVER_RELATIVE_PATH = "api/svc"
13
31
  MLFOUNDRY_SERVER_RELATIVE_PATH = "api/ml"
14
32
  VERSION_PREFIX = "v1"
@@ -3,7 +3,7 @@ import threading
3
3
  from abc import ABC, abstractmethod
4
4
 
5
5
  from truefoundry.common.auth_service_client import AuthServiceClient
6
- from truefoundry.common.constants import TFY_API_KEY_ENV_KEY
6
+ from truefoundry.common.constants import ENV_VARS, TFY_API_KEY_ENV_KEY
7
7
  from truefoundry.common.credential_file_manager import CredentialsFileManager
8
8
  from truefoundry.common.entities import CredentialsFileContent, Token
9
9
  from truefoundry.common.utils import resolve_tfy_host
@@ -30,7 +30,9 @@ class CredentialProvider(ABC):
30
30
  class EnvCredentialProvider(CredentialProvider):
31
31
  def __init__(self) -> None:
32
32
  logger.debug("Using env var credential provider")
33
- api_key = os.getenv(TFY_API_KEY_ENV_KEY)
33
+ api_key = (
34
+ ENV_VARS.TFY_API_KEY.get_secret_value() if ENV_VARS.TFY_API_KEY else None
35
+ )
34
36
  if not api_key:
35
37
  raise Exception(
36
38
  f"Value of {TFY_API_KEY_ENV_KEY} env var should be non-empty string"
@@ -51,7 +51,7 @@ def urllib3_retry(
51
51
  def requests_retry_session(
52
52
  retries: int = 2,
53
53
  backoff_factor: float = 0.3,
54
- status_forcelist=(408, 429, 500, 502, 503, 504, 524),
54
+ status_forcelist=(408, 429, 417, 500, 502, 503, 504, 524),
55
55
  method_whitelist=frozenset({"GET", "POST"}),
56
56
  raise_on_status: bool = False,
57
57
  session: Optional[requests.Session] = None,
@@ -43,8 +43,10 @@ def check_min_cli_version(fn):
43
43
  return inner
44
44
 
45
45
 
46
- def session_with_retries() -> requests.Session:
47
- return requests_retry_session(retries=SERVICEFOUNDRY_CLIENT_MAX_RETRIES)
46
+ def session_with_retries(
47
+ retries: int = SERVICEFOUNDRY_CLIENT_MAX_RETRIES,
48
+ ) -> requests.Session:
49
+ return requests_retry_session(retries=retries)
48
50
 
49
51
 
50
52
  @timed_lru_cache(seconds=30 * 60)
@@ -1,4 +1,3 @@
1
- import os
2
1
  import time
3
2
  from functools import lru_cache, wraps
4
3
  from time import monotonic_ns
@@ -7,8 +6,8 @@ from urllib.parse import urljoin, urlparse
7
6
 
8
7
  from truefoundry.common.constants import (
9
8
  API_SERVER_RELATIVE_PATH,
9
+ ENV_VARS,
10
10
  MLFOUNDRY_SERVER_RELATIVE_PATH,
11
- TFY_CLI_LOCAL_DEV_MODE_ENV_KEY,
12
11
  TFY_HOST_ENV_KEY,
13
12
  )
14
13
  from truefoundry.pydantic_v1 import BaseSettings
@@ -41,7 +40,7 @@ _tfy_servers_config = None
41
40
  def get_tfy_servers_config(base_url: str) -> _TFYServersConfig:
42
41
  global _tfy_servers_config
43
42
  if _tfy_servers_config is None:
44
- if os.getenv(TFY_CLI_LOCAL_DEV_MODE_ENV_KEY):
43
+ if ENV_VARS.TFY_CLI_LOCAL_DEV_MODE:
45
44
  _tfy_servers_config = _TFYServersConfig() # type: ignore[call-arg]
46
45
  else:
47
46
  _tfy_servers_config = _TFYServersConfig.from_base_url(base_url)
@@ -95,11 +94,11 @@ def validate_tfy_host(tfy_host: str) -> None:
95
94
 
96
95
 
97
96
  def resolve_tfy_host(tfy_host: Optional[str] = None) -> str:
98
- if not tfy_host and not os.getenv(TFY_HOST_ENV_KEY):
97
+ if not tfy_host and not ENV_VARS.TFY_HOST:
99
98
  raise ValueError(
100
99
  f"Either `host` should be provided using `--host <value>`, or `{TFY_HOST_ENV_KEY}` env must be set"
101
100
  )
102
- tfy_host = tfy_host or os.getenv(TFY_HOST_ENV_KEY)
101
+ tfy_host = tfy_host or ENV_VARS.TFY_HOST
103
102
  tfy_host = tfy_host.strip("/")
104
103
  validate_tfy_host(tfy_host)
105
104
  return tfy_host
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: application.json
3
- # timestamp: 2024-10-09T13:00:44+00:00
3
+ # timestamp: 2024-10-16T17:06:03+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -362,13 +362,17 @@ class HelmRepo(BaseModel):
362
362
  ...,
363
363
  description="+label=Helm repository URL\n+sort=1\n+message=Needs to be a valid URL.",
364
364
  )
365
+ integration_fqn: Optional[str] = Field(
366
+ None,
367
+ description='+docs=FQN of the helm repo integration. You can use the FQN of your desired helm integration (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations) page\n+label=Helm repo integration\n+sort=2\n+usage=FQN of the helm repo integration. If you can\'t find your integration here,\nadd it through the [Integrations](/integrations) page\n+uiType=IntegrationSelect\n+uiProps={"integrationType":"helm-repo"}',
368
+ )
365
369
  chart: str = Field(
366
370
  ...,
367
- description='+label=Chart name\n+sort=2\n+usage=The helm chart name\n+uiType=InputSelect\n+uiProps={"creatable":true, "searchable":true}',
371
+ description='+label=Chart name\n+sort=3\n+usage=The helm chart name\n+uiType=InputSelect\n+uiProps={"creatable":true, "searchable":true}',
368
372
  )
369
373
  version: str = Field(
370
374
  ...,
371
- description='+label=Version\n+sort=3\n+usage=Helm chart version\n+uiType=InputSelect\n+uiProps={"creatable":true, "searchable":true}',
375
+ description='+label=Version\n+sort=4\n+usage=Helm chart version\n+uiType=InputSelect\n+uiProps={"creatable":true, "searchable":true}',
372
376
  )
373
377
 
374
378
 
@@ -472,6 +476,31 @@ class JobAlert(BaseModel):
472
476
  )
473
477
 
474
478
 
479
+ class Claim(BaseModel):
480
+ key: str
481
+ values: List[str]
482
+
483
+
484
+ class JwtAuthCreds(BaseModel):
485
+ """
486
+ +label=JWT Authentication
487
+ +usage=Configure JWT-based authentication using JWKS
488
+ """
489
+
490
+ type: Literal["jwt_auth"] = Field(..., description="+value=jwt_auth")
491
+ issuer: str = Field(
492
+ ..., description="+label=Issuer\n+usage=The issuer of the JWT tokens"
493
+ )
494
+ jwksUri: str = Field(
495
+ ...,
496
+ description="+label=JWKS URI\n+usage=The URI of the JSON Web Key Set (JWKS) containing the public keys",
497
+ )
498
+ claims: Optional[List[Claim]] = Field(
499
+ None,
500
+ description="+label=Claims\n+usage=List of key-value pairs of claims to verify in the JWT token",
501
+ )
502
+
503
+
475
504
  class KafkaMetricConfig(BaseModel):
476
505
  type: Literal["kafka"] = Field(..., description="+value=kafka")
477
506
  lag_threshold: conint(ge=1) = Field(
@@ -655,6 +684,10 @@ class OCIRepo(BaseModel):
655
684
  oci_chart_url: constr(
656
685
  regex=r"^(((oci):\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*))$"
657
686
  ) = Field(..., description="+label=OCI chart URL\n+message=Need to be a valid URL.")
687
+ integration_fqn: Optional[str] = Field(
688
+ None,
689
+ description='+docs=FQN of the container registry. You can use the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations) page\n+label=Container Registry\n+usage=FQN of the container registry. If you can\'t find your registry here,\nadd it through the [Integrations](/integrations) page\n+uiType=IntegrationSelect\n+uiProps={"integrationType":"docker-registry"}',
690
+ )
658
691
  version: str = Field(..., description="+label=Version\n+usage=Helm chart version")
659
692
 
660
693
 
@@ -736,7 +769,9 @@ class Port(BaseModel):
736
769
  None,
737
770
  description="+label=Rewrite Path to\n+usage=Rewrite the path prefix to a different path.\nIf `path` is `/v1/api` and `rewrite_path_to` is `/api`. The URI in the HTTP request `http://0.0.0.0:8080/v1/api/houses` will be rewritten to `http://0.0.0.0:8080/api/houses` before the request is forwarded your service.\nDefaults to `/`.\nThis is only applicable if `path` is given.\n+message=Should begin and end with a forward slash (/). Each part can can contain alphabets, digits and hypen, must begin and end with an alphanumeric characters. Parts should be separated by forward slashes (/)",
738
771
  )
739
- auth: Optional[BasicAuthCreds] = None
772
+ auth: Optional[Union[BasicAuthCreds, JwtAuthCreds]] = Field(
773
+ None, description="+usage=Username and Password for service auth"
774
+ )
740
775
 
741
776
 
742
777
  class PythonBuild(BaseModel):
@@ -3,7 +3,7 @@ from typing import Dict, List, Optional
3
3
 
4
4
  from mako.template import Template
5
5
 
6
- from truefoundry.common.constants import TFY_CLI_PYTHONBUILD_PYTHON_IMAGE_REPO_ENV_KEY
6
+ from truefoundry.common.constants import ENV_VARS
7
7
  from truefoundry.deploy.auto_gen.models import PythonBuild
8
8
  from truefoundry.deploy.builder.constants import (
9
9
  PIP_CONF_BUILDKIT_SECRET_MOUNT,
@@ -156,9 +156,7 @@ def generate_dockerfile_content(
156
156
  apt_packages=build_configuration.apt_packages
157
157
  )
158
158
  template_args = {
159
- "python_image_repo": os.getenv(
160
- TFY_CLI_PYTHONBUILD_PYTHON_IMAGE_REPO_ENV_KEY, DEFAULT_PYTHON_IMAGE_REPO
161
- ),
159
+ "python_image_repo": ENV_VARS.TFY_PYTHONBUILD_PYTHON_IMAGE_REPO,
162
160
  "python_version": build_configuration.python_version,
163
161
  "apt_install_command": apt_install_command,
164
162
  "requirements_path": requirements_path,
@@ -48,6 +48,7 @@ from truefoundry.pydantic_v1 import parse_obj_as
48
48
 
49
49
  DEPLOYMENT_LOGS_SUBSCRIBE_MESSAGE = "DEPLOYMENT_LOGS"
50
50
  BUILD_LOGS_SUBSCRIBE_MESSAGE = "BUILD_LOGS"
51
+ MAX_RETRIES_WORKFLOW_TRIGGER = 3
51
52
 
52
53
  if TYPE_CHECKING:
53
54
  from truefoundry.deploy.auto_gen.models import Application
@@ -597,7 +598,7 @@ class ServiceFoundryServiceClient(BaseServiceFoundryServiceClient):
597
598
  def trigger_workflow(self, application_id: str, inputs: Dict[str, Any]):
598
599
  url = f"{self._api_server_url}/{VERSION_PREFIX}/workflow/{application_id}/executions"
599
600
  body = {"inputs": inputs}
600
- response = session_with_retries().post(
601
+ response = session_with_retries(retries=MAX_RETRIES_WORKFLOW_TRIGGER).post(
601
602
  url, json=body, headers=self._get_header()
602
603
  )
603
604
  response = request_handling(response)
@@ -32,7 +32,6 @@ class Base(BaseModel):
32
32
  class Entity(Base):
33
33
  createdAt: datetime.datetime = Field(repr=False)
34
34
  updatedAt: datetime.datetime = Field(repr=False)
35
- createdBy: str = Field(repr=False)
36
35
 
37
36
 
38
37
  class Workspace(Entity):
@@ -56,7 +55,6 @@ class Workspace(Entity):
56
55
  "cluster_fqn": self.clusterId,
57
56
  "created_at": self.createdAt,
58
57
  "updated_at": self.updatedAt,
59
- "created_by": self.createdBy,
60
58
  }
61
59
 
62
60
 
@@ -161,7 +159,6 @@ class Deployment(Entity):
161
159
  "cluster_fqn": cluster_fqn,
162
160
  "created_at": self.createdAt,
163
161
  "updated_at": self.updatedAt,
164
- "created_by": self.createdBy,
165
162
  }
166
163
 
167
164
  class Config:
@@ -208,7 +205,6 @@ class Application(Entity):
208
205
  "cluster_fqn": self.workspace.clusterId,
209
206
  "created_at": self.createdAt,
210
207
  "updated_at": self.updatedAt,
211
- "created_by": self.createdBy,
212
208
  }
213
209
 
214
210
 
@@ -34,6 +34,7 @@ from rich.progress import (
34
34
  )
35
35
  from tqdm.utils import CallbackIOWrapper
36
36
 
37
+ from truefoundry.common.constants import ENV_VARS
37
38
  from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
38
39
  ApiClient,
39
40
  CreateMultiPartUploadForDatasetRequestDto,
@@ -58,14 +59,12 @@ from truefoundry.ml.clients.utils import (
58
59
  augmented_raise_for_status,
59
60
  cloud_storage_http_request,
60
61
  )
61
- from truefoundry.ml.env_vars import DISABLE_MULTIPART_UPLOAD
62
62
  from truefoundry.ml.exceptions import MlFoundryException
63
63
  from truefoundry.ml.logger import logger
64
64
  from truefoundry.ml.session import _get_api_client
65
65
  from truefoundry.pydantic_v1 import BaseModel, root_validator
66
66
 
67
67
  _MIN_BYTES_REQUIRED_FOR_MULTIPART = 100 * 1024 * 1024
68
- _MULTIPART_DISABLED = os.getenv(DISABLE_MULTIPART_UPLOAD, "").lower() == "true"
69
68
  # GCP/S3 Maximum number of parts per upload 10,000
70
69
  # Maximum number of blocks in a block blob 50,000 blocks
71
70
  # TODO: This number is artificially limited now. Later
@@ -84,9 +83,6 @@ _MAX_NUM_PARTS_FOR_MULTIPART = 1000
84
83
  # Azure Maximum size of a block in a block blob 4000 MiB
85
84
  # GCP/S3 Maximum size of an individual part in a multipart upload 5 GiB
86
85
  _MAX_PART_SIZE_BYTES_FOR_MULTIPART = 4 * 1024 * 1024 * 1000
87
- _cpu_count = os.cpu_count() or 2
88
- _MAX_WORKERS_FOR_UPLOAD = max(min(32, _cpu_count * 2), 4)
89
- _MAX_WORKERS_FOR_DOWNLOAD = max(min(32, _cpu_count * 2), 4)
90
86
  _LIST_FILES_PAGE_SIZE = 500
91
87
  _GENERATE_SIGNED_URL_BATCH_SIZE = 50
92
88
  DEFAULT_PRESIGNED_URL_EXPIRY_TIME = 3600
@@ -199,7 +195,10 @@ class _FileMultiPartInfo(NamedTuple):
199
195
 
200
196
  def _decide_file_parts(file_path: str) -> _FileMultiPartInfo:
201
197
  file_size = os.path.getsize(file_path)
202
- if file_size < _MIN_BYTES_REQUIRED_FOR_MULTIPART or _MULTIPART_DISABLED:
198
+ if (
199
+ file_size < _MIN_BYTES_REQUIRED_FOR_MULTIPART
200
+ or ENV_VARS.TFY_ARTIFACTS_DISABLE_MULTIPART_UPLOAD
201
+ ):
203
202
  return _FileMultiPartInfo(1, part_size=file_size, file_size=file_size)
204
203
 
205
204
  ideal_num_parts = math.ceil(file_size / _PART_SIZE_BYTES_FOR_MULTIPART)
@@ -262,7 +261,7 @@ def _signed_url_upload_file(
262
261
  def _download_file_using_http_uri(
263
262
  http_uri,
264
263
  download_path,
265
- chunk_size=100000000,
264
+ chunk_size=ENV_VARS.TFY_ARTIFACTS_DOWNLOAD_CHUNK_SIZE_BYTES,
266
265
  callback: Optional[Callable[[int, int], Any]] = None,
267
266
  ):
268
267
  """
@@ -283,6 +282,9 @@ def _download_file_using_http_uri(
283
282
  if not chunk:
284
283
  break
285
284
  output_file.write(chunk)
285
+ if ENV_VARS.TFY_ARTIFACTS_DOWNLOAD_FSYNC_CHUNKS:
286
+ output_file.flush()
287
+ os.fsync(output_file.fileno())
286
288
 
287
289
 
288
290
  class _CallbackIOWrapperForMultiPartUpload(CallbackIOWrapper):
@@ -608,7 +610,7 @@ class MlFoundryArtifactsRepository:
608
610
  disable=not show_progress,
609
611
  expand=True,
610
612
  ) as progress_bar, ThreadPoolExecutor(
611
- max_workers=_MAX_WORKERS_FOR_UPLOAD
613
+ max_workers=ENV_VARS.TFY_ARTIFACTS_UPLOAD_MAX_WORKERS
612
614
  ) as executor:
613
615
  futures: List[Future] = []
614
616
  # Note: While this batching is beneficial when there is a large number of files, there is also
@@ -763,7 +765,9 @@ class MlFoundryArtifactsRepository:
763
765
  )
764
766
 
765
767
  if not executor_for_multipart_upload:
766
- with ThreadPoolExecutor(max_workers=_MAX_WORKERS_FOR_UPLOAD) as executor:
768
+ with ThreadPoolExecutor(
769
+ max_workers=ENV_VARS.TFY_ARTIFACTS_UPLOAD_MAX_WORKERS
770
+ ) as executor:
767
771
  return self._multipart_upload(
768
772
  local_file=local_file,
769
773
  artifact_path=artifact_path,
@@ -899,7 +903,9 @@ class MlFoundryArtifactsRepository:
899
903
  )
900
904
  file_paths.append((file_path, download_dest_path))
901
905
 
902
- with ThreadPoolExecutor(_MAX_WORKERS_FOR_DOWNLOAD) as executor:
906
+ with ThreadPoolExecutor(
907
+ max_workers=ENV_VARS.TFY_ARTIFACTS_DOWNLOAD_MAX_WORKERS
908
+ ) as executor:
903
909
  # Note: While this batching is beneficial when there is a large number of files, there is also
904
910
  # a rare case risk of the signed url expiring before a request is made to it
905
911
  batch_size = _GENERATE_SIGNED_URL_BATCH_SIZE
@@ -184,11 +184,6 @@ class ArtifactVersion:
184
184
  _validate_artifact_metadata(value)
185
185
  self._metadata = value
186
186
 
187
- @property
188
- def created_by(self) -> str:
189
- """Get the information about who created the artifact"""
190
- return self._artifact_version.created_by
191
-
192
187
  @property
193
188
  def created_at(self) -> datetime.datetime:
194
189
  """Get the time at which artifact was created"""
@@ -124,11 +124,6 @@ class DataDirectory:
124
124
  _validate_artifact_metadata(value)
125
125
  self._metadata = value
126
126
 
127
- @property
128
- def created_by(self) -> str:
129
- """Get the information about who created the DataDirectory"""
130
- return self._dataset.created_by
131
-
132
127
  @property
133
128
  def created_at(self) -> datetime.datetime:
134
129
  """Get the time at which DataDirectory was created"""
@@ -219,11 +219,6 @@ class ModelVersion:
219
219
  metrics_as_kv[metric.key] = metric.value
220
220
  return metrics_as_kv
221
221
 
222
- @property
223
- def created_by(self) -> str:
224
- """Get the information about who created the model version"""
225
- return self._model_version.created_by
226
-
227
222
  @property
228
223
  def created_at(self) -> datetime.datetime:
229
224
  """Get the time at which model version was created"""
@@ -8,7 +8,7 @@ import coolname
8
8
  import pandas as pd
9
9
 
10
10
  from truefoundry.common.utils import relogin_error_message
11
- from truefoundry.ml import constants, env_vars
11
+ from truefoundry.ml import constants
12
12
  from truefoundry.ml.autogen.client import ( # type: ignore[attr-defined]
13
13
  ArtifactDto,
14
14
  ArtifactType,
@@ -59,10 +59,15 @@ from truefoundry.ml.validation_utils import (
59
59
 
60
60
  _SEARCH_MAX_RESULTS_DEFAULT = 1000
61
61
 
62
+ _INTERNAL_ENV_VARS = [
63
+ "TFY_INTERNAL_APPLICATION_ID",
64
+ "TFY_INTERNAL_JOB_RUN_NAME",
65
+ ]
66
+
62
67
 
63
68
  def _get_internal_env_vars_values() -> Dict[str, str]:
64
69
  env = {}
65
- for env_var_name in env_vars.INTERNAL_ENV_VARS:
70
+ for env_var_name in _INTERNAL_ENV_VARS:
66
71
  value = os.getenv(env_var_name)
67
72
  if value:
68
73
  env[env_var_name] = value
truefoundry/ml/session.py CHANGED
@@ -113,6 +113,8 @@ def _get_api_client(
113
113
  session: Optional[Session] = None,
114
114
  allow_anonymous: bool = False,
115
115
  ) -> ApiClient:
116
+ from truefoundry.version import __version__
117
+
116
118
  session = session or get_active_session()
117
119
  if session is None:
118
120
  if allow_anonymous:
@@ -131,7 +133,7 @@ def _get_api_client(
131
133
  )
132
134
  configuration.retries = urllib3_retry(retries=2)
133
135
  api_client = ApiClient(configuration=configuration)
134
- api_client.user_agent = "truefoundry-cli"
136
+ api_client.user_agent = f"truefoundry-cli/{__version__}"
135
137
  return api_client
136
138
 
137
139
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: truefoundry
3
- Version: 0.4.3
3
+ Version: 0.4.4rc1
4
4
  Summary: Truefoundry CLI
5
5
  Author: Abhishek Choudhary
6
6
  Author-email: abhishek@truefoundry.com
@@ -27,23 +27,23 @@ truefoundry/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  truefoundry/cli/__main__.py,sha256=-NkhYlT3mC5MhtekueKAvCw-sWvguj0LJRpXWzvvFjc,727
28
28
  truefoundry/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  truefoundry/common/auth_service_client.py,sha256=tZOa0NdATnItsMeTnEnUeTZQIgUJtpU-nvLdWtB4Px8,7978
30
- truefoundry/common/constants.py,sha256=gnswB-aK5atSRY-GE1Cji6ZCEs2FoK9n1lCX5JuQGqI,484
30
+ truefoundry/common/constants.py,sha256=zpU9PD3B_cRVev6u9A37gKMxkPrcD6knJbKpwUCsaQg,1354
31
31
  truefoundry/common/credential_file_manager.py,sha256=1yEk1Zm2xS4G0VDFwKSZ4w0VUrcPWQ1nJnoBaz9xyKA,4251
32
- truefoundry/common/credential_provider.py,sha256=YQ6HKl8ZZFTg48vBZMauEAnM6IrEO3oOzM2DA47N-P0,4071
32
+ truefoundry/common/credential_provider.py,sha256=Aht7hFLsnyRgMR34dRbzln7dor0WYSeA8ej8ApNmnKM,4148
33
33
  truefoundry/common/entities.py,sha256=8O-EGPk4PKqnyoFMKUTxISCU19rz0KBnfRDJU695DhY,3797
34
34
  truefoundry/common/exceptions.py,sha256=ePpiQ_zmWe4e94gOgeMiyP_AZnKwjEBfyXsB5ScGYcI,329
35
- truefoundry/common/request_utils.py,sha256=-ss8033PClJOMJuS5Ue1zCFRVK7ZW9vjtva1b5G9uok,2849
36
- truefoundry/common/servicefoundry_client.py,sha256=klohrELTFTJX-jvl9LGtdIoJiZMZRuQQB4Ho7PJ7u3s,3091
37
- truefoundry/common/utils.py,sha256=lFiDEVoQDJoZPEN4Zun4GQz2TsfdbXfNHI41BErETq8,3320
35
+ truefoundry/common/request_utils.py,sha256=5xw4YGUcMf71Ncal3OfFCa-PoWDIvG3hYGCDa4Da4OI,2854
36
+ truefoundry/common/servicefoundry_client.py,sha256=2fxmgCM-ckFHpnm6n_mL-5Z8RWN_q-dYVvFC29bkYSg,3120
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=AjbjNFwWDTIOjN_E1fSUgP-ej9nsb2OpZPhsnIRAVGs,80621
39
+ truefoundry/deploy/auto_gen/models.py,sha256=4MaxkG2_5Wg6avaZRlK0D4JiVEM5rk3NU0BCiTx8VyU,82477
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
43
43
  truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py,sha256=UmMcTY-8MrLY3H5owpn6ax-VePQl4MiMTmHlQ9qEtQw,1742
44
44
  truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py,sha256=IZbXsSj86SxWRZNQXepEnsOL_eYwWaOq5oh-WiyvL2c,2485
45
45
  truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py,sha256=XNJ3MKWqyWIbFNnUQMpB8oVC5Pt5Wsm_bRKbvkXRIG8,1696
46
- truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=cJlQK_kgNELULcp2Q_kMWyPNmUuZdhOELDnI0rMiqRc,7473
46
+ truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py,sha256=nwTpeIrDOZC8_m_VcbQ5Vp_rEO2ioC8FtzOEo17JY7A,7373
47
47
  truefoundry/deploy/builder/constants.py,sha256=eIukBjD6I4KvEmAPpdbPlPPr76yhS-uNr3RVFkzEdgs,257
48
48
  truefoundry/deploy/builder/docker_service.py,sha256=OI8efqK0Gnoii8bcHihpA2StwHVzsMREfBk7NvMR4hY,3950
49
49
  truefoundry/deploy/builder/utils.py,sha256=9RZnkhoHFTRUt_x3nck0aVz7cLpzA3jiwQH-ZZZrjf8,938
@@ -92,7 +92,7 @@ truefoundry/deploy/json_util.py,sha256=x_-7YYQ4_HUIJ8ofOcclAp9JWhgTWjR9Th6Q0FuRq
92
92
  truefoundry/deploy/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
93
  truefoundry/deploy/lib/auth/servicefoundry_session.py,sha256=5TCYPunAygtn5mb0mp_VcWKEalKMKPbyWMWer-Vty2g,1916
94
94
  truefoundry/deploy/lib/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
- truefoundry/deploy/lib/clients/servicefoundry_client.py,sha256=vFrd5yeStjT_uWL3JxHrx0iAmNpuv26K7IEnsF1RMM8,26101
95
+ truefoundry/deploy/lib/clients/servicefoundry_client.py,sha256=tkuPNbo9vDTgXPHD4p3d-t6HigBvKNfML1pTQXBwJfY,26170
96
96
  truefoundry/deploy/lib/const.py,sha256=repGJLuoMqtzeq5tCjjkN4bH187FVHVKI30BricOlvc,244
97
97
  truefoundry/deploy/lib/dao/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  truefoundry/deploy/lib/dao/application.py,sha256=uUTFSQkLUrFCtQQgS2Jm9BpyHyhMkN4GI1yx9oJo4_E,9161
@@ -103,7 +103,7 @@ truefoundry/deploy/lib/exceptions.py,sha256=ZT2o3mar3BYtnjKHn2wf4rBGEaFIgf-zkQmz
103
103
  truefoundry/deploy/lib/logs_utils.py,sha256=SQxRv3jDDmgHdOUMhlMaAPGYskybnBUMpst7QU_i_sc,1469
104
104
  truefoundry/deploy/lib/messages.py,sha256=nhp0bCYf_XpUM68hTq5lBY-__vtEyV2uP7NgnJXJ_Vg,925
105
105
  truefoundry/deploy/lib/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
- truefoundry/deploy/lib/model/entity.py,sha256=8J8yd98iWtSy8giShdDRNyzbN1UgSXx4XtmZLljdWnE,8552
106
+ truefoundry/deploy/lib/model/entity.py,sha256=fq8hvdJQgQn4uZqxpKrzmaoJhQG53_EbDoDxUPPmOZ0,8387
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
@@ -125,7 +125,7 @@ truefoundry/langchain/utils.py,sha256=PGLDe9chZ3BuUjakexOGpIqZRFoHEgu-zJ9yKdpLLm
125
125
  truefoundry/logger.py,sha256=7dLqW_Q2rEgo-_z1WZnQbGHaoy1L1MP3NqGgssaSS6o,685
126
126
  truefoundry/ml/__init__.py,sha256=2A1l7pgqbVRt3cRW_0Lxg92hyJEkMxkCUh1EFprrmc0,942
127
127
  truefoundry/ml/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
- truefoundry/ml/artifact/truefoundry_artifact_repo.py,sha256=dA_QYAyNCcCuOw5eVxPbU5OeMK8YBNh42vBnGf6I0Sw,44911
128
+ truefoundry/ml/artifact/truefoundry_artifact_repo.py,sha256=uS4FZq4wUhxB8-BDx--fLYTcsLYL_V9clNtb32G0Wo0,45050
129
129
  truefoundry/ml/autogen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
130
  truefoundry/ml/autogen/client/__init__.py,sha256=M68r1z8Mi6dEFFKDsWPJ9NGdNOYdm6pcdH7_srCwkCI,16651
131
131
  truefoundry/ml/autogen/client/api/__init__.py,sha256=3sMSljMIS3UHYeF0BcNvrPPx6VbBSRt_1IfDn-13Kyc,752
@@ -302,16 +302,15 @@ truefoundry/ml/clients/utils.py,sha256=c0LdC8moejs-Zm30hu1sCqifLEmqhdq4SfZ_m0nUI
302
302
  truefoundry/ml/constants.py,sha256=vDq72d4C9FSWqr9MMdjgTF4TuyNFApvo_6RVsSeAjB4,2837
303
303
  truefoundry/ml/entities.py,sha256=si5GAqZsWzKu5MPrU4Hk6se7bebHOYhTiNw69ai-Uk8,1485
304
304
  truefoundry/ml/enums.py,sha256=arqDkF8duU_oVLFeYMhcfWYbF6Nq5mmjwupJMIheyXM,1790
305
- truefoundry/ml/env_vars.py,sha256=0CqhoV6RgxgPju71AJYvo7crHxVr0vJNzWTiSWKnLcI,212
306
305
  truefoundry/ml/exceptions.py,sha256=8aJm2NYtAWWsRLu4MbzaoOqHsQZ6RjOFwBWQWqb6qrc,244
307
306
  truefoundry/ml/git_info.py,sha256=jvAVm9ilqivnGq8qJdUvYdd8Siv0PLtqurB-PXsS5ho,2023
308
307
  truefoundry/ml/internal_namespace.py,sha256=QcqMHp6-C2im2H_02hlhi01EIcr1HhNaZprszs13EMU,1790
309
308
  truefoundry/ml/log_types/__init__.py,sha256=g4u4D4Jaj0aBK5GtrLV88-qThKZR9pSZ17vFEkN-LmM,125
310
- truefoundry/ml/log_types/artifacts/artifact.py,sha256=pNgLc6GaQ0UVJ6gaSRzpAW5CmGpJMC4iBgBY5FLlofc,17640
309
+ truefoundry/ml/log_types/artifacts/artifact.py,sha256=ltHLkJLLeeRO1d6BqoSq3VtizicvyjdG_Hf52wqig7w,17478
311
310
  truefoundry/ml/log_types/artifacts/constants.py,sha256=qKxQ5mMvJE4j83BvGW3qNTKunxCiBg_EEjTdgbgJtyE,1036
312
- truefoundry/ml/log_types/artifacts/dataset.py,sha256=oXi7itXOe3PrnN4_KY7s1GdhWV1lyvWXRWgY6_vPTAs,12981
311
+ truefoundry/ml/log_types/artifacts/dataset.py,sha256=ou6hF0RnwQ8clgpWW8SJPOu2YCG-xya51b91pGY-PjY,12823
313
312
  truefoundry/ml/log_types/artifacts/general_artifact.py,sha256=fY74EUeCGdHdlkrp_GMoaZPvl7EQctt8OlRM6yFgLF8,3772
314
- truefoundry/ml/log_types/artifacts/model.py,sha256=NRIvGX0yCLGnLvZkuCRJGGEuONoUhXZSY2jmSUM3JvI,22162
313
+ truefoundry/ml/log_types/artifacts/model.py,sha256=Qb0wq2qCbPCk4os74xsJwOXUQc-4sdGsBwKkV9emDsI,21998
315
314
  truefoundry/ml/log_types/artifacts/model_extras.py,sha256=TIE73bLKfwIVzNiVcjmaZ841A70BHBwu4XAM6ZAQRFI,1045
316
315
  truefoundry/ml/log_types/artifacts/utils.py,sha256=dwmRBrEmwIktVcA1a3lrsUfmROO7THTLgYwJ4MpSUWU,5885
317
316
  truefoundry/ml/log_types/image/__init__.py,sha256=fcOq8yQnNj1rkLcPeIjLXBpdA1WIeiPsXOlAAvMxx7M,76
@@ -323,10 +322,10 @@ truefoundry/ml/log_types/plot.py,sha256=oFnXNb2o5fVF0zsnRjvqjSjLaphQWUnQCdw72e2u
323
322
  truefoundry/ml/log_types/pydantic_base.py,sha256=eBlw_AEyAz4iJKDP4zgJOCFWcldwQqpf7FADW1jzIQY,272
324
323
  truefoundry/ml/log_types/utils.py,sha256=xjJ21jdPScvFmw3TbVh5NCzbzJwaqiXJyiiT4xxX1EI,335
325
324
  truefoundry/ml/logger.py,sha256=VT-BF3BnBYTWVq87O58F0c8uXMu94gYzsiFlGY3_7Ao,458
326
- truefoundry/ml/mlfoundry_api.py,sha256=I2T8tXeAIWpD8EH05fm80mNyX6cs2S1ORI4qoo0HTpQ,60847
325
+ truefoundry/ml/mlfoundry_api.py,sha256=UV42BLXf3R9Ql7TBJ4zGUoHq2B4ENEU2jK9aaEniGQc,60923
327
326
  truefoundry/ml/mlfoundry_run.py,sha256=rNJl130iJkpjW3MNoe5-d_J9VJJQBqWHEJCfYeiZCbE,45123
328
327
  truefoundry/ml/run_utils.py,sha256=0W208wSLUrbdfk2pjNcZlkUi9bNxG2JORqoe-5rVqHI,2423
329
- truefoundry/ml/session.py,sha256=Rvq419hdLNBt0KUzKn7jGvKKg9LI_gafOHcw-lFceAE,5330
328
+ truefoundry/ml/session.py,sha256=F83GTC5WwGBjnJ69Ct8MqMnlutYc56JCc6YhEY1Wl-A,5394
330
329
  truefoundry/ml/validation_utils.py,sha256=XBSUd9OoyriWJpT3M5LKz17iWY3yVMr3hM5vdaVjtf0,12082
331
330
  truefoundry/pydantic_v1.py,sha256=jSuhGtz0Mbk1qYu8jJ1AcnIDK4oxUsdhALc4spqstmM,345
332
331
  truefoundry/version.py,sha256=bqiT4Q-VWrTC6P4qfK43mez-Ppf-smWfrl6DcwV7mrw,137
@@ -341,7 +340,7 @@ truefoundry/workflow/map_task.py,sha256=2m3qGXQ90k9LdS45q8dqCCECc3qr8t2m_LMCVd1m
341
340
  truefoundry/workflow/python_task.py,sha256=SRXRLC4vdBqGjhkwuaY39LEWN6iPCpJAuW17URRdWTY,1128
342
341
  truefoundry/workflow/task.py,sha256=ToitYiKcNzFCtOVQwz1W8sRjbR97eVS7vQBdbgUQtKg,1779
343
342
  truefoundry/workflow/workflow.py,sha256=WaTqUjhwfAXDWu4E5ehuwAxrCbDJkoAf1oWmR2E9Qy0,4575
344
- truefoundry-0.4.3.dist-info/METADATA,sha256=GWyg6SdKw3D3tmYLGzlQ6tYsosmIVMAC0NuUMJ3qsJs,3098
345
- truefoundry-0.4.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
346
- truefoundry-0.4.3.dist-info/entry_points.txt,sha256=TXvUxQkI6zmqJuycPsyxEIMr3oqfDjgrWj0m_9X12x4,95
347
- truefoundry-0.4.3.dist-info/RECORD,,
343
+ truefoundry-0.4.4rc1.dist-info/METADATA,sha256=1fqRs-fBIXRc1DI21OJSATulj9ZPmnUtuNKVZML2y-U,3101
344
+ truefoundry-0.4.4rc1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
345
+ truefoundry-0.4.4rc1.dist-info/entry_points.txt,sha256=TXvUxQkI6zmqJuycPsyxEIMr3oqfDjgrWj0m_9X12x4,95
346
+ truefoundry-0.4.4rc1.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- """
2
- Define all the env variable names that users can use
3
- """
4
-
5
- DISABLE_MULTIPART_UPLOAD = "MLF_DISABLE_MULTIPART_UPLOAD"
6
- INTERNAL_ENV_VARS = [
7
- "TFY_INTERNAL_APPLICATION_ID",
8
- "TFY_INTERNAL_JOB_RUN_NAME",
9
- ]