arpakitlib 1.6.34__py3-none-any.whl → 1.6.37__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.
- arpakitlib/ar_fastapi_util.py +110 -3
- arpakitlib/ar_schedule_uust_api_client_util.py +7 -4
- {arpakitlib-1.6.34.dist-info → arpakitlib-1.6.37.dist-info}/METADATA +1 -1
- {arpakitlib-1.6.34.dist-info → arpakitlib-1.6.37.dist-info}/RECORD +8 -8
- /arpakitlib/{ar_arpakit_schedule_uust_api_client.py → ar_arpakit_schedule_uust_api_client_util.py} +0 -0
- {arpakitlib-1.6.34.dist-info → arpakitlib-1.6.37.dist-info}/LICENSE +0 -0
- {arpakitlib-1.6.34.dist-info → arpakitlib-1.6.37.dist-info}/NOTICE +0 -0
- {arpakitlib-1.6.34.dist-info → arpakitlib-1.6.37.dist-info}/WHEEL +0 -0
arpakitlib/ar_fastapi_util.py
CHANGED
@@ -13,11 +13,13 @@ from typing import Any, Callable
|
|
13
13
|
|
14
14
|
import fastapi.exceptions
|
15
15
|
import fastapi.responses
|
16
|
+
import fastapi.security
|
16
17
|
import starlette.exceptions
|
17
18
|
import starlette.requests
|
18
19
|
import starlette.status
|
19
|
-
from fastapi import FastAPI, APIRouter, Query
|
20
|
+
from fastapi import FastAPI, APIRouter, Query, Security
|
20
21
|
from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
|
22
|
+
from fastapi.security import APIKeyHeader
|
21
23
|
from jaraco.context import suppress
|
22
24
|
from pydantic import BaseModel, ConfigDict
|
23
25
|
from starlette.middleware.cors import CORSMiddleware
|
@@ -430,6 +432,100 @@ def get_transmitted_api_data(request: starlette.requests.Request) -> BaseTransmi
|
|
430
432
|
return request.app.state.transmitted_api_data
|
431
433
|
|
432
434
|
|
435
|
+
class BaseNeedAPIAuthData(BaseModel):
|
436
|
+
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True, from_attributes=True)
|
437
|
+
|
438
|
+
token_string: str | None = None
|
439
|
+
apikey_string: str | None = None
|
440
|
+
|
441
|
+
|
442
|
+
def need_api_auth(
|
443
|
+
*,
|
444
|
+
require_apikey_string: bool = False,
|
445
|
+
require_token_string: bool = False,
|
446
|
+
) -> Callable:
|
447
|
+
async def func(
|
448
|
+
*,
|
449
|
+
ac: fastapi.security.HTTPAuthorizationCredentials | None = fastapi.Security(
|
450
|
+
fastapi.security.HTTPBearer(auto_error=False)
|
451
|
+
),
|
452
|
+
apikey_string: str | None = Security(APIKeyHeader(name="apikey", auto_error=False)),
|
453
|
+
request: fastapi.Request
|
454
|
+
) -> BaseNeedAPIAuthData:
|
455
|
+
|
456
|
+
_error_data = {
|
457
|
+
"require_apikey_string": require_apikey_string,
|
458
|
+
"require_token_string": require_token_string
|
459
|
+
}
|
460
|
+
|
461
|
+
res = BaseNeedAPIAuthData()
|
462
|
+
|
463
|
+
# apikey
|
464
|
+
|
465
|
+
res.apikey_string = apikey_string
|
466
|
+
|
467
|
+
if not res.apikey_string and "api_key" in request.headers.keys():
|
468
|
+
res.apikey_string = request.headers["api_key"]
|
469
|
+
if not res.apikey_string and "apikey" in request.headers.keys():
|
470
|
+
res.apikey_string = request.headers["apikey"]
|
471
|
+
|
472
|
+
if not res.apikey_string and "apikey" in request.query_params.keys():
|
473
|
+
res.apikey_string = request.query_params["apikey"]
|
474
|
+
if not res.apikey_string and "api_key" in request.query_params.keys():
|
475
|
+
res.apikey_string = request.query_params["api_key"]
|
476
|
+
|
477
|
+
_error_data["res.apikey_string"] = res.apikey_string
|
478
|
+
|
479
|
+
# token
|
480
|
+
|
481
|
+
res.token_string = ac.credentials if ac and ac.credentials and ac.credentials.strip() else None
|
482
|
+
|
483
|
+
if not res.token_string and "token" in request.headers.keys():
|
484
|
+
res.token_string = request.headers["token"]
|
485
|
+
|
486
|
+
if not res.token_string and "token" in request.query_params.keys():
|
487
|
+
res.token_string = request.query_params["token"]
|
488
|
+
|
489
|
+
if not res.token_string and "user_token" in request.headers.keys():
|
490
|
+
res.token_string = request.headers["user_token"]
|
491
|
+
if not res.token_string and "usertoken" in request.headers.keys():
|
492
|
+
res.token_string = request.headers["usertoken"]
|
493
|
+
if not res.token_string and "user-token" in request.headers.keys():
|
494
|
+
res.token_string = request.headers["user-token"]
|
495
|
+
|
496
|
+
if not res.token_string and "user_token" in request.query_params.keys():
|
497
|
+
res.token_string = request.query_params["user_token"]
|
498
|
+
if not res.token_string and "usertoken" in request.query_params.keys():
|
499
|
+
res.token_string = request.query_params["usertoken"]
|
500
|
+
if not res.token_string and "user-token" in request.query_params.keys():
|
501
|
+
res.token_string = request.query_params["user-token"]
|
502
|
+
|
503
|
+
if res.token_string:
|
504
|
+
res.token_string = res.token_string.strip()
|
505
|
+
if not res.token_string:
|
506
|
+
res.token_string = None
|
507
|
+
|
508
|
+
_error_data["res.token_string"] = res.token_string
|
509
|
+
|
510
|
+
if require_apikey_string and not res.apikey_string:
|
511
|
+
raise APIException(
|
512
|
+
status_code=starlette.status.HTTP_401_UNAUTHORIZED,
|
513
|
+
error_code=ErrorSO.APIErrorCodes.cannot_authorize,
|
514
|
+
error_data=_error_data
|
515
|
+
)
|
516
|
+
|
517
|
+
if require_token_string and not res.token_string:
|
518
|
+
raise APIException(
|
519
|
+
status_code=starlette.status.HTTP_401_UNAUTHORIZED,
|
520
|
+
error_code=ErrorSO.APIErrorCodes.cannot_authorize,
|
521
|
+
error_data=_error_data
|
522
|
+
)
|
523
|
+
|
524
|
+
return res
|
525
|
+
|
526
|
+
return func
|
527
|
+
|
528
|
+
|
433
529
|
def simple_api_router_for_testing():
|
434
530
|
router = APIRouter(tags=["Testing"])
|
435
531
|
|
@@ -468,6 +564,12 @@ def simple_api_router_for_testing():
|
|
468
564
|
return router
|
469
565
|
|
470
566
|
|
567
|
+
_DEFAULT_CONTACT = {
|
568
|
+
"name": "arpakit",
|
569
|
+
"email": "support@arpakit.com"
|
570
|
+
}
|
571
|
+
|
572
|
+
|
471
573
|
def create_fastapi_app(
|
472
574
|
*,
|
473
575
|
title: str = "arpakitlib FastAPI",
|
@@ -477,8 +579,12 @@ def create_fastapi_app(
|
|
477
579
|
startup_api_events: list[BaseStartupAPIEvent] | None = None,
|
478
580
|
shutdown_api_events: list[BaseStartupAPIEvent] | None = None,
|
479
581
|
transmitted_api_data: BaseTransmittedAPIData = BaseTransmittedAPIData(),
|
480
|
-
main_api_router: APIRouter = simple_api_router_for_testing()
|
582
|
+
main_api_router: APIRouter = simple_api_router_for_testing(),
|
583
|
+
contact: dict[str, Any] | None = None
|
481
584
|
):
|
585
|
+
if contact is None:
|
586
|
+
contact = _DEFAULT_CONTACT
|
587
|
+
|
482
588
|
setup_normal_logging(log_filepath=log_filepath)
|
483
589
|
|
484
590
|
if not startup_api_events:
|
@@ -494,7 +600,8 @@ def create_fastapi_app(
|
|
494
600
|
redoc_url=None,
|
495
601
|
openapi_url="/openapi",
|
496
602
|
on_startup=[api_startup_event.async_on_startup for api_startup_event in startup_api_events],
|
497
|
-
on_shutdown=[api_shutdown_event.async_on_shutdown for api_shutdown_event in shutdown_api_events]
|
603
|
+
on_shutdown=[api_shutdown_event.async_on_shutdown for api_shutdown_event in shutdown_api_events],
|
604
|
+
contact=contact
|
498
605
|
)
|
499
606
|
|
500
607
|
app.state.transmitted_api_data = transmitted_api_data
|
@@ -52,23 +52,26 @@ class ScheduleUUSTAPIClient:
|
|
52
52
|
elif self.api_password_first_part:
|
53
53
|
return {
|
54
54
|
"login": self.api_login,
|
55
|
-
"pass": self.generate_v2_token(
|
55
|
+
"pass": self.generate_v2_token()
|
56
56
|
}
|
57
57
|
else:
|
58
58
|
return {}
|
59
59
|
|
60
60
|
@classmethod
|
61
|
-
def
|
61
|
+
def hash_new_token(cls, token: str) -> str:
|
62
62
|
sha256 = hashlib.sha256()
|
63
63
|
sha256.update(token.encode('utf-8'))
|
64
64
|
return sha256.hexdigest()
|
65
65
|
|
66
66
|
@classmethod
|
67
|
-
def
|
68
|
-
return cls.
|
67
|
+
def generate_new_v2_token(cls, password_first_part: str) -> str:
|
68
|
+
return cls.hash_new_token(
|
69
69
|
password_first_part + datetime.now(tz=pytz.timezone("Asia/Yekaterinburg")).strftime("%Y-%m-%d")
|
70
70
|
)
|
71
71
|
|
72
|
+
def generate_v2_token(self) -> str:
|
73
|
+
return self.generate_new_v2_token(password_first_part=self.api_password_first_part)
|
74
|
+
|
72
75
|
async def _async_make_http_get_request(
|
73
76
|
self,
|
74
77
|
*,
|
@@ -6,7 +6,7 @@ arpakitlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
arpakitlib/ar_additional_model_util.py,sha256=t95M4Ggl7EBRj7qOJHmuo5p2YmE7LlJdEAMNzse3vhE,309
|
7
7
|
arpakitlib/ar_aiogram_util.py,sha256=zQ5txWe359U8LCSD-jvSz1Ol8N40bEg3DdTRbdRD8fU,11974
|
8
8
|
arpakitlib/ar_arpakit_lib_module_util.py,sha256=V_mc3Ml73Tzz3arxmwEfIxruKMyrwbe8XZ9FfVDtUXY,5446
|
9
|
-
arpakitlib/
|
9
|
+
arpakitlib/ar_arpakit_schedule_uust_api_client_util.py,sha256=SYWWQDohPnw0qpBIu2hEvGZRVdaI4NUUQdEjnMnseo4,18237
|
10
10
|
arpakitlib/ar_arpakitlib_info.py,sha256=cvgrLnEznmYkCAg1adbY46ATjD6GJd-Yk8PTgOPjpKM,248
|
11
11
|
arpakitlib/ar_base64_util.py,sha256=aZkg2cZTuAaP2IWeG_LXJ6RO7qhyskVwec-Lks0iM-k,676
|
12
12
|
arpakitlib/ar_base_worker_util.py,sha256=8ruBoF9pARf3yc5duAajUOBi7Cce5KFAkp66lShRf7U,2796
|
@@ -35,7 +35,7 @@ arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css,sha256=jzPZlgJTFwSdSphk9C
|
|
35
35
|
arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.css.map,sha256=5wq8eXMLU6Zxb45orZPL1zAsBFJReFw6GjYqGpUX3hg,262650
|
36
36
|
arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js,sha256=ffrLZHHEQ_g84A-ul3yWa10Kk09waOAxHcQXPuZuavg,339292
|
37
37
|
arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map,sha256=9UhIW7MqCOZPAz1Sl1IKfZUuhWU0p-LJqrnjjJD9Xhc,1159454
|
38
|
-
arpakitlib/ar_fastapi_util.py,sha256=
|
38
|
+
arpakitlib/ar_fastapi_util.py,sha256=VoWJDJnBKcoej5OOgz0C_vqmOe5xz8e_5tW8zMw0VCI,20687
|
39
39
|
arpakitlib/ar_file_storage_in_dir_util.py,sha256=D3e3rGuHoI6xqAA5mVvEpVVpOWY1jyjNsjj2UhyHRbE,3674
|
40
40
|
arpakitlib/ar_generate_env_example.py,sha256=R_pdbFZe-mIZxEps2dm-K9m8rAg1pAaMzFOBPTGe4s4,370
|
41
41
|
arpakitlib/ar_hash_util.py,sha256=Iqy6KBAOLBQMFLWv676boI5sV7atT2B-fb7aCdHOmIQ,340
|
@@ -54,7 +54,7 @@ arpakitlib/ar_operation_execution_util.py,sha256=w_dz4XYEM4WbTxpBoYVkknG3U3_391c
|
|
54
54
|
arpakitlib/ar_parse_command.py,sha256=qpr2OwG3Bf7DFiL9S3iWgtbvtE80RSC35E5zFJvjG1I,2714
|
55
55
|
arpakitlib/ar_postgresql_util.py,sha256=1AuLjEaa1Lg4pzn-ukCVnDi35Eg1k91APRTqZhIJAdo,945
|
56
56
|
arpakitlib/ar_run_cmd_util.py,sha256=D_rPavKMmWkQtwvZFz-Io5Ak8eSODHkcFeLPzNVC68g,1072
|
57
|
-
arpakitlib/ar_schedule_uust_api_client_util.py,sha256=
|
57
|
+
arpakitlib/ar_schedule_uust_api_client_util.py,sha256=Z5BNiHdKWqHmmycinwCbX5_pSNBB59Qn9urvUXU0RDk,5877
|
58
58
|
arpakitlib/ar_sleep_util.py,sha256=9ZN4Qo4eZ_q3hjM7vNBQjFRcH-9-sqv3QLSjnxVJE90,1405
|
59
59
|
arpakitlib/ar_sqlalchemy_model_util.py,sha256=ttdgOwQfoHTKqgivBtXoSbJoBCASHDjLEFK5tJ9kNNE,4779
|
60
60
|
arpakitlib/ar_sqlalchemy_util.py,sha256=3jKHu5aUFPUQ492dWaisN0Y_-r2Pif16SfNawrQ_6xY,4012
|
@@ -63,8 +63,8 @@ arpakitlib/ar_str_util.py,sha256=xSEzmsDvRiZVaxyqFFjcgzpphktCbXg2FHcvsd1DYpA,188
|
|
63
63
|
arpakitlib/ar_type_util.py,sha256=I6jbTz7_dxR1lkhz1JfUb5ZyLLdXVhG_-hzjdgT6N6s,1932
|
64
64
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=5GMvu8paByni8buhc1vpHB7n6oXe0gPfj1LSvnyZCrQ,5307
|
65
65
|
arpakitlib/ar_zabbix_util.py,sha256=Q-VR4MvoZ9aHwZeYZr9G3LwN-ANx1T5KFmF6pvPM-9M,6402
|
66
|
-
arpakitlib-1.6.
|
67
|
-
arpakitlib-1.6.
|
68
|
-
arpakitlib-1.6.
|
69
|
-
arpakitlib-1.6.
|
70
|
-
arpakitlib-1.6.
|
66
|
+
arpakitlib-1.6.37.dist-info/LICENSE,sha256=1jqWIkbnMxDfs_i0SXP5qbV6PHjBr1g8506oW7uPjfg,11347
|
67
|
+
arpakitlib-1.6.37.dist-info/METADATA,sha256=dQxSVu2TKCD_JZibRrI4f98gpFjmgRJNywUEFJoP_yY,2320
|
68
|
+
arpakitlib-1.6.37.dist-info/NOTICE,sha256=wHwmiq3wExfFfgMsE5U5TOBP9_l72ocIG82KurEels0,43
|
69
|
+
arpakitlib-1.6.37.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
70
|
+
arpakitlib-1.6.37.dist-info/RECORD,,
|
/arpakitlib/{ar_arpakit_schedule_uust_api_client.py → ar_arpakit_schedule_uust_api_client_util.py}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|