amsdal 0.2.5__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of amsdal might be problematic. Click here for more details.
- amsdal/Third-Party Materials - AMSDAL Dependencies - License Notices.md +1308 -0
- amsdal/__about__.py +4 -0
- amsdal/__about__.pyi +1 -0
- amsdal/__init__.py +3 -0
- amsdal/__init__.pyi +0 -0
- amsdal/__migrations__/0000_initial.py +203 -0
- amsdal/__migrations__/0001_datetime_type.py +18 -0
- amsdal/__migrations__/0002_fixture_order.py +40 -0
- amsdal/cloud/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/__init__.pyi +0 -0
- amsdal/cloud/client.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/client.pyi +57 -0
- amsdal/cloud/constants.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/constants.pyi +13 -0
- amsdal/cloud/enums.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/enums.pyi +68 -0
- amsdal/cloud/models/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/models/__init__.pyi +0 -0
- amsdal/cloud/models/base.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/models/base.pyi +247 -0
- amsdal/cloud/services/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/__init__.pyi +0 -0
- amsdal/cloud/services/actions/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/__init__.pyi +0 -0
- amsdal/cloud/services/actions/add_allowlist_ip.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/add_allowlist_ip.pyi +19 -0
- amsdal/cloud/services/actions/add_basic_auth.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/add_basic_auth.pyi +21 -0
- amsdal/cloud/services/actions/add_dependency.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/add_dependency.pyi +19 -0
- amsdal/cloud/services/actions/add_secret.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/add_secret.pyi +20 -0
- amsdal/cloud/services/actions/base.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/base.pyi +122 -0
- amsdal/cloud/services/actions/create_deploy.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/create_deploy.pyi +41 -0
- amsdal/cloud/services/actions/create_env.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/create_env.pyi +19 -0
- amsdal/cloud/services/actions/create_session.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/create_session.pyi +17 -0
- amsdal/cloud/services/actions/delete_allowlist_ip.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/delete_allowlist_ip.pyi +19 -0
- amsdal/cloud/services/actions/delete_basic_auth.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/delete_basic_auth.pyi +20 -0
- amsdal/cloud/services/actions/delete_dependency.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/delete_dependency.pyi +21 -0
- amsdal/cloud/services/actions/delete_env.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/delete_env.pyi +21 -0
- amsdal/cloud/services/actions/delete_secret.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/delete_secret.pyi +21 -0
- amsdal/cloud/services/actions/destroy_deploy.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/destroy_deploy.pyi +18 -0
- amsdal/cloud/services/actions/expose_db.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/expose_db.pyi +22 -0
- amsdal/cloud/services/actions/get_basic_auth_credentials.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/get_basic_auth_credentials.pyi +21 -0
- amsdal/cloud/services/actions/get_monitoring_info.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/get_monitoring_info.pyi +21 -0
- amsdal/cloud/services/actions/list_dependencies.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/list_dependencies.pyi +21 -0
- amsdal/cloud/services/actions/list_deploys.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/list_deploys.pyi +19 -0
- amsdal/cloud/services/actions/list_envs.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/list_envs.pyi +20 -0
- amsdal/cloud/services/actions/list_secrets.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/list_secrets.pyi +22 -0
- amsdal/cloud/services/actions/manager.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/manager.pyi +278 -0
- amsdal/cloud/services/actions/signup_action.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/signup_action.pyi +20 -0
- amsdal/cloud/services/actions/update_deploy.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/actions/update_deploy.pyi +19 -0
- amsdal/cloud/services/auth/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/auth/__init__.pyi +0 -0
- amsdal/cloud/services/auth/base.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/auth/base.pyi +6 -0
- amsdal/cloud/services/auth/credentials.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/auth/credentials.pyi +31 -0
- amsdal/cloud/services/auth/manager.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/auth/manager.pyi +26 -0
- amsdal/cloud/services/auth/signup_service.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/auth/signup_service.pyi +32 -0
- amsdal/cloud/services/auth/token.cp312-win_amd64.pyd +0 -0
- amsdal/cloud/services/auth/token.pyi +28 -0
- amsdal/configs/__init__.py +0 -0
- amsdal/configs/__init__.pyi +0 -0
- amsdal/configs/constants.py +33 -0
- amsdal/configs/constants.pyi +22 -0
- amsdal/configs/main.py +254 -0
- amsdal/configs/main.pyi +177 -0
- amsdal/context/__init__.py +0 -0
- amsdal/context/__init__.pyi +0 -0
- amsdal/context/manager.py +69 -0
- amsdal/context/manager.pyi +50 -0
- amsdal/contrib/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/contrib/__init__.pyi +0 -0
- amsdal/contrib/app_config.py +7 -0
- amsdal/contrib/app_config.pyi +6 -0
- amsdal/contrib/auth/__init__.py +0 -0
- amsdal/contrib/auth/__init__.pyi +0 -0
- amsdal/contrib/auth/app.py +27 -0
- amsdal/contrib/auth/app.pyi +15 -0
- amsdal/contrib/auth/decorators/__init__.py +20 -0
- amsdal/contrib/auth/decorators/__init__.pyi +6 -0
- amsdal/contrib/auth/errors.py +7 -0
- amsdal/contrib/auth/errors.pyi +4 -0
- amsdal/contrib/auth/lifecycle/__init__.py +0 -0
- amsdal/contrib/auth/lifecycle/__init__.pyi +0 -0
- amsdal/contrib/auth/lifecycle/consumer.py +222 -0
- amsdal/contrib/auth/lifecycle/consumer.pyi +69 -0
- amsdal/contrib/auth/migrations/0000_initial.py +49 -0
- amsdal/contrib/auth/models/login_session/hooks/pre_init.py +64 -0
- amsdal/contrib/auth/models/login_session/model.json +23 -0
- amsdal/contrib/auth/models/login_session/modifiers/display_name.py +11 -0
- amsdal/contrib/auth/models/permission/fixtures/basic_permissions.json +62 -0
- amsdal/contrib/auth/models/permission/model.json +18 -0
- amsdal/contrib/auth/models/permission/modifiers/display_name.py +11 -0
- amsdal/contrib/auth/models/user/hooks/post_init.py +58 -0
- amsdal/contrib/auth/models/user/hooks/pre_create.py +8 -0
- amsdal/contrib/auth/models/user/model.json +25 -0
- amsdal/contrib/auth/models/user/modifiers/display_name.py +19 -0
- amsdal/contrib/auth/settings.py +36 -0
- amsdal/contrib/auth/settings.pyi +26 -0
- amsdal/contrib/frontend_configs/__init__.py +0 -0
- amsdal/contrib/frontend_configs/__init__.pyi +0 -0
- amsdal/contrib/frontend_configs/app.py +24 -0
- amsdal/contrib/frontend_configs/app.pyi +19 -0
- amsdal/contrib/frontend_configs/constants.py +1 -0
- amsdal/contrib/frontend_configs/constants.pyi +1 -0
- amsdal/contrib/frontend_configs/conversion/__init__.py +5 -0
- amsdal/contrib/frontend_configs/conversion/__init__.pyi +3 -0
- amsdal/contrib/frontend_configs/conversion/convert.py +250 -0
- amsdal/contrib/frontend_configs/conversion/convert.pyi +23 -0
- amsdal/contrib/frontend_configs/lifecycle/__init__.py +0 -0
- amsdal/contrib/frontend_configs/lifecycle/__init__.pyi +0 -0
- amsdal/contrib/frontend_configs/lifecycle/consumer.py +242 -0
- amsdal/contrib/frontend_configs/lifecycle/consumer.pyi +86 -0
- amsdal/contrib/frontend_configs/migrations/0000_initial.py +255 -0
- amsdal/contrib/frontend_configs/models/frontend_activator_config/model.json +11 -0
- amsdal/contrib/frontend_configs/models/frontend_config_async_validator/model.json +11 -0
- amsdal/contrib/frontend_configs/models/frontend_config_group_validator/model.json +52 -0
- amsdal/contrib/frontend_configs/models/frontend_config_option/model.json +15 -0
- amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base/model.json +6 -0
- amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base/properties/model_dump.py +13 -0
- amsdal/contrib/frontend_configs/models/frontend_config_slider_option/model.json +19 -0
- amsdal/contrib/frontend_configs/models/frontend_config_text_mask/model.json +26 -0
- amsdal/contrib/frontend_configs/models/frontend_config_validator/model.json +41 -0
- amsdal/contrib/frontend_configs/models/frontend_control_config/model.json +250 -0
- amsdal/contrib/frontend_configs/models/frontend_model_config/fixtures/permissions.json +24 -0
- amsdal/contrib/frontend_configs/models/frontend_model_config/model.json +17 -0
- amsdal/contrib/frontend_configs/models/frontent_config_control_action/model.json +54 -0
- amsdal/contrib/frontend_configs/models/frontent_config_control_action/properties/action_validate.py +33 -0
- amsdal/contrib/frontend_configs/utils.py +29 -0
- amsdal/contrib/frontend_configs/utils.pyi +17 -0
- amsdal/errors.py +31 -0
- amsdal/errors.pyi +12 -0
- amsdal/fixtures/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/fixtures/__init__.pyi +0 -0
- amsdal/fixtures/manager.cp312-win_amd64.pyd +0 -0
- amsdal/fixtures/manager.pyi +118 -0
- amsdal/manager.cp312-win_amd64.pyd +0 -0
- amsdal/manager.pyi +183 -0
- amsdal/migration/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/migration/__init__.pyi +0 -0
- amsdal/migration/base_migration_schemas.cp312-win_amd64.pyd +0 -0
- amsdal/migration/base_migration_schemas.pyi +120 -0
- amsdal/migration/data_classes.cp312-win_amd64.pyd +0 -0
- amsdal/migration/data_classes.pyi +178 -0
- amsdal/migration/executors/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/migration/executors/__init__.pyi +0 -0
- amsdal/migration/executors/base.cp312-win_amd64.pyd +0 -0
- amsdal/migration/executors/base.pyi +106 -0
- amsdal/migration/executors/default_executor.cp312-win_amd64.pyd +0 -0
- amsdal/migration/executors/default_executor.pyi +96 -0
- amsdal/migration/executors/state_executor.cp312-win_amd64.pyd +0 -0
- amsdal/migration/executors/state_executor.pyi +78 -0
- amsdal/migration/file_migration_executor.cp312-win_amd64.pyd +0 -0
- amsdal/migration/file_migration_executor.pyi +68 -0
- amsdal/migration/file_migration_generator.cp312-win_amd64.pyd +0 -0
- amsdal/migration/file_migration_generator.pyi +139 -0
- amsdal/migration/file_migration_store.cp312-win_amd64.pyd +0 -0
- amsdal/migration/file_migration_store.pyi +61 -0
- amsdal/migration/file_migration_writer.cp312-win_amd64.pyd +0 -0
- amsdal/migration/file_migration_writer.pyi +73 -0
- amsdal/migration/migrations.cp312-win_amd64.pyd +0 -0
- amsdal/migration/migrations.pyi +166 -0
- amsdal/migration/migrations_loader.cp312-win_amd64.pyd +0 -0
- amsdal/migration/migrations_loader.pyi +32 -0
- amsdal/migration/schemas_loaders.cp312-win_amd64.pyd +0 -0
- amsdal/migration/schemas_loaders.pyi +37 -0
- amsdal/migration/templates/data_migration.tmpl +18 -0
- amsdal/migration/templates/dict_validator.tmpl +4 -0
- amsdal/migration/templates/migration.tmpl +6 -0
- amsdal/migration/templates/model_class.tmpl +8 -0
- amsdal/migration/templates/model_class_layout.tmpl +24 -0
- amsdal/migration/templates/options_validator.tmpl +4 -0
- amsdal/migration/utils.cp312-win_amd64.pyd +0 -0
- amsdal/migration/utils.pyi +58 -0
- amsdal/mixins/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/mixins/__init__.pyi +0 -0
- amsdal/mixins/build_mixin.cp312-win_amd64.pyd +0 -0
- amsdal/mixins/build_mixin.pyi +78 -0
- amsdal/mixins/class_versions_mixin.cp312-win_amd64.pyd +0 -0
- amsdal/mixins/class_versions_mixin.pyi +6 -0
- amsdal/py.typed +0 -0
- amsdal/schemas/__init__.py +0 -0
- amsdal/schemas/__init__.pyi +0 -0
- amsdal/schemas/core/class_object/model.json +31 -0
- amsdal/schemas/core/class_object/properties/display_name.py +9 -0
- amsdal/schemas/core/class_object_meta/model.json +55 -0
- amsdal/schemas/core/class_property/model.json +22 -0
- amsdal/schemas/core/class_property_meta/model.json +23 -0
- amsdal/schemas/core/file/hooks/pre_create.py +11 -0
- amsdal/schemas/core/file/hooks/pre_update.py +11 -0
- amsdal/schemas/core/file/model.json +23 -0
- amsdal/schemas/core/file/properties/from_file.py +34 -0
- amsdal/schemas/core/file/properties/mimetype.py +13 -0
- amsdal/schemas/core/file/properties/str.py +6 -0
- amsdal/schemas/core/file/properties/to_file.py +24 -0
- amsdal/schemas/core/file/properties/validate_data.py +32 -0
- amsdal/schemas/core/fixture/model.json +35 -0
- amsdal/schemas/core/option/model.json +19 -0
- amsdal/schemas/core/validator/model.json +19 -0
- amsdal/schemas/manager.cp312-win_amd64.pyd +0 -0
- amsdal/schemas/manager.py +116 -0
- amsdal/schemas/manager.pyi +65 -0
- amsdal/schemas/types/anything/model.json +7 -0
- amsdal/schemas/types/array/model.json +7 -0
- amsdal/schemas/types/binary/model.json +7 -0
- amsdal/schemas/types/boolean/model.json +17 -0
- amsdal/schemas/types/date/model.json +7 -0
- amsdal/schemas/types/datetime/model.json +7 -0
- amsdal/schemas/types/dictionary/model.json +8 -0
- amsdal/schemas/types/number/model.json +8 -0
- amsdal/schemas/types/object/model.json +53 -0
- amsdal/schemas/types/string/model.json +8 -0
- amsdal/services/__init__.cp312-win_amd64.pyd +0 -0
- amsdal/services/__init__.pyi +0 -0
- amsdal/services/transaction_execution.cp312-win_amd64.pyd +0 -0
- amsdal/services/transaction_execution.pyi +76 -0
- amsdal/utils/__init__.py +0 -0
- amsdal/utils/__init__.pyi +0 -0
- amsdal/utils/contrib_paths.py +23 -0
- amsdal/utils/contrib_paths.pyi +14 -0
- amsdal/utils/tests/__init__.py +0 -0
- amsdal/utils/tests/enums.py +18 -0
- amsdal/utils/tests/factories.py +49 -0
- amsdal/utils/tests/helpers.py +309 -0
- amsdal-0.2.5.dist-info/LICENSE.txt +107 -0
- amsdal-0.2.5.dist-info/METADATA +366 -0
- amsdal-0.2.5.dist-info/RECORD +254 -0
- amsdal-0.2.5.dist-info/WHEEL +5 -0
- amsdal-0.2.5.dist-info/license_check.py +35 -0
- amsdal-0.2.5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def post_init(self, *, is_new_object: bool, kwargs: dict[str, Any]) -> None: # type: ignore[no-untyped-def]
|
|
5
|
+
"""
|
|
6
|
+
Post-initializes a user object by validating email and password, and hashing the password.
|
|
7
|
+
|
|
8
|
+
This method checks if the email and password are provided and valid. If the object is new,
|
|
9
|
+
it hashes the password and sets the object ID to the lowercased email.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
is_new_object (bool): Indicates if the object is new.
|
|
13
|
+
kwargs (dict[str, Any]): The keyword arguments containing user details.
|
|
14
|
+
|
|
15
|
+
Raises:
|
|
16
|
+
UserCreationError: If the email or password is invalid.
|
|
17
|
+
"""
|
|
18
|
+
import bcrypt
|
|
19
|
+
|
|
20
|
+
from amsdal.contrib.auth.errors import UserCreationError
|
|
21
|
+
|
|
22
|
+
email = kwargs.get('email', None)
|
|
23
|
+
password = kwargs.get('password', None)
|
|
24
|
+
|
|
25
|
+
if email is None or email == '':
|
|
26
|
+
msg = "Email can't be empty"
|
|
27
|
+
raise UserCreationError(msg)
|
|
28
|
+
|
|
29
|
+
if password is None or password == '':
|
|
30
|
+
msg = "Password can't be empty"
|
|
31
|
+
raise UserCreationError(msg)
|
|
32
|
+
|
|
33
|
+
kwargs['email'] = email.lower()
|
|
34
|
+
|
|
35
|
+
if is_new_object and '_metadata' not in kwargs:
|
|
36
|
+
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
|
|
37
|
+
self.password = hashed_password
|
|
38
|
+
self._object_id = email.lower()
|
|
39
|
+
self.get_metadata().address.object_id = self._object_id
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def pre_update(self) -> None: # type: ignore[no-untyped-def]
|
|
43
|
+
import bcrypt
|
|
44
|
+
|
|
45
|
+
original_object = self.refetch_from_db()
|
|
46
|
+
|
|
47
|
+
password = self.password
|
|
48
|
+
|
|
49
|
+
if original_object.password and password is not None:
|
|
50
|
+
if isinstance(password, str):
|
|
51
|
+
password = password.encode('utf-8')
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
if not bcrypt.checkpw(password, original_object.password):
|
|
55
|
+
self.password = password
|
|
56
|
+
except ValueError:
|
|
57
|
+
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
|
|
58
|
+
self.password = hashed_password
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "User",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"properties": {
|
|
5
|
+
"email": {
|
|
6
|
+
"title": "Email",
|
|
7
|
+
"type": "string"
|
|
8
|
+
},
|
|
9
|
+
"password": {
|
|
10
|
+
"title": "Password (hash)",
|
|
11
|
+
"type": "binary"
|
|
12
|
+
},
|
|
13
|
+
"permissions": {
|
|
14
|
+
"title": "Permissions",
|
|
15
|
+
"type": "array",
|
|
16
|
+
"items": {
|
|
17
|
+
"type": "Permission"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": [
|
|
22
|
+
"email",
|
|
23
|
+
"password"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
@property # type: ignore[misc]
|
|
2
|
+
def display_name(self) -> str: # type: ignore[no-untyped-def]
|
|
3
|
+
"""
|
|
4
|
+
Returns the display name of the user.
|
|
5
|
+
|
|
6
|
+
This method returns the email of the user as their display name.
|
|
7
|
+
|
|
8
|
+
Returns:
|
|
9
|
+
str: The email of the user.
|
|
10
|
+
"""
|
|
11
|
+
return self.email
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def __str__(self) -> str: # type: ignore[no-untyped-def] # noqa: N807
|
|
15
|
+
return f'User(email={self.email})'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def __repr__(self) -> str: # type: ignore[no-untyped-def] # noqa: N807
|
|
19
|
+
return str(self)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from pydantic_settings import BaseSettings
|
|
2
|
+
from pydantic_settings import SettingsConfigDict
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Settings(BaseSettings):
|
|
6
|
+
"""
|
|
7
|
+
Settings configuration for the application.
|
|
8
|
+
|
|
9
|
+
This class uses Pydantic's BaseSettings to manage application settings
|
|
10
|
+
from environment variables and a .env file.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
model_config (SettingsConfigDict): Configuration for Pydantic settings.
|
|
14
|
+
ADMIN_USER_EMAIL (str | None): The email of the admin user.
|
|
15
|
+
ADMIN_USER_PASSWORD (str | None): The password of the admin user.
|
|
16
|
+
AUTH_JWT_KEY (str | None): The key used for JWT authentication.
|
|
17
|
+
AUTH_TOKEN_EXPIRATION (int): The expiration time for authentication tokens in seconds.
|
|
18
|
+
REQUIRE_DEFAULT_AUTHORIZATION (bool): Flag to require default authorization.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
model_config = SettingsConfigDict(
|
|
22
|
+
case_sensitive=True,
|
|
23
|
+
env_prefix='AMSDAL_',
|
|
24
|
+
env_file='.env',
|
|
25
|
+
env_file_encoding='utf-8',
|
|
26
|
+
extra='ignore',
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
ADMIN_USER_EMAIL: str | None = None
|
|
30
|
+
ADMIN_USER_PASSWORD: str | None = None
|
|
31
|
+
AUTH_JWT_KEY: str | None = None
|
|
32
|
+
AUTH_TOKEN_EXPIRATION: int = 86400
|
|
33
|
+
REQUIRE_DEFAULT_AUTHORIZATION: bool = True
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
auth_settings = Settings()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from pydantic_settings import BaseSettings
|
|
3
|
+
|
|
4
|
+
class Settings(BaseSettings):
|
|
5
|
+
"""
|
|
6
|
+
Settings configuration for the application.
|
|
7
|
+
|
|
8
|
+
This class uses Pydantic's BaseSettings to manage application settings
|
|
9
|
+
from environment variables and a .env file.
|
|
10
|
+
|
|
11
|
+
Attributes:
|
|
12
|
+
model_config (SettingsConfigDict): Configuration for Pydantic settings.
|
|
13
|
+
ADMIN_USER_EMAIL (str | None): The email of the admin user.
|
|
14
|
+
ADMIN_USER_PASSWORD (str | None): The password of the admin user.
|
|
15
|
+
AUTH_JWT_KEY (str | None): The key used for JWT authentication.
|
|
16
|
+
AUTH_TOKEN_EXPIRATION (int): The expiration time for authentication tokens in seconds.
|
|
17
|
+
REQUIRE_DEFAULT_AUTHORIZATION (bool): Flag to require default authorization.
|
|
18
|
+
"""
|
|
19
|
+
model_config: Incomplete
|
|
20
|
+
ADMIN_USER_EMAIL: str | None
|
|
21
|
+
ADMIN_USER_PASSWORD: str | None
|
|
22
|
+
AUTH_JWT_KEY: str | None
|
|
23
|
+
AUTH_TOKEN_EXPIRATION: int
|
|
24
|
+
REQUIRE_DEFAULT_AUTHORIZATION: bool
|
|
25
|
+
|
|
26
|
+
auth_settings: Incomplete
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from amsdal_utils.lifecycle.producer import LifecycleProducer
|
|
2
|
+
|
|
3
|
+
from amsdal.contrib.app_config import AppConfig
|
|
4
|
+
from amsdal.contrib.frontend_configs.constants import ON_RESPONSE_EVENT
|
|
5
|
+
from amsdal.contrib.frontend_configs.lifecycle.consumer import ProcessResponseConsumer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FrontendConfigAppConfig(AppConfig):
|
|
9
|
+
"""
|
|
10
|
+
Application configuration class for frontend configurations.
|
|
11
|
+
|
|
12
|
+
This class extends the AppConfig and sets up listeners for lifecycle events
|
|
13
|
+
to process frontend configurations.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def on_ready(self) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Registers a listener for the ON_RESPONSE_EVENT to process responses
|
|
19
|
+
using the ProcessResponseConsumer.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
None
|
|
23
|
+
"""
|
|
24
|
+
LifecycleProducer.add_listener(ON_RESPONSE_EVENT, ProcessResponseConsumer) # type: ignore[arg-type]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from amsdal.contrib.app_config import AppConfig as AppConfig
|
|
2
|
+
from amsdal.contrib.frontend_configs.constants import ON_RESPONSE_EVENT as ON_RESPONSE_EVENT
|
|
3
|
+
from amsdal.contrib.frontend_configs.lifecycle.consumer import ProcessResponseConsumer as ProcessResponseConsumer
|
|
4
|
+
|
|
5
|
+
class FrontendConfigAppConfig(AppConfig):
|
|
6
|
+
"""
|
|
7
|
+
Application configuration class for frontend configurations.
|
|
8
|
+
|
|
9
|
+
This class extends the AppConfig and sets up listeners for lifecycle events
|
|
10
|
+
to process frontend configurations.
|
|
11
|
+
"""
|
|
12
|
+
def on_ready(self) -> None:
|
|
13
|
+
"""
|
|
14
|
+
Registers a listener for the ON_RESPONSE_EVENT to process responses
|
|
15
|
+
using the ProcessResponseConsumer.
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
None
|
|
19
|
+
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ON_RESPONSE_EVENT = 'on_response'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ON_RESPONSE_EVENT: str
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from inspect import _empty
|
|
5
|
+
from inspect import signature
|
|
6
|
+
from types import FunctionType
|
|
7
|
+
from types import UnionType
|
|
8
|
+
from typing import Any
|
|
9
|
+
from typing import ClassVar
|
|
10
|
+
from typing import ForwardRef
|
|
11
|
+
from typing import Union
|
|
12
|
+
|
|
13
|
+
from amsdal_models.classes.manager import ClassManager
|
|
14
|
+
from amsdal_models.classes.model import LegacyModel
|
|
15
|
+
from amsdal_models.classes.model import Model
|
|
16
|
+
from amsdal_utils.models.data_models.reference import Reference
|
|
17
|
+
from pydantic import BaseModel
|
|
18
|
+
from pydantic_core import PydanticUndefined
|
|
19
|
+
|
|
20
|
+
from amsdal.schemas.manager import SchemaManager
|
|
21
|
+
|
|
22
|
+
default_types_map = {
|
|
23
|
+
int: 'number',
|
|
24
|
+
float: 'number',
|
|
25
|
+
bool: 'checkbox',
|
|
26
|
+
str: 'text',
|
|
27
|
+
bytes: 'Bytes',
|
|
28
|
+
date: 'date',
|
|
29
|
+
datetime: 'datetime',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _process_union(value: UnionType, *, is_transaction: bool = False) -> dict[str, Any]:
|
|
34
|
+
arg_type = {'required': True}
|
|
35
|
+
for arg in value.__args__:
|
|
36
|
+
if arg is type(None):
|
|
37
|
+
arg_type['required'] = False
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
control = convert_to_frontend_config(arg, is_transaction=is_transaction)
|
|
41
|
+
if control:
|
|
42
|
+
arg_type.update(control)
|
|
43
|
+
|
|
44
|
+
return arg_type
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def convert_to_frontend_config(value: Any, *, is_transaction: bool = False) -> dict[str, Any]:
|
|
48
|
+
"""
|
|
49
|
+
Converts a given value to a frontend configuration dictionary.
|
|
50
|
+
|
|
51
|
+
This function takes a value and converts it into a dictionary that represents
|
|
52
|
+
the configuration for a frontend form control. It handles various types such as
|
|
53
|
+
Union, list, dict, BaseModel, and custom types.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
value (Any): The value to be converted to frontend configuration.
|
|
57
|
+
is_transaction (bool, optional): Indicates if the conversion is for a transaction. Defaults to False.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
dict[str, Any]: A dictionary representing the frontend configuration for the given value.
|
|
61
|
+
"""
|
|
62
|
+
if hasattr(value, '__origin__'):
|
|
63
|
+
origin_class = value.__origin__
|
|
64
|
+
|
|
65
|
+
if origin_class in [ClassVar]:
|
|
66
|
+
return {}
|
|
67
|
+
|
|
68
|
+
if origin_class is Union:
|
|
69
|
+
_union = _process_union(value, is_transaction=is_transaction)
|
|
70
|
+
|
|
71
|
+
if 'entityType' in _union and _union['entityType'] == 'File':
|
|
72
|
+
_union['type'] = 'file'
|
|
73
|
+
del _union['entityType']
|
|
74
|
+
|
|
75
|
+
return _union
|
|
76
|
+
|
|
77
|
+
if origin_class is list:
|
|
78
|
+
return {
|
|
79
|
+
'type': 'array',
|
|
80
|
+
'name': 'array_items',
|
|
81
|
+
'label': 'array_items',
|
|
82
|
+
'control': {
|
|
83
|
+
'name': 'array_items_values',
|
|
84
|
+
'label': 'array_items_values',
|
|
85
|
+
**convert_to_frontend_config(value.__args__[0], is_transaction=is_transaction),
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if origin_class is dict:
|
|
90
|
+
return {
|
|
91
|
+
'type': 'dict',
|
|
92
|
+
'name': 'dict_items',
|
|
93
|
+
'label': 'dict_items',
|
|
94
|
+
'control': {
|
|
95
|
+
'name': 'dict_items_values',
|
|
96
|
+
'label': 'dict_items_values',
|
|
97
|
+
**convert_to_frontend_config(value.__args__[1], is_transaction=is_transaction),
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if isinstance(value, ForwardRef):
|
|
102
|
+
class_name = value.__forward_arg__
|
|
103
|
+
_class = ClassManager().import_class(class_name, ClassManager().resolve_schema_type(class_name))
|
|
104
|
+
|
|
105
|
+
if issubclass(_class, Model):
|
|
106
|
+
return {
|
|
107
|
+
'entityType': value.__forward_arg__,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
value = _class
|
|
111
|
+
|
|
112
|
+
if isinstance(value, UnionType):
|
|
113
|
+
_union = _process_union(value, is_transaction=is_transaction)
|
|
114
|
+
|
|
115
|
+
if 'entityType' in _union and _union['entityType'] == 'File':
|
|
116
|
+
_union['type'] = 'file'
|
|
117
|
+
del _union['entityType']
|
|
118
|
+
|
|
119
|
+
return _union
|
|
120
|
+
|
|
121
|
+
if value in default_types_map:
|
|
122
|
+
return {
|
|
123
|
+
'type': default_types_map[value],
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if value is Any:
|
|
127
|
+
return {
|
|
128
|
+
'type': 'text',
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if isinstance(value, FunctionType):
|
|
132
|
+
function_controls = []
|
|
133
|
+
|
|
134
|
+
while hasattr(value, '__wrapped__'):
|
|
135
|
+
value = value.__wrapped__
|
|
136
|
+
|
|
137
|
+
_signature = signature(value)
|
|
138
|
+
_parameters = _signature.parameters
|
|
139
|
+
|
|
140
|
+
for arg_name in _parameters:
|
|
141
|
+
if arg_name in value.__annotations__:
|
|
142
|
+
arg_type = value.__annotations__[arg_name]
|
|
143
|
+
control = convert_to_frontend_config(
|
|
144
|
+
arg_type,
|
|
145
|
+
is_transaction=True,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if not control:
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
control['name'] = arg_name
|
|
152
|
+
control['label'] = arg_name
|
|
153
|
+
else:
|
|
154
|
+
control = {
|
|
155
|
+
'type': 'text',
|
|
156
|
+
'name': arg_name,
|
|
157
|
+
'label': arg_name,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
control.setdefault('required', True)
|
|
161
|
+
_param = _parameters[arg_name]
|
|
162
|
+
if _param.default is not _empty:
|
|
163
|
+
control['value'] = _param.default
|
|
164
|
+
control['required'] = False
|
|
165
|
+
|
|
166
|
+
function_controls.append(control)
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
'type': 'group',
|
|
170
|
+
'name': value.__name__,
|
|
171
|
+
'label': value.__name__,
|
|
172
|
+
'controls': function_controls,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if issubclass(value, Reference):
|
|
176
|
+
return {
|
|
177
|
+
'type': 'object_latest',
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if is_transaction and issubclass(value, Model):
|
|
181
|
+
if value.__name__ == 'File':
|
|
182
|
+
return {
|
|
183
|
+
'type': 'file',
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
'type': 'object_latest',
|
|
187
|
+
'entityType': value.__name__,
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if issubclass(value, LegacyModel):
|
|
191
|
+
return {}
|
|
192
|
+
|
|
193
|
+
if issubclass(value, BaseModel):
|
|
194
|
+
model_controls = []
|
|
195
|
+
|
|
196
|
+
try:
|
|
197
|
+
schema = SchemaManager().get_schema_by_name(value.__name__)
|
|
198
|
+
except FileNotFoundError:
|
|
199
|
+
schema = None
|
|
200
|
+
|
|
201
|
+
for field_name, field in value.__annotations__.items():
|
|
202
|
+
control = convert_to_frontend_config(field, is_transaction=is_transaction)
|
|
203
|
+
|
|
204
|
+
if not control:
|
|
205
|
+
continue
|
|
206
|
+
|
|
207
|
+
control.setdefault('required', True)
|
|
208
|
+
|
|
209
|
+
if field_name in value.model_fields:
|
|
210
|
+
_field = value.model_fields[field_name]
|
|
211
|
+
|
|
212
|
+
if _field.default is not PydanticUndefined:
|
|
213
|
+
control['value'] = _field.default
|
|
214
|
+
|
|
215
|
+
control['name'] = field_name
|
|
216
|
+
control['label'] = field_name
|
|
217
|
+
|
|
218
|
+
if schema and schema.properties and field_name in schema.properties:
|
|
219
|
+
schema_property = schema.properties[field_name]
|
|
220
|
+
|
|
221
|
+
if schema_property.options:
|
|
222
|
+
control['options'] = [
|
|
223
|
+
{
|
|
224
|
+
'label': option.key,
|
|
225
|
+
'value': option.value,
|
|
226
|
+
}
|
|
227
|
+
for option in schema_property.options
|
|
228
|
+
]
|
|
229
|
+
if control.get('type') == 'text':
|
|
230
|
+
control['type'] = 'select'
|
|
231
|
+
|
|
232
|
+
if schema_property.title:
|
|
233
|
+
control['label'] = schema_property.title
|
|
234
|
+
|
|
235
|
+
model_controls.append(control)
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
'type': 'group',
|
|
239
|
+
'name': value.__name__,
|
|
240
|
+
'label': value.__name__,
|
|
241
|
+
'controls': model_controls,
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if issubclass(value, Enum):
|
|
245
|
+
return {
|
|
246
|
+
'type': 'select',
|
|
247
|
+
'options': [{'label': option.name, 'value': option.value} for option in value],
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return {}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from amsdal.schemas.manager import SchemaManager as SchemaManager
|
|
3
|
+
from types import UnionType
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
default_types_map: Incomplete
|
|
7
|
+
|
|
8
|
+
def _process_union(value: UnionType, *, is_transaction: bool = False) -> dict[str, Any]: ...
|
|
9
|
+
def convert_to_frontend_config(value: Any, *, is_transaction: bool = False) -> dict[str, Any]:
|
|
10
|
+
"""
|
|
11
|
+
Converts a given value to a frontend configuration dictionary.
|
|
12
|
+
|
|
13
|
+
This function takes a value and converts it into a dictionary that represents
|
|
14
|
+
the configuration for a frontend form control. It handles various types such as
|
|
15
|
+
Union, list, dict, BaseModel, and custom types.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
value (Any): The value to be converted to frontend configuration.
|
|
19
|
+
is_transaction (bool, optional): Indicates if the conversion is for a transaction. Defaults to False.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
dict[str, Any]: A dictionary representing the frontend configuration for the given value.
|
|
23
|
+
"""
|
|
File without changes
|
|
File without changes
|