arpakitlib 1.7.76__py3-none-any.whl → 1.7.78__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.
@@ -1,6 +1,22 @@
1
- from arpakitlib.ar_fastapi_util import api_key_api_auth
1
+ from arpakitlib.ar_fastapi_util import base_api_auth
2
2
  from src.core.settings import get_cached_settings
3
3
 
4
- check_with_settings_api_key_api_auth = api_key_api_auth(
5
- correct_api_key=get_cached_settings().api_correct_api_key
4
+ api_key_with_settings_api_auth = base_api_auth(
5
+ correct_api_keys=get_cached_settings().api_correct_api_key,
6
+ require_correct_api_key=False
7
+ )
8
+
9
+ correct_api_key_with_settings_api_auth = base_api_auth(
10
+ correct_api_keys=get_cached_settings().api_correct_api_key,
11
+ require_correct_api_key=True
12
+ )
13
+
14
+ token_with_settings_api_auth = base_api_auth(
15
+ correct_api_keys=get_cached_settings().api_correct_token,
16
+ require_correct_token=False
17
+ )
18
+
19
+ correct_token_with_settings_api_auth = base_api_auth(
20
+ correct_api_keys=get_cached_settings().api_correct_token,
21
+ require_correct_token=True
6
22
  )
@@ -35,6 +35,8 @@ class Settings(SimpleSettings):
35
35
 
36
36
  api_correct_api_key: str | None = "1"
37
37
 
38
+ api_correct_token: str | None = "1"
39
+
38
40
  var_dirname: str | None = "var"
39
41
 
40
42
  var_dirpath: str | None = os.path.join(BASE_DIRPATH, var_dirname)
@@ -29,11 +29,12 @@ from arpakitlib.ar_base_worker_util import BaseWorker, safe_run_worker_in_backgr
29
29
  from arpakitlib.ar_dict_util import combine_dicts
30
30
  from arpakitlib.ar_enumeration_util import Enumeration
31
31
  from arpakitlib.ar_file_storage_in_dir_util import FileStorageInDir
32
+ from arpakitlib.ar_func_util import raise_if_not_async_func, is_async_function
32
33
  from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str_to_json_obj
33
34
  from arpakitlib.ar_logging_util import setup_normal_logging
34
35
  from arpakitlib.ar_sqlalchemy_model_util import StoryLogDBM
35
36
  from arpakitlib.ar_sqlalchemy_util import SQLAlchemyDB
36
- from arpakitlib.ar_type_util import raise_for_type, raise_if_not_async_func, raise_if_none
37
+ from arpakitlib.ar_type_util import raise_for_type, raise_if_none
37
38
 
38
39
  _ARPAKIT_LIB_MODULE_VERSION = "3.0"
39
40
 
@@ -250,7 +251,7 @@ def create_handle_exception(
250
251
  _func_data = func(
251
252
  status_code=status_code, error_so=error_so, request=request, exception=exception, **_kwargs
252
253
  )
253
- if asyncio.iscoroutine(_func_data):
254
+ if is_async_function(_func_data):
254
255
  _func_data = await _func_data
255
256
  if _func_data is not None:
256
257
  status_code, error_so, _kwargs = _func_data[0], _func_data[1], _func_data[2]
@@ -470,19 +471,49 @@ class BaseAPIAuthData(BaseModel):
470
471
  token_string: str | None = None
471
472
  api_key_string: str | None = None
472
473
 
474
+ is_token_string_correct: bool | None = None
475
+ is_api_key_string_correct: bool | None = None
476
+
473
477
 
474
478
  def base_api_auth(
475
479
  *,
476
480
  require_api_key_string: bool = False,
477
- require_token_string: bool = False
481
+ require_token_string: bool = False,
482
+ validate_api_key_func: Callable | None = None,
483
+ validate_token_func: Callable | None = None,
484
+ correct_api_keys: str | list[str] | None = None,
485
+ correct_tokens: str | list[str] | None = None,
486
+ require_correct_api_key: bool = False,
487
+ require_correct_token: bool = False,
478
488
  ) -> Callable:
489
+ if isinstance(correct_api_keys, str):
490
+ correct_api_keys = [correct_api_keys]
491
+ if correct_api_keys is not None:
492
+ raise_for_type(correct_api_keys, list)
493
+ validate_api_key_func = lambda *args, **kwargs: kwargs["api_key_string"] in correct_api_keys
494
+
495
+ if isinstance(correct_tokens, str):
496
+ correct_tokens = [correct_tokens]
497
+ if correct_tokens is not None:
498
+ raise_for_type(correct_tokens, list)
499
+ validate_token_func = lambda *args, **kwargs: kwargs["token_string"] in correct_tokens
500
+
501
+ if require_correct_api_key:
502
+ raise_if_none(validate_api_key_func)
503
+ require_api_key_string = True
504
+
505
+ if require_correct_token:
506
+ raise_if_none(validate_token_func)
507
+ require_token_string = True
508
+
479
509
  async def func(
480
510
  *,
481
511
  ac: fastapi.security.HTTPAuthorizationCredentials | None = fastapi.Security(
482
512
  fastapi.security.HTTPBearer(auto_error=False)
483
513
  ),
484
514
  api_key_string: str | None = Security(APIKeyHeader(name="apikey", auto_error=False)),
485
- request: starlette.requests.Request
515
+ request: starlette.requests.Request,
516
+ transmitted_api_data: BaseTransmittedAPIData = Depends(get_transmitted_api_data)
486
517
  ) -> BaseAPIAuthData:
487
518
 
488
519
  api_auth_data = BaseAPIAuthData(
@@ -537,6 +568,8 @@ def base_api_auth(
537
568
  if not api_auth_data.token_string:
538
569
  api_auth_data.token_string = None
539
570
 
571
+ # api_key
572
+
540
573
  if require_api_key_string and not api_auth_data.api_key_string:
541
574
  raise APIException(
542
575
  status_code=starlette.status.HTTP_401_UNAUTHORIZED,
@@ -544,6 +577,8 @@ def base_api_auth(
544
577
  error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
545
578
  )
546
579
 
580
+ # token
581
+
547
582
  if require_token_string and not api_auth_data.token_string:
548
583
  raise APIException(
549
584
  status_code=starlette.status.HTTP_401_UNAUTHORIZED,
@@ -551,49 +586,55 @@ def base_api_auth(
551
586
  error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
552
587
  )
553
588
 
554
- return api_auth_data
589
+ # api_key
555
590
 
556
- return func
591
+ if validate_api_key_func is not None:
592
+ validate_api_key_func_data = validate_api_key_func(
593
+ api_key_string=api_auth_data.api_key_string,
594
+ token_string=api_auth_data.token_string,
595
+ base_api_auth_data=api_auth_data,
596
+ transmitted_api_data=transmitted_api_data,
597
+ request=request
598
+ )
599
+ if is_async_function(validate_api_key_func_data):
600
+ validate_api_key_func_data = await validate_api_key_func_data
601
+ api_auth_data.is_api_key_string_correct = validate_api_key_func_data
557
602
 
603
+ # token
558
604
 
559
- class CheckAPIKeyAPIAuthData(BaseAPIAuthData):
560
- is_api_key_correct: bool | None = None
605
+ if validate_token_func is not None:
606
+ validate_token_func_data = validate_token_func(
607
+ api_key_string=api_auth_data.api_key_string,
608
+ token_string=api_auth_data.token_string,
609
+ base_api_auth_data=api_auth_data,
610
+ transmitted_api_data=transmitted_api_data,
611
+ request=request
612
+ )
613
+ if is_async_function(validate_token_func_data):
614
+ validate_token_func_data_data = await validate_token_func_data
615
+ api_auth_data.is_token_string_correct = validate_token_func_data_data
561
616
 
617
+ # api_key
562
618
 
563
- def api_key_api_auth(
564
- *,
565
- validate_api_key_func: Callable | None = None,
566
- correct_api_key: str | None = None
567
- ):
568
- if correct_api_key is not None:
569
- validate_api_key_func = lambda *args, **kwargs: kwargs["api_key_string"] == correct_api_key
570
- raise_if_none(validate_api_key_func)
619
+ if require_correct_api_key:
620
+ if not api_auth_data.is_api_key_string_correct:
621
+ raise APIException(
622
+ status_code=starlette.status.HTTP_401_UNAUTHORIZED,
623
+ error_code=BaseAPIErrorCodes.cannot_authorize,
624
+ error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
625
+ )
571
626
 
572
- async def func(
573
- *,
574
- base_api_auth_data: BaseAPIAuthData = Depends(base_api_auth(
575
- require_api_key_string=True,
576
- require_token_string=False
577
- )),
578
- transmitted_api_data: BaseTransmittedAPIData = Depends(get_transmitted_api_data),
579
- request: starlette.requests.Request
580
- ) -> CheckAPIKeyAPIAuthData:
581
- check_api_key_api_auth_data = CheckAPIKeyAPIAuthData.model_validate(base_api_auth_data)
582
- check_api_key_api_auth_data.is_api_key_correct = validate_api_key_func(
583
- api_key_string=base_api_auth_data.api_key_string,
584
- base_api_auth_data=base_api_auth_data,
585
- transmitted_api_data=transmitted_api_data,
586
- request=request
587
- )
627
+ # token
588
628
 
589
- if not check_api_key_api_auth_data.is_api_key_correct:
590
- raise APIException(
591
- status_code=starlette.status.HTTP_401_UNAUTHORIZED,
592
- error_code=BaseAPIErrorCodes.cannot_authorize,
593
- error_data=safely_transfer_obj_to_json_str_to_json_obj(check_api_key_api_auth_data.model_dump())
594
- )
629
+ if require_correct_token:
630
+ if not api_auth_data.is_token_string_correct:
631
+ raise APIException(
632
+ status_code=starlette.status.HTTP_401_UNAUTHORIZED,
633
+ error_code=BaseAPIErrorCodes.cannot_authorize,
634
+ error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
635
+ )
595
636
 
596
- return check_api_key_api_auth_data
637
+ return api_auth_data
597
638
 
598
639
  return func
599
640
 
@@ -0,0 +1,51 @@
1
+ import asyncio
2
+ import inspect
3
+ from typing import Callable
4
+
5
+ _ARPAKIT_LIB_MODULE_VERSION = "3.0"
6
+
7
+
8
+ def is_async_function(func: Callable) -> bool:
9
+ return asyncio.iscoroutinefunction(func)
10
+
11
+
12
+ def is_sync_function(func: Callable) -> bool:
13
+ return inspect.isfunction(func) and not is_async_function(func)
14
+
15
+
16
+ def raise_if_not_async_func(func: Callable):
17
+ if not is_async_function(func):
18
+ raise TypeError(f"The provided function '{func.__name__}' is not an async function")
19
+
20
+
21
+ def raise_if_not_sync_func(func: Callable):
22
+ if not is_sync_function(func):
23
+ raise TypeError(f"The provided function '{func.__name__}' is not a sync function")
24
+
25
+
26
+ def raise_if_async_func(func: Callable):
27
+ if is_async_function(func):
28
+ raise TypeError(f"The provided function '{func.__name__}' should not be async")
29
+
30
+
31
+ def raise_if_sync_func(func: Callable):
32
+ if is_sync_function(func):
33
+ raise TypeError(f"The provided function '{func.__name__}' should not be sync")
34
+
35
+
36
+ def __example():
37
+ def one():
38
+ pass
39
+
40
+ async def two():
41
+ pass
42
+
43
+ print(is_sync_function(one))
44
+ print(is_sync_function(two))
45
+
46
+ print(is_async_function(one))
47
+ print(is_async_function(two))
48
+
49
+
50
+ if __name__ == '__main__':
51
+ __example()
@@ -67,11 +67,6 @@ def raise_for_types(comparable, need_types, comment_for_error: Optional[str] = N
67
67
  raise TypeError(err)
68
68
 
69
69
 
70
- def raise_if_not_async_func(func: Any):
71
- if not inspect.iscoroutinefunction(func):
72
- raise TypeError(f"The provided function '{func.__name__}' is not an async function")
73
-
74
-
75
70
  def make_none_to_false(v: Any) -> Any:
76
71
  if v is None:
77
72
  return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: arpakitlib
3
- Version: 1.7.76
3
+ Version: 1.7.78
4
4
  Summary: arpakitlib
5
5
  Home-page: https://github.com/ARPAKIT-Company/arpakitlib
6
6
  License: Apache-2.0
@@ -73,7 +73,7 @@ arpakitlib/_arpakit_project_template/src/additional_model/__init__.py,sha256=47D
73
73
  arpakitlib/_arpakit_project_template/src/additional_model/additional_model.py,sha256=4KCOvto9Hj5eMYpvfaJChghhR9bkCvKluGGPWrTezoY,134
74
74
  arpakitlib/_arpakit_project_template/src/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  arpakitlib/_arpakit_project_template/src/api/asgi.py,sha256=a5UBxOyNC8NG3E0ayhiDo3t5tPoB3WtOf2gbZJFWBAA,74
76
- arpakitlib/_arpakit_project_template/src/api/auth.py,sha256=onnmSwjtc0aX7y6X2GCqayKcZ85Besz0KoElctv-H-w,228
76
+ arpakitlib/_arpakit_project_template/src/api/auth.py,sha256=bf5DtYA3q7HgyIIrzr1-X-AUfNfYe41mGV6Si977nxg,701
77
77
  arpakitlib/_arpakit_project_template/src/api/const.py,sha256=7d4qD5hedqr7QxVzbfsA7E1bNZn2Pm2U8joXGtpANu0,287
78
78
  arpakitlib/_arpakit_project_template/src/api/create_api_app.py,sha256=lDE77W6WkeAeRB_vJY3TXRTa3HeiO-t26eTtG7v8j6U,4594
79
79
  arpakitlib/_arpakit_project_template/src/api/event.py,sha256=58wCVyVSIe_kydWi44M0Wvp7bTnV8xvO30gMXzjbFYc,750
@@ -93,7 +93,7 @@ arpakitlib/_arpakit_project_template/src/api/util.py,sha256=47DEQpj8HBSa-_TImW-5
93
93
  arpakitlib/_arpakit_project_template/src/business_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  arpakitlib/_arpakit_project_template/src/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
95
  arpakitlib/_arpakit_project_template/src/core/const.py,sha256=CZZew674y7LhCAlYhvuF5cV4Zb9nQ17j2Tcuj2GEBf4,1232
96
- arpakitlib/_arpakit_project_template/src/core/settings.py,sha256=VR2wHHkiTc4GKfddt-UeeQ1zZREL1njBRuHsi7JWLuQ,2197
96
+ arpakitlib/_arpakit_project_template/src/core/settings.py,sha256=S1WPgnFWiRNjCXLllZHq6xp3AiyzzqnRBubg02iRkvo,2238
97
97
  arpakitlib/_arpakit_project_template/src/core/util.py,sha256=5R8gvcZdvuDQes45FBnLC2IDv2Jhajp1VhJJYNKYjMQ,1539
98
98
  arpakitlib/_arpakit_project_template/src/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
99
  arpakitlib/_arpakit_project_template/src/db/sqlalchemy_model.py,sha256=nXtayUkBaVb6tWx5qJgXZLbLOTVAjnSLpSDxBm7yZLc,234
@@ -148,9 +148,10 @@ arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css,sha256=jzPZlgJTFwSdSphk9C
148
148
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css.map,sha256=5wq8eXMLU6Zxb45orZPL1zAsBFJReFw6GjYqGpUX3hg,262650
149
149
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js,sha256=ffrLZHHEQ_g84A-ul3yWa10Kk09waOAxHcQXPuZuavg,339292
150
150
  arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map,sha256=9UhIW7MqCOZPAz1Sl1IKfZUuhWU0p-LJqrnjjJD9Xhc,1159454
151
- arpakitlib/ar_fastapi_util.py,sha256=9gUzWhtqBV8stxPmWQ76Btw8rzWGFoBjRwMofGWdyhQ,25258
151
+ arpakitlib/ar_fastapi_util.py,sha256=7VwkGwH2YXTx5i5HgX6sFg16wH3YyFSu8yNyP_4Sxtc,27078
152
152
  arpakitlib/ar_file_storage_in_dir_util.py,sha256=D3e3rGuHoI6xqAA5mVvEpVVpOWY1jyjNsjj2UhyHRbE,3674
153
153
  arpakitlib/ar_file_util.py,sha256=GUdJYm1tUZnYpY-SIPRHAZBHGra8NKy1eYEI0D5AfhY,489
154
+ arpakitlib/ar_func_util.py,sha256=aqcweSuaY73FbCly844sSnlud63g4TRkKhSwUUN-QM0,1239
154
155
  arpakitlib/ar_hash_util.py,sha256=Iqy6KBAOLBQMFLWv676boI5sV7atT2B-fb7aCdHOmIQ,340
155
156
  arpakitlib/ar_http_request_util.py,sha256=Kp2wKU4wGPsJ6m5sLwCEKWMs3Uqa59SUxhBevU6Gk_s,4328
156
157
  arpakitlib/ar_ip_util.py,sha256=aEAa1Hvobh9DWX7cmBAPLqnXSTiKe2hRk-WJaiKMaI8,1009
@@ -174,12 +175,12 @@ arpakitlib/ar_sqlalchemy_model_util.py,sha256=AuD0L4b-h0g3VqGoFHWK5JIet_Jxpg49o7
174
175
  arpakitlib/ar_sqlalchemy_util.py,sha256=Hcg1THrDsSR_-8dsY1CG3NWPEv0FqCbkPXFXLtjlSJ0,4207
175
176
  arpakitlib/ar_ssh_runner_util.py,sha256=e9deuUdBW7Eh0Exx2nTBhk57SaOZYaJaSjNk8q6dbJk,6804
176
177
  arpakitlib/ar_str_util.py,sha256=tFoGSDYoGpfdVHWor5Li9pEOFmDFlHkX-Z8iOy1LK7Y,3537
177
- arpakitlib/ar_type_util.py,sha256=46ZMuWls3uN0Re5T0sfEAmyNUDnxn9yvj6dHivSDZKs,3915
178
+ arpakitlib/ar_type_util.py,sha256=s0NsTM7mV3HuwyRwyYLdNn7Ep2HbyI4FIr-dd8x0lfI,3734
178
179
  arpakitlib/ar_yookassa_api_client_util.py,sha256=sh4fcUkAkdOetFn9JYoTvjcSXP-M1wU04KEY-ECLfLg,5137
179
180
  arpakitlib/ar_zabbix_api_client_util.py,sha256=Q-VR4MvoZ9aHwZeYZr9G3LwN-ANx1T5KFmF6pvPM-9M,6402
180
- arpakitlib-1.7.76.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
181
- arpakitlib-1.7.76.dist-info/METADATA,sha256=sat8Sj_1M9alTRio_zyVPE5uwkUufovTjH-aubogASI,2824
182
- arpakitlib-1.7.76.dist-info/NOTICE,sha256=95aUzaPJjVpDsGAsNzVnq7tHTxAl0s5UFznCTkVCau4,763
183
- arpakitlib-1.7.76.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
184
- arpakitlib-1.7.76.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
185
- arpakitlib-1.7.76.dist-info/RECORD,,
181
+ arpakitlib-1.7.78.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
182
+ arpakitlib-1.7.78.dist-info/METADATA,sha256=dMQB2b6Psj0ky04X33tUTYPkNADnuFbNEMWVBgLKfvk,2824
183
+ arpakitlib-1.7.78.dist-info/NOTICE,sha256=95aUzaPJjVpDsGAsNzVnq7tHTxAl0s5UFznCTkVCau4,763
184
+ arpakitlib-1.7.78.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
185
+ arpakitlib-1.7.78.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
186
+ arpakitlib-1.7.78.dist-info/RECORD,,