redis implemntations and api setup completed
This commit is contained in:
parent
32022ca521
commit
3d5a43220e
|
|
@ -0,0 +1,35 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyInterpreterInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="21">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="rsa" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="pydantic" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="alembic" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="starlette-context" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="pymongo" />
|
||||||
|
<item index="5" class="java.lang.String" itemvalue="arrow" />
|
||||||
|
<item index="6" class="java.lang.String" itemvalue="unidecode" />
|
||||||
|
<item index="7" class="java.lang.String" itemvalue="python-dotenv" />
|
||||||
|
<item index="8" class="java.lang.String" itemvalue="psycopg2-binary" />
|
||||||
|
<item index="9" class="java.lang.String" itemvalue="cryptography" />
|
||||||
|
<item index="10" class="java.lang.String" itemvalue="requests" />
|
||||||
|
<item index="11" class="java.lang.String" itemvalue="redis" />
|
||||||
|
<item index="12" class="java.lang.String" itemvalue="sqlalchemy" />
|
||||||
|
<item index="13" class="java.lang.String" itemvalue="pandas" />
|
||||||
|
<item index="14" class="java.lang.String" itemvalue="fastapi" />
|
||||||
|
<item index="15" class="java.lang.String" itemvalue="Deprecated" />
|
||||||
|
<item index="16" class="java.lang.String" itemvalue="faker" />
|
||||||
|
<item index="17" class="java.lang.String" itemvalue="textdistance" />
|
||||||
|
<item index="18" class="java.lang.String" itemvalue="uvicorn" />
|
||||||
|
<item index="19" class="java.lang.String" itemvalue="redmail" />
|
||||||
|
<item index="20" class="java.lang.String" itemvalue="sqlalchemy-mixins" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/wag-managment-api-service-version-5.iml" filepath="$PROJECT_DIR$/.idea/wag-managment-api-service-version-5.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="PyDocumentationSettings">
|
||||||
|
<option name="format" value="PLAIN" />
|
||||||
|
<option name="myDocStringFormat" value="Plain" />
|
||||||
|
</component>
|
||||||
|
<component name="TestRunnerService">
|
||||||
|
<option name="PROJECT_TEST_RUNNER" value="py.test" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
|
|
@ -0,0 +1,185 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AutoImportSettings">
|
||||||
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
|
</component>
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="b5202e0c-6ddf-4a56-a13a-e18798c4c7cf" name="Changes" comment="">
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/app.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/app_handler.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/application/__init__.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/application/app.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/create_file.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/create_routes.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/middleware/__init__.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/middleware/auth_middleware.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/middleware/function_wrappers.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/middleware/token_event_middleware.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllApiNeeds/open_api_creator.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllConfigs/Email/configs.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/AllConfigs/Email/configs.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllConfigs/NoSqlDatabase/configs.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/AllConfigs/NoSqlDatabase/configs.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllConfigs/Redis/configs.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/AllConfigs/Redis/configs.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllConfigs/SqlDatabase/configs.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/AllConfigs/SqlDatabase/configs.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/AllConfigs/Token/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/AllConfigs/Token/config.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiLibrary/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiLibrary/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiLibrary/date_time_actions/date_functions.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiLibrary/date_time_actions/date_functions.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiLibrary/token/password_module.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiLibrary/token/password_module.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/Login/user_login_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/Login/user_login_handler.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/Token/token_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/Token/token_handler.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiServices/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiServices/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/account_records.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/account_records.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/address.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/address.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/application.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/application.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/area.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/area.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/authentication.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/authentication.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/base_validations.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/base_validations.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/build_living_space.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/build_living_space.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/build_part.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/build_part.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/building.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/building.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/company.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/company.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/core_request_validations.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/core_request_validations.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/decision_book.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/decision_book.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/departments.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/departments.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/employee.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/employee.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/events.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/events.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/modules.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/modules.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/people.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/people.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/project_decision_book.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/project_decision_book.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/rules.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/rules.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/services.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/services.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/staff.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/staff.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/user.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Request/user.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ApiValidations/Response/default_response.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ApiValidations/Response/default_response.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/ErrorHandlers/api_exc_handler.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/ErrorHandlers/api_exc_handler.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/bases.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/ErrorHandlers/bases.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/account.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/account.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/iban.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/account/iban.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/budget.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/budget.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/build.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/build.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/decision_book.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/building/decision_book.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/company.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/company.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/department.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/department.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/employee.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/company/employee.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/event/event.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/event/event.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/identity/identity.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/identity/identity.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/rules/rules.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Database/rules/rules.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/LanguageModels/Errors/merge_all_error_languages.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/LanguageModels/Errors/merge_all_error_languages.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/account/account.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/account/account.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/building/build.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/building/build.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/building/decision_book.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/building/decision_book.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/company/company.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/company/company.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/company/employee.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/company/employee.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/event/event.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/event/event.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/identity/identity.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/identity/identity.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ApiLayers/Schemas/rules/rules.py" beforeDir="false" afterPath="$PROJECT_DIR$/ApiLayers/Schemas/rules/rules.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/Dockerfile" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/EventServiceApi/Dockerfile" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/Dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/DockerApiServices/ValidationServiceApi/Dockerfile" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/api_events.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/api_events.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/auth.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/auth.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/cluster.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/cluster.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/function_handlers.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/function_handlers.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/info.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/info.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/authentication/auth/models.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/events/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/events/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/AllEvents/validations/validation/validation.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/AllEvents/validations/validation/validation.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/Engine/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/Engine/abstract_class.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/abstract_class.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/Engine/set_defaults/run.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/set_defaults/run.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/Engine/set_defaults/setClusters.py" beforeDir="false" afterPath="$PROJECT_DIR$/Events/Engine/set_defaults/setClusters.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/abstract_class.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Events/abstract_class_old.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Scratches/endpoint.py" beforeDir="false" afterPath="$PROJECT_DIR$/Scratches/endpoint.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models/core_alchemy.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/Models/core_alchemy.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models/crud_alchemy.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/Models/crud_alchemy.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models/filter_functions.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/Models/filter_functions.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models_old/alchemy_response.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models_old/base_model.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models_old/filter_functions.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models_old/mixins.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models_old/query.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/Models_old/response.py" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/PostgresDb/database.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/PostgresDb/database.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/Redis/Actions/actions.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/Redis/Actions/actions.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/Redis/Models/row.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/Redis/Models/row.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/Redis/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/Redis/__init__.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Services/Redis/conn.py" beforeDir="false" afterPath="$PROJECT_DIR$/Services/Redis/conn.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/docker-compose-services.yml" beforeDir="false" afterPath="$PROJECT_DIR$/docker-compose-services.yml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/docs/improvements/validation_service/backend/unified_schema_service.py" beforeDir="false" afterPath="$PROJECT_DIR$/docs/improvements/validation_service/backend/unified_schema_service.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/trash/auth_old.py" beforeDir="false" afterPath="$PROJECT_DIR$/trash/auth_old.py" afterDir="false" />
|
||||||
|
</list>
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectColorInfo"><![CDATA[{
|
||||||
|
"associatedIndex": 4
|
||||||
|
}]]></component>
|
||||||
|
<component name="ProjectId" id="2s7vXt8ZNmztWMeL9tjyT9ledZJ" />
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
|
"keyToString": {
|
||||||
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
|
"git-widget-placeholder": "development",
|
||||||
|
"last_opened_file_path": "/home/berkay/git-gitea-evyos/wag-managment-api-service-version-5"
|
||||||
|
}
|
||||||
|
}]]></component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="events_file" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||||
|
<module name="wag-managment-api-service-version-5" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/DockerApiServices/AuthServiceApi" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/DockerApiServices/AuthServiceApi/events_file.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Python.events_file" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="SharedIndexes">
|
||||||
|
<attachedChunks>
|
||||||
|
<set>
|
||||||
|
<option value="bundled-python-sdk-1b1018131e27-aa17d162503b-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-243.22562.180" />
|
||||||
|
</set>
|
||||||
|
</attachedChunks>
|
||||||
|
</component>
|
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="b5202e0c-6ddf-4a56-a13a-e18798c4c7cf" name="Changes" comment="" />
|
||||||
|
<created>1737819471396</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1737819471396</updated>
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
"""
|
|
||||||
Base FastAPI application configuration.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
|
||||||
app = FastAPI(title="API Service")
|
|
||||||
|
|
||||||
# Configure CORS
|
|
||||||
app.add_middleware(
|
|
||||||
CORSMiddleware,
|
|
||||||
allow_origins=["*"],
|
|
||||||
allow_credentials=True,
|
|
||||||
allow_methods=["*"],
|
|
||||||
allow_headers=["*"],
|
|
||||||
)
|
|
||||||
|
|
||||||
return app
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
"""
|
|
||||||
FastAPI Application Factory Module
|
|
||||||
|
|
||||||
This module provides functionality to create and configure a FastAPI application with:
|
|
||||||
- Custom OpenAPI schema configuration
|
|
||||||
- Security scheme configuration for Bearer authentication
|
|
||||||
- Automatic router registration
|
|
||||||
- Response class configuration
|
|
||||||
- Security requirements for protected endpoints
|
|
||||||
"""
|
|
||||||
|
|
||||||
from typing import Any, Dict, List, Tuple
|
|
||||||
from fastapi import FastAPI, APIRouter
|
|
||||||
from fastapi.responses import JSONResponse, RedirectResponse
|
|
||||||
from fastapi.openapi.utils import get_openapi
|
|
||||||
|
|
||||||
from AllConfigs.Token.config import Auth
|
|
||||||
from AllConfigs.main import MainConfig as Config
|
|
||||||
|
|
||||||
from create_routes import get_all_routers
|
|
||||||
|
|
||||||
|
|
||||||
def setup_security_schema() -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Configure security schema for the OpenAPI documentation.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, Any]: Security schema configuration
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
"components": {
|
|
||||||
"securitySchemes": {
|
|
||||||
"Bearer Auth": {
|
|
||||||
"type": "apiKey",
|
|
||||||
"in": "header",
|
|
||||||
"name": Auth.ACCESS_TOKEN_TAG,
|
|
||||||
"description": "Enter: **'Bearer <JWT>'**, where JWT is the access token",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def configure_route_security(
|
|
||||||
path: str, method: str, schema: Dict[str, Any], protected_paths: List[str]
|
|
||||||
) -> None:
|
|
||||||
"""
|
|
||||||
Configure security requirements for a specific route.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
path: Route path
|
|
||||||
method: HTTP method
|
|
||||||
schema: OpenAPI schema to modify
|
|
||||||
protected_paths: List of paths that require authentication
|
|
||||||
"""
|
|
||||||
if path in protected_paths:
|
|
||||||
if "paths" in schema and path in schema["paths"]:
|
|
||||||
if method.lower() in schema["paths"][path]:
|
|
||||||
schema["paths"][path][method.lower()]["security"] = [{"Bearer": []}]
|
|
||||||
|
|
||||||
|
|
||||||
def create_app() -> FastAPI:
|
|
||||||
"""
|
|
||||||
Create and configure a FastAPI application with dynamic route creation.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
FastAPI: Configured FastAPI application instance
|
|
||||||
"""
|
|
||||||
|
|
||||||
from open_api_creator import create_openapi_schema
|
|
||||||
|
|
||||||
# Get all routers and protected routes using the dynamic route creation
|
|
||||||
|
|
||||||
app = FastAPI(
|
|
||||||
title=Config.TITLE,
|
|
||||||
description=Config.DESCRIPTION,
|
|
||||||
default_response_class=JSONResponse,
|
|
||||||
) # Initialize FastAPI app
|
|
||||||
|
|
||||||
@app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION))
|
|
||||||
async def home() -> RedirectResponse:
|
|
||||||
"""Redirect root path to API documentation."""
|
|
||||||
return RedirectResponse(url="/docs")
|
|
||||||
|
|
||||||
# Get all routers and protected routes using the dynamic route creation
|
|
||||||
routers, protected_routes = get_all_routers()
|
|
||||||
|
|
||||||
# Include all routers
|
|
||||||
for router in routers:
|
|
||||||
app.include_router(router)
|
|
||||||
|
|
||||||
app.openapi = lambda app=app: create_openapi_schema(app)
|
|
||||||
|
|
||||||
return app
|
|
||||||
|
|
@ -1,127 +0,0 @@
|
||||||
"""
|
|
||||||
Route configuration and factory module.
|
|
||||||
Handles dynamic route creation based on configurations.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from typing import Optional, Dict, Any, List, Callable, TypeVar, ParamSpec
|
|
||||||
|
|
||||||
P = ParamSpec("P") # For function parameters
|
|
||||||
R = TypeVar("R") # For return type
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from functools import wraps
|
|
||||||
from fastapi import APIRouter, Request
|
|
||||||
from fastapi.routing import APIRoute
|
|
||||||
from middleware.auth_middleware import MiddlewareModule
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from AllConfigs.main import MainConfig as Config
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class EndpointFactoryConfig:
|
|
||||||
endpoint: str
|
|
||||||
method: str
|
|
||||||
summary: str
|
|
||||||
description: str
|
|
||||||
endpoint_function: Callable[P, R] # Now accepts any parameters and return type
|
|
||||||
is_auth_required: bool = True
|
|
||||||
is_event_required: bool = False
|
|
||||||
extra_options: Dict[str, Any] = None
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
if self.extra_options is None:
|
|
||||||
self.extra_options = {}
|
|
||||||
|
|
||||||
|
|
||||||
class EnhancedEndpointFactory:
|
|
||||||
def __init__(self, router_config: dict):
|
|
||||||
self.router = APIRouter(
|
|
||||||
prefix=router_config["prefix"],
|
|
||||||
tags=router_config["tags"],
|
|
||||||
include_in_schema=router_config.get("include_in_schema", True),
|
|
||||||
)
|
|
||||||
self.endpoints = router_config["endpoints"]
|
|
||||||
self.protected_routes: Dict[str, List[str]] = {}
|
|
||||||
|
|
||||||
def create_endpoint(self, config: EndpointFactoryConfig):
|
|
||||||
"""
|
|
||||||
Create an endpoint directly from the configuration.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
config: EndpointFactoryConfig instance containing endpoint configuration
|
|
||||||
"""
|
|
||||||
endpoint_path = config.endpoint
|
|
||||||
endpoint_function = config.endpoint_function
|
|
||||||
|
|
||||||
if config.is_auth_required:
|
|
||||||
# endpoint_function = MiddlewareModule.auth_required(endpoint_function)
|
|
||||||
# Track protected routes
|
|
||||||
full_path = f"{self.router.prefix}{endpoint_path}"
|
|
||||||
if full_path not in self.protected_routes:
|
|
||||||
self.protected_routes[full_path] = []
|
|
||||||
self.protected_routes[full_path].append(config.method.lower())
|
|
||||||
|
|
||||||
# Register the endpoint with FastAPI router
|
|
||||||
getattr(self.router, config.method.lower())(
|
|
||||||
endpoint_path,
|
|
||||||
summary=config.summary,
|
|
||||||
description=config.description,
|
|
||||||
**config.extra_options,
|
|
||||||
)(endpoint_function)
|
|
||||||
|
|
||||||
def get_router(self) -> APIRouter:
|
|
||||||
"""Get the configured router."""
|
|
||||||
return self.router
|
|
||||||
|
|
||||||
def get_protected_routes(self) -> Dict[str, List[str]]:
|
|
||||||
"""Get the protected routes mapping."""
|
|
||||||
return self.protected_routes
|
|
||||||
|
|
||||||
|
|
||||||
async def health_check(request: Request):
|
|
||||||
"""Default health check endpoint."""
|
|
||||||
return {"status": "healthy", "message": "Service is running"}
|
|
||||||
|
|
||||||
|
|
||||||
async def ping_test(request: Request, service_name: str = "base-router"):
|
|
||||||
"""Default ping test endpoint."""
|
|
||||||
return {"ping": "pong", "service": service_name}
|
|
||||||
|
|
||||||
|
|
||||||
def get_all_routers() -> tuple[List[APIRouter], Dict[str, List[str]]]:
|
|
||||||
"""
|
|
||||||
Get all routers and protected routes from route configurations.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
tuple: (routers, protected_routes)
|
|
||||||
"""
|
|
||||||
from ApiEvents.route_configs import get_route_configs
|
|
||||||
|
|
||||||
routers = []
|
|
||||||
all_protected_routes = {}
|
|
||||||
|
|
||||||
# Get route configurations from the registry
|
|
||||||
route_configs = get_route_configs()
|
|
||||||
factory_all = []
|
|
||||||
for config in route_configs:
|
|
||||||
factory = EnhancedEndpointFactory(config)
|
|
||||||
|
|
||||||
# Create endpoints from configuration
|
|
||||||
for endpoint_dict in config["endpoints"]:
|
|
||||||
endpoint_config = EndpointFactoryConfig(
|
|
||||||
endpoint=endpoint_dict["endpoint"],
|
|
||||||
method=endpoint_dict["method"],
|
|
||||||
summary=endpoint_dict["summary"],
|
|
||||||
description=endpoint_dict["description"],
|
|
||||||
endpoint_function=endpoint_dict["endpoint_function"],
|
|
||||||
is_auth_required=endpoint_dict["is_auth_required"],
|
|
||||||
is_event_required=endpoint_dict["is_event_required"],
|
|
||||||
extra_options=endpoint_dict.get("extra_options", {}),
|
|
||||||
)
|
|
||||||
factory.create_endpoint(endpoint_config)
|
|
||||||
factory_all.append(endpoint_config.__dict__)
|
|
||||||
|
|
||||||
# Add router and protected routes
|
|
||||||
routers.append(factory.get_router())
|
|
||||||
all_protected_routes.update(factory.get_protected_routes())
|
|
||||||
return routers, all_protected_routes
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from AllConfigs import HostConfig
|
from ApiLayers.AllConfigs import HostConfig
|
||||||
|
|
||||||
|
|
||||||
class EmailConfig:
|
class EmailConfig:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from AllConfigs import HostConfig
|
from ApiLayers.AllConfigs import HostConfig
|
||||||
|
|
||||||
|
|
||||||
class MongoConfig:
|
class MongoConfig:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from AllConfigs import HostConfig
|
from ApiLayers.AllConfigs import HostConfig
|
||||||
|
|
||||||
|
|
||||||
class WagRedis:
|
class WagRedis:
|
||||||
|
|
@ -16,14 +16,18 @@ class WagRedis:
|
||||||
db=WagRedis.REDIS_DB,
|
db=WagRedis.REDIS_DB,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RedisCategoryKeys:
|
class RedisCategoryKeys:
|
||||||
|
REBUILD: str = "REBUILD"
|
||||||
|
ENDPOINT2CLASS: str = "ENDPOINT2CLASS"
|
||||||
LANGUAGE_MODELS: str = "LANGUAGE_MODELS"
|
LANGUAGE_MODELS: str = "LANGUAGE_MODELS"
|
||||||
VALIDATION_USER: str = "VALIDATION_USER"
|
VALIDATION_USER: str = "VALIDATION_USER"
|
||||||
|
CLUSTER_INDEX: str = "CLUSTER_INDEX"
|
||||||
CLUSTER_FUNCTION_CODES: str = "CLUSTER_FUNCTION_CODES"
|
CLUSTER_FUNCTION_CODES: str = "CLUSTER_FUNCTION_CODES"
|
||||||
METHOD_FUNCTION_CODES: str = "METHOD_FUNCTION_CODES"
|
METHOD_FUNCTION_CODES: str = "METHOD_FUNCTION_CODES"
|
||||||
MENU_FIRST_LAYER: str = "MENU_FIRST_LAYER"
|
MENU_FIRST_LAYER: str = "MENU_FIRST_LAYER"
|
||||||
PAGE_MAPPER: str = "PAGE_MAPPER"
|
PAGE_MAPPER: str = "PAGE_MAPPER"
|
||||||
MENU_MAPPER: str = "MENU_MAPPER"
|
MENU_MAPPER: str = "MENU_MAPPER"
|
||||||
AUTH: str = "AUTH"
|
AUTH: str = "AUTH"
|
||||||
OCC: str = "Occupant"
|
OCCUPANT: str = "OCCUPANT"
|
||||||
EMP: str = "Employee"
|
EMPLOYEE: str = "EMPLOYEE"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from AllConfigs import HostConfig
|
from ApiLayers.AllConfigs import HostConfig
|
||||||
|
|
||||||
|
|
||||||
class WagDatabase:
|
class WagDatabase:
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
class ApiStatic:
|
|
||||||
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
|
|
||||||
FORGOT_LINK = "https://www.evyos.com.tr/password/create?tokenUrl="
|
|
||||||
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
|
|
||||||
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def forgot_link(cls, forgot_key):
|
|
||||||
return cls.FORGOT_LINK + forgot_key
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def blacklist_login(cls, record_id):
|
|
||||||
return cls.BLACKLIST_LINK + record_id
|
|
||||||
|
|
||||||
|
|
||||||
class Auth:
|
class Auth:
|
||||||
ACCESS_EMAIL_EXT = "evyos.com.tr"
|
ACCESS_EMAIL_EXT = "evyos.com.tr"
|
||||||
ACCESS_TOKEN_TAG = "evyos-session-key"
|
ACCESS_TOKEN_TAG = "evyos-session-key"
|
||||||
|
|
@ -40,32 +25,3 @@ class Auth:
|
||||||
TOKEN_EXPIRE_DAY_5 = datetime.timedelta(days=5)
|
TOKEN_EXPIRE_DAY_5 = datetime.timedelta(days=5)
|
||||||
TOKEN_EXPIRE_DAY_15 = datetime.timedelta(days=15)
|
TOKEN_EXPIRE_DAY_15 = datetime.timedelta(days=15)
|
||||||
TOKEN_EXPIRE_DAY_30 = datetime.timedelta(days=30)
|
TOKEN_EXPIRE_DAY_30 = datetime.timedelta(days=30)
|
||||||
|
|
||||||
|
|
||||||
class Routers:
|
|
||||||
NO_TOKEN_REQUIRES = [
|
|
||||||
"/",
|
|
||||||
"/metrics",
|
|
||||||
"/openapi.json",
|
|
||||||
"/docs",
|
|
||||||
"/redoc",
|
|
||||||
"/auth/login",
|
|
||||||
"/favicon.ico",
|
|
||||||
"/docs/oauth2-redirect",
|
|
||||||
"/authentication/select",
|
|
||||||
"/authentication/login",
|
|
||||||
"/authentication/logout",
|
|
||||||
"/authentication/refresher",
|
|
||||||
"/authentication/refresh",
|
|
||||||
"/authentication/disconnect",
|
|
||||||
"/authentication/create_password",
|
|
||||||
"/authentication/reset_password",
|
|
||||||
"/authentication/forgot",
|
|
||||||
"/authentication/valid",
|
|
||||||
]
|
|
||||||
NO_EVENT_REQUIRES = [
|
|
||||||
"/access/endpoints/available",
|
|
||||||
"/access/endpoint/available",
|
|
||||||
"/validations/endpoint",
|
|
||||||
"/authentication/avatar",
|
|
||||||
]
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
from ApiLibrary.date_time_actions.date_functions import (
|
from ApiLayers.ApiLibrary.date_time_actions.date_functions import (
|
||||||
DateTimeLocal,
|
DateTimeLocal,
|
||||||
system_arrow,
|
system_arrow,
|
||||||
client_arrow,
|
client_arrow,
|
||||||
)
|
)
|
||||||
from ApiLibrary.extensions.select import SelectActionWithEmployee, SelectAction
|
from ApiLayers.ApiLibrary.extensions.select import (
|
||||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
SelectActionWithEmployee,
|
||||||
|
SelectAction,
|
||||||
|
)
|
||||||
|
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"DateTimeLocal",
|
"DateTimeLocal",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import arrow
|
import arrow
|
||||||
import calendar
|
import calendar
|
||||||
from AllConfigs.main import MainConfig as Config
|
|
||||||
|
from ApiLayers.AllConfigs.main import MainConfig as Config
|
||||||
|
|
||||||
|
|
||||||
class DateTimeLocal:
|
class DateTimeLocal:
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import uuid
|
||||||
import secrets
|
import secrets
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from AllConfigs.Token.config import Auth
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
|
|
||||||
|
|
||||||
class PasswordModule:
|
class PasswordModule:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
from fastapi import APIRouter
|
||||||
|
import uuid
|
||||||
|
from Events.Engine.abstract_class import CategoryCluster, MethodToEvent
|
||||||
|
|
||||||
|
|
||||||
|
class CreateRouterFromCluster:
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.prefix = kwargs.get("prefix")
|
||||||
|
self.tags = kwargs.get("tags")
|
||||||
|
self.router = APIRouter(prefix=self.prefix, tags=self.tags)
|
||||||
|
|
||||||
|
|
||||||
|
class CreateEndpointFromCluster:
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.router: CategoryCluster = kwargs.get("router")
|
||||||
|
self.method_endpoint: MethodToEvent = kwargs.get("method_endpoint")
|
||||||
|
self.unique_id = str(uuid.uuid4())[:8] # Use first 8 chars of UUID for brevity
|
||||||
|
self.attach_router()
|
||||||
|
|
||||||
|
def attach_router(self):
|
||||||
|
method = getattr(self.router, self.method_endpoint.METHOD.lower())
|
||||||
|
|
||||||
|
# Create a unique operation ID based on the endpoint path, method, and a unique identifier
|
||||||
|
base_path = self.method_endpoint.URL.strip('/').replace('/', '_').replace('-', '_')
|
||||||
|
operation_id = f"{base_path}_{self.method_endpoint.METHOD.lower()}_{self.unique_id}"
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
"path": self.method_endpoint.URL,
|
||||||
|
"summary": self.method_endpoint.SUMMARY,
|
||||||
|
"description": self.method_endpoint.DESCRIPTION,
|
||||||
|
"operation_id": operation_id
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasattr(self.method_endpoint, 'RESPONSE_MODEL') and self.method_endpoint.RESPONSE_MODEL is not None:
|
||||||
|
kwargs["response_model"] = self.method_endpoint.RESPONSE_MODEL
|
||||||
|
|
||||||
|
method(**kwargs)(self.method_endpoint.endpoint_callable)
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
from Services.Redis import RedisActions, AccessToken
|
||||||
|
from Services.Redis.Models.cluster import RedisList
|
||||||
|
|
||||||
|
redis_list = RedisList(redis_key="test")
|
||||||
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
from typing import Any, ClassVar, Dict
|
from typing import Any, ClassVar, Dict
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import or_
|
||||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
|
||||||
from Schemas import Users
|
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
|
||||||
from ErrorHandlers import HTTPExceptionApi
|
from ApiLayers.ErrorHandlers import HTTPExceptionApi
|
||||||
from ApiValidations.Request.authentication import Login
|
from ApiLayers.ApiValidations.Request.authentication import Login
|
||||||
from ApiLibrary.token.password_module import PasswordModule
|
from ApiLayers.ApiLibrary.token.password_module import PasswordModule
|
||||||
from ApiServices.Token.token_handler import TokenService
|
from ApiLayers.ApiServices.Token.token_handler import TokenService
|
||||||
|
from ApiLayers.Schemas import Users
|
||||||
|
|
||||||
|
|
||||||
class UserLoginModule:
|
class UserLoginModule:
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,20 @@
|
||||||
|
|
||||||
from typing import List, Union, TypeVar, Dict, Any, Optional, TYPE_CHECKING
|
from typing import List, Union, TypeVar, Dict, Any, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from AllConfigs.Token.config import Auth
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
|
||||||
from ApiLibrary.date_time_actions.date_functions import DateTimeLocal
|
from ApiLayers.ApiLibrary.date_time_actions.date_functions import DateTimeLocal
|
||||||
from ApiLibrary.token.password_module import PasswordModule
|
from ApiLayers.ApiLibrary.token.password_module import PasswordModule
|
||||||
from ErrorHandlers import HTTPExceptionApi
|
from ApiLayers.ErrorHandlers import HTTPExceptionApi
|
||||||
from Schemas.identity.identity import UsersTokens, People
|
from ApiLayers.Schemas.identity.identity import UsersTokens, People
|
||||||
from Services.Redis import RedisActions, AccessToken
|
from ApiLayers.ApiValidations.Custom.token_objects import (
|
||||||
from ApiValidations.Custom.token_objects import (
|
|
||||||
EmployeeTokenObject,
|
EmployeeTokenObject,
|
||||||
OccupantTokenObject,
|
OccupantTokenObject,
|
||||||
UserType,
|
UserType,
|
||||||
CompanyToken,
|
CompanyToken,
|
||||||
OccupantToken,
|
OccupantToken,
|
||||||
)
|
)
|
||||||
from Schemas import (
|
from ApiLayers.Schemas import (
|
||||||
Users,
|
Users,
|
||||||
BuildLivingSpace,
|
BuildLivingSpace,
|
||||||
BuildParts,
|
BuildParts,
|
||||||
|
|
@ -30,6 +29,8 @@ from Schemas import (
|
||||||
OccupantTypes,
|
OccupantTypes,
|
||||||
)
|
)
|
||||||
from Services.Redis.Models.response import RedisResponse
|
from Services.Redis.Models.response import RedisResponse
|
||||||
|
from Services.Redis import RedisActions, AccessToken
|
||||||
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ApiServices.Token.token_handler import TokenService
|
from ApiLayers.ApiServices.Token.token_handler import TokenService
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"TokenService",
|
"TokenService",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from ApiValidations.Request import PydanticBaseModel, ListOptions
|
from ApiLayers.ApiValidations.Request import PydanticBaseModel, ListOptions
|
||||||
from ApiValidations.handler import BaseModelRegular
|
from ApiLayers.ApiValidations.handler import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class PostCodeValidation:
|
class PostCodeValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class SingleEnumClassKeyValidation:
|
class SingleEnumClassKeyValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class BuildAreaValidation:
|
class BuildAreaValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.handler import BaseModelRegular
|
from ApiLayers.ApiValidations.handler import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class ListOptions(BaseModelRegular):
|
class ListOptions(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
# from api_validations.validations_request import (
|
# from api_validations.validations_request import (
|
||||||
# PydanticBaseModel,
|
# PydanticBaseModel,
|
||||||
# PydanticBaseModelValidation,
|
# PydanticBaseModelValidation,
|
||||||
# )
|
# )
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertBuildLivingSpace(BaseModelRegular):
|
class InsertBuildLivingSpace(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertBuildTypes(BaseModelRegular):
|
class InsertBuildTypes(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertBuild(BaseModelRegular):
|
class InsertBuild(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertCompany(BaseModelRegular):
|
class InsertCompany(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class ListOptionsValidation:
|
class ListOptionsValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel, ListOptions
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel, ListOptions
|
||||||
|
|
||||||
|
|
||||||
class DecisionBookDecisionBookInvitations(BaseModelRegular):
|
class DecisionBookDecisionBookInvitations(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import (
|
from ApiLayers.ApiValidations.Request import PydanticBaseModel
|
||||||
PydanticBaseModel,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DepartmentsPydantic(PydanticBaseModel):
|
class DepartmentsPydantic(PydanticBaseModel):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class BindEmployees2People(PydanticBaseModel):
|
class BindEmployees2People(PydanticBaseModel):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class RegisterEvents2EmployeeValidation:
|
class RegisterEvents2EmployeeValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class RegisterModules2OccupantValidation:
|
class RegisterModules2OccupantValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertPerson(BaseModelRegular):
|
class InsertPerson(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertBuildDecisionBookProjectItems(BaseModelRegular):
|
class InsertBuildDecisionBookProjectItems(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class CheckEndpointAccess(BaseModelRegular):
|
class CheckEndpointAccess(BaseModelRegular):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from ApiValidations.Request import BaseModelRegular
|
from ApiLayers.ApiValidations.Request import BaseModelRegular
|
||||||
|
|
||||||
|
|
||||||
class RegisterServices2OccupantValidation:
|
class RegisterServices2OccupantValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import BaseModelRegular, PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertStaffValidation:
|
class InsertStaffValidation:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from ApiValidations.Request import PydanticBaseModel
|
from ApiLayers.ApiValidations.Request import PydanticBaseModel
|
||||||
|
|
||||||
|
|
||||||
class InsertUsersValidation:
|
class InsertUsersValidation:
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from typing import Any, Optional
|
||||||
from fastapi import status
|
from fastapi import status
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
|
||||||
class BaseEndpointResponse:
|
class BaseEndpointResponse:
|
||||||
|
|
||||||
def __init__(self, code: str, lang: str):
|
def __init__(self, code: str, lang: str):
|
||||||
|
|
@ -24,8 +25,8 @@ class EndpointSuccessResponse(BaseEndpointResponse):
|
||||||
completed=True,
|
completed=True,
|
||||||
message=self.retrieve_message(),
|
message=self.retrieve_message(),
|
||||||
lang=self.lang,
|
lang=self.lang,
|
||||||
data=data
|
data=data,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,15 +40,14 @@ class EndpointCreatedResponse(BaseEndpointResponse):
|
||||||
completed=True,
|
completed=True,
|
||||||
message=self.retrieve_message(),
|
message=self.retrieve_message(),
|
||||||
lang=self.lang,
|
lang=self.lang,
|
||||||
data=data
|
data=data,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# 3. 202 Accepted
|
# 3. 202 Accepted
|
||||||
class EndpointAcceptedResponse(BaseEndpointResponse):
|
class EndpointAcceptedResponse(BaseEndpointResponse):
|
||||||
|
|
||||||
|
|
||||||
def as_dict(self, data: Optional[Dict[str, Any]] = None):
|
def as_dict(self, data: Optional[Dict[str, Any]] = None):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_202_ACCEPTED,
|
status_code=status.HTTP_202_ACCEPTED,
|
||||||
|
|
@ -55,8 +55,8 @@ class EndpointAcceptedResponse(BaseEndpointResponse):
|
||||||
completed=True,
|
completed=True,
|
||||||
message=self.retrieve_message(),
|
message=self.retrieve_message(),
|
||||||
lang=self.lang,
|
lang=self.lang,
|
||||||
data=data
|
data=data,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -70,8 +70,8 @@ class EndpointBadRequestResponse(BaseEndpointResponse):
|
||||||
completed=False,
|
completed=False,
|
||||||
message=self.retrieve_message(),
|
message=self.retrieve_message(),
|
||||||
lang=self.lang,
|
lang=self.lang,
|
||||||
data=data
|
data=data,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -82,10 +82,8 @@ class EndpointUnauthorizedResponse(BaseEndpointResponse):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -96,10 +94,8 @@ class EndpointNotFoundResponse(BaseEndpointResponse):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -110,10 +106,8 @@ class EndpointForbiddenResponse(BaseEndpointResponse):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -124,12 +118,11 @@ class EndpointConflictResponse(BaseEndpointResponse):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_409_CONFLICT,
|
status_code=status.HTTP_409_CONFLICT,
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# 7. 429 Too Many Requests
|
# 7. 429 Too Many Requests
|
||||||
class EndpointTooManyRequestsResponse(BaseEndpointResponse):
|
class EndpointTooManyRequestsResponse(BaseEndpointResponse):
|
||||||
|
|
||||||
|
|
@ -141,10 +134,8 @@ class EndpointTooManyRequestsResponse(BaseEndpointResponse):
|
||||||
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
|
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
|
||||||
headers={"Retry-After": str(self.retry_after)},
|
headers={"Retry-After": str(self.retry_after)},
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -155,10 +146,8 @@ class EndpointInternalErrorResponse(BaseEndpointResponse):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -168,8 +157,6 @@ class EndpointErrorResponse(BaseEndpointResponse):
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=status.HTTP_304_NOT_MODIFIED,
|
status_code=status.HTTP_304_NOT_MODIFIED,
|
||||||
content=dict(
|
content=dict(
|
||||||
completed=False,
|
completed=False, message=self.retrieve_message(), lang=self.lang
|
||||||
message=self.retrieve_message(),
|
),
|
||||||
lang=self.lang
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
from typing import Any, Dict, Union, Awaitable
|
from typing import Any, Union, Awaitable
|
||||||
from fastapi import Request, WebSocket
|
from fastapi import Request, WebSocket
|
||||||
from fastapi.responses import Response
|
from fastapi.responses import Response
|
||||||
|
|
||||||
from LanguageModels.Errors.merge_all_error_languages import MergedErrorLanguageModels
|
from ApiLayers.LanguageModels.Errors.merge_all_error_languages import (
|
||||||
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
MergedErrorLanguageModels,
|
||||||
from ErrorHandlers.bases import BaseErrorModelClass
|
)
|
||||||
|
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
|
from ApiLayers.ErrorHandlers.bases import BaseErrorModelClass
|
||||||
|
|
||||||
|
|
||||||
class HTTPExceptionApiHandler:
|
class HTTPExceptionApiHandler:
|
||||||
|
|
@ -23,7 +25,7 @@ class HTTPExceptionApiHandler:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def retrieve_error_message(exc: HTTPExceptionApi, error_languages) -> str:
|
def retrieve_error_message(exc: HTTPExceptionApi, error_languages) -> str:
|
||||||
from ErrorHandlers import DEFAULT_ERROR
|
from ApiLayers.ErrorHandlers import DEFAULT_ERROR
|
||||||
|
|
||||||
return error_languages.get(str(exc.error_code).upper(), DEFAULT_ERROR)
|
return error_languages.get(str(exc.error_code).upper(), DEFAULT_ERROR)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
from ErrorHandlers.ErrorHandlers.api_exc_handler import (
|
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import (
|
||||||
HTTPExceptionApiHandler,
|
HTTPExceptionApiHandler,
|
||||||
)
|
)
|
||||||
from ErrorHandlers.Exceptions.api_exc import (
|
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
HTTPExceptionApi,
|
|
||||||
)
|
|
||||||
|
|
||||||
DEFAULT_ERROR = "UNKNOWN_ERROR"
|
DEFAULT_ERROR = "UNKNOWN_ERROR"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from ErrorHandlers.base import BaseError
|
from ApiLayers.ErrorHandlers.base import BaseError
|
||||||
from ErrorHandlers.statuses import Statuses
|
from ApiLayers.ErrorHandlers.statuses import Statuses
|
||||||
|
|
||||||
|
|
||||||
class BaseErrorModelClass:
|
class BaseErrorModelClass:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
AccountBooksLanguageModel = dict(
|
AccountBooksLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
BuildIbansLanguageModel = dict(
|
BuildIbansLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
DecisionBookBudgetBooksLanguageModel = dict(
|
DecisionBookBudgetBooksLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
BuildTypesLanguageModel = dict(
|
BuildTypesLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
BuildDecisionBookLanguageModel = dict(
|
BuildDecisionBookLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
RelationshipDutyCompanyLanguageModel = dict(
|
RelationshipDutyCompanyLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
DepartmentsLanguageModel = dict(
|
DepartmentsLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
StaffLanguageModel = dict(
|
StaffLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
|
|
||||||
EventsLanguageModel = dict(
|
EventsLanguageModel = dict(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
UsersTokensLanguageModel = dict(
|
UsersTokensLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
from ApiLayers.LanguageModels.Database.Mixins.crud_mixin import CrudCollectionLanguageModel
|
||||||
|
|
||||||
EndpointRestrictionLanguageModel = dict(
|
EndpointRestrictionLanguageModel = dict(
|
||||||
tr={
|
tr={
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from LanguageModels.Errors.base_languages import BaseErrorLanguageModels
|
from ApiLayers.LanguageModels.Errors.base_languages import BaseErrorLanguageModels
|
||||||
|
|
||||||
|
|
||||||
class MergedErrorLanguageModels:
|
class MergedErrorLanguageModels:
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,19 @@ This module provides authentication decorator for protecting endpoints
|
||||||
and a middleware for request timing measurements.
|
and a middleware for request timing measurements.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
from time import perf_counter
|
from time import perf_counter
|
||||||
from typing import Callable, Optional, Dict, Any, Tuple, Union
|
from typing import Callable
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from fastapi import Request, Response
|
from fastapi import Request, Response
|
||||||
from starlette.middleware.base import BaseHTTPMiddleware
|
from starlette.middleware.base import BaseHTTPMiddleware
|
||||||
|
|
||||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
|
||||||
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApi
|
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApi
|
||||||
from AllConfigs.Token.config import Auth
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
import inspect
|
from ApiLayers.ApiServices.Token.token_handler import TokenService
|
||||||
|
|
||||||
|
|
||||||
class MiddlewareModule:
|
class MiddlewareModule:
|
||||||
|
|
@ -39,7 +41,6 @@ class MiddlewareModule:
|
||||||
Raises:
|
Raises:
|
||||||
HTTPExceptionApi: If token is missing, invalid, or user not found
|
HTTPExceptionApi: If token is missing, invalid, or user not found
|
||||||
"""
|
"""
|
||||||
from ApiServices.Token.token_handler import TokenService
|
|
||||||
|
|
||||||
# Get token and validate - will raise HTTPExceptionApi if invalid
|
# Get token and validate - will raise HTTPExceptionApi if invalid
|
||||||
redis_token = TokenService.get_access_token_from_request(request=request)
|
redis_token = TokenService.get_access_token_from_request(request=request)
|
||||||
|
|
@ -86,14 +87,22 @@ class MiddlewareModule:
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
async def wrapper(request: Request, *args, **kwargs):
|
async def wrapper(request: Request, *args, **kwargs):
|
||||||
# Get and validate token context from request
|
# Get and validate token context from request
|
||||||
# Create auth context and Attach auth context to both wrapper and original function
|
auth_context = {
|
||||||
func.auth = cls.get_user_from_request(request)
|
"is_employee": False,
|
||||||
wrapper.auth = func.auth
|
"is_occupant": False,
|
||||||
|
"context": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set auth context on the wrapper function itself
|
||||||
|
setattr(wrapper, 'auth', auth_context)
|
||||||
|
|
||||||
# Call the original endpoint function
|
# Call the original endpoint function
|
||||||
if inspect.iscoroutinefunction(func):
|
if inspect.iscoroutinefunction(func):
|
||||||
return await func(request, *args, **kwargs)
|
result = await func(request, *args, **kwargs)
|
||||||
return func(request, *args, **kwargs)
|
else:
|
||||||
|
result = func(request, *args, **kwargs)
|
||||||
|
|
||||||
|
return result
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9,13 +9,12 @@ from typing import Callable, Dict, Any, Optional, Union
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from ApiLibrary.common.line_number import get_line_number_for_error
|
from ApiLayers.ApiLibrary.common.line_number import get_line_number_for_error
|
||||||
from ApiServices.Token.token_handler import TokenService
|
from ApiLayers.ApiServices.Token.token_handler import TokenService
|
||||||
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
from Schemas.rules.rules import EndpointRestriction
|
from ApiLayers.Schemas import Events, EndpointRestriction
|
||||||
|
|
||||||
from .auth_middleware import MiddlewareModule
|
from .auth_middleware import MiddlewareModule
|
||||||
from Schemas import Events
|
|
||||||
|
|
||||||
|
|
||||||
class EventFunctions:
|
class EventFunctions:
|
||||||
|
|
@ -24,88 +23,7 @@ class EventFunctions:
|
||||||
self.endpoint = endpoint
|
self.endpoint = endpoint
|
||||||
self.request = request
|
self.request = request
|
||||||
|
|
||||||
def match_endpoint_with_accesiable_event(self) -> Optional[Dict[str, Any]]:
|
|
||||||
"""
|
|
||||||
Match an endpoint with accessible events.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
endpoint: The endpoint to match
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict containing the endpoint registration data
|
|
||||||
None if endpoint is not found in database
|
|
||||||
"""
|
|
||||||
access_token = TokenService.get_access_token_from_request(self.request)
|
|
||||||
token_context = TokenService.get_object_via_access_key(
|
|
||||||
access_token=access_token
|
|
||||||
)
|
|
||||||
if token_context.is_employee:
|
|
||||||
reachable_event_codes: list[str] = (
|
|
||||||
token_context.selected_company.reachable_event_codes
|
|
||||||
)
|
|
||||||
elif token_context.is_occupant:
|
|
||||||
reachable_event_codes: list[str] = (
|
|
||||||
token_context.selected_occupant.reachable_event_codes
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise HTTPExceptionApi(
|
|
||||||
error_code="",
|
|
||||||
lang="en",
|
|
||||||
loc=get_line_number_for_error(),
|
|
||||||
sys_msg="Token not found",
|
|
||||||
)
|
|
||||||
|
|
||||||
if not access_token:
|
|
||||||
raise HTTPExceptionApi(
|
|
||||||
error_code="",
|
|
||||||
lang="en",
|
|
||||||
loc=get_line_number_for_error(),
|
|
||||||
sys_msg="Token not found",
|
|
||||||
)
|
|
||||||
|
|
||||||
db = EndpointRestriction.new_session()
|
|
||||||
restriction = EndpointRestriction.filter_one(
|
|
||||||
EndpointRestriction.endpoint_name == self.endpoint,
|
|
||||||
db=db,
|
|
||||||
).data
|
|
||||||
if not restriction:
|
|
||||||
raise HTTPExceptionApi(
|
|
||||||
error_code="",
|
|
||||||
lang="en",
|
|
||||||
loc=get_line_number_for_error(),
|
|
||||||
sys_msg="Function code not found",
|
|
||||||
)
|
|
||||||
|
|
||||||
event_related = Events.filter_all(
|
|
||||||
Events.endpoint_id == restriction.id,
|
|
||||||
db=db,
|
|
||||||
).data
|
|
||||||
if not event_related:
|
|
||||||
raise HTTPExceptionApi(
|
|
||||||
error_code="",
|
|
||||||
lang="en",
|
|
||||||
loc=get_line_number_for_error(),
|
|
||||||
sys_msg="No event is registered for this user.",
|
|
||||||
)
|
|
||||||
an_event = event_related[0]
|
|
||||||
event_related_codes: list[str] = [
|
|
||||||
event.function_code for event in event_related
|
|
||||||
]
|
|
||||||
intersected_code: set = set(reachable_event_codes).intersection(
|
|
||||||
set(event_related_codes)
|
|
||||||
)
|
|
||||||
if not len(list(intersected_code)) == 1:
|
|
||||||
raise HTTPExceptionApi(
|
|
||||||
error_code="",
|
|
||||||
lang="en",
|
|
||||||
loc=get_line_number_for_error(),
|
|
||||||
sys_msg="No event is registered for this user.",
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
"endpoint_url": self.endpoint,
|
|
||||||
"reachable_event_code": list(intersected_code)[0],
|
|
||||||
"class": an_event.function_class,
|
|
||||||
}
|
|
||||||
|
|
||||||
def retrieve_function_dict(self) -> Optional[Dict[str, Any]]:
|
def retrieve_function_dict(self) -> Optional[Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -201,9 +119,91 @@ class TokenEventMiddleware:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def event_required(
|
def match_endpoint_with_accessible_event(request_from_scope, endpoint_from_scope) -> Optional[Dict[str, Any]]:
|
||||||
func: Callable[..., Dict[str, Any]]
|
"""
|
||||||
) -> Callable[..., Dict[str, Any]]:
|
Match an endpoint with accessible events.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request_from_scope: The endpoint to match
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict containing the endpoint registration data
|
||||||
|
None if endpoint is not found in database
|
||||||
|
"""
|
||||||
|
access_token = TokenService.get_access_token_from_request(request_from_scope)
|
||||||
|
token_context = TokenService.get_object_via_access_key(
|
||||||
|
access_token=access_token
|
||||||
|
)
|
||||||
|
if token_context.is_employee:
|
||||||
|
reachable_event_codes: list[str] = (
|
||||||
|
token_context.selected_company.reachable_event_codes
|
||||||
|
)
|
||||||
|
elif token_context.is_occupant:
|
||||||
|
reachable_event_codes: list[str] = (
|
||||||
|
token_context.selected_occupant.reachable_event_codes
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise HTTPExceptionApi(
|
||||||
|
error_code="",
|
||||||
|
lang="en",
|
||||||
|
loc=get_line_number_for_error(),
|
||||||
|
sys_msg="Token not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not access_token:
|
||||||
|
raise HTTPExceptionApi(
|
||||||
|
error_code="",
|
||||||
|
lang="en",
|
||||||
|
loc=get_line_number_for_error(),
|
||||||
|
sys_msg="Token not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
db = EndpointRestriction.new_session()
|
||||||
|
restriction = EndpointRestriction.filter_one(
|
||||||
|
EndpointRestriction.endpoint_name == endpoint_from_scope,
|
||||||
|
db=db,
|
||||||
|
).data
|
||||||
|
if not restriction:
|
||||||
|
raise HTTPExceptionApi(
|
||||||
|
error_code="",
|
||||||
|
lang="en",
|
||||||
|
loc=get_line_number_for_error(),
|
||||||
|
sys_msg="Function code not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
event_related = Events.filter_all(
|
||||||
|
Events.endpoint_id == restriction.id,
|
||||||
|
db=db,
|
||||||
|
).data
|
||||||
|
if not event_related:
|
||||||
|
raise HTTPExceptionApi(
|
||||||
|
error_code="",
|
||||||
|
lang="en",
|
||||||
|
loc=get_line_number_for_error(),
|
||||||
|
sys_msg="No event is registered for this user.",
|
||||||
|
)
|
||||||
|
an_event = event_related[0]
|
||||||
|
event_related_codes: list[str] = [
|
||||||
|
event.function_code for event in event_related
|
||||||
|
]
|
||||||
|
intersected_code: set = set(reachable_event_codes).intersection(
|
||||||
|
set(event_related_codes)
|
||||||
|
)
|
||||||
|
if not len(list(intersected_code)) == 1:
|
||||||
|
raise HTTPExceptionApi(
|
||||||
|
error_code="",
|
||||||
|
lang="en",
|
||||||
|
loc=get_line_number_for_error(),
|
||||||
|
sys_msg="No event is registered for this user.",
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"endpoint_url": endpoint_from_scope,
|
||||||
|
"reachable_event_code": list(intersected_code)[0],
|
||||||
|
"class": an_event.function_class,
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def event_required(cls, func: Callable) -> Callable:
|
||||||
"""
|
"""
|
||||||
Decorator for endpoints with token and event requirements.
|
Decorator for endpoints with token and event requirements.
|
||||||
This decorator:
|
This decorator:
|
||||||
|
|
@ -216,31 +216,36 @@ class TokenEventMiddleware:
|
||||||
Returns:
|
Returns:
|
||||||
Callable: The wrapped function with both auth and event handling
|
Callable: The wrapped function with both auth and event handling
|
||||||
"""
|
"""
|
||||||
# # First apply authentication
|
# First apply authentication
|
||||||
# authenticated_func = MiddlewareModule.auth_required(func)
|
authenticated_func = MiddlewareModule.auth_required(func)
|
||||||
authenticated_func = func
|
|
||||||
|
|
||||||
@wraps(authenticated_func)
|
@wraps(authenticated_func)
|
||||||
async def wrapper(request: Request, *args, **kwargs) -> Dict[str, Any]:
|
async def wrapper(request: Request, *args, **kwargs) -> Dict[str, Any]:
|
||||||
|
# Get the endpoint URL for matching with events
|
||||||
|
endpoint_url = str(request.url.path)
|
||||||
|
|
||||||
# Get function code from the function's metadata
|
# Set func_code first
|
||||||
endpoint_url = getattr(authenticated_func, "url_of_endpoint", {})
|
func_code = "8aytr-"
|
||||||
if not endpoint_url:
|
setattr(wrapper, 'func_code', func_code)
|
||||||
raise HTTPExceptionApi(
|
|
||||||
error_code="",
|
|
||||||
lang="en",
|
|
||||||
loc=get_line_number_for_error(),
|
|
||||||
sys_msg="Function code not found",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Make handler available to all functions in the chain
|
# Get auth context from the authenticated function's wrapper
|
||||||
func.func_code = EventFunctions(
|
auth_context = getattr(authenticated_func, 'auth', None)
|
||||||
endpoint_url, request
|
print('auth_context', auth_context)
|
||||||
).match_endpoint_with_accesiable_event()
|
if auth_context is not None:
|
||||||
# Call the authenticated function
|
setattr(wrapper, 'auth', auth_context)
|
||||||
|
|
||||||
|
# Execute the authenticated function and get its result
|
||||||
if inspect.iscoroutinefunction(authenticated_func):
|
if inspect.iscoroutinefunction(authenticated_func):
|
||||||
return await authenticated_func(request, *args, **kwargs)
|
result = await authenticated_func(request, *args, **kwargs)
|
||||||
return authenticated_func(request, *args, **kwargs)
|
else:
|
||||||
|
result = authenticated_func(request, *args, **kwargs)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
# Copy any existing attributes from the authenticated function
|
||||||
|
for attr in dir(authenticated_func):
|
||||||
|
if not attr.startswith('__'):
|
||||||
|
setattr(wrapper, attr, getattr(authenticated_func, attr))
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
@ -261,8 +266,8 @@ class TokenEventMiddleware:
|
||||||
Callable: The wrapped function with both auth and event handling
|
Callable: The wrapped function with both auth and event handling
|
||||||
"""
|
"""
|
||||||
# First apply authentication
|
# First apply authentication
|
||||||
authenticated_func = MiddlewareModule.auth_required(func)
|
# authenticated_func = MiddlewareModule.auth_required(func)
|
||||||
|
authenticated_func = func
|
||||||
@wraps(authenticated_func)
|
@wraps(authenticated_func)
|
||||||
async def wrapper(
|
async def wrapper(
|
||||||
request: Request, *args: Any, **kwargs: Any
|
request: Request, *args: Any, **kwargs: Any
|
||||||
|
|
@ -278,9 +283,9 @@ class TokenEventMiddleware:
|
||||||
loc=get_line_number_for_error(),
|
loc=get_line_number_for_error(),
|
||||||
sys_msg="Endpoint not found",
|
sys_msg="Endpoint not found",
|
||||||
)
|
)
|
||||||
wrapper.validation_code = EventFunctions(
|
func.func_code = cls.match_endpoint_with_accessible_event(
|
||||||
endpoint_asked, request
|
endpoint_url, request
|
||||||
).retrieve_function_dict()
|
)
|
||||||
if inspect.iscoroutinefunction(authenticated_func):
|
if inspect.iscoroutinefunction(authenticated_func):
|
||||||
result = await authenticated_func(request, *args, **kwargs)
|
result = await authenticated_func(request, *args, **kwargs)
|
||||||
else:
|
else:
|
||||||
|
|
@ -289,9 +294,14 @@ class TokenEventMiddleware:
|
||||||
wrapper.auth = function_auth
|
wrapper.auth = function_auth
|
||||||
func.auth = function_auth
|
func.auth = function_auth
|
||||||
authenticated_func.auth = function_auth
|
authenticated_func.auth = function_auth
|
||||||
# If result is a coroutine, await it
|
if inspect.iscoroutinefunction(authenticated_func):
|
||||||
if inspect.iscoroutine(result):
|
result = await authenticated_func(request, *args, **kwargs)
|
||||||
result = await result
|
else:
|
||||||
|
result = authenticated_func(request, *args, **kwargs)
|
||||||
|
if inspect.iscoroutinefunction(func):
|
||||||
|
result = await func(request, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
result = func(request, *args, **kwargs)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
@ -11,7 +11,7 @@ from sqlalchemy import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
from LanguageModels.Database.account.account import (
|
from ApiLayers.LanguageModels.Database.account.account import (
|
||||||
AccountBooksLanguageModel,
|
AccountBooksLanguageModel,
|
||||||
AccountCodesLanguageModel,
|
AccountCodesLanguageModel,
|
||||||
AccountRecordsLanguageModel,
|
AccountRecordsLanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,17 @@ from sqlalchemy import (
|
||||||
or_,
|
or_,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ApiLibrary import system_arrow, SelectActionWithEmployee
|
from ApiLayers.ApiLibrary import system_arrow, SelectActionWithEmployee
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
from ApiValidations.Request import (
|
from ApiLayers.ApiValidations.Request import (
|
||||||
InsertBuild,
|
InsertBuild,
|
||||||
InsertBuildParts,
|
InsertBuildParts,
|
||||||
InsertBuildLivingSpace,
|
InsertBuildLivingSpace,
|
||||||
UpdateBuild,
|
UpdateBuild,
|
||||||
)
|
)
|
||||||
|
|
||||||
from ApiValidations.Custom.token_objects import EmployeeTokenObject, OccupantTokenObject
|
from ApiLayers.ApiValidations.Custom.token_objects import EmployeeTokenObject, OccupantTokenObject
|
||||||
from LanguageModels.Database.building.build import (
|
from ApiLayers.LanguageModels.Database.building.build import (
|
||||||
BuildTypesLanguageModel,
|
BuildTypesLanguageModel,
|
||||||
Part2EmployeeLanguageModel,
|
Part2EmployeeLanguageModel,
|
||||||
BuildPartsLanguageModel,
|
BuildPartsLanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from decimal import Decimal
|
||||||
from typing import List
|
from typing import List
|
||||||
from fastapi import HTTPException, status
|
from fastapi import HTTPException, status
|
||||||
|
|
||||||
from ApiLibrary.date_time_actions.date_functions import system_arrow
|
from ApiLayers.ApiLibrary.date_time_actions.date_functions import system_arrow
|
||||||
|
|
||||||
from sqlalchemy import (
|
from sqlalchemy import (
|
||||||
String,
|
String,
|
||||||
|
|
@ -19,14 +19,14 @@ from sqlalchemy import (
|
||||||
)
|
)
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
|
|
||||||
from ApiValidations.Request import (
|
from ApiLayers.ApiValidations.Request import (
|
||||||
InsertDecisionBook,
|
InsertDecisionBook,
|
||||||
InsertBuildDecisionBookItems,
|
InsertBuildDecisionBookItems,
|
||||||
InsertBuildDecisionBookItemDebits,
|
InsertBuildDecisionBookItemDebits,
|
||||||
InsertBuildDecisionBookProjects,
|
InsertBuildDecisionBookProjects,
|
||||||
)
|
)
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
from LanguageModels.Database.building.decision_book import (
|
from ApiLayers.LanguageModels.Database.building.decision_book import (
|
||||||
BuildDecisionBookLanguageModel,
|
BuildDecisionBookLanguageModel,
|
||||||
BuildDecisionBookInvitationsLanguageModel,
|
BuildDecisionBookInvitationsLanguageModel,
|
||||||
BuildDecisionBookPersonLanguageModel,
|
BuildDecisionBookPersonLanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ from sqlalchemy import (
|
||||||
)
|
)
|
||||||
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
||||||
|
|
||||||
from ApiLibrary.extensions.select import SelectAction
|
from ApiLayers.ApiLibrary.extensions.select import SelectAction
|
||||||
from ApiValidations.Custom.token_objects import EmployeeTokenObject
|
from ApiLayers.ApiValidations.Custom.token_objects import EmployeeTokenObject
|
||||||
from ApiValidations.Request import (
|
from ApiLayers.ApiValidations.Request import (
|
||||||
InsertCompany,
|
InsertCompany,
|
||||||
UpdateCompany,
|
UpdateCompany,
|
||||||
MatchCompany2Company,
|
MatchCompany2Company,
|
||||||
)
|
)
|
||||||
from LanguageModels.Database.company.company import (
|
from ApiLayers.LanguageModels.Database.company.company import (
|
||||||
RelationshipDutyCompanyLanguageModel,
|
RelationshipDutyCompanyLanguageModel,
|
||||||
CompaniesLanguageModel,
|
CompaniesLanguageModel,
|
||||||
# CompanyDutiesLanguageModel,
|
# CompanyDutiesLanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from sqlalchemy import (
|
||||||
)
|
)
|
||||||
from sqlalchemy.orm import mapped_column, Mapped
|
from sqlalchemy.orm import mapped_column, Mapped
|
||||||
|
|
||||||
from LanguageModels.Database.company.employee import (
|
from ApiLayers.LanguageModels.Database.company.employee import (
|
||||||
StaffLanguageModel,
|
StaffLanguageModel,
|
||||||
EmployeesLanguageModel,
|
EmployeesLanguageModel,
|
||||||
EmployeeHistoryLanguageModel,
|
EmployeeHistoryLanguageModel,
|
||||||
|
|
@ -14,7 +14,7 @@ from LanguageModels.Database.company.employee import (
|
||||||
)
|
)
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
|
|
||||||
from ApiValidations.Request import InsertCompanyEmployees
|
from ApiLayers.ApiValidations.Request import InsertCompanyEmployees
|
||||||
|
|
||||||
|
|
||||||
class Staff(CrudCollection):
|
class Staff(CrudCollection):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
from LanguageModels.Database.event.event import (
|
from ApiLayers.LanguageModels.Database.event.event import (
|
||||||
EventsLanguageModel,
|
EventsLanguageModel,
|
||||||
ModulesLanguageModel,
|
ModulesLanguageModel,
|
||||||
ServicesLanguageModel,
|
ServicesLanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -8,24 +8,23 @@ from sqlalchemy import (
|
||||||
ForeignKey,
|
ForeignKey,
|
||||||
Index,
|
Index,
|
||||||
TIMESTAMP,
|
TIMESTAMP,
|
||||||
func,
|
|
||||||
Text,
|
Text,
|
||||||
BigInteger,
|
BigInteger,
|
||||||
Numeric,
|
Numeric,
|
||||||
|
func,
|
||||||
or_,
|
or_,
|
||||||
)
|
)
|
||||||
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
from sqlalchemy.orm import mapped_column, relationship, Mapped
|
||||||
|
|
||||||
from ApiLibrary.date_time_actions.date_functions import system_arrow
|
from ApiLayers.ApiLibrary.date_time_actions.date_functions import system_arrow
|
||||||
from AllConfigs.Token.config import Auth, ApiStatic
|
from ApiLayers.ApiLibrary.extensions.select import SelectAction, SelectActionWithEmployee
|
||||||
from ApiLibrary.extensions.select import SelectAction, SelectActionWithEmployee
|
|
||||||
|
|
||||||
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
|
from config import ApiStatic
|
||||||
|
|
||||||
# from databases.extensions import SelectAction, SelectActionWithEmployee
|
from ApiLayers.ApiValidations.Request import InsertUsers, InsertPerson
|
||||||
# from databases.extensions.auth import UserLoginModule
|
from ApiLayers.LanguageModels.Database.identity.identity import (
|
||||||
from ApiValidations.Request import InsertUsers, InsertPerson
|
|
||||||
from LanguageModels.Database.identity.identity import (
|
|
||||||
UsersTokensLanguageModel,
|
UsersTokensLanguageModel,
|
||||||
UsersLanguageModel,
|
UsersLanguageModel,
|
||||||
PeopleLanguageModel,
|
PeopleLanguageModel,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from sqlalchemy import String
|
from sqlalchemy import String
|
||||||
from sqlalchemy.orm import mapped_column, Mapped
|
from sqlalchemy.orm import mapped_column, Mapped
|
||||||
|
|
||||||
from LanguageModels.Database.rules.rules import EndpointRestrictionLanguageModel
|
from ApiLayers.LanguageModels.Database.rules.rules import EndpointRestrictionLanguageModel
|
||||||
from Services.PostgresDb import CrudCollection
|
from Services.PostgresDb import CrudCollection
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,18 @@ RUN poetry config virtualenvs.create false \
|
||||||
&& rm -rf ~/.cache/pypoetry
|
&& rm -rf ~/.cache/pypoetry
|
||||||
|
|
||||||
# Copy application code
|
# Copy application code
|
||||||
COPY DockerApiServices/AllApiNeeds /app
|
COPY DockerApiServices/AuthServiceApi /app
|
||||||
|
|
||||||
# Copy application code
|
# Copy application code
|
||||||
COPY ApiLayers /app/ApiLayers
|
COPY ApiLayers /app/ApiLayers
|
||||||
|
COPY Services /app/Services
|
||||||
|
|
||||||
# Events
|
# Events
|
||||||
COPY Events/AllEvents/auth /app/Events/AllEvents/auth
|
# COPY Events/base_request_model.py /app/Events/base_request_model.py
|
||||||
|
COPY Events/Engine /app/Events/Engine
|
||||||
COPY Events/base_request_model.py /app/Events/base_request_model.py
|
COPY Events/base_request_model.py /app/Events/base_request_model.py
|
||||||
COPY Events/abstract_class.py /app/Events/abstract_class.py
|
COPY Events/AllEvents/authentication /app/Events/AllEvents/authentication
|
||||||
|
COPY DockerApiServices/AuthServiceApi/events_file.py /app/Events/AllEvents/events_file.py
|
||||||
|
|
||||||
# Set Python path to include app directory
|
# Set Python path to include app directory
|
||||||
ENV PYTHONPATH=/app \
|
ENV PYTHONPATH=/app \
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ This module initializes and configures the FastAPI application with:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
from prometheus_fastapi_instrumentator import Instrumentator
|
from prometheus_fastapi_instrumentator import Instrumentator
|
||||||
from app_handler import setup_middleware, get_uvicorn_config
|
from app_handler import setup_middleware
|
||||||
from create_file import create_app
|
from create_file import create_app
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
app = create_app() # Initialize FastAPI application
|
app = create_app() # Initialize FastAPI application
|
||||||
|
|
@ -21,5 +23,5 @@ setup_middleware(app) # Configure middleware and exception handlers
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
uvicorn_config = get_uvicorn_config() # Run the application with Uvicorn
|
# Run the application with Uvicorn
|
||||||
uvicorn.Server(uvicorn.Config(**uvicorn_config)).run()
|
uvicorn.Server(uvicorn.Config(**ApiConfig.as_dict())).run()
|
||||||
|
|
@ -7,13 +7,12 @@ This module contains all the handler functions for configuring and setting up th
|
||||||
- Uvicorn server configuration
|
- Uvicorn server configuration
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Dict, Any
|
from fastapi import FastAPI, Request, status
|
||||||
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi import FastAPI, Request, HTTPException, status
|
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
|
||||||
from middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
|
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
|
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
|
||||||
|
|
||||||
|
|
||||||
def setup_cors_middleware(app: FastAPI) -> None:
|
def setup_cors_middleware(app: FastAPI) -> None:
|
||||||
|
|
@ -56,7 +55,7 @@ def setup_exception_handlers(app: FastAPI) -> None:
|
||||||
Args:
|
Args:
|
||||||
app: FastAPI application instance
|
app: FastAPI application instance
|
||||||
"""
|
"""
|
||||||
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
|
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
|
||||||
|
|
||||||
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
|
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
|
||||||
app.add_exception_handler(
|
app.add_exception_handler(
|
||||||
|
|
@ -76,19 +75,3 @@ def setup_middleware(app: FastAPI) -> None:
|
||||||
app.add_middleware(RequestTimingMiddleware)
|
app.add_middleware(RequestTimingMiddleware)
|
||||||
app.add_middleware(LoggerTimingMiddleware)
|
app.add_middleware(LoggerTimingMiddleware)
|
||||||
setup_exception_handlers(app)
|
setup_exception_handlers(app)
|
||||||
|
|
||||||
|
|
||||||
def get_uvicorn_config() -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Get Uvicorn server configuration.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dict[str, Any]: Uvicorn configuration dictionary
|
|
||||||
"""
|
|
||||||
return {
|
|
||||||
"app": "app:app",
|
|
||||||
"host": "0.0.0.0",
|
|
||||||
"port": 41575,
|
|
||||||
"log_level": "info",
|
|
||||||
"reload": True,
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
class DefaultApiConfig:
|
||||||
|
app: str
|
||||||
|
host: str
|
||||||
|
port: int
|
||||||
|
log_level: str
|
||||||
|
reload: bool
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def as_dict(cls):
|
||||||
|
return {
|
||||||
|
"app": cls.app,
|
||||||
|
"host": cls.host,
|
||||||
|
"port": int(cls.port),
|
||||||
|
"log_level": cls.log_level,
|
||||||
|
"reload": bool(cls.reload),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ApiStatic:
|
||||||
|
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
|
||||||
|
FORGOT_LINK = "https://www.evyos.com.tr/password/create?tokenUrl="
|
||||||
|
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
|
||||||
|
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def forgot_link(cls, forgot_key):
|
||||||
|
return cls.FORGOT_LINK + forgot_key
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def blacklist_login(cls, record_id):
|
||||||
|
return cls.BLACKLIST_LINK + record_id
|
||||||
|
|
||||||
|
|
||||||
|
class HostConfig:
|
||||||
|
MAIN_HOST = "10.10.2.36" # http://10.10.2.36
|
||||||
|
EMAIL_HOST = "10.10.2.34" # http://10.10.2.34
|
||||||
|
|
||||||
|
|
||||||
|
class ApiConfig(DefaultApiConfig):
|
||||||
|
# Application Information
|
||||||
|
APP_NAME = "evyos-auth-api-gateway"
|
||||||
|
TITLE = "WAG API Auth Api Gateway"
|
||||||
|
DESCRIPTION = "This api is serves as web auth api gateway only to evyos web services."
|
||||||
|
APP_URL = "https://www.auth.eys.gen.tr"
|
||||||
|
|
||||||
|
# Server Configuration
|
||||||
|
app = "app:app"
|
||||||
|
host = "0.0.0.0"
|
||||||
|
port = 41575
|
||||||
|
log_level = "info"
|
||||||
|
reload = True
|
||||||
|
|
||||||
|
|
||||||
|
class MainConfig:
|
||||||
|
|
||||||
|
# Date and Time Configuration
|
||||||
|
DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss Z"
|
||||||
|
DATETIME_FORMAT_JS = "YYYY-MM-DD HH:mm:ss +0"
|
||||||
|
|
||||||
|
# Timezone Configuration
|
||||||
|
DEFAULT_TIMEZONE = "GMT+3" # Default timezone for the application
|
||||||
|
SYSTEM_TIMEZONE = "GMT+0" # System timezone (used for internal operations)
|
||||||
|
SUPPORTED_TIMEZONES = ["GMT+0", "GMT+3"] # List of supported timezones
|
||||||
|
|
||||||
|
|
||||||
|
class LanguageConfig:
|
||||||
|
|
||||||
|
SUPPORTED_LANGUAGES = ["en", "tr"]
|
||||||
|
DEFAULT_LANGUAGE = "tr"
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Factory Module
|
||||||
|
|
||||||
|
This module provides functionality to create and configure a FastAPI application with:
|
||||||
|
- Custom OpenAPI schema configuration
|
||||||
|
- Security scheme configuration for Bearer authentication
|
||||||
|
- Automatic router registration
|
||||||
|
- Response class configuration
|
||||||
|
- Security requirements for protected endpoints
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import JSONResponse, RedirectResponse
|
||||||
|
|
||||||
|
from config import ApiConfig
|
||||||
|
from create_routes import get_all_routers
|
||||||
|
|
||||||
|
|
||||||
|
def create_app() -> FastAPI:
|
||||||
|
"""
|
||||||
|
Create and configure a FastAPI application with dynamic route creation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
FastAPI: Configured FastAPI application instance
|
||||||
|
"""
|
||||||
|
|
||||||
|
from open_api_creator import create_openapi_schema
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title=ApiConfig.TITLE,
|
||||||
|
description=ApiConfig.DESCRIPTION,
|
||||||
|
default_response_class=JSONResponse,
|
||||||
|
) # Initialize FastAPI app
|
||||||
|
|
||||||
|
@app.get("/", include_in_schema=False, summary=str(ApiConfig.DESCRIPTION))
|
||||||
|
def home() -> RedirectResponse:
|
||||||
|
"""Redirect root path to API documentation."""
|
||||||
|
return RedirectResponse(url="/docs")
|
||||||
|
|
||||||
|
# Get all routers and protected routes using the dynamic route creation
|
||||||
|
prepare_routing = get_all_routers()
|
||||||
|
|
||||||
|
# Include all routers
|
||||||
|
for router in prepare_routing.routers:
|
||||||
|
app.include_router(router)
|
||||||
|
|
||||||
|
app.openapi = lambda app=app: create_openapi_schema(app)
|
||||||
|
return app
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
"""
|
||||||
|
Route configuration and factory module.
|
||||||
|
Handles dynamic route creation based on configurations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import Request
|
||||||
|
from Events.Engine.set_defaults.setClusters import PrepareRouting
|
||||||
|
|
||||||
|
|
||||||
|
async def health_check(request: Request):
|
||||||
|
"""Default health check endpoint."""
|
||||||
|
return {"status": "healthy", "message": "Service is running"}
|
||||||
|
|
||||||
|
|
||||||
|
async def ping_test(request: Request, service_name: str = "base-router"):
|
||||||
|
"""Default ping test endpoint."""
|
||||||
|
return {"ping": "pong", "service": service_name}
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_routers() -> PrepareRouting:
|
||||||
|
"""
|
||||||
|
Get all routers and protected routes from route configurations.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (routers, protected_routes)
|
||||||
|
"""
|
||||||
|
from Events.Engine.set_defaults.run import get_cluster_controller_group
|
||||||
|
|
||||||
|
cluster_list = get_cluster_controller_group()
|
||||||
|
prepare_routing = PrepareRouting(cluster_controller_group=cluster_list)
|
||||||
|
return prepare_routing
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Events.AllEvents.authentication as auths_events
|
||||||
|
|
||||||
|
events_list = (auths_events,)
|
||||||
|
|
@ -9,14 +9,13 @@ This module provides functionality to create and customize OpenAPI documentation
|
||||||
- Custom documentation extensions
|
- Custom documentation extensions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, Dict, List, Optional, Set
|
from typing import Any, Dict
|
||||||
from fastapi import FastAPI, APIRouter
|
from fastapi import FastAPI
|
||||||
from fastapi.routing import APIRoute
|
from fastapi.routing import APIRoute
|
||||||
from fastapi.openapi.utils import get_openapi
|
from fastapi.openapi.utils import get_openapi
|
||||||
|
|
||||||
from AllConfigs.Token.config import Auth
|
|
||||||
from AllConfigs.main import MainConfig as Config
|
|
||||||
from create_routes import get_all_routers
|
from create_routes import get_all_routers
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
class OpenAPISchemaCreator:
|
class OpenAPISchemaCreator:
|
||||||
|
|
@ -32,28 +31,8 @@ class OpenAPISchemaCreator:
|
||||||
app: FastAPI application instance
|
app: FastAPI application instance
|
||||||
"""
|
"""
|
||||||
self.app = app
|
self.app = app
|
||||||
_, self.protected_routes = get_all_routers()
|
self.cluster = get_all_routers()
|
||||||
# self.tags_metadata = self._create_tags_metadata()
|
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _create_tags_metadata() -> List[Dict[str, str]]:
|
|
||||||
"""
|
|
||||||
Create metadata for API tags.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
List[Dict[str, str]]: List of tag metadata
|
|
||||||
"""
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
"name": "Authentication",
|
|
||||||
"description": "Operations related to user authentication and authorization",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Users",
|
|
||||||
"description": "User management and profile operations",
|
|
||||||
},
|
|
||||||
# Add more tags as needed
|
|
||||||
]
|
|
||||||
|
|
||||||
def _create_security_schemes(self) -> Dict[str, Any]:
|
def _create_security_schemes(self) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -62,6 +41,7 @@ class OpenAPISchemaCreator:
|
||||||
Returns:
|
Returns:
|
||||||
Dict[str, Any]: Security scheme configurations
|
Dict[str, Any]: Security scheme configurations
|
||||||
"""
|
"""
|
||||||
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
return {
|
return {
|
||||||
"BearerAuth": {
|
"BearerAuth": {
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
|
|
@ -206,19 +186,17 @@ class OpenAPISchemaCreator:
|
||||||
method: HTTP method
|
method: HTTP method
|
||||||
schema: OpenAPI schema to modify
|
schema: OpenAPI schema to modify
|
||||||
"""
|
"""
|
||||||
# Check if route is protected based on dynamic routing info
|
if not schema.get("paths", {}).get(path, {}).get(method):
|
||||||
if path in self.protected_routes and method in self.protected_routes[path]:
|
return
|
||||||
schema["paths"][path][method]["security"] = [
|
|
||||||
{"Bearer Auth": []},
|
|
||||||
]
|
|
||||||
schema["paths"][path][method]["responses"].update(
|
|
||||||
self._create_common_responses()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Process request body examples
|
# Check if endpoint is in safe list
|
||||||
self._process_request_body(path, method, schema)
|
endpoint_path = f"{path}:{method}"
|
||||||
# Process response examples
|
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
|
||||||
self._process_response_examples(path, method, schema)
|
if "security" not in schema["paths"][path][method]:
|
||||||
|
schema["paths"][path][method]["security"] = []
|
||||||
|
schema["paths"][path][method]["security"].append(
|
||||||
|
{"BearerAuth": []}
|
||||||
|
)
|
||||||
|
|
||||||
def create_schema(self) -> Dict[str, Any]:
|
def create_schema(self) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -228,8 +206,8 @@ class OpenAPISchemaCreator:
|
||||||
Dict[str, Any]: Complete OpenAPI schema
|
Dict[str, Any]: Complete OpenAPI schema
|
||||||
"""
|
"""
|
||||||
openapi_schema = get_openapi(
|
openapi_schema = get_openapi(
|
||||||
title=Config.TITLE,
|
title=ApiConfig.TITLE,
|
||||||
description=Config.DESCRIPTION,
|
description=ApiConfig.DESCRIPTION,
|
||||||
version="1.1.1",
|
version="1.1.1",
|
||||||
routes=self.app.routes,
|
routes=self.app.routes,
|
||||||
)
|
)
|
||||||
|
|
@ -238,9 +216,8 @@ class OpenAPISchemaCreator:
|
||||||
if "components" not in openapi_schema:
|
if "components" not in openapi_schema:
|
||||||
openapi_schema["components"] = {}
|
openapi_schema["components"] = {}
|
||||||
|
|
||||||
openapi_schema["components"][
|
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
|
||||||
"securitySchemes"
|
|
||||||
] = self._create_security_schemes()
|
|
||||||
# Configure route security and responses
|
# Configure route security and responses
|
||||||
for route in self.app.routes:
|
for route in self.app.routes:
|
||||||
if isinstance(route, APIRoute) and route.include_in_schema:
|
if isinstance(route, APIRoute) and route.include_in_schema:
|
||||||
|
|
@ -249,13 +226,12 @@ class OpenAPISchemaCreator:
|
||||||
for method in methods:
|
for method in methods:
|
||||||
self.configure_route_security(path, method, openapi_schema)
|
self.configure_route_security(path, method, openapi_schema)
|
||||||
|
|
||||||
# # Add custom documentation extensions
|
# Add custom documentation extensions
|
||||||
openapi_schema["x-documentation"] = {
|
openapi_schema["x-documentation"] = {
|
||||||
"postman_collection": "/docs/postman",
|
"postman_collection": "/docs/postman",
|
||||||
"swagger_ui": "/docs",
|
"swagger_ui": "/docs",
|
||||||
"redoc": "/redoc",
|
"redoc": "/redoc",
|
||||||
}
|
}
|
||||||
|
|
||||||
return openapi_schema
|
return openapi_schema
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -19,22 +19,18 @@ RUN poetry config virtualenvs.create false \
|
||||||
&& rm -rf ~/.cache/pypoetry
|
&& rm -rf ~/.cache/pypoetry
|
||||||
|
|
||||||
# Copy application code
|
# Copy application code
|
||||||
COPY DockerApiServices/AllApiNeeds /app
|
COPY DockerApiServices/EventServiceApi /app
|
||||||
COPY ErrorHandlers /app/ErrorHandlers
|
|
||||||
COPY LanguageModels /app/LanguageModels
|
# Copy application code
|
||||||
COPY ApiLibrary /app/ApiLibrary
|
COPY ApiLayers /app/ApiLayers
|
||||||
COPY ApiValidations /app/ApiValidations
|
|
||||||
COPY AllConfigs /app/AllConfigs
|
|
||||||
COPY ErrorHandlers /app/ErrorHandlers
|
|
||||||
COPY Schemas /app/Schemas
|
|
||||||
COPY Services /app/Services
|
COPY Services /app/Services
|
||||||
COPY ApiServices /app/ApiServices
|
|
||||||
|
|
||||||
# Copy Events structure with consistent naming
|
|
||||||
COPY ApiEvents/EventServiceApi /app/ApiEvents
|
|
||||||
COPY ApiEvents/abstract_class.py /app/ApiEvents/abstract_class.py
|
|
||||||
COPY ApiEvents/base_request_model.py /app/ApiEvents/base_request_model.py
|
|
||||||
|
|
||||||
|
# Events
|
||||||
|
# COPY Events/base_request_model.py /app/Events/base_request_model.py
|
||||||
|
COPY Events/Engine /app/Events/Engine
|
||||||
|
COPY Events/base_request_model.py /app/Events/base_request_model.py
|
||||||
|
COPY Events/AllEvents/events /app/Events/AllEvents/events
|
||||||
|
COPY DockerApiServices/EventServiceApi/events_file.py /app/Events/AllEvents/events_file.py
|
||||||
|
|
||||||
# Set Python path to include app directory
|
# Set Python path to include app directory
|
||||||
ENV PYTHONPATH=/app \
|
ENV PYTHONPATH=/app \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Entry Point
|
||||||
|
|
||||||
|
This module initializes and configures the FastAPI application with:
|
||||||
|
- CORS middleware for cross-origin requests
|
||||||
|
- Request timing middleware for performance monitoring
|
||||||
|
- Custom exception handlers for consistent error responses
|
||||||
|
- Prometheus instrumentation for metrics
|
||||||
|
- API routers for endpoint organization
|
||||||
|
"""
|
||||||
|
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
from prometheus_fastapi_instrumentator import Instrumentator
|
||||||
|
from app_handler import setup_middleware
|
||||||
|
from create_file import create_app
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
|
app = create_app() # Initialize FastAPI application
|
||||||
|
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
|
||||||
|
setup_middleware(app) # Configure middleware and exception handlers
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Run the application with Uvicorn
|
||||||
|
uvicorn.Server(uvicorn.Config(**ApiConfig.as_dict())).run()
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Handler Module
|
||||||
|
|
||||||
|
This module contains all the handler functions for configuring and setting up the FastAPI application:
|
||||||
|
- CORS middleware configuration
|
||||||
|
- Exception handlers setup
|
||||||
|
- Uvicorn server configuration
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import FastAPI, Request, status
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
|
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
def setup_cors_middleware(app: FastAPI) -> None:
|
||||||
|
"""
|
||||||
|
Configure CORS middleware for the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
||||||
|
"""
|
||||||
|
Handle generic exceptions and return formatted error responses.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request: FastAPI request object
|
||||||
|
exc: Exception instance
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JSONResponse: Formatted error response
|
||||||
|
"""
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
content={"detail": "Internal server error", "error_code": "INTERNAL_ERROR"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_exception_handlers(app: FastAPI) -> None:
|
||||||
|
"""
|
||||||
|
Configure custom exception handlers for the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
|
||||||
|
|
||||||
|
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
|
||||||
|
app.add_exception_handler(
|
||||||
|
HTTPExceptionApi, custom_exception_handler.handle_exception
|
||||||
|
)
|
||||||
|
app.add_exception_handler(Exception, generic_exception_handler)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_middleware(app: FastAPI) -> None:
|
||||||
|
"""
|
||||||
|
Configure all middleware for the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
setup_cors_middleware(app)
|
||||||
|
app.add_middleware(RequestTimingMiddleware)
|
||||||
|
app.add_middleware(LoggerTimingMiddleware)
|
||||||
|
setup_exception_handlers(app)
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
class DefaultApiConfig:
|
||||||
|
app: str
|
||||||
|
host: str
|
||||||
|
port: int
|
||||||
|
log_level: str
|
||||||
|
reload: bool
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def as_dict(cls):
|
||||||
|
return {
|
||||||
|
"app": cls.app,
|
||||||
|
"host": cls.host,
|
||||||
|
"port": int(cls.port),
|
||||||
|
"log_level": cls.log_level,
|
||||||
|
"reload": bool(cls.reload),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ApiStatic:
|
||||||
|
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
|
||||||
|
FORGOT_LINK = "https://www.evyos.com.tr/password/create?tokenUrl="
|
||||||
|
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
|
||||||
|
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def forgot_link(cls, forgot_key):
|
||||||
|
return cls.FORGOT_LINK + forgot_key
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def blacklist_login(cls, record_id):
|
||||||
|
return cls.BLACKLIST_LINK + record_id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ApiConfig(DefaultApiConfig):
|
||||||
|
# Api configuration
|
||||||
|
APP_NAME = "evyos-event-api-gateway"
|
||||||
|
TITLE = "WAG API Event Api Gateway"
|
||||||
|
DESCRIPTION = "This api is serves as web event api gateway only to evyos web services."
|
||||||
|
APP_URL = "https://www.event.eys.gen.tr"
|
||||||
|
|
||||||
|
# Uvicorn server configuration
|
||||||
|
app = "app:app"
|
||||||
|
host = "0.0.0.0"
|
||||||
|
port = 41576
|
||||||
|
log_level = "info"
|
||||||
|
reload = True
|
||||||
|
|
||||||
|
|
||||||
|
class MainConfig:
|
||||||
|
# Date and Time Configuration
|
||||||
|
DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss Z"
|
||||||
|
DATETIME_FORMAT_JS = "YYYY-MM-DD HH:mm:ss +0"
|
||||||
|
|
||||||
|
# Timezone Configuration
|
||||||
|
DEFAULT_TIMEZONE = "GMT+3" # Default timezone for the application
|
||||||
|
SYSTEM_TIMEZONE = "GMT+0" # System timezone (used for internal operations)
|
||||||
|
SUPPORTED_TIMEZONES = ["GMT+0", "GMT+3"] # List of supported timezones
|
||||||
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Factory Module
|
||||||
|
|
||||||
|
This module provides functionality to create and configure a FastAPI application with:
|
||||||
|
- Custom OpenAPI schema configuration
|
||||||
|
- Security scheme configuration for Bearer authentication
|
||||||
|
- Automatic router registration
|
||||||
|
- Response class configuration
|
||||||
|
- Security requirements for protected endpoints
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import JSONResponse, RedirectResponse
|
||||||
|
|
||||||
|
from config import ApiConfig
|
||||||
|
from create_routes import get_all_routers
|
||||||
|
|
||||||
|
|
||||||
|
def create_app() -> FastAPI:
|
||||||
|
"""
|
||||||
|
Create and configure a FastAPI application with dynamic route creation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
FastAPI: Configured FastAPI application instance
|
||||||
|
"""
|
||||||
|
|
||||||
|
from open_api_creator import create_openapi_schema
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title=ApiConfig.TITLE,
|
||||||
|
description=ApiConfig.DESCRIPTION,
|
||||||
|
default_response_class=JSONResponse,
|
||||||
|
) # Initialize FastAPI app
|
||||||
|
|
||||||
|
@app.get("/", include_in_schema=False, summary=str(ApiConfig.DESCRIPTION))
|
||||||
|
def home() -> RedirectResponse:
|
||||||
|
"""Redirect root path to API documentation."""
|
||||||
|
return RedirectResponse(url="/docs")
|
||||||
|
|
||||||
|
# Get all routers and protected routes using the dynamic route creation
|
||||||
|
prepare_routing = get_all_routers()
|
||||||
|
|
||||||
|
# Include all routers
|
||||||
|
for router in prepare_routing.routers:
|
||||||
|
app.include_router(router)
|
||||||
|
|
||||||
|
app.openapi = lambda app=app: create_openapi_schema(app)
|
||||||
|
return app
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
"""
|
||||||
|
Route configuration and factory module.
|
||||||
|
Handles dynamic route creation based on configurations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import Request
|
||||||
|
from Events.Engine.set_defaults.setClusters import PrepareRouting
|
||||||
|
|
||||||
|
|
||||||
|
async def health_check(request: Request):
|
||||||
|
"""Default health check endpoint."""
|
||||||
|
return {"status": "healthy", "message": "Service is running"}
|
||||||
|
|
||||||
|
|
||||||
|
async def ping_test(request: Request, service_name: str = "base-router"):
|
||||||
|
"""Default ping test endpoint."""
|
||||||
|
return {"ping": "pong", "service": service_name}
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_routers() -> PrepareRouting:
|
||||||
|
"""
|
||||||
|
Get all routers and protected routes from route configurations.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (routers, protected_routes)
|
||||||
|
"""
|
||||||
|
from Events.Engine.set_defaults.run import get_cluster_controller_group
|
||||||
|
|
||||||
|
cluster_list = get_cluster_controller_group()
|
||||||
|
prepare_routing = PrepareRouting(cluster_controller_group=cluster_list)
|
||||||
|
return prepare_routing
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Events.AllEvents.events as events_events
|
||||||
|
|
||||||
|
events_list = (events_events,)
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
"""
|
||||||
|
OpenAPI Schema Creator Module
|
||||||
|
|
||||||
|
This module provides functionality to create and customize OpenAPI documentation:
|
||||||
|
- Custom security schemes (Bearer Auth, API Key)
|
||||||
|
- Response schemas and examples
|
||||||
|
- Tag management and descriptions
|
||||||
|
- Error responses and validation
|
||||||
|
- Custom documentation extensions
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Dict
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.routing import APIRoute
|
||||||
|
from fastapi.openapi.utils import get_openapi
|
||||||
|
|
||||||
|
from create_routes import get_all_routers
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
|
class OpenAPISchemaCreator:
|
||||||
|
"""
|
||||||
|
OpenAPI schema creator and customizer for FastAPI applications.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, app: FastAPI):
|
||||||
|
"""
|
||||||
|
Initialize the OpenAPI schema creator.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
self.app = app
|
||||||
|
self.cluster = get_all_routers()
|
||||||
|
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
|
||||||
|
|
||||||
|
def _create_security_schemes(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create security scheme definitions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Security scheme configurations
|
||||||
|
"""
|
||||||
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
|
return {
|
||||||
|
"BearerAuth": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"in": "header",
|
||||||
|
"name": Auth.ACCESS_TOKEN_TAG,
|
||||||
|
"description": "Enter: **'Bearer <JWT>'**, where JWT is the access token",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def _create_common_responses(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create common response schemas.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Common response configurations
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized - Invalid or missing credentials",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden - Insufficient permissions",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"detail": {"type": "string"},
|
||||||
|
"error_code": {"type": "string"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"detail": "Internal server error occurred",
|
||||||
|
"error_code": "INTERNAL_ERROR",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def _process_request_body(
|
||||||
|
self, path: str, method: str, schema: Dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Process request body to include examples from model config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Route path
|
||||||
|
method: HTTP method
|
||||||
|
schema: OpenAPI schema to modify
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
route_schema = schema["paths"][path][method]
|
||||||
|
if "requestBody" in route_schema:
|
||||||
|
request_body = route_schema["requestBody"]
|
||||||
|
if "content" in request_body:
|
||||||
|
content = request_body["content"]
|
||||||
|
if "application/json" in content:
|
||||||
|
json_content = content["application/json"]
|
||||||
|
if (
|
||||||
|
"schema" in json_content
|
||||||
|
and "$ref" in json_content["schema"]
|
||||||
|
):
|
||||||
|
ref = json_content["schema"]["$ref"]
|
||||||
|
model_name = ref.split("/")[-1]
|
||||||
|
if model_name in schema["components"]["schemas"]:
|
||||||
|
model_schema = schema["components"]["schemas"][
|
||||||
|
model_name
|
||||||
|
]
|
||||||
|
if "example" in model_schema:
|
||||||
|
json_content["example"] = model_schema["example"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _process_response_examples(
|
||||||
|
self, path: str, method: str, schema: Dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Process response body to include examples from model config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Route path
|
||||||
|
method: HTTP method
|
||||||
|
schema: OpenAPI schema to modify
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
route_schema = schema["paths"][path][method]
|
||||||
|
if "responses" in route_schema:
|
||||||
|
responses = route_schema["responses"]
|
||||||
|
if "200" in responses:
|
||||||
|
response = responses["200"]
|
||||||
|
if "content" in response:
|
||||||
|
content = response["content"]
|
||||||
|
if "application/json" in content:
|
||||||
|
json_content = content["application/json"]
|
||||||
|
if (
|
||||||
|
"schema" in json_content
|
||||||
|
and "$ref" in json_content["schema"]
|
||||||
|
):
|
||||||
|
ref = json_content["schema"]["$ref"]
|
||||||
|
model_name = ref.split("/")[-1]
|
||||||
|
if model_name in schema["components"]["schemas"]:
|
||||||
|
model_schema = schema["components"]["schemas"][
|
||||||
|
model_name
|
||||||
|
]
|
||||||
|
if "example" in model_schema:
|
||||||
|
json_content["example"] = model_schema[
|
||||||
|
"example"
|
||||||
|
]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def configure_route_security(
|
||||||
|
self, path: str, method: str, schema: Dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Configure security requirements for a specific route.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Route path
|
||||||
|
method: HTTP method
|
||||||
|
schema: OpenAPI schema to modify
|
||||||
|
"""
|
||||||
|
if not schema.get("paths", {}).get(path, {}).get(method):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if endpoint is in safe list
|
||||||
|
endpoint_path = f"{path}:{method}"
|
||||||
|
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
|
||||||
|
if "security" not in schema["paths"][path][method]:
|
||||||
|
schema["paths"][path][method]["security"] = []
|
||||||
|
schema["paths"][path][method]["security"].append(
|
||||||
|
{"BearerAuth": []}
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_schema(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create the complete OpenAPI schema.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Complete OpenAPI schema
|
||||||
|
"""
|
||||||
|
openapi_schema = get_openapi(
|
||||||
|
title=ApiConfig.TITLE,
|
||||||
|
description=ApiConfig.DESCRIPTION,
|
||||||
|
version="1.1.1",
|
||||||
|
routes=self.app.routes,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add security schemes
|
||||||
|
if "components" not in openapi_schema:
|
||||||
|
openapi_schema["components"] = {}
|
||||||
|
|
||||||
|
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
|
||||||
|
|
||||||
|
# Configure route security and responses
|
||||||
|
for route in self.app.routes:
|
||||||
|
if isinstance(route, APIRoute) and route.include_in_schema:
|
||||||
|
path = str(route.path)
|
||||||
|
methods = [method.lower() for method in route.methods]
|
||||||
|
for method in methods:
|
||||||
|
self.configure_route_security(path, method, openapi_schema)
|
||||||
|
|
||||||
|
# Add custom documentation extensions
|
||||||
|
openapi_schema["x-documentation"] = {
|
||||||
|
"postman_collection": "/docs/postman",
|
||||||
|
"swagger_ui": "/docs",
|
||||||
|
"redoc": "/redoc",
|
||||||
|
}
|
||||||
|
return openapi_schema
|
||||||
|
|
||||||
|
|
||||||
|
def create_openapi_schema(app: FastAPI) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create OpenAPI schema for a FastAPI application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Complete OpenAPI schema
|
||||||
|
"""
|
||||||
|
creator = OpenAPISchemaCreator(app)
|
||||||
|
return creator.create_schema()
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies and Poetry
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
gcc \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& pip install --no-cache-dir poetry
|
||||||
|
|
||||||
|
# Copy Poetry configuration
|
||||||
|
COPY DockerApiServices/pyproject.toml ./pyproject.toml
|
||||||
|
|
||||||
|
# # Configure Poetry and install dependencies with optimizations
|
||||||
|
# RUN poetry config virtualenvs.create false \
|
||||||
|
# && poetry install --no-interaction --no-ansi --no-root --only main \
|
||||||
|
# && pip cache purge \
|
||||||
|
# && rm -rf ~/.cache/pypoetry
|
||||||
|
|
||||||
|
# # Copy application code
|
||||||
|
# COPY DockerApiServices/EventServiceApi /app
|
||||||
|
|
||||||
|
# # Copy application code
|
||||||
|
# COPY ApiLayers /app/ApiLayers
|
||||||
|
# COPY Services /app/Services
|
||||||
|
|
||||||
|
# # Events
|
||||||
|
# # COPY Events/base_request_model.py /app/Events/base_request_model.py
|
||||||
|
# COPY Events/Engine /app/Events/Engine
|
||||||
|
# COPY Events/AllEvents/events /app/Events/AllEvents/events
|
||||||
|
# COPY DockerApiServices/EventServiceApi/events_file.py /app/Events/AllEvents/events_file.py
|
||||||
|
|
||||||
|
# # Set Python path to include app directory
|
||||||
|
# ENV PYTHONPATH=/app \
|
||||||
|
# PYTHONUNBUFFERED=1 \
|
||||||
|
# PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
||||||
|
# # Run the application using the configured uvicorn server
|
||||||
|
# CMD ["poetry", "run", "python", "app.py"]
|
||||||
|
|
@ -19,23 +19,17 @@ RUN poetry config virtualenvs.create false \
|
||||||
&& rm -rf ~/.cache/pypoetry
|
&& rm -rf ~/.cache/pypoetry
|
||||||
|
|
||||||
# Copy application code
|
# Copy application code
|
||||||
COPY DockerApiServices/AllApiNeeds /app
|
COPY DockerApiServices/ValidationServiceApi /app
|
||||||
COPY ErrorHandlers /app/ErrorHandlers
|
|
||||||
COPY LanguageModels /app/LanguageModels
|
|
||||||
COPY ApiLibrary /app/ApiLibrary
|
|
||||||
COPY ApiValidations /app/ApiValidations
|
|
||||||
COPY AllConfigs /app/AllConfigs
|
|
||||||
COPY ErrorHandlers /app/ErrorHandlers
|
|
||||||
COPY Schemas /app/Schemas
|
|
||||||
COPY Services /app/Services
|
|
||||||
COPY ApiServices /app/ApiServices
|
|
||||||
|
|
||||||
# Copy Events structure with consistent naming
|
# Copy application code
|
||||||
COPY ApiEvents/ValidationServiceApi /app/ApiEvents
|
COPY ApiLayers /app/ApiLayers
|
||||||
ADD ApiEvents/AuthServiceApi/events /app/ApiEvents/events
|
COPY Services /app/Services
|
||||||
ADD ApiEvents/EventServiceApi/events /app/ApiEvents/events
|
|
||||||
COPY ApiEvents/abstract_class.py /app/ApiEvents/abstract_class.py
|
# Events
|
||||||
COPY ApiEvents/base_request_model.py /app/ApiEvents/base_request_model.py
|
# COPY Events/base_request_model.py /app/Events/base_request_model.py
|
||||||
|
COPY Events/Engine /app/Events/Engine
|
||||||
|
COPY Events/AllEvents/validations /app/Events/AllEvents/validations
|
||||||
|
COPY DockerApiServices/ValidationServiceApi/events_file.py /app/Events/AllEvents/events_file.py
|
||||||
|
|
||||||
# Set Python path to include app directory
|
# Set Python path to include app directory
|
||||||
ENV PYTHONPATH=/app \
|
ENV PYTHONPATH=/app \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Entry Point
|
||||||
|
|
||||||
|
This module initializes and configures the FastAPI application with:
|
||||||
|
- CORS middleware for cross-origin requests
|
||||||
|
- Request timing middleware for performance monitoring
|
||||||
|
- Custom exception handlers for consistent error responses
|
||||||
|
- Prometheus instrumentation for metrics
|
||||||
|
- API routers for endpoint organization
|
||||||
|
"""
|
||||||
|
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
from prometheus_fastapi_instrumentator import Instrumentator
|
||||||
|
from app_handler import setup_middleware
|
||||||
|
from create_file import create_app
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
|
app = create_app() # Initialize FastAPI application
|
||||||
|
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
|
||||||
|
setup_middleware(app) # Configure middleware and exception handlers
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Run the application with Uvicorn
|
||||||
|
uvicorn.Server(uvicorn.Config(**ApiConfig.as_dict())).run()
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Handler Module
|
||||||
|
|
||||||
|
This module contains all the handler functions for configuring and setting up the FastAPI application:
|
||||||
|
- CORS middleware configuration
|
||||||
|
- Exception handlers setup
|
||||||
|
- Uvicorn server configuration
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import FastAPI, Request, status
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
from ApiLayers.ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
|
||||||
|
from ApiLayers.Middleware.auth_middleware import RequestTimingMiddleware, LoggerTimingMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
def setup_cors_middleware(app: FastAPI) -> None:
|
||||||
|
"""
|
||||||
|
Configure CORS middleware for the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
|
||||||
|
"""
|
||||||
|
Handle generic exceptions and return formatted error responses.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request: FastAPI request object
|
||||||
|
exc: Exception instance
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
JSONResponse: Formatted error response
|
||||||
|
"""
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
content={"detail": "Internal server error", "error_code": "INTERNAL_ERROR"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_exception_handlers(app: FastAPI) -> None:
|
||||||
|
"""
|
||||||
|
Configure custom exception handlers for the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
from ApiLayers.ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
|
||||||
|
|
||||||
|
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
|
||||||
|
app.add_exception_handler(
|
||||||
|
HTTPExceptionApi, custom_exception_handler.handle_exception
|
||||||
|
)
|
||||||
|
app.add_exception_handler(Exception, generic_exception_handler)
|
||||||
|
|
||||||
|
|
||||||
|
def setup_middleware(app: FastAPI) -> None:
|
||||||
|
"""
|
||||||
|
Configure all middleware for the application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
setup_cors_middleware(app)
|
||||||
|
app.add_middleware(RequestTimingMiddleware)
|
||||||
|
app.add_middleware(LoggerTimingMiddleware)
|
||||||
|
setup_exception_handlers(app)
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
class DefaultApiConfig:
|
||||||
|
app: str
|
||||||
|
host: str
|
||||||
|
port: int
|
||||||
|
log_level: str
|
||||||
|
reload: bool
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def as_dict(cls):
|
||||||
|
return {
|
||||||
|
"app": cls.app,
|
||||||
|
"host": cls.host,
|
||||||
|
"port": int(cls.port),
|
||||||
|
"log_level": cls.log_level,
|
||||||
|
"reload": bool(cls.reload),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ApiStatic:
|
||||||
|
PLACEHOLDER = "https://s.tmimgcdn.com/scr/800x500/276800/building-home-nature-logo-vector-template-3_276851-original.jpg"
|
||||||
|
FORGOT_LINK = "https://www.evyos.com.tr/password/create?tokenUrl="
|
||||||
|
BLACKLIST_LINK = "https://www.evyos.com.tr/support/unknown-login-notice/"
|
||||||
|
APP_DIR = "/home/berkay/git-evyos/api-managment-backend/"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def forgot_link(cls, forgot_key):
|
||||||
|
return cls.FORGOT_LINK + forgot_key
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def blacklist_login(cls, record_id):
|
||||||
|
return cls.BLACKLIST_LINK + record_id
|
||||||
|
|
||||||
|
|
||||||
|
class ApiConfig(DefaultApiConfig):
|
||||||
|
# Api configuration
|
||||||
|
APP_NAME = "evyos-validation-api-gateway"
|
||||||
|
TITLE = "WAG API Validation Api Gateway"
|
||||||
|
DESCRIPTION = "This api is serves as web validation api gateway only to evyos web services."
|
||||||
|
APP_URL = "https://www.validation.eys.gen.tr"
|
||||||
|
# App configuration
|
||||||
|
app = "app:app"
|
||||||
|
host = "0.0.0.0"
|
||||||
|
port = 41577
|
||||||
|
log_level = "info"
|
||||||
|
reload = True
|
||||||
|
|
||||||
|
|
||||||
|
class MainConfig:
|
||||||
|
# Main configuration
|
||||||
|
DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss Z"
|
||||||
|
DATETIME_FORMAT_JS = "YYYY-MM-DD HH:mm:ss +0"
|
||||||
|
|
||||||
|
# Timezone Configuration
|
||||||
|
DEFAULT_TIMEZONE = "GMT+3" # Default timezone for the application
|
||||||
|
SYSTEM_TIMEZONE = "GMT+0" # System timezone (used for internal operations)
|
||||||
|
SUPPORTED_TIMEZONES = ["GMT+0", "GMT+3"] # List of supported timezones
|
||||||
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
"""
|
||||||
|
FastAPI Application Factory Module
|
||||||
|
|
||||||
|
This module provides functionality to create and configure a FastAPI application with:
|
||||||
|
- Custom OpenAPI schema configuration
|
||||||
|
- Security scheme configuration for Bearer authentication
|
||||||
|
- Automatic router registration
|
||||||
|
- Response class configuration
|
||||||
|
- Security requirements for protected endpoints
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.responses import JSONResponse, RedirectResponse
|
||||||
|
|
||||||
|
from create_routes import get_all_routers
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
|
def create_app() -> FastAPI:
|
||||||
|
"""
|
||||||
|
Create and configure a FastAPI application with dynamic route creation.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
FastAPI: Configured FastAPI application instance
|
||||||
|
"""
|
||||||
|
|
||||||
|
from open_api_creator import create_openapi_schema
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title=ApiConfig.TITLE,
|
||||||
|
description=ApiConfig.DESCRIPTION,
|
||||||
|
default_response_class=JSONResponse,
|
||||||
|
) # Initialize FastAPI app
|
||||||
|
|
||||||
|
@app.get("/", include_in_schema=False, summary=str(ApiConfig.DESCRIPTION))
|
||||||
|
def home() -> RedirectResponse:
|
||||||
|
"""Redirect root path to API documentation."""
|
||||||
|
return RedirectResponse(url="/docs")
|
||||||
|
|
||||||
|
# Get all routers and protected routes using the dynamic route creation
|
||||||
|
prepare_routing = get_all_routers()
|
||||||
|
|
||||||
|
# Include all routers
|
||||||
|
for router in prepare_routing.routers:
|
||||||
|
app.include_router(router)
|
||||||
|
|
||||||
|
app.openapi = lambda app=app: create_openapi_schema(app)
|
||||||
|
return app
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
"""
|
||||||
|
Route configuration and factory module.
|
||||||
|
Handles dynamic route creation based on configurations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from fastapi import Request
|
||||||
|
from Events.Engine.set_defaults.setClusters import PrepareRouting
|
||||||
|
|
||||||
|
|
||||||
|
async def health_check(request: Request):
|
||||||
|
"""Default health check endpoint."""
|
||||||
|
return {"status": "healthy", "message": "Service is running"}
|
||||||
|
|
||||||
|
|
||||||
|
async def ping_test(request: Request, service_name: str = "base-router"):
|
||||||
|
"""Default ping test endpoint."""
|
||||||
|
return {"ping": "pong", "service": service_name}
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_routers() -> PrepareRouting:
|
||||||
|
"""
|
||||||
|
Get all routers and protected routes from route configurations.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (routers, protected_routes)
|
||||||
|
"""
|
||||||
|
from Events.Engine.set_defaults.run import get_cluster_controller_group
|
||||||
|
|
||||||
|
cluster_list = get_cluster_controller_group()
|
||||||
|
prepare_routing = PrepareRouting(cluster_controller_group=cluster_list)
|
||||||
|
return prepare_routing
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
import Events.AllEvents.validations as validations_events
|
||||||
|
|
||||||
|
events_list = (validations_events,)
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
"""
|
||||||
|
OpenAPI Schema Creator Module
|
||||||
|
|
||||||
|
This module provides functionality to create and customize OpenAPI documentation:
|
||||||
|
- Custom security schemes (Bearer Auth, API Key)
|
||||||
|
- Response schemas and examples
|
||||||
|
- Tag management and descriptions
|
||||||
|
- Error responses and validation
|
||||||
|
- Custom documentation extensions
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Any, Dict
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.routing import APIRoute
|
||||||
|
from fastapi.openapi.utils import get_openapi
|
||||||
|
|
||||||
|
from create_routes import get_all_routers
|
||||||
|
from config import ApiConfig
|
||||||
|
|
||||||
|
|
||||||
|
class OpenAPISchemaCreator:
|
||||||
|
"""
|
||||||
|
OpenAPI schema creator and customizer for FastAPI applications.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, app: FastAPI):
|
||||||
|
"""
|
||||||
|
Initialize the OpenAPI schema creator.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
"""
|
||||||
|
self.app = app
|
||||||
|
self.cluster = get_all_routers()
|
||||||
|
self.safe_endpoint_list = self.cluster.safe_endpoints if hasattr(self.cluster, 'safe_endpoints') else []
|
||||||
|
|
||||||
|
def _create_security_schemes(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create security scheme definitions.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Security scheme configurations
|
||||||
|
"""
|
||||||
|
from ApiLayers.AllConfigs.Token.config import Auth
|
||||||
|
return {
|
||||||
|
"BearerAuth": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"in": "header",
|
||||||
|
"name": Auth.ACCESS_TOKEN_TAG,
|
||||||
|
"description": "Enter: **'Bearer <JWT>'**, where JWT is the access token",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def _create_common_responses(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create common response schemas.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Common response configurations
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"401": {
|
||||||
|
"description": "Unauthorized - Invalid or missing credentials",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden - Insufficient permissions",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/HTTPValidationError"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"detail": {"type": "string"},
|
||||||
|
"error_code": {"type": "string"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"example": {
|
||||||
|
"detail": "Internal server error occurred",
|
||||||
|
"error_code": "INTERNAL_ERROR",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def _process_request_body(
|
||||||
|
self, path: str, method: str, schema: Dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Process request body to include examples from model config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Route path
|
||||||
|
method: HTTP method
|
||||||
|
schema: OpenAPI schema to modify
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
route_schema = schema["paths"][path][method]
|
||||||
|
if "requestBody" in route_schema:
|
||||||
|
request_body = route_schema["requestBody"]
|
||||||
|
if "content" in request_body:
|
||||||
|
content = request_body["content"]
|
||||||
|
if "application/json" in content:
|
||||||
|
json_content = content["application/json"]
|
||||||
|
if (
|
||||||
|
"schema" in json_content
|
||||||
|
and "$ref" in json_content["schema"]
|
||||||
|
):
|
||||||
|
ref = json_content["schema"]["$ref"]
|
||||||
|
model_name = ref.split("/")[-1]
|
||||||
|
if model_name in schema["components"]["schemas"]:
|
||||||
|
model_schema = schema["components"]["schemas"][
|
||||||
|
model_name
|
||||||
|
]
|
||||||
|
if "example" in model_schema:
|
||||||
|
json_content["example"] = model_schema["example"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _process_response_examples(
|
||||||
|
self, path: str, method: str, schema: Dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Process response body to include examples from model config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Route path
|
||||||
|
method: HTTP method
|
||||||
|
schema: OpenAPI schema to modify
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
route_schema = schema["paths"][path][method]
|
||||||
|
if "responses" in route_schema:
|
||||||
|
responses = route_schema["responses"]
|
||||||
|
if "200" in responses:
|
||||||
|
response = responses["200"]
|
||||||
|
if "content" in response:
|
||||||
|
content = response["content"]
|
||||||
|
if "application/json" in content:
|
||||||
|
json_content = content["application/json"]
|
||||||
|
if (
|
||||||
|
"schema" in json_content
|
||||||
|
and "$ref" in json_content["schema"]
|
||||||
|
):
|
||||||
|
ref = json_content["schema"]["$ref"]
|
||||||
|
model_name = ref.split("/")[-1]
|
||||||
|
if model_name in schema["components"]["schemas"]:
|
||||||
|
model_schema = schema["components"]["schemas"][
|
||||||
|
model_name
|
||||||
|
]
|
||||||
|
if "example" in model_schema:
|
||||||
|
json_content["example"] = model_schema[
|
||||||
|
"example"
|
||||||
|
]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def configure_route_security(
|
||||||
|
self, path: str, method: str, schema: Dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Configure security requirements for a specific route.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Route path
|
||||||
|
method: HTTP method
|
||||||
|
schema: OpenAPI schema to modify
|
||||||
|
"""
|
||||||
|
if not schema.get("paths", {}).get(path, {}).get(method):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if endpoint is in safe list
|
||||||
|
endpoint_path = f"{path}:{method}"
|
||||||
|
if endpoint_path not in [f"{e.URL}:{e.METHOD.lower()}" for e in self.safe_endpoint_list]:
|
||||||
|
if "security" not in schema["paths"][path][method]:
|
||||||
|
schema["paths"][path][method]["security"] = []
|
||||||
|
schema["paths"][path][method]["security"].append(
|
||||||
|
{"BearerAuth": []}
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_schema(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create the complete OpenAPI schema.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Complete OpenAPI schema
|
||||||
|
"""
|
||||||
|
openapi_schema = get_openapi(
|
||||||
|
title=ApiConfig.TITLE,
|
||||||
|
description=ApiConfig.DESCRIPTION,
|
||||||
|
version="1.1.1",
|
||||||
|
routes=self.app.routes,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add security schemes
|
||||||
|
if "components" not in openapi_schema:
|
||||||
|
openapi_schema["components"] = {}
|
||||||
|
|
||||||
|
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
|
||||||
|
|
||||||
|
# Configure route security and responses
|
||||||
|
for route in self.app.routes:
|
||||||
|
if isinstance(route, APIRoute) and route.include_in_schema:
|
||||||
|
path = str(route.path)
|
||||||
|
methods = [method.lower() for method in route.methods]
|
||||||
|
for method in methods:
|
||||||
|
self.configure_route_security(path, method, openapi_schema)
|
||||||
|
|
||||||
|
# Add custom documentation extensions
|
||||||
|
openapi_schema["x-documentation"] = {
|
||||||
|
"postman_collection": "/docs/postman",
|
||||||
|
"swagger_ui": "/docs",
|
||||||
|
"redoc": "/redoc",
|
||||||
|
}
|
||||||
|
return openapi_schema
|
||||||
|
|
||||||
|
|
||||||
|
def create_openapi_schema(app: FastAPI) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Create OpenAPI schema for a FastAPI application.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
app: FastAPI application instance
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, Any]: Complete OpenAPI schema
|
||||||
|
"""
|
||||||
|
creator = OpenAPISchemaCreator(app)
|
||||||
|
return creator.create_schema()
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
Authentication package initialization.
|
Authentication package initialization.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .auth import AUTH_CONFIG
|
from .auth.cluster import AuthCluster
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"AUTH_CONFIG",
|
"AuthCluster",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
from uuid import UUID
|
|
||||||
from Events.Engine.abstract_class import Event
|
from Events.Engine.abstract_class import Event
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
|
|
@ -14,8 +13,6 @@ from .models import (
|
||||||
from .function_handlers import (
|
from .function_handlers import (
|
||||||
authentication_login_with_domain_and_creds,
|
authentication_login_with_domain_and_creds,
|
||||||
authentication_select_company_or_occupant_type,
|
authentication_select_company_or_occupant_type,
|
||||||
handle_employee_selection,
|
|
||||||
handle_occupant_selection,
|
|
||||||
authentication_check_token_is_valid,
|
authentication_check_token_is_valid,
|
||||||
authentication_refresh_user_info,
|
authentication_refresh_user_info,
|
||||||
authentication_change_password,
|
authentication_change_password,
|
||||||
|
|
@ -31,124 +28,126 @@ from .function_handlers import (
|
||||||
|
|
||||||
# Auth Login
|
# Auth Login
|
||||||
authentication_login_super_user_event = Event(
|
authentication_login_super_user_event = Event(
|
||||||
key=UUID("a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e"),
|
name="authentication_login_super_user_event",
|
||||||
|
key="a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e",
|
||||||
request_validator=LoginSuperUserRequestModel,
|
request_validator=LoginSuperUserRequestModel,
|
||||||
response_validator=LoginSuperUserResponseModel,
|
# response_validator=LoginSuperUserResponseModel,
|
||||||
description="Login super user",
|
description="Login super user",
|
||||||
)
|
)
|
||||||
authentication_login_super_user_event.endpoint_callable = authentication_login_with_domain_and_creds
|
authentication_login_super_user_event.endpoint_callable = (
|
||||||
|
authentication_login_with_domain_and_creds
|
||||||
|
)
|
||||||
|
|
||||||
# Auth Select Company or Occupant Type
|
# Auth Select Company or Occupant Type
|
||||||
authentication_select_company_or_occupant_type_super_user_event = Event(
|
authentication_select_company_or_occupant_type_super_user_event = Event(
|
||||||
key=UUID("a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e"),
|
name="authentication_select_company_or_occupant_type_super_user_event",
|
||||||
|
key="a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e",
|
||||||
request_validator=SelectCompanyOrOccupantTypeSuperUserRequestModel,
|
request_validator=SelectCompanyOrOccupantTypeSuperUserRequestModel,
|
||||||
response_validator=SelectCompanyOrOccupantTypeSuperUserResponseModel,
|
# response_validator=SelectCompanyOrOccupantTypeSuperUserResponseModel,
|
||||||
description="Select company or occupant type super user",
|
description="Select company or occupant type super user",
|
||||||
)
|
)
|
||||||
authentication_select_company_or_occupant_type_super_user_event.endpoint_callable = authentication_select_company_or_occupant_type
|
authentication_select_company_or_occupant_type_super_user_event.endpoint_callable = (
|
||||||
|
authentication_select_company_or_occupant_type
|
||||||
authentication_employee_selection_super_user_event = Event(
|
|
||||||
key=UUID("a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e"),
|
|
||||||
request_validator=EmployeeSelectionSuperUserRequestModel,
|
|
||||||
response_validator=EmployeeSelectionSuperUserResponseModel,
|
|
||||||
description="Employee selection super user",
|
|
||||||
)
|
)
|
||||||
authentication_employee_selection_super_user_event.endpoint_callable = handle_employee_selection
|
|
||||||
|
|
||||||
authentication_occupant_selection_super_user_event = Event(
|
|
||||||
key=UUID("a5d2d0d1-3e9b-4b0f-8c7d-6d4a4b4c4d4e"),
|
|
||||||
request_validator=OccupantSelectionSuperUserRequestModel,
|
|
||||||
response_validator=OccupantSelectionSuperUserResponseModel,
|
|
||||||
description="Occupant selection super user",
|
|
||||||
)
|
|
||||||
authentication_occupant_selection_super_user_event.endpoint_callable = handle_occupant_selection
|
|
||||||
|
|
||||||
# Check Token Validity
|
# Check Token Validity
|
||||||
authentication_check_token_event = Event(
|
authentication_check_token_event = Event(
|
||||||
key=UUID("b6e3d1e2-4f9c-5c1g-9d8e-7e5f6f5e5d5f"),
|
name="authentication_check_token_event",
|
||||||
|
key="b6e3d1e2-4f9c-5c1g-9d8e-7e5f6f5e5d5f",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Check if token is valid",
|
description="Check if token is valid",
|
||||||
)
|
)
|
||||||
authentication_check_token_event.endpoint_callable = authentication_check_token_is_valid
|
authentication_check_token_event.endpoint_callable = authentication_check_token_is_valid
|
||||||
|
|
||||||
# Refresh User Info
|
# Refresh User Info
|
||||||
authentication_refresh_user_info_event = Event(
|
authentication_refresh_user_info_event = Event(
|
||||||
key=UUID("c7f4e2f3-5g0d-6d2h-0e9f-8f6g7g6f6e6g"),
|
name="authentication_refresh_user_info_event",
|
||||||
|
key="c7f4e2f3-5g0d-6d2h-0e9f-8f6g7g6f6e6g",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Refresh user information",
|
description="Refresh user information",
|
||||||
)
|
)
|
||||||
authentication_refresh_user_info_event.endpoint_callable = authentication_refresh_user_info
|
authentication_refresh_user_info_event.endpoint_callable = (
|
||||||
|
authentication_refresh_user_info
|
||||||
|
)
|
||||||
|
|
||||||
# Change Password
|
# Change Password
|
||||||
authentication_change_password_event = Event(
|
authentication_change_password_event = Event(
|
||||||
key=UUID("d8g5f3g4-6h1e-7e3i-1f0g-9g7h8h7g7f7h"),
|
name="authentication_change_password_event",
|
||||||
|
key="d8g5f3g4-6h1e-7e3i-1f0g-9g7h8h7g7f7h",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Change user password",
|
description="Change user password",
|
||||||
)
|
)
|
||||||
authentication_change_password_event.endpoint_callable = authentication_change_password
|
authentication_change_password_event.endpoint_callable = authentication_change_password
|
||||||
|
|
||||||
# Create Password
|
# Create Password
|
||||||
authentication_create_password_event = Event(
|
authentication_create_password_event = Event(
|
||||||
key=UUID("e9h6g4h5-7i2f-8f4j-2g1h-0h8i9i8h8g8i"),
|
name="authentication_create_password_event",
|
||||||
|
key="e9h6g4h5-7i2f-8f4j-2g1h-0h8i9i8h8g8i",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Create new password",
|
description="Create new password",
|
||||||
)
|
)
|
||||||
authentication_create_password_event.endpoint_callable = authentication_create_password
|
authentication_create_password_event.endpoint_callable = authentication_create_password
|
||||||
|
|
||||||
# Disconnect User
|
# Disconnect User
|
||||||
authentication_disconnect_user_event = Event(
|
authentication_disconnect_user_event = Event(
|
||||||
key=UUID("f0i7h5i6-8j3g-9g5k-3h2i-1i9j0j9i9h9j"),
|
name="authentication_disconnect_user_event",
|
||||||
|
key="f0i7h5i6-8j3g-9g5k-3h2i-1i9j0j9i9h9j",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Disconnect all user sessions",
|
description="Disconnect all user sessions",
|
||||||
)
|
)
|
||||||
authentication_disconnect_user_event.endpoint_callable = authentication_disconnect_user
|
authentication_disconnect_user_event.endpoint_callable = authentication_disconnect_user
|
||||||
|
|
||||||
# Logout User
|
# Logout User
|
||||||
authentication_logout_user_event = Event(
|
authentication_logout_user_event = Event(
|
||||||
key=UUID("g1j8i6j7-9k4h-0h6l-4i3j-2j0k1k0j0i0k"),
|
name="authentication_logout_user_event",
|
||||||
|
key="g1j8i6j7-9k4h-0h6l-4i3j-2j0k1k0j0i0k",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Logout user session",
|
description="Logout user session",
|
||||||
)
|
)
|
||||||
authentication_logout_user_event.endpoint_callable = authentication_logout_user
|
authentication_logout_user_event.endpoint_callable = authentication_logout_user
|
||||||
|
|
||||||
# Refresh Token
|
# Refresh Token
|
||||||
authentication_refresher_token_event = Event(
|
authentication_refresher_token_event = Event(
|
||||||
key=UUID("h2k9j7k8-0l5i-1i7m-5j4k-3k1l2l1k1j1l"),
|
name="authentication_refresher_token_event",
|
||||||
|
key="h2k9j7k8-0l5i-1i7m-5j4k-3k1l2l1k1j1l",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Refresh authentication token",
|
description="Refresh authentication token",
|
||||||
)
|
)
|
||||||
authentication_refresher_token_event.endpoint_callable = authentication_refresher_token
|
authentication_refresher_token_event.endpoint_callable = authentication_refresher_token
|
||||||
|
|
||||||
# Forgot Password
|
# Forgot Password
|
||||||
authentication_forgot_password_event = Event(
|
authentication_forgot_password_event = Event(
|
||||||
key=UUID("i3l0k8l9-1m6j-2j8n-6k5l-4l2m3m2l2k2m"),
|
name="authentication_forgot_password_event",
|
||||||
|
key="i3l0k8l9-1m6j-2j8n-6k5l-4l2m3m2l2k2m",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Request password reset",
|
description="Request password reset",
|
||||||
)
|
)
|
||||||
authentication_forgot_password_event.endpoint_callable = authentication_forgot_password
|
authentication_forgot_password_event.endpoint_callable = authentication_forgot_password
|
||||||
|
|
||||||
# Reset Password
|
# Reset Password
|
||||||
authentication_reset_password_event = Event(
|
authentication_reset_password_event = Event(
|
||||||
key=UUID("j4m1l9m0-2n7k-3k9o-7l6m-5m3n4n3m3l3n"),
|
name="authentication_reset_password_event",
|
||||||
|
key="j4m1l9m0-2n7k-3k9o-7l6m-5m3n4n3m3l3n",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Reset user password",
|
description="Reset user password",
|
||||||
)
|
)
|
||||||
authentication_reset_password_event.endpoint_callable = authentication_reset_password
|
authentication_reset_password_event.endpoint_callable = authentication_reset_password
|
||||||
|
|
||||||
# Download Avatar
|
# Download Avatar
|
||||||
authentication_download_avatar_event = Event(
|
authentication_download_avatar_event = Event(
|
||||||
key=UUID("k5n2m0n1-3o8l-4l0p-8m7n-6n4o5o4n4m4o"),
|
name="authentication_download_avatar_event",
|
||||||
|
key="k5n2m0n1-3o8l-4l0p-8m7n-6n4o5o4n4m4o",
|
||||||
request_validator=None, # TODO: Add request validator
|
request_validator=None, # TODO: Add request validator
|
||||||
response_validator=None, # TODO: Add response validator
|
# response_validator=None, # TODO: Add response validator
|
||||||
description="Download user avatar and profile info",
|
description="Download user avatar and profile info",
|
||||||
)
|
)
|
||||||
authentication_download_avatar_event.endpoint_callable = authentication_download_avatar
|
authentication_download_avatar_event.endpoint_callable = authentication_download_avatar
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue