reyserver 1.1.50__py3-none-any.whl → 1.1.52__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.
- reyserver/rauth.py +70 -19
- reyserver/rbase.py +166 -30
- reyserver/rclient.py +38 -1
- reyserver/rfile.py +5 -5
- reyserver/rserver.py +11 -4
- {reyserver-1.1.50.dist-info → reyserver-1.1.52.dist-info}/METADATA +1 -1
- reyserver-1.1.52.dist-info/RECORD +11 -0
- reyserver-1.1.50.dist-info/RECORD +0 -11
- {reyserver-1.1.50.dist-info → reyserver-1.1.52.dist-info}/WHEEL +0 -0
- {reyserver-1.1.50.dist-info → reyserver-1.1.52.dist-info}/licenses/LICENSE +0 -0
reyserver/rauth.py
CHANGED
@@ -9,10 +9,12 @@
|
|
9
9
|
"""
|
10
10
|
|
11
11
|
|
12
|
+
from typing import Any, Literal
|
13
|
+
from datetime import datetime as Datetime
|
12
14
|
from fastapi import APIRouter
|
13
15
|
from reydb import rorm, DatabaseEngine, DatabaseEngineAsync
|
14
|
-
from reykit.rdata import encode_jwt,
|
15
|
-
from reykit.rtime import now
|
16
|
+
from reykit.rdata import encode_jwt, is_hash_bcrypt
|
17
|
+
from reykit.rtime import now, time_to
|
16
18
|
|
17
19
|
from .rbase import ServerConfig, Bind, exit_api
|
18
20
|
|
@@ -72,8 +74,7 @@ class DatabaseORMTablePerm(rorm.Model, table=True):
|
|
72
74
|
perm_id: int = rorm.Field(rorm.types_mysql.SMALLINT(unsigned=True), key_auto=True, comment='Permission ID.')
|
73
75
|
name: str = rorm.Field(rorm.types.VARCHAR(50), not_null=True, index_u=True, comment='Permission name.')
|
74
76
|
desc: str = rorm.Field(rorm.types.VARCHAR(500), comment='Permission description.')
|
75
|
-
|
76
|
-
path: str = rorm.Field(rorm.types.VARCHAR(1000), comment='API resource path regular expression "match" pattern.')
|
77
|
+
api: str = rorm.Field(rorm.types.VARCHAR(1000), comment='API resource path regular expression "match" pattern.')
|
77
78
|
|
78
79
|
|
79
80
|
class DatabaseORMTableUserRole(rorm.Model, table=True):
|
@@ -202,8 +203,9 @@ depend_auth_conn = Bind.create_depend_db('auth', 'conn')
|
|
202
203
|
|
203
204
|
@auth_router.post('/sessions')
|
204
205
|
async def create_sessions(
|
205
|
-
|
206
|
-
password: str = Bind.body,
|
206
|
+
account: str = Bind.i.body,
|
207
|
+
password: str = Bind.i.body,
|
208
|
+
account_type: Literal['name', 'email', 'phone'] = Bind.Body('name'),
|
207
209
|
conn: Bind.Conn = depend_auth_conn
|
208
210
|
) -> dict:
|
209
211
|
"""
|
@@ -211,8 +213,9 @@ async def create_sessions(
|
|
211
213
|
|
212
214
|
Parameters
|
213
215
|
----------
|
214
|
-
|
216
|
+
account : User account, name or email or phone.
|
215
217
|
password : User password.
|
218
|
+
account_type : User account type.
|
216
219
|
|
217
220
|
Returns
|
218
221
|
-------
|
@@ -221,30 +224,78 @@ async def create_sessions(
|
|
221
224
|
|
222
225
|
# Parameter.
|
223
226
|
key = ServerConfig.server.api_auth_key
|
224
|
-
|
227
|
+
sess_seconds = ServerConfig.server.api_auth_sess_seconds
|
225
228
|
|
226
229
|
# Check.
|
227
230
|
sql = (
|
228
|
-
''
|
231
|
+
'SELECT ANY_VALUE(`create_time`) AS `create_time`,\n'
|
232
|
+
' ANY_VALUE(`update_time`) AS `update_time`,\n'
|
233
|
+
' ANY_VALUE(`user`.`user_id`) AS `user_id`,\n'
|
234
|
+
' ANY_VALUE(`user`.`name`) AS `user_name`,\n'
|
235
|
+
' ANY_VALUE(`password`) AS `password`,\n'
|
236
|
+
' ANY_VALUE(`email`) AS `email`,\n'
|
237
|
+
' ANY_VALUE(`phone`) AS `phone`,\n'
|
238
|
+
' ANY_VALUE(`avatar`) AS `avatar`,\n'
|
239
|
+
" GROUP_CONCAT(DISTINCT `role`.`name` SEPARATOR ';') AS `role_names`,\n"
|
240
|
+
" GROUP_CONCAT(DISTINCT `perm`.`name` SEPARATOR ';') AS `perm_names`,\n"
|
241
|
+
" GROUP_CONCAT(DISTINCT `perm`.`api` SEPARATOR ';') AS `perm_apis`\n"
|
242
|
+
'FROM (\n'
|
243
|
+
' SELECT `create_time`, `update_time`, `user_id`, `password`, `name`, `email`, `phone`, `avatar`\n'
|
244
|
+
' FROM `test`.`user`\n'
|
245
|
+
f' WHERE `{account_type}` = :account\n'
|
246
|
+
' LIMIT 1\n'
|
247
|
+
') as `user`\n'
|
248
|
+
'LEFT JOIN (\n'
|
249
|
+
' SELECT `user_id`, `role_id`\n'
|
250
|
+
' FROM `test`.`user_role`\n'
|
251
|
+
') as `user_role`\n'
|
252
|
+
'ON `user_role`.`user_id` = `user`.`user_id`\n'
|
253
|
+
'LEFT JOIN (\n'
|
254
|
+
' SELECT `role_id`, `name`\n'
|
255
|
+
' FROM `test`.`role`\n'
|
256
|
+
') AS `role`\n'
|
257
|
+
'ON `user_role`.`role_id` = `role`.`role_id`\n'
|
258
|
+
'LEFT JOIN (\n'
|
259
|
+
' SELECT `role_id`, `perm_id`\n'
|
260
|
+
' FROM `test`.`role_perm`\n'
|
261
|
+
') as `role_perm`\n'
|
262
|
+
'ON `role_perm`.`role_id` = `role`.`role_id`\n'
|
263
|
+
'LEFT JOIN (\n'
|
264
|
+
" SELECT `perm_id`, `name`, CONCAT(`method`, ':', `path`) as `api`\n"
|
265
|
+
' FROM `test`.`perm`\n'
|
266
|
+
') AS `perm`\n'
|
267
|
+
'ON `role_perm`.`perm_id` = `perm`.`perm_id`\n'
|
268
|
+
'GROUP BY `user_id`'
|
229
269
|
)
|
230
270
|
result = await conn.execute(
|
231
271
|
sql,
|
232
|
-
|
233
|
-
password_hash=password_hash
|
272
|
+
account=account
|
234
273
|
)
|
235
274
|
|
236
275
|
# Check.
|
237
276
|
if result.empty:
|
238
277
|
exit_api(401)
|
278
|
+
json: dict[str, Datetime | Any] = result.to_row()
|
279
|
+
if not is_hash_bcrypt(password, json['password']):
|
280
|
+
exit_api(401)
|
239
281
|
|
240
|
-
#
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
282
|
+
# JWT.
|
283
|
+
now_timestamp_s = now('timestamp_s')
|
284
|
+
json['sub'] = json.pop('user_id')
|
285
|
+
json['iat'] = now_timestamp_s
|
286
|
+
json['nbf'] = now_timestamp_s
|
287
|
+
json['exp'] = now_timestamp_s + sess_seconds
|
288
|
+
json['role_names'] = json['role_names'].split(';')
|
289
|
+
json['perm_names'] = json['perm_names'].split(';')
|
290
|
+
perm_apis: list[str] = json['perm_apis'].split(';')
|
291
|
+
perm_api_dict = {}
|
292
|
+
for perm_api in perm_apis:
|
293
|
+
method, path = perm_api.split(':', 1)
|
294
|
+
paths: list = perm_api_dict.setdefault(method, [])
|
295
|
+
paths.append(path)
|
296
|
+
json['perm_apis'] = perm_api_dict
|
297
|
+
json['create_time'] = json['create_time'].timestamp()
|
298
|
+
json['update_time'] = json['update_time'].timestamp()
|
248
299
|
token = encode_jwt(json, key)
|
249
300
|
data = {'token': token}
|
250
301
|
|
reyserver/rbase.py
CHANGED
@@ -26,8 +26,7 @@ from fastapi.params import (
|
|
26
26
|
)
|
27
27
|
from reydb.rconn import DatabaseConnectionAsync
|
28
28
|
from reydb.rorm import DatabaseORMModel, DatabaseORMSessionAsync
|
29
|
-
from reykit.
|
30
|
-
from reykit.rbase import CoroutineFunctionSimple, Base, Exit, StaticMeta, ConfigMeta, throw
|
29
|
+
from reykit.rbase import CoroutineFunctionSimple, Base, Exit, StaticMeta, ConfigMeta, Singleton, throw
|
31
30
|
|
32
31
|
from . import rserver
|
33
32
|
|
@@ -38,7 +37,8 @@ __all__ = (
|
|
38
37
|
'ServerExit',
|
39
38
|
'ServerExitAPI',
|
40
39
|
'exit_api',
|
41
|
-
'ServerBind'
|
40
|
+
'ServerBind',
|
41
|
+
'Bind'
|
42
42
|
)
|
43
43
|
|
44
44
|
|
@@ -91,6 +91,168 @@ def exit_api(code: int = 400, text: str | None = None) -> NoReturn:
|
|
91
91
|
raise ServerExitAPI(code, text)
|
92
92
|
|
93
93
|
|
94
|
+
class ServerBindInstance(ServerBase, Singleton):
|
95
|
+
"""
|
96
|
+
Server API bind parameter build instance type.
|
97
|
+
"""
|
98
|
+
|
99
|
+
|
100
|
+
@property
|
101
|
+
def path(self) -> Path:
|
102
|
+
"""
|
103
|
+
Path instance.
|
104
|
+
"""
|
105
|
+
|
106
|
+
# Build.
|
107
|
+
path = Path()
|
108
|
+
|
109
|
+
return path
|
110
|
+
|
111
|
+
|
112
|
+
@property
|
113
|
+
def query(self) -> Query:
|
114
|
+
"""
|
115
|
+
Query instance.
|
116
|
+
"""
|
117
|
+
|
118
|
+
# Build.
|
119
|
+
query = Query()
|
120
|
+
|
121
|
+
return query
|
122
|
+
|
123
|
+
|
124
|
+
@property
|
125
|
+
def header(self) -> Header:
|
126
|
+
"""
|
127
|
+
Header instance.
|
128
|
+
"""
|
129
|
+
|
130
|
+
# Build.
|
131
|
+
header = Header()
|
132
|
+
|
133
|
+
return header
|
134
|
+
|
135
|
+
|
136
|
+
@property
|
137
|
+
def cookie(self) -> Cookie:
|
138
|
+
"""
|
139
|
+
Cookie instance.
|
140
|
+
"""
|
141
|
+
|
142
|
+
# Build.
|
143
|
+
cookie = Cookie()
|
144
|
+
|
145
|
+
return cookie
|
146
|
+
|
147
|
+
|
148
|
+
@property
|
149
|
+
def body(self) -> Body:
|
150
|
+
"""
|
151
|
+
Body instance.
|
152
|
+
"""
|
153
|
+
|
154
|
+
# Build.
|
155
|
+
body = Body()
|
156
|
+
|
157
|
+
return body
|
158
|
+
|
159
|
+
|
160
|
+
@property
|
161
|
+
def form(self) -> Form:
|
162
|
+
"""
|
163
|
+
Form instance.
|
164
|
+
"""
|
165
|
+
|
166
|
+
# Build.
|
167
|
+
form = Form()
|
168
|
+
|
169
|
+
return form
|
170
|
+
|
171
|
+
|
172
|
+
@property
|
173
|
+
def forms(self) -> Forms:
|
174
|
+
"""
|
175
|
+
Forms instance.
|
176
|
+
"""
|
177
|
+
|
178
|
+
# Build.
|
179
|
+
forms = Forms()
|
180
|
+
|
181
|
+
return forms
|
182
|
+
|
183
|
+
|
184
|
+
@property
|
185
|
+
def query_n(self) -> Query:
|
186
|
+
"""
|
187
|
+
Query instance, default `None`.
|
188
|
+
"""
|
189
|
+
|
190
|
+
# Build.
|
191
|
+
query = Query(None)
|
192
|
+
|
193
|
+
return query
|
194
|
+
|
195
|
+
|
196
|
+
@property
|
197
|
+
def header_n(self) -> Header:
|
198
|
+
"""
|
199
|
+
Header instance, default `None`.
|
200
|
+
"""
|
201
|
+
|
202
|
+
# Build.
|
203
|
+
header = Header(None)
|
204
|
+
|
205
|
+
return header
|
206
|
+
|
207
|
+
|
208
|
+
@property
|
209
|
+
def cookie_n(self) -> Cookie:
|
210
|
+
"""
|
211
|
+
Cookie instance, default `None`.
|
212
|
+
"""
|
213
|
+
|
214
|
+
# Build.
|
215
|
+
cookie = Cookie(None)
|
216
|
+
|
217
|
+
return cookie
|
218
|
+
|
219
|
+
|
220
|
+
@property
|
221
|
+
def body_n(self) -> Body:
|
222
|
+
"""
|
223
|
+
Body instance, default `None`.
|
224
|
+
"""
|
225
|
+
|
226
|
+
# Build.
|
227
|
+
body = Body(None)
|
228
|
+
|
229
|
+
return body
|
230
|
+
|
231
|
+
|
232
|
+
@property
|
233
|
+
def form_n(self) -> Form:
|
234
|
+
"""
|
235
|
+
Form instance, default `None`.
|
236
|
+
"""
|
237
|
+
|
238
|
+
# Build.
|
239
|
+
form = Form(None)
|
240
|
+
|
241
|
+
return form
|
242
|
+
|
243
|
+
|
244
|
+
@property
|
245
|
+
def forms_n(self) -> Forms:
|
246
|
+
"""
|
247
|
+
Forms instance, default `None`.
|
248
|
+
"""
|
249
|
+
|
250
|
+
# Build.
|
251
|
+
forms = Forms(None)
|
252
|
+
|
253
|
+
return forms
|
254
|
+
|
255
|
+
|
94
256
|
class ServerBind(ServerBase, metaclass=StaticMeta):
|
95
257
|
"""
|
96
258
|
Server API bind parameter type.
|
@@ -148,7 +310,6 @@ class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
148
310
|
return lifespan
|
149
311
|
|
150
312
|
|
151
|
-
@wrap_cache
|
152
313
|
def create_depend_db(database: str, mode: Literal['sess', 'conn']) -> Depends:
|
153
314
|
"""
|
154
315
|
Create dependencie type of asynchronous database.
|
@@ -201,32 +362,7 @@ class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
201
362
|
JSON = DatabaseORMModel
|
202
363
|
Conn = DatabaseConnectionAsync
|
203
364
|
Sess = DatabaseORMSessionAsync
|
204
|
-
|
205
|
-
'Path instance.'
|
206
|
-
query = Query()
|
207
|
-
'Query instance.'
|
208
|
-
header = Header()
|
209
|
-
'Header instance.'
|
210
|
-
cookie = Cookie()
|
211
|
-
'Cookie instance.'
|
212
|
-
body = Body()
|
213
|
-
'Body instance.'
|
214
|
-
form = Form()
|
215
|
-
'Form instance.'
|
216
|
-
forms = Forms()
|
217
|
-
'Forms instance.'
|
218
|
-
query_n = Query(None)
|
219
|
-
'Query instance, default `None`.'
|
220
|
-
header_n = Header(None)
|
221
|
-
'Header instance, default `None`.'
|
222
|
-
cookie_n = Cookie(None)
|
223
|
-
'Cookie instance, default `None`.'
|
224
|
-
body_n = Body(None)
|
225
|
-
'Body instance, default `None`.'
|
226
|
-
form_n = Form(None)
|
227
|
-
'Form instance, default `None`.'
|
228
|
-
forms_n = Forms(None)
|
229
|
-
'Forms instance, default `None`.'
|
365
|
+
i = ServerBindInstance()
|
230
366
|
|
231
367
|
|
232
368
|
Bind = ServerBind
|
reyserver/rclient.py
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
"""
|
10
10
|
|
11
11
|
|
12
|
-
from typing import TypedDict
|
12
|
+
from typing import TypedDict, Literal
|
13
13
|
from datetime import datetime as Datetime
|
14
14
|
from reykit.ros import File, Folder, overload
|
15
15
|
from reykit.rnet import join_url, request, get_response_file_name
|
@@ -44,6 +44,43 @@ class ServerClient(ServerBase):
|
|
44
44
|
self.url = url
|
45
45
|
|
46
46
|
|
47
|
+
def create_session(
|
48
|
+
self,
|
49
|
+
account: str,
|
50
|
+
password: str,
|
51
|
+
account_type: Literal['name', 'email', 'phone'] = 'name'
|
52
|
+
) -> str:
|
53
|
+
"""
|
54
|
+
Create session.
|
55
|
+
|
56
|
+
Parameters
|
57
|
+
----------
|
58
|
+
account : User account, name or email or phone.
|
59
|
+
password : User password.
|
60
|
+
account_type : User account type.
|
61
|
+
|
62
|
+
Returns
|
63
|
+
-------
|
64
|
+
Token.
|
65
|
+
"""
|
66
|
+
|
67
|
+
# Parameter.
|
68
|
+
url = join_url(self.url, 'sessions')
|
69
|
+
json = {
|
70
|
+
'account': account,
|
71
|
+
'password': password,
|
72
|
+
'account_type': account_type
|
73
|
+
}
|
74
|
+
|
75
|
+
# Request.
|
76
|
+
response = request(url, json=json, check=True)
|
77
|
+
response_dict = response.json()
|
78
|
+
print(response_dict)
|
79
|
+
token = response_dict['token']
|
80
|
+
|
81
|
+
return token
|
82
|
+
|
83
|
+
|
47
84
|
def upload_file(
|
48
85
|
self,
|
49
86
|
source: str | bytes,
|
reyserver/rfile.py
CHANGED
@@ -184,7 +184,7 @@ depend_file_conn = Bind.create_depend_db('file', 'conn')
|
|
184
184
|
|
185
185
|
@file_router.get('/files/{file_id}')
|
186
186
|
async def get_file_info(
|
187
|
-
file_id: int = Bind.path,
|
187
|
+
file_id: int = Bind.i.path,
|
188
188
|
sess: Bind.Sess = depend_file_sess
|
189
189
|
) -> DatabaseORMTableInfo:
|
190
190
|
"""
|
@@ -211,9 +211,9 @@ async def get_file_info(
|
|
211
211
|
|
212
212
|
@file_router.post('/files')
|
213
213
|
async def upload_file(
|
214
|
-
file: Bind.File = Bind.forms,
|
215
|
-
name: str = Bind.forms_n,
|
216
|
-
note: str = Bind.forms_n,
|
214
|
+
file: Bind.File = Bind.i.forms,
|
215
|
+
name: str = Bind.i.forms_n,
|
216
|
+
note: str = Bind.i.forms_n,
|
217
217
|
sess: Bind.Sess = depend_file_sess
|
218
218
|
) -> DatabaseORMTableInfo:
|
219
219
|
"""
|
@@ -265,7 +265,7 @@ async def upload_file(
|
|
265
265
|
|
266
266
|
@file_router.get('/files/{file_id}/download')
|
267
267
|
async def download_file(
|
268
|
-
file_id: int = Bind.path,
|
268
|
+
file_id: int = Bind.i.path,
|
269
269
|
conn: Bind.Conn = depend_file_conn
|
270
270
|
) -> FileResponse:
|
271
271
|
"""
|
reyserver/rserver.py
CHANGED
@@ -105,6 +105,8 @@ class Server(ServerBase, Singleton):
|
|
105
105
|
# API.
|
106
106
|
self.api_auth_key: str
|
107
107
|
'Authentication API JWT encryption key.'
|
108
|
+
self.api_auth_sess_seconds: int
|
109
|
+
'Authentication API session valid seconds.'
|
108
110
|
self.api_file_dir: str
|
109
111
|
'File API store directory path.'
|
110
112
|
|
@@ -136,7 +138,10 @@ class Server(ServerBase, Singleton):
|
|
136
138
|
response = await call_next(request)
|
137
139
|
|
138
140
|
# After.
|
139
|
-
if
|
141
|
+
if (
|
142
|
+
response.status_code == 200
|
143
|
+
and request.method == 'POST'
|
144
|
+
):
|
140
145
|
response.status_code = 201
|
141
146
|
|
142
147
|
return response
|
@@ -190,7 +195,7 @@ class Server(ServerBase, Singleton):
|
|
190
195
|
setattr(self.app, key, value)
|
191
196
|
|
192
197
|
|
193
|
-
def add_api_auth(self, key: str | None = None) -> None:
|
198
|
+
def add_api_auth(self, key: str | None = None, sess_seconds: int = 28800) -> None:
|
194
199
|
"""
|
195
200
|
Add authentication API.
|
196
201
|
Note: must include database engine of `auth` name.
|
@@ -199,9 +204,10 @@ class Server(ServerBase, Singleton):
|
|
199
204
|
----------
|
200
205
|
key : JWT encryption key.
|
201
206
|
- `None`: Random 32 length string.
|
207
|
+
sess_seconds : Session valid seconds.
|
202
208
|
"""
|
203
209
|
|
204
|
-
from .rauth import
|
210
|
+
from .rauth import build_auth_db, auth_router
|
205
211
|
|
206
212
|
# Parameter.
|
207
213
|
if key is None:
|
@@ -209,10 +215,11 @@ class Server(ServerBase, Singleton):
|
|
209
215
|
|
210
216
|
# Build database.
|
211
217
|
engine = self.db.auth
|
212
|
-
|
218
|
+
build_auth_db(engine)
|
213
219
|
|
214
220
|
# Add.
|
215
221
|
self.api_auth_key = key
|
222
|
+
self.api_auth_sess_seconds = sess_seconds
|
216
223
|
self.app.include_router(auth_router, tags=['auth'])
|
217
224
|
|
218
225
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
reyserver/__init__.py,sha256=7GX64p7uI2eetJH9NJ-DTg-8iyQwOsGcviADFJCPxVA,373
|
2
|
+
reyserver/rall.py,sha256=riyDRTUsigco_Bee1H4aZFb8IgvjnxdX9qcnVb9i9mE,270
|
3
|
+
reyserver/rauth.py,sha256=oa6Iwuutcj9eO6RH7DaT-rPn_YqYwKuyHYaBd3lZoZE,11728
|
4
|
+
reyserver/rbase.py,sha256=xgdLP_O77e-pSrRWm9GVSziPSqEOh2w20cWkF4HBeWo,7042
|
5
|
+
reyserver/rclient.py,sha256=IWZ3smyIP0_YJrfSrM8JFCr0FCtN02AyT3hp8YuSsDQ,5103
|
6
|
+
reyserver/rfile.py,sha256=bvuXOYO3UDM1jMiyNzQDz56_0ekZUEIRcfNFAhGgdUY,9010
|
7
|
+
reyserver/rserver.py,sha256=bfakJGhcHF0CIiAmRyMVOURLbPNCIALGyrnKpf_Yi80,6800
|
8
|
+
reyserver-1.1.52.dist-info/METADATA,sha256=ujWE6YB95IdJf4nCYtq7FZW2sw0s_TGSeyuEwAjfHW8,1689
|
9
|
+
reyserver-1.1.52.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
+
reyserver-1.1.52.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
11
|
+
reyserver-1.1.52.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=xknFI0IEMJcDRTkmO8jb-4Pbl7QSnQOA8m87D7gU3MM,9228
|
4
|
-
reyserver/rbase.py,sha256=IUVkkNsLmQh-QRLX6qtbCjPZAbQAsxoe0goPLCxG9KA,5283
|
5
|
-
reyserver/rclient.py,sha256=pTJtn78jPKgFo5EoQwZRdM0cYHdCs7QUKqfl-jUBRgk,4220
|
6
|
-
reyserver/rfile.py,sha256=RpMeq0vRStop4RnyjKv4wjdXgJjKPOAKpwPAKpLt0hk,9000
|
7
|
-
reyserver/rserver.py,sha256=oOfAc0aM-C561k8mKhF8_gYDmF0Kn6hKyZ5ff6mzPCE,6498
|
8
|
-
reyserver-1.1.50.dist-info/METADATA,sha256=iVbZ7pE_k0IlyYw1bsuw5lJIziRJ2CvsRyM4ivSQRi8,1689
|
9
|
-
reyserver-1.1.50.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
-
reyserver-1.1.50.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
11
|
-
reyserver-1.1.50.dist-info/RECORD,,
|
File without changes
|
File without changes
|