brilliance-admin 0.44.1__tar.gz → 0.44.3__tar.gz

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.
Files changed (123) hide show
  1. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/PKG-INFO +2 -1
  2. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/auth.py +1 -2
  3. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/fields.py +22 -9
  4. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin.egg-info/PKG-INFO +2 -1
  5. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin.egg-info/SOURCES.txt +0 -37
  6. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin.egg-info/requires.txt +1 -0
  7. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/pyproject.toml +7 -2
  8. brilliance_admin-0.44.1/.configs/docker/Dockerfile +0 -22
  9. brilliance_admin-0.44.1/.configs/docker/docker-compose.yml +0 -40
  10. brilliance_admin-0.44.1/.configs/nginx/example.conf +0 -25
  11. brilliance_admin-0.44.1/.github/workflows/certbot.yml +0 -36
  12. brilliance_admin-0.44.1/.github/workflows/deploy.yml +0 -127
  13. brilliance_admin-0.44.1/.github/workflows/install-docker.yml +0 -26
  14. brilliance_admin-0.44.1/.gitignore +0 -12
  15. brilliance_admin-0.44.1/.isort.cfg +0 -7
  16. brilliance_admin-0.44.1/.python-version +0 -1
  17. brilliance_admin-0.44.1/example/README.md +0 -32
  18. brilliance_admin-0.44.1/example/__init__.py +0 -0
  19. brilliance_admin-0.44.1/example/locales/en.yml +0 -57
  20. brilliance_admin-0.44.1/example/locales/ru.yml +0 -57
  21. brilliance_admin-0.44.1/example/main.py +0 -155
  22. brilliance_admin-0.44.1/example/sections/__init__.py +0 -0
  23. brilliance_admin-0.44.1/example/sections/currency.py +0 -21
  24. brilliance_admin-0.44.1/example/sections/graphs.py +0 -136
  25. brilliance_admin-0.44.1/example/sections/merchant.py +0 -47
  26. brilliance_admin-0.44.1/example/sections/models.py +0 -278
  27. brilliance_admin-0.44.1/example/sections/payments.py +0 -183
  28. brilliance_admin-0.44.1/example/sections/terminal.py +0 -43
  29. brilliance_admin-0.44.1/example/sections/users.py +0 -25
  30. brilliance_admin-0.44.1/example/sqlite.py +0 -51
  31. brilliance_admin-0.44.1/example/static/favicon.ico +0 -0
  32. brilliance_admin-0.44.1/example/static/favicon.jpg +0 -0
  33. brilliance_admin-0.44.1/example/static/logo-outline.png +0 -0
  34. brilliance_admin-0.44.1/example/static/logo.png +0 -0
  35. brilliance_admin-0.44.1/example/utils.py +0 -26
  36. brilliance_admin-0.44.1/screenshots/PC-graphs.jpeg +0 -0
  37. brilliance_admin-0.44.1/screenshots/PC-table.jpeg +0 -0
  38. brilliance_admin-0.44.1/screenshots/iPad-edit.jpeg +0 -0
  39. brilliance_admin-0.44.1/screenshots/iPhone 15-edit.jpeg +0 -0
  40. brilliance_admin-0.44.1/screenshots/iPhone 15-login.jpeg +0 -0
  41. brilliance_admin-0.44.1/screenshots/websitemockupgenerator.png +0 -0
  42. brilliance_admin-0.44.1/tests/__init__.py +0 -0
  43. brilliance_admin-0.44.1/tests/conftest.py +0 -26
  44. brilliance_admin-0.44.1/uv.lock +0 -991
  45. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/LICENSE +0 -0
  46. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/README.md +0 -0
  47. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/__init__.py +0 -0
  48. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/__init__.py +0 -0
  49. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/routers.py +0 -0
  50. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/utils.py +0 -0
  51. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/__init__.py +0 -0
  52. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/auth.py +0 -0
  53. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/autocomplete.py +0 -0
  54. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/graphs.py +0 -0
  55. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/index.py +0 -0
  56. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/schema.py +0 -0
  57. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/settings.py +0 -0
  58. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/api/views/table.py +0 -0
  59. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/auth.py +0 -0
  60. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/docs.py +0 -0
  61. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/exceptions.py +0 -0
  62. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/__init__.py +0 -0
  63. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/__init__.py +0 -0
  64. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/autocomplete.py +0 -0
  65. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/fields_schema.py +0 -0
  66. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/__init__.py +0 -0
  67. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/base.py +0 -0
  68. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/create.py +0 -0
  69. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/delete.py +0 -0
  70. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/list.py +0 -0
  71. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/retrieve.py +0 -0
  72. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/integrations/sqlalchemy/table/update.py +0 -0
  73. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/locales/en.yml +0 -0
  74. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/locales/ru.yml +0 -0
  75. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/__init__.py +0 -0
  76. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/admin_schema.py +0 -0
  77. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/category.py +0 -0
  78. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/graphs/__init__.py +0 -0
  79. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/graphs/category_graphs.py +0 -0
  80. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/__init__.py +0 -0
  81. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/admin_action.py +0 -0
  82. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/category_table.py +0 -0
  83. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/fields/__init__.py +0 -0
  84. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/fields/base.py +0 -0
  85. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/fields/function_field.py +0 -0
  86. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/fields_schema.py +0 -0
  87. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/schema/table/table_models.py +0 -0
  88. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/index-P_wdMBbz.css +0 -0
  89. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/index-rBvEkjGg.js +0 -0
  90. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/materialdesignicons-webfont-CYDMK1kx.woff2 +0 -0
  91. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/materialdesignicons-webfont-CgCzGbLl.woff +0 -0
  92. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/materialdesignicons-webfont-D3kAzl71.ttf +0 -0
  93. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/materialdesignicons-webfont-DttUABo4.eot +0 -0
  94. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/dark-first/content.min.css +0 -0
  95. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/dark-first/skin.min.css +0 -0
  96. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/dark-slim/content.min.css +0 -0
  97. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/dark-slim/skin.min.css +0 -0
  98. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/img/example.png +0 -0
  99. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/img/tinymce.woff2 +0 -0
  100. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/lightgray/content.min.css +0 -0
  101. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/lightgray/fonts/tinymce.woff +0 -0
  102. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/lightgray/skin.min.css +0 -0
  103. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/plugins/accordion/css/accordion.css +0 -0
  104. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/plugins/accordion/plugin.js +0 -0
  105. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/plugins/codesample/css/prism.css +0 -0
  106. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/plugins/customLink/css/link.css +0 -0
  107. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/plugins/customLink/plugin.js +0 -0
  108. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/tinymce/tinymce.min.js +0 -0
  109. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/static/vanilla-picker-B6E6ObS_.js +0 -0
  110. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/templates/index.html +0 -0
  111. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/translations.py +0 -0
  112. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin/utils.py +0 -0
  113. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin.egg-info/dependency_links.txt +0 -0
  114. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/brilliance_admin.egg-info/top_level.txt +0 -0
  115. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/setup.cfg +0 -0
  116. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_action.py +0 -0
  117. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_payments_fields_schema.py +0 -0
  118. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_settings.py +0 -0
  119. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_sqlalcmeny_auth.py +0 -0
  120. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_sqlalcmeny_crud.py +0 -0
  121. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_sqlalcmeny_filters.py +0 -0
  122. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_sqlalcmeny_schema.py +0 -0
  123. {brilliance_admin-0.44.1 → brilliance_admin-0.44.3}/tests/test_translations.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brilliance-admin
3
- Version: 0.44.1
3
+ Version: 0.44.3
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
@@ -18,6 +18,7 @@ Requires-Dist: structlog>=25.5.0; extra == "example"
18
18
  Requires-Dist: rich>=14.2.0; extra == "example"
19
19
  Requires-Dist: asyncpg>=0.31.0; extra == "example"
20
20
  Requires-Dist: pydantic-settings>=2.12.0; extra == "example"
21
+ Requires-Dist: twine; extra == "example"
21
22
  Provides-Extra: tests
22
23
  Requires-Dist: pytest>=8.4.2; extra == "tests"
23
24
  Requires-Dist: pytest-asyncio>=1.2.0; extra == "tests"
@@ -122,6 +122,7 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
122
122
  try:
123
123
  async with self.db_async_session() as session:
124
124
  result = await session.execute(stmt)
125
+ user = result.scalar_one_or_none()
125
126
 
126
127
  except ConnectionRefusedError as e:
127
128
  logger.exception(
@@ -133,8 +134,6 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
133
134
  status_code=500,
134
135
  ) from e
135
136
 
136
- user = result.scalar_one_or_none()
137
-
138
137
  if not user:
139
138
  raise AdminAPIException(
140
139
  APIError(message="User not found", code="user_not_found"),
@@ -6,7 +6,7 @@ from brilliance_admin.auth import UserABC
6
6
  from brilliance_admin.exceptions import AdminAPIException, APIError, FieldError
7
7
  from brilliance_admin.schema.category import FieldSchemaData
8
8
  from brilliance_admin.schema.table.fields.base import TableField
9
- from brilliance_admin.schema.table.table_models import Record
9
+ from brilliance_admin.schema.table.table_models import AutocompleteData, Record
10
10
  from brilliance_admin.translations import LanguageContext
11
11
  from brilliance_admin.translations import TranslateText as _
12
12
  from brilliance_admin.utils import DeserializeAction
@@ -96,10 +96,9 @@ class SQLAlchemyRelatedField(TableField):
96
96
  msg = f'Cannot resolve target model for FK "{field_slug}"'
97
97
  raise AttributeError(msg)
98
98
 
99
- async def autocomplete(self, model, data, user, *, extra: dict | None = None) -> List[Record]:
99
+ async def autocomplete(self, model, data: AutocompleteData, user, *, extra: dict | None = None) -> List[Record]:
100
100
  # pylint: disable=import-outside-toplevel
101
101
  from sqlalchemy import select
102
- from sqlalchemy.sql import expression
103
102
 
104
103
  if extra is None or extra.get('db_async_session') is None:
105
104
  msg = f'SQLAlchemyRelatedField.autocomplete {type(self).__name__} requires extra["db_async_session"] (AsyncSession)'
@@ -113,23 +112,37 @@ class SQLAlchemyRelatedField(TableField):
113
112
  limit = min(150, data.limit)
114
113
  stmt = select(target_model).limit(limit)
115
114
 
115
+ pk = get_pk(target_model)
116
+ python_pk_type = pk.property.columns[0].type.python_type
117
+
116
118
  if data.search_string:
117
- if hasattr(target_model, 'id'):
118
- stmt = stmt.where(getattr(target_model, 'id') == data.search_string)
119
+ try:
120
+ value = python_pk_type(data.search_string)
121
+ except (ValueError, TypeError):
122
+ # Search string cannot be cast to primary key type, skip id filter
123
+ value = None
124
+
125
+ stmt = stmt.where(pk == value)
119
126
 
120
127
  # Add already selected choices
121
- existed_choices = []
122
128
  if data.existed_choices:
123
129
  existed_choices = [i['key'] for i in data.existed_choices if 'key' in i]
124
130
 
125
- if existed_choices and hasattr(target_model, 'id'):
126
- stmt = stmt.where(getattr(target_model, 'id').in_(existed_choices) | expression.true())
131
+ values = []
132
+ for value in existed_choices:
133
+ try:
134
+ values.append(python_pk_type(value))
135
+ except (ValueError, TypeError) as e:
136
+ msg = f'Invalid existed_choices value "{value}" for pk {pk} python_pk_type:{python_pk_type.__name__}'
137
+ raise AdminAPIException(APIError(message=msg), status_code=500) from e
138
+
139
+ stmt = stmt.where(pk.in_(values))
127
140
 
128
141
  async with db_async_session() as session:
129
142
  records = (await session.execute(stmt)).scalars().all()
130
143
 
131
144
  for record in records:
132
- results.append(Record(key=getattr(record, 'id'), title=str(record)))
145
+ results.append(Record(key=getattr(record, pk.key), title=str(record)))
133
146
 
134
147
  return results
135
148
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brilliance-admin
3
- Version: 0.44.1
3
+ Version: 0.44.3
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
@@ -18,6 +18,7 @@ Requires-Dist: structlog>=25.5.0; extra == "example"
18
18
  Requires-Dist: rich>=14.2.0; extra == "example"
19
19
  Requires-Dist: asyncpg>=0.31.0; extra == "example"
20
20
  Requires-Dist: pydantic-settings>=2.12.0; extra == "example"
21
+ Requires-Dist: twine; extra == "example"
21
22
  Provides-Extra: tests
22
23
  Requires-Dist: pytest>=8.4.2; extra == "tests"
23
24
  Requires-Dist: pytest-asyncio>=1.2.0; extra == "tests"
@@ -1,16 +1,6 @@
1
- .gitignore
2
- .isort.cfg
3
- .python-version
4
1
  LICENSE
5
2
  README.md
6
3
  pyproject.toml
7
- uv.lock
8
- .configs/docker/Dockerfile
9
- .configs/docker/docker-compose.yml
10
- .configs/nginx/example.conf
11
- .github/workflows/certbot.yml
12
- .github/workflows/deploy.yml
13
- .github/workflows/install-docker.yml
14
4
  brilliance_admin/__init__.py
15
5
  brilliance_admin/auth.py
16
6
  brilliance_admin/docs.py
@@ -84,33 +74,6 @@ brilliance_admin/static/tinymce/plugins/codesample/css/prism.css
84
74
  brilliance_admin/static/tinymce/plugins/customLink/plugin.js
85
75
  brilliance_admin/static/tinymce/plugins/customLink/css/link.css
86
76
  brilliance_admin/templates/index.html
87
- example/README.md
88
- example/__init__.py
89
- example/main.py
90
- example/sqlite.py
91
- example/utils.py
92
- example/locales/en.yml
93
- example/locales/ru.yml
94
- example/sections/__init__.py
95
- example/sections/currency.py
96
- example/sections/graphs.py
97
- example/sections/merchant.py
98
- example/sections/models.py
99
- example/sections/payments.py
100
- example/sections/terminal.py
101
- example/sections/users.py
102
- example/static/favicon.ico
103
- example/static/favicon.jpg
104
- example/static/logo-outline.png
105
- example/static/logo.png
106
- screenshots/PC-graphs.jpeg
107
- screenshots/PC-table.jpeg
108
- screenshots/iPad-edit.jpeg
109
- screenshots/iPhone 15-edit.jpeg
110
- screenshots/iPhone 15-login.jpeg
111
- screenshots/websitemockupgenerator.png
112
- tests/__init__.py
113
- tests/conftest.py
114
77
  tests/test_action.py
115
78
  tests/test_payments_fields_schema.py
116
79
  tests/test_settings.py
@@ -11,6 +11,7 @@ structlog>=25.5.0
11
11
  rich>=14.2.0
12
12
  asyncpg>=0.31.0
13
13
  pydantic-settings>=2.12.0
14
+ twine
14
15
 
15
16
  [scalar]
16
17
  scalar-fastapi>=1.5.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "brilliance-admin"
3
- version = "0.44.1"
3
+ version = "0.44.3"
4
4
  description = 'Simple and lightweight data managment framework powered by FastAPI and Vue3 Vuetify all-in-one. Some call it heavenly in its brilliance.'
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -20,7 +20,11 @@ build-backend = "setuptools.build_meta"
20
20
  include = ["brilliance_admin*"]
21
21
 
22
22
  [tool.setuptools.package-data]
23
- brilliance_admin = ["static/**/*", "templates/**/*"]
23
+ brilliance_admin = [
24
+ "static/**/*",
25
+ "templates/**/*",
26
+ "locales/**/*.yml",
27
+ ]
24
28
 
25
29
  [project.optional-dependencies]
26
30
  example = [
@@ -31,6 +35,7 @@ example = [
31
35
  "rich>=14.2.0",
32
36
  "asyncpg>=0.31.0",
33
37
  "pydantic-settings>=2.12.0",
38
+ "twine",
34
39
  ]
35
40
  tests = [
36
41
  "pytest>=8.4.2",
@@ -1,22 +0,0 @@
1
- FROM python:3.12-slim
2
-
3
- # The installer requires curl (and certificates) to download the release archive
4
- RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates
5
-
6
- # Download the latest installer
7
- ADD https://astral.sh/uv/install.sh /uv-installer.sh
8
-
9
- # Run the installer then remove it
10
- RUN sh /uv-installer.sh && rm /uv-installer.sh
11
-
12
- # Ensure the installed binary is on the `PATH`
13
- ENV PATH="/root/.local/bin/:$PATH"
14
-
15
- # Copy the project into the image
16
- ADD . /app
17
-
18
- RUN apt-get install -y --no-install-recommends curl build-essential gettext libpq-dev git ssh openssh-client
19
-
20
- # Sync the project into a new environment, using the frozen lockfile
21
- WORKDIR /app
22
- RUN uv sync --frozen
@@ -1,40 +0,0 @@
1
- name: brilliance
2
-
3
- services:
4
- backend:
5
- build:
6
- context: ./../..
7
- dockerfile: .configs/docker/Dockerfile
8
- volumes:
9
- - ./../../:/app
10
- - ~/.ssh/id_rsa:/root/.ssh/id_rsa:delegated
11
- - ~/.ssh/known_hosts:/root/.ssh/known_hosts:delegated
12
- environment:
13
- POSTGRES_DB: brilliance
14
- POSTGRES_USER: brilliance
15
- POSTGRES_PASSWORD: brilliance
16
- POSTGRES_HOST: postgres
17
- tmpfs:
18
- - /tmp
19
- ports:
20
- - 8082:8082
21
- command: uv run uvicorn example.main:app --host 0.0.0.0 --port 8082 --reload --proxy-headers --forwarded-allow-ips='*'
22
- depends_on:
23
- postgres:
24
- condition: service_healthy
25
-
26
- postgres:
27
- image: postgres:alpine
28
- environment:
29
- POSTGRES_DB: brilliance
30
- POSTGRES_USER: brilliance
31
- POSTGRES_PASSWORD: brilliance
32
- tmpfs:
33
- - /var/lib/postgresql/data
34
- ports:
35
- - 5432:5432
36
- healthcheck:
37
- test: ['CMD', 'pg_isready', '-h', 'localhost', '-p', '5432', '-U', 'brilliance']
38
- interval: 2s
39
- timeout: 2s
40
- retries: 10
@@ -1,25 +0,0 @@
1
- server {
2
- listen 80;
3
- server_name brilliance-admin.com www.brilliance-admin.com;
4
-
5
- return 301 https://$host$request_uri;
6
- }
7
-
8
- server {
9
- listen 443 ssl;
10
- server_name brilliance-admin.com www.brilliance-admin.com;
11
-
12
- ssl_certificate /etc/letsencrypt/live/brilliance-admin.com/fullchain.pem;
13
- ssl_certificate_key /etc/letsencrypt/live/brilliance-admin.com/privkey.pem;
14
-
15
- ssl_protocols TLSv1.2 TLSv1.3;
16
- ssl_prefer_server_ciphers off;
17
-
18
- location / {
19
- proxy_pass http://127.0.0.1:8082;
20
- proxy_set_header Host $host;
21
- proxy_set_header X-Real-IP $remote_addr;
22
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
23
- proxy_set_header X-Forwarded-Proto https;
24
- }
25
- }
@@ -1,36 +0,0 @@
1
- name: Setup HTTPS
2
-
3
- on:
4
- workflow_dispatch:
5
-
6
- jobs:
7
- setup-https:
8
- runs-on: ubuntu-latest
9
- steps:
10
- - name: Setup HTTPS with certbot (snap)
11
- uses: appleboy/ssh-action@master
12
- with:
13
- host: ${{ vars.SERVER_HOST }}
14
- username: deploy
15
- key: ${{ secrets.SERVER_SSH_KEY }}
16
- script: |
17
- sudo apt remove -y certbot python3-certbot-nginx || true
18
-
19
- if ! command -v snap >/dev/null 2>&1; then
20
- sudo apt update
21
- sudo apt install -y snapd
22
- fi
23
-
24
- sudo snap install core || sudo snap refresh core
25
- sudo snap install --classic certbot || true
26
- sudo ln -sf /snap/bin/certbot /usr/bin/certbot
27
-
28
- sudo certbot --nginx \
29
- -d brilliance-admin.com \
30
- -d www.brilliance-admin.com \
31
- -d docs.brilliance-admin.com \
32
- --expand \
33
- --non-interactive \
34
- --agree-tos \
35
- -m admin@brilliance-admin.com \
36
- --redirect
@@ -1,127 +0,0 @@
1
- name: CI-CD Pipeline
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
-
7
- jobs:
8
- build-test:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Checkout code
12
- uses: actions/checkout@v5
13
-
14
- - name: Build containers
15
- run: docker compose -f .configs/docker/docker-compose.yml build
16
-
17
- - name: Run tests
18
- run: docker compose -f .configs/docker/docker-compose.yml run --rm backend sh -c 'uv sync --all-groups --all-extras && uv run pytest'
19
-
20
- deploy:
21
- needs: build-test
22
- runs-on: ubuntu-latest
23
- if: ${{ success() }}
24
- steps:
25
- - name: Checkout code
26
- uses: actions/checkout@v5
27
-
28
- - name: Clone repo via GitHub App
29
- uses: GuillaumeFalourd/clone-github-repo-action@v2
30
- with:
31
- owner: brilliance-admin
32
- repository: backend-python
33
- app_id: ${{ secrets.GH_APP_ID }}
34
- installation_id: ${{ secrets.GH_APP_INSTALLATION_ID }}
35
- private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
36
-
37
- - name: Ensure rsync installed on server
38
- uses: appleboy/ssh-action@master
39
- with:
40
- host: ${{ vars.SERVER_HOST }}
41
- username: deploy
42
- key: ${{ secrets.SERVER_SSH_KEY }}
43
- script: |
44
- if ! command -v rsync >/dev/null 2>&1; then
45
- sudo apt update
46
- sudo apt install -y rsync
47
- fi
48
-
49
- - name: Fix folder permissions
50
- uses: appleboy/ssh-action@master
51
- with:
52
- host: ${{ vars.SERVER_HOST }}
53
- username: deploy
54
- key: ${{ secrets.SERVER_SSH_KEY }}
55
- script: |
56
- sudo chown -R deploy:deploy /home/deploy/apps/backend-python
57
-
58
- - name: Copy files to server
59
- uses: burnett01/rsync-deployments@v8
60
- with:
61
- switches: -avzr --delete --chown=deploy:deploy
62
- path: .
63
- remote_path: /home/deploy/apps/backend-python
64
- remote_host: ${{ vars.SERVER_HOST }}
65
- remote_user: deploy
66
- remote_key: ${{ secrets.SERVER_SSH_KEY }}
67
-
68
- - name: Run Docker on server
69
- uses: appleboy/ssh-action@master
70
- with:
71
- host: ${{ vars.SERVER_HOST }}
72
- username: deploy
73
- key: ${{ secrets.SERVER_SSH_KEY }}
74
- script: |
75
- cd /home/deploy/apps/backend-python
76
- docker compose -f .configs/docker/docker-compose.yml run --rm backend /bin/bash -c "uv sync --all-groups --all-extras"
77
- docker compose -f .configs/docker/docker-compose.yml up -d --build
78
-
79
- - name: Wait backend healthy
80
- uses: appleboy/ssh-action@master
81
- with:
82
- host: ${{ vars.SERVER_HOST }}
83
- username: deploy
84
- key: ${{ secrets.SERVER_SSH_KEY }}
85
- script: |
86
- for i in 1 2 3 4 5 6; do
87
- STATUS=$(docker inspect --format='{{.State.Health.Status}}' brilliance-backend-1 2>/dev/null || true)
88
- if [ "$STATUS" = "healthy" ]; then
89
- exit 0
90
- fi
91
- sleep 3
92
- done
93
- exit 1
94
-
95
- update-nginx:
96
- needs: deploy
97
- runs-on: ubuntu-latest
98
- if: ${{ success() }}
99
- steps:
100
-
101
- - name: Ensure nginx is running
102
- uses: appleboy/ssh-action@master
103
- with:
104
- host: ${{ vars.SERVER_HOST }}
105
- username: deploy
106
- key: ${{ secrets.SERVER_SSH_KEY }}
107
- script: |
108
- if ! systemctl is-active --quiet nginx; then
109
- sudo systemctl start nginx
110
- fi
111
- sudo systemctl status nginx --no-pager
112
-
113
- - name: Ensure nginx and update config
114
- uses: appleboy/ssh-action@master
115
- with:
116
- host: ${{ vars.SERVER_HOST }}
117
- username: deploy
118
- key: ${{ secrets.SERVER_SSH_KEY }}
119
- script: |
120
- if ! command -v nginx >/dev/null 2>&1; then
121
- sudo apt update
122
- sudo apt install -y nginx
123
- fi
124
- sudo ln -sf /home/deploy/apps/backend-python/.configs/nginx/example.conf /etc/nginx/sites-enabled/example
125
- sudo rm -f /etc/nginx/sites-enabled/default
126
- sudo nginx -t
127
- sudo systemctl reload nginx
@@ -1,26 +0,0 @@
1
- name: Install Docker on server
2
-
3
- on:
4
- workflow_dispatch:
5
-
6
- jobs:
7
- install-docker:
8
- runs-on: ubuntu-latest
9
- steps:
10
- - name: Ensure Docker installed and deploy in docker group
11
- uses: appleboy/ssh-action@master
12
- with:
13
- host: ${{ vars.SERVER_HOST }}
14
- username: ${{ vars.SERVER_USER }}
15
- key: ${{ secrets.SERVER_SSH_KEY }}
16
- script: |
17
- if ! command -v docker >/dev/null 2>&1; then
18
- sudo apt update
19
- sudo apt install -y ca-certificates curl gnupg
20
- sudo install -m 0755 -d /etc/apt/keyrings
21
- curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
22
- sudo chmod a+r /etc/apt/keyrings/docker.gpg
23
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
24
- sudo apt update
25
- sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
26
- fi
@@ -1,12 +0,0 @@
1
- # Python-generated files
2
- .env
3
- test.db
4
- __pycache__/
5
- *.py[oc]
6
- build/
7
- dist/
8
- wheels/
9
- *.egg-info
10
-
11
- # Virtual environments
12
- .venv
@@ -1,7 +0,0 @@
1
- [isort]
2
- line_length=120
3
- py_version=39
4
- multi_line_output=4
5
- known_third_party=fastapi
6
- known_first_party=app,tests,brilliance_admin
7
- virtual_env=py3
@@ -1 +0,0 @@
1
- 3.10
@@ -1,32 +0,0 @@
1
- # Example
2
-
3
- ## Development
4
-
5
- ``` shell
6
- uv sync --all-groups --all-extras
7
- uv run uvicorn example.main:app --host 0.0.0.0 --port 8082 --reload
8
- ```
9
-
10
- Tests:
11
- ``` shell
12
- uv run pytest
13
- ```
14
-
15
- Docs:
16
- - `http://0.0.0.0:8082/docs`
17
- - `http://0.0.0.0:8082/redoc`
18
- - `http://0.0.0.0:8082/scalar`
19
-
20
- ## Docker
21
-
22
- ``` shell
23
- docker compose -f .configs/docker/docker-compose.yml build
24
- docker compose -f .configs/docker/docker-compose.yml up
25
- docker compose -f .configs/docker/docker-compose.yml run --rm backend /bin/bash -c "uv sync --all-groups --all-extras"
26
- docker compose -f .configs/docker/docker-compose.yml run --rm backend /bin/bash -c "uv run pytest"
27
- ```
28
-
29
- ``` shell
30
- docker exec -it rollyum-backend-1 git config --global --add safe.directory '*'
31
- docker exec -it rollyum-backend-1 uv run pre-commit run --all-files
32
- ```
File without changes
@@ -1,57 +0,0 @@
1
- admin_title: 'Brilliance Admin Demo'
2
- docs: 'Documentation'
3
-
4
- admin_description: |
5
- Used to demonstrate the capabilities of the admin panel.<br>
6
- <br>
7
- Data and actions in this mode do not affect the production environment and are periodically reset.
8
-
9
- login_greetings_message: |
10
- <div class="text-h6 mb-1">
11
- Demo mode
12
- </div>
13
- <div class="text-caption">
14
- Login: admin<br>
15
- Password: admin
16
- </div>
17
-
18
- created_at: 'Created time'
19
- graphs_example: 'Graphs example'
20
- amount: 'Amount'
21
- registry_checked: 'Registry checked'
22
- registry_info_checked: 'Registry info checked'
23
- payments: 'Payments'
24
- payments_description: 'Static data'
25
- statistics: 'Statistics'
26
- image: 'Image'
27
- payments_search_fields: 'Search fields: id'
28
- create_payment: 'Create payment'
29
- create_payment_description: 'Create a payment and send it to the payment system for processing.'
30
-
31
- payment_create_result: |
32
- <h3>The payment was created successfully!</h3>
33
- %(desctiption)s<br>
34
- <br>
35
- Payment details:
36
- gateway_id=%(gateway_id)s<br>
37
- redirect_url: <a href="%(redirect_url)s" target="_blank"/>%(redirect_url)s</a>
38
-
39
- description: 'Description'
40
- status: 'Status'
41
- endpoint: 'Endpoint'
42
- action_with_exception: 'Action with exception'
43
- is_throw_error: 'Is throw error?'
44
- throw_error: 'Example of a field validation error.'
45
- exception_example: 'Exception example.'
46
- merchants: 'Merchants'
47
- terminals: 'Terminals'
48
- currencies: 'Currencies'
49
- whitelist_ips: 'Whitelist IPs'
50
- users: 'Users'
51
- field_not_found_in_schema: 'The field "{field_slug}" was not found among the available fields: {available}'
52
- related_not_found: 'Error updating related field {field_slug}: {model} record with pk={pk} was not found. The record may no longer be available.'
53
-
54
- statuses:
55
- process: 'Process'
56
- success: 'Success'
57
- error: 'Error'
@@ -1,57 +0,0 @@
1
- admin_title: 'Brilliance Admin Демо'
2
- docs: 'Документация'
3
-
4
- admin_description: |
5
- Используется для демонстрации возможностей админ панели.<br>
6
- <br>
7
- Данные и действия в этом режиме не влияют на рабочее окружение и периодически сбрасываются.
8
-
9
- login_greetings_message: |
10
- <div class="text-h6 mb-1">
11
- Демо режим
12
- </div>
13
- <div class="text-caption">
14
- Логин: admin<br>
15
- Пароль: admin
16
- </div>
17
-
18
- created_at: 'Время создания'
19
- graphs_example: 'Пример графиков'
20
- amount: 'Сумма'
21
- registry_checked: 'Реестр проверен'
22
- registry_info_checked: 'Информация по реестру провайдера'
23
- payments: 'Платежи'
24
- payments_description: 'Статичные данные'
25
- statistics: 'Статистика'
26
- image: 'Изображение'
27
- payments_search_fields: 'Доступные поля для поиска: id'
28
- create_payment: 'Создать платеж'
29
- create_payment_description: 'Создать платеж и отправить его на обработку в платежную систему.'
30
-
31
- payment_create_result: |
32
- <h3>Платеж успешно создан!</h3>
33
- %(desctiption)s<br>
34
- <br>
35
- Данные платежа:<br>
36
- gateway_id=%(gateway_id)s<br>
37
- redirect_url: <a href="%(redirect_url)s" target="_blank"/>%(redirect_url)s</a>
38
-
39
- description: 'Описание'
40
- status: 'Статус'
41
- endpoint: 'Эндпоинт'
42
- action_with_exception: 'Действие с ошибкой'
43
- is_throw_error: 'Выбросить ошибку?'
44
- throw_error: 'Пример ошибки валидации поля.'
45
- exception_example: 'Пример ошибки исключения.'
46
- merchants: 'Мерчанты'
47
- terminals: 'Терминалы'
48
- currencies: 'Валюты'
49
- whitelist_ips: 'Белый список IP'
50
- users: 'Пользователи'
51
- field_not_found_in_schema: 'Поле "{field_slug}" не найдено среди доступных: {available}'
52
- related_not_found: 'Ошибка при обновлении связей поля {field_slug}: запись {model} с ключем pk={pk} не найдена. Возможно запись более недоступна.'
53
-
54
- statuses:
55
- process: 'В процессе'
56
- success: 'Успех'
57
- error: 'Ошибка'