amsdal 0.5.34__cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.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 (276) hide show
  1. amsdal/Third-Party Materials - AMSDAL Dependencies - License Notices.md +1362 -0
  2. amsdal/__about__.py +4 -0
  3. amsdal/__about__.pyi +1 -0
  4. amsdal/__init__.py +23 -0
  5. amsdal/__init__.pyi +9 -0
  6. amsdal/__migrations__/0000_initial.py +36 -0
  7. amsdal/__migrations__/0001_create_class_file.py +61 -0
  8. amsdal/__migrations__/0002_create_class_file.py +109 -0
  9. amsdal/__migrations__/0003_update_class_file.py +91 -0
  10. amsdal/__migrations__/0004_update_class_file.py +45 -0
  11. amsdal/cloud/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  12. amsdal/cloud/__init__.pyi +0 -0
  13. amsdal/cloud/client.cpython-313-x86_64-linux-gnu.so +0 -0
  14. amsdal/cloud/client.pyi +57 -0
  15. amsdal/cloud/constants.cpython-313-x86_64-linux-gnu.so +0 -0
  16. amsdal/cloud/constants.pyi +13 -0
  17. amsdal/cloud/enums.cpython-313-x86_64-linux-gnu.so +0 -0
  18. amsdal/cloud/enums.pyi +68 -0
  19. amsdal/cloud/models/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  20. amsdal/cloud/models/__init__.pyi +0 -0
  21. amsdal/cloud/models/base.cpython-313-x86_64-linux-gnu.so +0 -0
  22. amsdal/cloud/models/base.pyi +247 -0
  23. amsdal/cloud/services/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  24. amsdal/cloud/services/__init__.pyi +0 -0
  25. amsdal/cloud/services/actions/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  26. amsdal/cloud/services/actions/__init__.pyi +0 -0
  27. amsdal/cloud/services/actions/add_allowlist_ip.cpython-313-x86_64-linux-gnu.so +0 -0
  28. amsdal/cloud/services/actions/add_allowlist_ip.pyi +19 -0
  29. amsdal/cloud/services/actions/add_basic_auth.cpython-313-x86_64-linux-gnu.so +0 -0
  30. amsdal/cloud/services/actions/add_basic_auth.pyi +21 -0
  31. amsdal/cloud/services/actions/add_dependency.cpython-313-x86_64-linux-gnu.so +0 -0
  32. amsdal/cloud/services/actions/add_dependency.pyi +19 -0
  33. amsdal/cloud/services/actions/add_secret.cpython-313-x86_64-linux-gnu.so +0 -0
  34. amsdal/cloud/services/actions/add_secret.pyi +20 -0
  35. amsdal/cloud/services/actions/base.cpython-313-x86_64-linux-gnu.so +0 -0
  36. amsdal/cloud/services/actions/base.pyi +122 -0
  37. amsdal/cloud/services/actions/create_deploy.cpython-313-x86_64-linux-gnu.so +0 -0
  38. amsdal/cloud/services/actions/create_deploy.pyi +41 -0
  39. amsdal/cloud/services/actions/create_env.cpython-313-x86_64-linux-gnu.so +0 -0
  40. amsdal/cloud/services/actions/create_env.pyi +19 -0
  41. amsdal/cloud/services/actions/create_session.cpython-313-x86_64-linux-gnu.so +0 -0
  42. amsdal/cloud/services/actions/create_session.pyi +17 -0
  43. amsdal/cloud/services/actions/delete_allowlist_ip.cpython-313-x86_64-linux-gnu.so +0 -0
  44. amsdal/cloud/services/actions/delete_allowlist_ip.pyi +19 -0
  45. amsdal/cloud/services/actions/delete_basic_auth.cpython-313-x86_64-linux-gnu.so +0 -0
  46. amsdal/cloud/services/actions/delete_basic_auth.pyi +20 -0
  47. amsdal/cloud/services/actions/delete_dependency.cpython-313-x86_64-linux-gnu.so +0 -0
  48. amsdal/cloud/services/actions/delete_dependency.pyi +21 -0
  49. amsdal/cloud/services/actions/delete_env.cpython-313-x86_64-linux-gnu.so +0 -0
  50. amsdal/cloud/services/actions/delete_env.pyi +21 -0
  51. amsdal/cloud/services/actions/delete_secret.cpython-313-x86_64-linux-gnu.so +0 -0
  52. amsdal/cloud/services/actions/delete_secret.pyi +21 -0
  53. amsdal/cloud/services/actions/destroy_deploy.cpython-313-x86_64-linux-gnu.so +0 -0
  54. amsdal/cloud/services/actions/destroy_deploy.pyi +18 -0
  55. amsdal/cloud/services/actions/expose_db.cpython-313-x86_64-linux-gnu.so +0 -0
  56. amsdal/cloud/services/actions/expose_db.pyi +22 -0
  57. amsdal/cloud/services/actions/get_basic_auth_credentials.cpython-313-x86_64-linux-gnu.so +0 -0
  58. amsdal/cloud/services/actions/get_basic_auth_credentials.pyi +21 -0
  59. amsdal/cloud/services/actions/get_monitoring_info.cpython-313-x86_64-linux-gnu.so +0 -0
  60. amsdal/cloud/services/actions/get_monitoring_info.pyi +21 -0
  61. amsdal/cloud/services/actions/list_dependencies.cpython-313-x86_64-linux-gnu.so +0 -0
  62. amsdal/cloud/services/actions/list_dependencies.pyi +21 -0
  63. amsdal/cloud/services/actions/list_deploys.cpython-313-x86_64-linux-gnu.so +0 -0
  64. amsdal/cloud/services/actions/list_deploys.pyi +19 -0
  65. amsdal/cloud/services/actions/list_envs.cpython-313-x86_64-linux-gnu.so +0 -0
  66. amsdal/cloud/services/actions/list_envs.pyi +20 -0
  67. amsdal/cloud/services/actions/list_secrets.cpython-313-x86_64-linux-gnu.so +0 -0
  68. amsdal/cloud/services/actions/list_secrets.pyi +22 -0
  69. amsdal/cloud/services/actions/manager.cpython-313-x86_64-linux-gnu.so +0 -0
  70. amsdal/cloud/services/actions/manager.pyi +278 -0
  71. amsdal/cloud/services/actions/signup_action.cpython-313-x86_64-linux-gnu.so +0 -0
  72. amsdal/cloud/services/actions/signup_action.pyi +20 -0
  73. amsdal/cloud/services/actions/update_deploy.cpython-313-x86_64-linux-gnu.so +0 -0
  74. amsdal/cloud/services/actions/update_deploy.pyi +19 -0
  75. amsdal/cloud/services/auth/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  76. amsdal/cloud/services/auth/__init__.pyi +0 -0
  77. amsdal/cloud/services/auth/base.cpython-313-x86_64-linux-gnu.so +0 -0
  78. amsdal/cloud/services/auth/base.pyi +6 -0
  79. amsdal/cloud/services/auth/credentials.cpython-313-x86_64-linux-gnu.so +0 -0
  80. amsdal/cloud/services/auth/credentials.pyi +30 -0
  81. amsdal/cloud/services/auth/manager.cpython-313-x86_64-linux-gnu.so +0 -0
  82. amsdal/cloud/services/auth/manager.pyi +26 -0
  83. amsdal/cloud/services/auth/signup_service.cpython-313-x86_64-linux-gnu.so +0 -0
  84. amsdal/cloud/services/auth/signup_service.pyi +32 -0
  85. amsdal/cloud/services/auth/token.cpython-313-x86_64-linux-gnu.so +0 -0
  86. amsdal/cloud/services/auth/token.pyi +27 -0
  87. amsdal/configs/__init__.py +0 -0
  88. amsdal/configs/__init__.pyi +0 -0
  89. amsdal/configs/constants.py +33 -0
  90. amsdal/configs/constants.pyi +22 -0
  91. amsdal/configs/main.py +274 -0
  92. amsdal/configs/main.pyi +178 -0
  93. amsdal/context/__init__.py +0 -0
  94. amsdal/context/__init__.pyi +0 -0
  95. amsdal/context/manager.py +69 -0
  96. amsdal/context/manager.pyi +50 -0
  97. amsdal/contrib/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  98. amsdal/contrib/__init__.pyi +0 -0
  99. amsdal/contrib/app_config.py +7 -0
  100. amsdal/contrib/app_config.pyi +6 -0
  101. amsdal/contrib/auth/__init__.py +0 -0
  102. amsdal/contrib/auth/__init__.pyi +0 -0
  103. amsdal/contrib/auth/app.py +27 -0
  104. amsdal/contrib/auth/app.pyi +15 -0
  105. amsdal/contrib/auth/decorators/__init__.py +35 -0
  106. amsdal/contrib/auth/decorators/__init__.pyi +6 -0
  107. amsdal/contrib/auth/errors.py +43 -0
  108. amsdal/contrib/auth/errors.pyi +16 -0
  109. amsdal/contrib/auth/fixtures/basic_permissions.json +64 -0
  110. amsdal/contrib/auth/lifecycle/__init__.py +0 -0
  111. amsdal/contrib/auth/lifecycle/__init__.pyi +0 -0
  112. amsdal/contrib/auth/lifecycle/consumer.py +394 -0
  113. amsdal/contrib/auth/lifecycle/consumer.pyi +108 -0
  114. amsdal/contrib/auth/migrations/0000_initial.py +87 -0
  115. amsdal/contrib/auth/migrations/0001_add_mfa_support.py +188 -0
  116. amsdal/contrib/auth/models/__init__.py +1 -0
  117. amsdal/contrib/auth/models/backup_code.py +85 -0
  118. amsdal/contrib/auth/models/email_mfa_device.py +108 -0
  119. amsdal/contrib/auth/models/login_session.py +235 -0
  120. amsdal/contrib/auth/models/mfa_device.py +86 -0
  121. amsdal/contrib/auth/models/permission.py +23 -0
  122. amsdal/contrib/auth/models/sms_device.py +113 -0
  123. amsdal/contrib/auth/models/totp_device.py +58 -0
  124. amsdal/contrib/auth/models/user.py +156 -0
  125. amsdal/contrib/auth/services/__init__.py +1 -0
  126. amsdal/contrib/auth/services/__init__.pyi +0 -0
  127. amsdal/contrib/auth/services/mfa_device_service.py +544 -0
  128. amsdal/contrib/auth/services/mfa_device_service.pyi +216 -0
  129. amsdal/contrib/auth/services/totp_service.py +358 -0
  130. amsdal/contrib/auth/services/totp_service.pyi +158 -0
  131. amsdal/contrib/auth/settings.py +44 -0
  132. amsdal/contrib/auth/settings.pyi +34 -0
  133. amsdal/contrib/auth/transactions/__init__.py +1 -0
  134. amsdal/contrib/auth/transactions/__init__.pyi +0 -0
  135. amsdal/contrib/auth/transactions/mfa_device_transactions.py +458 -0
  136. amsdal/contrib/auth/transactions/mfa_device_transactions.pyi +226 -0
  137. amsdal/contrib/auth/transactions/totp_transactions.py +203 -0
  138. amsdal/contrib/auth/transactions/totp_transactions.pyi +113 -0
  139. amsdal/contrib/auth/utils/__init__.py +0 -0
  140. amsdal/contrib/auth/utils/__init__.pyi +0 -0
  141. amsdal/contrib/auth/utils/mfa.py +257 -0
  142. amsdal/contrib/auth/utils/mfa.pyi +119 -0
  143. amsdal/contrib/frontend_configs/__init__.py +0 -0
  144. amsdal/contrib/frontend_configs/__init__.pyi +0 -0
  145. amsdal/contrib/frontend_configs/app.py +24 -0
  146. amsdal/contrib/frontend_configs/app.pyi +19 -0
  147. amsdal/contrib/frontend_configs/constants.py +1 -0
  148. amsdal/contrib/frontend_configs/constants.pyi +1 -0
  149. amsdal/contrib/frontend_configs/conversion/__init__.py +5 -0
  150. amsdal/contrib/frontend_configs/conversion/__init__.pyi +3 -0
  151. amsdal/contrib/frontend_configs/conversion/convert.py +310 -0
  152. amsdal/contrib/frontend_configs/conversion/convert.pyi +22 -0
  153. amsdal/contrib/frontend_configs/lifecycle/__init__.py +0 -0
  154. amsdal/contrib/frontend_configs/lifecycle/__init__.pyi +0 -0
  155. amsdal/contrib/frontend_configs/lifecycle/consumer.py +306 -0
  156. amsdal/contrib/frontend_configs/lifecycle/consumer.pyi +98 -0
  157. amsdal/contrib/frontend_configs/migrations/0000_initial.py +227 -0
  158. amsdal/contrib/frontend_configs/migrations/0001_update_frontend_control_config.py +245 -0
  159. amsdal/contrib/frontend_configs/migrations/0002_add_button_and_invoke_actions.py +352 -0
  160. amsdal/contrib/frontend_configs/migrations/0003_create_class_frontendconfigdashboardelement.py +145 -0
  161. amsdal/contrib/frontend_configs/models/__init__.py +0 -0
  162. amsdal/contrib/frontend_configs/models/frontend_activator_config.py +22 -0
  163. amsdal/contrib/frontend_configs/models/frontend_config_async_validator.py +11 -0
  164. amsdal/contrib/frontend_configs/models/frontend_config_control_action.py +110 -0
  165. amsdal/contrib/frontend_configs/models/frontend_config_dashboard.py +51 -0
  166. amsdal/contrib/frontend_configs/models/frontend_config_group_validator.py +21 -0
  167. amsdal/contrib/frontend_configs/models/frontend_config_option.py +12 -0
  168. amsdal/contrib/frontend_configs/models/frontend_config_skip_none_base.py +17 -0
  169. amsdal/contrib/frontend_configs/models/frontend_config_slider_option.py +13 -0
  170. amsdal/contrib/frontend_configs/models/frontend_config_text_mask.py +14 -0
  171. amsdal/contrib/frontend_configs/models/frontend_config_validator.py +28 -0
  172. amsdal/contrib/frontend_configs/models/frontend_control_config.py +110 -0
  173. amsdal/contrib/frontend_configs/models/frontend_model_config.py +14 -0
  174. amsdal/contrib/frontend_configs/utils.py +29 -0
  175. amsdal/contrib/frontend_configs/utils.pyi +17 -0
  176. amsdal/errors.py +31 -0
  177. amsdal/errors.pyi +12 -0
  178. amsdal/fixtures/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  179. amsdal/fixtures/__init__.pyi +0 -0
  180. amsdal/fixtures/manager.cpython-313-x86_64-linux-gnu.so +0 -0
  181. amsdal/fixtures/manager.pyi +170 -0
  182. amsdal/fixtures/utils.cpython-313-x86_64-linux-gnu.so +0 -0
  183. amsdal/fixtures/utils.pyi +9 -0
  184. amsdal/manager.cpython-313-x86_64-linux-gnu.so +0 -0
  185. amsdal/manager.pyi +265 -0
  186. amsdal/mixins/__init__.cpython-313-x86_64-linux-gnu.so +0 -0
  187. amsdal/mixins/__init__.pyi +0 -0
  188. amsdal/mixins/class_versions_mixin.cpython-313-x86_64-linux-gnu.so +0 -0
  189. amsdal/mixins/class_versions_mixin.pyi +12 -0
  190. amsdal/models/__init__.py +19 -0
  191. amsdal/models/core/__init__.py +0 -0
  192. amsdal/models/core/class_object.py +38 -0
  193. amsdal/models/core/class_property.py +26 -0
  194. amsdal/models/core/file.py +243 -0
  195. amsdal/models/core/fixture.py +25 -0
  196. amsdal/models/core/option.py +11 -0
  197. amsdal/models/core/storage_metadata.py +15 -0
  198. amsdal/models/core/validator.py +12 -0
  199. amsdal/models/mixins.py +31 -0
  200. amsdal/models/types/__init__.py +0 -0
  201. amsdal/models/types/object.py +26 -0
  202. amsdal/py.typed +0 -0
  203. amsdal/queryset/__init__.py +21 -0
  204. amsdal/queryset/__init__.pyi +6 -0
  205. amsdal/schemas/__init__.py +0 -0
  206. amsdal/schemas/__init__.pyi +0 -0
  207. amsdal/schemas/core/class_object/model.json +51 -0
  208. amsdal/schemas/core/class_object/properties/display_name.py +9 -0
  209. amsdal/schemas/core/class_property/model.json +41 -0
  210. amsdal/schemas/core/file/hooks/pre_create.py +24 -0
  211. amsdal/schemas/core/file/hooks/pre_update.py +24 -0
  212. amsdal/schemas/core/file/model.json +23 -0
  213. amsdal/schemas/core/file/properties/from_file.py +34 -0
  214. amsdal/schemas/core/file/properties/mimetype.py +13 -0
  215. amsdal/schemas/core/file/properties/str.py +6 -0
  216. amsdal/schemas/core/file/properties/to_file.py +24 -0
  217. amsdal/schemas/core/file/properties/validate_data.py +31 -0
  218. amsdal/schemas/core/fixture/model.json +35 -0
  219. amsdal/schemas/core/option/model.json +19 -0
  220. amsdal/schemas/core/storage_metadata/model.json +52 -0
  221. amsdal/schemas/core/validator/model.json +19 -0
  222. amsdal/schemas/interfaces.py +25 -0
  223. amsdal/schemas/interfaces.pyi +20 -0
  224. amsdal/schemas/manager.cpython-313-x86_64-linux-gnu.so +0 -0
  225. amsdal/schemas/manager.py +0 -0
  226. amsdal/schemas/manager.pyi +0 -0
  227. amsdal/schemas/mixins/__init__.py +0 -0
  228. amsdal/schemas/mixins/__init__.pyi +0 -0
  229. amsdal/schemas/mixins/check_dependencies_mixin.py +130 -0
  230. amsdal/schemas/mixins/check_dependencies_mixin.pyi +45 -0
  231. amsdal/schemas/mixins/verify_schemas_mixin.py +96 -0
  232. amsdal/schemas/mixins/verify_schemas_mixin.pyi +33 -0
  233. amsdal/schemas/repository.py +84 -0
  234. amsdal/schemas/repository.pyi +22 -0
  235. amsdal/schemas/types/anything/model.json +7 -0
  236. amsdal/schemas/types/array/model.json +7 -0
  237. amsdal/schemas/types/binary/model.json +7 -0
  238. amsdal/schemas/types/boolean/model.json +17 -0
  239. amsdal/schemas/types/date/model.json +7 -0
  240. amsdal/schemas/types/datetime/model.json +7 -0
  241. amsdal/schemas/types/dictionary/model.json +8 -0
  242. amsdal/schemas/types/number/model.json +8 -0
  243. amsdal/schemas/types/object/model.json +53 -0
  244. amsdal/schemas/types/string/model.json +8 -0
  245. amsdal/schemas/utils.py +16 -0
  246. amsdal/schemas/utils.pyi +10 -0
  247. amsdal/services/__init__.py +11 -0
  248. amsdal/services/__init__.pyi +4 -0
  249. amsdal/services/external_connections.py +262 -0
  250. amsdal/services/external_connections.pyi +190 -0
  251. amsdal/services/external_model_generator.py +350 -0
  252. amsdal/services/external_model_generator.pyi +134 -0
  253. amsdal/services/transaction_execution.cpython-313-x86_64-linux-gnu.so +0 -0
  254. amsdal/services/transaction_execution.pyi +93 -0
  255. amsdal/storages/__init__.py +20 -0
  256. amsdal/storages/__init__.pyi +8 -0
  257. amsdal/storages/file_system.py +214 -0
  258. amsdal/storages/file_system.pyi +36 -0
  259. amsdal/transactions/__init__.py +13 -0
  260. amsdal/transactions/__init__.pyi +4 -0
  261. amsdal/utils/__init__.py +0 -0
  262. amsdal/utils/__init__.pyi +0 -0
  263. amsdal/utils/contrib_paths.py +23 -0
  264. amsdal/utils/contrib_paths.pyi +14 -0
  265. amsdal/utils/rollback/__init__.py +440 -0
  266. amsdal/utils/rollback/__init__.pyi +38 -0
  267. amsdal/utils/tests/__init__.py +0 -0
  268. amsdal/utils/tests/enums.py +16 -0
  269. amsdal/utils/tests/factories.py +49 -0
  270. amsdal/utils/tests/helpers.py +331 -0
  271. amsdal/utils/tests/migrations.py +157 -0
  272. amsdal-0.5.34.dist-info/METADATA +375 -0
  273. amsdal-0.5.34.dist-info/RECORD +276 -0
  274. amsdal-0.5.34.dist-info/WHEEL +6 -0
  275. amsdal-0.5.34.dist-info/licenses/LICENSE.txt +107 -0
  276. amsdal-0.5.34.dist-info/top_level.txt +1 -0
@@ -0,0 +1,331 @@
1
+ import random
2
+ import string
3
+ from collections.abc import AsyncGenerator
4
+ from collections.abc import AsyncIterator
5
+ from collections.abc import Generator
6
+ from collections.abc import Iterator
7
+ from contextlib import ExitStack
8
+ from contextlib import asynccontextmanager
9
+ from contextlib import contextmanager
10
+ from functools import partial
11
+ from pathlib import Path
12
+ from typing import Any
13
+
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
44
+ from amsdal_utils.config.manager import AmsdalConfigManager
45
+
46
+ from amsdal.manager import AmsdalManager
47
+ from amsdal.manager import AsyncAmsdalManager
48
+ from amsdal.utils.tests.enums import DbExecutionType
49
+ from amsdal.utils.tests.enums import LakehouseOption
50
+ from amsdal.utils.tests.enums import StateOption
51
+ from amsdal.utils.tests.migrations import async_migrate
52
+ from amsdal.utils.tests.migrations import migrate
53
+
54
+
55
+ @contextmanager
56
+ def override_settings(**kwargs: Any) -> Iterator[None]:
57
+ """
58
+ A context manager that temporarily overrides settings.
59
+
60
+ This is a copy of django.test.utils.override_settings, but with the
61
+ ability to override settings with None.
62
+ """
63
+ from amsdal.configs.main import settings
64
+
65
+ original_settings = settings.model_dump()
66
+
67
+ settings.override(**kwargs)
68
+
69
+ try:
70
+ yield
71
+ finally:
72
+ settings.override(**original_settings)
73
+
74
+
75
+ @contextmanager
76
+ def init_config(
77
+ db_execution_type: DbExecutionType,
78
+ lakehouse_option: LakehouseOption,
79
+ state_option: StateOption,
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:
90
+ lakehouse_database = ''.join(random.sample(string.ascii_letters, 16))
91
+ state_database = ''.join(random.sample(string.ascii_letters, 16))
92
+
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
+ }
136
+
137
+ with ctx_managers[lakehouse_option]() as _amsdal_config:
138
+ yield _amsdal_config
139
+ return
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')
161
+ try:
162
+ yield config
163
+ finally:
164
+ AmsdalConfigManager.invalidate()
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')
186
+
187
+ try:
188
+ yield config
189
+ finally:
190
+ AmsdalConfigManager.invalidate()
191
+
192
+ if drop_database:
193
+ drop_postgres_database(state_database)
194
+
195
+
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,
221
+ ),
222
+ )
223
+
224
+ manager = AmsdalManager()
225
+ manager.setup()
226
+ manager.post_setup() # type: ignore[call-arg]
227
+
228
+ try:
229
+ yield manager
230
+ finally:
231
+ manager.teardown()
232
+ AmsdalManager.invalidate()
233
+ AsyncDataApplication.invalidate()
234
+
235
+
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,
261
+ )
262
+ )
263
+ manager = AsyncAmsdalManager()
264
+ await manager.setup()
265
+ await manager.post_setup() # type: ignore[call-arg,misc]
266
+
267
+ try:
268
+ yield manager
269
+ finally:
270
+ await manager.teardown()
271
+ await AsyncDataApplication().teardown()
272
+ AsyncAmsdalManager.invalidate()
273
+ AsyncDataApplication.invalidate()
274
+
275
+
276
+ @contextmanager
277
+ def init_manager_and_migrate(
278
+ src_dir_path: Path,
279
+ db_execution_type: DbExecutionType,
280
+ lakehouse_option: LakehouseOption,
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,
286
+ ) -> Generator[AmsdalManager, Any, None]:
287
+ with init_manager(
288
+ src_dir_path=src_dir_path,
289
+ db_execution_type=db_execution_type,
290
+ lakehouse_option=lakehouse_option,
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
+ ) as manager:
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()
327
+ manager.authenticate()
328
+ manager.init_classes()
329
+ AsyncHistoricalSchemaVersionManager()._cache_object_classes.clear()
330
+
331
+ yield manager
@@ -0,0 +1,157 @@
1
+ import contextlib
2
+ from asyncio import iscoroutine
3
+
4
+ from amsdal_data.connections.historical.schema_version_manager import AsyncHistoricalSchemaVersionManager
5
+ from amsdal_data.connections.historical.schema_version_manager import HistoricalSchemaVersionManager
6
+ from amsdal_models.migration import migrations
7
+ from amsdal_models.migration.executors.default_executor import DefaultAsyncMigrationExecutor
8
+ from amsdal_models.migration.executors.default_executor import DefaultMigrationExecutor
9
+ from amsdal_models.migration.file_migration_executor import AsyncFileMigrationExecutorManager
10
+ from amsdal_models.migration.file_migration_executor import FileMigrationExecutorManager
11
+ from amsdal_models.migration.file_migration_generator import SimpleFileMigrationGenerator
12
+ from amsdal_models.migration.file_migration_store import AsyncFileMigrationStore
13
+ from amsdal_models.migration.file_migration_store import FileMigrationStore
14
+ from amsdal_models.migration.file_migration_writer import FileMigrationWriter
15
+ from amsdal_models.migration.migrations import MigrationSchemas
16
+ from amsdal_models.migration.migrations_loader import MigrationsLoader
17
+ from amsdal_models.schemas.class_schema_loader import ClassSchemaLoader
18
+ from amsdal_utils.models.enums import ModuleType
19
+
20
+ from amsdal.configs.constants import CORE_MIGRATIONS_PATH
21
+ from amsdal.configs.main import settings
22
+
23
+
24
+ def migrate() -> None:
25
+ schemas = MigrationSchemas()
26
+ executor = DefaultMigrationExecutor(schemas, use_foreign_keys=True)
27
+ store = FileMigrationStore(settings.migrations_root_path)
28
+ store.init_migration_table()
29
+
30
+ class UserMigrationsLoader(MigrationsLoader):
31
+ def __init__(self):
32
+ super().__init__(settings.migrations_root_path, ModuleType.USER)
33
+ self._migrations_files = []
34
+
35
+ with contextlib.suppress(Exception):
36
+ HistoricalSchemaVersionManager().object_classes # noqa: B018
37
+
38
+ # migrate core and contrib due to applied migrations
39
+ executor_manager = FileMigrationExecutorManager(
40
+ core_migrations_path=CORE_MIGRATIONS_PATH,
41
+ app_migrations_loader=UserMigrationsLoader(),
42
+ executor=executor,
43
+ store=store,
44
+ contrib=settings.CONTRIBS,
45
+ )
46
+ executor_manager.execute()
47
+
48
+ # always apply migrations for user models
49
+ user_schema_loader = ClassSchemaLoader(
50
+ settings.USER_MODELS_MODULE,
51
+ class_filter=lambda cls: cls.__module_type__ == ModuleType.USER,
52
+ )
53
+ _schemas, _cycle_schemas = user_schema_loader.load_sorted()
54
+ _schemas_map = {_schema.title: _schema for _schema in _schemas}
55
+
56
+ for object_schema in _schemas:
57
+ for _operation_data in SimpleFileMigrationGenerator.build_operations(
58
+ ModuleType.USER,
59
+ object_schema,
60
+ None,
61
+ ):
62
+ _operation_name = FileMigrationWriter.operation_name_map[_operation_data.type]
63
+ _operation = getattr(migrations, _operation_name)(
64
+ module_type=ModuleType.USER,
65
+ class_name=_operation_data.class_name,
66
+ new_schema=_operation_data.new_schema.model_dump(),
67
+ )
68
+
69
+ _operation.forward(executor)
70
+
71
+ for object_schema in _cycle_schemas:
72
+ for _operation_data in SimpleFileMigrationGenerator.build_operations(
73
+ ModuleType.USER,
74
+ object_schema,
75
+ _schemas_map[object_schema.title],
76
+ ):
77
+ _operation_name = FileMigrationWriter.operation_name_map[_operation_data.type]
78
+ _operation = getattr(migrations, _operation_name)(
79
+ module_type=ModuleType.USER,
80
+ class_name=_operation_data.class_name,
81
+ new_schema=_operation_data.new_schema.model_dump(),
82
+ )
83
+
84
+ _operation.forward(executor)
85
+
86
+ executor.flush_buffer()
87
+
88
+
89
+ async def async_migrate() -> None:
90
+ schemas = MigrationSchemas()
91
+ executor = DefaultAsyncMigrationExecutor(schemas)
92
+ store = AsyncFileMigrationStore(settings.migrations_root_path)
93
+ await store.init_migration_table()
94
+
95
+ class UserMigrationsLoader(MigrationsLoader):
96
+ def __init__(self):
97
+ super().__init__(settings.migrations_root_path, ModuleType.USER)
98
+ self._migrations_files = []
99
+
100
+ with contextlib.suppress(Exception):
101
+ await AsyncHistoricalSchemaVersionManager().object_classes
102
+
103
+ # migrate core and contrib due to applied migrations
104
+ executor_manager = AsyncFileMigrationExecutorManager(
105
+ core_migrations_path=CORE_MIGRATIONS_PATH,
106
+ app_migrations_loader=UserMigrationsLoader(),
107
+ executor=executor,
108
+ store=store,
109
+ contrib=settings.CONTRIBS,
110
+ )
111
+ await executor_manager.execute()
112
+
113
+ # always apply migrations for user models
114
+ user_schema_loader = ClassSchemaLoader(
115
+ settings.USER_MODELS_MODULE,
116
+ class_filter=lambda cls: cls.__module_type__ == ModuleType.USER,
117
+ )
118
+ _schemas, _cycle_schemas = user_schema_loader.load_sorted()
119
+ _schemas_map = {_schema.title: _schema for _schema in _schemas}
120
+
121
+ for object_schema in _schemas:
122
+ for _operation_data in SimpleFileMigrationGenerator.build_operations(
123
+ ModuleType.USER,
124
+ object_schema,
125
+ None,
126
+ ):
127
+ _operation_name = FileMigrationWriter.operation_name_map[_operation_data.type]
128
+ _operation = getattr(migrations, _operation_name)(
129
+ module_type=ModuleType.USER,
130
+ class_name=_operation_data.class_name,
131
+ new_schema=_operation_data.new_schema.model_dump(),
132
+ )
133
+
134
+ forward_result = _operation.forward(executor)
135
+
136
+ if iscoroutine(forward_result):
137
+ await forward_result
138
+
139
+ for object_schema in _cycle_schemas:
140
+ for _operation_data in SimpleFileMigrationGenerator.build_operations(
141
+ ModuleType.USER,
142
+ object_schema,
143
+ _schemas_map[object_schema.title],
144
+ ):
145
+ _operation_name = FileMigrationWriter.operation_name_map[_operation_data.type]
146
+ _operation = getattr(migrations, _operation_name)(
147
+ module_type=ModuleType.USER,
148
+ class_name=_operation_data.class_name,
149
+ new_schema=_operation_data.new_schema.model_dump(),
150
+ )
151
+
152
+ forward_result = _operation.forward(executor)
153
+
154
+ if iscoroutine(forward_result):
155
+ await forward_result
156
+
157
+ await executor.flush_buffer()