reyserver 1.1.80__py3-none-any.whl → 1.1.82__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 +2 -0
- reyserver/rall.py +1 -0
- reyserver/rbase.py +12 -1
- reyserver/rbind.py +7 -3
- reyserver/rcache.py +116 -0
- reyserver/rclient.py +0 -3
- reyserver/rfile.py +2 -0
- reyserver/rserver.py +36 -8
- {reyserver-1.1.80.dist-info → reyserver-1.1.82.dist-info}/METADATA +2 -1
- reyserver-1.1.82.dist-info/RECORD +16 -0
- reyserver-1.1.80.dist-info/RECORD +0 -15
- {reyserver-1.1.80.dist-info → reyserver-1.1.82.dist-info}/WHEEL +0 -0
- {reyserver-1.1.80.dist-info → reyserver-1.1.82.dist-info}/licenses/LICENSE +0 -0
reyserver/__init__.py
CHANGED
reyserver/rall.py
CHANGED
reyserver/rbase.py
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
from typing import NoReturn
|
|
13
13
|
from http import HTTPStatus
|
|
14
14
|
from fastapi import HTTPException
|
|
15
|
+
from fastapi.params import Depends
|
|
15
16
|
from reykit.rbase import Base, Exit, throw
|
|
16
17
|
|
|
17
18
|
|
|
@@ -19,7 +20,8 @@ __all__ = (
|
|
|
19
20
|
'ServerBase',
|
|
20
21
|
'ServerExit',
|
|
21
22
|
'ServerExitAPI',
|
|
22
|
-
'exit_api'
|
|
23
|
+
'exit_api',
|
|
24
|
+
'depend_pass'
|
|
23
25
|
)
|
|
24
26
|
|
|
25
27
|
|
|
@@ -61,3 +63,12 @@ def exit_api(code: int = 400, text: str | None = None) -> NoReturn:
|
|
|
61
63
|
|
|
62
64
|
# Throw exception.
|
|
63
65
|
raise ServerExitAPI(code, text)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def depend_pass_func() -> None:
|
|
69
|
+
"""
|
|
70
|
+
Depend pass.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
depend_pass = Depends(depend_pass_func)
|
reyserver/rbind.py
CHANGED
|
@@ -23,10 +23,10 @@ from fastapi.params import (
|
|
|
23
23
|
)
|
|
24
24
|
from reydb.rconn import DatabaseConnectionAsync
|
|
25
25
|
from reydb.rorm import DatabaseORMSessionAsync
|
|
26
|
-
from reykit.rbase import StaticMeta, Singleton
|
|
26
|
+
from reykit.rbase import StaticMeta, Singleton, throw
|
|
27
27
|
|
|
28
28
|
from . import rserver
|
|
29
|
-
from .rbase import ServerBase
|
|
29
|
+
from .rbase import ServerBase, depend_pass
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
__all__ = (
|
|
@@ -67,6 +67,10 @@ class ServerBindInstanceDatabaseSuper(ServerBase):
|
|
|
67
67
|
Dependencie function of asynchronous database.
|
|
68
68
|
"""
|
|
69
69
|
|
|
70
|
+
# Check.
|
|
71
|
+
if server.db is None:
|
|
72
|
+
throw(TypeError, server.db)
|
|
73
|
+
|
|
70
74
|
# Parameter.
|
|
71
75
|
engine = server.db[name]
|
|
72
76
|
|
|
@@ -324,7 +328,7 @@ class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
|
324
328
|
'Server API bind parameter asynchronous database connection.'
|
|
325
329
|
sess = ServerBindInstanceDatabaseSession()
|
|
326
330
|
'Server API bind parameter asynchronous database session.'
|
|
327
|
-
token: Depend
|
|
331
|
+
token: Depend = depend_pass
|
|
328
332
|
'Server authentication token dependency type.'
|
|
329
333
|
|
|
330
334
|
|
reyserver/rcache.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
@Time : 2025-10-25
|
|
6
|
+
@Author : Rey
|
|
7
|
+
@Contact : reyxbo@163.com
|
|
8
|
+
@Explain : Cache methods.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
from collections.abc import Callable
|
|
14
|
+
from inspect import iscoroutinefunction
|
|
15
|
+
from fastapi import Request, Response
|
|
16
|
+
from fastapi_cache import FastAPICache
|
|
17
|
+
from fastapi_cache.coder import PickleCoder
|
|
18
|
+
from fastapi_cache.backends.redis import RedisBackend
|
|
19
|
+
from fastapi_cache.decorator import cache as fastapi_cache_cache
|
|
20
|
+
from redis.asyncio import Redis
|
|
21
|
+
from reykit.rbase import CallableT
|
|
22
|
+
from reykit.ros import get_md5
|
|
23
|
+
from reykit.rre import sub
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
__all__ = (
|
|
27
|
+
'init_cache',
|
|
28
|
+
'wrap_cache'
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def init_cache(redis: Redis, redis_expire: int | None = None) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Initialize cache based on Redis.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
redis : Asynchronous Redis
|
|
39
|
+
redis_expire : Redis cache expire seconds.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def key_builder(
|
|
44
|
+
func: Callable,
|
|
45
|
+
namespace: str,
|
|
46
|
+
request: Request | None,
|
|
47
|
+
response: Response | None,
|
|
48
|
+
args: tuple,
|
|
49
|
+
kwargs: dict[str, Any],
|
|
50
|
+
) -> str:
|
|
51
|
+
"""
|
|
52
|
+
Cache key builder.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
func : Decorated function.
|
|
57
|
+
namespace : Cache key prefix.
|
|
58
|
+
request : API Request.
|
|
59
|
+
response : API response.
|
|
60
|
+
args : Position arguments of decorated function.
|
|
61
|
+
kwargs : Keyword arguments of decorated function.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
# Parameter.
|
|
65
|
+
data = f'{func.__module__}:{func.__name__}:{args}:{kwargs}'
|
|
66
|
+
pattern = r' object at 0x[0-9a-fA-F]+>'
|
|
67
|
+
data = sub(pattern, data, '>')
|
|
68
|
+
|
|
69
|
+
# Build.
|
|
70
|
+
key = get_md5(data)
|
|
71
|
+
|
|
72
|
+
return key
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# Initialize.
|
|
76
|
+
backend = RedisBackend(redis)
|
|
77
|
+
FastAPICache.init(
|
|
78
|
+
backend,
|
|
79
|
+
expire=redis_expire,
|
|
80
|
+
coder=PickleCoder,
|
|
81
|
+
key_builder=key_builder
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def wrap_cache(func_or_expire: CallableT | int | None = None) -> CallableT | Callable[[CallableT], CallableT]:
|
|
86
|
+
"""
|
|
87
|
+
Decorator, use Redis cache.
|
|
88
|
+
When Redis is not set, then skip.
|
|
89
|
+
|
|
90
|
+
Parameters
|
|
91
|
+
----------
|
|
92
|
+
func_or_expire : Decorated function or Redis cache expire seconds.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
Decorated function or decorator.
|
|
97
|
+
|
|
98
|
+
Examples
|
|
99
|
+
--------
|
|
100
|
+
No parameter.
|
|
101
|
+
>>> @wrap_cache
|
|
102
|
+
>>> def foo(): ...
|
|
103
|
+
|
|
104
|
+
Set parameter.
|
|
105
|
+
>>> @wrap_cache(60)
|
|
106
|
+
>>> def foo(): ...
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
# Decorate.
|
|
110
|
+
if callable(func_or_expire):
|
|
111
|
+
decorator = fastapi_cache_cache()
|
|
112
|
+
func = decorator(func_or_expire)
|
|
113
|
+
return func
|
|
114
|
+
else:
|
|
115
|
+
decorator = fastapi_cache_cache(func_or_expire)
|
|
116
|
+
return decorator
|
reyserver/rclient.py
CHANGED
reyserver/rfile.py
CHANGED
|
@@ -16,6 +16,7 @@ from reykit.ros import get_md5
|
|
|
16
16
|
|
|
17
17
|
from .rbase import exit_api
|
|
18
18
|
from .rbind import Bind
|
|
19
|
+
from .rcache import wrap_cache
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
__all__ = (
|
|
@@ -182,6 +183,7 @@ router_file = APIRouter()
|
|
|
182
183
|
|
|
183
184
|
|
|
184
185
|
@router_file.get('/files/{file_id}')
|
|
186
|
+
@wrap_cache
|
|
185
187
|
async def get_file_info(
|
|
186
188
|
file_id: int = Bind.i.path,
|
|
187
189
|
sess: Bind.Sess = Bind.sess.file
|
reyserver/rserver.py
CHANGED
|
@@ -20,6 +20,8 @@ from fastapi.staticfiles import StaticFiles
|
|
|
20
20
|
from fastapi.middleware.gzip import GZipMiddleware
|
|
21
21
|
from fastapi.middleware.trustedhost import TrustedHostMiddleware
|
|
22
22
|
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
|
|
23
|
+
from fastapi_cache import FastAPICache
|
|
24
|
+
from redis.asyncio import Redis
|
|
23
25
|
from reydb import DatabaseAsync
|
|
24
26
|
from reykit.rbase import CoroutineFunctionSimple, Singleton, throw
|
|
25
27
|
from reykit.ros import FileStore
|
|
@@ -27,6 +29,7 @@ from reykit.rrand import randchar
|
|
|
27
29
|
|
|
28
30
|
from .rbase import ServerBase
|
|
29
31
|
from .rbind import Bind
|
|
32
|
+
from .rcache import init_cache
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
__all__ = (
|
|
@@ -59,6 +62,8 @@ class Server(ServerBase, Singleton):
|
|
|
59
62
|
self,
|
|
60
63
|
db: DatabaseAsync | None = None,
|
|
61
64
|
db_warm: bool = False,
|
|
65
|
+
redis: Redis | None = None,
|
|
66
|
+
redis_expire: int | None = None,
|
|
62
67
|
depend: CoroutineFunctionSimple | Sequence[CoroutineFunctionSimple] | None = None,
|
|
63
68
|
before: CoroutineFunctionSimple | Sequence[CoroutineFunctionSimple] | None = None,
|
|
64
69
|
after: CoroutineFunctionSimple | Sequence[CoroutineFunctionSimple] | None = None,
|
|
@@ -70,8 +75,10 @@ class Server(ServerBase, Singleton):
|
|
|
70
75
|
|
|
71
76
|
Parameters
|
|
72
77
|
----------
|
|
73
|
-
db : Asynchronous database,
|
|
78
|
+
db : Asynchronous database, include database engines required for APIs.
|
|
74
79
|
db_warm : Whether database pre create connection to warm all pool.
|
|
80
|
+
redis : Asynchronous Redis, activate cache function.
|
|
81
|
+
redis_expire : Redis cache expire seconds.
|
|
75
82
|
depend : Global api dependencies.
|
|
76
83
|
before : Execute before server start.
|
|
77
84
|
after : Execute after server end.
|
|
@@ -88,10 +95,16 @@ class Server(ServerBase, Singleton):
|
|
|
88
95
|
Bind.Depend(task)
|
|
89
96
|
for task in depend
|
|
90
97
|
]
|
|
91
|
-
lifespan = self.__create_lifespan(
|
|
98
|
+
lifespan = self.__create_lifespan(
|
|
99
|
+
before,
|
|
100
|
+
after,
|
|
101
|
+
db_warm,
|
|
102
|
+
redis_expire
|
|
103
|
+
)
|
|
92
104
|
|
|
93
105
|
# Build.
|
|
94
106
|
self.db = db
|
|
107
|
+
self.redis = redis
|
|
95
108
|
self.app = FastAPI(
|
|
96
109
|
dependencies=depend,
|
|
97
110
|
lifespan=lifespan,
|
|
@@ -113,7 +126,8 @@ class Server(ServerBase, Singleton):
|
|
|
113
126
|
self,
|
|
114
127
|
before: CoroutineFunctionSimple | Sequence[CoroutineFunctionSimple] | None,
|
|
115
128
|
after: CoroutineFunctionSimple | Sequence[CoroutineFunctionSimple] | None,
|
|
116
|
-
db_warm: bool
|
|
129
|
+
db_warm: bool,
|
|
130
|
+
redis_expire: int | None
|
|
117
131
|
) -> _AsyncGeneratorContextManager[None, None]:
|
|
118
132
|
"""
|
|
119
133
|
Create asynchronous function of lifespan manager.
|
|
@@ -123,6 +137,7 @@ class Server(ServerBase, Singleton):
|
|
|
123
137
|
before : Execute before server start.
|
|
124
138
|
after : Execute after server end.
|
|
125
139
|
db_warm : Whether database pre create connection to warm all pool.
|
|
140
|
+
redis_expire : Redis cache expire seconds.
|
|
126
141
|
|
|
127
142
|
Returns
|
|
128
143
|
-------
|
|
@@ -158,6 +173,12 @@ class Server(ServerBase, Singleton):
|
|
|
158
173
|
if db_warm:
|
|
159
174
|
await self.db.warm_all()
|
|
160
175
|
|
|
176
|
+
## Redis.
|
|
177
|
+
if self.redis is not None:
|
|
178
|
+
init_cache(self.redis, redis_expire)
|
|
179
|
+
else:
|
|
180
|
+
FastAPICache._enable = False
|
|
181
|
+
|
|
161
182
|
# Runing.
|
|
162
183
|
yield
|
|
163
184
|
|
|
@@ -166,7 +187,8 @@ class Server(ServerBase, Singleton):
|
|
|
166
187
|
await after()
|
|
167
188
|
|
|
168
189
|
## Database.
|
|
169
|
-
|
|
190
|
+
if self.db is not None:
|
|
191
|
+
await self.db.dispose_all()
|
|
170
192
|
|
|
171
193
|
|
|
172
194
|
return lifespan
|
|
@@ -370,8 +392,11 @@ class Server(ServerBase, Singleton):
|
|
|
370
392
|
key = randchar(32)
|
|
371
393
|
|
|
372
394
|
# Database.
|
|
373
|
-
if
|
|
374
|
-
|
|
395
|
+
if (
|
|
396
|
+
self.db is None
|
|
397
|
+
or 'auth' not in self.db
|
|
398
|
+
):
|
|
399
|
+
throw(TypeError, self.db)
|
|
375
400
|
engine = self.db.auth
|
|
376
401
|
build_db_auth(engine)
|
|
377
402
|
|
|
@@ -395,8 +420,11 @@ class Server(ServerBase, Singleton):
|
|
|
395
420
|
from .rfile import build_db_file, router_file
|
|
396
421
|
|
|
397
422
|
# Database.
|
|
398
|
-
if
|
|
399
|
-
|
|
423
|
+
if (
|
|
424
|
+
self.db is None
|
|
425
|
+
or 'file' not in self.db
|
|
426
|
+
):
|
|
427
|
+
throw(TypeError, self.db)
|
|
400
428
|
engine = self.db.file
|
|
401
429
|
build_db_file(engine)
|
|
402
430
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reyserver
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.82
|
|
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>
|
|
@@ -14,6 +14,7 @@ License: Copyright 2025 ReyXBo
|
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Keywords: API,async,asynchronous,backend,rey,reyxbo,server
|
|
16
16
|
Requires-Python: >=3.12
|
|
17
|
+
Requires-Dist: fastapi-cache2[redis]
|
|
17
18
|
Requires-Dist: fastapi[standard]
|
|
18
19
|
Requires-Dist: reydb
|
|
19
20
|
Requires-Dist: reykit
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
reyserver/__init__.py,sha256=WnSqy03gZLHltfWe7bbg-q8-z-fn9UF9tokkXTc3ycI,513
|
|
2
|
+
reyserver/rall.py,sha256=ZK-Dn7wmG_GkiCefN7Fx5UJ3r8w_1gJ7OhyPP8__M0s,387
|
|
3
|
+
reyserver/rauth.py,sha256=7mANcRcbJ3e4u0PDSMquBeCWKchHbmVeFOVv7syU7Q0,15236
|
|
4
|
+
reyserver/rbase.py,sha256=JVgFso6Aohow1sEgZCH83xB90sriZPv6DHlNwGTfOhw,1314
|
|
5
|
+
reyserver/rbind.py,sha256=zGXRzKWbhhFNJIdAj-cqO307fVhs3yzDBAKnAy2ixt4,6930
|
|
6
|
+
reyserver/rcache.py,sha256=DLNea4gcLKjh3pkuI2A9aDV0lNtw6dzWuREGzptS1wk,2756
|
|
7
|
+
reyserver/rclient.py,sha256=s2uXigkSnpzdkQ_nLroyDvwo9XyHbxUFHVHUn_Z5QzU,6234
|
|
8
|
+
reyserver/rfile.py,sha256=_-MGyIst3jzUheYOhhJUYvw8Ed20rD660za0pTgKypg,8936
|
|
9
|
+
reyserver/rpublic.py,sha256=ixKDWdDihdVQ8Pqjpril7veJ9kkFK9yiRm8CTwmck4Q,1095
|
|
10
|
+
reyserver/rredirect.py,sha256=c7wgXn5UeF53irMlbJ8vctec2KEc3DuHhBOa8NBoFjA,857
|
|
11
|
+
reyserver/rserver.py,sha256=BUpP0U0ycZO6z_OTa1QYlK1RaLJCIQ_UVApKO7YHYEQ,12153
|
|
12
|
+
reyserver/rtest.py,sha256=MPYsyRzO3mZL5LJfUeBY1cafXvDsT2BGqoXq49wmJeo,777
|
|
13
|
+
reyserver-1.1.82.dist-info/METADATA,sha256=k2nB0e9XO19xvqda0eNp5pkOaMepmk-plcCunD0zZOk,1703
|
|
14
|
+
reyserver-1.1.82.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
15
|
+
reyserver-1.1.82.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
16
|
+
reyserver-1.1.82.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
reyserver/__init__.py,sha256=iT5IWIBDvaeYvxs0HuV6mZfN2D0G4xkb_0DhX-VpsDk,454
|
|
2
|
-
reyserver/rall.py,sha256=a3e8o1wtV_wBlR2m-df94SQ7TakC9-jPUoxNZfix1nM,364
|
|
3
|
-
reyserver/rauth.py,sha256=7mANcRcbJ3e4u0PDSMquBeCWKchHbmVeFOVv7syU7Q0,15236
|
|
4
|
-
reyserver/rbase.py,sha256=mq6ChIcxb8-RUZgYqJZ8LOa0XTr0d8VU-xVzhJ0q5AQ,1134
|
|
5
|
-
reyserver/rbind.py,sha256=QrRCT8p-2bwxxBQNZmFq4RAsVHs3_mRuobsbHo1Uc9M,6792
|
|
6
|
-
reyserver/rclient.py,sha256=Q-nU-knvvuyO7hHYnAvKteVkUhk26K4kGKVExrO8Kww,6290
|
|
7
|
-
reyserver/rfile.py,sha256=xudSM-bVRqzCvifCUTgiZwitPzPNe1KQ2GXLgHtu2zg,8891
|
|
8
|
-
reyserver/rpublic.py,sha256=ixKDWdDihdVQ8Pqjpril7veJ9kkFK9yiRm8CTwmck4Q,1095
|
|
9
|
-
reyserver/rredirect.py,sha256=c7wgXn5UeF53irMlbJ8vctec2KEc3DuHhBOa8NBoFjA,857
|
|
10
|
-
reyserver/rserver.py,sha256=GnsGTsjTUogIqY8o1onKzYqIAoGUSVXWnpxJoW7nvSg,11329
|
|
11
|
-
reyserver/rtest.py,sha256=MPYsyRzO3mZL5LJfUeBY1cafXvDsT2BGqoXq49wmJeo,777
|
|
12
|
-
reyserver-1.1.80.dist-info/METADATA,sha256=ZV5cAro5bMrbz0Aojifa_ApMY4LNVnciqYMrcsjfvvU,1666
|
|
13
|
-
reyserver-1.1.80.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
14
|
-
reyserver-1.1.80.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
15
|
-
reyserver-1.1.80.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|