reyserver 1.1.93__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/__init__.py +26 -0
- reyserver/rall.py +21 -0
- reyserver/rauth.py +471 -0
- reyserver/rbase.py +74 -0
- reyserver/rbind.py +335 -0
- reyserver/rcache.py +116 -0
- reyserver/rclient.py +267 -0
- reyserver/rfile.py +316 -0
- reyserver/rpublic.py +62 -0
- reyserver/rredirect.py +48 -0
- reyserver/rserver.py +432 -0
- reyserver/rtest.py +80 -0
- reyserver-1.1.93.dist-info/METADATA +33 -0
- reyserver-1.1.93.dist-info/RECORD +16 -0
- reyserver-1.1.93.dist-info/WHEEL +4 -0
- reyserver-1.1.93.dist-info/licenses/LICENSE +7 -0
reyserver/rbind.py
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
@Time : 2025-10-21
|
|
6
|
+
@Author : Rey
|
|
7
|
+
@Contact : reyxbo@163.com
|
|
8
|
+
@Explain : Dependency bind methods.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from typing import overload, TYPE_CHECKING
|
|
13
|
+
from fastapi import FastAPI, Request, UploadFile
|
|
14
|
+
from fastapi.params import (
|
|
15
|
+
Depends,
|
|
16
|
+
Path,
|
|
17
|
+
Query,
|
|
18
|
+
Header,
|
|
19
|
+
Cookie,
|
|
20
|
+
Body,
|
|
21
|
+
Form,
|
|
22
|
+
File as Forms
|
|
23
|
+
)
|
|
24
|
+
from reydb.rconn import DatabaseConnectionAsync
|
|
25
|
+
from reydb.rorm import DatabaseORMSessionAsync
|
|
26
|
+
from reykit.rbase import StaticMeta, Singleton, throw
|
|
27
|
+
|
|
28
|
+
from . import rserver
|
|
29
|
+
from .rbase import ServerBase, depend_pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
__all__ = (
|
|
33
|
+
'ServerBindInstanceDatabaseSuper',
|
|
34
|
+
'ServerBindInstanceDatabaseConnection',
|
|
35
|
+
'ServerBindInstanceDatabaseSession',
|
|
36
|
+
'ServerBindInstance',
|
|
37
|
+
'ServerBind',
|
|
38
|
+
'Bind'
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ServerBindInstanceDatabaseSuper(ServerBase):
|
|
43
|
+
"""
|
|
44
|
+
Server API bind parameter build database instance super type.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def __getattr__(self, name: str) -> Depends:
|
|
49
|
+
"""
|
|
50
|
+
Create dependencie instance of asynchronous database.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
name : Database engine name.
|
|
55
|
+
mode : Mode.
|
|
56
|
+
- `Literl['sess']`: Create ORM session instance.
|
|
57
|
+
- `Literl['conn']`: Create connection instance.
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
Dependencie instance.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
async def depend_func(server: Bind.Server = Bind.server):
|
|
66
|
+
"""
|
|
67
|
+
Dependencie function of asynchronous database.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
# Check.
|
|
71
|
+
if server.db is None:
|
|
72
|
+
throw(TypeError, server.db)
|
|
73
|
+
|
|
74
|
+
# Parameter.
|
|
75
|
+
engine = server.db[name]
|
|
76
|
+
|
|
77
|
+
# Context.
|
|
78
|
+
match self:
|
|
79
|
+
case ServerBindInstanceDatabaseConnection():
|
|
80
|
+
async with engine.connect() as conn:
|
|
81
|
+
yield conn
|
|
82
|
+
case ServerBindInstanceDatabaseSession():
|
|
83
|
+
async with engine.orm.session() as sess:
|
|
84
|
+
yield sess
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Create.
|
|
88
|
+
depend = Depends(depend_func)
|
|
89
|
+
|
|
90
|
+
return depend
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@overload
|
|
94
|
+
def __getitem__(self, engine: str) -> DatabaseConnectionAsync: ...
|
|
95
|
+
|
|
96
|
+
__getitem__ = __getattr__
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class ServerBindInstanceDatabaseConnection(ServerBindInstanceDatabaseSuper, Singleton):
|
|
100
|
+
"""
|
|
101
|
+
Server API bind parameter build database connection instance type, singleton mode.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class ServerBindInstanceDatabaseSession(ServerBindInstanceDatabaseSuper, Singleton):
|
|
106
|
+
"""
|
|
107
|
+
Server API bind parameter build database session instance type, singleton mode.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ServerBindInstance(ServerBase, Singleton):
|
|
112
|
+
"""
|
|
113
|
+
Server API bind parameter build instance type.
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def path(self) -> Path:
|
|
119
|
+
"""
|
|
120
|
+
Path instance.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
# Build.
|
|
124
|
+
path = Path()
|
|
125
|
+
|
|
126
|
+
return path
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def query(self) -> Query:
|
|
131
|
+
"""
|
|
132
|
+
Query instance.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
# Build.
|
|
136
|
+
query = Query()
|
|
137
|
+
|
|
138
|
+
return query
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def header(self) -> Header:
|
|
143
|
+
"""
|
|
144
|
+
Header instance.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
# Build.
|
|
148
|
+
header = Header()
|
|
149
|
+
|
|
150
|
+
return header
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def cookie(self) -> Cookie:
|
|
155
|
+
"""
|
|
156
|
+
Cookie instance.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
# Build.
|
|
160
|
+
cookie = Cookie()
|
|
161
|
+
|
|
162
|
+
return cookie
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def body(self) -> Body:
|
|
167
|
+
"""
|
|
168
|
+
Body instance.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
# Build.
|
|
172
|
+
body = Body()
|
|
173
|
+
|
|
174
|
+
return body
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@property
|
|
178
|
+
def form(self) -> Form:
|
|
179
|
+
"""
|
|
180
|
+
Form instance.
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
# Build.
|
|
184
|
+
form = Form()
|
|
185
|
+
|
|
186
|
+
return form
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def forms(self) -> Forms:
|
|
191
|
+
"""
|
|
192
|
+
Forms instance.
|
|
193
|
+
"""
|
|
194
|
+
|
|
195
|
+
# Build.
|
|
196
|
+
forms = Forms()
|
|
197
|
+
|
|
198
|
+
return forms
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@property
|
|
202
|
+
def query_n(self) -> Query:
|
|
203
|
+
"""
|
|
204
|
+
Query instance, default `None`.
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
# Build.
|
|
208
|
+
query = Query(None)
|
|
209
|
+
|
|
210
|
+
return query
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
def header_n(self) -> Header:
|
|
215
|
+
"""
|
|
216
|
+
Header instance, default `None`.
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
# Build.
|
|
220
|
+
header = Header(None)
|
|
221
|
+
|
|
222
|
+
return header
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def cookie_n(self) -> Cookie:
|
|
227
|
+
"""
|
|
228
|
+
Cookie instance, default `None`.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
# Build.
|
|
232
|
+
cookie = Cookie(None)
|
|
233
|
+
|
|
234
|
+
return cookie
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@property
|
|
238
|
+
def body_n(self) -> Body:
|
|
239
|
+
"""
|
|
240
|
+
Body instance, default `None`.
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
# Build.
|
|
244
|
+
body = Body(None)
|
|
245
|
+
|
|
246
|
+
return body
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@property
|
|
250
|
+
def form_n(self) -> Form:
|
|
251
|
+
"""
|
|
252
|
+
Form instance, default `None`.
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
# Build.
|
|
256
|
+
form = Form(None)
|
|
257
|
+
|
|
258
|
+
return form
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def forms_n(self) -> Forms:
|
|
263
|
+
"""
|
|
264
|
+
Forms instance, default `None`.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
# Build.
|
|
268
|
+
forms = Forms(None)
|
|
269
|
+
|
|
270
|
+
return forms
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
async def depend_server(request: Request) -> 'rserver.Server':
|
|
274
|
+
"""
|
|
275
|
+
Dependencie function of now Server instance.
|
|
276
|
+
|
|
277
|
+
Parameters
|
|
278
|
+
----------
|
|
279
|
+
request : Request.
|
|
280
|
+
|
|
281
|
+
Returns
|
|
282
|
+
-------
|
|
283
|
+
Server.
|
|
284
|
+
"""
|
|
285
|
+
|
|
286
|
+
# Get.
|
|
287
|
+
app: FastAPI = request.app
|
|
288
|
+
server: rserver.Server = app.extra['server']
|
|
289
|
+
|
|
290
|
+
return server
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class ServerBind(ServerBase, metaclass=StaticMeta):
|
|
294
|
+
"""
|
|
295
|
+
Server API bind parameter type.
|
|
296
|
+
"""
|
|
297
|
+
|
|
298
|
+
Request = Request
|
|
299
|
+
'Reqeust instance dependency type.'
|
|
300
|
+
Path = Path
|
|
301
|
+
'URL source path dependency type.'
|
|
302
|
+
Query = Query
|
|
303
|
+
'URL query parameter dependency type.'
|
|
304
|
+
Header = Header
|
|
305
|
+
'Request header parameter dependency type.'
|
|
306
|
+
Cookie = Cookie
|
|
307
|
+
'Request header cookie parameter dependency type.'
|
|
308
|
+
Body = Body
|
|
309
|
+
'Request body JSON parameter dependency type.'
|
|
310
|
+
Form = Form
|
|
311
|
+
'Request body form parameter dependency type.'
|
|
312
|
+
Forms = Forms
|
|
313
|
+
'Request body multiple forms parameter dependency type.'
|
|
314
|
+
File = UploadFile
|
|
315
|
+
'Type hints file type.'
|
|
316
|
+
Depend = Depends
|
|
317
|
+
'Dependency type.'
|
|
318
|
+
Conn = DatabaseConnectionAsync
|
|
319
|
+
Sess = DatabaseORMSessionAsync
|
|
320
|
+
if TYPE_CHECKING:
|
|
321
|
+
Server = rserver.Server
|
|
322
|
+
'Server type.'
|
|
323
|
+
server: Depend = Depend(depend_server)
|
|
324
|
+
'Server instance dependency type.'
|
|
325
|
+
i = ServerBindInstance()
|
|
326
|
+
'Server API bind parameter build instance.'
|
|
327
|
+
conn = ServerBindInstanceDatabaseConnection()
|
|
328
|
+
'Server API bind parameter asynchronous database connection.'
|
|
329
|
+
sess = ServerBindInstanceDatabaseSession()
|
|
330
|
+
'Server API bind parameter asynchronous database session.'
|
|
331
|
+
token: Depend = depend_pass
|
|
332
|
+
'Server authentication token dependency type.'
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
Bind = ServerBind
|
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
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# !/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
@Time : 2025-10-09
|
|
6
|
+
@Author : Rey
|
|
7
|
+
@Contact : reyxbo@163.com
|
|
8
|
+
@Explain : Client methods.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from typing import TypedDict
|
|
13
|
+
from datetime import datetime as Datetime
|
|
14
|
+
from requests import Response
|
|
15
|
+
from reykit.rbase import copy_type_hints
|
|
16
|
+
from reykit.ros import File, Folder, overload
|
|
17
|
+
from reykit.rnet import join_url, request, get_response_file_name
|
|
18
|
+
|
|
19
|
+
from .rbase import ServerBase
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = (
|
|
23
|
+
'ServerClient',
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
FileInfo = TypedDict('FileInfo', {'create_time': Datetime, 'md5': str, 'name': str | None, 'size': int, 'note': str | None})
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ServerClient(ServerBase):
|
|
31
|
+
"""
|
|
32
|
+
Server client type.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
username: str,
|
|
39
|
+
password: str,
|
|
40
|
+
url: str = 'http://127.0.0.1:8000',
|
|
41
|
+
) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Build instance attributes.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
username: User name.
|
|
48
|
+
password: User password.
|
|
49
|
+
url : Server url.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
# Build.
|
|
53
|
+
self.username = username
|
|
54
|
+
self.password = password
|
|
55
|
+
self.url = url
|
|
56
|
+
self.token = self.get_token(username, password)
|
|
57
|
+
self.request = copy_type_hints(self._request, request)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_token(
|
|
61
|
+
self,
|
|
62
|
+
username: str,
|
|
63
|
+
password: str
|
|
64
|
+
) -> str:
|
|
65
|
+
"""
|
|
66
|
+
Get token.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
username : User name.
|
|
71
|
+
password : User password.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
Token.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
# Parameter.
|
|
79
|
+
url = join_url(self.url, 'token')
|
|
80
|
+
data = {
|
|
81
|
+
'username': username,
|
|
82
|
+
'password': password
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Request.
|
|
86
|
+
response = request(url, data=data, check=True)
|
|
87
|
+
response_dict = response.json()
|
|
88
|
+
token = response_dict['access_token']
|
|
89
|
+
|
|
90
|
+
return token
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _request(self, *args, **kwargs) -> Response:
|
|
94
|
+
"""
|
|
95
|
+
Send request.
|
|
96
|
+
|
|
97
|
+
Parameters
|
|
98
|
+
----------
|
|
99
|
+
args : Position arguments.
|
|
100
|
+
kwargs : Keyword arguments.
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
Response.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
# Parameter.
|
|
108
|
+
headers = kwargs.setdefault('headers', {})
|
|
109
|
+
headers['Authorization'] = f'Bearer {self.token}'
|
|
110
|
+
kwargs['check'] = list(range(200, 400))
|
|
111
|
+
kwargs['check'].append(401)
|
|
112
|
+
|
|
113
|
+
# Request.
|
|
114
|
+
response = request(*args, **kwargs)
|
|
115
|
+
|
|
116
|
+
# Check.
|
|
117
|
+
if response.status_code != 401:
|
|
118
|
+
return response
|
|
119
|
+
|
|
120
|
+
# Try request.
|
|
121
|
+
self.token = self.get_token(self.username, self.password)
|
|
122
|
+
headers['Authorization'] = f'Bearer {self.token}'
|
|
123
|
+
kwargs['check'] = True
|
|
124
|
+
response = request(*args, **kwargs)
|
|
125
|
+
|
|
126
|
+
return response
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def upload_file(
|
|
130
|
+
self,
|
|
131
|
+
source: str | bytes,
|
|
132
|
+
name: str | None = None,
|
|
133
|
+
note: str | None = None
|
|
134
|
+
) -> int:
|
|
135
|
+
"""
|
|
136
|
+
Upload file.
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
source : File path or file bytes.
|
|
141
|
+
name : File name.
|
|
142
|
+
- `None`: Automatic set.
|
|
143
|
+
`parameter 'file' is 'str'`: Use path file name.
|
|
144
|
+
`parameter 'file' is 'bytes'`: No name.
|
|
145
|
+
- `str`: Use this name.
|
|
146
|
+
note : File note.
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
File ID.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
# Parameter.
|
|
154
|
+
url = join_url(self.url, 'files')
|
|
155
|
+
match source:
|
|
156
|
+
|
|
157
|
+
## File path.
|
|
158
|
+
case str():
|
|
159
|
+
file = File(source)
|
|
160
|
+
file_bytes = file.bytes
|
|
161
|
+
file_name = file.name_suffix
|
|
162
|
+
|
|
163
|
+
## File bytes.
|
|
164
|
+
case bytes() | bytearray():
|
|
165
|
+
if type(source) == bytearray:
|
|
166
|
+
source = bytes(source)
|
|
167
|
+
file_bytes = source
|
|
168
|
+
file_name = None
|
|
169
|
+
|
|
170
|
+
## File name.
|
|
171
|
+
if name is not None:
|
|
172
|
+
file_name = name
|
|
173
|
+
|
|
174
|
+
# Request.
|
|
175
|
+
data = {'name': file_name, 'note': note}
|
|
176
|
+
files = {'file': file_bytes}
|
|
177
|
+
response = self.request(url, data=data, files=files, check=True)
|
|
178
|
+
|
|
179
|
+
## Extract.
|
|
180
|
+
response_json = response.json()
|
|
181
|
+
file_id = response_json['file_id']
|
|
182
|
+
|
|
183
|
+
return file_id
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@overload
|
|
187
|
+
def download_file(
|
|
188
|
+
self,
|
|
189
|
+
file_id: int,
|
|
190
|
+
path: None = None
|
|
191
|
+
) -> bytes: ...
|
|
192
|
+
|
|
193
|
+
@overload
|
|
194
|
+
def download_file(
|
|
195
|
+
self,
|
|
196
|
+
file_id: int,
|
|
197
|
+
path: str
|
|
198
|
+
) -> str: ...
|
|
199
|
+
|
|
200
|
+
def download_file(
|
|
201
|
+
self,
|
|
202
|
+
file_id: int,
|
|
203
|
+
path: str | None = None
|
|
204
|
+
) -> bytes | str:
|
|
205
|
+
"""
|
|
206
|
+
Download file.
|
|
207
|
+
|
|
208
|
+
Parameters
|
|
209
|
+
----------
|
|
210
|
+
file_id : File ID.
|
|
211
|
+
path : File save path.
|
|
212
|
+
- `None`: Not save and return file bytes.
|
|
213
|
+
- `str`: Save and return file path.
|
|
214
|
+
`File path`: Use this file path.
|
|
215
|
+
`Folder path`: Use this folder path and original name.
|
|
216
|
+
|
|
217
|
+
Returns
|
|
218
|
+
-------
|
|
219
|
+
File bytes or file path.
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
# Parameter.
|
|
223
|
+
url = join_url(self.url, 'files', file_id, 'download')
|
|
224
|
+
|
|
225
|
+
# Request.
|
|
226
|
+
response = self.request(url, check=True)
|
|
227
|
+
file_bytes = response.content
|
|
228
|
+
|
|
229
|
+
# Not save.
|
|
230
|
+
if path is None:
|
|
231
|
+
return file_bytes
|
|
232
|
+
|
|
233
|
+
# Save.
|
|
234
|
+
else:
|
|
235
|
+
folder = Folder(path)
|
|
236
|
+
if folder:
|
|
237
|
+
file_name = get_response_file_name(response)
|
|
238
|
+
path = folder + file_name
|
|
239
|
+
file = File(path)
|
|
240
|
+
file(file_bytes)
|
|
241
|
+
return file.path
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def get_file_info(
|
|
245
|
+
self,
|
|
246
|
+
file_id: int
|
|
247
|
+
) -> FileInfo:
|
|
248
|
+
"""
|
|
249
|
+
Query file information.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
file_id : File ID.
|
|
254
|
+
|
|
255
|
+
Returns
|
|
256
|
+
-------
|
|
257
|
+
File information.
|
|
258
|
+
"""
|
|
259
|
+
|
|
260
|
+
# Parameter.
|
|
261
|
+
url = join_url(self.url, 'files', file_id)
|
|
262
|
+
|
|
263
|
+
# Request.
|
|
264
|
+
response = self.request(url, check=True)
|
|
265
|
+
response_dict = response.json()
|
|
266
|
+
|
|
267
|
+
return response_dict
|