amsdal 0.3.3__cp311-cp311-macosx_10_9_universal2.whl → 0.5.29__cp311-cp311-macosx_10_9_universal2.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.
Files changed (244) hide show
  1. amsdal/Third-Party Materials - AMSDAL Dependencies - License Notices.md +56 -2
  2. amsdal/__about__.py +1 -1
  3. amsdal/__init__.py +20 -0
  4. amsdal/__init__.pyi +9 -0
  5. amsdal/__migrations__/0000_initial.py +23 -190
  6. amsdal/__migrations__/0001_create_class_file.py +61 -0
  7. amsdal/__migrations__/0002_create_class_file.py +109 -0
  8. amsdal/__migrations__/0003_update_class_file.py +91 -0
  9. amsdal/__migrations__/0004_update_class_file.py +45 -0
  10. amsdal/cloud/__init__.cpython-311-darwin.so +0 -0
  11. amsdal/cloud/client.cpython-311-darwin.so +0 -0
  12. amsdal/cloud/constants.cpython-311-darwin.so +0 -0
  13. amsdal/cloud/enums.cpython-311-darwin.so +0 -0
  14. amsdal/cloud/models/__init__.cpython-311-darwin.so +0 -0
  15. amsdal/cloud/models/base.cpython-311-darwin.so +0 -0
  16. amsdal/cloud/services/__init__.cpython-311-darwin.so +0 -0
  17. amsdal/cloud/services/actions/__init__.cpython-311-darwin.so +0 -0
  18. amsdal/cloud/services/actions/add_allowlist_ip.cpython-311-darwin.so +0 -0
  19. amsdal/cloud/services/actions/add_basic_auth.cpython-311-darwin.so +0 -0
  20. amsdal/cloud/services/actions/add_dependency.cpython-311-darwin.so +0 -0
  21. amsdal/cloud/services/actions/add_secret.cpython-311-darwin.so +0 -0
  22. amsdal/cloud/services/actions/base.cpython-311-darwin.so +0 -0
  23. amsdal/cloud/services/actions/create_deploy.cpython-311-darwin.so +0 -0
  24. amsdal/cloud/services/actions/create_env.cpython-311-darwin.so +0 -0
  25. amsdal/cloud/services/actions/create_session.cpython-311-darwin.so +0 -0
  26. amsdal/cloud/services/actions/delete_allowlist_ip.cpython-311-darwin.so +0 -0
  27. amsdal/cloud/services/actions/delete_basic_auth.cpython-311-darwin.so +0 -0
  28. amsdal/cloud/services/actions/delete_dependency.cpython-311-darwin.so +0 -0
  29. amsdal/cloud/services/actions/delete_env.cpython-311-darwin.so +0 -0
  30. amsdal/cloud/services/actions/delete_secret.cpython-311-darwin.so +0 -0
  31. amsdal/cloud/services/actions/destroy_deploy.cpython-311-darwin.so +0 -0
  32. amsdal/cloud/services/actions/expose_db.cpython-311-darwin.so +0 -0
  33. amsdal/cloud/services/actions/get_basic_auth_credentials.cpython-311-darwin.so +0 -0
  34. amsdal/cloud/services/actions/get_monitoring_info.cpython-311-darwin.so +0 -0
  35. amsdal/cloud/services/actions/list_dependencies.cpython-311-darwin.so +0 -0
  36. amsdal/cloud/services/actions/list_deploys.cpython-311-darwin.so +0 -0
  37. amsdal/cloud/services/actions/list_envs.cpython-311-darwin.so +0 -0
  38. amsdal/cloud/services/actions/list_secrets.cpython-311-darwin.so +0 -0
  39. amsdal/cloud/services/actions/manager.cpython-311-darwin.so +0 -0
  40. amsdal/cloud/services/actions/signup_action.cpython-311-darwin.so +0 -0
  41. amsdal/cloud/services/actions/update_deploy.cpython-311-darwin.so +0 -0
  42. amsdal/cloud/services/auth/__init__.cpython-311-darwin.so +0 -0
  43. amsdal/cloud/services/auth/base.cpython-311-darwin.so +0 -0
  44. amsdal/cloud/services/auth/credentials.cpython-311-darwin.so +0 -0
  45. amsdal/cloud/services/auth/credentials.pyi +0 -1
  46. amsdal/cloud/services/auth/manager.cpython-311-darwin.so +0 -0
  47. amsdal/cloud/services/auth/signup_service.cpython-311-darwin.so +0 -0
  48. amsdal/cloud/services/auth/token.cpython-311-darwin.so +0 -0
  49. amsdal/cloud/services/auth/token.pyi +0 -1
  50. amsdal/configs/main.py +40 -20
  51. amsdal/configs/main.pyi +19 -18
  52. amsdal/contrib/__init__.cpython-311-darwin.so +0 -0
  53. amsdal/contrib/auth/errors.py +36 -0
  54. amsdal/contrib/auth/errors.pyi +12 -0
  55. amsdal/contrib/auth/fixtures/basic_permissions.json +64 -0
  56. amsdal/contrib/auth/lifecycle/consumer.py +13 -13
  57. amsdal/contrib/auth/lifecycle/consumer.pyi +3 -0
  58. amsdal/contrib/auth/migrations/0000_initial.py +69 -31
  59. amsdal/contrib/auth/migrations/0001_add_mfa_support.py +188 -0
  60. amsdal/contrib/auth/models/__init__.py +1 -0
  61. amsdal/contrib/auth/models/backup_code.py +85 -0
  62. amsdal/contrib/auth/models/email_mfa_device.py +108 -0
  63. amsdal/contrib/auth/models/login_session.py +235 -0
  64. amsdal/contrib/auth/models/mfa_device.py +86 -0
  65. amsdal/contrib/auth/models/permission.py +23 -0
  66. amsdal/contrib/auth/models/sms_device.py +113 -0
  67. amsdal/contrib/auth/models/totp_device.py +58 -0
  68. amsdal/contrib/auth/models/user.py +156 -0
  69. amsdal/contrib/auth/services/__init__.py +1 -0
  70. amsdal/contrib/auth/services/mfa_device_service.py +544 -0
  71. amsdal/contrib/auth/services/mfa_device_service.pyi +216 -0
  72. amsdal/contrib/auth/services/totp_service.py +358 -0
  73. amsdal/contrib/auth/services/totp_service.pyi +158 -0
  74. amsdal/contrib/auth/settings.py +8 -0
  75. amsdal/contrib/auth/settings.pyi +8 -0
  76. amsdal/contrib/auth/transactions/__init__.py +1 -0
  77. amsdal/contrib/auth/transactions/mfa_device_transactions.py +463 -0
  78. amsdal/contrib/auth/transactions/mfa_device_transactions.pyi +226 -0
  79. amsdal/contrib/auth/transactions/totp_transactions.py +206 -0
  80. amsdal/contrib/auth/transactions/totp_transactions.pyi +113 -0
  81. amsdal/contrib/auth/utils/__init__.py +0 -0
  82. amsdal/contrib/auth/utils/__init__.pyi +0 -0
  83. amsdal/contrib/auth/utils/mfa.py +257 -0
  84. amsdal/contrib/auth/utils/mfa.pyi +119 -0
  85. amsdal/contrib/frontend_configs/conversion/convert.py +85 -25
  86. amsdal/contrib/frontend_configs/conversion/convert.pyi +0 -1
  87. amsdal/contrib/frontend_configs/lifecycle/consumer.py +32 -13
  88. amsdal/contrib/frontend_configs/lifecycle/consumer.pyi +1 -1
  89. amsdal/contrib/frontend_configs/migrations/0000_initial.py +167 -195
  90. amsdal/contrib/frontend_configs/migrations/0001_update_frontend_control_config.py +245 -0
  91. amsdal/contrib/frontend_configs/migrations/0002_add_button_and_invoke_actions.py +352 -0
  92. amsdal/contrib/frontend_configs/migrations/0003_create_class_frontendconfigdashboardelement.py +145 -0
  93. amsdal/contrib/frontend_configs/models/__init__.py +0 -0
  94. amsdal/contrib/frontend_configs/models/frontend_activator_config.py +22 -0
  95. amsdal/contrib/frontend_configs/models/frontend_config_async_validator.py +11 -0
  96. amsdal/contrib/frontend_configs/models/frontend_config_control_action.py +110 -0
  97. amsdal/contrib/frontend_configs/models/frontend_config_dashboard.py +51 -0
  98. amsdal/contrib/frontend_configs/models/frontend_config_group_validator.py +21 -0
  99. amsdal/contrib/frontend_configs/models/frontend_config_option.py +12 -0
  100. amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base.py +17 -0
  101. amsdal/contrib/frontend_configs/models/frontend_config_slider_option.py +13 -0
  102. amsdal/contrib/frontend_configs/models/frontend_config_text_mask.py +14 -0
  103. amsdal/contrib/frontend_configs/models/frontend_config_validator.py +28 -0
  104. amsdal/contrib/frontend_configs/models/frontend_control_config.py +110 -0
  105. amsdal/contrib/frontend_configs/models/frontend_model_config.py +14 -0
  106. amsdal/errors.py +0 -3
  107. amsdal/errors.pyi +0 -1
  108. amsdal/fixtures/__init__.cpython-311-darwin.so +0 -0
  109. amsdal/fixtures/manager.cpython-311-darwin.so +0 -0
  110. amsdal/fixtures/manager.pyi +73 -123
  111. amsdal/fixtures/utils.cpython-311-darwin.so +0 -0
  112. amsdal/fixtures/utils.pyi +9 -0
  113. amsdal/manager.cpython-311-darwin.so +0 -0
  114. amsdal/manager.pyi +9 -96
  115. amsdal/mixins/__init__.cpython-311-darwin.so +0 -0
  116. amsdal/mixins/class_versions_mixin.cpython-311-darwin.so +0 -0
  117. amsdal/models/__init__.py +19 -0
  118. amsdal/models/core/__init__.py +0 -0
  119. amsdal/models/core/class_object.py +38 -0
  120. amsdal/models/core/class_property.py +26 -0
  121. amsdal/models/core/file.py +243 -0
  122. amsdal/models/core/fixture.py +25 -0
  123. amsdal/models/core/option.py +11 -0
  124. amsdal/models/core/storage_metadata.py +15 -0
  125. amsdal/models/core/validator.py +12 -0
  126. amsdal/models/mixins.py +31 -0
  127. amsdal/models/types/__init__.py +0 -0
  128. amsdal/models/types/object.py +26 -0
  129. amsdal/queryset/__init__.py +21 -0
  130. amsdal/queryset/__init__.pyi +6 -0
  131. amsdal/schemas/core/class_object/model.json +20 -0
  132. amsdal/schemas/core/class_property/model.json +19 -0
  133. amsdal/schemas/core/file/properties/from_file.py +1 -1
  134. amsdal/schemas/core/file/properties/validate_data.py +3 -4
  135. amsdal/schemas/core/storage_metadata/model.json +52 -0
  136. amsdal/schemas/interfaces.py +25 -0
  137. amsdal/schemas/interfaces.pyi +20 -0
  138. amsdal/schemas/manager.cpython-311-darwin.so +0 -0
  139. amsdal/schemas/manager.py +0 -116
  140. amsdal/schemas/manager.pyi +0 -65
  141. amsdal/schemas/mixins/__init__.py +0 -0
  142. amsdal/schemas/mixins/__init__.pyi +0 -0
  143. amsdal/schemas/mixins/check_dependencies_mixin.py +130 -0
  144. amsdal/schemas/mixins/check_dependencies_mixin.pyi +45 -0
  145. amsdal/schemas/mixins/verify_schemas_mixin.py +96 -0
  146. amsdal/schemas/mixins/verify_schemas_mixin.pyi +33 -0
  147. amsdal/schemas/repository.py +84 -0
  148. amsdal/schemas/repository.pyi +22 -0
  149. amsdal/schemas/utils.py +16 -0
  150. amsdal/schemas/utils.pyi +10 -0
  151. amsdal/services/__init__.py +11 -0
  152. amsdal/services/__init__.pyi +4 -0
  153. amsdal/services/external_connections.py +262 -0
  154. amsdal/services/external_connections.pyi +190 -0
  155. amsdal/services/external_model_generator.py +350 -0
  156. amsdal/services/external_model_generator.pyi +134 -0
  157. amsdal/services/transaction_execution.cpython-311-darwin.so +0 -0
  158. amsdal/services/transaction_execution.pyi +2 -1
  159. amsdal/storages/__init__.py +20 -0
  160. amsdal/storages/__init__.pyi +8 -0
  161. amsdal/storages/file_system.py +214 -0
  162. amsdal/storages/file_system.pyi +36 -0
  163. amsdal/transactions/__init__.py +13 -0
  164. amsdal/transactions/__init__.pyi +4 -0
  165. amsdal/utils/rollback/__init__.py +99 -54
  166. amsdal/utils/rollback/__init__.pyi +6 -0
  167. amsdal/utils/tests/enums.py +0 -2
  168. amsdal/utils/tests/helpers.py +253 -231
  169. amsdal/utils/tests/migrations.py +157 -0
  170. {amsdal-0.3.3.dist-info → amsdal-0.5.29.dist-info}/METADATA +17 -10
  171. amsdal-0.5.29.dist-info/RECORD +276 -0
  172. {amsdal-0.3.3.dist-info → amsdal-0.5.29.dist-info}/WHEEL +1 -1
  173. amsdal/__migrations__/0001_datetime_type.py +0 -18
  174. amsdal/__migrations__/0002_fixture_order.py +0 -40
  175. amsdal/__migrations__/0003_schema_type_in_class_meta.py +0 -56
  176. amsdal/contrib/auth/models/login_session/hooks/pre_init.py +0 -68
  177. amsdal/contrib/auth/models/login_session/model.json +0 -23
  178. amsdal/contrib/auth/models/login_session/modifiers/display_name.py +0 -11
  179. amsdal/contrib/auth/models/permission/fixtures/basic_permissions.json +0 -62
  180. amsdal/contrib/auth/models/permission/model.json +0 -18
  181. amsdal/contrib/auth/models/permission/modifiers/display_name.py +0 -11
  182. amsdal/contrib/auth/models/user/hooks/post_init.py +0 -76
  183. amsdal/contrib/auth/models/user/hooks/pre_create.py +0 -8
  184. amsdal/contrib/auth/models/user/model.json +0 -25
  185. amsdal/contrib/auth/models/user/modifiers/display_name.py +0 -19
  186. amsdal/contrib/frontend_configs/models/frontend_activator_config/model.json +0 -11
  187. amsdal/contrib/frontend_configs/models/frontend_config_async_validator/model.json +0 -11
  188. amsdal/contrib/frontend_configs/models/frontend_config_group_validator/model.json +0 -52
  189. amsdal/contrib/frontend_configs/models/frontend_config_option/model.json +0 -15
  190. amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base/model.json +0 -6
  191. amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base/properties/model_dump.py +0 -13
  192. amsdal/contrib/frontend_configs/models/frontend_config_slider_option/model.json +0 -19
  193. amsdal/contrib/frontend_configs/models/frontend_config_text_mask/model.json +0 -26
  194. amsdal/contrib/frontend_configs/models/frontend_config_validator/model.json +0 -41
  195. amsdal/contrib/frontend_configs/models/frontend_control_config/model.json +0 -250
  196. amsdal/contrib/frontend_configs/models/frontend_model_config/fixtures/permissions.json +0 -24
  197. amsdal/contrib/frontend_configs/models/frontend_model_config/model.json +0 -17
  198. amsdal/contrib/frontend_configs/models/frontent_config_control_action/model.json +0 -54
  199. amsdal/contrib/frontend_configs/models/frontent_config_control_action/properties/action_validate.py +0 -33
  200. amsdal/migration/__init__.cpython-311-darwin.so +0 -0
  201. amsdal/migration/base_migration_schemas.cpython-311-darwin.so +0 -0
  202. amsdal/migration/base_migration_schemas.pyi +0 -120
  203. amsdal/migration/data_classes.cpython-311-darwin.so +0 -0
  204. amsdal/migration/data_classes.pyi +0 -172
  205. amsdal/migration/executors/__init__.cpython-311-darwin.so +0 -0
  206. amsdal/migration/executors/base.cpython-311-darwin.so +0 -0
  207. amsdal/migration/executors/base.pyi +0 -118
  208. amsdal/migration/executors/default_executor.cpython-311-darwin.so +0 -0
  209. amsdal/migration/executors/default_executor.pyi +0 -184
  210. amsdal/migration/executors/state_executor.cpython-311-darwin.so +0 -0
  211. amsdal/migration/executors/state_executor.pyi +0 -78
  212. amsdal/migration/file_migration_executor.cpython-311-darwin.so +0 -0
  213. amsdal/migration/file_migration_executor.pyi +0 -68
  214. amsdal/migration/file_migration_generator.cpython-311-darwin.so +0 -0
  215. amsdal/migration/file_migration_generator.pyi +0 -139
  216. amsdal/migration/file_migration_store.cpython-311-darwin.so +0 -0
  217. amsdal/migration/file_migration_store.pyi +0 -61
  218. amsdal/migration/file_migration_writer.cpython-311-darwin.so +0 -0
  219. amsdal/migration/file_migration_writer.pyi +0 -73
  220. amsdal/migration/migrations.cpython-311-darwin.so +0 -0
  221. amsdal/migration/migrations.pyi +0 -166
  222. amsdal/migration/migrations_loader.cpython-311-darwin.so +0 -0
  223. amsdal/migration/migrations_loader.pyi +0 -32
  224. amsdal/migration/schemas_loaders.cpython-311-darwin.so +0 -0
  225. amsdal/migration/schemas_loaders.pyi +0 -37
  226. amsdal/migration/templates/data_migration.tmpl +0 -18
  227. amsdal/migration/templates/dict_validator.tmpl +0 -4
  228. amsdal/migration/templates/migration.tmpl +0 -6
  229. amsdal/migration/templates/model_class.tmpl +0 -8
  230. amsdal/migration/templates/model_class_layout.tmpl +0 -24
  231. amsdal/migration/templates/options_validator.tmpl +0 -4
  232. amsdal/migration/utils.cpython-311-darwin.so +0 -0
  233. amsdal/migration/utils.pyi +0 -58
  234. amsdal/mixins/build_mixin.cpython-311-darwin.so +0 -0
  235. amsdal/mixins/build_mixin.pyi +0 -78
  236. amsdal/schemas/core/class_object_meta/model.json +0 -59
  237. amsdal/schemas/core/class_property_meta/model.json +0 -23
  238. amsdal/services/__init__.cpython-311-darwin.so +0 -0
  239. amsdal-0.3.3.dist-info/RECORD +0 -257
  240. amsdal-0.3.3.dist-info/licenses/LICENSE.txt +0 -107
  241. /amsdal/{migration → contrib/auth/services}/__init__.pyi +0 -0
  242. /amsdal/{migration/executors → contrib/auth/transactions}/__init__.pyi +0 -0
  243. {amsdal-0.3.3.dist-info → amsdal-0.5.29.dist-info/licenses}/LICENSE.txt +0 -0
  244. {amsdal-0.3.3.dist-info → amsdal-0.5.29.dist-info}/top_level.txt +0 -0
@@ -1,68 +1,55 @@
1
- import os
2
1
  import random
3
2
  import string
4
- import tempfile
3
+ from collections.abc import AsyncGenerator
4
+ from collections.abc import AsyncIterator
5
5
  from collections.abc import Generator
6
6
  from collections.abc import Iterator
7
+ from contextlib import ExitStack
8
+ from contextlib import asynccontextmanager
7
9
  from contextlib import contextmanager
8
- from contextlib import suppress
10
+ from functools import partial
9
11
  from pathlib import Path
10
12
  from typing import Any
11
13
 
12
- import yaml
14
+ from amsdal_data.aliases.db import POSTGRES_HISTORICAL_ALIAS
15
+ from amsdal_data.aliases.db import POSTGRES_HISTORICAL_ASYNC_ALIAS
16
+ from amsdal_data.aliases.db import POSTGRES_STATE_ALIAS
17
+ from amsdal_data.aliases.db import POSTGRES_STATE_ASYNC_ALIAS
18
+ from amsdal_data.aliases.db import SQLITE_ALIAS
19
+ from amsdal_data.aliases.db import SQLITE_ASYNC_ALIAS
20
+ from amsdal_data.aliases.db import SQLITE_HISTORICAL_ALIAS
21
+ from amsdal_data.aliases.db import SQLITE_HISTORICAL_ASYNC_ALIAS
22
+ from amsdal_data.application import AsyncDataApplication
23
+ from amsdal_data.connections.db_alias_map import CONNECTION_BACKEND_ALIASES
24
+ from amsdal_data.connections.historical.schema_version_manager import AsyncHistoricalSchemaVersionManager
25
+ from amsdal_data.connections.historical.schema_version_manager import HistoricalSchemaVersionManager
26
+ from amsdal_data.test_utils.common import temp_dir
27
+ from amsdal_data.test_utils.config import build_config
28
+ from amsdal_data.test_utils.config import postgres_async_config
29
+ from amsdal_data.test_utils.config import postgres_async_lakehouse_only_config
30
+ from amsdal_data.test_utils.config import postgres_config
31
+ from amsdal_data.test_utils.config import postgres_lakehouse_only_config
32
+ from amsdal_data.test_utils.config import sqlite_async_config
33
+ from amsdal_data.test_utils.config import sqlite_async_lakehouse_only_config
34
+ from amsdal_data.test_utils.config import sqlite_config
35
+ from amsdal_data.test_utils.config import sqlite_lakehouse_only_config
36
+ from amsdal_data.test_utils.constants import PG_TEST_HOST
37
+ from amsdal_data.test_utils.constants import PG_TEST_PASSWORD
38
+ from amsdal_data.test_utils.constants import PG_TEST_PORT
39
+ from amsdal_data.test_utils.constants import PG_TEST_USER
40
+ from amsdal_data.test_utils.db import create_postgres_database
41
+ from amsdal_data.test_utils.db import create_postgres_extension
42
+ from amsdal_data.test_utils.db import drop_postgres_database
43
+ from amsdal_utils.config.data_models.amsdal_config import AmsdalConfig
13
44
  from amsdal_utils.config.manager import AmsdalConfigManager
14
- from amsdal_utils.models.enums import SchemaTypes
15
45
 
16
- from amsdal.configs.constants import CORE_MIGRATIONS_PATH
17
- from amsdal.configs.main import settings
18
46
  from amsdal.manager import AmsdalManager
19
- from amsdal.migration import migrations
20
- from amsdal.migration.data_classes import ModuleTypes
21
- from amsdal.migration.executors.default_executor import DefaultMigrationExecutor
22
- from amsdal.migration.file_migration_executor import FileMigrationExecutorManager
23
- from amsdal.migration.file_migration_generator import FileMigrationGenerator
24
- from amsdal.migration.file_migration_writer import FileMigrationWriter
25
- from amsdal.migration.migrations import MigrateData
26
- from amsdal.migration.migrations import MigrationSchemas
27
- from amsdal.migration.migrations_loader import MigrationsLoader
28
- from amsdal.migration.schemas_loaders import JsonClassSchemaLoader
29
- from amsdal.migration.utils import contrib_to_module_root_path
47
+ from amsdal.manager import AsyncAmsdalManager
30
48
  from amsdal.utils.tests.enums import DbExecutionType
31
49
  from amsdal.utils.tests.enums import LakehouseOption
32
50
  from amsdal.utils.tests.enums import StateOption
33
-
34
- TESTS_DIR = Path(os.getcwd())
35
-
36
-
37
- def create_postgres_database(database: str) -> tuple[str, str, str, str]:
38
- import psycopg
39
-
40
- db_host = os.getenv('POSTGRES_HOST', 'localhost')
41
- db_port = os.getenv('POSTGRES_PORT', '5432')
42
- db_user = os.getenv('POSTGRES_USER', 'postgres')
43
- db_password = os.getenv('POSTGRES_PASSWORD', 'example')
44
-
45
- conn = psycopg.connect(
46
- host=db_host,
47
- port=db_port,
48
- user=db_user,
49
- password=db_password,
50
- autocommit=True,
51
- )
52
- cur = conn.cursor()
53
-
54
- with suppress(psycopg.errors.DuplicateDatabase):
55
- cur.execute(f'CREATE DATABASE "{database}"')
56
-
57
- cur.close()
58
- conn.close()
59
-
60
- return (
61
- db_host,
62
- db_port,
63
- db_user,
64
- db_password,
65
- )
51
+ from amsdal.utils.tests.migrations import async_migrate
52
+ from amsdal.utils.tests.migrations import migrate
66
53
 
67
54
 
68
55
  @contextmanager
@@ -85,225 +72,260 @@ def override_settings(**kwargs: Any) -> Iterator[None]:
85
72
  settings.override(**original_settings)
86
73
 
87
74
 
88
- def _get_config_template(
89
- db_execution_type: DbExecutionType,
90
- lakehouse_option: LakehouseOption,
91
- state_option: StateOption,
92
- ) -> str:
93
- config_object: dict[str, Any] = {
94
- 'application_name': 'test_client_app',
95
- 'connections': [
96
- {'name': 'lock', 'backend': 'amsdal_data.lock.implementations.thread_lock.ThreadLock'},
97
- ],
98
- 'resources_config': {'lakehouse': 'lakehouse', 'lock': 'lock', 'repository': {'default': 'state'}},
99
- }
100
- if lakehouse_option in [LakehouseOption.postgres, LakehouseOption.postgres_immutable]:
101
- config_object['connections'].append(
102
- {
103
- 'name': 'lakehouse',
104
- 'backend': 'postgres-historical',
105
- 'credentials': [
106
- {
107
- 'db_host': '{{ db_host }}',
108
- 'db_port': '{{ db_port }}',
109
- 'db_user': '{{ db_user }}',
110
- 'db_password': '{{ db_password }}',
111
- 'db_name': '{{ lakehouse_postgres_db }}',
112
- }
113
- ],
114
- }
115
- )
116
- elif lakehouse_option in [LakehouseOption.sqlite, LakehouseOption.sqlite_immutable]:
117
- config_object['connections'].append(
118
- {
119
- 'name': 'lakehouse',
120
- 'backend': 'sqlite-historical',
121
- 'credentials': [{'db_path': '{{ db_dir }}/sqlite_lakehouse.sqlite3'}],
122
- }
123
- )
124
-
125
- if db_execution_type == DbExecutionType.lakehouse_only:
126
- config_object['resources_config']['repository']['default'] = 'lakehouse'
127
-
128
- return yaml.dump(config_object)
129
-
130
- if state_option == StateOption.postgres:
131
- config_object['connections'].append(
132
- {
133
- 'name': 'state',
134
- 'backend': 'postgres',
135
- 'credentials': [
136
- {
137
- 'db_host': '{{ db_host }}',
138
- 'db_port': '{{ db_port }}',
139
- 'db_user': '{{ db_user }}',
140
- 'db_password': '{{ db_password }}',
141
- 'db_name': '{{ state_postgres_db }}',
142
- }
143
- ],
144
- }
145
- )
146
-
147
- elif state_option == StateOption.sqlite:
148
- config_object['connections'].append(
149
- {
150
- 'name': 'state',
151
- 'backend': 'sqlite',
152
- 'credentials': [{'db_path': '{{ db_dir }}/sqlite_state.sqlite3'}],
153
- }
154
- )
155
-
156
- return yaml.dump(config_object)
157
-
158
-
159
75
  @contextmanager
160
- def init_manager(
76
+ def init_config(
161
77
  db_execution_type: DbExecutionType,
162
78
  lakehouse_option: LakehouseOption,
163
79
  state_option: StateOption,
164
- ) -> Generator[AmsdalManager, Any, None]:
165
- Path('.tmp').mkdir(exist_ok=True)
166
- with tempfile.TemporaryDirectory(dir='.tmp') as temp_dir:
167
- db_dir = Path(temp_dir) / 'db_dir'
168
- (db_dir / 'warehouse').mkdir(exist_ok=True, parents=True)
169
-
80
+ *,
81
+ is_async: bool = False,
82
+ db_name_prefix: str | None = None,
83
+ db_path: Path | None = None,
84
+ drop_database: bool = False,
85
+ ) -> Iterator[AmsdalConfig]:
86
+ if db_name_prefix:
87
+ lakehouse_database = f'{db_name_prefix}_lakehouse'
88
+ state_database = f'{db_name_prefix}_state'
89
+ else:
170
90
  lakehouse_database = ''.join(random.sample(string.ascii_letters, 16))
171
91
  state_database = ''.join(random.sample(string.ascii_letters, 16))
172
- config_text = _get_config_template(db_execution_type, lakehouse_option, state_option)
173
-
174
- if lakehouse_option in [LakehouseOption.postgres, LakehouseOption.postgres_immutable]:
175
- (
176
- db_host,
177
- db_port,
178
- db_user,
179
- db_password,
180
- ) = create_postgres_database(lakehouse_database)
181
-
182
- config_text = (
183
- config_text.replace('{{ db_host }}', db_host)
184
- .replace('{{ db_port }}', db_port)
185
- .replace('{{ db_user }}', db_user)
186
- .replace('{{ db_password }}', db_password)
187
- .replace('{{ lakehouse_postgres_db }}', lakehouse_database)
188
- )
189
- elif lakehouse_option in [LakehouseOption.sqlite, LakehouseOption.sqlite_immutable]:
190
- config_text = config_text.replace('{{ db_dir }}', db_dir.absolute().as_posix())
191
-
192
- if state_option == StateOption.postgres:
193
- create_postgres_database(state_database)
194
- config_text = (
195
- config_text.replace('{{ db_host }}', db_host)
196
- .replace('{{ db_port }}', db_port)
197
- .replace('{{ db_user }}', db_user)
198
- .replace('{{ db_password }}', db_password)
199
- .replace('{{ state_postgres_db }}', state_database)
200
- )
201
- elif state_option == StateOption.sqlite:
202
- config_text = config_text.replace('{{ db_dir }}', db_dir.absolute().as_posix())
203
92
 
204
- config_path = Path(temp_dir) / 'config.yml'
205
- config_path.write_text(config_text)
93
+ if db_execution_type == DbExecutionType.lakehouse_only:
94
+ ctx_managers = {
95
+ LakehouseOption.sqlite: (
96
+ partial(sqlite_async_lakehouse_only_config, db_path)
97
+ if is_async
98
+ else partial(sqlite_lakehouse_only_config, db_path)
99
+ ),
100
+ LakehouseOption.postgres: (
101
+ partial(postgres_async_lakehouse_only_config, lakehouse_database, drop_database=drop_database)
102
+ if is_async
103
+ else partial(postgres_lakehouse_only_config, lakehouse_database, drop_database=drop_database)
104
+ ),
105
+ }
106
+ with ctx_managers[lakehouse_option]() as _amsdal_config:
107
+ yield _amsdal_config
108
+ return
109
+
110
+ if lakehouse_option.value == state_option.value:
111
+ ctx_managers = {
112
+ LakehouseOption.sqlite: (
113
+ partial(
114
+ sqlite_async_config,
115
+ db_path=db_path,
116
+ )
117
+ if is_async
118
+ else partial(sqlite_config, db_path)
119
+ ),
120
+ LakehouseOption.postgres: (
121
+ partial(
122
+ postgres_async_config,
123
+ lakehouse_database=lakehouse_database,
124
+ state_database=state_database,
125
+ drop_database=drop_database,
126
+ )
127
+ if is_async
128
+ else partial(
129
+ postgres_config,
130
+ lakehouse_database=lakehouse_database,
131
+ state_database=state_database,
132
+ drop_database=drop_database,
133
+ )
134
+ ),
135
+ }
206
136
 
207
- with override_settings(APP_PATH=db_dir, CONFIG_PATH=config_path):
208
- config_manager = AmsdalConfigManager()
209
- config_manager.load_config(config_path)
210
- manager = AmsdalManager()
211
- manager.setup()
212
- manager.post_setup() # type: ignore[call-arg]
137
+ with ctx_managers[lakehouse_option]() as _amsdal_config:
138
+ yield _amsdal_config
139
+ return
213
140
 
141
+ with ExitStack() as stack:
142
+ db_path = db_path if db_path else stack.enter_context(temp_dir())
143
+
144
+ if lakehouse_option == LakehouseOption.postgres:
145
+ config = build_config(
146
+ lakehouse_backend=CONNECTION_BACKEND_ALIASES[
147
+ POSTGRES_HISTORICAL_ASYNC_ALIAS if is_async else POSTGRES_HISTORICAL_ALIAS
148
+ ],
149
+ lakehouse_credentials={
150
+ 'dsn': f'postgresql://{PG_TEST_USER}:{PG_TEST_PASSWORD}@{PG_TEST_HOST}:{PG_TEST_PORT}/{lakehouse_database}',
151
+ },
152
+ state_backend=CONNECTION_BACKEND_ALIASES[SQLITE_ASYNC_ALIAS if is_async else SQLITE_ALIAS],
153
+ state_credentials={
154
+ 'db_path': f'{db_path}/amsdal_state.sqlite3',
155
+ },
156
+ is_async_mode=is_async,
157
+ )
158
+ AmsdalConfigManager().set_config(config)
159
+ create_postgres_database(lakehouse_database)
160
+ create_postgres_extension(lakehouse_database, 'vector')
214
161
  try:
215
- yield manager
162
+ yield config
216
163
  finally:
217
- manager.teardown()
218
- AmsdalManager.invalidate()
219
164
  AmsdalConfigManager.invalidate()
220
165
 
166
+ if drop_database:
167
+ drop_postgres_database(lakehouse_database)
168
+ return
169
+
170
+ config = build_config(
171
+ lakehouse_backend=CONNECTION_BACKEND_ALIASES[
172
+ SQLITE_HISTORICAL_ASYNC_ALIAS if is_async else SQLITE_HISTORICAL_ALIAS
173
+ ],
174
+ lakehouse_credentials={
175
+ 'db_path': f'{db_path}/amsdal_historical.sqlite3',
176
+ },
177
+ state_backend=CONNECTION_BACKEND_ALIASES[POSTGRES_STATE_ASYNC_ALIAS if is_async else POSTGRES_STATE_ALIAS],
178
+ state_credentials={
179
+ 'dsn': f'postgresql://{PG_TEST_USER}:{PG_TEST_PASSWORD}@{PG_TEST_HOST}:{PG_TEST_PORT}/{state_database}',
180
+ },
181
+ is_async_mode=True,
182
+ )
183
+ AmsdalConfigManager().set_config(config)
184
+ create_postgres_database(state_database)
185
+ create_postgres_extension(state_database, 'vector')
221
186
 
222
- def _migrate_per_loader(executor: DefaultMigrationExecutor, loader: MigrationsLoader) -> None:
223
- for _migration in loader:
224
- migration_class = FileMigrationExecutorManager.get_migration_class(_migration)
225
- migration_class_instance = migration_class()
226
-
227
- for _operation in migration_class_instance.operations:
228
- if isinstance(_operation, MigrateData):
229
- executor.flush_buffer()
230
-
231
- _operation.forward(executor)
232
-
233
- executor.flush_buffer()
187
+ try:
188
+ yield config
189
+ finally:
190
+ AmsdalConfigManager.invalidate()
234
191
 
192
+ if drop_database:
193
+ drop_postgres_database(state_database)
235
194
 
236
- def migrate(app_schemas_path: Path) -> None:
237
- schemas = MigrationSchemas()
238
- executor = DefaultMigrationExecutor(schemas)
239
- _migrate_per_loader(
240
- executor,
241
- MigrationsLoader(
242
- migrations_dir=CORE_MIGRATIONS_PATH,
243
- module_type=ModuleTypes.CORE,
244
- ),
245
- )
246
195
 
247
- for contrib in settings.CONTRIBS:
248
- contrib_root_path = contrib_to_module_root_path(contrib)
249
- _migrate_per_loader(
250
- executor,
251
- MigrationsLoader(
252
- migrations_dir=contrib_root_path / settings.MIGRATIONS_DIRECTORY_NAME,
253
- module_type=ModuleTypes.CONTRIB,
254
- module_name=contrib,
196
+ @contextmanager
197
+ def init_manager(
198
+ src_dir_path: Path,
199
+ db_execution_type: DbExecutionType,
200
+ lakehouse_option: LakehouseOption,
201
+ state_option: StateOption,
202
+ app_models_path: Path | None = None,
203
+ app_transactions_path: Path | None = None,
204
+ app_fixtures_path: Path | None = None,
205
+ **settings_options: Any,
206
+ ) -> Iterator[AmsdalManager]:
207
+ app_models_path = app_models_path or src_dir_path / 'models'
208
+ app_transactions_path = app_transactions_path or src_dir_path / 'transactions'
209
+ app_fixtures_path = app_fixtures_path or src_dir_path / 'fixtures'
210
+
211
+ with ExitStack() as stack:
212
+ tmp_dir = stack.enter_context(temp_dir())
213
+ stack.enter_context(init_config(db_execution_type, lakehouse_option, state_option))
214
+ stack.enter_context(
215
+ override_settings(
216
+ APP_PATH=tmp_dir,
217
+ USER_MODELS_MODULE_PATH=app_models_path,
218
+ TRANSACTIONS_MODULE_PATH=app_transactions_path,
219
+ FIXTURES_MODULE_PATH=app_fixtures_path,
220
+ **settings_options,
255
221
  ),
256
222
  )
257
223
 
258
- schema_loader = JsonClassSchemaLoader(app_schemas_path)
224
+ manager = AmsdalManager()
225
+ manager.setup()
226
+ manager.post_setup() # type: ignore[call-arg]
259
227
 
260
- for class_schema in schema_loader.iter_app_schemas():
261
- for _operation_data in FileMigrationGenerator.build_operations(
262
- SchemaTypes.USER,
263
- class_schema.object_schema,
264
- None,
265
- ):
266
- _operation_name = FileMigrationWriter.operation_name_map[_operation_data.type]
267
- kwargs = {}
228
+ try:
229
+ yield manager
230
+ finally:
231
+ manager.teardown()
232
+ AmsdalManager.invalidate()
233
+ AsyncDataApplication.invalidate()
268
234
 
269
- if _operation_data.old_schema:
270
- kwargs['old_schema'] = _operation_data.old_schema.model_dump()
271
235
 
272
- if _operation_data.new_schema:
273
- kwargs['new_schema'] = _operation_data.new_schema.model_dump()
274
-
275
- _operation = getattr(migrations, _operation_name)(
276
- schema_type=SchemaTypes.USER,
277
- class_name=_operation_data.class_name,
278
- **kwargs,
236
+ @asynccontextmanager
237
+ async def async_init_manager(
238
+ src_dir_path: Path,
239
+ db_execution_type: DbExecutionType,
240
+ lakehouse_option: LakehouseOption,
241
+ state_option: StateOption,
242
+ app_models_path: Path | None = None,
243
+ app_transactions_path: Path | None = None,
244
+ app_fixtures_path: Path | None = None,
245
+ **settings_options: Any,
246
+ ) -> AsyncIterator[AsyncAmsdalManager]:
247
+ app_models_path = app_models_path or src_dir_path / 'models'
248
+ app_transactions_path = app_transactions_path or src_dir_path / 'transactions'
249
+ app_fixtures_path = app_fixtures_path or src_dir_path / 'fixtures'
250
+
251
+ with ExitStack() as stack:
252
+ tmp_dir = stack.enter_context(temp_dir())
253
+ stack.enter_context(init_config(db_execution_type, lakehouse_option, state_option, is_async=True))
254
+ stack.enter_context(
255
+ override_settings(
256
+ APP_PATH=tmp_dir,
257
+ USER_MODELS_MODULE_PATH=app_models_path,
258
+ TRANSACTIONS_MODULE_PATH=app_transactions_path,
259
+ FIXTURES_MODULE_PATH=app_fixtures_path,
260
+ **settings_options,
279
261
  )
262
+ )
263
+ manager = AsyncAmsdalManager()
264
+ await manager.setup()
265
+ await manager.post_setup() # type: ignore[call-arg,misc]
280
266
 
281
- _operation.forward(executor)
282
-
283
- executor.flush_buffer()
267
+ try:
268
+ yield manager
269
+ finally:
270
+ await manager.teardown()
271
+ await AsyncDataApplication().teardown()
272
+ AsyncAmsdalManager.invalidate()
273
+ AsyncDataApplication.invalidate()
284
274
 
285
275
 
286
276
  @contextmanager
287
277
  def init_manager_and_migrate(
278
+ src_dir_path: Path,
288
279
  db_execution_type: DbExecutionType,
289
280
  lakehouse_option: LakehouseOption,
290
281
  state_option: StateOption,
282
+ app_models_path: Path | None = None,
283
+ app_transactions_path: Path | None = None,
284
+ app_fixtures_path: Path | None = None,
285
+ **settings_options: Any,
291
286
  ) -> Generator[AmsdalManager, Any, None]:
292
287
  with init_manager(
288
+ src_dir_path=src_dir_path,
293
289
  db_execution_type=db_execution_type,
294
290
  lakehouse_option=lakehouse_option,
295
291
  state_option=state_option,
292
+ app_models_path=app_models_path,
293
+ app_transactions_path=app_transactions_path,
294
+ app_fixtures_path=app_fixtures_path,
295
+ **settings_options,
296
296
  ) as manager:
297
- app_schemas_path = TESTS_DIR / 'src' / 'models'
298
- manager.build(
299
- source_models_path=app_schemas_path,
300
- source_fixtures_path=app_schemas_path,
301
- source_transactions_path=app_schemas_path,
302
- source_static_files_path=app_schemas_path,
303
- source_migrations_path=app_schemas_path,
304
- )
297
+ migrate()
298
+ manager.authenticate()
299
+ manager.init_classes()
300
+ HistoricalSchemaVersionManager()._cache_object_classes.clear()
301
+
302
+ yield manager
303
+
304
+
305
+ @asynccontextmanager
306
+ async def async_init_manager_and_migrate(
307
+ src_dir_path: Path,
308
+ db_execution_type: DbExecutionType,
309
+ lakehouse_option: LakehouseOption,
310
+ state_option: StateOption,
311
+ app_models_path: Path | None = None,
312
+ app_transactions_path: Path | None = None,
313
+ app_fixtures_path: Path | None = None,
314
+ **settings_options: Any,
315
+ ) -> AsyncGenerator[AsyncAmsdalManager, Any]:
316
+ async with async_init_manager(
317
+ src_dir_path=src_dir_path,
318
+ db_execution_type=db_execution_type,
319
+ lakehouse_option=lakehouse_option,
320
+ state_option=state_option,
321
+ app_models_path=app_models_path,
322
+ app_transactions_path=app_transactions_path,
323
+ app_fixtures_path=app_fixtures_path,
324
+ **settings_options,
325
+ ) as manager:
326
+ await async_migrate()
305
327
  manager.authenticate()
306
- migrate(app_schemas_path)
307
328
  manager.init_classes()
329
+ AsyncHistoricalSchemaVersionManager()._cache_object_classes.clear()
308
330
 
309
331
  yield manager