truefoundry 0.2.10__py3-none-any.whl → 0.3.0rc2__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.

Files changed (100) hide show
  1. truefoundry/__init__.py +1 -0
  2. truefoundry/autodeploy/cli.py +31 -18
  3. truefoundry/deploy/__init__.py +119 -1
  4. truefoundry/deploy/auto_gen/models.py +1791 -0
  5. truefoundry/deploy/builder/__init__.py +138 -0
  6. truefoundry/deploy/builder/builders/__init__.py +22 -0
  7. truefoundry/deploy/builder/builders/dockerfile.py +57 -0
  8. truefoundry/deploy/builder/builders/tfy_notebook_buildpack/__init__.py +44 -0
  9. truefoundry/deploy/builder/builders/tfy_notebook_buildpack/dockerfile_template.py +51 -0
  10. truefoundry/deploy/builder/builders/tfy_python_buildpack/__init__.py +44 -0
  11. truefoundry/deploy/builder/builders/tfy_python_buildpack/dockerfile_template.py +158 -0
  12. truefoundry/deploy/builder/docker_service.py +168 -0
  13. truefoundry/deploy/cli/cli.py +19 -26
  14. truefoundry/deploy/cli/commands/__init__.py +18 -0
  15. truefoundry/deploy/cli/commands/apply_command.py +52 -0
  16. truefoundry/deploy/cli/commands/build_command.py +45 -0
  17. truefoundry/deploy/cli/commands/build_logs_command.py +89 -0
  18. truefoundry/deploy/cli/commands/create_command.py +75 -0
  19. truefoundry/deploy/cli/commands/delete_command.py +77 -0
  20. truefoundry/deploy/cli/commands/deploy_command.py +99 -0
  21. truefoundry/deploy/cli/commands/get_command.py +216 -0
  22. truefoundry/deploy/cli/commands/list_command.py +171 -0
  23. truefoundry/deploy/cli/commands/login_command.py +33 -0
  24. truefoundry/deploy/cli/commands/logout_command.py +20 -0
  25. truefoundry/deploy/cli/commands/logs_command.py +134 -0
  26. truefoundry/deploy/cli/commands/patch_application_command.py +79 -0
  27. truefoundry/deploy/cli/commands/patch_command.py +70 -0
  28. truefoundry/deploy/cli/commands/redeploy_command.py +41 -0
  29. truefoundry/deploy/cli/commands/terminate_comand.py +44 -0
  30. truefoundry/deploy/cli/commands/trigger_command.py +87 -0
  31. truefoundry/deploy/cli/config.py +10 -0
  32. truefoundry/deploy/cli/console.py +5 -0
  33. truefoundry/deploy/cli/const.py +12 -0
  34. truefoundry/deploy/cli/display_util.py +118 -0
  35. truefoundry/deploy/cli/util.py +92 -0
  36. truefoundry/deploy/core/__init__.py +7 -0
  37. truefoundry/deploy/core/login.py +9 -0
  38. truefoundry/deploy/core/logout.py +5 -0
  39. truefoundry/deploy/function_service/__init__.py +3 -0
  40. truefoundry/deploy/function_service/__main__.py +27 -0
  41. truefoundry/deploy/function_service/app.py +92 -0
  42. truefoundry/deploy/function_service/build.py +45 -0
  43. truefoundry/deploy/function_service/remote/__init__.py +6 -0
  44. truefoundry/deploy/function_service/remote/context.py +3 -0
  45. truefoundry/deploy/function_service/remote/method.py +67 -0
  46. truefoundry/deploy/function_service/remote/remote.py +144 -0
  47. truefoundry/deploy/function_service/route.py +137 -0
  48. truefoundry/deploy/function_service/service.py +113 -0
  49. truefoundry/deploy/function_service/utils.py +53 -0
  50. truefoundry/deploy/io/__init__.py +0 -0
  51. truefoundry/deploy/io/output_callback.py +23 -0
  52. truefoundry/deploy/io/rich_output_callback.py +27 -0
  53. truefoundry/deploy/json_util.py +7 -0
  54. truefoundry/deploy/lib/__init__.py +0 -0
  55. truefoundry/deploy/lib/auth/auth_service_client.py +81 -0
  56. truefoundry/deploy/lib/auth/credential_file_manager.py +115 -0
  57. truefoundry/deploy/lib/auth/credential_provider.py +131 -0
  58. truefoundry/deploy/lib/auth/servicefoundry_session.py +59 -0
  59. truefoundry/deploy/lib/clients/__init__.py +0 -0
  60. truefoundry/deploy/lib/clients/servicefoundry_client.py +723 -0
  61. truefoundry/deploy/lib/clients/shell_client.py +13 -0
  62. truefoundry/deploy/lib/clients/utils.py +41 -0
  63. truefoundry/deploy/lib/const.py +43 -0
  64. truefoundry/deploy/lib/dao/__init__.py +0 -0
  65. truefoundry/deploy/lib/dao/application.py +246 -0
  66. truefoundry/deploy/lib/dao/apply.py +80 -0
  67. truefoundry/deploy/lib/dao/version.py +33 -0
  68. truefoundry/deploy/lib/dao/workspace.py +71 -0
  69. truefoundry/deploy/lib/exceptions.py +23 -0
  70. truefoundry/deploy/lib/logs_utils.py +43 -0
  71. truefoundry/deploy/lib/messages.py +12 -0
  72. truefoundry/deploy/lib/model/__init__.py +0 -0
  73. truefoundry/deploy/lib/model/entity.py +382 -0
  74. truefoundry/deploy/lib/session.py +146 -0
  75. truefoundry/deploy/lib/util.py +70 -0
  76. truefoundry/deploy/lib/win32.py +129 -0
  77. truefoundry/deploy/v2/__init__.py +0 -0
  78. truefoundry/deploy/v2/lib/__init__.py +3 -0
  79. truefoundry/deploy/v2/lib/deploy.py +232 -0
  80. truefoundry/deploy/v2/lib/deployable_patched_models.py +72 -0
  81. truefoundry/deploy/v2/lib/models.py +53 -0
  82. truefoundry/deploy/v2/lib/patched_models.py +515 -0
  83. truefoundry/deploy/v2/lib/source.py +267 -0
  84. truefoundry/flyte/__init__.py +6 -0
  85. truefoundry/langchain/__init__.py +12 -1
  86. truefoundry/langchain/deprecated.py +302 -0
  87. truefoundry/langchain/truefoundry_chat.py +130 -0
  88. truefoundry/langchain/truefoundry_embeddings.py +171 -0
  89. truefoundry/langchain/truefoundry_llm.py +106 -0
  90. truefoundry/langchain/utils.py +85 -0
  91. truefoundry/logger.py +17 -0
  92. truefoundry/pydantic_v1.py +5 -0
  93. truefoundry/python_deploy_codegen.py +132 -0
  94. {truefoundry-0.2.10.dist-info → truefoundry-0.3.0rc2.dist-info}/METADATA +25 -6
  95. truefoundry-0.3.0rc2.dist-info/RECORD +125 -0
  96. truefoundry/deploy/cli/deploy.py +0 -165
  97. truefoundry-0.2.10.dist-info/RECORD +0 -38
  98. /truefoundry/{deploy/cli/version.py → version.py} +0 -0
  99. {truefoundry-0.2.10.dist-info → truefoundry-0.3.0rc2.dist-info}/WHEEL +0 -0
  100. {truefoundry-0.2.10.dist-info → truefoundry-0.3.0rc2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,1791 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: application.json
3
+ # timestamp: 2024-07-05T13:46:01+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+ from typing import Any, Dict, List, Literal, Optional, Union
9
+
10
+ from truefoundry.pydantic_v1 import (
11
+ BaseModel,
12
+ Field,
13
+ PositiveFloat,
14
+ PositiveInt,
15
+ confloat,
16
+ conint,
17
+ constr,
18
+ )
19
+
20
+
21
+ class AMQPInputConfig(BaseModel):
22
+ """
23
+ +docs=Describes the configuration for the input AMQP worker
24
+ +label=AMQP
25
+ """
26
+
27
+ type: Literal["amqp"] = Field(..., description="+value=amqp")
28
+ url: constr(
29
+ regex=r"^(amqp|amqps?)://(?:[^:@]+(?::[^:@]+)?@)?([^/?]+)(?:/([^?]+))?/?([^?]+)?(?:\?(.*))?$"
30
+ ) = Field(
31
+ ...,
32
+ description="+label=Queue URL\n+usage=AMQP Queue URL of Subscriber\n+sort=1",
33
+ )
34
+ queue_name: str = Field(
35
+ ..., description="+label=Queue Name\n+usage=AMQP Queue Name\n+sort=2"
36
+ )
37
+ wait_time_seconds: conint(ge=1) = Field(
38
+ 5, description="+label=Wait Time Seconds\n+usage=Wait timeout for long polling."
39
+ )
40
+
41
+
42
+ class AMQPMetricConfig(BaseModel):
43
+ type: Literal["amqp"] = Field(..., description="+value=amqp")
44
+ queue_length: conint(ge=1) = Field(
45
+ ...,
46
+ description="+label=Queue Length\n+usage=Upper limit of the number of backlog messages the auto-scaler will try to maintain per replica. If you set this number to 10 and have 30 messages in the stream and one replica, the auto-scaler will scale the number of replicas to 3.",
47
+ )
48
+
49
+
50
+ class AMQPOutputConfig(BaseModel):
51
+ """
52
+ +docs=Describes the configuration for the output AMQP worker
53
+ +label=AMQP
54
+ """
55
+
56
+ type: Literal["amqp"] = Field(..., description="+value=amqp")
57
+ url: constr(
58
+ regex=r"^(amqp|amqps?)://(?:[^:@]+(?::[^:@]+)?@)?([^/?]+)(?:/([^?]+))?/?([^?]+)?(?:\?(.*))?$"
59
+ ) = Field(
60
+ ..., description="+label=Queue URL\n+usage=AMQP Queue URL of Publisher\n+sort=1"
61
+ )
62
+ routing_key: str = Field(
63
+ ...,
64
+ description="+label=Routing Key\n+usage=AMQP Routing Key to publish to.\n+sort=2",
65
+ )
66
+ exchange_name: Optional[str] = Field(
67
+ None, description="+label=Exchange Name\n+usage=AMQP Exchange Name\n+sort=3"
68
+ )
69
+
70
+
71
+ class AWSAccessKeyAuth(BaseModel):
72
+ aws_access_key_id: str = Field(
73
+ ..., description="+label=AWS Access Key ID\n+usage=AWS Access Key ID\n+sort=1"
74
+ )
75
+ aws_secret_access_key: str = Field(
76
+ ...,
77
+ description="+label=AWS Secret Access Key\n+usage=AWS Secret Access Key for the user to authenticate with\n+sort=2",
78
+ )
79
+ aws_session_token: Optional[str] = Field(
80
+ None,
81
+ description="+label=AWS Session Token\n+usage=AWS Session Token, only required when using temporary credentials\n+sort=3",
82
+ )
83
+
84
+
85
+ class AWSInferentia(BaseModel):
86
+ type: Literal["aws_inferentia"] = Field(..., description="+value=aws_inferentia")
87
+ name: Optional[str] = Field(
88
+ None,
89
+ description="+label=Inferentia accelerator name\n+usage=Name of the AWS Inferentia Accccelerator. One of [INF1, INF2].\nThis field is required for Node Selector and can be ignored in Nodepool Selector.",
90
+ )
91
+ count: conint(ge=1, le=16) = Field(
92
+ ...,
93
+ description="+label=Count\n+usage=Count of Inferentia accelerator chips to provide to the application",
94
+ )
95
+
96
+
97
+ class ArtifactsCacheVolume(BaseModel):
98
+ """
99
+ +docs=Describes the volume that will be used to cache the models
100
+ +label=Artifacts Cache Volume
101
+ """
102
+
103
+ storage_class: str = Field(
104
+ ...,
105
+ description="+label=Storage Class\n+usage=Storage class of the Volume where artifacts will be cached",
106
+ )
107
+ cache_size: conint(ge=1, le=1000) = Field(
108
+ 200,
109
+ description="+label=Cache Size (GB)\n+usage=Size of the Volume (in GB) where artifacts will be cached. Should be greater than twice the size of artifacts getting cached",
110
+ )
111
+
112
+
113
+ class AsyncProcessorSidecar(BaseModel):
114
+ destination_url: str = Field(
115
+ ...,
116
+ description="+label=Destination URL\n+usage=URL for the processor to invoke",
117
+ )
118
+ request_timeout: conint(ge=1) = Field(
119
+ 10,
120
+ description="+label=Request Timeout Seconds\n+usage=Timeout for the invoke request in seconds",
121
+ )
122
+ sidecar_image: Optional[str] = Field(
123
+ None,
124
+ description="+label=Sidecar Image\n+usage=Image for the processor sidecar (This field will be deprecated in the future)",
125
+ )
126
+
127
+
128
+ class BaseAutoscaling(BaseModel):
129
+ min_replicas: conint(ge=0) = Field(
130
+ 1,
131
+ description="+label=Minimum replicas\n+usage=Minimum number of replicas to keep available\n+sort=1",
132
+ )
133
+ max_replicas: conint(ge=1, le=500) = Field(
134
+ ...,
135
+ description="+label=Maximum replicas\n+usage=Maximum number of replicas allowed for the component.\n+sort=2",
136
+ )
137
+ polling_interval: conint(ge=0) = Field(
138
+ 30,
139
+ description="+label=Polling Interval\n+usage=This is the interval to check each trigger on.",
140
+ )
141
+ cooldown_period: conint(ge=0) = Field(
142
+ 300,
143
+ description="+label=Cooldown Period\n+usage=The period to wait after the last trigger reported active before scaling the resource back to 0.",
144
+ )
145
+
146
+
147
+ class BasicAuthCreds(BaseModel):
148
+ """
149
+ +label=Username and password for service auth
150
+ """
151
+
152
+ type: Literal["basic_auth"] = Field(..., description="+value=basic_auth")
153
+ username: str = Field(
154
+ ...,
155
+ description="+label=Username for service auth\n+message=Username for the user to authenticate with\n+sort=1",
156
+ )
157
+ password: str = Field(
158
+ ...,
159
+ description="+label=Password for service auth\n+message=Password for the user to authenticate with\n+sort=2",
160
+ )
161
+
162
+
163
+ class BlueGreen(BaseModel):
164
+ """
165
+ +docs=This strategy brings up the new release completely before switching the complete load to the new release.
166
+ This minimizes the time that two versions are serving traffic at the same time.
167
+ +label=Blue Green strategy
168
+ """
169
+
170
+ type: Literal["blue_green"] = Field(..., description="+value=blue_green")
171
+ enable_auto_promotion: bool = Field(
172
+ False,
173
+ description="+docs=Promote the new release to handle the complete traffic. A manual promotion would be needed if this is disabled\n+label=Auto-promotion",
174
+ )
175
+ auto_promotion_seconds: conint(ge=0) = Field(
176
+ 30,
177
+ description="+docs=Promote the new release to handle the complete traffic after waiting for these many seconds\n+label=Auto-promotion seconds",
178
+ )
179
+
180
+
181
+ class CPUUtilizationMetric(BaseModel):
182
+ type: Literal["cpu_utilization"] = Field(..., description="+value=cpu_utilization")
183
+ value: conint(ge=1, le=100) = Field(
184
+ ...,
185
+ description="+label=CPU utilization %\n+usage=Percentage of cpu request averaged over all replicas which the autoscaler should try to maintain",
186
+ )
187
+
188
+
189
+ class CanaryStep(BaseModel):
190
+ weight_percentage: conint(ge=0, le=100) = Field(
191
+ ...,
192
+ description="+docs=Percentage of total traffic to be shifted to the canary release.\nThe rest will continue to go to the existing deployment\n+label=Canary weight percentage\n+unit=%\n+placeholder=Weight",
193
+ )
194
+ pause_duration: conint(ge=0) = Field(
195
+ 30,
196
+ description="+docs=Duration for which to pause the release. The release process will wait for these seconds before proceeding to the next step.\nIf this is not set, the step will pause indefinitely on this step\n+label=Pause duration\n+unit=seconds\n+placeholder=Duration",
197
+ )
198
+
199
+
200
+ class CodeserverImage(BaseModel):
201
+ """
202
+ +usage=Codeserver with persistent environment (Python 3.11.6)
203
+ """
204
+
205
+ type: constr(regex=r"^codeserver$") = Field(..., description="+value=codeserver")
206
+ enable_sudo: bool = Field(
207
+ True,
208
+ description="+label=Enable root access to the container\n+usage=Changes made to the root directory `/` will not be persisted across notebook restarts",
209
+ )
210
+ apt_packages: Optional[List[str]] = Field(
211
+ None,
212
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
213
+ )
214
+ docker_registry: Optional[str] = Field(
215
+ None,
216
+ description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
217
+ )
218
+
219
+
220
+ class CronMetric(BaseModel):
221
+ type: Literal["cron"] = Field(..., description="+value=cron")
222
+ desired_replicas: Optional[conint(ge=1)] = Field(
223
+ None,
224
+ description="+label=Desired Replicas\n+usage=Desired number of replicas during the given interval. Default value is max_replicas.",
225
+ )
226
+ start: str = Field(
227
+ ...,
228
+ description="+label=Start Schedule\n+docs=Cron expression indicating the start of the cron schedule.\n+usage=Cron expression indicating the start of the cron schedule.\n```\n* * * * *\n| | | | |\n| | | | |___ day of week (0-6) (Sunday is 0)\n| | | |_____ month (1-12)\n| | |_______ day of month (1-31)\n| |_________ hour (0-23)\n|___________ minute (0-59)\n```",
229
+ )
230
+ end: str = Field(
231
+ ...,
232
+ description="+label=End Schedule\n+docs=Cron expression indicating the end of the cron schedule.\n+usage=Cron expression indicating the end of the cron schedule.\n```\n* * * * *\n| | | | |\n| | | | |___ day of week (0-6) (Sunday is 0)\n| | | |_____ month (1-12)\n| | |_______ day of month (1-31)\n| |_________ hour (0-23)\n|___________ minute (0-59)\n```",
233
+ )
234
+ timezone: str = Field(
235
+ "UTC",
236
+ description='+usage=Timezone against which the cron schedule will be calculated, e.g. "Asia/Tokyo". Default is machine\'s local time.\nhttps://docs.truefoundry.com/docs/list-of-supported-timezones',
237
+ )
238
+
239
+
240
+ class CustomCodeserverImage(BaseModel):
241
+ """
242
+ +usage=User supplied docker image URI for vscode server
243
+ """
244
+
245
+ type: constr(regex=r"^customcodeserver$") = Field(
246
+ ..., description="+value=customcodeserver"
247
+ )
248
+ image_uri: str = Field(
249
+ ...,
250
+ description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
251
+ )
252
+ docker_registry: Optional[str] = Field(
253
+ None,
254
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
255
+ )
256
+
257
+
258
+ class CustomNotebookImage(BaseModel):
259
+ """
260
+ +usage=User supplied docker image URI for jupyter notebook
261
+ """
262
+
263
+ type: constr(regex=r"^customnotebook$") = Field(
264
+ ..., description="+value=customnotebook"
265
+ )
266
+ image_uri: str = Field(
267
+ ...,
268
+ description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
269
+ )
270
+ docker_registry: Optional[str] = Field(
271
+ None,
272
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
273
+ )
274
+
275
+
276
+ class CustomSSHServerImage(BaseModel):
277
+ """
278
+ +usage=User supplied docker image URI for ssh server
279
+ """
280
+
281
+ type: constr(regex=r"^custom-ssh-server$") = Field(
282
+ ..., description="+value=custom-ssh-server"
283
+ )
284
+ image_uri: str = Field(
285
+ ...,
286
+ description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version",
287
+ )
288
+ docker_registry: Optional[str] = Field(
289
+ None,
290
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
291
+ )
292
+
293
+
294
+ class DockerFileBuild(BaseModel):
295
+ """
296
+ +docs=Describes that we are using a dockerfile to build our image
297
+ +label=Docker File (I already have Docker File)
298
+ +icon=fa-brands fa-docker:#0db7ed
299
+ """
300
+
301
+ type: Literal["dockerfile"] = Field(..., description="+value=dockerfile")
302
+ dockerfile_path: str = Field(
303
+ "./Dockerfile",
304
+ description="+label=Path to Dockerfile\n+usage=The file path of the Dockerfile relative to project root path.",
305
+ )
306
+ build_context_path: str = Field(
307
+ "./",
308
+ description="+label=Path to build context\n+usage=Build context path for the Dockerfile relative to project root path.",
309
+ )
310
+ command: Optional[Union[str, List[str]]] = Field(
311
+ None,
312
+ description="+label=Command Override\n+usage=Override the command to run when the container starts\nWhen deploying a Job, the command can be templatized by defining `params` and referencing them in command\nE.g. `python main.py --learning_rate {{learning_rate}}`",
313
+ )
314
+ build_args: Optional[Dict[str, str]] = Field(
315
+ None, description="+label=Build arguments to pass to docker build"
316
+ )
317
+
318
+
319
+ class DynamicVolumeConfig(BaseModel):
320
+ """
321
+ +label=Dynamic Volume Config
322
+ """
323
+
324
+ type: constr(regex=r"^dynamic$") = Field(
325
+ ...,
326
+ description="+label=Volume Type\n+value=dynamic\n+usage=Volume Type for the volume.",
327
+ )
328
+ storage_class: str = Field(
329
+ ...,
330
+ description="+label=Storage Class Name\n+usage=Name of the storage class to be used for the volume.",
331
+ )
332
+ size: conint(ge=1, le=64000) = Field(
333
+ ..., description="+label=Size\n+unit=Gi\n+usage=Size of volume in Gi"
334
+ )
335
+
336
+
337
+ class Endpoint(BaseModel):
338
+ host: constr(
339
+ regex=r"^((([a-zA-Z0-9\-]{1,63}\.)([a-zA-Z0-9\-]{1,63}\.)*([A-Za-z]{1,63}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$"
340
+ ) = Field(
341
+ ...,
342
+ description="+usage=Host e.g. ai.example.com, app.truefoundry.com\n+message=Upto 253 characters, each part of host should be at most 63 characters long, can contain alphabets, digits and hypen, must begin and end with an alphanumeric characters. Parts must be separated by periods (.)",
343
+ )
344
+ path: Optional[
345
+ constr(regex=r"^(/([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-_\.]*[a-zA-Z0-9]))*/$")
346
+ ] = Field(
347
+ None,
348
+ description="+usage=Path e.g. /v1/api/ml/, /v2/docs/\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 (/)",
349
+ )
350
+
351
+
352
+ class GcpTPU(BaseModel):
353
+ type: Literal["gcp_tpu"] = Field(..., description="+value=gcp_tpu")
354
+ name: constr(regex=r"^tpu-[a-z\d\-]+$") = Field(
355
+ ...,
356
+ description="+label=TPU Type name\n+usage=Name of the TPU Type. One of\n - `tpu-v4-podslice` (TPU v4, ct4p)\n - `tpu-v5-lite-device` (TPU v5e, ct5l)\n - `tpu-v5-lite-podslice` (TPU v5e, ct5lp)\n - `tpu-v5p-slice` (TPU v5p, ct5p)",
357
+ )
358
+ topology: constr(regex=r"^\d+x\d+(x\d+)?$") = Field(
359
+ ...,
360
+ description="+label=Slice Topology\n+usage=Topology of the TPU slices. Currently only single-host topology is supported.\n Please refer to [TPUs on GKE docs](https://cloud.google.com/kubernetes-engine/docs/concepts/tpus#plan-tpu-configuration)\n Allowed Values:\n - `2x2x1` for `tpu-v4-podslice`\n - One of `1x1`, `2x2`, `2x4` for `tpu-v5-lite-device` and `tpu-v5-lite-podslice`\n - `2x2x1` for `tpu-v5p-slice`",
361
+ )
362
+
363
+
364
+ class GitHelmRepo(BaseModel):
365
+ type: constr(regex=r"^git-helm-repo$") = Field(
366
+ ..., description="+value=git-helm-repo"
367
+ )
368
+ repo_url: constr(
369
+ regex=r"^(((https?|wss):\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*))$"
370
+ ) = Field(
371
+ ...,
372
+ description="+label=Git repository URL\n+sort=1\n+message=Needs to be a valid URL.\nTODO: Check this regex and add guidelines",
373
+ )
374
+ revision: str = Field(
375
+ ...,
376
+ description="+label=Revision\n+sort=2\n+usage=Branch/Commit SHA/Tag of the git repo.",
377
+ )
378
+ path: str = Field(
379
+ ..., description="+label=Path\n+sort=3\n+usage=Path to the chart."
380
+ )
381
+ value_files: Optional[List[str]] = Field(
382
+ None,
383
+ description="+label=Value files\n+sort=3\n+usage=Helm values files for overriding values in the helm chart.\nThe path is relative to the Path directory defined above",
384
+ )
385
+
386
+
387
+ class GitSource(BaseModel):
388
+ """
389
+ +docs=Describes that we are using code stored in a git repository to build our image
390
+ +label=Git Source
391
+ +icon=fa-solid fa-code-branch:black
392
+ +sort=300
393
+ """
394
+
395
+ type: Literal["git"] = Field(..., description="+value=git")
396
+ repo_url: constr(
397
+ regex=r"^(http(s?)://)(github\.com|(.+@)*bitbucket\.org|gitlab\.com|(.*)@dev.azure.com).*$"
398
+ ) = Field(
399
+ ...,
400
+ description="+label=Repo URL\n+usage=The repository URL.\n+sort=1\n+message=Needs to be a valid Github, Bitbucket, Azure Repos or Gitlab link",
401
+ )
402
+ ref: str = Field(
403
+ ..., description="+label=Commit SHA\n+usage=The commit SHA.\n+sort=2"
404
+ )
405
+ branch_name: Optional[str] = Field(
406
+ None,
407
+ description="+label=Branch Name\n+usage=Selecting branch will select latest commit SHA of the branch.\n+sort=3",
408
+ )
409
+
410
+
411
+ class HelmRepo(BaseModel):
412
+ type: constr(regex=r"^helm-repo$") = Field(..., description="+value=helm-repo")
413
+ repo_url: constr(
414
+ regex=r"^(((https?|wss):\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*))$"
415
+ ) = Field(
416
+ ...,
417
+ description="+label=Helm repository URL\n+sort=1\n+message=Needs to be a valid URL.",
418
+ )
419
+ chart: str = Field(
420
+ ..., description="+label=Chart name\n+sort=2\n+usage=The helm chart name"
421
+ )
422
+ version: str = Field(
423
+ ..., description="+label=Version\n+sort=3\n+usage=Helm chart version"
424
+ )
425
+
426
+
427
+ class HttpProbe(BaseModel):
428
+ """
429
+ +docs=Describes the Instructions for assessing container health by executing an HTTP GET request.
430
+ To learn more you can go [here](https://docs.truefoundry.com/docs/liveness-readiness-probe)
431
+ +label=Instructions for assessing container health by executing an HTTP GET request.
432
+ """
433
+
434
+ type: Literal["http"] = Field(..., description="+sort=1\n+value=http")
435
+ path: str = Field(
436
+ ...,
437
+ description="+usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.\n+sort=2",
438
+ )
439
+ port: conint(ge=0, le=65535) = Field(
440
+ ...,
441
+ description="+usage=The TCP socket within the container to which the HTTP GET request should be directed.\n+sort=3",
442
+ )
443
+ host: Optional[str] = Field(
444
+ None,
445
+ description="+sort=4\n+usage=Host name to connect to, defaults to the pod IP",
446
+ )
447
+ scheme: str = Field(
448
+ "HTTP", description="+sort=5\n+usage=Scheme to use for connecting to the host"
449
+ )
450
+
451
+
452
+ class HuggingfaceArtifactSource(BaseModel):
453
+ """
454
+ +docs=Input for Artifact from Huggingface Model Hub
455
+ +label=Huggingface Model Source
456
+ """
457
+
458
+ type: Literal["huggingface-hub"] = Field(..., description="+value=huggingface-hub")
459
+ model_id: str = Field(
460
+ ...,
461
+ description="+label=Model ID\n+usage=Model ID of the artifact to be downloaded",
462
+ )
463
+ revision: str = Field(
464
+ ...,
465
+ description="+label=Revision\n+usage=Revision of the artifact to be downloaded",
466
+ )
467
+ ignore_patterns: List[str] = Field(
468
+ ["*.h5", "*.ot", "*.tflite", "*.msgpack"],
469
+ description="+label=Ignore Patterns\n+usage=List of patterns to ignore while downloading the artifact",
470
+ )
471
+ download_path_env_variable: str = Field(
472
+ ...,
473
+ description="+label=Download Path Environment Variable\n+usage=Environment variable which will contain the download path of the artifact",
474
+ )
475
+
476
+
477
+ class Image(BaseModel):
478
+ """
479
+ +docs=Describes that we are using a pre-built image stored in a Docker Image registry
480
+ +label=Docker Image (Deploy an existing image)
481
+ +icon=fa-brands fa-docker:#0db7ed
482
+ """
483
+
484
+ type: Literal["image"] = Field(..., description="+value=image")
485
+ image_uri: constr(regex=r"^\S*$") = Field(
486
+ ...,
487
+ description="+label=Image URI\n+usage=The image URI. Specify the name of the image and the tag.\nIf the image is in Dockerhub, you can skip registry-url (for e.g. `tensorflow/tensorflow`).\nYou can use an image from a private registry using Advanced fields\n+placeholder=registry-url/account/image:version (e.g. docker.io/tensorflow/tensorflow)",
488
+ )
489
+ docker_registry: Optional[str] = Field(
490
+ None,
491
+ description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
492
+ )
493
+ command: Optional[Union[str, List[str]]] = Field(
494
+ None,
495
+ description="+label=Command Override\n+usage=Override the command to run when container starts.\nWhen deploying a Job, the command can be templatized by defining `params` and referencing them in command\nE.g. `python main.py --learning_rate {{learning_rate}}`",
496
+ )
497
+
498
+
499
+ class KafkaMetricConfig(BaseModel):
500
+ type: Literal["kafka"] = Field(..., description="+value=kafka")
501
+ lag_threshold: conint(ge=1) = Field(
502
+ ...,
503
+ description="+label=Lag Threshold\n+usage=Upper limit of the number of backlog messages the auto-scaler will try to maintain per replica. If you set this number to 10 and have 30 messages in the stream and one replica, the auto-scaler will scale the number of replicas to 3.",
504
+ )
505
+
506
+
507
+ class KafkaSASLAuth(BaseModel):
508
+ username: str = Field(
509
+ ...,
510
+ description="+label=Username\n+usage=Username for SASL authentication\n+sort=1",
511
+ )
512
+ password: str = Field(
513
+ ...,
514
+ description="+label=Password\n+usage=Password for SASL authentication\n+sort=2",
515
+ )
516
+
517
+
518
+ class Kustomize(BaseModel):
519
+ patch: Optional[Dict[str, Any]] = Field(
520
+ None,
521
+ description="+label=Patch\n+usage=Content of kustomization.yaml to perform kustomize operation. Please do not include the `resources` section. It is filled in automatically",
522
+ )
523
+ additions: Optional[List[Dict[str, Any]]] = Field(
524
+ None,
525
+ description="+label=Additional Manifests\n+usage=Additional kubernetes manifests to be included in the application",
526
+ )
527
+
528
+
529
+ class LocalSource(BaseModel):
530
+ """
531
+ +docs=Describes that we are using code stored in a local developement environment to build our image
532
+ +label=Local
533
+ +icon=fa-folder:black
534
+ +sort=100
535
+ """
536
+
537
+ type: Literal["local"] = Field(..., description="+value=local")
538
+ project_root_path: str = Field("./", description="+usage=Local project root path.")
539
+ local_build: bool = Field(True, description="run docker build locally")
540
+
541
+
542
+ class Manual(BaseModel):
543
+ """
544
+ +docs=Describes that we are going to manually trigger our job.
545
+ +label=Manual
546
+ +usage=Trigger the job manually. [Docs](https://docs.truefoundry.com/docs/deploy-a-cron-job)
547
+ """
548
+
549
+ type: constr(regex=r"^manual$") = Field(..., description="+value=manual")
550
+
551
+
552
+ class NATSMetricConfig(BaseModel):
553
+ type: Literal["nats"] = Field(..., description="+value=nats")
554
+ lag_threshold: conint(ge=1) = Field(
555
+ ...,
556
+ description="+label=Lag Threshold\n+usage=Upper limit of the number of backlog messages the auto-scaler will try to maintain per replica. If you set this number to 10 and have 30 messages in the stream and one replica, the auto-scaler will scale the number of replicas to 3.",
557
+ )
558
+
559
+
560
+ class NATSUserPasswordAuth(BaseModel):
561
+ """
562
+ +docs=NATS User Password Authentication
563
+ +label=NATS User Password Authentication
564
+ """
565
+
566
+ account_name: str = Field(
567
+ "$G",
568
+ description="+label=Account Name\n+usage=Name of the NATS account\n+sort=1",
569
+ )
570
+ user: str = Field(
571
+ ..., description="+label=User\n+usage=User for NATS authentication\n+sort=2"
572
+ )
573
+ password: str = Field(
574
+ ...,
575
+ description="+label=Password\n+usage=Password for NATS authentication\n+sort=3",
576
+ )
577
+
578
+
579
+ class CapacityType(str, Enum):
580
+ """
581
+ +label=Capacity Type
582
+ +usage=Configure what type of nodes to run the app. By default no placement logic is applied.
583
+ "spot_fallback_on_demand" will try to place the application on spot nodes but will fallback to on-demand when spot nodes are not available.
584
+ "spot" will strictly place the application on spot nodes.
585
+ "on_demand" will strictly place the application on on-demand nodes.
586
+ """
587
+
588
+ spot_fallback_on_demand = "spot_fallback_on_demand"
589
+ spot = "spot"
590
+ on_demand = "on_demand"
591
+
592
+
593
+ class NodeSelector(BaseModel):
594
+ """
595
+ +label=Node selector
596
+ +usage=Constraints to select a Node - Specific GPU / Instance Families, On-Demand/Spot.
597
+ """
598
+
599
+ type: Literal["node_selector"] = Field(..., description="+value=node_selector")
600
+ gpu_type: Optional[str] = Field(
601
+ None,
602
+ description="+label=GPU Type\n+usage=Name of the Nvidia GPU. One of [P4, P100, V100, T4, A10G, A100_40GB, A100_80GB]\nOne instance of the card contains the following amount of memory -\nP4: 8 GB, P100: 16 GB, V100: 16 GB, T4: 16 GB, A10G: 24 GB, A100_40GB: 40GB, A100_80GB: 80 GB",
603
+ )
604
+ instance_families: Optional[List[str]] = Field(
605
+ None,
606
+ description="+label=Instance family\n+usage=Instance family of the underlying machine to use. Multiple instance families can be supplied.\nThe workload is guaranteed to be scheduled on one of them.",
607
+ )
608
+ capacity_type: Optional[CapacityType] = Field(
609
+ None,
610
+ description='+label=Capacity Type\n+usage=Configure what type of nodes to run the app. By default no placement logic is applied.\n"spot_fallback_on_demand" will try to place the application on spot nodes but will fallback to on-demand when spot nodes are not available.\n"spot" will strictly place the application on spot nodes.\n"on_demand" will strictly place the application on on-demand nodes.',
611
+ )
612
+
613
+
614
+ class NodepoolSelector(BaseModel):
615
+ """
616
+ +label=Nodepool selector
617
+ +usage=Specify one or more nodepools to run your application on.
618
+ """
619
+
620
+ type: Literal["nodepool_selector"] = Field(
621
+ ..., description="+value=nodepool_selector"
622
+ )
623
+ nodepools: Optional[List[str]] = Field(
624
+ None,
625
+ description="+label=Nodepools\n+usage=Nodepools where you want to run your workload. Multiple nodepools can be selected.\n The workload is guaranteed to be scheduled on one of the nodepool",
626
+ )
627
+
628
+
629
+ class NvidiaGPU(BaseModel):
630
+ type: Literal["nvidia_gpu"] = Field(..., description="+value=nvidia_gpu")
631
+ name: Optional[str] = Field(
632
+ None,
633
+ description="+label=GPU Name\n+usage=Name of the Nvidia GPU. One of [P4, P100, V100, T4, A10G, A100_40GB, A100_80GB]\nThis field is required for Node Selector and can be ignored in Nodepool Selector.\nOne instance of the card contains the following amount of memory -\nP4: 8 GB, P100: 16 GB, V100: 16 GB, T4: 16 GB, A10G: 24 GB, A100_40GB: 40GB, A100_80GB: 80 GB",
634
+ )
635
+ count: conint(ge=1, le=16) = Field(
636
+ ...,
637
+ description="+label=GPU Count\n+usage=Count of GPUs to provide to the application\nNote the exact count and max count available for a given GPU type depends on cloud provider and cluster type.",
638
+ )
639
+
640
+
641
+ class Profile(str, Enum):
642
+ """
643
+ +label=MIG Profile
644
+ +usage=Name of the MIG profile to use. One of [1g.5gb, 2g.10gb, 3g.20gb, 1g.10gb, 2g.20gb, 3g.40gb]
645
+ """
646
+
647
+ field_1g_5gb = "1g.5gb"
648
+ field_2g_10gb = "2g.10gb"
649
+ field_3g_20gb = "3g.20gb"
650
+ field_1g_10gb = "1g.10gb"
651
+ field_2g_20gb = "2g.20gb"
652
+ field_3g_40gb = "3g.40gb"
653
+
654
+
655
+ class NvidiaMIGGPU(BaseModel):
656
+ type: Literal["nvidia_mig_gpu"] = Field(..., description="+value=nvidia_mig_gpu")
657
+ profile: Profile = Field(
658
+ ...,
659
+ description="+label=MIG Profile\n+usage=Name of the MIG profile to use. One of [1g.5gb, 2g.10gb, 3g.20gb, 1g.10gb, 2g.20gb, 3g.40gb]",
660
+ )
661
+
662
+
663
+ class NvidiaTimeslicingGPU(BaseModel):
664
+ type: Literal["nvidia_timeslicing_gpu"] = Field(
665
+ ..., description="+value=nvidia_timeslicing_gpu"
666
+ )
667
+ gpu_memory: conint(ge=1, le=200000) = Field(
668
+ ...,
669
+ description="+label=GPU Memory (MB)\n+usage=Amount of GPU memory (in MB) to allocate. Please note, this limit is not being enforced today but will be in future. Applications are expected to operate in co-opertative mode",
670
+ )
671
+
672
+
673
+ class OCIRepo(BaseModel):
674
+ """
675
+ +label=OCIRepo
676
+ """
677
+
678
+ type: constr(regex=r"^oci-repo$") = Field(..., description="+value=oci-repo")
679
+ oci_chart_url: constr(
680
+ regex=r"^(((oci):\/\/)?(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*))$"
681
+ ) = Field(..., description="+label=OCI chart URL\n+message=Need to be a valid URL.")
682
+ version: str = Field(..., description="+label=Version\n+usage=Helm chart version")
683
+
684
+
685
+ class ParamType(str, Enum):
686
+ string = "string"
687
+ ml_repo = "ml_repo"
688
+
689
+
690
+ class Param(BaseModel):
691
+ name: constr(regex=r"^[a-z][a-z0-9\-_]{0,30}[a-z0-9]$") = Field(
692
+ ...,
693
+ description="+usage=Name of the param\n+message=name can contain lower case alphabets, digits, underscore (_) and hypen (-). It can be 32 characters long, should start with an alphabet, and should end with either an alphabet or digit.",
694
+ )
695
+ description: Optional[constr(regex=r"^.{1,127}$")] = Field(
696
+ None,
697
+ description="+usage=Description of param\n+message=description cannot be longer than 127 characters",
698
+ )
699
+ default: Optional[constr(regex=r"^.{0,127}$")] = Field(
700
+ None,
701
+ description="+usage=Default value or placeholder\n+message=default value cannot be longer than 127 characters\n+label=Default value",
702
+ )
703
+ param_type: ParamType = "string"
704
+
705
+
706
+ class Protocol(str, Enum):
707
+ """
708
+ +usage=Protocol for the port.
709
+ """
710
+
711
+ TCP = "TCP"
712
+ UDP = "UDP"
713
+
714
+
715
+ class AppProtocol(str, Enum):
716
+ """
717
+ +label=Application Protocol
718
+ +usage=Application Protocol for the port.
719
+ Select the application protocol used by your service. For most use cases, this should be `http`(HTTP/1.1).
720
+ If you are running a gRPC server, select the `grpc` option.
721
+ This is only applicable if `expose=true`.
722
+ """
723
+
724
+ http = "http"
725
+ grpc = "grpc"
726
+ tcp = "tcp"
727
+
728
+
729
+ class Port(BaseModel):
730
+ """
731
+ +docs=Describes the ports the service should be exposed to.
732
+ """
733
+
734
+ port: conint(ge=1, le=65535) = Field(
735
+ 80, description="+usage=Port number to expose."
736
+ )
737
+ protocol: Protocol = Field("TCP", description="+usage=Protocol for the port.")
738
+ expose: bool = Field(True, description="+usage=Expose the port")
739
+ app_protocol: AppProtocol = Field(
740
+ "http",
741
+ description="+label=Application Protocol\n+usage=Application Protocol for the port.\nSelect the application protocol used by your service. For most use cases, this should be `http`(HTTP/1.1).\nIf you are running a gRPC server, select the `grpc` option.\nThis is only applicable if `expose=true`.",
742
+ )
743
+ host: Optional[
744
+ constr(
745
+ regex=r"^((([a-zA-Z0-9\-]{1,63}\.)([a-zA-Z0-9\-]{1,63}\.)*([A-Za-z]{1,63}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$"
746
+ )
747
+ ] = Field(
748
+ None,
749
+ description="+usage=Host e.g. ai.example.com, app.truefoundry.com\n+message=Upto 253 characters, each part of host should be at most 63 characters long, can contain alphabets, digits and hypen, must begin and end with an alphanumeric characters. Parts must be separated by periods (.)",
750
+ )
751
+ path: Optional[
752
+ constr(regex=r"^(/([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-_\.]*[a-zA-Z0-9]))*/$")
753
+ ] = Field(
754
+ None,
755
+ description="+usage=Path e.g. /v1/api/ml/, /v2/docs/\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 (/)",
756
+ )
757
+ rewrite_path_to: Optional[
758
+ constr(regex=r"^(/([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-_\.]*[a-zA-Z0-9]))*/$")
759
+ ] = Field(
760
+ None,
761
+ 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 (/)",
762
+ )
763
+ auth: Optional[BasicAuthCreds] = None
764
+
765
+
766
+ class PythonBuild(BaseModel):
767
+ """
768
+ +docs=Describes that we are using python to build a container image with a specific python version and pip packages installed.
769
+ +label=Python Code (I don't have Dockerfile)
770
+ +icon=fa-brands fa-python:#306998
771
+ """
772
+
773
+ type: Literal["tfy-python-buildpack"] = Field(
774
+ ..., description="+value=tfy-python-buildpack"
775
+ )
776
+ python_version: constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$") = Field(
777
+ "3.9",
778
+ description="+label=Python version\n+usage=Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python)\n+message=Please enter a valid Python version tag",
779
+ )
780
+ build_context_path: str = Field(
781
+ "./",
782
+ description="+label=Path to build context\n+usage=Build path relative to project root path.",
783
+ )
784
+ requirements_path: Optional[str] = Field(
785
+ None,
786
+ description="`Path to build context`\n+label=Path to requirements\n+usage=Path to `requirements.txt` relative to\n`Path to build context`",
787
+ )
788
+ pip_packages: Optional[List[str]] = Field(
789
+ None,
790
+ description='+label=Pip packages to install\n+usage=Define pip package requirements.\nIn Python/YAML E.g. ["fastapi>=0.90,<1.0", "uvicorn"]\n+placeholder=Enter a pip package name E.g. fastapi>=0.90,<1.0',
791
+ )
792
+ apt_packages: Optional[List[str]] = Field(
793
+ None,
794
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
795
+ )
796
+ command: Union[str, List[str]] = Field(
797
+ ...,
798
+ description="Command will be set as the Entrypoint of the generatede\nimage.\n+label=Command\n+usage=Command to run when the container starts.\nCommand will be set as the Entrypoint of the generated image.\nWhen deploying a Job, the command can be templatized by defining `params` and referencing them in command\nE.g. `python main.py --learning_rate {{learning_rate}}`",
799
+ )
800
+ cuda_version: Optional[
801
+ constr(
802
+ 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)$"
803
+ )
804
+ ] = Field(
805
+ None,
806
+ description="+label=CUDA Version\n+usage=Version of CUDA Toolkit and CUDNN to install in the image\nThese combinations are based off of publically available docker images on docker hub\nYou can also specify a valid tag of the form {cuda_version_number}-cudnn{cudnn_version_number}-{runtime|devel}-ubuntu{ubuntu_version}\nRefer https://hub.docker.com/r/nvidia/cuda/tags for valid set of values\nNote: We use deadsnakes ubuntu ppa to add Python that currently supports only Ubuntu 18.04, 20.04 and 22.04",
807
+ )
808
+
809
+
810
+ class RPSMetric(BaseModel):
811
+ type: Literal["rps"] = Field(..., description="+value=rps")
812
+ value: PositiveFloat = Field(
813
+ ...,
814
+ description="+label=Requests per second\n+usage=Average request per second averaged over all replicas that autoscaler should try to maintain",
815
+ )
816
+
817
+
818
+ class RemoteSource(BaseModel):
819
+ """
820
+ +docs=Describes that we are using code stored in a remote respository to build our image
821
+ +label=S3
822
+ +icon=fa-brands fa-aws:black
823
+ +sort=200
824
+ """
825
+
826
+ type: Literal["remote"] = Field(..., description="+value=remote")
827
+ remote_uri: str = Field(
828
+ ..., description="+docs=Remote repository URI\n+label=Remote URI"
829
+ )
830
+
831
+
832
+ class Resources(BaseModel):
833
+ """
834
+ +docs=Describes the resource constraints for the application so that it can be deployed accordingly on the cluster
835
+ To learn more you can go [here](https://docs.truefoundry.com/docs/resources)
836
+ +icon=fa-microchip
837
+ +label=Resources
838
+ +usage=Configure resource allocations, specify node constraints and capacity types to improve performance and reduce expenses. [Docs](https://docs.truefoundry.com/docs/resources)
839
+ """
840
+
841
+ cpu_request: confloat(ge=0.001, le=256.0) = Field(
842
+ 0.2,
843
+ description="+label=CPU Request\n+sort=1\n+usage=Requested CPU which determines the minimum cost incurred. The CPU usage can exceed the requested\namount, but not the value specified in the limit. 1 CPU means 1 CPU core. Fractional CPU can be requested\nlike `0.5` or `0.05`",
844
+ )
845
+ cpu_limit: confloat(ge=0.001, le=256.0) = Field(
846
+ 0.5,
847
+ description="+label=CPU Limit\n+usage=CPU limit beyond which the usage cannot be exceeded. 1 CPU means 1 CPU core. Fractional CPU can be requested\nlike `0.5`. CPU limit should be >= cpu request.\n+sort=2",
848
+ )
849
+ memory_request: conint(ge=1, le=2000000) = Field(
850
+ 200,
851
+ description="+label=Memory Request\n+usage=Requested memory which determines the minimum cost incurred. The unit of memory is in megabytes(MB).\nSo 1 means 1 MB and 2000 means 2GB.\n+sort=3",
852
+ )
853
+ memory_limit: conint(ge=1, le=2000000) = Field(
854
+ 500,
855
+ description="+label=Memory Limit\n+usage=Memory limit after which the application will be killed with an OOM error. The unit of memory is\nin megabytes(MB). So 1 means 1 MB and 2000 means 2GB. MemoryLimit should be greater than memory request.\n+sort=4",
856
+ )
857
+ ephemeral_storage_request: conint(ge=1, le=2000000) = Field(
858
+ 1000,
859
+ description="+label=Storage Request\n+usage=Requested disk storage. The unit of memory is in megabytes(MB).\nThis is ephemeral storage and will be wiped out on pod restarts or eviction\n+sort=5",
860
+ )
861
+ ephemeral_storage_limit: conint(ge=1, le=2000000) = Field(
862
+ 2000,
863
+ description="+label=Storage Limit\n+usage=Disk storage limit. The unit of memory is in megabytes(MB). Exceeding this limit will result in eviction.\nIt should be greater than the request. This is ephemeral storage and will be wiped out on pod restarts or eviction\n+sort=6",
864
+ )
865
+ gpu_count: Optional[conint(ge=0, le=16)] = Field(
866
+ None,
867
+ description="+label=GPU Count\n+usage=Count of GPUs to provide to the application\nNote the exact count and max count available for a given GPU type depends on cloud provider and cluster type.",
868
+ )
869
+ shared_memory_size: Optional[conint(ge=64, le=32000)] = Field(
870
+ None,
871
+ description="+label=Shared Memory Size (MB)\n+usage=Define the shared memory requirements for your workload. Machine learning libraries like Pytorch can use Shared Memory\nfor inter-process communication. If you use this, we will mount a `tmpfs` backed volume at the `/dev/shm` directory.\nAny usage will also count against the workload's memory limit (`resources.memory_limit`) along with your workload's memory usage.\nIf the overall usage goes above `resources.memory_limit` the user process may get killed.\nShared Memory Size cannot be more than the defined Memory Limit for the workload.",
872
+ )
873
+ node: Optional[Union[NodeSelector, NodepoolSelector]] = Field(
874
+ None,
875
+ description="+label=Node\n+usage=This field determines how the underlying node resource is to be utilized",
876
+ )
877
+ devices: Optional[
878
+ List[
879
+ Union[NvidiaGPU, AWSInferentia, NvidiaMIGGPU, NvidiaTimeslicingGPU, GcpTPU]
880
+ ]
881
+ ] = Field(
882
+ None,
883
+ description="+label=Devices\n+usage=Define custom device or accelerator requirements for your workload. We currently support NVIDIA GPUs, AWS Inferentia Accelerators, Single Host TPU Slices.",
884
+ )
885
+
886
+
887
+ class Rolling(BaseModel):
888
+ """
889
+ +docs=This strategy updates the pods in a rolling fashion such that a subset of the
890
+ total pods are replaced with new version at one time.
891
+ A commonly used strategy can be to have maxUnavailablePercentage close to 0 so that there
892
+ is no downtime and keep the maxSurgePercentage to around 25%. If you are anyways running
893
+ a large number of pods, the service can often tolerate a few pods going down - so you
894
+ max maxUnavailablePercentage = 10 and maxSurgePercentage=0. You can read about it more
895
+ [here](https://spot.io/resources/kubernetes-autoscaling/5-kubernetes-deployment-strategies-roll-out-like-the-pros/)
896
+ +label=Rolling update strategy
897
+ """
898
+
899
+ type: Literal["rolling_update"] = Field(..., description="+value=rolling_update")
900
+ max_unavailable_percentage: conint(ge=0, le=100) = Field(
901
+ 25,
902
+ description="+label=Max unavailable(%)\n+usage=Percentage of total replicas that can be brought down at one time.\nFor a value of 25 when replicas are set to 12 this would mean minimum (25% of 12) = 3 pods might be unavailable during the deployment.\nSetting this to a higher value can help in speeding up the deployment process.",
903
+ )
904
+ max_surge_percentage: conint(ge=0, le=100) = Field(
905
+ 0,
906
+ description="+label=Max Surge(%)\n+usage=Percentage of total replicas of updated image that can be brought up over the total replicas count.\nFor a value of 25 when replicas are set to 12 this would mean (12+(25% of 12) = 15) pods might be running at one time.\nSetting this to a higher value can help in speeding up the deployment process.",
907
+ )
908
+
909
+
910
+ class SQSInputConfig(BaseModel):
911
+ """
912
+ +docs=Describes the configuration for the input SQS worker
913
+ +label=SQS
914
+ """
915
+
916
+ type: Literal["sqs"] = Field(..., description="+value=sqs")
917
+ queue_url: str = Field(
918
+ ...,
919
+ description="+label=Queue URL\n+usage=AWS SQS Queue URL of Subscriber\n+sort=1",
920
+ )
921
+ region_name: str = Field(
922
+ ..., description="+label=Region Name\n+usage=AWS Region Name\n+sort=2"
923
+ )
924
+ visibility_timeout: conint(ge=1, le=43200) = Field(
925
+ ...,
926
+ description="+label=Visibility Timeout (seconds)\n+usage=A period during which Amazon SQS prevents all consumers from receiving and processing the message. If one message takes 5 seconds to process, you can set this number to 7 or any number higher than 5. This will ensure that while the message is being processed, it will not be available to other replicas. For more information, see [here](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html)\n+sort=3",
927
+ )
928
+ wait_time_seconds: conint(ge=1, le=20) = Field(
929
+ 19,
930
+ description="+label=Wait Time Seconds\n+usage=Wait timeout for long polling. For more information, see [here](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html)",
931
+ )
932
+ auth: AWSAccessKeyAuth
933
+
934
+
935
+ class SQSOutputConfig(BaseModel):
936
+ """
937
+ +docs=Describes the configuration for the output SQS worker
938
+ +label=SQS
939
+ """
940
+
941
+ type: Literal["sqs"] = Field(..., description="+value=sqs")
942
+ queue_url: str = Field(
943
+ ...,
944
+ description="+label=Queue URL\n+usage=AWS SQS Queue URL of Publisher\n+sort=1",
945
+ )
946
+ region_name: str = Field(
947
+ ..., description="+label=Region Name\n+usage=AWS Region Name\n+sort=2"
948
+ )
949
+ auth: AWSAccessKeyAuth
950
+
951
+
952
+ class SQSQueueMetricConfig(BaseModel):
953
+ type: Literal["sqs"] = Field(..., description="+value=sqs")
954
+ queue_length: conint(ge=1) = Field(
955
+ ...,
956
+ description="+label=Queue length\n+usage=Upper limit of the number of backlog messages the auto-scaler will try to maintain per replica. If you set this number to 10 and have 30 messages in the queue and one replica, the auto-scaler will scale the number of replicas to 3.",
957
+ )
958
+
959
+
960
+ class SSHServerImage(BaseModel):
961
+ """
962
+ +usage=Ssh Server with persistent environment (Python 3.11.6)
963
+ """
964
+
965
+ type: constr(regex=r"^ssh-server$") = Field(..., description="+value=ssh-server")
966
+ apt_packages: Optional[List[str]] = Field(
967
+ None,
968
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
969
+ )
970
+ docker_registry: Optional[str] = Field(
971
+ None,
972
+ description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
973
+ )
974
+
975
+
976
+ class ConcurrencyPolicy(str, Enum):
977
+ """
978
+ +usage=Choose whether to allow this job to run while another instance of the job is running, or to replace the currently running instance. Allow
979
+ will enable multiple instances of this job to run. Forbid will keep the current instance of the job running and stop a new instance from being run.
980
+ Replace will terminate any currently running instance of the job and start a new one.
981
+ """
982
+
983
+ Forbid = "Forbid"
984
+ Allow = "Allow"
985
+ Replace = "Replace"
986
+
987
+
988
+ class Schedule(BaseModel):
989
+ """
990
+ +docs=Describes that we are going to schedule our job to run at a schedule, making our job a cron job.
991
+ +label=Schedule
992
+ +usage=Run the job on a schedule. [Docs](https://docs.truefoundry.com/docs/deploy-a-cron-job)
993
+ """
994
+
995
+ type: constr(regex=r"^scheduled$") = Field(..., description="+value=scheduled")
996
+ schedule: str = Field(
997
+ ...,
998
+ description="+docs=Specify the schedule for this job to be run periodically in cron format. [Learn more](https://docs.truefoundry.com/docs/deploy-a-cron-job)\n+usage=Specify the schedule for this job to be run periodically in cron format.\n```\n* * * * *\n| | | | |\n| | | | |___ day of week (0-6) (Sunday is 0)\n| | | |_____ month (1-12)\n| | |_______ day of month (1-31)\n| |_________ hour (0-23)\n|___________ minute (0-59)\n```",
999
+ )
1000
+ concurrency_policy: ConcurrencyPolicy = Field(
1001
+ "Forbid",
1002
+ description="+usage=Choose whether to allow this job to run while another instance of the job is running, or to replace the currently running instance. Allow\nwill enable multiple instances of this job to run. Forbid will keep the current instance of the job running and stop a new instance from being run.\nReplace will terminate any currently running instance of the job and start a new one.",
1003
+ )
1004
+ timezone: Optional[str] = Field(
1005
+ None,
1006
+ description='+usage=Timezone against which the cron schedule will be calculated, e.g. "Asia/Tokyo". Default is machine\'s local time.\nhttps://docs.truefoundry.com/docs/list-of-supported-timezones',
1007
+ )
1008
+
1009
+
1010
+ class SecretMount(BaseModel):
1011
+ type: Literal["secret"] = Field(..., description="+value=secret")
1012
+ mount_path: constr(regex=r"^\/(?:[^/\n]+\/*)*[^/\n]+(\.[^/\n]+)?$") = Field(
1013
+ ...,
1014
+ description="+label=File path\n+usage=Absolute file path where the file will be created.\n+message=Please enter a valid file path",
1015
+ )
1016
+ secret_fqn: constr(regex=r"^tfy-secret:\/\/.+:.+:.+$") = Field(
1017
+ ...,
1018
+ description="+label=Secret\n+usage=The Truefoundry secret whose value will be the file content.",
1019
+ )
1020
+
1021
+
1022
+ class ServiceAutoscaling(BaseAutoscaling):
1023
+ metrics: Union[CPUUtilizationMetric, RPSMetric, CronMetric] = Field(
1024
+ ...,
1025
+ description="+label=Autoscaling metrics\n+usage=Metrics to use for the autoscaler\n+sort=4",
1026
+ )
1027
+
1028
+
1029
+ class StaticVolumeConfig(BaseModel):
1030
+ """
1031
+ +label=Static Volume Config
1032
+ """
1033
+
1034
+ type: constr(regex=r"^static$") = Field(
1035
+ ...,
1036
+ description="+label=Volume Type\n+value=static\n+usage=Volume Type for the volume.",
1037
+ )
1038
+ persistent_volume_name: str = Field(
1039
+ ...,
1040
+ description="+label=Persistent Volume\n+usage=Persistent Volume Name of the volume to be used.",
1041
+ )
1042
+
1043
+
1044
+ class StringDataMount(BaseModel):
1045
+ type: Literal["string"] = Field(..., description="+value=string")
1046
+ mount_path: constr(regex=r"^\/(?:[^/\n]+\/*)*[^/\n]+(\.[^/\n]+)?$") = Field(
1047
+ ...,
1048
+ description="+label=File Path\n+usage=Absolute file path where the file will be created.\n+message=Please enter a valid file path",
1049
+ )
1050
+ data: str = Field(..., description="+label=Data\n+usage=The file content.")
1051
+
1052
+
1053
+ class TaskDockerFileBuild(BaseModel):
1054
+ """
1055
+ +docs=Describes the configuration for the docker build for a task
1056
+ +label=Docker File
1057
+ +icon=fa-brands fa-docker:#0db7ed
1058
+ """
1059
+
1060
+ type: Literal["task-dockerfile-build"] = Field(..., description="+value=dockerfile")
1061
+ dockerfile_path: str = Field(
1062
+ "./Dockerfile",
1063
+ description="+label=Path to Dockerfile\n+usage=The file path of the Dockerfile relative to project root path.",
1064
+ )
1065
+ build_args: Optional[Dict[str, str]] = Field(
1066
+ None, description="+label=Build arguments to pass to docker build"
1067
+ )
1068
+
1069
+
1070
+ class TaskPythonBuild(BaseModel):
1071
+ """
1072
+ +docs=Describes the configuration for the python build for a task
1073
+ +label=Python Buid Spec
1074
+ +icon=fa-brands fa-python:#306998
1075
+ """
1076
+
1077
+ type: Literal["task-python-build"] = Field(
1078
+ ..., description="+value=task-python-build"
1079
+ )
1080
+ python_version: constr(regex=r"^\d+(\.\d+){1,2}([\-\.a-z0-9]+)?$") = Field(
1081
+ "3.9",
1082
+ description="+label=Python version\n+usage=Python version to run your application. Should be one of the tags listed on [Official Python Docker Page](https://hub.docker.com/_/python)\n+message=Please enter a valid Python version tag",
1083
+ )
1084
+ requirements_path: Optional[str] = Field(
1085
+ None,
1086
+ description="`Path to build context`\n+label=Path to requirements\n+usage=Path to `requirements.txt` relative to\n`Path to build context`",
1087
+ )
1088
+ pip_packages: Optional[List[str]] = Field(
1089
+ None,
1090
+ description='+label=Pip packages to install\n+usage=Define pip package requirements.\nIn Python/YAML E.g. ["fastapi>=0.90,<1.0", "uvicorn"]\n+placeholder=Enter a pip package name E.g. fastapi>=0.90,<1.0',
1091
+ )
1092
+ apt_packages: Optional[List[str]] = Field(
1093
+ None,
1094
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
1095
+ )
1096
+ cuda_version: Optional[
1097
+ constr(
1098
+ 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)$"
1099
+ )
1100
+ ] = Field(
1101
+ None,
1102
+ description="+label=CUDA Version\n+usage=Version of CUDA Toolkit and CUDNN to install in the image\nThese combinations are based off of publically available docker images on docker hub\nYou can also specify a valid tag of the form {cuda_version_number}-cudnn{cudnn_version_number}-{runtime|devel}-ubuntu{ubuntu_version}\nRefer https://hub.docker.com/r/nvidia/cuda/tags for valid set of values\nNote: We use deadsnakes ubuntu ppa to add Python that currently supports only Ubuntu 18.04, 20.04 and 22.04",
1103
+ )
1104
+
1105
+
1106
+ class TruefoundryArtifactSource(BaseModel):
1107
+ """
1108
+ +docs=Input for Artifact from Truefoundry Artifact Registry
1109
+ +label=Truefoundry Artifact Source
1110
+ """
1111
+
1112
+ type: Literal["truefoundry-artifact"] = Field(
1113
+ ..., description="+value=truefoundry-artifact"
1114
+ )
1115
+ artifact_version_fqn: str = Field(
1116
+ ...,
1117
+ description="+label=Artifact or Model Version FQN\n+usage=Artifact or Model Version FQN of the artifact to be downloaded",
1118
+ )
1119
+ download_path_env_variable: str = Field(
1120
+ ...,
1121
+ description="+label=Download Path Environment Variable\n+usage=Environment variable which will contain the download path of the artifact",
1122
+ )
1123
+
1124
+
1125
+ class TruefoundryImageBase(BaseModel):
1126
+ """
1127
+ +usage=JupyterLab with persistent python environment (Python 3.11.6)
1128
+ """
1129
+
1130
+ type: constr(regex=r"^truefoundrybase$") = Field(
1131
+ ..., description="+value=truefoundrybase"
1132
+ )
1133
+ enable_sudo: bool = Field(
1134
+ True,
1135
+ description="+label=Enable root access to the container\n+usage=Changes made to the root directory `/` will not be persisted across notebook restarts",
1136
+ )
1137
+ apt_packages: Optional[List[str]] = Field(
1138
+ None,
1139
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
1140
+ )
1141
+ docker_registry: Optional[str] = Field(
1142
+ None,
1143
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
1144
+ )
1145
+
1146
+
1147
+ class TruefoundryImageCuda1180(BaseModel):
1148
+ """
1149
+ +usage=JupyterLab with persistent python environment (Python 3.11.6, Cuda 11.8.0)
1150
+ """
1151
+
1152
+ type: constr(regex=r"^truefoundrycuda1180$") = Field(
1153
+ ..., description="+value=truefoundrycuda1180"
1154
+ )
1155
+ apt_packages: Optional[List[str]] = Field(
1156
+ None,
1157
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
1158
+ )
1159
+ docker_registry: Optional[str] = Field(
1160
+ None,
1161
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
1162
+ )
1163
+
1164
+
1165
+ class TruefoundryImageCuda1211(BaseModel):
1166
+ """
1167
+ +usage=JupyterLab with persistent python environment (Python 3.11.6, Cuda 12.1.1)
1168
+ """
1169
+
1170
+ type: constr(regex=r"^truefoundrycuda1211$") = Field(
1171
+ ..., description="+value=truefoundrycuda1211"
1172
+ )
1173
+ apt_packages: Optional[List[str]] = Field(
1174
+ None,
1175
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
1176
+ )
1177
+ docker_registry: Optional[str] = Field(
1178
+ None,
1179
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
1180
+ )
1181
+
1182
+
1183
+ class TruefoundryImageFull(BaseModel):
1184
+ """
1185
+ +usage=JupyterLab + Tensorflow 2.15.0 and Pytorch 2.1.1 with persistent environment (Python 3.11.6)
1186
+ """
1187
+
1188
+ type: constr(regex=r"^truefoundryfull$") = Field(
1189
+ ..., description="+value=truefoundryfull"
1190
+ )
1191
+ enable_sudo: bool = Field(
1192
+ True,
1193
+ description="+label=Enable root access to the container\n+usage=Changes made to the root directory `/` will not be persisted across notebook restarts",
1194
+ )
1195
+ apt_packages: Optional[List[str]] = Field(
1196
+ None,
1197
+ description='+label=List of Debian packages to install.\n+usage=Debian packages to install via `apt get`.\nIn Python/YAML E.g. ["git", "ffmpeg", "htop"]\n+placeholder=Enter a debian package name E.g. ffmpeg',
1198
+ )
1199
+ docker_registry: Optional[str] = Field(
1200
+ None,
1201
+ 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?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
1202
+ )
1203
+
1204
+
1205
+ class VolumeBrowser(BaseModel):
1206
+ """
1207
+ +label=Volume Browser
1208
+ """
1209
+
1210
+ username: constr(regex=r"^[a-z][a-z0-9]{1,8}[a-z0-9]$") = Field(
1211
+ ...,
1212
+ description="+message=3 to 10 lower case characters long alphanumeric word, may contain - in between, cannot start with a number.\n+usage=Username for logging in the volume browser.\n+sort=1",
1213
+ )
1214
+ password_secret_fqn: constr(regex=r"^tfy-secret:\/\/.+:.+:.+$") = Field(
1215
+ ...,
1216
+ description="+label=Password Secret FQN\n+usage=TFY Secret containing the password for logging in the volume browser.\n+sort=2",
1217
+ )
1218
+ endpoint: Endpoint
1219
+ service_account: Optional[str] = Field(
1220
+ None,
1221
+ description="+label=Service Account Name\n+usage=Kubernetes Service account name for the volume browser.\n+sort=4",
1222
+ )
1223
+
1224
+
1225
+ class VolumeMount(BaseModel):
1226
+ type: Literal["volume"] = Field(..., description="+value=volume")
1227
+ mount_path: constr(regex=r"^\/(?:[^/\n]+\/*)*[^/\n]+(\.[^/\n]+)?$") = Field(
1228
+ ...,
1229
+ description="+label=Volume mount path\n+usage=Absolute file path where the volume will be mounted.\n+message=Please enter a valid mount path",
1230
+ )
1231
+ sub_path: Optional[str] = Field(
1232
+ None,
1233
+ description="+label=Sub Path\n+usage=Sub path within the volume to mount. Defaults to root of the volume.",
1234
+ )
1235
+ volume_fqn: constr(regex=r"^tfy-volume:\/\/.+:.+:.+$") = Field(
1236
+ ...,
1237
+ description="+label=Volume\n+usage=The Truefoundry volume that needs to be mounted.",
1238
+ )
1239
+
1240
+
1241
+ class Workflow(BaseModel):
1242
+ """
1243
+ +docs=Describes the configuration for the worflow
1244
+ """
1245
+
1246
+ type: constr(regex=r"^workflow$") = Field(..., description="+value=workflow")
1247
+ name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1248
+ ...,
1249
+ 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",
1250
+ )
1251
+ source: Union[LocalSource, RemoteSource] = Field(
1252
+ ...,
1253
+ description="+docs=Source Code for the workflow, either local or remote\n+label=Source Code for your workflow\n+icon=fa-solid fa-cloud-arrow-up:#21B6A8\n+sort=200",
1254
+ )
1255
+ env: Optional[Dict[str, str]] = Field(
1256
+ None,
1257
+ description="+label=Environment Variables\n+usage=Configure environment variables to be injected in the service either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables)\n+icon=fa-globe\n+sort=500",
1258
+ )
1259
+ docker_registry: Optional[str] = Field(
1260
+ None,
1261
+ description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
1262
+ )
1263
+ flyte_entities: List[Dict[str, Any]] = Field(
1264
+ ...,
1265
+ description="+docs=These\n+label=Flyte Entities\nActually ContainerTaskConfig and PythonTaskConfig are not flyte entities, this is just for code generation",
1266
+ )
1267
+
1268
+
1269
+ class ArtifactsDownload(BaseModel):
1270
+ """
1271
+ +docs=Describes the configuration for the artifacts cache
1272
+ +label=Artifacts Download
1273
+ +usage=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)
1274
+ """
1275
+
1276
+ cache_volume: Optional[ArtifactsCacheVolume] = None
1277
+ artifacts: List[Union[TruefoundryArtifactSource, HuggingfaceArtifactSource]] = (
1278
+ Field(
1279
+ ..., description="+label=Artifacts\n+usage=List of artifacts to be cached"
1280
+ )
1281
+ )
1282
+
1283
+
1284
+ class AsyncServiceAutoscaling(BaseAutoscaling):
1285
+ metrics: Union[
1286
+ SQSQueueMetricConfig,
1287
+ NATSMetricConfig,
1288
+ KafkaMetricConfig,
1289
+ CronMetric,
1290
+ AMQPMetricConfig,
1291
+ ] = Field(
1292
+ ...,
1293
+ description="+label=Autoscaling metrics\n+usage=Metrics to use for the autoscaler\n+sort=4",
1294
+ )
1295
+
1296
+
1297
+ class BaseWorkbenchInput(BaseModel):
1298
+ """
1299
+ +docs=Describes the configuration for the service
1300
+ """
1301
+
1302
+ name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1303
+ ...,
1304
+ description="+usage=Name of the workbench. This uniquely identifies this workbench in the workspace.\n> Name can only contain alphanumeric characters and '-' and can be atmost 25 characters long\n+sort=1\n+message=3 to 32 lower case characters long alphanumeric word, may contain - in between, cannot start with a number",
1305
+ )
1306
+ home_directory_size: conint(ge=5, le=64000) = Field(
1307
+ 20,
1308
+ description="+label=Home Directory Size in GB (Persistent)\n+usage=Size of the home directory for the workbench (Persistent Storage)\n+sort=6",
1309
+ )
1310
+ resources: Optional[Resources] = None
1311
+ env: Optional[Dict[str, str]] = Field(
1312
+ None,
1313
+ description="+label=Environment Variables\n+usage=Configure environment variables to be injected in the service either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/environment-variables-and-secrets-jobs)\n+sort=10110",
1314
+ )
1315
+ mounts: Optional[List[Union[SecretMount, StringDataMount, VolumeMount]]] = Field(
1316
+ None,
1317
+ description="+usage=Configure data to be mounted to workbench pod(s) as a string, secret or volume. [Docs](https://docs.truefoundry.com/docs/mounting-volumes-job)\n+sort=10111",
1318
+ )
1319
+ service_account: Optional[str] = Field(None, description="+sort=10113")
1320
+ kustomize: Optional[Kustomize] = None
1321
+
1322
+
1323
+ class Build(BaseModel):
1324
+ """
1325
+ +docs=Describes how we build our code into a Docker image.
1326
+ +label=Source Code (Build and deploy source code)
1327
+ +icon=fa-code
1328
+ """
1329
+
1330
+ type: Literal["build"] = Field(..., description="+value=build")
1331
+ docker_registry: Optional[str] = Field(
1332
+ None,
1333
+ description="+docs=FQN of the container registry. You can the FQN of your desired container registry (or add one)\nin the Integrations page[Integrations](https://app.truefoundry.tech/integrations?tab=docker-registry) page\n+label=Docker Registry\n+usage=FQN of the container registry. If you can't find your registry here,\nadd it through the [Integrations](/integrations?tab=docker-registry) page",
1334
+ )
1335
+ build_source: Union[RemoteSource, GitSource, LocalSource] = Field(
1336
+ ...,
1337
+ description="+docs=Source code location.\n+label=Fetch source code to build and deploy\n+icon=fa-code\n+sort=1",
1338
+ )
1339
+ build_spec: Union[DockerFileBuild, PythonBuild] = Field(
1340
+ ...,
1341
+ description="+docs=Instructions to build a container image out of the build source\n+label=Build using DockerFile or using Buildpack\n+icon=fa-wrench\n+sort=2",
1342
+ )
1343
+
1344
+
1345
+ class Canary(BaseModel):
1346
+ """
1347
+ +docs=This strategy brings up the new release without bringing the older release down. Traffic is shifted from the older release to the newer release in a staged manner.
1348
+ This can help with verifying the health of the new release without shifting complete traffic.
1349
+ +label=Canary strategy
1350
+ """
1351
+
1352
+ type: Literal["canary"] = Field(..., description="+value=canary")
1353
+ steps: List[CanaryStep] = Field(
1354
+ ...,
1355
+ description="+docs=These steps would be executed in order to enable shifting of traffic slowly from stable to canary version\n+label=Steps",
1356
+ )
1357
+
1358
+
1359
+ class Codeserver(BaseWorkbenchInput):
1360
+ """
1361
+ +docs=Describes the configuration for the code server
1362
+ """
1363
+
1364
+ type: constr(regex=r"^codeserver$") = Field(..., description="+value=Code Server")
1365
+ image: Union[CodeserverImage, CustomCodeserverImage] = Field(
1366
+ ..., description="+usage=Pick a codeserver image to deploy\n+sort=2"
1367
+ )
1368
+ auth: Optional[BasicAuthCreds] = None
1369
+
1370
+
1371
+ class ContainerTaskConfig(BaseModel):
1372
+ type: constr(regex=r"^container-task-config$") = Field(
1373
+ ..., description="+value=container-task-config"
1374
+ )
1375
+ image: Union[Build, Image] = Field(
1376
+ ...,
1377
+ description="+docs=Specify whether you want to deploy a Docker image or build and deploy from source code\n+label=Deploy a Docker image or build and deploy from source code\n+icon=fa-solid fa-cloud-arrow-up:#21B6A8\n+sort=200",
1378
+ )
1379
+ env: Optional[Dict[str, str]] = Field(
1380
+ None,
1381
+ description="+label=Environment Variables\n+usage=Configure environment variables to be injected in the task either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables)\n+icon=fa-globe\n+sort=200",
1382
+ )
1383
+ resources: Optional[Resources] = None
1384
+
1385
+
1386
+ class CoreNATSOutputConfig(BaseModel):
1387
+ """
1388
+ +docs=Describes the configuration for the output Core NATS worker
1389
+ +label=Core NATS
1390
+ """
1391
+
1392
+ type: Literal["core-nats"] = Field(..., description="+value=core-nats")
1393
+ nats_url: str = Field(
1394
+ ..., description="+label=NATS URL\n+usage=Output NATS URL\n+sort=1"
1395
+ )
1396
+ root_subject: constr(regex=r"^[a-zA-Z0-9][a-zA-Z0-9\-.]+[a-zA-Z0-9]$") = Field(
1397
+ ...,
1398
+ description="+label=Root Subject\n+usage=Root subject of output NATS\n+message=Output NATS root subject should only contain alphanumeric letters, dashes(-), and periods(.)\n+sort=2",
1399
+ )
1400
+ auth: Optional[NATSUserPasswordAuth] = None
1401
+
1402
+
1403
+ class HealthProbe(BaseModel):
1404
+ """
1405
+ +docs=Describes the configuration for the Health Probe's
1406
+ To learn more you can go [here](https://docs.truefoundry.com/docs/liveness-readiness-probe)
1407
+ +icon=fa-heart
1408
+ """
1409
+
1410
+ config: HttpProbe
1411
+ initial_delay_seconds: conint(ge=0, le=36000) = Field(
1412
+ 0,
1413
+ description="+usage=Number of seconds after the container is started before the first probe is initiated.",
1414
+ )
1415
+ period_seconds: conint(ge=1, le=36000) = Field(
1416
+ 10, description="+usage=How often, in seconds, to execute the probe."
1417
+ )
1418
+ timeout_seconds: conint(ge=1, le=36000) = Field(
1419
+ 1, description="+usage=Number of seconds after which the probe times out."
1420
+ )
1421
+ success_threshold: conint(ge=1, le=100) = Field(
1422
+ 1,
1423
+ description="+usage=Minimum consecutive successes for the probe to be considered successful after having failed.",
1424
+ )
1425
+ failure_threshold: conint(ge=1, le=100) = Field(
1426
+ 3,
1427
+ description="+usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).",
1428
+ )
1429
+
1430
+
1431
+ class Helm(BaseModel):
1432
+ type: constr(regex=r"^helm$") = Field(..., description="+value=helm")
1433
+ name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1434
+ ...,
1435
+ description="+sort=1\n+message=3 to 32 lower case characters long alphanumeric word, may contain - in between, cannot start with a number\n+usage=Name of the Helm deployment. This will be set as the release name of the chart you are deploying.",
1436
+ )
1437
+ labels: Optional[Dict[str, str]] = Field(
1438
+ None, description="+label=Labels\n+usage=Add labels to base argo app"
1439
+ )
1440
+ source: Union[HelmRepo, OCIRepo, GitHelmRepo] = Field(
1441
+ ..., description="+label=Source helm repository\n+sort=2"
1442
+ )
1443
+ values: Optional[Dict[str, Any]] = Field(
1444
+ None, description="+label=Values\n+usage=Values file as block file"
1445
+ )
1446
+ kustomize: Optional[Kustomize] = None
1447
+ ignoreDifferences: Optional[List[Dict[str, Any]]] = None
1448
+
1449
+
1450
+ class Job(BaseModel):
1451
+ """
1452
+ +docs=Describes the configuration for the job
1453
+ """
1454
+
1455
+ type: constr(regex=r"^job$") = Field(..., description="+value=job")
1456
+ name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1457
+ ...,
1458
+ description="+usage=Name of the job\n+sort=1\n+message=3 to 32 lower case characters long alphanumeric word, may contain - in between, cannot start with a number",
1459
+ )
1460
+ image: Union[Build, Image] = Field(
1461
+ ...,
1462
+ description="+docs=Specify whether you want to deploy a Docker image or build and deploy from source code\n+label=Deploy a Docker image or build and deploy from source code\n+icon=fa-solid fa-cloud-arrow-up:#21B6A8\n+sort=200",
1463
+ )
1464
+ trigger: Union[Manual, Schedule] = Field(
1465
+ {"type": "manual"}, description="+docs=Specify the trigger\n+sort=300"
1466
+ )
1467
+ trigger_on_deploy: bool = Field(
1468
+ False,
1469
+ description="+docs=Trigger on deploy\n+sort=350\n+usage=Trigger the job after deploy immediately",
1470
+ )
1471
+ params: Optional[List[Param]] = Field(
1472
+ None,
1473
+ description="+label=Params for input\n+usage=Configure params and pass it to create different job runs\n+sort=400",
1474
+ )
1475
+ env: Optional[Dict[str, str]] = Field(
1476
+ None,
1477
+ description="+label=Environment Variables\n+usage=Configure environment variables to be injected in the service either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables)\n+icon=fa-globe\n+sort=500",
1478
+ )
1479
+ resources: Optional[Resources] = None
1480
+ retries: conint(ge=0, le=10) = Field(
1481
+ 0,
1482
+ description="+label=Retries\n+usage=Specify the maximum number of attempts to retry a job before it is marked as failed.\n+icon=fa-repeat\n+sort=700",
1483
+ )
1484
+ timeout: Optional[conint(le=432000, gt=0)] = Field(
1485
+ None,
1486
+ description="+label=Timeout\n+usage=Job timeout in seconds.\n+icon=fa-clock\n+sort=800",
1487
+ )
1488
+ concurrency_limit: Optional[PositiveInt] = Field(
1489
+ None,
1490
+ description="+label=Concurrency Limit\n+usage=Number of runs that can run concurrently\n+icon=fa-copy\n+sort=900",
1491
+ )
1492
+ service_account: Optional[str] = Field(None, description="+sort=1000")
1493
+ mounts: Optional[List[Union[SecretMount, StringDataMount, VolumeMount]]] = Field(
1494
+ None,
1495
+ description="+usage=Configure data to be mounted to job pod(s) as a string, secret or volume. [Docs](https://docs.truefoundry.com/docs/mounting-volumes-job)",
1496
+ )
1497
+ labels: Optional[Dict[str, str]] = Field(None, description="+label=Labels")
1498
+ kustomize: Optional[Kustomize] = None
1499
+
1500
+
1501
+ class KafkaInputConfig(BaseModel):
1502
+ """
1503
+ +docs=Describes the configuration for the input Kafka worker
1504
+ +label=Kafka
1505
+ """
1506
+
1507
+ type: Literal["kafka"] = Field(..., description="+value=kafka")
1508
+ bootstrap_servers: str = Field(
1509
+ ...,
1510
+ description="+label=Bootstrap servers\n+usage='Kafka Bootstrap servers - Comma separated list of Kafka brokers \"hostname:port\" to connect to for bootstrap'\n+sort=1",
1511
+ )
1512
+ topic_name: str = Field(
1513
+ ...,
1514
+ description="+label=Topic Name\n+usage=Kafka topic to subscribe to\n+sort=2",
1515
+ )
1516
+ consumer_group: str = Field(
1517
+ ...,
1518
+ description="+label=Consumer Group Name\n+usage=The name of the consumer group to join for dynamic partition assignment\n+sort=3",
1519
+ )
1520
+ tls: bool = Field(
1521
+ True, description="+label=TLS\n+usage=TLS configuration for SASL authentication"
1522
+ )
1523
+ wait_time_seconds: conint(ge=1, le=300) = Field(
1524
+ 10,
1525
+ description="+label=Wait Time Seconds\n+usage=Wait timeout for long polling.",
1526
+ )
1527
+ auth: Optional[KafkaSASLAuth] = None
1528
+
1529
+
1530
+ class KafkaOutputConfig(BaseModel):
1531
+ """
1532
+ +docs=Describes the configuration for the output Kafka worker
1533
+ +label=Kafka
1534
+ """
1535
+
1536
+ type: Literal["kafka"] = Field(..., description="+value=kafka")
1537
+ bootstrap_servers: str = Field(
1538
+ ...,
1539
+ description="+label=Bootstrap servers\n+usage='Kafka Bootstrap servers - Comma separated list of Kafka brokers \"hostname:port\" to connect to for bootstrap'\n+sort=1",
1540
+ )
1541
+ topic_name: str = Field(
1542
+ ..., description="+label=Topic Name\n+usage=Kafka topic to publish to\n+sort=2"
1543
+ )
1544
+ tls: bool = Field(
1545
+ True, description="+label=TLS\n+usage=TLS configuration for SASL authentication"
1546
+ )
1547
+ auth: Optional[KafkaSASLAuth] = None
1548
+
1549
+
1550
+ class NATSInputConfig(BaseModel):
1551
+ """
1552
+ +docs=Describes the configuration for the input NATS worker
1553
+ +label=NATS
1554
+ """
1555
+
1556
+ type: Literal["nats"] = Field(..., description="+value=nats")
1557
+ nats_url: str = Field(
1558
+ ..., description="+label=NATS URL\n+usage=Input NATS URL\n+sort=1"
1559
+ )
1560
+ stream_name: str = Field(
1561
+ ..., description="+label=Stream Name\n+usage=Name of the NATS stream\n+sort=2"
1562
+ )
1563
+ root_subject: constr(regex=r"^[a-zA-Z0-9][a-zA-Z0-9\-.]+[a-zA-Z0-9]$") = Field(
1564
+ ...,
1565
+ description="+label=Root Subject\n+usage=Root subject of input NATS\n+message=Input NATS root subject should only contain alphanumeric letters, dashes(-), and periods(.)\n+sort=3",
1566
+ )
1567
+ consumer_name: constr(regex=r"^[a-zA-Z0-9][a-zA-Z0-9\-_]+[a-zA-Z0-9]$") = Field(
1568
+ ...,
1569
+ description="+label=Consumer Name\n+usage=Consumer name of input NATS\n+message=Consumer name should only contain alphanumeric letters, dashes(-), and underscores(_)\n+sort=4",
1570
+ )
1571
+ wait_time_seconds: conint(ge=1, le=20) = Field(
1572
+ 19,
1573
+ description="+label=Wait Time Seconds\n+usage=Wait timeout for long polling.\n+sort=5",
1574
+ )
1575
+ nats_metrics_url: Optional[constr(regex=r"^(http(s?)://).*$")] = Field(
1576
+ None,
1577
+ description="+label=NATS metrics URL\n+usage=URL for the NATS metrics endpoint. It is compulsory if you want to use NATS autoscaling.\n+message=NATS Metrics URL should be a valid HTTP/HTTPS URL",
1578
+ )
1579
+ auth: Optional[NATSUserPasswordAuth] = None
1580
+
1581
+
1582
+ class NATSOutputConfig(BaseModel):
1583
+ """
1584
+ +docs=Describes the configuration for the output NATS worker
1585
+ +label=NATS
1586
+ """
1587
+
1588
+ type: Literal["nats"] = Field(..., description="+value=nats")
1589
+ nats_url: str = Field(
1590
+ ..., description="+label=NATS URL\n+usage=Output NATS URL\n+sort=1"
1591
+ )
1592
+ root_subject: constr(regex=r"^[a-zA-Z0-9][a-zA-Z0-9\-.]+[a-zA-Z0-9]$") = Field(
1593
+ ...,
1594
+ description="+label=Root Subject\n+usage=Root subject of output NATS\n+message=Output NATS root subject should only contain alphanumeric letters, dashes(-), and periods(.)\n+sort=2",
1595
+ )
1596
+ auth: Optional[NATSUserPasswordAuth] = None
1597
+
1598
+
1599
+ class Notebook(BaseWorkbenchInput):
1600
+ """
1601
+ +docs=Describes the configuration for the service
1602
+ """
1603
+
1604
+ type: constr(regex=r"^notebook$") = Field(..., description="+value=notebook")
1605
+ image: Union[
1606
+ TruefoundryImageBase,
1607
+ TruefoundryImageFull,
1608
+ CustomNotebookImage,
1609
+ TruefoundryImageCuda1180,
1610
+ TruefoundryImageCuda1211,
1611
+ ] = Field(
1612
+ ...,
1613
+ description="+usage=Changes made to the root directory `/` will not be persisted across notebook restarts\n+sort=2",
1614
+ )
1615
+ auth: Optional[BasicAuthCreds] = None
1616
+ cull_timeout: conint(ge=5) = Field(
1617
+ 30,
1618
+ description="+label=Stop after (minutes of inactivity)\n+usage=Stop the notebook instance after this much time in minutes of inactivity.\nThe notebook instance will be stopped even if the notebook is open in your browser, but nothing is running on the notebook.\n+sort=5",
1619
+ )
1620
+
1621
+
1622
+ class PythonTaskConfig(BaseModel):
1623
+ """
1624
+ +docs=Describes the configuration for the python function task
1625
+ """
1626
+
1627
+ type: constr(regex=r"^python-task-config$") = Field(
1628
+ ..., description="+value=python-task-config"
1629
+ )
1630
+ image: Union[TaskPythonBuild, TaskDockerFileBuild] = Field(
1631
+ ...,
1632
+ description="+label=Image Spec\n+docs=Specification for the image to be used for the task\n+sort=100\n+usage=Specify the image spec for the task",
1633
+ )
1634
+ env: Optional[Dict[str, str]] = Field(
1635
+ None,
1636
+ description="+label=Environment Variables\n+usage=Configure environment variables to be injected in the task either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables)\n+icon=fa-globe\n+sort=200",
1637
+ )
1638
+ resources: Optional[Resources] = None
1639
+
1640
+
1641
+ class SSHServer(BaseWorkbenchInput):
1642
+ """
1643
+ +docs=Describes the configuration for the ssh server
1644
+ """
1645
+
1646
+ type: constr(regex=r"^ssh-server$") = Field(..., description="+value=SSH Server")
1647
+ image: Union[SSHServerImage, CustomSSHServerImage] = Field(
1648
+ ..., description="+usage=Pick a ssh server image to deploy\n+sort=2"
1649
+ )
1650
+ ssh_public_key: str = Field(
1651
+ ...,
1652
+ description="+label: SSH Public Key\n+usage=Add Your SSH Public Key, this will be used to authenticate you to the SSH Server. You can find it using `cat ~/.ssh/id_rsa.pub`\n+sort=4",
1653
+ )
1654
+
1655
+
1656
+ class Volume(BaseModel):
1657
+ type: constr(regex=r"^volume$") = Field(..., description="+value=volume")
1658
+ name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1659
+ ...,
1660
+ description="+sort=1\n+message=3 to 32 lower case characters long alphanumeric word, may contain - in between, cannot start with a number\n+usage=Name of the Volume. This will be set as the volume name.",
1661
+ )
1662
+ config: Union[DynamicVolumeConfig, StaticVolumeConfig] = Field(
1663
+ ...,
1664
+ description="+sort=2\n+label=Volume Config\n+message=Volume Configuration, can be either Dynamically provisioned or statically provisioned.",
1665
+ )
1666
+ volume_browser: Optional[VolumeBrowser] = None
1667
+
1668
+
1669
+ class WorkerConfig(BaseModel):
1670
+ input_config: Union[
1671
+ SQSInputConfig, NATSInputConfig, KafkaInputConfig, AMQPInputConfig
1672
+ ] = Field(..., description="+label=Input Config\n+usage=Input Config\n+sort=1")
1673
+ output_config: Optional[
1674
+ Union[
1675
+ SQSOutputConfig,
1676
+ NATSOutputConfig,
1677
+ CoreNATSOutputConfig,
1678
+ KafkaOutputConfig,
1679
+ AMQPOutputConfig,
1680
+ ]
1681
+ ] = Field(None, description="+label=Output Config\n+usage=Output Config\n+sort=2")
1682
+ num_concurrent_workers: conint(ge=1, le=10) = Field(
1683
+ 1,
1684
+ description="+label=Number of Concurrent Workers\n+usage=Number of concurrent workers to spawn for the processor\n+sort=3",
1685
+ )
1686
+
1687
+
1688
+ class BaseService(BaseModel):
1689
+ name: constr(regex=r"^[a-z][a-z0-9\-]{1,30}[a-z0-9]$") = Field(
1690
+ ...,
1691
+ description="+usage=Name of the service. This uniquely identifies this service in the workspace.\n> Name can only contain alphanumeric characters and '-' and can be atmost 25 characters long\n+sort=1\n+message=3 to 32 lower case characters long alphanumeric word, may contain - in between, cannot start with a number",
1692
+ )
1693
+ image: Union[Build, Image] = Field(
1694
+ ...,
1695
+ description="+docs=Specify whether you want to deploy a Docker image or build and deploy from source code\n+label=Deploy a Docker image or build and deploy from source code\n+icon=fa-solid fa-cloud-arrow-up:#21B6A8\n+sort=2",
1696
+ )
1697
+ artifacts_download: Optional[ArtifactsDownload] = None
1698
+ resources: Optional[Resources] = None
1699
+ env: Optional[Dict[str, str]] = Field(
1700
+ None,
1701
+ description="+label=Environment Variables\n+usage=Configure environment variables to be injected in the service either as plain text or secrets. [Docs](https://docs.truefoundry.com/docs/env-variables)\n+icon=fa-globe\n+sort=6",
1702
+ )
1703
+ ports: List[Port] = Field(
1704
+ ...,
1705
+ description="+docs=Specify the ports you want the service to be exposed to\n+label=Configure ports and endpoints to route customer traffic\n+usage=Expose the deployment to make it accessible over the internet or keep it private. Implement authentication to restrict access. [Docs](https://docs.truefoundry.com/docs/define-ports-and-domains)\n+icon=fa-plug\n+sort=4",
1706
+ )
1707
+ service_account: Optional[str] = None
1708
+ mounts: Optional[List[Union[SecretMount, StringDataMount, VolumeMount]]] = Field(
1709
+ None,
1710
+ description="+usage=Configure data to be mounted to service pod(s) as a string, secret or volume. [Docs](https://docs.truefoundry.com/docs/mounting-volumes-service)\n+sort=10011",
1711
+ )
1712
+ labels: Optional[Dict[str, str]] = Field(None, description="+label=Labels")
1713
+ kustomize: Optional[Kustomize] = None
1714
+ liveness_probe: Optional[HealthProbe] = None
1715
+ readiness_probe: Optional[HealthProbe] = None
1716
+
1717
+
1718
+ class Service(BaseService):
1719
+ """
1720
+ +docs=Describes the configuration for the service
1721
+ """
1722
+
1723
+ type: Literal["service"] = Field(..., description="+value=service")
1724
+ replicas: Union[confloat(ge=0.0, le=500.0), ServiceAutoscaling] = Field(
1725
+ 1,
1726
+ description="+label=Replicas\n+usage=Deploy multiple instances of your pods to distribute incoming traffic across them, ensuring effective load balancing.\n+icon=fa-clone\n+sort=4",
1727
+ )
1728
+ allow_interception: bool = Field(
1729
+ False,
1730
+ description="+label=Allow intercepts\n+usage=Whether to allow intercepts to be applied for this service.\nThis would inject an additional sidecar in each pod of the service. Not recommended on production",
1731
+ )
1732
+ rollout_strategy: Optional[Union[Rolling, Canary, BlueGreen]] = Field(
1733
+ None,
1734
+ description="+label=Rollout strategy\n+usage=Strategy to dictate how a rollout should happen when a new release for this service is made [Docs](https://docs.truefoundry.com/docs/rollout-strategy)",
1735
+ )
1736
+
1737
+
1738
+ class AsyncService(BaseService):
1739
+ """
1740
+ +docs=Describes the configuration for the async-service
1741
+ """
1742
+
1743
+ type: Literal["async-service"] = Field(..., description="+value=async-service")
1744
+ replicas: Union[confloat(ge=0.0, le=500.0), AsyncServiceAutoscaling] = Field(
1745
+ 1,
1746
+ description="+label=Replicas\n+usage=Deploy multiple instances of your pods to distribute incoming traffic across them, ensuring effective load balancing.\n+icon=fa-clone",
1747
+ )
1748
+ rollout_strategy: Optional[Rolling] = None
1749
+ worker_config: WorkerConfig
1750
+ sidecar: Optional[AsyncProcessorSidecar] = None
1751
+
1752
+
1753
+ class ApplicationSet(BaseModel):
1754
+ """
1755
+ +docs=Describes the configuration for the application set
1756
+ """
1757
+
1758
+ type: constr(regex=r"^application-set$") = Field(
1759
+ ..., description="+value=application-set"
1760
+ )
1761
+ name: str = Field(
1762
+ ...,
1763
+ description="+label=Name\n+usage=Name of the application set.\n+icon=fa-font",
1764
+ )
1765
+ components: Optional[List[Union[Service, AsyncService, Job, Helm]]] = Field(
1766
+ None,
1767
+ description="+label=Components\n+usage=Array of components with their specifications.\n+icon=fa-puzzle-piece\n+uiType=AppComponents",
1768
+ )
1769
+ template: Optional[str] = Field(
1770
+ None,
1771
+ description="+label=Template\n+usage=Template to be used for the application set.\n+icon=fa-file\n+uiType=Hidden",
1772
+ )
1773
+ values: Optional[Dict[str, Any]] = Field(
1774
+ None,
1775
+ description='+label=Values\n+usage=Values to be used to render components for the application set.\n+icon=fa-file\n+uiType=YamlInput\n+uiProps={"allowAllValues":true}',
1776
+ )
1777
+
1778
+
1779
+ class Application(BaseModel):
1780
+ __root__: Union[
1781
+ Service,
1782
+ AsyncService,
1783
+ Job,
1784
+ Notebook,
1785
+ Codeserver,
1786
+ SSHServer,
1787
+ Helm,
1788
+ Volume,
1789
+ ApplicationSet,
1790
+ Workflow,
1791
+ ]