reyserver 1.1.79__py3-none-any.whl → 1.1.81__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
@@ -12,6 +12,8 @@ Modules
12
12
  rall : All methods.
13
13
  rauth : Authentication methods.
14
14
  rbase : Base methods.
15
+ rbind : Dependency bind methods.
16
+ rcache : Cache methods.
15
17
  rclient : Client methods.
16
18
  rfile : File methods.
17
19
  rpublic : Public methods.
reyserver/rall.py CHANGED
@@ -12,6 +12,7 @@
12
12
  from .rauth import *
13
13
  from .rbase import *
14
14
  from .rbind import *
15
+ from .rcache import *
15
16
  from .rclient import *
16
17
  from .rfile import *
17
18
  from .rpublic import *
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-F]{8,16}+>'
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
@@ -118,7 +118,7 @@ class ServerClient(ServerBase):
118
118
  return response
119
119
 
120
120
  # Try request.
121
- self.token = self.create_session(self.username, self.password)
121
+ self.token = self.get_token(self.username, self.password)
122
122
  headers['Authorization'] = f'Bearer {self.token}'
123
123
  kwargs['check'] = True
124
124
  response = request(*args, **kwargs)
@@ -126,9 +126,6 @@ class ServerClient(ServerBase):
126
126
  return response
127
127
 
128
128
 
129
- # request = copy_type_hints(_request, request)
130
-
131
-
132
129
  def upload_file(
133
130
  self,
134
131
  source: str | bytes,
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, must include database engines with APIs.
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(before, after, db_warm)
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
- await self.db.dispose_all()
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 'auth' not in self.db:
374
- throw(AssertionError, self.db)
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 'file' not in self.db:
399
- throw(AssertionError, self.db)
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.79
3
+ Version: 1.1.81
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=v-NUA_VqIxZNPveKmJpnRU37cH6W-L_Vt5rhrjKz4mM,2759
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.81.dist-info/METADATA,sha256=1zQzR1DYgGCnspwK2EPuDUxVQhyYTdF7_SfQl_nYE9s,1703
14
+ reyserver-1.1.81.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
+ reyserver-1.1.81.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
16
+ reyserver-1.1.81.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=w79RJEjAfIlQatCeZZIlrGLH_A5vEw9HvpHp3a5bNYw,6295
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.79.dist-info/METADATA,sha256=rNMsd11WUSGw5uG_xhjC4oncl1V5Uh323zSfYrphCqs,1666
13
- reyserver-1.1.79.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
14
- reyserver-1.1.79.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
15
- reyserver-1.1.79.dist-info/RECORD,,