brilliance-admin 0.44.5__py3-none-any.whl → 0.44.6__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.
- brilliance_admin/exceptions.py +1 -0
- brilliance_admin/integrations/sqlalchemy/table/list.py +27 -10
- brilliance_admin/integrations/sqlalchemy/table/retrieve.py +21 -12
- brilliance_admin/locales/en.yml +4 -1
- brilliance_admin/locales/ru.yml +4 -1
- brilliance_admin/schema/table/fields_schema.py +7 -1
- {brilliance_admin-0.44.5.dist-info → brilliance_admin-0.44.6.dist-info}/METADATA +1 -1
- {brilliance_admin-0.44.5.dist-info → brilliance_admin-0.44.6.dist-info}/RECORD +11 -11
- {brilliance_admin-0.44.5.dist-info → brilliance_admin-0.44.6.dist-info}/WHEEL +0 -0
- {brilliance_admin-0.44.5.dist-info → brilliance_admin-0.44.6.dist-info}/licenses/LICENSE +0 -0
- {brilliance_admin-0.44.5.dist-info → brilliance_admin-0.44.6.dist-info}/top_level.txt +0 -0
brilliance_admin/exceptions.py
CHANGED
|
@@ -10,6 +10,7 @@ from brilliance_admin.utils import DataclassBase, SupportsStr
|
|
|
10
10
|
class FieldError(DataclassBase, Exception):
|
|
11
11
|
message: SupportsStr = None
|
|
12
12
|
code: str | None = None
|
|
13
|
+
field_slug: str | None = None
|
|
13
14
|
|
|
14
15
|
def __post_init__(self):
|
|
15
16
|
if not self.message and not self.code:
|
|
@@ -30,12 +30,12 @@ class SQLAlchemyAdminListMixin:
|
|
|
30
30
|
|
|
31
31
|
if list_data.ordering and ordering not in self.ordering_fields:
|
|
32
32
|
msg = f'Ordering "{ordering}" is not allowed; available options: {self.ordering_fields} default_ordering: {self.default_ordering}'
|
|
33
|
-
raise FieldError(message=msg)
|
|
33
|
+
raise FieldError(message=msg, field_slug='ordering')
|
|
34
34
|
|
|
35
35
|
column = getattr(self.model, ordering, None)
|
|
36
36
|
if not isinstance(column, InstrumentedAttribute):
|
|
37
37
|
msg = f'{type(self).__name__} ordering field "{ordering}" not found in model {self.model}'
|
|
38
|
-
raise FieldError(message=msg)
|
|
38
|
+
raise FieldError(message=msg, field_slug='ordering')
|
|
39
39
|
|
|
40
40
|
return stmt.order_by(direction(column))
|
|
41
41
|
|
|
@@ -122,18 +122,10 @@ class SQLAlchemyAdminListMixin:
|
|
|
122
122
|
)
|
|
123
123
|
raise AdminAPIException(APIError(message=_('errors.filters_exception'), code='filters_exception'), status_code=500) from e
|
|
124
124
|
|
|
125
|
-
data = []
|
|
126
|
-
|
|
127
125
|
try:
|
|
128
126
|
async with self.db_async_session() as session:
|
|
129
127
|
total_count = await session.scalar(count_stmt)
|
|
130
128
|
records = (await session.execute(stmt)).scalars().all()
|
|
131
|
-
for record in records:
|
|
132
|
-
line = await self.table_schema.serialize(
|
|
133
|
-
record,
|
|
134
|
-
extra={"record": record, "user": user},
|
|
135
|
-
)
|
|
136
|
-
data.append(line)
|
|
137
129
|
|
|
138
130
|
except ConnectionRefusedError as e:
|
|
139
131
|
logger.exception(
|
|
@@ -176,4 +168,29 @@ class SQLAlchemyAdminListMixin:
|
|
|
176
168
|
APIError(message=msg, code='db_error_list'), status_code=500,
|
|
177
169
|
) from e
|
|
178
170
|
|
|
171
|
+
try:
|
|
172
|
+
data = []
|
|
173
|
+
for record in records:
|
|
174
|
+
line = await self.table_schema.serialize(
|
|
175
|
+
record,
|
|
176
|
+
extra={"record": record, "user": user},
|
|
177
|
+
)
|
|
178
|
+
data.append(line)
|
|
179
|
+
|
|
180
|
+
except FieldError as e:
|
|
181
|
+
logger.exception(
|
|
182
|
+
'SQLAlchemy %s list %s serialize field error: %s',
|
|
183
|
+
type(self).__name__, self.model.__name__, e,
|
|
184
|
+
)
|
|
185
|
+
msg = _('serialize_error.field_error') % {'error': e.message, 'field_slug': e.field_slug}
|
|
186
|
+
raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
|
|
187
|
+
|
|
188
|
+
except Exception as e:
|
|
189
|
+
logger.exception(
|
|
190
|
+
'SQLAlchemy %s list %s serialize error: %s',
|
|
191
|
+
type(self).__name__, self.model.__name__, e,
|
|
192
|
+
)
|
|
193
|
+
msg = _('serialize_error.unexpected_error') % {'error': str(e)}
|
|
194
|
+
raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
|
|
195
|
+
|
|
179
196
|
return schema.TableListResult(data=data, total_count=int(total_count or 0))
|
|
@@ -36,18 +36,6 @@ class SQLAlchemyAdminRetrieveMixin:
|
|
|
36
36
|
try:
|
|
37
37
|
async with self.db_async_session() as session:
|
|
38
38
|
record = (await session.execute(stmt)).scalars().first()
|
|
39
|
-
data = await self.table_schema.serialize(
|
|
40
|
-
record,
|
|
41
|
-
extra={"record": record, "user": user},
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
except FieldError as e:
|
|
45
|
-
logger.exception(
|
|
46
|
-
'SQLAlchemy %s retrieve %s #%s field error: %s',
|
|
47
|
-
type(self).__name__, self.model.__name__, pk, e,
|
|
48
|
-
)
|
|
49
|
-
msg = _('errors.serialize_field_error') % {'error': e.message}
|
|
50
|
-
raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
|
|
51
39
|
|
|
52
40
|
except Exception as e:
|
|
53
41
|
logger.exception(
|
|
@@ -66,6 +54,27 @@ class SQLAlchemyAdminRetrieveMixin:
|
|
|
66
54
|
status_code=400,
|
|
67
55
|
)
|
|
68
56
|
|
|
57
|
+
try:
|
|
58
|
+
data = await self.table_schema.serialize(
|
|
59
|
+
record,
|
|
60
|
+
extra={"record": record, "user": user},
|
|
61
|
+
)
|
|
62
|
+
except FieldError as e:
|
|
63
|
+
logger.exception(
|
|
64
|
+
'SQLAlchemy %s retrieve %s #%s serialize field error: %s',
|
|
65
|
+
type(self).__name__, self.model.__name__, pk, e,
|
|
66
|
+
)
|
|
67
|
+
msg = _('serialize_error.field_error') % {'error': e.message, 'field_slug': e.field_slug}
|
|
68
|
+
raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
|
|
69
|
+
|
|
70
|
+
except Exception as e:
|
|
71
|
+
logger.exception(
|
|
72
|
+
'SQLAlchemy %s list %s #%s serialize error: %s',
|
|
73
|
+
type(self).__name__, self.model.__name__, pk, e,
|
|
74
|
+
)
|
|
75
|
+
msg = _('serialize_error.unexpected_error') % {'error': str(e)}
|
|
76
|
+
raise AdminAPIException(APIError(message=msg, code='filters_exception'), status_code=500) from e
|
|
77
|
+
|
|
69
78
|
logger.debug(
|
|
70
79
|
'%s model %s #%s retrieved by %s',
|
|
71
80
|
type(self).__name__, self.table_schema.model.__name__, pk, user.username,
|
brilliance_admin/locales/en.yml
CHANGED
|
@@ -15,9 +15,12 @@ errors:
|
|
|
15
15
|
filters_exception: 'An unknown technical error occurred while filtering data.'
|
|
16
16
|
method_not_allowed: 'Error, method not allowed. This action is not permitted.'
|
|
17
17
|
filter_error: 'An error occurred during filtering: {error}'
|
|
18
|
-
serialize_field_error: 'Serialize error: %(error)s'
|
|
19
18
|
bad_type_error: 'Invalid data type: %(type)s but %(expected)s expected'
|
|
20
19
|
|
|
20
|
+
serialize_error:
|
|
21
|
+
field_error: 'Field %(field_slug)s serialize error: %(error)s'
|
|
22
|
+
unexpected_error: 'Unexpected serialize error: %(error)s'
|
|
23
|
+
|
|
21
24
|
search_help: 'Available search fields: %(fields)s'
|
|
22
25
|
sqlalchemy_search_help: |
|
|
23
26
|
<b>Available search fields:</b>
|
brilliance_admin/locales/ru.yml
CHANGED
|
@@ -15,9 +15,12 @@ errors:
|
|
|
15
15
|
filters_exception: 'Произошла неизвестная техническая ошибка при фильтрации данных.'
|
|
16
16
|
method_not_allowed: 'Ошибка, данный метод недоступен.'
|
|
17
17
|
filter_error: 'Проишла ошибка при фильтрации: %(error)s'
|
|
18
|
-
serialize_field_error: 'Ошибка чтения данных: %(error)s'
|
|
19
18
|
bad_type_error: 'Некорректный тип данных: %(type)s; ожидается %(expected)s'
|
|
20
19
|
|
|
20
|
+
serialize_error:
|
|
21
|
+
field_error: 'ошибка чтения поля %(field_slug)s: %(error)s'
|
|
22
|
+
unexpected_error: 'Ошибка обработки данных: %(error)s'
|
|
23
|
+
|
|
21
24
|
search_help: 'Доступные поля для поиска: %(fields)s'
|
|
22
25
|
sqlalchemy_search_help: |
|
|
23
26
|
<b>Доступные поля для поиска:</b>
|
|
@@ -159,7 +159,13 @@ class FieldsSchema:
|
|
|
159
159
|
result = {}
|
|
160
160
|
for field_slug, field in self.get_fields().items():
|
|
161
161
|
value = data.get(field_slug)
|
|
162
|
-
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
result[field_slug] = await field.serialize(value, extra)
|
|
165
|
+
except FieldError as e:
|
|
166
|
+
e.field_slug = field_slug
|
|
167
|
+
raise e
|
|
168
|
+
|
|
163
169
|
return result
|
|
164
170
|
|
|
165
171
|
async def deserialize(self, data: dict, action: DeserializeAction, extra) -> dict:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brilliance-admin
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.6
|
|
4
4
|
Summary: Simple and lightweight data managment framework powered by FastAPI and Vue3 Vuetify all-in-one. Some call it heavenly in its brilliance.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
brilliance_admin/__init__.py,sha256=qxGzLVhFNm2FKL2lVt7bEFb6pTPqyXEQvUsDfyfv6SM,183
|
|
2
2
|
brilliance_admin/auth.py,sha256=d57XRfLJIbOosLP1-0SCFkePPT8M5WhLcwxu4yW92RA,673
|
|
3
3
|
brilliance_admin/docs.py,sha256=fKeJKuiCCi1jHRmNcmkuDD6_2di7bwc6-w8V1VCTu0s,1231
|
|
4
|
-
brilliance_admin/exceptions.py,sha256=
|
|
4
|
+
brilliance_admin/exceptions.py,sha256=CJGvpo7EiaX3RVAEUDpwgH_Tuw8kY7tMy57pVcnBxak,947
|
|
5
5
|
brilliance_admin/translations.py,sha256=I_iSfj05Qv5fbZqDvnnHZGUFsi1wk-J0EXSftKBLw5Q,3850
|
|
6
6
|
brilliance_admin/utils.py,sha256=M_0WANlb-1NW4aOA33MxOgoRx0GIVJ6w6PCGKAwmflk,5971
|
|
7
7
|
brilliance_admin/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -25,11 +25,11 @@ brilliance_admin/integrations/sqlalchemy/table/__init__.py,sha256=g_in2pLTi8UQnT
|
|
|
25
25
|
brilliance_admin/integrations/sqlalchemy/table/base.py,sha256=-osqhTvqE7YcBxsAjqIUMWyYk1df04GIDmdvtieTXcg,4885
|
|
26
26
|
brilliance_admin/integrations/sqlalchemy/table/create.py,sha256=8ER27mQe1GGUHpAcWxv0o4HBZ2HyKo2NUAK3m0Jum9o,2771
|
|
27
27
|
brilliance_admin/integrations/sqlalchemy/table/delete.py,sha256=toH9at-MAWO46K_4YmvkOqXX2-cFANVVhAURiZ-dwWQ,738
|
|
28
|
-
brilliance_admin/integrations/sqlalchemy/table/list.py,sha256=
|
|
29
|
-
brilliance_admin/integrations/sqlalchemy/table/retrieve.py,sha256
|
|
28
|
+
brilliance_admin/integrations/sqlalchemy/table/list.py,sha256=J2zMl5hMYrRoP6zMtVYeHRONefsbwAXKrwjR6nA-4zM,7615
|
|
29
|
+
brilliance_admin/integrations/sqlalchemy/table/retrieve.py,sha256=-UG9eniBcUg8GfEW54B-i4Oi0ELfV8BlV7pQ3W1213Q,3226
|
|
30
30
|
brilliance_admin/integrations/sqlalchemy/table/update.py,sha256=0BQpkke1ge6snUfdGDBZwpdva446BegXS4uVPzPCWcw,3635
|
|
31
|
-
brilliance_admin/locales/en.yml,sha256=
|
|
32
|
-
brilliance_admin/locales/ru.yml,sha256=
|
|
31
|
+
brilliance_admin/locales/en.yml,sha256=GO76VbfqnnsHfn7rPUF-D9s3k3pnYr75UxjZMKDiXo4,1438
|
|
32
|
+
brilliance_admin/locales/ru.yml,sha256=wKlQb8f4Cm_cdeY-MlCRlChit6REx_PNZ6VT6Bm_dQY,2037
|
|
33
33
|
brilliance_admin/schema/__init__.py,sha256=tZIRTSKFsNOmDqjoAgtYthYrT8ljPvLnYRzfupBLT00,290
|
|
34
34
|
brilliance_admin/schema/admin_schema.py,sha256=9w88GuogRjdphFuDdx7On553qHTwGoJVCyKpooFSKQ8,6723
|
|
35
35
|
brilliance_admin/schema/category.py,sha256=D2aIpDyL-2CibkpenNu8uyh4AzOdQ2ArTDltVYS7xZQ,6592
|
|
@@ -38,7 +38,7 @@ brilliance_admin/schema/graphs/category_graphs.py,sha256=iTjwjQoZocEfJWJEAdYcJTG
|
|
|
38
38
|
brilliance_admin/schema/table/__init__.py,sha256=vuRw8HBuak2LaTZi2dNn5YOrJPalQps-O3Ht-d0AZV4,378
|
|
39
39
|
brilliance_admin/schema/table/admin_action.py,sha256=0ymRL9DKkBK-AF6wKy7K9R4hkmblh55eHuZA_rjO1Lk,2018
|
|
40
40
|
brilliance_admin/schema/table/category_table.py,sha256=YNDEabnKkIjqhZ0niVOFqXDFIk0I2H6_FbGgbuO5NZ8,6509
|
|
41
|
-
brilliance_admin/schema/table/fields_schema.py,sha256=
|
|
41
|
+
brilliance_admin/schema/table/fields_schema.py,sha256=E6U0oLREyCU-8HnwNB8Sf40al2bIzgs0-g5fOpqbQkw,8475
|
|
42
42
|
brilliance_admin/schema/table/table_models.py,sha256=xidraifRYbXGkiVLn6dJ96dkOhW8-22ynE-fbiOjfAU,1018
|
|
43
43
|
brilliance_admin/schema/table/fields/__init__.py,sha256=RW-sIFTAaSQo4mMR6iWtnefogWPjmg6KAsDwe9mKW1k,291
|
|
44
44
|
brilliance_admin/schema/table/fields/base.py,sha256=HTOMWjuiTSV7lP1F5huUoit06j8Xd8v82cZ3Qz8Y7TI,9182
|
|
@@ -66,8 +66,8 @@ brilliance_admin/static/tinymce/plugins/codesample/css/prism.css,sha256=exAdMtHb
|
|
|
66
66
|
brilliance_admin/static/tinymce/plugins/customLink/plugin.js,sha256=illBNpnHDkBsLG6wo_jDPF6z7CGnO1MQWUoDwZKy6vQ,5589
|
|
67
67
|
brilliance_admin/static/tinymce/plugins/customLink/css/link.css,sha256=gh5nvY8Z92hJfCEBPnIm4jIPCcKKbJnab-30oIfX7Hc,56
|
|
68
68
|
brilliance_admin/templates/index.html,sha256=T1d7BYLJOmL6eTICyxH82aCStGXq-bom_dJG5aVxfKA,1294
|
|
69
|
-
brilliance_admin-0.44.
|
|
70
|
-
brilliance_admin-0.44.
|
|
71
|
-
brilliance_admin-0.44.
|
|
72
|
-
brilliance_admin-0.44.
|
|
73
|
-
brilliance_admin-0.44.
|
|
69
|
+
brilliance_admin-0.44.6.dist-info/licenses/LICENSE,sha256=rgWE5Cxk53W0PhTOVmcQedABEWN1QMG-PRz3fz531sE,1074
|
|
70
|
+
brilliance_admin-0.44.6.dist-info/METADATA,sha256=pp645oX-1YAteZF-c67SV2hLYayrxfKNEVd_nMDJDqY,6951
|
|
71
|
+
brilliance_admin-0.44.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
72
|
+
brilliance_admin-0.44.6.dist-info/top_level.txt,sha256=almFFSWrVYieI3i54hYL0fMUaeuIYiazS2Kx4wtK-ns,17
|
|
73
|
+
brilliance_admin-0.44.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|