thestage 0.6.5__py3-none-any.whl → 0.6.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- thestage/__init__.py +1 -1
- thestage/color_scheme/color_scheme.py +1 -0
- thestage/controllers/base_controller.py +4 -3
- thestage/controllers/config_controller.py +16 -4
- thestage/controllers/container_controller.py +151 -106
- thestage/controllers/instance_controller.py +35 -9
- thestage/controllers/project_controller.py +335 -89
- thestage/entities/container.py +5 -3
- thestage/entities/project_inference_simulator.py +2 -1
- thestage/entities/project_inference_simulator_model.py +2 -2
- thestage/entities/project_task.py +2 -3
- thestage/entities/rented_instance.py +2 -2
- thestage/entities/self_hosted_instance.py +2 -2
- thestage/helpers/error_handler.py +1 -1
- thestage/main.py +1 -1
- thestage/services/clients/git/git_client.py +1 -1
- thestage/services/clients/thestage_api/api_client.py +142 -109
- thestage/services/clients/thestage_api/dtos/base_controller/connect_resolve_response.py +22 -0
- thestage/services/clients/thestage_api/dtos/container_param_request.py +1 -1
- thestage/services/clients/thestage_api/dtos/container_response.py +1 -21
- thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +2 -1
- thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +5 -1
- thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +2 -1
- thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +1 -0
- thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +2 -1
- thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_request.py → inference_simulator_list_request.py} +3 -2
- thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_response.py → inference_simulator_list_response.py} +1 -1
- thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +2 -1
- thestage/services/clients/thestage_api/dtos/instance_rented_response.py +4 -37
- thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +3 -3
- thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +3 -11
- thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +1 -0
- thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +2 -1
- thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +2 -4
- thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +3 -0
- thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +5 -3
- thestage/services/clients/thestage_api/dtos/project_response.py +3 -15
- thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +2 -20
- thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +1 -1
- thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +4 -2
- thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +1 -1
- thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +4 -1
- thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +0 -2
- thestage/services/config_provider/config_provider.py +2 -2
- thestage/services/connect/connect_service.py +77 -74
- thestage/services/container/container_service.py +120 -41
- thestage/services/container/mapper/container_mapper.py +2 -1
- thestage/services/instance/instance_service.py +13 -20
- thestage/services/instance/mapper/instance_mapper.py +1 -3
- thestage/services/instance/mapper/selfhosted_mapper.py +3 -4
- thestage/services/logging/logging_service.py +45 -48
- thestage/services/project/dto/inference_simulator_dto.py +1 -10
- thestage/services/project/dto/inference_simulator_model_dto.py +2 -10
- thestage/services/project/dto/project_config.py +2 -2
- thestage/services/project/mapper/project_inference_simulator_mapper.py +1 -0
- thestage/services/project/mapper/project_inference_simulator_model_mapper.py +2 -2
- thestage/services/project/mapper/project_task_mapper.py +2 -3
- thestage/services/project/project_service.py +174 -140
- thestage/services/remote_server_service.py +1 -0
- thestage/services/task/dto/task_dto.py +3 -23
- {thestage-0.6.5.dist-info → thestage-0.6.7.dist-info}/METADATA +4 -2
- {thestage-0.6.5.dist-info → thestage-0.6.7.dist-info}/RECORD +65 -74
- {thestage-0.6.5.dist-info → thestage-0.6.7.dist-info}/WHEEL +1 -1
- thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +0 -19
- thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +0 -10
- thestage/services/clients/thestage_api/dtos/enums/currency_type.py +0 -10
- thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +0 -9
- thestage/services/clients/thestage_api/dtos/enums/disk_type.py +0 -7
- thestage/services/clients/thestage_api/dtos/enums/drive_type.py +0 -7
- thestage/services/clients/thestage_api/dtos/enums/instance_type.py +0 -7
- thestage/services/clients/thestage_api/dtos/enums/location_region.py +0 -11
- thestage/services/clients/thestage_api/dtos/enums/power_status.py +0 -10
- thestage/services/clients/thestage_api/dtos/price_definition.py +0 -14
- {thestage-0.6.5.dist-info → thestage-0.6.7.dist-info}/entry_points.txt +0 -0
- {thestage-0.6.5.dist-info → thestage-0.6.7.dist-info/licenses}/LICENSE.txt +0 -0
|
@@ -43,9 +43,9 @@ class LoggingService:
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
@error_handler()
|
|
46
|
-
def print_last_task_logs(self,
|
|
46
|
+
def print_last_task_logs(self, task_public_id: str, logs_number: Optional[int]):
|
|
47
47
|
logs = self.__thestage_api_client.query_user_logs(
|
|
48
|
-
|
|
48
|
+
task_public_id=task_public_id,
|
|
49
49
|
limit=logs_number
|
|
50
50
|
)
|
|
51
51
|
for log_message in reversed(logs.queryResult):
|
|
@@ -53,9 +53,9 @@ class LoggingService:
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
@error_handler()
|
|
56
|
-
def print_last_inference_simulator_logs(self,
|
|
56
|
+
def print_last_inference_simulator_logs(self, inference_simulator_public_id: str, logs_number: Optional[int]):
|
|
57
57
|
logs = self.__thestage_api_client.query_user_logs(
|
|
58
|
-
|
|
58
|
+
inference_simulator_public_id=inference_simulator_public_id,
|
|
59
59
|
limit=logs_number
|
|
60
60
|
)
|
|
61
61
|
for log_message in reversed(logs.queryResult):
|
|
@@ -63,9 +63,10 @@ class LoggingService:
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
@error_handler()
|
|
66
|
-
def print_last_container_logs(self,
|
|
66
|
+
def print_last_container_logs(self, container_public_id: Optional[str], container_slug: Optional[str], logs_number: Optional[int]):
|
|
67
67
|
container: Optional[DockerContainerDto] = self.__thestage_api_client.get_container(
|
|
68
|
-
|
|
68
|
+
container_public_id=container_public_id,
|
|
69
|
+
container_slug=container_slug,
|
|
69
70
|
)
|
|
70
71
|
|
|
71
72
|
if not container:
|
|
@@ -73,7 +74,7 @@ class LoggingService:
|
|
|
73
74
|
raise typer.Exit(1)
|
|
74
75
|
|
|
75
76
|
logs = self.__thestage_api_client.query_user_logs(
|
|
76
|
-
|
|
77
|
+
container_public_id=container.public_id,
|
|
77
78
|
limit=logs_number
|
|
78
79
|
)
|
|
79
80
|
for log_message in reversed(logs.queryResult):
|
|
@@ -81,15 +82,15 @@ class LoggingService:
|
|
|
81
82
|
|
|
82
83
|
|
|
83
84
|
@error_handler()
|
|
84
|
-
def stream_task_logs_with_controls(self,
|
|
85
|
+
def stream_task_logs_with_controls(self, task_public_id: str):
|
|
85
86
|
asyncio.run(
|
|
86
|
-
self.__stream_task_logs_with_controls_async(
|
|
87
|
+
self.__stream_task_logs_with_controls_async(task_public_id=task_public_id)
|
|
87
88
|
)
|
|
88
89
|
|
|
89
90
|
|
|
90
91
|
@error_handler()
|
|
91
|
-
async def __stream_task_logs_with_controls_async(self,
|
|
92
|
-
task_view_response: Optional[TaskViewResponse] = self.__thestage_api_client.get_task(
|
|
92
|
+
async def __stream_task_logs_with_controls_async(self, task_public_id: str):
|
|
93
|
+
task_view_response: Optional[TaskViewResponse] = self.__thestage_api_client.get_task(task_public_id=task_public_id,)
|
|
93
94
|
|
|
94
95
|
task_status_map: Dict[str, str] = self.__thestage_api_client.get_task_localized_status_map()
|
|
95
96
|
|
|
@@ -98,25 +99,20 @@ class LoggingService:
|
|
|
98
99
|
if task:
|
|
99
100
|
if task.frontend_status.status_key not in [TaskStatus.RUNNING, TaskStatus.SCHEDULED]:
|
|
100
101
|
typer.echo(__("Task must be in status '%required_status%' to stream real-time logs. Task %task_id% status: '%status%'.", {
|
|
101
|
-
'task_id': str(task.
|
|
102
|
+
'task_id': str(task.public_id),
|
|
102
103
|
'status': task.frontend_status.status_translation,
|
|
103
104
|
'required_status': task_status_map.get(TaskStatus.RUNNING) or TaskStatus.RUNNING
|
|
104
105
|
}))
|
|
105
106
|
raise typer.Exit(1)
|
|
106
107
|
else:
|
|
107
|
-
typer.echo(
|
|
108
|
+
typer.echo(f"Task with ID {task_public_id} was not found")
|
|
108
109
|
raise typer.Exit(1)
|
|
109
110
|
|
|
110
|
-
typer.echo(
|
|
111
|
-
f"Log stream for task %task_id% started",
|
|
112
|
-
{
|
|
113
|
-
'task_id': str(task.id),
|
|
114
|
-
}
|
|
115
|
-
))
|
|
111
|
+
typer.echo(f"Log stream for task {task.public_id} started")
|
|
116
112
|
|
|
117
113
|
typer.echo(__("CTRL+C to cancel the task. CTRL+D to disconnect from log stream."))
|
|
118
114
|
|
|
119
|
-
print_logs_task = asyncio.create_task(self.print_realtime_logs(
|
|
115
|
+
print_logs_task = asyncio.create_task(self.print_realtime_logs(task_public_id=task.public_id))
|
|
120
116
|
input_task = asyncio.create_task(self.read_log_stream_input())
|
|
121
117
|
|
|
122
118
|
def sigint_handler():
|
|
@@ -131,22 +127,24 @@ class LoggingService:
|
|
|
131
127
|
if input_task in done:
|
|
132
128
|
print_logs_task.cancel()
|
|
133
129
|
if not input_task.result(): # result is only expected if ctrl+D triggered EOFError
|
|
134
|
-
typer.echo(f"\rTask {
|
|
130
|
+
typer.echo(f"\rTask {task_public_id} will be canceled")
|
|
135
131
|
self.__thestage_api_client.cancel_task(
|
|
136
|
-
|
|
132
|
+
task_public_id=task.public_id,
|
|
137
133
|
)
|
|
138
134
|
|
|
139
135
|
@error_handler()
|
|
140
|
-
def stream_inference_simulator_logs_with_controls(self, slug: str):
|
|
136
|
+
def stream_inference_simulator_logs_with_controls(self, public_id: Optional[str] = None, slug: Optional[str] = None):
|
|
141
137
|
asyncio.run(
|
|
142
138
|
self.__stream_inference_simulator_logs_with_controls_async(
|
|
139
|
+
public_id=public_id,
|
|
143
140
|
slug=slug
|
|
144
141
|
)
|
|
145
142
|
)
|
|
146
143
|
|
|
147
144
|
@error_handler()
|
|
148
|
-
async def __stream_inference_simulator_logs_with_controls_async(self, slug: str):
|
|
145
|
+
async def __stream_inference_simulator_logs_with_controls_async(self, public_id: Optional[str], slug: Optional[str]):
|
|
149
146
|
get_inference_simulator_response: Optional[GetInferenceSimulatorResponse] = self.__thestage_api_client.get_inference_simulator(
|
|
147
|
+
public_id=public_id,
|
|
150
148
|
slug=slug,
|
|
151
149
|
)
|
|
152
150
|
|
|
@@ -164,20 +162,15 @@ class LoggingService:
|
|
|
164
162
|
}))
|
|
165
163
|
raise typer.Exit(1)
|
|
166
164
|
else:
|
|
167
|
-
typer.echo(
|
|
165
|
+
typer.echo("Inference simulator was not found")
|
|
168
166
|
raise typer.Exit(1)
|
|
169
167
|
|
|
170
|
-
typer.echo(
|
|
171
|
-
f"Log stream for inference simulator %slug% started",
|
|
172
|
-
{
|
|
173
|
-
'slug': str(inference_simulator.slug),
|
|
174
|
-
}
|
|
175
|
-
))
|
|
168
|
+
typer.echo(f"Log stream for inference simulator '{inference_simulator.public_id}' started")
|
|
176
169
|
|
|
177
170
|
typer.echo(__("CTRL+D to disconnect from log stream."))
|
|
178
171
|
|
|
179
172
|
print_task_or_inference_simulator_logs = asyncio.create_task(
|
|
180
|
-
self.print_realtime_logs(
|
|
173
|
+
self.print_realtime_logs(inference_simulator_public_id=inference_simulator.public_id)
|
|
181
174
|
)
|
|
182
175
|
input_task = asyncio.create_task(self.read_log_stream_input())
|
|
183
176
|
|
|
@@ -186,22 +179,25 @@ class LoggingService:
|
|
|
186
179
|
|
|
187
180
|
if input_task in done:
|
|
188
181
|
print_task_or_inference_simulator_logs.cancel()
|
|
189
|
-
|
|
182
|
+
inference_logs_cmd_id = f"-isn {slug}" if slug else f"-isid {public_id}"
|
|
183
|
+
typer.echo(f"Disconnected from log stream. You can try to reconnect with 'thestage project inference-simulator logs {inference_logs_cmd_id}'")
|
|
190
184
|
|
|
191
185
|
|
|
192
186
|
@error_handler()
|
|
193
|
-
def stream_container_logs_with_controls(self,
|
|
187
|
+
def stream_container_logs_with_controls(self, container_public_id: Optional[str], container_slug: Optional[str]):
|
|
194
188
|
asyncio.run(
|
|
195
189
|
self.__stream_container_logs_with_controls_async(
|
|
196
|
-
|
|
190
|
+
container_public_id=container_public_id,
|
|
191
|
+
container_slug=container_slug
|
|
197
192
|
)
|
|
198
193
|
)
|
|
199
194
|
|
|
200
195
|
|
|
201
196
|
@error_handler()
|
|
202
|
-
async def __stream_container_logs_with_controls_async(self,
|
|
197
|
+
async def __stream_container_logs_with_controls_async(self, container_public_id: Optional[str], container_slug: Optional[str]):
|
|
203
198
|
container: Optional[DockerContainerDto] = self.__thestage_api_client.get_container(
|
|
204
|
-
|
|
199
|
+
container_public_id=container_public_id,
|
|
200
|
+
container_slug=container_slug,
|
|
205
201
|
)
|
|
206
202
|
|
|
207
203
|
if container:
|
|
@@ -214,7 +210,7 @@ class LoggingService:
|
|
|
214
210
|
typer.echo(f"Log stream for Docker container started")
|
|
215
211
|
typer.echo("CTRL+D to disconnect from log stream.")
|
|
216
212
|
|
|
217
|
-
print_logs_task = asyncio.create_task(self.print_realtime_logs(
|
|
213
|
+
print_logs_task = asyncio.create_task(self.print_realtime_logs(docker_container_public_id=container.public_id))
|
|
218
214
|
input_task = asyncio.create_task(self.read_log_stream_input())
|
|
219
215
|
|
|
220
216
|
def sigint_handler():
|
|
@@ -243,9 +239,9 @@ class LoggingService:
|
|
|
243
239
|
|
|
244
240
|
async def print_realtime_logs(
|
|
245
241
|
self,
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
242
|
+
task_public_id: Optional[str] = None,
|
|
243
|
+
inference_simulator_public_id: Optional[str] = None,
|
|
244
|
+
docker_container_public_id: Optional[str] = None,
|
|
249
245
|
):
|
|
250
246
|
polling_interval_seconds: float = 4 # also adjust polling api method timeout if changed
|
|
251
247
|
between_logs_sleeping_coef: float = 1 # we emulate delay between logs, but if for any reason code runs for too long - delays will be controlled with this coef
|
|
@@ -269,9 +265,9 @@ class LoggingService:
|
|
|
269
265
|
# print_nonblocking(f'TDIFF {stream_to_logs_diff.total_seconds()}', writer)
|
|
270
266
|
try:
|
|
271
267
|
logs_response = await self.__thestage_api_client.poll_logs_httpx(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
task_public_id=task_public_id,
|
|
269
|
+
inference_simulator_public_id=inference_simulator_public_id,
|
|
270
|
+
docker_container_public_id=docker_container_public_id,
|
|
275
271
|
last_log_timestamp=last_iteration_log_timestamp,
|
|
276
272
|
last_log_id=last_log_id
|
|
277
273
|
)
|
|
@@ -285,6 +281,7 @@ class LoggingService:
|
|
|
285
281
|
consecutive_error_count = 0
|
|
286
282
|
errors_started_at = None
|
|
287
283
|
log_wait_remaining_limit = 0 # no log delays after reconnect
|
|
284
|
+
print_nonblocking("Reconnected to log stream", writer, BytePrintStyle.GREEN)
|
|
288
285
|
|
|
289
286
|
last_iteration_log_timestamp = logs_response.lastLogTimestamp
|
|
290
287
|
last_log_id = logs_response.lastLogId
|
|
@@ -314,11 +311,11 @@ class LoggingService:
|
|
|
314
311
|
|
|
315
312
|
if consecutive_error_count > 7:
|
|
316
313
|
seconds_with_error = (datetime.utcnow() - errors_started_at).total_seconds()
|
|
317
|
-
if
|
|
314
|
+
if inference_simulator_public_id:
|
|
318
315
|
print_nonblocking(f"Log stream: disconnected from server (connectivity issues for {seconds_with_error} seconds). Try 'thestage inference-simulator logs <inference-simulator-UID>' to reconnect.", writer)
|
|
319
|
-
elif
|
|
320
|
-
print_nonblocking(f"Log stream: disconnected from server (connectivity issues for {seconds_with_error} seconds). Try 'thestage project task logs {
|
|
321
|
-
elif
|
|
316
|
+
elif task_public_id:
|
|
317
|
+
print_nonblocking(f"Log stream: disconnected from server (connectivity issues for {seconds_with_error} seconds). Try 'thestage project task logs {task_public_id}' to reconnect.", writer)
|
|
318
|
+
elif docker_container_public_id:
|
|
322
319
|
print_nonblocking(f"Log stream: disconnected from server (connectivity issues for {seconds_with_error} seconds). Try 'thestage container logs <docker-container-UID>' to reconnect.", writer)
|
|
323
320
|
else:
|
|
324
321
|
print_nonblocking(f"Log stream: disconnected from server (connectivity issues for {seconds_with_error} seconds)", writer)
|
|
@@ -4,20 +4,11 @@ from pydantic import BaseModel, ConfigDict, Field
|
|
|
4
4
|
class InferenceSimulatorDto(BaseModel):
|
|
5
5
|
model_config = ConfigDict(use_enum_values=True)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
client_id: Optional[int] = Field(None, alias="clientId")
|
|
9
|
-
title: Optional[str] = Field(None, alias="title")
|
|
7
|
+
public_id: Optional[str] = Field(None, alias="publicId")
|
|
10
8
|
slug: Optional[str] = Field(None, alias="slug")
|
|
11
|
-
docker_container_id: Optional[int] = Field(None, alias="dockerContainerId")
|
|
12
|
-
instance_rented_id: Optional[int] = Field(None, alias="instanceRentedId")
|
|
13
|
-
selfhosted_instance_id: Optional[int] = Field(None, alias="selfhostedInstanceId")
|
|
14
|
-
project_id: Optional[int] = Field(None, alias="projectId")
|
|
15
9
|
status: Optional[str] = Field(None, alias="status")
|
|
16
|
-
commit_hash: Optional[str] = Field(None, alias="commitHash")
|
|
17
10
|
http_endpoint: Optional[str] = Field(None, alias="httpEndpoint")
|
|
18
11
|
grpc_endpoint: Optional[str] = Field(None, alias="grpcEndpoint")
|
|
19
12
|
metrics_endpoint: Optional[str] = Field(None, alias="metricsEndpoint")
|
|
20
|
-
inference_metadata: Optional[Dict[str, Any]] = Field(None, alias="inferenceMetadata")
|
|
21
13
|
qlip_serve_metadata: Optional[Dict[str, Any]] = Field(None, alias="qlipServeMetadata")
|
|
22
14
|
created_at: Optional[str] = Field(None, alias="createdAt")
|
|
23
|
-
updated_at: Optional[str] = Field(None, alias="updatedAt")
|
|
@@ -4,18 +4,10 @@ from pydantic import BaseModel, ConfigDict, Field
|
|
|
4
4
|
class InferenceSimulatorModelDto(BaseModel):
|
|
5
5
|
model_config = ConfigDict(use_enum_values=True)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
public_id: Optional[str] = Field(None, alias='publicId')
|
|
8
8
|
slug: Optional[str] = Field(None, alias='slug')
|
|
9
|
-
client_id: Optional[int] = Field(None, alias='clientId')
|
|
10
|
-
instance_rented_id: Optional[int] = Field(None, alias='instanceRentedId')
|
|
11
|
-
selfhosted_instance_id: Optional[int] = Field(None, alias='selfhostedInstanceId')
|
|
12
|
-
project_id: Optional[int] = Field(None, alias='projectId')
|
|
13
9
|
status: Optional[str] = Field(None, alias='status')
|
|
14
10
|
environment_metadata: Optional[Dict[str, Any]] = Field(None, alias='environmentMetadata')
|
|
15
11
|
commit_hash: Optional[str] = Field(None, alias='commitHash')
|
|
16
|
-
cpu_architecture: Optional[str] = Field(None, alias='cpuArchitecture')
|
|
17
|
-
gpu_model: Optional[str] = Field(None, alias='gpuModel')
|
|
18
|
-
ecr_image_url: Optional[str] = Field(None, alias='ecrImageUrl')
|
|
19
|
-
s3_artifacts_url: Optional[str] = Field(None, alias='s3ArtifactsUrl')
|
|
20
12
|
created_at: Optional[str] = Field(None, alias='createdAt')
|
|
21
|
-
updated_at: Optional[str] = Field(None, alias='updatedAt')
|
|
13
|
+
updated_at: Optional[str] = Field(None, alias='updatedAt')
|
|
@@ -6,9 +6,9 @@ from pydantic import Field, ConfigDict, BaseModel
|
|
|
6
6
|
class ProjectConfig(BaseModel):
|
|
7
7
|
model_config = ConfigDict(use_enum_values=True)
|
|
8
8
|
|
|
9
|
-
id: int = Field(None, alias='id')
|
|
10
9
|
slug: str = Field(None, alias='slug')
|
|
10
|
+
public_id: str = Field(None, alias='public_id')
|
|
11
11
|
git_repository_url: str = Field(None, alias='git_repository_url')
|
|
12
12
|
deploy_key_path: str = Field(None, alias='deploy_key_path')
|
|
13
|
-
|
|
13
|
+
default_container_public_id: Optional[str] = Field(None, alias='default_container_public_id')
|
|
14
14
|
prompt_for_default_container: bool = Field(True, alias='prompt_for_default_container')
|
|
@@ -11,11 +11,11 @@ class ProjectInferenceSimulatorModelMapper(AbstractMapper):
|
|
|
11
11
|
return None
|
|
12
12
|
|
|
13
13
|
return ProjectInferenceSimulatorModelEntity(
|
|
14
|
-
|
|
14
|
+
public_id=item.public_id,
|
|
15
15
|
slug=item.slug,
|
|
16
16
|
status=item.status or '',
|
|
17
17
|
commit_hash=item.commit_hash or '',
|
|
18
18
|
environment_metadata=item.environment_metadata or {},
|
|
19
19
|
started_at=item.created_at or '',
|
|
20
|
-
finished_at=item.updated_at or ''
|
|
20
|
+
finished_at=item.updated_at or '' # TODO updated_at cannot be finished_at
|
|
21
21
|
)
|
|
@@ -12,11 +12,10 @@ class ProjectTaskMapper(AbstractMapper):
|
|
|
12
12
|
return None
|
|
13
13
|
|
|
14
14
|
return ProjectTaskEntity(
|
|
15
|
-
|
|
15
|
+
public_id=item.public_id or '',
|
|
16
16
|
title=item.title or '',
|
|
17
17
|
status=item.frontend_status.status_translation or '',
|
|
18
|
-
|
|
19
|
-
docker_container_slug=(str(item.docker_container.slug) or '') if item.docker_container else '',
|
|
18
|
+
docker_container_public_id=item.docker_container_public_id,
|
|
20
19
|
started_at=item.started_at or '',
|
|
21
20
|
finished_at=item.finished_at or '',
|
|
22
21
|
)
|