reyserver 1.1.56__py3-none-any.whl → 1.1.57__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.
Potentially problematic release.
This version of reyserver might be problematic. Click here for more details.
- reyserver/__init__.py +1 -0
- reyserver/radmin.py +128 -0
- reyserver/rall.py +1 -0
- reyserver/rauth.py +5 -2
- reyserver/rbase.py +5 -4
- reyserver/rclient.py +0 -1
- reyserver/rserver.py +75 -6
- {reyserver-1.1.56.dist-info → reyserver-1.1.57.dist-info}/METADATA +3 -4
- reyserver-1.1.57.dist-info/RECORD +12 -0
- reyserver-1.1.56.dist-info/RECORD +0 -11
- {reyserver-1.1.56.dist-info → reyserver-1.1.57.dist-info}/WHEEL +0 -0
- {reyserver-1.1.56.dist-info → reyserver-1.1.57.dist-info}/licenses/LICENSE +0 -0
reyserver/__init__.py
CHANGED
reyserver/radmin.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
@Time : 2025-10-14
|
|
6
|
+
@Author : Rey
|
|
7
|
+
@Contact : reyxbo@163.com
|
|
8
|
+
@Explain : Admin methods.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from typing import Any, Type
|
|
13
|
+
from collections.abc import Sequence
|
|
14
|
+
from sqlalchemy.ext.asyncio import async_sessionmaker
|
|
15
|
+
from sqladmin import Admin, ModelView
|
|
16
|
+
from reydb import DatabaseEngineAsync, rorm
|
|
17
|
+
from reykit.rbase import Singleton
|
|
18
|
+
|
|
19
|
+
from .rbase import ServerBase
|
|
20
|
+
from . import rserver
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
__all__ = (
|
|
24
|
+
'ServerAdminModel',
|
|
25
|
+
'ServerAdminModelView',
|
|
26
|
+
'ServerAdminModelViewStats'
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ServerAdminModel(ModelView):
|
|
31
|
+
"""
|
|
32
|
+
Server admin model type.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ServerAdminModelView(ServerAdminModel):
|
|
37
|
+
"""
|
|
38
|
+
Server admin view model type.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
category = 'View'
|
|
42
|
+
can_view_details = can_edit = can_create = can_delete = False
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ServerAdminModelViewStats(ServerAdminModelView):
|
|
46
|
+
"""
|
|
47
|
+
Server admin stats view model type.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
column_list = ['item', 'value', 'comment']
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ServerAdmin(ServerBase, Singleton):
|
|
54
|
+
"""
|
|
55
|
+
Server admin type, singleton mode.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def __init__(self, server: 'rserver.Server') -> None:
|
|
60
|
+
"""
|
|
61
|
+
Build instance attributes.
|
|
62
|
+
|
|
63
|
+
Parameters
|
|
64
|
+
----------
|
|
65
|
+
server : Server.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
# Build.
|
|
69
|
+
self.server = server
|
|
70
|
+
|
|
71
|
+
## Admin.
|
|
72
|
+
self.api_admin_binds: dict[ServerAdminModel, DatabaseEngineAsync] = {}
|
|
73
|
+
'Admin API model bind database engine dictionary.'
|
|
74
|
+
Session = async_sessionmaker()
|
|
75
|
+
Session.configure(binds=self.api_admin_binds)
|
|
76
|
+
self.admin = Admin(self.server.app, session_maker=Session)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def add_model(
|
|
80
|
+
self,
|
|
81
|
+
model: Type[ServerAdminModel] | type[rorm.Model],
|
|
82
|
+
engine: DatabaseEngineAsync | str = None,
|
|
83
|
+
label: str | None = None,
|
|
84
|
+
name: str | None = None,
|
|
85
|
+
column: str | Sequence[str] | None = None,
|
|
86
|
+
**attrs: Any
|
|
87
|
+
) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Add admin model type.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
model : Model type.
|
|
94
|
+
- `type[rorm.Model]`: Define as `ServerAdminModel`.
|
|
95
|
+
engine : Database engine or name.
|
|
96
|
+
label : Admin model class label.
|
|
97
|
+
name : Admin model name.
|
|
98
|
+
column : Admin model display column names.
|
|
99
|
+
attrs : Other admin model attributes.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
# Parameter.
|
|
103
|
+
if issubclass(model, rorm.Model):
|
|
104
|
+
class ServerAdminModel_(ServerAdminModel, model=model): ...
|
|
105
|
+
model = ServerAdminModel_
|
|
106
|
+
if type(engine) == str:
|
|
107
|
+
engine = self.server.db[engine]
|
|
108
|
+
if label is not None:
|
|
109
|
+
model.category = label
|
|
110
|
+
if name is not None:
|
|
111
|
+
model.name = model.name_plural = name
|
|
112
|
+
if type(column) == str:
|
|
113
|
+
column = [column]
|
|
114
|
+
if column is not None:
|
|
115
|
+
model.column_list = list(column)
|
|
116
|
+
for key, value in attrs.items():
|
|
117
|
+
setattr(model, key, value)
|
|
118
|
+
|
|
119
|
+
# Add.
|
|
120
|
+
self.api_admin_binds[model.model] = engine.engine
|
|
121
|
+
self.admin.add_view(model)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# Simple path.
|
|
125
|
+
|
|
126
|
+
## Server admin model type.
|
|
127
|
+
View = ServerAdminModelView
|
|
128
|
+
ViewStats = ServerAdminModelViewStats
|
reyserver/rall.py
CHANGED
reyserver/rauth.py
CHANGED
|
@@ -14,7 +14,7 @@ from datetime import datetime as Datetime
|
|
|
14
14
|
from fastapi import APIRouter, Request
|
|
15
15
|
from reydb import rorm, DatabaseEngine, DatabaseEngineAsync
|
|
16
16
|
from reykit.rdata import encode_jwt, is_hash_bcrypt
|
|
17
|
-
from reykit.rtime import now
|
|
17
|
+
from reykit.rtime import now
|
|
18
18
|
|
|
19
19
|
from .rbase import ServerConfig, Bind, exit_api
|
|
20
20
|
|
|
@@ -74,7 +74,10 @@ class DatabaseORMTablePerm(rorm.Table):
|
|
|
74
74
|
perm_id: int = rorm.Field(rorm.types_mysql.SMALLINT(unsigned=True), key_auto=True, comment='Permission ID.')
|
|
75
75
|
name: str = rorm.Field(rorm.types.VARCHAR(50), not_null=True, index_u=True, comment='Permission name.')
|
|
76
76
|
desc: str = rorm.Field(rorm.types.VARCHAR(500), comment='Permission description.')
|
|
77
|
-
api: str = rorm.Field(
|
|
77
|
+
api: str = rorm.Field(
|
|
78
|
+
rorm.types.VARCHAR(1000),
|
|
79
|
+
comment=r'API method and resource path regular expression "match" pattern, case insensitive, format is "{method} {path}" (e.g. "GET /users").'
|
|
80
|
+
)
|
|
78
81
|
|
|
79
82
|
|
|
80
83
|
class DatabaseORMTableUserRole(rorm.Table):
|
reyserver/rbase.py
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
from typing import NoReturn, overload
|
|
13
13
|
from http import HTTPStatus
|
|
14
|
-
from fastapi import HTTPException, UploadFile as File
|
|
14
|
+
from fastapi import HTTPException, Request, UploadFile as File
|
|
15
15
|
from fastapi.params import (
|
|
16
16
|
Depends,
|
|
17
17
|
Path,
|
|
@@ -148,13 +148,13 @@ class ServerBindInstanceDatabaseSuper(ServerBase):
|
|
|
148
148
|
|
|
149
149
|
class ServerBindInstanceDatabaseConnection(ServerBindInstanceDatabaseSuper, Singleton):
|
|
150
150
|
"""
|
|
151
|
-
Server API bind parameter build database connection instance type.
|
|
151
|
+
Server API bind parameter build database connection instance type, singleton mode.
|
|
152
152
|
"""
|
|
153
153
|
|
|
154
154
|
|
|
155
155
|
class ServerBindInstanceDatabaseSession(ServerBindInstanceDatabaseSuper, Singleton):
|
|
156
156
|
"""
|
|
157
|
-
Server API bind parameter build database session instance type.
|
|
157
|
+
Server API bind parameter build database session instance type, singleton mode.
|
|
158
158
|
"""
|
|
159
159
|
|
|
160
160
|
|
|
@@ -325,7 +325,7 @@ class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
|
325
325
|
Server API bind parameter type.
|
|
326
326
|
"""
|
|
327
327
|
|
|
328
|
-
|
|
328
|
+
Request = Request
|
|
329
329
|
Path = Path
|
|
330
330
|
Query = Query
|
|
331
331
|
Header = Header
|
|
@@ -334,6 +334,7 @@ class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
|
334
334
|
Form = Form
|
|
335
335
|
Forms = Forms
|
|
336
336
|
File = File
|
|
337
|
+
Depend = Depends
|
|
337
338
|
JSON = DatabaseORMModel
|
|
338
339
|
Conn = DatabaseConnectionAsync
|
|
339
340
|
Sess = DatabaseORMSessionAsync
|
reyserver/rclient.py
CHANGED
reyserver/rserver.py
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
from typing import Literal
|
|
12
|
+
from typing import Any, Literal, Type
|
|
13
13
|
from collections.abc import Sequence, Callable, Coroutine
|
|
14
14
|
from inspect import iscoroutinefunction
|
|
15
15
|
from contextlib import asynccontextmanager, _AsyncGeneratorContextManager
|
|
@@ -19,11 +19,12 @@ from fastapi import FastAPI, Request
|
|
|
19
19
|
from fastapi.staticfiles import StaticFiles
|
|
20
20
|
from fastapi.middleware.gzip import GZipMiddleware
|
|
21
21
|
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
|
|
22
|
-
from reydb import DatabaseAsync
|
|
22
|
+
from reydb import rorm, DatabaseAsync, DatabaseEngineAsync
|
|
23
23
|
from reykit.rbase import CoroutineFunctionSimple, Singleton, throw
|
|
24
24
|
from reykit.rrand import randchar
|
|
25
25
|
|
|
26
26
|
from .rbase import ServerBase, ServerConfig, Bind
|
|
27
|
+
from . import radmin
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
__all__ = (
|
|
@@ -261,6 +262,46 @@ class Server(ServerBase, Singleton):
|
|
|
261
262
|
setattr(self.app, key, value)
|
|
262
263
|
|
|
263
264
|
|
|
265
|
+
def add_api_admin(self) -> None:
|
|
266
|
+
"""
|
|
267
|
+
Add admin API.
|
|
268
|
+
"""
|
|
269
|
+
|
|
270
|
+
# Add.
|
|
271
|
+
self.admin = radmin.ServerAdmin(self)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def add_admin_model(
|
|
275
|
+
self,
|
|
276
|
+
model: Type['radmin.ServerAdminModel'] | type[rorm.Model],
|
|
277
|
+
engine: DatabaseEngineAsync | str = None,
|
|
278
|
+
label: str | None = None,
|
|
279
|
+
name: str | None = None,
|
|
280
|
+
column: str | Sequence[str] | None = None,
|
|
281
|
+
**attrs: Any
|
|
282
|
+
) -> None:
|
|
283
|
+
"""
|
|
284
|
+
Add admin model type.
|
|
285
|
+
|
|
286
|
+
Parameters
|
|
287
|
+
----------
|
|
288
|
+
model : Model type.
|
|
289
|
+
- `type[rorm.Model]`: Define as `ServerAdminModel`.
|
|
290
|
+
engine : Database engine or name.
|
|
291
|
+
label : Admin model class label.
|
|
292
|
+
name : Admin model name.
|
|
293
|
+
column : Admin model display column names.
|
|
294
|
+
attrs : Other admin model attributes.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
# Check.
|
|
298
|
+
if not hasattr(self, 'admin'):
|
|
299
|
+
return
|
|
300
|
+
|
|
301
|
+
# Add.
|
|
302
|
+
self.admin.add_model(model, engine, label, name, column, **attrs)
|
|
303
|
+
|
|
304
|
+
|
|
264
305
|
def add_api_auth(self, key: str | None = None, sess_seconds: int = 28800) -> None:
|
|
265
306
|
"""
|
|
266
307
|
Add authentication API.
|
|
@@ -273,13 +314,23 @@ class Server(ServerBase, Singleton):
|
|
|
273
314
|
sess_seconds : Session valid seconds.
|
|
274
315
|
"""
|
|
275
316
|
|
|
276
|
-
from .rauth import
|
|
317
|
+
from .rauth import (
|
|
318
|
+
build_auth_db,
|
|
319
|
+
auth_router,
|
|
320
|
+
DatabaseORMTableUser,
|
|
321
|
+
DatabaseORMTableRole,
|
|
322
|
+
DatabaseORMTablePerm,
|
|
323
|
+
DatabaseORMTableUserRole,
|
|
324
|
+
DatabaseORMTableRolePerm
|
|
325
|
+
)
|
|
277
326
|
|
|
278
327
|
# Parameter.
|
|
279
328
|
if key is None:
|
|
280
329
|
key = randchar(32)
|
|
281
330
|
|
|
282
|
-
#
|
|
331
|
+
# Database.
|
|
332
|
+
if 'auth' not in self.db:
|
|
333
|
+
throw(AssertionError, self.db)
|
|
283
334
|
engine = self.db.auth
|
|
284
335
|
build_auth_db(engine)
|
|
285
336
|
|
|
@@ -288,6 +339,13 @@ class Server(ServerBase, Singleton):
|
|
|
288
339
|
self.api_auth_sess_seconds = sess_seconds
|
|
289
340
|
self.app.include_router(auth_router, tags=['auth'])
|
|
290
341
|
|
|
342
|
+
## Admin.
|
|
343
|
+
self.add_admin_model(DatabaseORMTableUser, engine, category='auth', name='User', column_list=['user_id', 'name'])
|
|
344
|
+
self.add_admin_model(DatabaseORMTableRole, engine, category='auth', name='Role', column_list=['role_id', 'name'])
|
|
345
|
+
self.add_admin_model(DatabaseORMTablePerm, engine, category='auth', name='Perm', column_list=['perm_id', 'name'])
|
|
346
|
+
self.add_admin_model(DatabaseORMTableUserRole, engine, category='auth', name='User Role')
|
|
347
|
+
self.add_admin_model(DatabaseORMTableRolePerm, engine, category='auth', name='Role Perm')
|
|
348
|
+
|
|
291
349
|
|
|
292
350
|
def add_api_file(self, file_dir: str = 'file') -> None:
|
|
293
351
|
"""
|
|
@@ -300,12 +358,23 @@ class Server(ServerBase, Singleton):
|
|
|
300
358
|
prefix : File API path prefix.
|
|
301
359
|
"""
|
|
302
360
|
|
|
303
|
-
from .rfile import
|
|
361
|
+
from .rfile import (
|
|
362
|
+
build_file_db,
|
|
363
|
+
file_router,
|
|
364
|
+
DatabaseORMTableInfo,
|
|
365
|
+
DatabaseORMTableData
|
|
366
|
+
)
|
|
304
367
|
|
|
305
|
-
#
|
|
368
|
+
# Database.
|
|
369
|
+
if 'file' not in self.db:
|
|
370
|
+
throw(AssertionError, self.db)
|
|
306
371
|
engine = self.db.file
|
|
307
372
|
build_file_db(engine)
|
|
308
373
|
|
|
309
374
|
# Add.
|
|
310
375
|
self.api_file_dir = file_dir
|
|
311
376
|
self.app.include_router(file_router, tags=['file'])
|
|
377
|
+
|
|
378
|
+
## Admin.
|
|
379
|
+
self.add_admin_model(DatabaseORMTableInfo, engine, category='file', name='Info', column_list=['file_id', 'name'])
|
|
380
|
+
self.add_admin_model(DatabaseORMTableData, engine, category='file', name='Data')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reyserver
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.57
|
|
4
4
|
Summary: Backend server method set.
|
|
5
5
|
Project-URL: homepage, https://github.com/reyxbo/reyserver/
|
|
6
6
|
Author-email: Rey <reyxbo@163.com>
|
|
@@ -15,11 +15,10 @@ License-File: LICENSE
|
|
|
15
15
|
Keywords: API,async,asynchronous,backend,rey,reyxbo,server
|
|
16
16
|
Requires-Python: >=3.12
|
|
17
17
|
Requires-Dist: email-validator
|
|
18
|
-
Requires-Dist: fastapi
|
|
19
|
-
Requires-Dist: python-multipart
|
|
18
|
+
Requires-Dist: fastapi[standard]
|
|
20
19
|
Requires-Dist: reydb
|
|
21
20
|
Requires-Dist: reykit
|
|
22
|
-
Requires-Dist: sqladmin
|
|
21
|
+
Requires-Dist: sqladmin[full]
|
|
23
22
|
Requires-Dist: uvicorn[standard]
|
|
24
23
|
Description-Content-Type: text/markdown
|
|
25
24
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
reyserver/__init__.py,sha256=Oq-lOcQInzhgKt1_4OB2jNx0OO2d9qZg9iZqUx6YRr8,398
|
|
2
|
+
reyserver/radmin.py,sha256=Hwy8QsiQOyK2YP7abcS22IbRKB7sgcDGPHQ2-mHtf-8,3269
|
|
3
|
+
reyserver/rall.py,sha256=MI1NnqUpq22CK9w3XPPBS0K8lNuf0BnbI0pn4MGMx38,293
|
|
4
|
+
reyserver/rauth.py,sha256=5zQwi7eGjhHD2BHGQDQclLCn3HHg646Q4Cp2Bt6i3uc,11701
|
|
5
|
+
reyserver/rbase.py,sha256=_bP_suBPF7dLd4RNKn96-X4ZAEx3vAjMS6vnheCokU4,6617
|
|
6
|
+
reyserver/rclient.py,sha256=Ffm66YuWupzEtQ6RqEm2KCc6jSF8JeMB7Xq6pzRFZ6M,5073
|
|
7
|
+
reyserver/rfile.py,sha256=CH2uJbBNmBH9ISDirn1LWL5wsjGW5xjB9ZIrdc5UzL0,8864
|
|
8
|
+
reyserver/rserver.py,sha256=9-bhgVn_XZ6bvBl4GLdGkUs4UR1TSG08WC3F6ETQo7M,10986
|
|
9
|
+
reyserver-1.1.57.dist-info/METADATA,sha256=xNQ5RW2H-ittdf-DEkYv5nIuWSwnX2xH_jKrIDkXp4k,1697
|
|
10
|
+
reyserver-1.1.57.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
+
reyserver-1.1.57.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
12
|
+
reyserver-1.1.57.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
reyserver/__init__.py,sha256=7GX64p7uI2eetJH9NJ-DTg-8iyQwOsGcviADFJCPxVA,373
|
|
2
|
-
reyserver/rall.py,sha256=riyDRTUsigco_Bee1H4aZFb8IgvjnxdX9qcnVb9i9mE,270
|
|
3
|
-
reyserver/rauth.py,sha256=pOkA7E4W31Ii8iCLkhhcoL5-ge9cFq7lMYxQtLYvQbg,11606
|
|
4
|
-
reyserver/rbase.py,sha256=WbL2W6nc2jbkDumiXWrb25TaAhT-9xAI4wE0e_2prtg,6553
|
|
5
|
-
reyserver/rclient.py,sha256=IWZ3smyIP0_YJrfSrM8JFCr0FCtN02AyT3hp8YuSsDQ,5103
|
|
6
|
-
reyserver/rfile.py,sha256=CH2uJbBNmBH9ISDirn1LWL5wsjGW5xjB9ZIrdc5UzL0,8864
|
|
7
|
-
reyserver/rserver.py,sha256=0lCvaac7N-A25vbrNAbQKQoWFqvxMNlHtMfnoVoGX0I,8563
|
|
8
|
-
reyserver-1.1.56.dist-info/METADATA,sha256=M5Ocw__l3_sN1Pso7TryMu2505S-B82fOJ7uevyOIN0,1713
|
|
9
|
-
reyserver-1.1.56.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
-
reyserver-1.1.56.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
11
|
-
reyserver-1.1.56.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|