reyserver 1.1.61__py3-none-any.whl → 1.1.63__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/rauth.py +39 -39
- reyserver/rbase.py +58 -25
- reyserver/rclient.py +1 -1
- reyserver/rserver.py +68 -30
- {reyserver-1.1.61.dist-info → reyserver-1.1.63.dist-info}/METADATA +1 -1
- reyserver-1.1.63.dist-info/RECORD +11 -0
- reyserver-1.1.61.dist-info/RECORD +0 -11
- {reyserver-1.1.61.dist-info → reyserver-1.1.63.dist-info}/WHEEL +0 -0
- {reyserver-1.1.61.dist-info → reyserver-1.1.63.dist-info}/licenses/LICENSE +0 -0
reyserver/rauth.py
CHANGED
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
from typing import Any, TypedDict, NotRequired, Literal
|
|
13
13
|
from datetime import datetime as Datetime
|
|
14
|
-
from re import PatternError
|
|
15
14
|
from fastapi import APIRouter, Request
|
|
16
|
-
from fastapi.params import Depends
|
|
17
15
|
from fastapi.security import OAuth2PasswordBearer
|
|
18
16
|
from reydb import rorm, DatabaseEngine, DatabaseEngineAsync
|
|
19
17
|
from reykit.rdata import encode_jwt, decode_jwt, is_hash_bcrypt
|
|
@@ -34,8 +32,8 @@ __all__ = (
|
|
|
34
32
|
)
|
|
35
33
|
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
'
|
|
35
|
+
UserData = TypedDict(
|
|
36
|
+
'UserData',
|
|
39
37
|
{
|
|
40
38
|
'create_time': float,
|
|
41
39
|
'udpate_time': float,
|
|
@@ -50,19 +48,19 @@ UserInfo = TypedDict(
|
|
|
50
48
|
'password': NotRequired[str]
|
|
51
49
|
}
|
|
52
50
|
)
|
|
53
|
-
|
|
54
|
-
'
|
|
51
|
+
TokenData = TypedDict(
|
|
52
|
+
'TokenData',
|
|
55
53
|
{
|
|
56
54
|
'sub': int,
|
|
57
55
|
'iat': int,
|
|
58
56
|
'nbf': int,
|
|
59
57
|
'exp': int,
|
|
60
|
-
'user':
|
|
58
|
+
'user': UserData
|
|
61
59
|
}
|
|
62
60
|
)
|
|
63
61
|
Token = str
|
|
64
|
-
|
|
65
|
-
'
|
|
62
|
+
JSONToken = TypedDict(
|
|
63
|
+
'JSONToken',
|
|
66
64
|
{
|
|
67
65
|
'access_token': Token,
|
|
68
66
|
'token_type': Literal['Bearer']
|
|
@@ -241,19 +239,19 @@ def build_db_auth(engine: DatabaseEngine | DatabaseEngineAsync) -> None:
|
|
|
241
239
|
|
|
242
240
|
bearer = OAuth2PasswordBearer(
|
|
243
241
|
tokenUrl='/token',
|
|
244
|
-
scheme_name='
|
|
245
|
-
description='
|
|
242
|
+
scheme_name='OAuth2Password',
|
|
243
|
+
description='Authentication of OAuth2 password model.',
|
|
246
244
|
auto_error=False
|
|
247
245
|
)
|
|
248
246
|
|
|
249
247
|
|
|
250
|
-
async def
|
|
248
|
+
async def depend_token(
|
|
251
249
|
request: Request,
|
|
252
250
|
server: Bind.Server = Bind.server,
|
|
253
|
-
token: Token | None =
|
|
254
|
-
) ->
|
|
251
|
+
token: Token | None = Bind.Depend(bearer)
|
|
252
|
+
) -> TokenData:
|
|
255
253
|
"""
|
|
256
|
-
Dependencie function of authentication.
|
|
254
|
+
Dependencie function of authentication token.
|
|
257
255
|
If the verification fails, then response status code is 401 or 403.
|
|
258
256
|
|
|
259
257
|
Parameters
|
|
@@ -264,7 +262,7 @@ async def depend_auth(
|
|
|
264
262
|
|
|
265
263
|
Returns
|
|
266
264
|
-------
|
|
267
|
-
|
|
265
|
+
Token data.
|
|
268
266
|
"""
|
|
269
267
|
|
|
270
268
|
# Check.
|
|
@@ -278,18 +276,17 @@ async def depend_auth(
|
|
|
278
276
|
api_path = f'{request.method} {request.url.path}'
|
|
279
277
|
|
|
280
278
|
# Cache.
|
|
281
|
-
|
|
279
|
+
token_data: UserData | None = getattr(request.state, 'token_data', None)
|
|
282
280
|
|
|
283
281
|
# Decode.
|
|
284
|
-
if
|
|
285
|
-
|
|
286
|
-
if
|
|
282
|
+
if token_data is None:
|
|
283
|
+
token_data: TokenData | None = decode_jwt(token, key)
|
|
284
|
+
if token_data is None:
|
|
287
285
|
exit_api(401)
|
|
288
|
-
|
|
289
|
-
request.state.user = user
|
|
286
|
+
request.state.token_data = token_data
|
|
290
287
|
|
|
291
288
|
# Authentication.
|
|
292
|
-
perm_apis =
|
|
289
|
+
perm_apis = token_data['user']['perm_apis']
|
|
293
290
|
perm_apis = [
|
|
294
291
|
f'^{pattern}$'
|
|
295
292
|
for pattern in perm_apis
|
|
@@ -298,20 +295,22 @@ async def depend_auth(
|
|
|
298
295
|
if result is None:
|
|
299
296
|
exit_api(403)
|
|
300
297
|
|
|
301
|
-
return
|
|
298
|
+
return token_data
|
|
302
299
|
|
|
303
300
|
|
|
301
|
+
Bind.token = Bind.Depend(depend_token)
|
|
302
|
+
|
|
304
303
|
router_auth = APIRouter()
|
|
305
304
|
|
|
306
305
|
|
|
307
|
-
async def
|
|
306
|
+
async def get_user_data(
|
|
308
307
|
conn: Bind.Conn,
|
|
309
308
|
account: str,
|
|
310
|
-
account_type: Literal['name', 'email', 'phone'],
|
|
309
|
+
account_type: Literal['user_id', 'name', 'email', 'phone'] = 'name',
|
|
311
310
|
filter_invalid: bool = True
|
|
312
|
-
) ->
|
|
311
|
+
) -> UserData | None:
|
|
313
312
|
"""
|
|
314
|
-
Get user
|
|
313
|
+
Get user data.
|
|
315
314
|
|
|
316
315
|
Parameters
|
|
317
316
|
----------
|
|
@@ -325,7 +324,7 @@ async def get_user_info(
|
|
|
325
324
|
|
|
326
325
|
Returns
|
|
327
326
|
-------
|
|
328
|
-
User
|
|
327
|
+
User data or null.
|
|
329
328
|
"""
|
|
330
329
|
|
|
331
330
|
# Parameters.
|
|
@@ -356,6 +355,7 @@ async def get_user_info(
|
|
|
356
355
|
' SELECT `create_time`, `update_time`, `user_id`, `password`, `name`, `email`, `phone`, `avatar`\n'
|
|
357
356
|
' FROM `test`.`user`\n'
|
|
358
357
|
f'{sql_where}'
|
|
358
|
+
' LIMIT 1\n'
|
|
359
359
|
') as `user`\n'
|
|
360
360
|
'LEFT JOIN (\n'
|
|
361
361
|
' SELECT `user_id`, `role_id`\n'
|
|
@@ -389,7 +389,7 @@ async def get_user_info(
|
|
|
389
389
|
info = None
|
|
390
390
|
else:
|
|
391
391
|
row: dict[str, Datetime | Any] = result.to_row()
|
|
392
|
-
info:
|
|
392
|
+
info: UserData = {
|
|
393
393
|
'create_time': row['create_time'].timestamp(),
|
|
394
394
|
'udpate_time': row['update_time'].timestamp(),
|
|
395
395
|
'user_id': row['user_id'],
|
|
@@ -412,9 +412,9 @@ async def create_sessions(
|
|
|
412
412
|
password: str = Bind.i.form,
|
|
413
413
|
conn: Bind.Conn = Bind.conn.auth,
|
|
414
414
|
server: Bind.Server = Bind.server
|
|
415
|
-
) ->
|
|
415
|
+
) -> JSONToken:
|
|
416
416
|
"""
|
|
417
|
-
Create
|
|
417
|
+
Create token.
|
|
418
418
|
|
|
419
419
|
Parameters
|
|
420
420
|
----------
|
|
@@ -430,25 +430,25 @@ async def create_sessions(
|
|
|
430
430
|
key = server.api_auth_key
|
|
431
431
|
sess_seconds = server.api_auth_sess_seconds
|
|
432
432
|
|
|
433
|
-
# User
|
|
434
|
-
|
|
433
|
+
# User data.
|
|
434
|
+
user_data = await get_user_data(conn, username)
|
|
435
435
|
|
|
436
436
|
# Check.
|
|
437
|
-
if
|
|
437
|
+
if user_data is None:
|
|
438
438
|
exit_api(401)
|
|
439
|
-
password_hash =
|
|
439
|
+
password_hash = user_data.pop('password')
|
|
440
440
|
if not is_hash_bcrypt(password, password_hash):
|
|
441
441
|
exit_api(401)
|
|
442
442
|
|
|
443
443
|
# Response.
|
|
444
444
|
now_timestamp_s = now('timestamp_s')
|
|
445
|
-
user_id =
|
|
446
|
-
data:
|
|
445
|
+
user_id = user_data.pop('user_id')
|
|
446
|
+
data: TokenData = {
|
|
447
447
|
'sub': str(user_id),
|
|
448
448
|
'iat': now_timestamp_s,
|
|
449
449
|
'nbf': now_timestamp_s,
|
|
450
450
|
'exp': now_timestamp_s + sess_seconds,
|
|
451
|
-
'user':
|
|
451
|
+
'user': user_data
|
|
452
452
|
}
|
|
453
453
|
token = encode_jwt(data, key)
|
|
454
454
|
response = {
|
reyserver/rbase.py
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
from typing import Type, NoReturn, overload
|
|
12
|
+
from typing import Literal, Type, NoReturn, overload
|
|
13
13
|
from http import HTTPStatus
|
|
14
|
-
from fastapi import
|
|
14
|
+
from fastapi import APIRouter
|
|
15
15
|
from fastapi import HTTPException, Request, UploadFile as File
|
|
16
16
|
from fastapi.params import (
|
|
17
17
|
Depends,
|
|
@@ -24,7 +24,7 @@ from fastapi.params import (
|
|
|
24
24
|
File as Forms
|
|
25
25
|
)
|
|
26
26
|
from reydb.rconn import DatabaseConnectionAsync
|
|
27
|
-
from reydb.rorm import
|
|
27
|
+
from reydb.rorm import DatabaseORMSessionAsync
|
|
28
28
|
from reykit.rbase import Base, Exit, StaticMeta, Singleton, throw
|
|
29
29
|
|
|
30
30
|
from . import rserver
|
|
@@ -311,49 +311,82 @@ class ServerBindInstance(ServerBase, Singleton):
|
|
|
311
311
|
return forms
|
|
312
312
|
|
|
313
313
|
|
|
314
|
-
async def depend_server(request: Request) -> 'rserver.Server':
|
|
315
|
-
"""
|
|
316
|
-
Dependencie function of now Server instance.
|
|
317
|
-
|
|
318
|
-
Parameters
|
|
319
|
-
----------
|
|
320
|
-
request : Request.
|
|
321
|
-
|
|
322
|
-
Returns
|
|
323
|
-
-------
|
|
324
|
-
Server.
|
|
325
|
-
"""
|
|
326
|
-
|
|
327
|
-
# Get.
|
|
328
|
-
app: FastAPI = request.app
|
|
329
|
-
server = app.extra['server']
|
|
330
|
-
|
|
331
|
-
return server
|
|
332
|
-
|
|
333
|
-
|
|
334
314
|
class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
335
315
|
"""
|
|
336
316
|
Server API bind parameter type.
|
|
337
317
|
"""
|
|
338
318
|
|
|
339
319
|
Request = Request
|
|
320
|
+
'Reqeust instance dependency type.'
|
|
340
321
|
Path = Path
|
|
322
|
+
'URL source path dependency type.'
|
|
341
323
|
Query = Query
|
|
324
|
+
'URL query parameter dependency type.'
|
|
342
325
|
Header = Header
|
|
326
|
+
'Request header parameter dependency type.'
|
|
343
327
|
Cookie = Cookie
|
|
328
|
+
'Request header cookie parameter dependency type.'
|
|
344
329
|
Body = Body
|
|
330
|
+
'Request body JSON parameter dependency type.'
|
|
345
331
|
Form = Form
|
|
332
|
+
'Request body form parameter dependency type.'
|
|
346
333
|
Forms = Forms
|
|
334
|
+
'Request body multiple forms parameter dependency type.'
|
|
347
335
|
File = File
|
|
336
|
+
'Verify file type.'
|
|
348
337
|
Depend = Depends
|
|
349
|
-
|
|
338
|
+
'Dependency type.'
|
|
350
339
|
Conn = DatabaseConnectionAsync
|
|
351
340
|
Sess = DatabaseORMSessionAsync
|
|
352
341
|
Server = Type['rserver.Server']
|
|
353
|
-
|
|
342
|
+
'Server type.'
|
|
343
|
+
server: Depend
|
|
344
|
+
'Server instance dependency type.'
|
|
354
345
|
i = ServerBindInstance()
|
|
346
|
+
'Server API bind parameter build instance.'
|
|
355
347
|
conn = ServerBindInstanceDatabaseConnection()
|
|
348
|
+
'Server API bind parameter asynchronous database connection.'
|
|
356
349
|
sess = ServerBindInstanceDatabaseSession()
|
|
350
|
+
'Server API bind parameter asynchronous database session.'
|
|
351
|
+
token: Depend
|
|
352
|
+
'Server authentication token dependency type.'
|
|
357
353
|
|
|
358
354
|
|
|
359
355
|
Bind = ServerBind
|
|
356
|
+
|
|
357
|
+
router_base = APIRouter()
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
@router_base.get('/test')
|
|
361
|
+
def test() -> Literal['test']:
|
|
362
|
+
"""
|
|
363
|
+
Test.
|
|
364
|
+
|
|
365
|
+
Returns
|
|
366
|
+
-------
|
|
367
|
+
Text `test`.
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
# Resposne.
|
|
371
|
+
response = 'test'
|
|
372
|
+
|
|
373
|
+
return response
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
@router_base.post('/test/echo')
|
|
377
|
+
def echo(data: dict = Bind.i.body) -> dict:
|
|
378
|
+
"""
|
|
379
|
+
Echo test.
|
|
380
|
+
|
|
381
|
+
Paremeters
|
|
382
|
+
----------
|
|
383
|
+
data : Echo data.
|
|
384
|
+
|
|
385
|
+
Returns
|
|
386
|
+
-------
|
|
387
|
+
Echo data.
|
|
388
|
+
"""
|
|
389
|
+
|
|
390
|
+
# Resposne.
|
|
391
|
+
|
|
392
|
+
return data
|
reyserver/rclient.py
CHANGED
reyserver/rserver.py
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
from typing import
|
|
12
|
+
from typing import Literal
|
|
13
13
|
from collections.abc import Sequence, Callable, Coroutine
|
|
14
14
|
from inspect import iscoroutinefunction
|
|
15
15
|
from contextlib import asynccontextmanager, _AsyncGeneratorContextManager
|
|
@@ -19,7 +19,7 @@ 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
|
|
22
|
+
from reydb import DatabaseAsync
|
|
23
23
|
from reykit.rbase import CoroutineFunctionSimple, Singleton, throw
|
|
24
24
|
from reykit.rrand import randchar
|
|
25
25
|
|
|
@@ -216,16 +216,50 @@ class Server(ServerBase, Singleton):
|
|
|
216
216
|
return response
|
|
217
217
|
|
|
218
218
|
|
|
219
|
-
def run(
|
|
219
|
+
def run(
|
|
220
|
+
self,
|
|
221
|
+
host: str = '127.0.0.1',
|
|
222
|
+
port: int = 1024,
|
|
223
|
+
app: str | None = None,
|
|
224
|
+
workers: int = 1
|
|
225
|
+
) -> None:
|
|
220
226
|
"""
|
|
221
227
|
Run server.
|
|
228
|
+
|
|
229
|
+
Parameters
|
|
230
|
+
----------
|
|
231
|
+
host : Server host.
|
|
232
|
+
port: Server port.
|
|
233
|
+
app : Application path, format is `Module[.Sub....]:Variable[.Attributre....]` (e.g. `module.sub:server.app`).
|
|
234
|
+
- `None`: Cannot use parameter `workers`.
|
|
235
|
+
workers: Number of server work processes.
|
|
236
|
+
|
|
237
|
+
Examples
|
|
238
|
+
--------
|
|
239
|
+
>>> server = Server(db)
|
|
240
|
+
|
|
241
|
+
Single work process.
|
|
242
|
+
>>> server.run()
|
|
243
|
+
|
|
244
|
+
Multiple work processes.
|
|
245
|
+
>>> server = Server(db)
|
|
246
|
+
>>> if __name__ == '__main__':
|
|
247
|
+
>>> server('module.sub:server.app')
|
|
222
248
|
"""
|
|
223
249
|
|
|
250
|
+
# Parameter.
|
|
251
|
+
if app is None:
|
|
252
|
+
app = self.app
|
|
253
|
+
|
|
224
254
|
# Run.
|
|
225
255
|
uvicorn_run(
|
|
226
|
-
|
|
256
|
+
app,
|
|
257
|
+
host=host,
|
|
258
|
+
port=port,
|
|
259
|
+
workers=workers,
|
|
227
260
|
ssl_certfile=self.ssl_cert,
|
|
228
|
-
ssl_keyfile=self.ssl_key
|
|
261
|
+
ssl_keyfile=self.ssl_key,
|
|
262
|
+
# factory=True
|
|
229
263
|
)
|
|
230
264
|
|
|
231
265
|
|
|
@@ -272,29 +306,10 @@ class Server(ServerBase, Singleton):
|
|
|
272
306
|
Add base API.
|
|
273
307
|
"""
|
|
274
308
|
|
|
275
|
-
from
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
def func():
|
|
280
|
-
return int(time())
|
|
281
|
-
depend = Depends(func)
|
|
282
|
-
@self.app.get('/test')
|
|
283
|
-
async def test(a: int = form, b: int = form) -> str:
|
|
284
|
-
print(a, b)
|
|
285
|
-
return 'test'
|
|
286
|
-
@self.app.get('/test1')
|
|
287
|
-
async def test1(a: int = depend, b: int = depend) -> str:
|
|
288
|
-
print(a, b)
|
|
289
|
-
return 'test'
|
|
290
|
-
@self.app.get('/test2')
|
|
291
|
-
async def test2(a: int = form, b: int = depend) -> str:
|
|
292
|
-
print(a, b)
|
|
293
|
-
return 'test'
|
|
294
|
-
@self.app.get('/test3')
|
|
295
|
-
async def test3(a: int = form, b: int = depend) -> str:
|
|
296
|
-
print(a, b)
|
|
297
|
-
return 'test'
|
|
309
|
+
from .rbase import router_base
|
|
310
|
+
|
|
311
|
+
# Add.
|
|
312
|
+
self.app.include_router(router_base, tags=['test'])
|
|
298
313
|
|
|
299
314
|
|
|
300
315
|
def add_api_auth(self, key: str | None = None, sess_seconds: int = 28800) -> None:
|
|
@@ -338,7 +353,6 @@ class Server(ServerBase, Singleton):
|
|
|
338
353
|
file_dir : File API store directory path.
|
|
339
354
|
"""
|
|
340
355
|
|
|
341
|
-
from .rauth import depend_auth
|
|
342
356
|
from .rfile import build_db_file, router_file
|
|
343
357
|
|
|
344
358
|
# Database.
|
|
@@ -349,4 +363,28 @@ class Server(ServerBase, Singleton):
|
|
|
349
363
|
|
|
350
364
|
# Add.
|
|
351
365
|
self.api_file_dir = file_dir
|
|
352
|
-
self.app.include_router(router_file, tags=['file'])
|
|
366
|
+
self.app.include_router(router_file, tags=['file'], dependencies=(Bind.token,))
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
async def depend_server(request: Request) -> Server:
|
|
370
|
+
"""
|
|
371
|
+
Dependencie function of now Server instance.
|
|
372
|
+
|
|
373
|
+
Parameters
|
|
374
|
+
----------
|
|
375
|
+
request : Request.
|
|
376
|
+
|
|
377
|
+
Returns
|
|
378
|
+
-------
|
|
379
|
+
Server.
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
# Get.
|
|
383
|
+
app: FastAPI = request.app
|
|
384
|
+
server = app.extra['server']
|
|
385
|
+
|
|
386
|
+
return server
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
Bind.Server = Server
|
|
390
|
+
Bind.server = Bind.Depend(depend_server)
|
|
@@ -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=JGo5lLTRGoP1SFPyQA-Q5EE-O3OU_86Mb3pvwhvFu-w,15125
|
|
4
|
+
reyserver/rbase.py,sha256=0ECJ1zuUpJhwaNc0u5GvR5VyGxIAnKQep-EdotwnLoE,7752
|
|
5
|
+
reyserver/rclient.py,sha256=og5YuWm-PODkFn9njBwYQpGlk0j1BfqFuEarlCFSQYI,6229
|
|
6
|
+
reyserver/rfile.py,sha256=6H5_7B9aiA3F56VToQDI9Trarkrl9gcIuFqYyCVCiCU,8877
|
|
7
|
+
reyserver/rserver.py,sha256=sSFoWTnsSRBJ9SZT5i6yzMzDnwg0_YFbSUI7e_8QfiA,10465
|
|
8
|
+
reyserver-1.1.63.dist-info/METADATA,sha256=de-VXiY3vj5atn-pdBUX0zz6FFg_7hWVJV_JEABCnTw,1666
|
|
9
|
+
reyserver-1.1.63.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
+
reyserver-1.1.63.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
11
|
+
reyserver-1.1.63.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=hXI21VrZ_sDrFZzd982ENymFJfPWi6U1XHmGmiglez0,15103
|
|
4
|
-
reyserver/rbase.py,sha256=kzSbo6yoPlWquR6XiseTKi5hEbllaG3qVmmwnnKKac0,6898
|
|
5
|
-
reyserver/rclient.py,sha256=a07zHDUH4Y3f-WdAXMX7Wq9PocwvlrDfdIl2s-M4IWo,6222
|
|
6
|
-
reyserver/rfile.py,sha256=6H5_7B9aiA3F56VToQDI9Trarkrl9gcIuFqYyCVCiCU,8877
|
|
7
|
-
reyserver/rserver.py,sha256=mrtsYu8wsxJmctmh2qWfwD9l70gOZq57UrKcDJ9EAVM,9856
|
|
8
|
-
reyserver-1.1.61.dist-info/METADATA,sha256=IghNj6ce-pWACkbexwa3jvtkMx0lc8hto2XGWhWtWyo,1666
|
|
9
|
-
reyserver-1.1.61.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
10
|
-
reyserver-1.1.61.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
|
11
|
-
reyserver-1.1.61.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|