brilliance-admin 0.43.5__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.
- brilliance_admin-0.43.5/.configs/docker/Dockerfile +22 -0
- brilliance_admin-0.43.5/.configs/docker/docker-compose.yml +35 -0
- brilliance_admin-0.43.5/.configs/nginx/example.conf +25 -0
- brilliance_admin-0.43.5/.env +0 -0
- brilliance_admin-0.43.5/.github/workflows/certbot.yml +27 -0
- brilliance_admin-0.43.5/.github/workflows/deploy.yml +127 -0
- brilliance_admin-0.43.5/.github/workflows/install-docker.yml +26 -0
- brilliance_admin-0.43.5/.gitignore +11 -0
- brilliance_admin-0.43.5/.isort.cfg +7 -0
- brilliance_admin-0.43.5/.python-version +1 -0
- brilliance_admin-0.43.5/LICENSE +17 -0
- brilliance_admin-0.43.5/PKG-INFO +214 -0
- brilliance_admin-0.43.5/README.md +183 -0
- brilliance_admin-0.43.5/brilliance_admin/__init__.py +4 -0
- brilliance_admin-0.43.5/brilliance_admin/api/__init__.py +0 -0
- brilliance_admin-0.43.5/brilliance_admin/api/routers.py +18 -0
- brilliance_admin-0.43.5/brilliance_admin/api/utils.py +28 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/__init__.py +0 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/auth.py +29 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/autocomplete.py +33 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/graphs.py +30 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/index.py +45 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/schema.py +29 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/settings.py +29 -0
- brilliance_admin-0.43.5/brilliance_admin/api/views/table.py +136 -0
- brilliance_admin-0.43.5/brilliance_admin/auth.py +32 -0
- brilliance_admin-0.43.5/brilliance_admin/docs.py +37 -0
- brilliance_admin-0.43.5/brilliance_admin/exceptions.py +37 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/__init__.py +0 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/__init__.py +6 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/auth.py +144 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/autocomplete.py +38 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/fields.py +259 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/fields_schema.py +325 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/__init__.py +19 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/base.py +141 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/create.py +73 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/delete.py +18 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/list.py +178 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/retrieve.py +73 -0
- brilliance_admin-0.43.5/brilliance_admin/integrations/sqlalchemy/table/update.py +95 -0
- brilliance_admin-0.43.5/brilliance_admin/locales/en.yml +25 -0
- brilliance_admin-0.43.5/brilliance_admin/locales/ru.yml +26 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/__init__.py +7 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/admin_schema.py +199 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/category.py +148 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/graphs/__init__.py +1 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/graphs/category_graphs.py +51 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/group.py +67 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/__init__.py +8 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/admin_action.py +77 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/category_table.py +175 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/fields/__init__.py +5 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/fields/base.py +278 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/fields/function_field.py +65 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/fields_schema.py +217 -0
- brilliance_admin-0.43.5/brilliance_admin/schema/table/table_models.py +53 -0
- brilliance_admin-0.43.5/brilliance_admin/static/index-D9axz5zK.js +525 -0
- brilliance_admin-0.43.5/brilliance_admin/static/index-vlBToOhT.css +8 -0
- brilliance_admin-0.43.5/brilliance_admin/static/materialdesignicons-webfont-CYDMK1kx.woff2 +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/materialdesignicons-webfont-CgCzGbLl.woff +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/materialdesignicons-webfont-D3kAzl71.ttf +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/materialdesignicons-webfont-DttUABo4.eot +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/dark-first/content.min.css +250 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/dark-first/skin.min.css +2820 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/dark-slim/content.min.css +249 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/dark-slim/skin.min.css +2821 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/img/example.png +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/img/tinymce.woff2 +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/lightgray/content.min.css +1 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/lightgray/fonts/tinymce.woff +0 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/lightgray/skin.min.css +1 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/plugins/accordion/css/accordion.css +17 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/plugins/accordion/plugin.js +48 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/plugins/codesample/css/prism.css +1 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/plugins/customLink/css/link.css +3 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/plugins/customLink/plugin.js +147 -0
- brilliance_admin-0.43.5/brilliance_admin/static/tinymce/tinymce.min.js +2 -0
- brilliance_admin-0.43.5/brilliance_admin/static/vanilla-picker-B6E6ObS_.js +8 -0
- brilliance_admin-0.43.5/brilliance_admin/templates/index.html +25 -0
- brilliance_admin-0.43.5/brilliance_admin/translations.py +115 -0
- brilliance_admin-0.43.5/brilliance_admin/utils.py +153 -0
- brilliance_admin-0.43.5/brilliance_admin.egg-info/PKG-INFO +214 -0
- brilliance_admin-0.43.5/brilliance_admin.egg-info/SOURCES.txt +123 -0
- brilliance_admin-0.43.5/brilliance_admin.egg-info/dependency_links.txt +1 -0
- brilliance_admin-0.43.5/brilliance_admin.egg-info/requires.txt +24 -0
- brilliance_admin-0.43.5/brilliance_admin.egg-info/top_level.txt +1 -0
- brilliance_admin-0.43.5/example/README.md +32 -0
- brilliance_admin-0.43.5/example/__init__.py +0 -0
- brilliance_admin-0.43.5/example/locales/en.yml +57 -0
- brilliance_admin-0.43.5/example/locales/ru.yml +56 -0
- brilliance_admin-0.43.5/example/main.py +144 -0
- brilliance_admin-0.43.5/example/sections/__init__.py +0 -0
- brilliance_admin-0.43.5/example/sections/currency.py +21 -0
- brilliance_admin-0.43.5/example/sections/graphs.py +136 -0
- brilliance_admin-0.43.5/example/sections/merchant.py +45 -0
- brilliance_admin-0.43.5/example/sections/models.py +256 -0
- brilliance_admin-0.43.5/example/sections/payments.py +186 -0
- brilliance_admin-0.43.5/example/sections/terminal.py +42 -0
- brilliance_admin-0.43.5/example/sections/users.py +25 -0
- brilliance_admin-0.43.5/example/sqlite.py +45 -0
- brilliance_admin-0.43.5/example/static/favicon.ico +0 -0
- brilliance_admin-0.43.5/example/static/favicon.jpg +0 -0
- brilliance_admin-0.43.5/example/static/logo-outline.png +0 -0
- brilliance_admin-0.43.5/example/static/logo.png +0 -0
- brilliance_admin-0.43.5/example/utils.py +26 -0
- brilliance_admin-0.43.5/pyproject.toml +48 -0
- brilliance_admin-0.43.5/screenshots/PC-graphs.jpeg +0 -0
- brilliance_admin-0.43.5/screenshots/PC-table.jpeg +0 -0
- brilliance_admin-0.43.5/screenshots/iPad-edit.jpeg +0 -0
- brilliance_admin-0.43.5/screenshots/iPhone 15-edit.jpeg +0 -0
- brilliance_admin-0.43.5/screenshots/iPhone 15-login.jpeg +0 -0
- brilliance_admin-0.43.5/screenshots/websitemockupgenerator.png +0 -0
- brilliance_admin-0.43.5/setup.cfg +4 -0
- brilliance_admin-0.43.5/tests/__init__.py +0 -0
- brilliance_admin-0.43.5/tests/conftest.py +26 -0
- brilliance_admin-0.43.5/tests/test_action.py +26 -0
- brilliance_admin-0.43.5/tests/test_payments_fields_schema.py +191 -0
- brilliance_admin-0.43.5/tests/test_settings.py +48 -0
- brilliance_admin-0.43.5/tests/test_sqlalcmeny_auth.py +98 -0
- brilliance_admin-0.43.5/tests/test_sqlalcmeny_crud.py +284 -0
- brilliance_admin-0.43.5/tests/test_sqlalcmeny_filters.py +223 -0
- brilliance_admin-0.43.5/tests/test_sqlalcmeny_schema.py +185 -0
- brilliance_admin-0.43.5/tests/test_translations.py +40 -0
- brilliance_admin-0.43.5/uv.lock +886 -0
|
@@ -0,0 +1,22 @@
|
|
|
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
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: brilliance
|
|
2
|
+
|
|
3
|
+
volumes:
|
|
4
|
+
db_data:
|
|
5
|
+
|
|
6
|
+
services:
|
|
7
|
+
backend:
|
|
8
|
+
build:
|
|
9
|
+
context: ./../..
|
|
10
|
+
dockerfile: .configs/docker/Dockerfile
|
|
11
|
+
volumes:
|
|
12
|
+
- ./../../:/app
|
|
13
|
+
- ~/.ssh/id_rsa:/root/.ssh/id_rsa:delegated
|
|
14
|
+
- ~/.ssh/known_hosts:/root/.ssh/known_hosts:delegated
|
|
15
|
+
env_file:
|
|
16
|
+
- ./../../.env
|
|
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
|
+
healthcheck:
|
|
23
|
+
test: ['CMD', 'curl', '-f', 'http://127.0.0.1:8082']
|
|
24
|
+
interval: 5s
|
|
25
|
+
timeout: 2s
|
|
26
|
+
retries: 5
|
|
27
|
+
|
|
28
|
+
postgres:
|
|
29
|
+
image: postgres:alpine
|
|
30
|
+
env_file:
|
|
31
|
+
- ./../../.env
|
|
32
|
+
volumes:
|
|
33
|
+
- db_data:/var/lib/postgresql/data
|
|
34
|
+
ports:
|
|
35
|
+
- 5432:5432
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
|
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
|
+
if ! command -v certbot >/dev/null 2>&1; then
|
|
18
|
+
sudo apt update
|
|
19
|
+
sudo apt install -y certbot python3-certbot-nginx
|
|
20
|
+
fi
|
|
21
|
+
sudo certbot --nginx \
|
|
22
|
+
-d brilliance-admin.com \
|
|
23
|
+
-d www.brilliance-admin.com \
|
|
24
|
+
--non-interactive \
|
|
25
|
+
--agree-tos \
|
|
26
|
+
-m admin@brilliance-admin.com \
|
|
27
|
+
--redirect
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2025 Your Name
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Affero General Public License as published
|
|
8
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brilliance-admin
|
|
3
|
+
Version: 0.43.5
|
|
4
|
+
Summary: Simple and lightweight admin panel framework powered by FastAPI and Vue3 Vuetify together.. Some call it heavenly in its brilliance.
|
|
5
|
+
License-Expression: AGPL-3.0
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: asgiref>=3.11
|
|
10
|
+
Requires-Dist: fastapi>=0.115
|
|
11
|
+
Requires-Dist: jinja2>=3.1
|
|
12
|
+
Requires-Dist: PyYAML>=6.0
|
|
13
|
+
Provides-Extra: example
|
|
14
|
+
Requires-Dist: uvicorn>=0.34.0; extra == "example"
|
|
15
|
+
Requires-Dist: faker>=38.2.0; extra == "example"
|
|
16
|
+
Requires-Dist: pyjwt>=2.10.1; extra == "example"
|
|
17
|
+
Requires-Dist: structlog>=25.5.0; extra == "example"
|
|
18
|
+
Requires-Dist: rich>=14.2.0; extra == "example"
|
|
19
|
+
Provides-Extra: tests
|
|
20
|
+
Requires-Dist: pytest>=8.4.2; extra == "tests"
|
|
21
|
+
Requires-Dist: pytest-asyncio>=1.2.0; extra == "tests"
|
|
22
|
+
Requires-Dist: httpx>=0.28.1; extra == "tests"
|
|
23
|
+
Requires-Dist: pytest-mock>=3.15.1; extra == "tests"
|
|
24
|
+
Requires-Dist: sqlalchemy>=2.0.41; extra == "tests"
|
|
25
|
+
Requires-Dist: aiosqlite>=0.22.1; extra == "tests"
|
|
26
|
+
Requires-Dist: factory-boy>=3.3.3; extra == "tests"
|
|
27
|
+
Requires-Dist: pyjwt>=2.10.1; extra == "tests"
|
|
28
|
+
Provides-Extra: scalar
|
|
29
|
+
Requires-Dist: scalar-fastapi>=1.5.0; extra == "scalar"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
<div align="center">
|
|
33
|
+
<img src="https://github.com/brilliance-admin/backend-python/blob/main/example/static/logo-outline.png?raw=true"
|
|
34
|
+
alt="Brilliance Admin"
|
|
35
|
+
width="600">
|
|
36
|
+
|
|
37
|
+
[](https://pypi.org/project/brilliance-admin/)
|
|
38
|
+
[](https://github.com/brilliance-admin/backend-python/actions)
|
|
39
|
+
|
|
40
|
+
Simple and lightweight admin panel framework powered by `FastAPI` and `Vue3` `Vuetify` together. \
|
|
41
|
+
Integrated with `SQLAlchemy`. Inspaired by Django Admin and DRF.\
|
|
42
|
+
_Some call it heavenly in its brilliance._
|
|
43
|
+
|
|
44
|
+
### [Live Demo](https://brilliance-admin.com/) | [Demo Sources](https://github.com/brilliance-admin/backend-python/tree/main/example) | Documentation (todo)
|
|
45
|
+
|
|
46
|
+
<img src="https://github.com/brilliance-admin/backend-python/blob/main/screenshots/websitemockupgenerator.png?raw=true"
|
|
47
|
+
alt="Preview">
|
|
48
|
+
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
**Key ideas:**
|
|
52
|
+
- **API oriented**\
|
|
53
|
+
Works entirely on FastAPI and provides a prebuilt SPA [frontend](https://github.com/brilliance-admin/frontend) via static files (Vue3 + Vuetify). No separate startup is required.
|
|
54
|
+
> Data generation/updating API separated from rendering fontend with zero hardcode, this makes it possible to have a single frontend with multiple backend implementations in different languages and makes test coverage easier.
|
|
55
|
+
- **Rich visualization**\
|
|
56
|
+
Providing rich and convenient ways to display and manage data (tables, charts, etc) from any data source.
|
|
57
|
+
- **ORM**\
|
|
58
|
+
Automatic schema generation and methods for CRUD operations.
|
|
59
|
+
- **Minimal boilerplate**\
|
|
60
|
+
Focused on simplified, but rich configuration.
|
|
61
|
+
|
|
62
|
+
**How it works:**
|
|
63
|
+
- After authentication, the user receives the admin panel schema, and the frontend renders it
|
|
64
|
+
- The frontend communicates with the backend via API to fetch and modify data
|
|
65
|
+
|
|
66
|
+
### Features:
|
|
67
|
+
|
|
68
|
+
* Tables with full CRUD support, including filtering, sorting, and pagination.
|
|
69
|
+
* Ability to define custom table actions with forms, response messages, and file downloads.
|
|
70
|
+
* Graphs via ChartJS
|
|
71
|
+
* Localization support
|
|
72
|
+
* Adapted for different screen sizes and mobile devices
|
|
73
|
+
* Authorization via any account data source
|
|
74
|
+
|
|
75
|
+
**Integrations:**
|
|
76
|
+
* **SQLAlchemy** - schema autogeneration for tables + CRUD operations + authorization
|
|
77
|
+
|
|
78
|
+
**Planned:**
|
|
79
|
+
* Role-based access control system
|
|
80
|
+
* Nested data support for creation and detail views
|
|
81
|
+
* Django ORM inegration
|
|
82
|
+
|
|
83
|
+
## How to use it
|
|
84
|
+
|
|
85
|
+
Installation:
|
|
86
|
+
``` shell
|
|
87
|
+
pip install brilliance-admin
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
You need to generate `AdminSchema` instance:
|
|
91
|
+
``` python
|
|
92
|
+
from brilliance_admin import schema
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class CategoryExample(schema.CategoryTable):
|
|
96
|
+
"Implementation of get_list and retrieve; update and create are optional"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
admin_schema = schema.AdminSchema(
|
|
100
|
+
title='Admin Panel',
|
|
101
|
+
auth=YourAdminAuthentication(),
|
|
102
|
+
groups=[
|
|
103
|
+
schema.Group(
|
|
104
|
+
slug='example',
|
|
105
|
+
title='Example',
|
|
106
|
+
icon='mdi-star',
|
|
107
|
+
categories=[
|
|
108
|
+
CategoryExample(),
|
|
109
|
+
]
|
|
110
|
+
),
|
|
111
|
+
],
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
admin_app = admin_schema.generate_app()
|
|
115
|
+
|
|
116
|
+
# Your FastAPI app
|
|
117
|
+
app = FastAPI()
|
|
118
|
+
app.mount('/admin', admin_app)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## SQLAlchemy integration
|
|
122
|
+
|
|
123
|
+
Supports automatic schema generation for CRUD tables:
|
|
124
|
+
|
|
125
|
+
``` python
|
|
126
|
+
category = sqlalchemy.SQLAlchemyAdmin(db_async_session=async_sessionmaker, model=Terminal)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
> [!NOTE]
|
|
130
|
+
> If `table_schema` is not specified, it will be generated automatically with all discovered fields and relationships
|
|
131
|
+
|
|
132
|
+
Now, the `category` instance can be passed to `categories`.
|
|
133
|
+
|
|
134
|
+
### DRF class style schema
|
|
135
|
+
|
|
136
|
+
``` python
|
|
137
|
+
from brilliance_admin import sqlalchemy
|
|
138
|
+
from brilliance_admin.translations import TranslateText as _
|
|
139
|
+
|
|
140
|
+
from your_project.models import Terminal
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class TerminalFiltersSchema(sqlalchemy.SQLAlchemyFieldsSchema):
|
|
144
|
+
model = Terminal
|
|
145
|
+
fields = ['id', 'created_at']
|
|
146
|
+
created_at = schema.DateTimeField(range=True)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class TerminalSchema(sqlalchemy.SQLAlchemyFieldsSchema):
|
|
150
|
+
model = Terminal
|
|
151
|
+
list_display = ['id', 'merchant_id']
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class TerminalAdmin(sqlalchemy.SQLAlchemyAdmin):
|
|
155
|
+
db_async_session = async_sessionmaker
|
|
156
|
+
model = Terminal
|
|
157
|
+
title = _('terminals')
|
|
158
|
+
icon = 'mdi-console-network-outline'
|
|
159
|
+
|
|
160
|
+
ordering_fields = ['id']
|
|
161
|
+
search_fields = ['id', 'title']
|
|
162
|
+
|
|
163
|
+
table_schema = TerminalSchema()
|
|
164
|
+
table_filters = TerminalFiltersSchema()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
category = TerminalAdmin()
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Can be used both via inheritance and instancing
|
|
171
|
+
|
|
172
|
+
Optionally, functional-style generation can be used to reduce boilerplate code
|
|
173
|
+
|
|
174
|
+
Availiable for `SQLAlchemyAdmin` and `SQLAlchemyFieldsSchema`
|
|
175
|
+
|
|
176
|
+
``` python
|
|
177
|
+
category = sqlalchemy.SQLAlchemyAdmin(
|
|
178
|
+
db_async_session=async_sessionmaker,
|
|
179
|
+
model=Terminal,
|
|
180
|
+
|
|
181
|
+
table_schema = sqlalchemy.SQLAlchemyFieldsSchema(
|
|
182
|
+
model=Terminal,
|
|
183
|
+
list_display=['id', 'merchant_id'],
|
|
184
|
+
),
|
|
185
|
+
table_filters = sqlalchemy.SQLAlchemyFieldsSchema(
|
|
186
|
+
model=Terminal,
|
|
187
|
+
fields=['id', 'created_at'],
|
|
188
|
+
created_at=schema.DateTimeField(range=True),
|
|
189
|
+
),
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### SQLAlchemy JWT Authentication
|
|
194
|
+
|
|
195
|
+
``` python
|
|
196
|
+
auth = sqlalchemy.SQLAlchemyJWTAdminAuthentication(
|
|
197
|
+
secret='auth_secret',
|
|
198
|
+
db_async_session=async_session,
|
|
199
|
+
user_model=User,
|
|
200
|
+
)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Comparison of Similar Projects
|
|
204
|
+
|
|
205
|
+
| Criterion | Brilliance Admin | Django Admin/Unfold | FastAPI Admin | Starlette Admin |
|
|
206
|
+
|---------|------------------|---------------|---------------|-----------------|
|
|
207
|
+
| Base framework | FastAPI | Django | FastAPI | Starlette / FastAPI |
|
|
208
|
+
| Rendering model | Prebuilt Vue 3 + Vuetify SPA + Jinja2 | Server-side Django templates | Server-side Jinja2 templates + Tabler UI | Server-side Jinja2 templates + Tabler UI |
|
|
209
|
+
| Frontend architecture | Separate frontend (SPA) | Classic server-rendered UI | Server-rendered UI with JS interactivity | Server-rendered UI with JS interactivity |
|
|
210
|
+
| Data source | Any source + SQLAlchemy | Django ORM | Tortoise ORM | Any source + SQLAlchemy, MongoDB |
|
|
211
|
+
| Multiple databases per model | Yes | Database routers | No (global engine) | Yes (session per ModelView) |
|
|
212
|
+
| Schema generation | User-defined format | From Django models | From ORM models | User-defined format |
|
|
213
|
+
| Async support | Yes | No | Yes | Yes |
|
|
214
|
+
| API-first approach | Yes | No | Partially | Partially |
|