restiny 0.2.1__py3-none-any.whl → 0.6.1__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.
- restiny/__about__.py +1 -1
- restiny/__main__.py +28 -14
- restiny/assets/style.tcss +56 -2
- restiny/consts.py +236 -0
- restiny/data/db.py +60 -0
- restiny/data/models.py +111 -0
- restiny/data/repos.py +455 -0
- restiny/data/sql/__init__.py +3 -0
- restiny/entities.py +438 -0
- restiny/enums.py +14 -5
- restiny/httpx_auths.py +52 -0
- restiny/ui/__init__.py +17 -0
- restiny/ui/app.py +586 -0
- restiny/ui/collections_area.py +594 -0
- restiny/ui/environments_screen.py +270 -0
- restiny/ui/request_area.py +602 -0
- restiny/{core → ui}/response_area.py +4 -1
- restiny/ui/settings_screen.py +73 -0
- restiny/ui/top_bar_area.py +60 -0
- restiny/{core → ui}/url_area.py +54 -38
- restiny/utils.py +52 -15
- restiny/widgets/__init__.py +15 -1
- restiny/widgets/collections_tree.py +74 -0
- restiny/widgets/confirm_prompt.py +76 -0
- restiny/widgets/custom_input.py +20 -0
- restiny/widgets/dynamic_fields.py +65 -70
- restiny/widgets/password_input.py +161 -0
- restiny/widgets/path_chooser.py +12 -12
- {restiny-0.2.1.dist-info → restiny-0.6.1.dist-info}/METADATA +7 -5
- restiny-0.6.1.dist-info/RECORD +38 -0
- restiny/core/__init__.py +0 -15
- restiny/core/app.py +0 -348
- restiny/core/request_area.py +0 -337
- restiny-0.2.1.dist-info/RECORD +0 -24
- {restiny-0.2.1.dist-info → restiny-0.6.1.dist-info}/WHEEL +0 -0
- {restiny-0.2.1.dist-info → restiny-0.6.1.dist-info}/entry_points.txt +0 -0
- {restiny-0.2.1.dist-info → restiny-0.6.1.dist-info}/licenses/LICENSE +0 -0
- {restiny-0.2.1.dist-info → restiny-0.6.1.dist-info}/top_level.txt +0 -0
restiny/data/repos.py
ADDED
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
import traceback
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from datetime import UTC
|
|
7
|
+
from enum import StrEnum
|
|
8
|
+
from functools import wraps
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from sqlalchemy import case, select
|
|
12
|
+
from sqlalchemy.exc import IntegrityError, InterfaceError, OperationalError
|
|
13
|
+
|
|
14
|
+
from restiny.data.db import DBManager
|
|
15
|
+
from restiny.data.models import (
|
|
16
|
+
SQLEnvironment,
|
|
17
|
+
SQLFolder,
|
|
18
|
+
SQLRequest,
|
|
19
|
+
SQLSettings,
|
|
20
|
+
)
|
|
21
|
+
from restiny.entities import Environment, Folder, Request, Settings
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def safe_repo(func):
|
|
25
|
+
@wraps(func)
|
|
26
|
+
def wrapper(*args, **kwargs):
|
|
27
|
+
try:
|
|
28
|
+
return func(*args, **kwargs)
|
|
29
|
+
|
|
30
|
+
except (
|
|
31
|
+
InterfaceError,
|
|
32
|
+
OperationalError,
|
|
33
|
+
):
|
|
34
|
+
traceback.print_exc(file=sys.stderr)
|
|
35
|
+
return RepoResp(status=RepoStatus.DB_ERROR)
|
|
36
|
+
|
|
37
|
+
except IntegrityError as error:
|
|
38
|
+
error_msg = str(error)
|
|
39
|
+
if 'UNIQUE' in str(error_msg):
|
|
40
|
+
return RepoResp(status=RepoStatus.DUPLICATED)
|
|
41
|
+
|
|
42
|
+
traceback.print_exc(file=sys.stderr)
|
|
43
|
+
return RepoResp(status=RepoStatus.DB_ERROR)
|
|
44
|
+
|
|
45
|
+
return wrapper
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class RepoStatus(StrEnum):
|
|
49
|
+
OK = 'ok'
|
|
50
|
+
NOT_FOUND = 'not_found'
|
|
51
|
+
DUPLICATED = 'duplicated'
|
|
52
|
+
DB_ERROR = 'db_error'
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class RepoResp:
|
|
57
|
+
status: RepoStatus = RepoStatus.OK
|
|
58
|
+
data: Any = None
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def ok(self) -> bool:
|
|
62
|
+
return self.status == RepoStatus.OK
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class SQLRepoBase(ABC):
|
|
66
|
+
def __init__(self, db_manager: DBManager):
|
|
67
|
+
self.db_manager = db_manager
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
@abstractmethod
|
|
71
|
+
def _updatable_sql_fields(self) -> list[str]:
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class FoldersSQLRepo(SQLRepoBase):
|
|
76
|
+
@property
|
|
77
|
+
def _updatable_sql_fields(self) -> list[str]:
|
|
78
|
+
return [SQLFolder.parent_id.key, SQLFolder.name.key]
|
|
79
|
+
|
|
80
|
+
@safe_repo
|
|
81
|
+
def list_by_parent_id(self, parent_id: int) -> RepoResp:
|
|
82
|
+
with self.db_manager.session_scope() as session:
|
|
83
|
+
sql_folders = session.scalars(
|
|
84
|
+
select(SQLFolder)
|
|
85
|
+
.where(SQLFolder.parent_id == parent_id)
|
|
86
|
+
.order_by(SQLFolder.name.asc())
|
|
87
|
+
).all()
|
|
88
|
+
folders = [
|
|
89
|
+
self._sql_to_folder(sql_folder) for sql_folder in sql_folders
|
|
90
|
+
]
|
|
91
|
+
return RepoResp(data=folders)
|
|
92
|
+
|
|
93
|
+
@safe_repo
|
|
94
|
+
def list_roots(self) -> RepoResp:
|
|
95
|
+
with self.db_manager.session_scope() as session:
|
|
96
|
+
sql_folders = session.scalars(
|
|
97
|
+
select(SQLFolder)
|
|
98
|
+
.where(SQLFolder.parent_id.is_(None))
|
|
99
|
+
.order_by(SQLFolder.name.asc())
|
|
100
|
+
).all()
|
|
101
|
+
folders = [
|
|
102
|
+
self._sql_to_folder(sql_folder) for sql_folder in sql_folders
|
|
103
|
+
]
|
|
104
|
+
return RepoResp(data=folders)
|
|
105
|
+
|
|
106
|
+
@safe_repo
|
|
107
|
+
def get_by_id(self, id: int) -> RepoResp:
|
|
108
|
+
with self.db_manager.session_scope() as session:
|
|
109
|
+
sql_folder = session.get(SQLFolder, id)
|
|
110
|
+
if not sql_folder:
|
|
111
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
112
|
+
|
|
113
|
+
folder = self._sql_to_folder(sql_folder)
|
|
114
|
+
return RepoResp(data=folder)
|
|
115
|
+
|
|
116
|
+
@safe_repo
|
|
117
|
+
def create(self, folder: Folder) -> RepoResp:
|
|
118
|
+
with self.db_manager.session_scope() as session:
|
|
119
|
+
sql_folder = self._folder_to_sql(folder)
|
|
120
|
+
session.add(sql_folder)
|
|
121
|
+
session.flush()
|
|
122
|
+
new_folder = self._sql_to_folder(sql_folder)
|
|
123
|
+
return RepoResp(data=new_folder)
|
|
124
|
+
|
|
125
|
+
@safe_repo
|
|
126
|
+
def update(self, folder: Folder) -> RepoResp:
|
|
127
|
+
with self.db_manager.session_scope() as session:
|
|
128
|
+
sql_folder = session.get(SQLFolder, folder.id)
|
|
129
|
+
if not sql_folder:
|
|
130
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
131
|
+
|
|
132
|
+
new_data = self._folder_to_sql(folder)
|
|
133
|
+
for field in self._updatable_sql_fields:
|
|
134
|
+
setattr(sql_folder, field, getattr(new_data, field))
|
|
135
|
+
|
|
136
|
+
session.flush()
|
|
137
|
+
|
|
138
|
+
new_folder = self._sql_to_folder(sql_folder)
|
|
139
|
+
return RepoResp(data=new_folder)
|
|
140
|
+
|
|
141
|
+
@safe_repo
|
|
142
|
+
def delete_by_id(self, id: int) -> RepoResp:
|
|
143
|
+
with self.db_manager.session_scope() as session:
|
|
144
|
+
sql_folder = session.get(SQLFolder, id)
|
|
145
|
+
if not sql_folder:
|
|
146
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
147
|
+
|
|
148
|
+
session.delete(sql_folder)
|
|
149
|
+
return RepoResp()
|
|
150
|
+
|
|
151
|
+
def _sql_to_folder(self, sql_folder: SQLFolder) -> Folder:
|
|
152
|
+
return Folder(
|
|
153
|
+
id=sql_folder.id,
|
|
154
|
+
parent_id=sql_folder.parent_id,
|
|
155
|
+
name=sql_folder.name,
|
|
156
|
+
created_at=sql_folder.created_at.replace(tzinfo=UTC),
|
|
157
|
+
updated_at=sql_folder.updated_at.replace(tzinfo=UTC),
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
def _folder_to_sql(self, folder: Folder) -> SQLFolder:
|
|
161
|
+
return SQLFolder(
|
|
162
|
+
id=folder.id,
|
|
163
|
+
parent_id=folder.parent_id,
|
|
164
|
+
name=folder.name,
|
|
165
|
+
created_at=folder.created_at,
|
|
166
|
+
updated_at=folder.updated_at,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class RequestsSQLRepo(SQLRepoBase):
|
|
171
|
+
@safe_repo
|
|
172
|
+
def list_by_folder_id(self, folder_id: int) -> RepoResp:
|
|
173
|
+
with self.db_manager.session_scope() as session:
|
|
174
|
+
sql_requests = session.scalars(
|
|
175
|
+
select(SQLRequest)
|
|
176
|
+
.where(SQLRequest.folder_id == folder_id)
|
|
177
|
+
.order_by(SQLRequest.name.asc())
|
|
178
|
+
).all()
|
|
179
|
+
requests = [
|
|
180
|
+
self._sql_to_request(sql_folder) for sql_folder in sql_requests
|
|
181
|
+
]
|
|
182
|
+
return RepoResp(data=requests)
|
|
183
|
+
|
|
184
|
+
@safe_repo
|
|
185
|
+
def get_by_id(self, id: int) -> RepoResp:
|
|
186
|
+
with self.db_manager.session_scope() as session:
|
|
187
|
+
sql_request = session.get(SQLRequest, id)
|
|
188
|
+
|
|
189
|
+
if not sql_request:
|
|
190
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
191
|
+
|
|
192
|
+
request = self._sql_to_request(sql_request)
|
|
193
|
+
return RepoResp(data=request)
|
|
194
|
+
|
|
195
|
+
@safe_repo
|
|
196
|
+
def create(self, request: Request) -> RepoResp:
|
|
197
|
+
with self.db_manager.session_scope() as session:
|
|
198
|
+
sql_request = self._request_to_sql(request)
|
|
199
|
+
session.add(sql_request)
|
|
200
|
+
session.flush()
|
|
201
|
+
new_request = self._sql_to_request(sql_request)
|
|
202
|
+
return RepoResp(data=new_request)
|
|
203
|
+
|
|
204
|
+
@safe_repo
|
|
205
|
+
def update(self, request: Request) -> RepoResp:
|
|
206
|
+
with self.db_manager.session_scope() as session:
|
|
207
|
+
sql_request = session.get(SQLRequest, request.id)
|
|
208
|
+
if not sql_request:
|
|
209
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
210
|
+
|
|
211
|
+
new_data = self._request_to_sql(request)
|
|
212
|
+
for field in self._updatable_sql_fields:
|
|
213
|
+
setattr(sql_request, field, getattr(new_data, field))
|
|
214
|
+
|
|
215
|
+
session.flush()
|
|
216
|
+
|
|
217
|
+
new_request = self._sql_to_request(sql_request)
|
|
218
|
+
return RepoResp(data=new_request)
|
|
219
|
+
|
|
220
|
+
@safe_repo
|
|
221
|
+
def delete_by_id(self, id: int) -> RepoResp:
|
|
222
|
+
with self.db_manager.session_scope() as session:
|
|
223
|
+
sql_request = session.get(SQLRequest, id)
|
|
224
|
+
if not sql_request:
|
|
225
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
226
|
+
|
|
227
|
+
session.delete(sql_request)
|
|
228
|
+
return RepoResp()
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def _updatable_sql_fields(self) -> list[str]:
|
|
232
|
+
return [
|
|
233
|
+
SQLRequest.folder_id.key,
|
|
234
|
+
SQLRequest.name.key,
|
|
235
|
+
SQLRequest.method.key,
|
|
236
|
+
SQLRequest.url.key,
|
|
237
|
+
SQLRequest.headers.key,
|
|
238
|
+
SQLRequest.params.key,
|
|
239
|
+
SQLRequest.body_enabled.key,
|
|
240
|
+
SQLRequest.body_mode.key,
|
|
241
|
+
SQLRequest.body.key,
|
|
242
|
+
SQLRequest.auth_enabled.key,
|
|
243
|
+
SQLRequest.auth_mode.key,
|
|
244
|
+
SQLRequest.auth.key,
|
|
245
|
+
SQLRequest.option_timeout.key,
|
|
246
|
+
SQLRequest.option_follow_redirects.key,
|
|
247
|
+
SQLRequest.option_verify_ssl.key,
|
|
248
|
+
]
|
|
249
|
+
|
|
250
|
+
def _sql_to_request(self, sql_request: SQLRequest) -> Request:
|
|
251
|
+
return Request(
|
|
252
|
+
id=sql_request.id,
|
|
253
|
+
folder_id=sql_request.folder_id,
|
|
254
|
+
name=sql_request.name,
|
|
255
|
+
method=sql_request.method,
|
|
256
|
+
url=sql_request.url,
|
|
257
|
+
headers=json.loads(sql_request.headers),
|
|
258
|
+
params=json.loads(sql_request.params),
|
|
259
|
+
body_enabled=sql_request.body_enabled,
|
|
260
|
+
body_mode=sql_request.body_mode,
|
|
261
|
+
body=json.loads(sql_request.body) if sql_request.body else None,
|
|
262
|
+
auth_enabled=sql_request.auth_enabled,
|
|
263
|
+
auth_mode=sql_request.auth_mode,
|
|
264
|
+
auth=json.loads(sql_request.auth) if sql_request.auth else None,
|
|
265
|
+
options=Request.Options(
|
|
266
|
+
timeout=sql_request.option_timeout,
|
|
267
|
+
follow_redirects=sql_request.option_follow_redirects,
|
|
268
|
+
verify_ssl=sql_request.option_verify_ssl,
|
|
269
|
+
),
|
|
270
|
+
created_at=sql_request.created_at.replace(tzinfo=UTC),
|
|
271
|
+
updated_at=sql_request.updated_at.replace(tzinfo=UTC),
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def _request_to_sql(self, request: Request) -> SQLRequest:
|
|
275
|
+
return SQLRequest(
|
|
276
|
+
id=request.id,
|
|
277
|
+
folder_id=request.folder_id,
|
|
278
|
+
name=request.name,
|
|
279
|
+
method=request.method,
|
|
280
|
+
url=request.url,
|
|
281
|
+
headers=json.dumps(
|
|
282
|
+
[header.model_dump() for header in request.headers]
|
|
283
|
+
),
|
|
284
|
+
params=json.dumps(
|
|
285
|
+
[param.model_dump() for param in request.params]
|
|
286
|
+
),
|
|
287
|
+
body_enabled=request.body_enabled,
|
|
288
|
+
body_mode=request.body_mode,
|
|
289
|
+
body=json.dumps(request.body.model_dump(), default=str)
|
|
290
|
+
if request.body
|
|
291
|
+
else None,
|
|
292
|
+
auth_enabled=request.auth_enabled,
|
|
293
|
+
auth_mode=request.auth_mode,
|
|
294
|
+
auth=json.dumps(request.auth.model_dump(), default=str)
|
|
295
|
+
if request.auth
|
|
296
|
+
else None,
|
|
297
|
+
option_timeout=request.options.timeout,
|
|
298
|
+
option_follow_redirects=request.options.follow_redirects,
|
|
299
|
+
option_verify_ssl=request.options.verify_ssl,
|
|
300
|
+
created_at=request.created_at,
|
|
301
|
+
updated_at=request.updated_at,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
class SettingsSQLRepo(SQLRepoBase):
|
|
306
|
+
@safe_repo
|
|
307
|
+
def get(self) -> RepoResp:
|
|
308
|
+
with self.db_manager.session_scope() as session:
|
|
309
|
+
sql_settings = session.scalar(select(SQLSettings).limit(1))
|
|
310
|
+
|
|
311
|
+
if not sql_settings:
|
|
312
|
+
return RepoResp(data=Settings())
|
|
313
|
+
|
|
314
|
+
settings = self._sql_to_settings(sql_settings)
|
|
315
|
+
return RepoResp(data=settings)
|
|
316
|
+
|
|
317
|
+
@safe_repo
|
|
318
|
+
def set(self, settings: Settings) -> RepoResp:
|
|
319
|
+
with self.db_manager.session_scope() as session:
|
|
320
|
+
sql_settings = session.scalar(select(SQLSettings).limit(1))
|
|
321
|
+
|
|
322
|
+
if not sql_settings:
|
|
323
|
+
# create
|
|
324
|
+
sql_settings = self._settings_to_sql(settings=settings)
|
|
325
|
+
session.add(sql_settings)
|
|
326
|
+
session.flush()
|
|
327
|
+
new_settings = self._sql_to_settings(sql_settings=sql_settings)
|
|
328
|
+
return RepoResp(data=new_settings)
|
|
329
|
+
else:
|
|
330
|
+
# update
|
|
331
|
+
new_data = self._settings_to_sql(settings=settings)
|
|
332
|
+
for field in self._updatable_sql_fields:
|
|
333
|
+
setattr(sql_settings, field, getattr(new_data, field))
|
|
334
|
+
session.flush()
|
|
335
|
+
new_settings = self._sql_to_settings(sql_settings=sql_settings)
|
|
336
|
+
return RepoResp(data=new_settings)
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def _updatable_sql_fields(self) -> list[str]:
|
|
340
|
+
return [SQLSettings.theme.key]
|
|
341
|
+
|
|
342
|
+
def _sql_to_settings(self, sql_settings: SQLSettings) -> Settings:
|
|
343
|
+
return Settings(
|
|
344
|
+
id=sql_settings.id,
|
|
345
|
+
theme=sql_settings.theme,
|
|
346
|
+
created_at=sql_settings.created_at.replace(tzinfo=UTC),
|
|
347
|
+
updated_at=sql_settings.updated_at.replace(tzinfo=UTC),
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
def _settings_to_sql(self, settings: Settings) -> SQLSettings:
|
|
351
|
+
return SQLSettings(
|
|
352
|
+
id=settings.id,
|
|
353
|
+
theme=settings.theme,
|
|
354
|
+
created_at=settings.created_at,
|
|
355
|
+
updated_at=settings.updated_at,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
class EnvironmentsSQLRepo(SQLRepoBase):
|
|
360
|
+
@safe_repo
|
|
361
|
+
def get_by_id(self, id: int) -> RepoResp:
|
|
362
|
+
with self.db_manager.session_scope() as session:
|
|
363
|
+
sql_environment = session.get(SQLEnvironment, id)
|
|
364
|
+
|
|
365
|
+
if not sql_environment:
|
|
366
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
367
|
+
|
|
368
|
+
environment = self._sql_to_environment(sql_environment)
|
|
369
|
+
return RepoResp(data=environment)
|
|
370
|
+
|
|
371
|
+
@safe_repo
|
|
372
|
+
def get_by_name(self, name: str) -> RepoResp:
|
|
373
|
+
with self.db_manager.session_scope() as session:
|
|
374
|
+
sql_environment = session.scalar(
|
|
375
|
+
select(SQLEnvironment).where(SQLEnvironment.name == name)
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
if not sql_environment:
|
|
379
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
380
|
+
|
|
381
|
+
environment = self._sql_to_environment(sql_environment)
|
|
382
|
+
return RepoResp(data=environment)
|
|
383
|
+
|
|
384
|
+
@safe_repo
|
|
385
|
+
def list(self) -> RepoResp:
|
|
386
|
+
with self.db_manager.session_scope() as session:
|
|
387
|
+
sql_envs = session.scalars(
|
|
388
|
+
select(SQLEnvironment).order_by(
|
|
389
|
+
case((SQLEnvironment.name == 'global', 0), else_=1),
|
|
390
|
+
SQLEnvironment.name.asc(),
|
|
391
|
+
)
|
|
392
|
+
)
|
|
393
|
+
envs = [self._sql_to_environment(sql_env) for sql_env in sql_envs]
|
|
394
|
+
return RepoResp(data=envs)
|
|
395
|
+
|
|
396
|
+
@safe_repo
|
|
397
|
+
def create(self, environment: Environment) -> RepoResp:
|
|
398
|
+
with self.db_manager.session_scope() as session:
|
|
399
|
+
sql_env = self._environment_to_sql(environment)
|
|
400
|
+
session.add(sql_env)
|
|
401
|
+
session.flush()
|
|
402
|
+
new_env = self._sql_to_environment(sql_env)
|
|
403
|
+
return RepoResp(data=new_env)
|
|
404
|
+
|
|
405
|
+
@safe_repo
|
|
406
|
+
def update(self, environment: Environment) -> RepoResp:
|
|
407
|
+
with self.db_manager.session_scope() as session:
|
|
408
|
+
sql_environment = session.get(SQLEnvironment, environment.id)
|
|
409
|
+
if not sql_environment:
|
|
410
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
411
|
+
|
|
412
|
+
new_data = self._environment_to_sql(environment)
|
|
413
|
+
for field in self._updatable_sql_fields:
|
|
414
|
+
setattr(sql_environment, field, getattr(new_data, field))
|
|
415
|
+
|
|
416
|
+
session.flush()
|
|
417
|
+
|
|
418
|
+
new_environment = self._sql_to_environment(sql_environment)
|
|
419
|
+
return RepoResp(data=new_environment)
|
|
420
|
+
|
|
421
|
+
@safe_repo
|
|
422
|
+
def delete_by_id(self, id: int) -> RepoResp:
|
|
423
|
+
with self.db_manager.session_scope() as session:
|
|
424
|
+
sql_environment = session.get(SQLEnvironment, id)
|
|
425
|
+
if not sql_environment:
|
|
426
|
+
return RepoResp(status=RepoStatus.NOT_FOUND)
|
|
427
|
+
|
|
428
|
+
session.delete(sql_environment)
|
|
429
|
+
return RepoResp()
|
|
430
|
+
|
|
431
|
+
@property
|
|
432
|
+
def _updatable_sql_fields(self) -> list[str]:
|
|
433
|
+
return [SQLEnvironment.name.key, SQLEnvironment.variables.key]
|
|
434
|
+
|
|
435
|
+
def _sql_to_environment(
|
|
436
|
+
self, sql_environment: SQLEnvironment
|
|
437
|
+
) -> Environment:
|
|
438
|
+
return Environment(
|
|
439
|
+
id=sql_environment.id,
|
|
440
|
+
name=sql_environment.name,
|
|
441
|
+
variables=json.loads(sql_environment.variables),
|
|
442
|
+
created_at=sql_environment.created_at.replace(tzinfo=UTC),
|
|
443
|
+
updated_at=sql_environment.updated_at.replace(tzinfo=UTC),
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
def _environment_to_sql(self, environment: Environment) -> SQLEnvironment:
|
|
447
|
+
return SQLEnvironment(
|
|
448
|
+
id=environment.id,
|
|
449
|
+
name=environment.name,
|
|
450
|
+
variables=json.dumps(
|
|
451
|
+
[variable.model_dump() for variable in environment.variables]
|
|
452
|
+
),
|
|
453
|
+
created_at=environment.created_at,
|
|
454
|
+
updated_at=environment.updated_at,
|
|
455
|
+
)
|