GNServer 0.0.0.0.5__py3-none-any.whl → 0.0.0.0.7__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.
GNServer/__init__.py CHANGED
@@ -30,7 +30,7 @@ DEALINGS IN THE SOFTWARE.
30
30
  """
31
31
 
32
32
  from ._app import App
33
- from KeyisBClient.gn import GNRequest, GNResponse
33
+ from KeyisBClient.gn import GNRequest, GNResponse, CORSObject
34
34
 
35
35
 
36
36
 
GNServer/_app.py CHANGED
@@ -44,6 +44,12 @@ console = logging.StreamHandler()
44
44
  console.setLevel(logging.INFO)
45
45
  console.setFormatter(logging.Formatter("[GNServer] %(name)s: %(levelname)s: %(message)s"))
46
46
 
47
+
48
+
49
+
50
+
51
+
52
+
47
53
  def guess_type(filename: str) -> str:
48
54
  """
49
55
  Возвращает актуальный MIME-тип по расширению файла.
@@ -112,6 +118,7 @@ class Route:
112
118
  param_types: dict[str, Callable[[str], Any]]
113
119
  handler: Callable[..., Any]
114
120
  name: str
121
+ cors: Optional[gn.CORSObject]
115
122
 
116
123
  _PARAM_REGEX: dict[str, str] = {
117
124
  "str": r"[^/]+",
@@ -193,8 +200,9 @@ def _ensure_async(fn: Callable[..., Any]) -> Callable[..., Any]:
193
200
  class App:
194
201
  def __init__(self):
195
202
  self._routes: List[Route] = []
203
+ self._cors: Optional[gn.CORSObject] = None
196
204
 
197
- def route(self, method: str, path: str, *, name: str | None = None):
205
+ def route(self, method: str, path: str, cors: Optional[gn.CORSObject] = None):
198
206
  def decorator(fn: Callable[..., Any]):
199
207
  regex, param_types = _compile_path(path)
200
208
  self._routes.append(
@@ -204,26 +212,29 @@ class App:
204
212
  regex,
205
213
  param_types,
206
214
  _ensure_async(fn),
207
- name or fn.__name__,
215
+ fn.__name__,
216
+ cors
208
217
  )
209
218
  )
210
219
  return fn
211
220
  return decorator
212
221
 
213
- def get(self, path: str, *, name: str | None = None):
214
- return self.route("GET", path, name=name)
222
+ def get(self, path: str, *, cors: Optional[gn.CORSObject] = None):
223
+ return self.route("GET", path, cors)
224
+
225
+ def post(self, path: str, *, cors: Optional[gn.CORSObject] = None):
226
+ return self.route("POST", path, cors)
215
227
 
216
- def post(self, path: str, *, name: str | None = None):
217
- return self.route("POST", path, name=name)
228
+ def put(self, path: str, *, cors: Optional[gn.CORSObject] = None):
229
+ return self.route("PUT", path, cors)
218
230
 
219
- def put(self, path: str, *, name: str | None = None):
220
- return self.route("PUT", path, name=name)
231
+ def delete(self, path: str, *, cors: Optional[gn.CORSObject] = None):
232
+ return self.route("DELETE", path, cors)
221
233
 
222
- def delete(self, path: str, *, name: str | None = None):
223
- return self.route("DELETE", path, name=name)
234
+
235
+ def setRouteCors(self, cors: Optional[gn.CORSObject] = None):
236
+ self._cors = cors
224
237
 
225
- def custom(self, method: str, path: str, *, name: str | None = None):
226
- return self.route(method, path, name=name)
227
238
 
228
239
 
229
240
  async def dispatch(
@@ -277,18 +288,38 @@ class App:
277
288
  return gn.GNResponse("gn:backend:404", {'error': 'Not Found'})
278
289
 
279
290
 
280
- def static(self, path: str, dir_path: str):
291
+ def fastFile(self, path: str, file_path: str, cors: Optional[gn.CORSObject] = None):
292
+ @self.get(path)
293
+ async def r_static(path: str):
294
+ nonlocal file_path
295
+ if file_path.endswith('/'):
296
+ file_path = file_path[:-1]
297
+
298
+ if not os.path.isfile(file_path):
299
+ return gn.GNResponse('gn:backend:404', cors=cors)
300
+
301
+ mime_type = guess_type(file_path.split('/')[-1])
302
+ async with aiofiles.open(file_path, "rb") as f:
303
+ data = await f.read()
304
+
305
+ return gn.GNResponse('ok', {'files': [{'mime-type': mime_type, 'data': data}]}, cors=cors)
306
+
307
+ def static(self, path: str, dir_path: str, cors: Optional[gn.CORSObject] = None):
281
308
  @self.get(f"{path}/{{_path:path}}")
282
309
  async def r_static(_path: str):
283
310
  file_path = os.path.join(dir_path, _path)
311
+
312
+ if file_path.endswith('/'):
313
+ file_path = file_path[:-1]
314
+
284
315
  if not os.path.isfile(file_path):
285
- return gn.GNResponse('gn:backend:404')
316
+ return gn.GNResponse('gn:backend:404', cors=cors)
286
317
 
287
318
  mime_type = guess_type(file_path.split('/')[-1])
288
319
  async with aiofiles.open(file_path, "rb") as f:
289
- data = f.read()
320
+ data = await f.read()
290
321
 
291
- return gn.GNResponse('ok', {'files': [{'mime-type': mime_type, 'data': data}]})
322
+ return gn.GNResponse('ok', {'files': [{'mime-type': mime_type, 'data': data}]}, cors=cors)
292
323
 
293
324
 
294
325
 
@@ -397,6 +428,7 @@ class App:
397
428
  try:
398
429
 
399
430
  response = await self._api.dispatch(request)
431
+
400
432
 
401
433
  response = await self.resolve_extra_response(response)
402
434
 
@@ -404,18 +436,21 @@ class App:
404
436
  if inspect.isasyncgen(response):
405
437
  async for chunk in response: # type: ignore[misc]
406
438
  chunk._stream = True
439
+ chunk = await self.resolve_response(chunk)
407
440
  self._quic.send_stream_data(request.stream_id, chunk.serialize(3), end_stream=False)
408
441
  self.transmit()
409
442
 
410
443
  l = gn.GNResponse('gn:end-stream')
411
444
  l._stream = True
445
+ l = self.resolve_response(l)
412
446
  self._quic.send_stream_data(request.stream_id, l.serialize(3), end_stream=True)
413
447
  self.transmit()
414
448
  return
415
449
 
416
450
 
451
+ response = await self.resolve_response(response)
417
452
  self._quic.send_stream_data(request.stream_id, response.serialize(3), end_stream=True)
418
- logger.debug(f'Отправлен на сервер ответ -> {response.command()} {response.payload if response.payload and len((response.payload)) < 200 else ''}')
453
+ logger.debug(f'Отправлен на сервер ответ -> {response.command} {response.payload if response.payload and len((response.payload)) < 200 else ''}')
419
454
  self.transmit()
420
455
  except Exception as e:
421
456
  logger.error('GNServer: error\n' + traceback.format_exc())
@@ -424,6 +459,13 @@ class App:
424
459
  self._quic.send_stream_data(request.stream_id, response.serialize(3), end_stream=True)
425
460
  self.transmit()
426
461
 
462
+ async def resolve_response(self, response: gn.GNResponse) -> gn.GNResponse:
463
+ if response._cors is None:
464
+ response._cors = self._api._cors
465
+
466
+ return response
467
+
468
+
427
469
  async def resolve_extra_response(self, response: Union[gn.GNResponse, AsyncGenerator[gn.GNResponse, None]]) -> Union[gn.GNResponse, AsyncGenerator[gn.GNResponse, None]]:
428
470
 
429
471
  file_types = (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GNServer
3
- Version: 0.0.0.0.5
3
+ Version: 0.0.0.0.7
4
4
  Summary: GNServer
5
5
  Home-page: https://github.com/KeyisB/libs/tree/main/GNServer
6
6
  Author: KeyisB
@@ -0,0 +1,8 @@
1
+ GNServer/__init__.py,sha256=l9B6gZZ2gTkWvNdla--J15_Bj0BtP8RyPsrMI6amgDo,1376
2
+ GNServer/_app.py,sha256=w2rK4nrDWVZ_f0c3tC2cVckvkb8gY4Xudajiajw6yqQ,18534
3
+ GNServer/models.py,sha256=3HTbPgXMcltK3hh3RWii0z6X2qYitXmPWzud8pOc4Rk,50
4
+ gnserver-0.0.0.0.7.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
5
+ gnserver-0.0.0.0.7.dist-info/METADATA,sha256=bqObiR6rIxTCq4Lg_GU9oRyYbw6B1wg2NggJV2qrg5c,804
6
+ gnserver-0.0.0.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ gnserver-0.0.0.0.7.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
8
+ gnserver-0.0.0.0.7.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- GNServer/__init__.py,sha256=T6kT6WoJpmIXashMSHfuafb9DSePUIzw192h27j9a4M,1364
2
- GNServer/_app.py,sha256=sLQwfXmEbMCpRulSVVqUGC5-4jdSQmtDD5JWWhsgXQs,17169
3
- gnserver-0.0.0.0.5.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
4
- gnserver-0.0.0.0.5.dist-info/METADATA,sha256=uEYN3KzhtTxDmRKKNFMo2LYVIZu4O5BnL8BEPubn9KQ,804
5
- gnserver-0.0.0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
6
- gnserver-0.0.0.0.5.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
7
- gnserver-0.0.0.0.5.dist-info/RECORD,,