arpakitlib 1.7.257__py3-none-any.whl → 1.8.1__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/{_arpakit_project_template → _arpakit_project_template_v_1}/README.md +1 -1
- arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic/env.py +3 -3
- arpakitlib/_arpakit_project_template_v_1/api/asgi.py +3 -0
- arpakitlib/_arpakit_project_template_v_1/api/auth.py +235 -0
- arpakitlib/_arpakit_project_template_v_1/api/const.py +18 -0
- arpakitlib/_arpakit_project_template_v_1/api/create_api_app.py +71 -0
- arpakitlib/_arpakit_project_template_v_1/api/event.py +74 -0
- arpakitlib/_arpakit_project_template_v_1/api/exception.py +38 -0
- arpakitlib/_arpakit_project_template_v_1/api/exception_handler.py +308 -0
- arpakitlib/_arpakit_project_template_v_1/api/openapi_ui.py +28 -0
- arpakitlib/_arpakit_project_template_v_1/api/response.py +31 -0
- arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/api/router/main_router.py +4 -3
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/arpakit_project_template.py +22 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/check_auth.py +30 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/clear_log_file.py +25 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/get_errors_info.py +24 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/get_log_file.py +23 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/healthcheck.py +21 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/main_router.py +67 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/now_utc_datetime.py +21 -0
- arpakitlib/_arpakit_project_template_v_1/api/router/v1/raise_fake_error.py +35 -0
- arpakitlib/_arpakit_project_template_v_1/api/schema/base_schema.py +26 -0
- arpakitlib/_arpakit_project_template_v_1/api/schema/common/in_.py +5 -0
- arpakitlib/_arpakit_project_template_v_1/api/schema/common/out.py +60 -0
- arpakitlib/_arpakit_project_template_v_1/api/schema/v1/in_.py +5 -0
- arpakitlib/_arpakit_project_template_v_1/api/schema/v1/out.py +47 -0
- arpakitlib/_arpakit_project_template_v_1/arpakitlib_project_template.json +3 -0
- arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/business_service/hello_world.py +1 -1
- arpakitlib/_arpakit_project_template_v_1/business_service/remove_operations.py +51 -0
- arpakitlib/_arpakit_project_template_v_1/command/alembic_history.sh +2 -0
- arpakitlib/_arpakit_project_template_v_1/command/alembic_revision_autogenerate.sh +2 -0
- arpakitlib/{_arpakit_project_template/manage/json_beautify.py → _arpakit_project_template_v_1/command/beautify_json.py} +2 -2
- arpakitlib/{_arpakit_project_template/src/core/_check_logging.py → _arpakit_project_template_v_1/command/check_logging.py} +3 -3
- arpakitlib/_arpakit_project_template_v_1/command/check_sqlalchemy_db.py +11 -0
- arpakitlib/_arpakit_project_template_v_1/command/drop_json_db.py +13 -0
- arpakitlib/_arpakit_project_template_v_1/command/drop_sqlalchemy_db.py +14 -0
- arpakitlib/{_arpakit_project_template/src/core/_generate_settings_env_example.py → _arpakit_project_template_v_1/command/generate_settings_env_example.py} +4 -4
- arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/hello_world.py +2 -2
- arpakitlib/_arpakit_project_template_v_1/command/init_json_db.py +11 -0
- arpakitlib/_arpakit_project_template_v_1/command/init_sqlalchemy_db.py +11 -0
- arpakitlib/_arpakit_project_template_v_1/command/reinit_json_db.py +13 -0
- arpakitlib/_arpakit_project_template_v_1/command/reinit_sqlalchemy_db.py +13 -0
- arpakitlib/_arpakit_project_template_v_1/command/remove_operations.py +13 -0
- arpakitlib/_arpakit_project_template_v_1/command/remove_story_logs.py +16 -0
- arpakitlib/_arpakit_project_template_v_1/command/rm_all_records_in_json_db.py +13 -0
- arpakitlib/{_arpakit_project_template/src/core/_show_settings.py → _arpakit_project_template_v_1/command/show_settings.py} +3 -3
- arpakitlib/{_arpakit_project_template/src/api/_start_api_with_reload.py → _arpakit_project_template_v_1/command/start_api_with_reload.py} +5 -5
- arpakitlib/{_arpakit_project_template/src/api/_start_api_without_reload.py → _arpakit_project_template_v_1/command/start_api_without_reload.py} +5 -5
- arpakitlib/_arpakit_project_template_v_1/command/start_async_operation_executor_worker.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/command/start_async_scheduled_operation_creator_worker.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/command/start_sync_operation_executor_worker.py +15 -0
- arpakitlib/_arpakit_project_template_v_1/command/start_sync_operation_executor_workers.py +22 -0
- arpakitlib/_arpakit_project_template_v_1/command/start_sync_scheduled_operation_creator_worker.py +12 -0
- arpakitlib/_arpakit_project_template_v_1/core/cache_file_storage_in_dir.py +23 -0
- arpakitlib/_arpakit_project_template_v_1/core/const.py +33 -0
- arpakitlib/_arpakit_project_template_v_1/core/dump_file_storage_in_dir.py +23 -0
- arpakitlib/_arpakit_project_template_v_1/core/jinja2_templates.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/core/media_file_storage_in_dir.py +23 -0
- arpakitlib/_arpakit_project_template_v_1/core/settings.py +195 -0
- arpakitlib/_arpakit_project_template_v_1/core/util.py +29 -0
- arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/example.env +13 -7
- arpakitlib/_arpakit_project_template_v_1/json_db/json_db.py +28 -0
- arpakitlib/_arpakit_project_template_v_1/operation_execution/operation_executor_worker.py +256 -0
- arpakitlib/_arpakit_project_template_v_1/operation_execution/scheduled_operation_creator_worker.py +106 -0
- arpakitlib/_arpakit_project_template_v_1/operation_execution/scheduled_operations.py +49 -0
- arpakitlib/_arpakit_project_template_v_1/operation_execution/util.py +29 -0
- arpakitlib/_arpakit_project_template_v_1/resource/static/openapi-favicon.png +0 -0
- arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/index.html +19 -0
- arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-bundle.js +2 -0
- arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-es-bundle-core.js +1 -1
- arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-es-bundle-core.js.map +1 -0
- arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-es-bundle.js +2 -0
- arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui-standalone-preset.js +2 -0
- arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui.js +1 -1
- arpakitlib/_arpakit_project_template_v_1/resource/static/swagger-ui/swagger-ui.js.map +1 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_1.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_2.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_3.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_4.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_5.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_6.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/sandbox/sandbox_7.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/site/router/main_router.py +3 -0
- arpakitlib/_arpakit_project_template_v_1/sqladmin_/add_admin_in_app.py +24 -0
- arpakitlib/_arpakit_project_template_v_1/sqladmin_/admin_auth.py +54 -0
- arpakitlib/_arpakit_project_template_v_1/sqladmin_/model_view.py +95 -0
- arpakitlib/_arpakit_project_template_v_1/sqlalchemy_db/sqlalchemy_db.py +22 -0
- arpakitlib/_arpakit_project_template_v_1/sqlalchemy_db/sqlalchemy_model.py +129 -0
- arpakitlib/_arpakit_project_template_v_1/sqlalchemy_db/util.py +28 -0
- arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_3.py → _arpakit_project_template_v_1/test_data/make_test_data_1.py} +8 -3
- arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_4.py → _arpakit_project_template_v_1/test_data/make_test_data_2.py} +8 -3
- arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_1.py → _arpakit_project_template_v_1/test_data/make_test_data_3.py} +8 -3
- arpakitlib/{_arpakit_project_template/src/sandbox/sandbox_2.py → _arpakit_project_template_v_1/test_data/make_test_data_4.py} +8 -3
- arpakitlib/_arpakit_project_template_v_1/test_data/make_test_data_5.py +22 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/blank/blank.py +5 -0
- arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/blank/util.py +1 -1
- arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/const.py +6 -3
- arpakitlib/_arpakit_project_template_v_1/tg_bot/event.py +51 -0
- arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/filter/not_prod_mode.py +1 -1
- arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/tg_bot/filter/prod_mode.py +1 -1
- arpakitlib/_arpakit_project_template_v_1/tg_bot/kb/static_/__init__.py +0 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/kb/static_/common.py +0 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/middleware/__init__.py +0 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/middleware/init_user.py +24 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/middleware/middleware.py +12 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/router/__init__.py +0 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/router/arpakitlib_.py +10 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/router/error.py +15 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/router/healthcheck.py +10 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/router/main_router.py +14 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/start_tg_bot.py +34 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/tg_bot.py +24 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/tg_bot_dispatcher.py +19 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/transmitted_tg_data.py +58 -0
- arpakitlib/_arpakit_project_template_v_1/tg_bot/util.py +0 -0
- arpakitlib/_arpakit_project_template_v_1/util/__init__.py +0 -0
- arpakitlib/_arpakit_project_template_v_1/util/read_arpakitlib_project_template_file.py +17 -0
- arpakitlib/ar_aiogram_util.py +41 -52
- arpakitlib/ar_arpakit_project_template_util.py +5 -11
- arpakitlib/ar_arpakitlib_cli_util.py +8 -2
- arpakitlib/ar_base_worker_util.py +35 -17
- arpakitlib/ar_class_util.py +11 -0
- arpakitlib/ar_func_util.py +19 -29
- arpakitlib/ar_http_request_util.py +10 -2
- arpakitlib/ar_rat_func_util.py +1 -1
- arpakitlib/ar_retry_func_util.py +4 -4
- arpakitlib/ar_schedule_uust_api_client_util.py +1 -1
- arpakitlib/ar_settings_util.py +3 -204
- arpakitlib/ar_sqladmin_util.py +7 -102
- arpakitlib/ar_sqlalchemy_util.py +65 -13
- arpakitlib/ar_type_util.py +0 -2
- {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/METADATA +5 -3
- arpakitlib-1.8.1.dist-info/RECORD +261 -0
- {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/WHEEL +1 -1
- arpakitlib/_arpakit_project_template/ARPAKITLIB +0 -1
- arpakitlib/_arpakit_project_template/manage/docker_ps.sh +0 -2
- arpakitlib/_arpakit_project_template/manage/git_branch.sh +0 -2
- arpakitlib/_arpakit_project_template/manage/poetry_add_plugin_export.sh +0 -2
- arpakitlib/_arpakit_project_template/manage/poetry_config_virtualenvs_in_project_true.sh +0 -2
- arpakitlib/_arpakit_project_template/manage/poetry_self_add_plugin_export.sh +0 -2
- arpakitlib/_arpakit_project_template/src/admin1/add_admin_in_app.py +0 -32
- arpakitlib/_arpakit_project_template/src/admin1/admin_auth.py +0 -29
- arpakitlib/_arpakit_project_template/src/admin1/model_view.py +0 -1
- arpakitlib/_arpakit_project_template/src/api/asgi.py +0 -3
- arpakitlib/_arpakit_project_template/src/api/auth.py +0 -53
- arpakitlib/_arpakit_project_template/src/api/const.py +0 -13
- arpakitlib/_arpakit_project_template/src/api/create_api_app.py +0 -43
- arpakitlib/_arpakit_project_template/src/api/create_handle_exception_.py +0 -59
- arpakitlib/_arpakit_project_template/src/api/event.py +0 -83
- arpakitlib/_arpakit_project_template/src/api/router/v1/get_api_error_info.py +0 -27
- arpakitlib/_arpakit_project_template/src/api/router/v1/main_router.py +0 -15
- arpakitlib/_arpakit_project_template/src/api/schema/v1/in_.py +0 -1
- arpakitlib/_arpakit_project_template/src/api/schema/v1/out.py +0 -1
- arpakitlib/_arpakit_project_template/src/api/transmitted_api_data.py +0 -7
- arpakitlib/_arpakit_project_template/src/api/util.py +0 -44
- arpakitlib/_arpakit_project_template/src/core/const.py +0 -41
- arpakitlib/_arpakit_project_template/src/core/settings.py +0 -21
- arpakitlib/_arpakit_project_template/src/core/util.py +0 -61
- arpakitlib/_arpakit_project_template/src/json_db/_drop_json_db.py +0 -13
- arpakitlib/_arpakit_project_template/src/json_db/_init_json_db.py +0 -11
- arpakitlib/_arpakit_project_template/src/json_db/_reinit_json_db.py +0 -13
- arpakitlib/_arpakit_project_template/src/json_db/_rm_all_records_in_json_db.py +0 -13
- arpakitlib/_arpakit_project_template/src/json_db/json_db.py +0 -11
- arpakitlib/_arpakit_project_template/src/json_db/util.py +0 -17
- arpakitlib/_arpakit_project_template/src/just_script/example.py +0 -16
- arpakitlib/_arpakit_project_template/src/operation_execution/_start_operation_executor_worker.py +0 -17
- arpakitlib/_arpakit_project_template/src/operation_execution/_start_scheduled_operation_creator_worker.py +0 -17
- arpakitlib/_arpakit_project_template/src/operation_execution/const.py +0 -9
- arpakitlib/_arpakit_project_template/src/operation_execution/operation_executor.py +0 -16
- arpakitlib/_arpakit_project_template/src/operation_execution/scheduled_operations.py +0 -29
- arpakitlib/_arpakit_project_template/src/operation_execution/util.py +0 -1
- arpakitlib/_arpakit_project_template/src/sandbox/sandbox_5.py +0 -17
- arpakitlib/_arpakit_project_template/src/sandbox/sandbox_6.py +0 -17
- arpakitlib/_arpakit_project_template/src/sandbox/sandbox_7.py +0 -17
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_check_conn_sqlalchemy_db.py +0 -11
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_drop_sqlalchemy_db.py +0 -13
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_init_sqlalchemy_db.py +0 -11
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_reinit_sqlalchemy_db.py +0 -13
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_remove_operations.py +0 -15
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/_remove_story_logs.py +0 -16
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/sqlalchemy_model.py +0 -13
- arpakitlib/_arpakit_project_template/src/sqlalchemy_db/util.py +0 -27
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_1.py +0 -8
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_2.py +0 -8
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_3.py +0 -8
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_4.py +0 -8
- arpakitlib/_arpakit_project_template/src/test_data/make_test_data_5.py +0 -8
- arpakitlib/_arpakit_project_template/src/tg_bot/blank/blank.py +0 -10
- arpakitlib/_arpakit_project_template/src/tg_bot/event.py +0 -39
- arpakitlib/_arpakit_project_template/src/tg_bot/router/error.py +0 -3
- arpakitlib/_arpakit_project_template/src/tg_bot/router/router.py +0 -7
- arpakitlib/_arpakit_project_template/src/tg_bot/start_tg_bot.py +0 -11
- arpakitlib/_arpakit_project_template/src/tg_bot/transmitted_tg_data.py +0 -6
- arpakitlib/_arpakit_project_template/src/tg_bot/util.py +0 -44
- arpakitlib/ar_api_key_util.py +0 -21
- arpakitlib/ar_fastapi_static/swagger-ui/index.html +0 -19
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-bundle.js +0 -2
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle-core.js.map +0 -1
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-es-bundle.js +0 -2
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui-standalone-preset.js +0 -2
- arpakitlib/ar_fastapi_static/swagger-ui/swagger-ui.js.map +0 -1
- arpakitlib/ar_fastapi_util.py +0 -862
- arpakitlib/ar_operation_execution_util.py +0 -504
- arpakitlib/ar_sqlalchemy_model_util.py +0 -183
- arpakitlib-1.7.257.dist-info/RECORD +0 -236
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/.gitignore +0 -0
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/.python-version +0 -0
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/LICENSE +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/additional_model}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/additional_model/additional_model.py +0 -0
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic/README +0 -0
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic/script.py.mako +0 -0
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/alembic.ini +0 -0
- /arpakitlib/{_arpakit_project_template/manage/note → _arpakit_project_template_v_1/api}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/resource → _arpakit_project_template_v_1/api/router}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/resource/static → _arpakit_project_template_v_1/api/router/v1}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1/api/schema}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/additional_model → _arpakit_project_template_v_1/api/schema/common}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/admin1 → _arpakit_project_template_v_1/api/schema/v1}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/manage/note/note_1.txt → _arpakit_project_template_v_1/api/util.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/api → _arpakit_project_template_v_1/business_service}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/api/router → _arpakit_project_template_v_1/celery_}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/api/router/v1 → _arpakit_project_template_v_1/command}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/alembic_upgrade_head .sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_ps_a.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_rm_postgres.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_run_postgres.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_start_postgres.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/docker_stop_postgres.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_commit.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_company_github_1.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_company_gitlab_1.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_github_1.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_push_arpakit_gitlab_1.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage/git_remote_v.sh → _arpakit_project_template_v_1/command/git_remote.sh} +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_set_arpakit_company_origin.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_set_arpakit_origin.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/git_status.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_check.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_clear_cache.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_config.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_install.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_lock.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_remove_and_add_arpakitlib.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_show.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_show_arpakitlib.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_update.sh +0 -0
- /arpakitlib/{_arpakit_project_template/manage → _arpakit_project_template_v_1/command}/poetry_update_arpakitlib.sh +0 -0
- /arpakitlib/{_arpakit_project_template/src/api/schema → _arpakit_project_template_v_1/core}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/api/schema/v1 → _arpakit_project_template_v_1/json_db}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/business_service → _arpakit_project_template_v_1/note}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/manage/note/note_2.txt → _arpakit_project_template_v_1/note/note_1.txt} +0 -0
- /arpakitlib/{_arpakit_project_template/manage/note/note_3.txt → _arpakit_project_template_v_1/note/note_2.txt} +0 -0
- /arpakitlib/{_arpakit_project_template/manage/note/note_4.txt → _arpakit_project_template_v_1/note/note_3.txt} +0 -0
- /arpakitlib/{_arpakit_project_template/manage/note/note_5.txt → _arpakit_project_template_v_1/note/note_4.txt} +0 -0
- /arpakitlib/{_arpakit_project_template/src/core/__init__.py → _arpakit_project_template_v_1/note/note_5.txt} +0 -0
- /arpakitlib/{_arpakit_project_template/src/json_db → _arpakit_project_template_v_1/operation_execution}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/just_script/__init__.py → _arpakit_project_template_v_1/operation_execution/const.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/operation_execution → _arpakit_project_template_v_1/resource}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/resource/static/healthcheck → _arpakit_project_template_v_1/resource/static/1} +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/healthcheck +0 -0
- /arpakitlib/{_arpakit_project_template → _arpakit_project_template_v_1}/resource/static/helloworld +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/redoc/redoc.standalone.js +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/favicon-16x16.png +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/favicon-32x32.png +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/index.css +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/oauth2-redirect.html +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-initializer.js +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-bundle.js.map +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-es-bundle.js.map +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui-standalone-preset.js.map +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui.css +0 -0
- /arpakitlib/{ar_fastapi_static → _arpakit_project_template_v_1/resource/static}/swagger-ui/swagger-ui.css.map +0 -0
- /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/sandbox/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/sqlalchemy_db → _arpakit_project_template_v_1/site}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/test_data/__init__.py → _arpakit_project_template_v_1/site/asgi.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/__init__.py → _arpakit_project_template_v_1/site/consts.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/blank/__init__.py → _arpakit_project_template_v_1/site/create_site_app.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/filter/__init__.py → _arpakit_project_template_v_1/site/event.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/handler/__init__.py → _arpakit_project_template_v_1/site/exception_handler.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/kb → _arpakit_project_template_v_1/site/router}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/inline_ → _arpakit_project_template_v_1/sqladmin_}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/static_ → _arpakit_project_template_v_1/sqlalchemy_db}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src → _arpakit_project_template_v_1}/sqlalchemy_db/const.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/middleware → _arpakit_project_template_v_1/test_data}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/router → _arpakit_project_template_v_1/tg_bot}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/util → _arpakit_project_template_v_1/tg_bot/blank}/__init__.py +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/handler/cmd_arpakitlib.py → _arpakit_project_template_v_1/tg_bot/filter/__init__.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/handler/cmd_healthcheck.py → _arpakit_project_template_v_1/tg_bot/kb/__init__.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/inline_/callback.py → _arpakit_project_template_v_1/tg_bot/kb/inline_/__init__.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/inline_/common.py → _arpakit_project_template_v_1/tg_bot/kb/inline_/callback.py} +0 -0
- /arpakitlib/{_arpakit_project_template/src/tg_bot/kb/static_ → _arpakit_project_template_v_1/tg_bot/kb/inline_}/common.py +0 -0
- {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/LICENSE +0 -0
- {arpakitlib-1.7.257.dist-info → arpakitlib-1.8.1.dist-info}/entry_points.txt +0 -0
arpakitlib/ar_fastapi_util.py
DELETED
@@ -1,862 +0,0 @@
|
|
1
|
-
# arpakit
|
2
|
-
|
3
|
-
from __future__ import annotations
|
4
|
-
|
5
|
-
import asyncio
|
6
|
-
import datetime as dt
|
7
|
-
import inspect
|
8
|
-
import logging
|
9
|
-
import os.path
|
10
|
-
import pathlib
|
11
|
-
from contextlib import suppress
|
12
|
-
from typing import Any, Callable
|
13
|
-
|
14
|
-
import fastapi.exceptions
|
15
|
-
import fastapi.responses
|
16
|
-
import fastapi.security
|
17
|
-
import starlette.exceptions
|
18
|
-
import starlette.requests
|
19
|
-
import starlette.status
|
20
|
-
from fastapi import FastAPI, APIRouter, Query, Security, Depends
|
21
|
-
from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
|
22
|
-
from fastapi.security import APIKeyHeader
|
23
|
-
from pydantic import BaseModel, ConfigDict
|
24
|
-
from starlette import status
|
25
|
-
from starlette.middleware.cors import CORSMiddleware
|
26
|
-
from starlette.staticfiles import StaticFiles
|
27
|
-
|
28
|
-
from arpakitlib.ar_datetime_util import now_utc_dt
|
29
|
-
from arpakitlib.ar_dict_util import combine_dicts
|
30
|
-
from arpakitlib.ar_enumeration_util import Enumeration
|
31
|
-
from arpakitlib.ar_exception_util import exception_to_traceback_str
|
32
|
-
from arpakitlib.ar_file_storage_in_dir_util import FileStorageInDir
|
33
|
-
from arpakitlib.ar_func_util import raise_if_not_async_func, is_async_object
|
34
|
-
from arpakitlib.ar_json_db_util import BaseJSONDb
|
35
|
-
from arpakitlib.ar_json_util import safely_transfer_obj_to_json_str_to_json_obj, safely_transfer_obj_to_json_str
|
36
|
-
from arpakitlib.ar_settings_util import BaseSettings2
|
37
|
-
from arpakitlib.ar_sqlalchemy_model_util import StoryLogDBM, OperationDBM
|
38
|
-
from arpakitlib.ar_sqlalchemy_util import SQLAlchemyDb
|
39
|
-
from arpakitlib.ar_type_util import raise_for_type, raise_if_none
|
40
|
-
|
41
|
-
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
42
|
-
|
43
|
-
_logger = logging.getLogger(__name__)
|
44
|
-
|
45
|
-
|
46
|
-
class BaseSchema(BaseModel):
|
47
|
-
model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True, from_attributes=True)
|
48
|
-
|
49
|
-
@classmethod
|
50
|
-
def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
|
51
|
-
if not (
|
52
|
-
cls.__name__.endswith("SO")
|
53
|
-
or cls.__name__.endswith("SI")
|
54
|
-
or cls.__name__.endswith("SchemaIn")
|
55
|
-
or cls.__name__.endswith("SchemaOut")
|
56
|
-
):
|
57
|
-
raise ValueError("APISchema class should ends with SO | SI | SchemaIn | SchemaOut")
|
58
|
-
super().__init_subclass__(**kwargs)
|
59
|
-
|
60
|
-
|
61
|
-
class BaseSI(BaseSchema):
|
62
|
-
pass
|
63
|
-
|
64
|
-
|
65
|
-
class BaseSO(BaseSchema):
|
66
|
-
pass
|
67
|
-
|
68
|
-
|
69
|
-
class SimpleSO(BaseSO):
|
70
|
-
id: int
|
71
|
-
long_id: str
|
72
|
-
creation_dt: dt.datetime
|
73
|
-
|
74
|
-
|
75
|
-
class BaseAPIErrorCodes(Enumeration):
|
76
|
-
cannot_authorize = "CANNOT_AUTHORIZE"
|
77
|
-
unknown_error = "UNKNOWN_ERROR"
|
78
|
-
error_in_request = "ERROR_IN_REQUEST"
|
79
|
-
not_found = "NOT_FOUND"
|
80
|
-
|
81
|
-
|
82
|
-
class BaseAPIErrorSpecificationCodes(Enumeration):
|
83
|
-
pass
|
84
|
-
|
85
|
-
|
86
|
-
class ErrorSO(BaseSO):
|
87
|
-
has_error: bool = True
|
88
|
-
error_code: str | None = None
|
89
|
-
error_specification_code: str | None = None
|
90
|
-
error_description: str | None = None
|
91
|
-
error_data: dict[str, Any] = {}
|
92
|
-
|
93
|
-
|
94
|
-
class RawDataSO(BaseSO):
|
95
|
-
data: dict[str, Any] = {}
|
96
|
-
|
97
|
-
|
98
|
-
class DatetimeSO(BaseSO):
|
99
|
-
date: dt.date
|
100
|
-
datetime: dt.datetime | None = None
|
101
|
-
year: int
|
102
|
-
month: int
|
103
|
-
day: int
|
104
|
-
hour: int | None = None
|
105
|
-
minute: int | None = None
|
106
|
-
second: int | None = None
|
107
|
-
microsecond: int | None = None
|
108
|
-
|
109
|
-
@classmethod
|
110
|
-
def from_datetime(cls, datetime_: dt.datetime):
|
111
|
-
return cls(
|
112
|
-
date=datetime_.date(),
|
113
|
-
datetime=datetime_,
|
114
|
-
year=datetime_.year,
|
115
|
-
month=datetime_.month,
|
116
|
-
day=datetime_.day,
|
117
|
-
hour=datetime_.hour,
|
118
|
-
minute=datetime_.minute,
|
119
|
-
second=datetime_.second,
|
120
|
-
microsecond=datetime_.microsecond
|
121
|
-
)
|
122
|
-
|
123
|
-
@classmethod
|
124
|
-
def from_date(cls, date_: dt.date):
|
125
|
-
return cls(
|
126
|
-
date=date_,
|
127
|
-
year=date_.year,
|
128
|
-
month=date_.month,
|
129
|
-
day=date_.day
|
130
|
-
)
|
131
|
-
|
132
|
-
|
133
|
-
class StoryLogSO(SimpleSO):
|
134
|
-
level: str
|
135
|
-
title: str | None
|
136
|
-
data: dict[str, Any]
|
137
|
-
|
138
|
-
@classmethod
|
139
|
-
def from_story_log_dbm(cls, *, story_log_dbm: StoryLogDBM) -> StoryLogSO:
|
140
|
-
return cls.model_validate(story_log_dbm.simple_dict(include_sd_properties=True))
|
141
|
-
|
142
|
-
|
143
|
-
class OperationSO(SimpleSO):
|
144
|
-
execution_start_dt: dt.datetime | None
|
145
|
-
execution_finish_dt: dt.datetime | None
|
146
|
-
status: str
|
147
|
-
type: str
|
148
|
-
input_data: dict[str, Any]
|
149
|
-
output_data: dict[str, Any]
|
150
|
-
error_data: dict[str, Any]
|
151
|
-
duration_total_seconds: float | None
|
152
|
-
|
153
|
-
@classmethod
|
154
|
-
def from_operation_dbm(cls, *, operation_dbm: OperationDBM) -> OperationSO:
|
155
|
-
return cls.model_validate(operation_dbm.simple_dict(include_sd_properties=True))
|
156
|
-
|
157
|
-
|
158
|
-
class APIErrorInfoSO(BaseSO):
|
159
|
-
api_error_codes: list[str] = []
|
160
|
-
api_error_specification_codes: list[str] = []
|
161
|
-
|
162
|
-
|
163
|
-
class APIJSONResponse(fastapi.responses.JSONResponse):
|
164
|
-
def __init__(self, *, content: dict | list | BaseSO | None, status_code: int = starlette.status.HTTP_200_OK):
|
165
|
-
if isinstance(content, dict):
|
166
|
-
content = safely_transfer_obj_to_json_str_to_json_obj(content)
|
167
|
-
elif isinstance(content, list):
|
168
|
-
content = safely_transfer_obj_to_json_str_to_json_obj(content)
|
169
|
-
elif isinstance(content, BaseSO):
|
170
|
-
content = safely_transfer_obj_to_json_str_to_json_obj(content.model_dump())
|
171
|
-
elif content is None:
|
172
|
-
content = None
|
173
|
-
else:
|
174
|
-
raise ValueError(f"unknown content type, type(content)={type(content)}")
|
175
|
-
|
176
|
-
self.content_ = content
|
177
|
-
self.status_code_ = status_code
|
178
|
-
|
179
|
-
super().__init__(
|
180
|
-
content=content,
|
181
|
-
status_code=status_code
|
182
|
-
)
|
183
|
-
|
184
|
-
|
185
|
-
class APIException(fastapi.exceptions.HTTPException):
|
186
|
-
def __init__(
|
187
|
-
self,
|
188
|
-
*,
|
189
|
-
status_code: int = starlette.status.HTTP_400_BAD_REQUEST,
|
190
|
-
error_code: str | None = BaseAPIErrorCodes.unknown_error,
|
191
|
-
error_specification_code: str | None = None,
|
192
|
-
error_description: str | None = None,
|
193
|
-
error_data: dict[str, Any] | None = None
|
194
|
-
):
|
195
|
-
self.status_code = status_code
|
196
|
-
self.error_code = error_code
|
197
|
-
self.error_specification_code = error_specification_code
|
198
|
-
self.error_description = error_description
|
199
|
-
if error_data is None:
|
200
|
-
error_data = {}
|
201
|
-
self.error_data = error_data
|
202
|
-
|
203
|
-
self.error_so = ErrorSO(
|
204
|
-
has_error=True,
|
205
|
-
error_code=self.error_code,
|
206
|
-
error_specification_code=self.error_specification_code,
|
207
|
-
error_description=self.error_description,
|
208
|
-
error_data=self.error_data
|
209
|
-
)
|
210
|
-
|
211
|
-
super().__init__(
|
212
|
-
status_code=self.status_code,
|
213
|
-
detail=self.error_so.model_dump(mode="json")
|
214
|
-
)
|
215
|
-
|
216
|
-
|
217
|
-
def create_handle_exception(
|
218
|
-
*,
|
219
|
-
funcs_before: list[Callable | None] | None = None,
|
220
|
-
async_funcs_after: list[Callable | None] | None = None,
|
221
|
-
) -> Callable:
|
222
|
-
if funcs_before is None:
|
223
|
-
funcs_before = []
|
224
|
-
funcs_before = [v for v in funcs_before if v is not None]
|
225
|
-
|
226
|
-
if async_funcs_after is None:
|
227
|
-
async_funcs_after = []
|
228
|
-
async_funcs_after = [v for v in async_funcs_after if v is not None]
|
229
|
-
|
230
|
-
async def func(
|
231
|
-
request: starlette.requests.Request,
|
232
|
-
exception: Exception
|
233
|
-
) -> APIJSONResponse:
|
234
|
-
status_code = starlette.status.HTTP_500_INTERNAL_SERVER_ERROR
|
235
|
-
|
236
|
-
error_so = ErrorSO(
|
237
|
-
has_error=True,
|
238
|
-
error_code=BaseAPIErrorCodes.unknown_error,
|
239
|
-
error_data={
|
240
|
-
"exception_type": str(type(exception)),
|
241
|
-
"exception_str": str(exception),
|
242
|
-
"request.method": str(request.method),
|
243
|
-
"request.url": str(request.url),
|
244
|
-
"request.headers": str(request.headers),
|
245
|
-
}
|
246
|
-
)
|
247
|
-
|
248
|
-
if isinstance(exception, APIException):
|
249
|
-
old_error_data = error_so.error_data
|
250
|
-
error_so = exception.error_so
|
251
|
-
error_so.error_data = combine_dicts(old_error_data, error_so.error_data)
|
252
|
-
|
253
|
-
elif isinstance(exception, starlette.exceptions.HTTPException):
|
254
|
-
status_code = exception.status_code
|
255
|
-
if status_code in (starlette.status.HTTP_403_FORBIDDEN, starlette.status.HTTP_401_UNAUTHORIZED):
|
256
|
-
error_so.error_code = BaseAPIErrorCodes.cannot_authorize
|
257
|
-
elif status_code == starlette.status.HTTP_404_NOT_FOUND:
|
258
|
-
error_so.error_code = BaseAPIErrorCodes.not_found
|
259
|
-
else:
|
260
|
-
status_code = starlette.status.HTTP_500_INTERNAL_SERVER_ERROR
|
261
|
-
with suppress(Exception):
|
262
|
-
error_so.error_data["exception.detail"] = exception.detail
|
263
|
-
|
264
|
-
elif isinstance(exception, fastapi.exceptions.RequestValidationError):
|
265
|
-
status_code = starlette.status.HTTP_422_UNPROCESSABLE_ENTITY
|
266
|
-
error_so.error_code = BaseAPIErrorCodes.error_in_request
|
267
|
-
with suppress(Exception):
|
268
|
-
error_so.error_data["exception.errors"] = str(exception.errors()) if exception.errors() else {}
|
269
|
-
|
270
|
-
else:
|
271
|
-
status_code = starlette.status.HTTP_500_INTERNAL_SERVER_ERROR
|
272
|
-
error_so.error_code = BaseAPIErrorCodes.unknown_error
|
273
|
-
|
274
|
-
if error_so.error_code is not None:
|
275
|
-
error_so.error_code = error_so.error_code.upper().replace(" ", "_").strip()
|
276
|
-
|
277
|
-
if error_so.error_specification_code is not None:
|
278
|
-
error_so.error_specification_code = (
|
279
|
-
error_so.error_specification_code.upper().replace(" ", "_").strip()
|
280
|
-
)
|
281
|
-
|
282
|
-
if error_so.error_code == BaseAPIErrorCodes.not_found:
|
283
|
-
status_code = status.HTTP_404_NOT_FOUND
|
284
|
-
|
285
|
-
if error_so.error_code == BaseAPIErrorCodes.cannot_authorize:
|
286
|
-
status_code = status.HTTP_401_UNAUTHORIZED
|
287
|
-
|
288
|
-
error_so.error_data["status_code"] = status_code
|
289
|
-
|
290
|
-
# funcs_before
|
291
|
-
|
292
|
-
_transmitted_kwargs = {}
|
293
|
-
for func_before in funcs_before:
|
294
|
-
_func_data = func_before(
|
295
|
-
request=request, status_code=status_code, error_so=error_so, exception=exception,
|
296
|
-
transmitted_kwargs=_transmitted_kwargs
|
297
|
-
)
|
298
|
-
if is_async_object(_func_data):
|
299
|
-
_func_data = await _func_data
|
300
|
-
if _func_data is not None:
|
301
|
-
error_so, _transmitted_kwargs = _func_data[0], _func_data[1]
|
302
|
-
raise_for_type(error_so, ErrorSO)
|
303
|
-
raise_for_type(_transmitted_kwargs, dict)
|
304
|
-
|
305
|
-
# async_funcs_after
|
306
|
-
|
307
|
-
for async_func_after in async_funcs_after:
|
308
|
-
raise_if_not_async_func(async_func_after)
|
309
|
-
_ = asyncio.create_task(async_func_after(
|
310
|
-
request=request, status_code=status_code, error_so=error_so, exception=exception
|
311
|
-
))
|
312
|
-
|
313
|
-
return APIJSONResponse(
|
314
|
-
content=error_so,
|
315
|
-
status_code=status_code
|
316
|
-
)
|
317
|
-
|
318
|
-
return func
|
319
|
-
|
320
|
-
|
321
|
-
def logging__api_func_before_in_handle_exception(
|
322
|
-
*,
|
323
|
-
ignore_api_error_codes: list[str] | None = None,
|
324
|
-
ignore_status_codes: list[int] | None = None,
|
325
|
-
ignore_exception_types: list[type[Exception]] | None = None,
|
326
|
-
need_exc_info: bool = False
|
327
|
-
) -> Callable:
|
328
|
-
current_func_name = inspect.currentframe().f_code.co_name
|
329
|
-
|
330
|
-
def func(
|
331
|
-
*,
|
332
|
-
request: starlette.requests.Request,
|
333
|
-
status_code: int,
|
334
|
-
error_so: ErrorSO,
|
335
|
-
exception: Exception,
|
336
|
-
transmitted_kwargs: dict[str, Any],
|
337
|
-
**kwargs
|
338
|
-
) -> (ErrorSO, dict[str, Any]):
|
339
|
-
transmitted_kwargs[current_func_name] = now_utc_dt()
|
340
|
-
|
341
|
-
if ignore_api_error_codes and error_so.error_code in ignore_api_error_codes:
|
342
|
-
return error_so, transmitted_kwargs
|
343
|
-
|
344
|
-
if ignore_status_codes and status_code in ignore_status_codes:
|
345
|
-
return error_so, transmitted_kwargs
|
346
|
-
|
347
|
-
if ignore_exception_types and (
|
348
|
-
exception in ignore_exception_types or type(exception) in ignore_exception_types
|
349
|
-
):
|
350
|
-
return error_so, transmitted_kwargs
|
351
|
-
|
352
|
-
_logger.error(safely_transfer_obj_to_json_str(error_so.model_dump()), exc_info=need_exc_info)
|
353
|
-
|
354
|
-
return func
|
355
|
-
|
356
|
-
|
357
|
-
def story_log__api_func_before_in_handle_exception(
|
358
|
-
*,
|
359
|
-
sqlalchemy_db: SQLAlchemyDb,
|
360
|
-
ignore_api_error_codes: list[str] | None = None,
|
361
|
-
ignore_status_codes: list[int] | None = None,
|
362
|
-
ignore_exception_types: list[type[Exception]] | None = None
|
363
|
-
) -> Callable:
|
364
|
-
raise_for_type(sqlalchemy_db, SQLAlchemyDb)
|
365
|
-
|
366
|
-
current_func_name = inspect.currentframe().f_code.co_name
|
367
|
-
|
368
|
-
async def async_func(
|
369
|
-
*,
|
370
|
-
request: starlette.requests.Request,
|
371
|
-
status_code: int,
|
372
|
-
error_so: ErrorSO,
|
373
|
-
exception: Exception,
|
374
|
-
transmitted_kwargs: dict[str, Any],
|
375
|
-
**kwargs
|
376
|
-
) -> (ErrorSO, dict[str, Any]):
|
377
|
-
transmitted_kwargs[current_func_name] = now_utc_dt()
|
378
|
-
|
379
|
-
if ignore_api_error_codes and error_so.error_code in ignore_api_error_codes:
|
380
|
-
return error_so, transmitted_kwargs
|
381
|
-
|
382
|
-
if ignore_status_codes and status_code in ignore_status_codes:
|
383
|
-
return error_so, transmitted_kwargs
|
384
|
-
|
385
|
-
if ignore_exception_types and (
|
386
|
-
exception in ignore_exception_types or type(exception) in ignore_exception_types
|
387
|
-
):
|
388
|
-
return error_so, transmitted_kwargs
|
389
|
-
|
390
|
-
async with sqlalchemy_db.new_async_session() as session:
|
391
|
-
story_log_dbm = StoryLogDBM(
|
392
|
-
level=StoryLogDBM.Levels.error,
|
393
|
-
title=f"{status_code}, {type(exception)}",
|
394
|
-
data={
|
395
|
-
"error_so": error_so.model_dump(),
|
396
|
-
"traceback_str": exception_to_traceback_str(exception=exception)
|
397
|
-
}
|
398
|
-
)
|
399
|
-
session.add(story_log_dbm)
|
400
|
-
await session.commit()
|
401
|
-
await session.refresh(story_log_dbm)
|
402
|
-
|
403
|
-
error_so.error_data.update({"story_log_long_id": story_log_dbm.long_id})
|
404
|
-
transmitted_kwargs["story_log_id"] = story_log_dbm.id
|
405
|
-
|
406
|
-
return error_so, transmitted_kwargs
|
407
|
-
|
408
|
-
return async_func
|
409
|
-
|
410
|
-
|
411
|
-
def add_exception_handler_to_app(*, app: FastAPI, handle_exception: Callable) -> FastAPI:
|
412
|
-
app.add_exception_handler(
|
413
|
-
exc_class_or_status_code=Exception,
|
414
|
-
handler=handle_exception
|
415
|
-
)
|
416
|
-
app.add_exception_handler(
|
417
|
-
exc_class_or_status_code=ValueError,
|
418
|
-
handler=handle_exception
|
419
|
-
)
|
420
|
-
app.add_exception_handler(
|
421
|
-
exc_class_or_status_code=fastapi.exceptions.RequestValidationError,
|
422
|
-
handler=handle_exception
|
423
|
-
)
|
424
|
-
app.add_exception_handler(
|
425
|
-
exc_class_or_status_code=starlette.exceptions.HTTPException,
|
426
|
-
handler=handle_exception
|
427
|
-
)
|
428
|
-
return app
|
429
|
-
|
430
|
-
|
431
|
-
def add_swagger_to_app(
|
432
|
-
*,
|
433
|
-
app: FastAPI,
|
434
|
-
favicon_url: str | None = None
|
435
|
-
):
|
436
|
-
app.mount(
|
437
|
-
"/ar_fastapi_static",
|
438
|
-
StaticFiles(directory=os.path.join(str(pathlib.Path(__file__).parent), "ar_fastapi_static")),
|
439
|
-
name="ar_fastapi_static"
|
440
|
-
)
|
441
|
-
|
442
|
-
@app.get("/docs", include_in_schema=False)
|
443
|
-
async def custom_swagger_ui_html():
|
444
|
-
return get_swagger_ui_html(
|
445
|
-
openapi_url=app.openapi_url,
|
446
|
-
title=app.title,
|
447
|
-
swagger_js_url="/ar_fastapi_static/swagger-ui/swagger-ui-bundle.js",
|
448
|
-
swagger_css_url="/ar_fastapi_static/swagger-ui/swagger-ui.css",
|
449
|
-
swagger_favicon_url=favicon_url
|
450
|
-
)
|
451
|
-
|
452
|
-
@app.get("/redoc", include_in_schema=False)
|
453
|
-
async def custom_redoc_html():
|
454
|
-
return get_redoc_html(
|
455
|
-
openapi_url=app.openapi_url,
|
456
|
-
title=app.title,
|
457
|
-
redoc_js_url="/ar_fastapi_static/redoc/redoc.standalone.js",
|
458
|
-
redoc_favicon_url=favicon_url
|
459
|
-
)
|
460
|
-
|
461
|
-
return app
|
462
|
-
|
463
|
-
|
464
|
-
def add_cors_to_app(*, app: FastAPI):
|
465
|
-
app.add_middleware(
|
466
|
-
CORSMiddleware,
|
467
|
-
allow_origins=["*"],
|
468
|
-
allow_credentials=True,
|
469
|
-
allow_methods=["*"],
|
470
|
-
allow_headers=["*"],
|
471
|
-
)
|
472
|
-
return app
|
473
|
-
|
474
|
-
|
475
|
-
class HealthcheckSO(BaseSO):
|
476
|
-
is_ok: bool = True
|
477
|
-
|
478
|
-
|
479
|
-
class ARPAKITLibSO(BaseSO):
|
480
|
-
arpakitlib: bool = True
|
481
|
-
|
482
|
-
|
483
|
-
def create_needed_api_router():
|
484
|
-
api_router = APIRouter()
|
485
|
-
|
486
|
-
@api_router.get(
|
487
|
-
"/healthcheck",
|
488
|
-
response_model=HealthcheckSO | ErrorSO,
|
489
|
-
status_code=starlette.status.HTTP_200_OK,
|
490
|
-
tags=["Healthcheck"]
|
491
|
-
)
|
492
|
-
async def _():
|
493
|
-
return APIJSONResponse(
|
494
|
-
status_code=starlette.status.HTTP_200_OK,
|
495
|
-
content=HealthcheckSO(is_ok=True)
|
496
|
-
)
|
497
|
-
|
498
|
-
@api_router.get(
|
499
|
-
"/arpakitlib",
|
500
|
-
response_model=ARPAKITLibSO | ErrorSO,
|
501
|
-
status_code=starlette.status.HTTP_200_OK,
|
502
|
-
tags=["arpakitlib"]
|
503
|
-
)
|
504
|
-
async def _():
|
505
|
-
return APIJSONResponse(
|
506
|
-
status_code=starlette.status.HTTP_200_OK,
|
507
|
-
content=ARPAKITLibSO(arpakitlib=True)
|
508
|
-
)
|
509
|
-
|
510
|
-
return api_router
|
511
|
-
|
512
|
-
|
513
|
-
class BaseStartupAPIEvent:
|
514
|
-
def __init__(self, *args, **kwargs):
|
515
|
-
self._logger = logging.getLogger()
|
516
|
-
|
517
|
-
async def async_on_startup(self, *args, **kwargs):
|
518
|
-
self._logger.info("on_startup starts")
|
519
|
-
self._logger.info("on_startup ends")
|
520
|
-
|
521
|
-
|
522
|
-
class BaseShutdownAPIEvent:
|
523
|
-
def __init__(self, *args, **kwargs):
|
524
|
-
self._logger = logging.getLogger()
|
525
|
-
|
526
|
-
async def async_on_shutdown(self, *args, **kwargs):
|
527
|
-
self._logger.info("on_shutdown starts")
|
528
|
-
self._logger.info("on_shutdown ends")
|
529
|
-
|
530
|
-
|
531
|
-
class BaseTransmittedAPIData(BaseModel):
|
532
|
-
model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True, from_attributes=True)
|
533
|
-
|
534
|
-
|
535
|
-
class SimpleTransmittedAPIData(BaseTransmittedAPIData):
|
536
|
-
settings: BaseSettings2 | None = None
|
537
|
-
|
538
|
-
|
539
|
-
class AdvancedTransmittedAPIData(SimpleTransmittedAPIData):
|
540
|
-
sqlalchemy_db: SQLAlchemyDb | None = None
|
541
|
-
json_db: BaseJSONDb | None = None
|
542
|
-
media_file_storage_in_dir: FileStorageInDir | None = None
|
543
|
-
cache_file_storage_in_dir: FileStorageInDir | None = None
|
544
|
-
dump_file_storage_in_dir: FileStorageInDir | None = None
|
545
|
-
|
546
|
-
|
547
|
-
def get_transmitted_api_data(request: starlette.requests.Request) -> BaseTransmittedAPIData:
|
548
|
-
return request.app.state.transmitted_api_data
|
549
|
-
|
550
|
-
|
551
|
-
class BaseAPIAuthData(BaseModel):
|
552
|
-
model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True, from_attributes=True)
|
553
|
-
|
554
|
-
require_api_key_string: bool = False
|
555
|
-
require_token_string: bool = False
|
556
|
-
|
557
|
-
require_correct_api_key: bool = False
|
558
|
-
require_correct_token: bool = False
|
559
|
-
|
560
|
-
token_string: str | None = None
|
561
|
-
api_key_string: str | None = None
|
562
|
-
|
563
|
-
is_token_correct: bool | None = None
|
564
|
-
is_api_key_correct: bool | None = None
|
565
|
-
|
566
|
-
|
567
|
-
def base_api_auth(
|
568
|
-
*,
|
569
|
-
require_api_key_string: bool = False,
|
570
|
-
require_token_string: bool = False,
|
571
|
-
validate_api_key_func: Callable | None = None,
|
572
|
-
validate_token_func: Callable | None = None,
|
573
|
-
correct_api_keys: str | list[str] | None = None,
|
574
|
-
correct_tokens: str | list[str] | None = None,
|
575
|
-
require_correct_api_key: bool = False,
|
576
|
-
require_correct_token: bool = False,
|
577
|
-
**kwargs
|
578
|
-
) -> Callable:
|
579
|
-
if isinstance(correct_api_keys, str):
|
580
|
-
correct_api_keys = [correct_api_keys]
|
581
|
-
if correct_api_keys is not None:
|
582
|
-
raise_for_type(correct_api_keys, list)
|
583
|
-
validate_api_key_func = lambda *args, **kwargs_: kwargs_["api_key_string"] in correct_api_keys
|
584
|
-
|
585
|
-
if isinstance(correct_tokens, str):
|
586
|
-
correct_tokens = [correct_tokens]
|
587
|
-
if correct_tokens is not None:
|
588
|
-
raise_for_type(correct_tokens, list)
|
589
|
-
validate_token_func = lambda *args, **kwargs_: kwargs_["token_string"] in correct_tokens
|
590
|
-
|
591
|
-
if require_correct_api_key:
|
592
|
-
raise_if_none(validate_api_key_func)
|
593
|
-
require_api_key_string = True
|
594
|
-
|
595
|
-
if require_correct_token:
|
596
|
-
raise_if_none(validate_token_func)
|
597
|
-
require_token_string = True
|
598
|
-
|
599
|
-
async def func(
|
600
|
-
*,
|
601
|
-
ac: fastapi.security.HTTPAuthorizationCredentials | None = fastapi.Security(
|
602
|
-
fastapi.security.HTTPBearer(auto_error=False)
|
603
|
-
),
|
604
|
-
api_key_string: str | None = Security(
|
605
|
-
APIKeyHeader(name="apikey", auto_error=False)
|
606
|
-
),
|
607
|
-
request: starlette.requests.Request,
|
608
|
-
transmitted_api_data: BaseTransmittedAPIData = Depends(get_transmitted_api_data)
|
609
|
-
) -> BaseAPIAuthData:
|
610
|
-
|
611
|
-
api_auth_data = BaseAPIAuthData(
|
612
|
-
require_api_key_string=require_api_key_string,
|
613
|
-
require_token_string=require_token_string,
|
614
|
-
require_correct_api_key=require_correct_api_key,
|
615
|
-
require_correct_token=require_correct_token
|
616
|
-
)
|
617
|
-
|
618
|
-
# parse api_key
|
619
|
-
|
620
|
-
api_auth_data.api_key_string = api_key_string
|
621
|
-
|
622
|
-
if not api_auth_data.api_key_string and "api_key" in request.headers.keys():
|
623
|
-
api_auth_data.api_key_string = request.headers["api_key"]
|
624
|
-
if not api_auth_data.api_key_string and "api-key" in request.headers.keys():
|
625
|
-
api_auth_data.api_key_string = request.headers["api-key"]
|
626
|
-
if not api_auth_data.api_key_string and "apikey" in request.headers.keys():
|
627
|
-
api_auth_data.api_key_string = request.headers["apikey"]
|
628
|
-
|
629
|
-
if not api_auth_data.api_key_string and "api_key" in request.query_params.keys():
|
630
|
-
api_auth_data.api_key_string = request.query_params["api_key"]
|
631
|
-
if not api_auth_data.api_key_string and "api-key" in request.query_params.keys():
|
632
|
-
api_auth_data.api_key_string = request.query_params["api-key"]
|
633
|
-
if not api_auth_data.api_key_string and "apikey" in request.query_params.keys():
|
634
|
-
api_auth_data.api_key_string = request.query_params["apikey"]
|
635
|
-
|
636
|
-
# parse token
|
637
|
-
|
638
|
-
api_auth_data.token_string = ac.credentials if ac and ac.credentials and ac.credentials.strip() else None
|
639
|
-
|
640
|
-
if not api_auth_data.token_string and "token" in request.headers.keys():
|
641
|
-
api_auth_data.token_string = request.headers["token"]
|
642
|
-
|
643
|
-
if not api_auth_data.token_string and "user_token" in request.headers.keys():
|
644
|
-
api_auth_data.token_string = request.headers["user_token"]
|
645
|
-
if not api_auth_data.token_string and "user-token" in request.headers.keys():
|
646
|
-
api_auth_data.token_string = request.headers["user-token"]
|
647
|
-
if not api_auth_data.token_string and "usertoken" in request.headers.keys():
|
648
|
-
api_auth_data.token_string = request.headers["usertoken"]
|
649
|
-
|
650
|
-
if not api_auth_data.token_string and "token" in request.query_params.keys():
|
651
|
-
api_auth_data.token_string = request.query_params["token"]
|
652
|
-
|
653
|
-
if not api_auth_data.token_string and "user_token" in request.query_params.keys():
|
654
|
-
api_auth_data.token_string = request.query_params["user_token"]
|
655
|
-
if not api_auth_data.token_string and "user-token" in request.query_params.keys():
|
656
|
-
api_auth_data.token_string = request.query_params["user-token"]
|
657
|
-
if not api_auth_data.token_string and "usertoken" in request.query_params.keys():
|
658
|
-
api_auth_data.token_string = request.query_params["usertoken"]
|
659
|
-
|
660
|
-
if api_auth_data.token_string:
|
661
|
-
api_auth_data.token_string = api_auth_data.token_string.strip()
|
662
|
-
if not api_auth_data.token_string:
|
663
|
-
api_auth_data.token_string = None
|
664
|
-
|
665
|
-
# require_api_key_string
|
666
|
-
|
667
|
-
if require_api_key_string and not api_auth_data.api_key_string:
|
668
|
-
raise APIException(
|
669
|
-
status_code=starlette.status.HTTP_401_UNAUTHORIZED,
|
670
|
-
error_code=BaseAPIErrorCodes.cannot_authorize,
|
671
|
-
error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
|
672
|
-
)
|
673
|
-
|
674
|
-
# require_token_string
|
675
|
-
|
676
|
-
if require_token_string and not api_auth_data.token_string:
|
677
|
-
raise APIException(
|
678
|
-
status_code=starlette.status.HTTP_401_UNAUTHORIZED,
|
679
|
-
error_code=BaseAPIErrorCodes.cannot_authorize,
|
680
|
-
error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
|
681
|
-
)
|
682
|
-
|
683
|
-
# validate_api_key_func
|
684
|
-
|
685
|
-
if validate_api_key_func is not None:
|
686
|
-
validate_api_key_func_res = validate_api_key_func(
|
687
|
-
api_key_string=api_auth_data.api_key_string,
|
688
|
-
token_string=api_auth_data.token_string,
|
689
|
-
base_api_auth_data=api_auth_data,
|
690
|
-
transmitted_api_data=transmitted_api_data,
|
691
|
-
request=request,
|
692
|
-
**kwargs
|
693
|
-
)
|
694
|
-
if is_async_object(validate_api_key_func_res):
|
695
|
-
validate_api_key_func_res = await validate_api_key_func_res
|
696
|
-
api_auth_data.is_api_key_correct = validate_api_key_func_res
|
697
|
-
|
698
|
-
# validate_token_func
|
699
|
-
|
700
|
-
if validate_token_func is not None:
|
701
|
-
validate_token_func_res = validate_token_func(
|
702
|
-
api_key_string=api_auth_data.api_key_string,
|
703
|
-
token_string=api_auth_data.token_string,
|
704
|
-
base_api_auth_data=api_auth_data,
|
705
|
-
transmitted_api_data=transmitted_api_data,
|
706
|
-
request=request,
|
707
|
-
**kwargs
|
708
|
-
)
|
709
|
-
if is_async_object(validate_token_func_res):
|
710
|
-
validate_token_func_res = await validate_token_func_res
|
711
|
-
api_auth_data.is_token_correct = validate_token_func_res
|
712
|
-
|
713
|
-
# require_correct_api_key
|
714
|
-
|
715
|
-
if require_correct_api_key:
|
716
|
-
if not api_auth_data.is_api_key_correct:
|
717
|
-
raise APIException(
|
718
|
-
status_code=starlette.status.HTTP_401_UNAUTHORIZED,
|
719
|
-
error_code=BaseAPIErrorCodes.cannot_authorize,
|
720
|
-
error_description="not api_auth_data.is_api_key_correct",
|
721
|
-
error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump()),
|
722
|
-
)
|
723
|
-
|
724
|
-
# require_correct_token
|
725
|
-
|
726
|
-
if require_correct_token:
|
727
|
-
if not api_auth_data.is_token_correct:
|
728
|
-
raise APIException(
|
729
|
-
status_code=starlette.status.HTTP_401_UNAUTHORIZED,
|
730
|
-
error_code=BaseAPIErrorCodes.cannot_authorize,
|
731
|
-
error_description="not api_auth_data.is_token_correct",
|
732
|
-
error_data=safely_transfer_obj_to_json_str_to_json_obj(api_auth_data.model_dump())
|
733
|
-
)
|
734
|
-
|
735
|
-
return api_auth_data
|
736
|
-
|
737
|
-
return func
|
738
|
-
|
739
|
-
|
740
|
-
def simple_api_router_for_testing():
|
741
|
-
router = APIRouter(tags=["Testing"])
|
742
|
-
|
743
|
-
@router.get(
|
744
|
-
"/raise_fake_exception_1",
|
745
|
-
response_model=ErrorSO
|
746
|
-
)
|
747
|
-
async def _():
|
748
|
-
raise fastapi.HTTPException(status_code=starlette.status.HTTP_500_INTERNAL_SERVER_ERROR)
|
749
|
-
|
750
|
-
@router.get(
|
751
|
-
"/raise_fake_exception_2",
|
752
|
-
response_model=ErrorSO
|
753
|
-
)
|
754
|
-
async def _():
|
755
|
-
raise APIException(
|
756
|
-
error_code="raise_fake_exception_2",
|
757
|
-
error_specification_code="raise_fake_exception_2",
|
758
|
-
error_description="raise_fake_exception_2"
|
759
|
-
)
|
760
|
-
|
761
|
-
@router.get(
|
762
|
-
"/raise_fake_exception_3",
|
763
|
-
response_model=ErrorSO
|
764
|
-
)
|
765
|
-
async def _():
|
766
|
-
raise Exception("raise_fake_exception_3")
|
767
|
-
|
768
|
-
@router.get(
|
769
|
-
"/check_params_1",
|
770
|
-
response_model=ErrorSO
|
771
|
-
)
|
772
|
-
async def _(name: int = Query()):
|
773
|
-
return RawDataSO(data={"name": name})
|
774
|
-
|
775
|
-
return router
|
776
|
-
|
777
|
-
|
778
|
-
def create_fastapi_app(
|
779
|
-
*,
|
780
|
-
title: str = "arpakitlib FastAPI",
|
781
|
-
description: str | None = "arpakitlib FastAPI",
|
782
|
-
handle_exception_: Callable | None = None,
|
783
|
-
startup_api_events: list[BaseStartupAPIEvent | None] | None = None,
|
784
|
-
shutdown_api_events: list[BaseShutdownAPIEvent | None] | None = None,
|
785
|
-
transmitted_api_data: BaseTransmittedAPIData = BaseTransmittedAPIData(),
|
786
|
-
main_api_router: APIRouter = simple_api_router_for_testing(),
|
787
|
-
contact: dict[str, Any] | None = None,
|
788
|
-
media_dirpath: str | None = None,
|
789
|
-
static_dirpath: str | None = None
|
790
|
-
):
|
791
|
-
_logger.info("start")
|
792
|
-
|
793
|
-
if handle_exception_ is None:
|
794
|
-
handle_exception_ = create_handle_exception(
|
795
|
-
funcs_before=[
|
796
|
-
logging__api_func_before_in_handle_exception()
|
797
|
-
]
|
798
|
-
)
|
799
|
-
|
800
|
-
if not startup_api_events:
|
801
|
-
startup_api_events = [BaseStartupAPIEvent()]
|
802
|
-
startup_api_events = [v for v in startup_api_events if v is not None]
|
803
|
-
|
804
|
-
if not shutdown_api_events:
|
805
|
-
shutdown_api_events = [BaseShutdownAPIEvent()]
|
806
|
-
shutdown_api_events = [v for v in shutdown_api_events if v is not None]
|
807
|
-
|
808
|
-
app = FastAPI(
|
809
|
-
title=title,
|
810
|
-
description=description,
|
811
|
-
docs_url=None,
|
812
|
-
redoc_url=None,
|
813
|
-
openapi_url="/openapi",
|
814
|
-
on_startup=[api_startup_event.async_on_startup for api_startup_event in startup_api_events],
|
815
|
-
on_shutdown=[api_shutdown_event.async_on_shutdown for api_shutdown_event in shutdown_api_events],
|
816
|
-
contact=contact
|
817
|
-
)
|
818
|
-
|
819
|
-
if media_dirpath is not None:
|
820
|
-
if not os.path.exists(media_dirpath):
|
821
|
-
os.makedirs(media_dirpath, exist_ok=True)
|
822
|
-
app.mount("/media", StaticFiles(directory=media_dirpath), name="media")
|
823
|
-
|
824
|
-
if static_dirpath is not None:
|
825
|
-
if not os.path.exists(static_dirpath):
|
826
|
-
os.makedirs(static_dirpath, exist_ok=True)
|
827
|
-
app.mount("/static", StaticFiles(directory=static_dirpath), name="static")
|
828
|
-
|
829
|
-
app.state.transmitted_api_data = transmitted_api_data
|
830
|
-
|
831
|
-
add_cors_to_app(app=app)
|
832
|
-
|
833
|
-
add_swagger_to_app(app=app)
|
834
|
-
|
835
|
-
add_exception_handler_to_app(
|
836
|
-
app=app,
|
837
|
-
handle_exception=handle_exception_
|
838
|
-
)
|
839
|
-
|
840
|
-
app.include_router(
|
841
|
-
router=create_needed_api_router(),
|
842
|
-
prefix=""
|
843
|
-
)
|
844
|
-
|
845
|
-
app.include_router(router=main_api_router)
|
846
|
-
|
847
|
-
_logger.info("finish")
|
848
|
-
|
849
|
-
return app
|
850
|
-
|
851
|
-
|
852
|
-
def __example():
|
853
|
-
pass
|
854
|
-
|
855
|
-
|
856
|
-
async def __async_example():
|
857
|
-
pass
|
858
|
-
|
859
|
-
|
860
|
-
if __name__ == '__main__':
|
861
|
-
__example()
|
862
|
-
asyncio.run(__async_example())
|