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 CHANGED
@@ -9,6 +9,7 @@
9
9
 
10
10
  Modules
11
11
  -------
12
+ radmin : Admin methods.
12
13
  rall : All methods.
13
14
  rauth : Authentication methods.
14
15
  rbase : Base methods.
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
@@ -9,6 +9,7 @@
9
9
  """
10
10
 
11
11
 
12
+ from .radmin import *
12
13
  from .rauth import *
13
14
  from .rbase import *
14
15
  from .rclient import *
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, time_to
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(rorm.types.VARCHAR(1000), comment='API resource path regular expression "match" pattern.')
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
- Depend = Depends
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
@@ -75,7 +75,6 @@ class ServerClient(ServerBase):
75
75
  # Request.
76
76
  response = request(url, json=json, check=True)
77
77
  response_dict = response.json()
78
- print(response_dict)
79
78
  token = response_dict['token']
80
79
 
81
80
  return token
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 build_auth_db, auth_router
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
- # Build database.
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 build_file_db, file_router
361
+ from .rfile import (
362
+ build_file_db,
363
+ file_router,
364
+ DatabaseORMTableInfo,
365
+ DatabaseORMTableData
366
+ )
304
367
 
305
- # Build database.
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.56
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,,