amsdal_cli 0.5.6__tar.gz → 0.5.8__tar.gz

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 (243) hide show
  1. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/PKG-INFO +1 -1
  2. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/change-logs.md +12 -0
  3. amsdal_cli-0.5.8/latest-changelogs.md +5 -0
  4. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/__about__.py +1 -1
  5. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/base.py +11 -1
  6. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/services/builder.py +7 -2
  7. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/services/mixin.py +25 -0
  8. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/sub_commands/deploy_new.py +1 -2
  9. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/enums.py +0 -1
  10. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/__init__.py +2 -0
  11. amsdal_cli-0.5.8/src/amsdal_cli/commands/generate/sub_commands/generate_external_models.py +365 -0
  12. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_model.py +3 -4
  13. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_permission.py +1 -2
  14. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_tests.py +1 -2
  15. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_transaction.py +1 -2
  16. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/build_base_path.py +1 -2
  17. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/conftest_utils.py +1 -2
  18. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/unit.py +2 -3
  19. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/sub_commands/apply.py +2 -2
  20. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/sub_commands/make.py +2 -4
  21. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/sub_commands/make_contrib.py +2 -4
  22. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/command.py +1 -2
  23. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/command.py +14 -5
  24. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/.amsdal-cli +1 -0
  25. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/pyproject.toml +1 -1
  26. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/command.py +1 -2
  27. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/build.py +1 -2
  28. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/restore/command.py +1 -2
  29. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/command.py +1 -2
  30. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/utils.py +2 -4
  31. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/tests/command.py +2 -3
  32. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/verify/command.py +1 -2
  33. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/worker/sub_commands/run.py +1 -2
  34. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/cli_config.py +1 -0
  35. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/schema_repository.py +1 -2
  36. amsdal_cli-0.5.8/uv.lock +2016 -0
  37. amsdal_cli-0.5.6/latest-changelogs.md +0 -5
  38. amsdal_cli-0.5.6/uv.lock +0 -1855
  39. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/.editorconfig +0 -0
  40. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/.gitignore +0 -0
  41. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/.junie/guidelines.md +0 -0
  42. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/CONTRIBUTING.md +0 -0
  43. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/LICENSE.txt +0 -0
  44. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/README.md +0 -0
  45. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/license_check.py +0 -0
  46. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/pyproject.toml +0 -0
  47. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/release_notes/.gitkeep +0 -0
  48. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/scripts/release.sh +0 -0
  49. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/scripts/tag_check.sh +0 -0
  50. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/Third-Party Materials - AMSDAL Dependencies - License Notices.md +0 -0
  51. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/__init__.py +0 -0
  52. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/app.py +0 -0
  53. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/__init__.py +0 -0
  54. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/__init__.py +0 -0
  55. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/command.py +0 -0
  56. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/config.py +0 -0
  57. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/data_classes.py +0 -0
  58. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/operation_log.py +0 -0
  59. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/services/__init__.py +0 -0
  60. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/services/comparison.py +0 -0
  61. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/services/data_factory.py +0 -0
  62. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/services/loader.py +0 -0
  63. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/services/runner.py +0 -0
  64. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/api_check/services/storage.py +0 -0
  65. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/__init__.py +0 -0
  66. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/command.py +0 -0
  67. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/constants.py +0 -0
  68. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/__init__.py +0 -0
  69. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/data_models/__init__.py +0 -0
  70. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/data_models/custom_code.py +0 -0
  71. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/data_models/options.py +0 -0
  72. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/data_models/schemas_directory.py +0 -0
  73. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/extenders/__init__.py +0 -0
  74. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/extenders/custom_code_extender.py +0 -0
  75. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/extenders/options_extender.py +0 -0
  76. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/__init__.py +0 -0
  77. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/cli_custom_code_loader.py +0 -0
  78. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/cli_loader.py +0 -0
  79. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/cli_options_loader.py +0 -0
  80. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/cli_statics_loader.py +0 -0
  81. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/cli_transactions_loader.py +0 -0
  82. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/loaders/utils.py +0 -0
  83. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/mixins/__init__.py +0 -0
  84. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/mixins/enrich_schemas_mixin.py +0 -0
  85. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/schema_json_loader.py +0 -0
  86. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/utils/__init__.py +0 -0
  87. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/schemas/utils/merger.py +0 -0
  88. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/services/__init__.py +0 -0
  89. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/utils/__init__.py +0 -0
  90. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/build/utils/build_config_file.py +0 -0
  91. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/callbacks.py +0 -0
  92. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/ci_cd/__init__.py +0 -0
  93. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/ci_cd/command.py +0 -0
  94. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/ci_cd/constants.py +0 -0
  95. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/ci_cd/templates/github.yml +0 -0
  96. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/clean/__init__.py +0 -0
  97. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/clean/command.py +0 -0
  98. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/__init__.py +0 -0
  99. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/app.py +0 -0
  100. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/command.py +0 -0
  101. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/__init__.py +0 -0
  102. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/app.py +0 -0
  103. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/command.py +0 -0
  104. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/sub_commands/__init__.py +0 -0
  105. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/sub_commands/dependency_delete.py +0 -0
  106. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/sub_commands/dependency_list.py +0 -0
  107. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/dependency/sub_commands/dependency_new.py +0 -0
  108. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/__init__.py +0 -0
  109. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/app.py +0 -0
  110. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/command.py +0 -0
  111. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/sub_commands/__init__.py +0 -0
  112. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/sub_commands/deploy_delete.py +0 -0
  113. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/deploy/sub_commands/deploy_list.py +0 -0
  114. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/enums.py +0 -0
  115. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/__init__.py +0 -0
  116. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/app.py +0 -0
  117. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/command.py +0 -0
  118. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/constants.py +0 -0
  119. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/sub_commands/__init__.py +0 -0
  120. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_checkout.py +0 -0
  121. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_delete.py +0 -0
  122. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_list.py +0 -0
  123. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_new.py +0 -0
  124. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/environments/utils.py +0 -0
  125. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/__init__.py +0 -0
  126. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/app.py +0 -0
  127. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/command.py +0 -0
  128. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/constants.py +0 -0
  129. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/sub_commands/__init__.py +0 -0
  130. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/sub_commands/secret_delete.py +0 -0
  131. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/sub_commands/secret_list.py +0 -0
  132. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/secret/sub_commands/secret_new.py +0 -0
  133. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/__init__.py +0 -0
  134. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/allowlist/__init__.py +0 -0
  135. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/allowlist/app.py +0 -0
  136. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/allowlist/command.py +0 -0
  137. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/allowlist/sub_commands/__init__.py +0 -0
  138. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/allowlist/sub_commands/allowlist_delete.py +0 -0
  139. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/allowlist/sub_commands/allowlist_new.py +0 -0
  140. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/app.py +0 -0
  141. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/__init__.py +0 -0
  142. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/app.py +0 -0
  143. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/command.py +0 -0
  144. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/__init__.py +0 -0
  145. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/basic_auth_delete.py +0 -0
  146. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/basic_auth_new.py +0 -0
  147. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/basic_auth_retrieve.py +0 -0
  148. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/security/command.py +0 -0
  149. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/sub_commands/__init__.py +0 -0
  150. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/sub_commands/expose_db.py +0 -0
  151. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/sub_commands/get_monitoring_info.py +0 -0
  152. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/cloud/sub_commands/sync_db.py +0 -0
  153. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/__init__.py +0 -0
  154. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/app.py +0 -0
  155. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/command.py +0 -0
  156. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_frontend_config.py +0 -0
  157. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_hook.py +0 -0
  158. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_modifier.py +0 -0
  159. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/sub_commands/generate_property.py +0 -0
  160. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/async_transaction.pyt +0 -0
  161. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/hook.pyt +0 -0
  162. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/modifier/constructor.pyt +0 -0
  163. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/modifier/display_name.pyt +0 -0
  164. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/modifier/version_name.pyt +0 -0
  165. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/property.pyt +0 -0
  166. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/templates/transaction.pyt +0 -0
  167. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/__init__.py +0 -0
  168. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/cast_to_attribute_type.py +0 -0
  169. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/model_attributes.py +0 -0
  170. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/__init__.py +0 -0
  171. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/async_mode_utils.py +0 -0
  172. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/function_utils.py +0 -0
  173. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/model_utils.py +0 -0
  174. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/templates/async/conftest.py +0 -0
  175. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/templates/sync/conftest.py +0 -0
  176. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/generate/utils/tests/type_utils.py +0 -0
  177. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/__init__.py +0 -0
  178. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/app.py +0 -0
  179. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/command.py +0 -0
  180. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/constants.py +0 -0
  181. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/sub_commands/__init__.py +0 -0
  182. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/sub_commands/list.py +0 -0
  183. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/migrations/utils.py +0 -0
  184. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/__init__.py +0 -0
  185. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/.amsdal/.dependencies +0 -0
  186. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/.amsdal/.environment +0 -0
  187. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/.amsdal/.secrets +0 -0
  188. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/.amsdal-cli +0 -0
  189. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/.gitignore +0 -0
  190. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/README.md +0 -0
  191. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/config.yml +0 -0
  192. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/new/templates/requirements.txt +0 -0
  193. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/__init__.py +0 -0
  194. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/README.md +0 -0
  195. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/config.yml +0 -0
  196. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/src/__about__.py +0 -0
  197. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/src/__init__.py +0 -0
  198. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/src/models/__init__.py +0 -0
  199. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/src/transactions/__init__.py +0 -0
  200. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/plugin/templates/src/transactions/example_transaction.py +0 -0
  201. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/__init__.py +0 -0
  202. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/__init__.py +0 -0
  203. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/config_updater.py +0 -0
  204. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/credentials.py +0 -0
  205. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/initialize.py +0 -0
  206. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/meta.py +0 -0
  207. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/migrate_models.py +0 -0
  208. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/model_generator.py +0 -0
  209. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/register_connection/utils/tables.py +0 -0
  210. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/restore/__init__.py +0 -0
  211. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/restore/enums.py +0 -0
  212. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/__init__.py +0 -0
  213. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/filters/__init__.py +0 -0
  214. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/filters/models_watch_filter.py +0 -0
  215. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/filters/static_files_watch_filter.py +0 -0
  216. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/services/__init__.py +0 -0
  217. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/serve/services/supervisor.py +0 -0
  218. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/tests/__init__.py +0 -0
  219. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/verify/__init__.py +0 -0
  220. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/verify/models.py +0 -0
  221. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/verify/utils/__init__.py +0 -0
  222. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/verify/utils/verify_json_model.py +0 -0
  223. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/verify/utils/verify_python_file.py +0 -0
  224. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/worker/__init__.py +0 -0
  225. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/worker/app.py +0 -0
  226. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/worker/command.py +0 -0
  227. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/commands/worker/sub_commands/__init__.py +0 -0
  228. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/config/__init__.py +0 -0
  229. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/config/main.py +0 -0
  230. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/main.py +0 -0
  231. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/py.typed +0 -0
  232. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/__init__.py +0 -0
  233. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/alias_group.py +0 -0
  234. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/check_versions.py +0 -0
  235. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/copier.py +0 -0
  236. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/markdown_patch.py +0 -0
  237. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/render_template.py +0 -0
  238. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/text.py +0 -0
  239. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/vcs/__init__.py +0 -0
  240. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/vcs/base.py +0 -0
  241. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/vcs/dummy.py +0 -0
  242. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/vcs/enums.py +0 -0
  243. {amsdal_cli-0.5.6 → amsdal_cli-0.5.8}/src/amsdal_cli/utils/vcs/git.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amsdal_cli
3
- Version: 0.5.6
3
+ Version: 0.5.8
4
4
  Summary: CLI for AMSDAL framework
5
5
  Project-URL: Documentation, https://pypi.org/project/amsdal_cli/#readme
6
6
  Project-URL: Issues, https://pypi.org/project/amsdal_cli/
@@ -1,3 +1,15 @@
1
+ ## [v0.5.8](https://pypi.org/project/amsdal_cli/0.5.8/) - 2025-10-21
2
+
3
+ ### Added
4
+
5
+ - External connections
6
+
7
+ ## [v0.5.7](https://pypi.org/project/amsdal_cli/0.5.7/) - 2025-09-02
8
+
9
+ ### Changed
10
+
11
+ - Allow to specify source directory
12
+
1
13
  ## [v0.5.6](https://pypi.org/project/amsdal_cli/0.5.6/) - 2025-08-15
2
14
 
3
15
  ### Changed
@@ -0,0 +1,5 @@
1
+ ## [v0.5.8](https://pypi.org/project/amsdal_cli/0.5.8/) - 2025-10-21
2
+
3
+ ### Added
4
+
5
+ - External connections
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2023-present
2
2
  #
3
3
  # SPDX-License-Identifier: AMSDAL End User License Agreement
4
- __version__ = '0.5.6'
4
+ __version__ = '0.5.8'
@@ -81,7 +81,17 @@ class ConfigReaderMixin:
81
81
  """
82
82
  object_config = next(cls.read_configs_from_file(json_file))
83
83
 
84
- return object_config.type != 'Fixture'
84
+ # Exclude fixtures
85
+ if object_config.type == 'Fixture':
86
+ return False
87
+
88
+ # Exclude external models (models with __connection__ attribute)
89
+ # Check model_extra (Pydantic v2) for extra fields
90
+ if hasattr(object_config, 'model_extra') and object_config.model_extra:
91
+ if '__connection__' in object_config.model_extra:
92
+ return False
93
+
94
+ return True
85
95
 
86
96
  @staticmethod
87
97
  def read_configs_from_file(json_file: Path) -> Iterator[ObjectSchema]:
@@ -4,7 +4,6 @@ from typing import TYPE_CHECKING
4
4
  from rich import print as rprint
5
5
 
6
6
  from amsdal_cli.commands.build.services.mixin import BuildMixin
7
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
8
7
 
9
8
  if TYPE_CHECKING:
10
9
  from amsdal_cli.utils.cli_config import CliConfig
@@ -15,7 +14,7 @@ class AppBuilder(BuildMixin):
15
14
  from amsdal_models.classes.class_manager import ClassManager
16
15
 
17
16
  self.cli_config = cli_config
18
- self.source_path = cli_config.app_directory / SOURCES_DIR
17
+ self.source_path = cli_config.app_directory / cli_config.src_dir
19
18
  self.config_path = config_path
20
19
  self.class_manager = ClassManager()
21
20
 
@@ -39,6 +38,12 @@ class AppBuilder(BuildMixin):
39
38
  self.build_models(self.cli_config)
40
39
  elif (self.source_path / 'models').exists():
41
40
  self.copy_class_models(self.source_path / 'models')
41
+
42
+ # Copy external models if they exist
43
+ external_models_path = self.cli_config.app_directory / 'models' / 'external'
44
+ if external_models_path.exists():
45
+ self.copy_external_models(external_models_path)
46
+
42
47
  if not is_silent:
43
48
  rprint(rich_success('OK!'))
44
49
 
@@ -53,6 +53,31 @@ class BuildMixin:
53
53
  dirs_exist_ok=True,
54
54
  )
55
55
 
56
+ @staticmethod
57
+ def copy_external_models(external_models_path: Path) -> None:
58
+ """Copy external models to the build directory.
59
+
60
+ Args:
61
+ external_models_path: Path to the external models directory (e.g., models/external)
62
+ """
63
+ from amsdal.configs.main import settings
64
+
65
+ if not settings.USER_MODELS_MODULE_PATH:
66
+ return
67
+
68
+ # External models go to USER_MODELS_MODULE_PATH/external
69
+ target_path = settings.USER_MODELS_MODULE_PATH / 'external'
70
+
71
+ # Skip copy if source and target are the same (e.g., when building in place)
72
+ if external_models_path.resolve() == target_path.resolve():
73
+ return
74
+
75
+ shutil.copytree(
76
+ external_models_path,
77
+ target_path,
78
+ dirs_exist_ok=True,
79
+ )
80
+
56
81
  @staticmethod
57
82
  def build_transactions(cli_app_path: Path) -> None:
58
83
  """
@@ -70,7 +70,6 @@ async def _deploy(
70
70
 
71
71
  from amsdal_cli.commands.build.services.builder import AppBuilder
72
72
  from amsdal_cli.commands.cloud.environments.utils import get_current_env
73
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
74
73
  from amsdal_cli.utils.cli_config import CliConfig
75
74
  from amsdal_cli.utils.text import CustomConfirm
76
75
  from amsdal_cli.utils.text import rich_error
@@ -79,7 +78,7 @@ async def _deploy(
79
78
  from amsdal_cli.utils.text import rich_warning
80
79
 
81
80
  cli_config: CliConfig = ctx.meta['config']
82
- app_source_path = cli_config.app_directory / SOURCES_DIR
81
+ app_source_path = cli_config.app_directory / cli_config.src_dir
83
82
  env_name = env_name or get_current_env(cli_config)
84
83
 
85
84
  if cli_config.verbose:
@@ -1,6 +1,5 @@
1
1
  from enum import Enum
2
2
 
3
- SOURCES_DIR = 'src'
4
3
  MODEL_JSON_FILE = 'model.json'
5
4
  MODEL_PY_FILE = 'model.py'
6
5
  FIXTURES_JSON_FILE = 'fixtures.json'
@@ -1,3 +1,4 @@
1
+ from amsdal_cli.commands.generate.sub_commands.generate_external_models import generate_external_models
1
2
  from amsdal_cli.commands.generate.sub_commands.generate_frontend_config import generate_frontend_config
2
3
  from amsdal_cli.commands.generate.sub_commands.generate_hook import generate_hook
3
4
  from amsdal_cli.commands.generate.sub_commands.generate_model import generate_model
@@ -8,6 +9,7 @@ from amsdal_cli.commands.generate.sub_commands.generate_tests import generate_te
8
9
  from amsdal_cli.commands.generate.sub_commands.generate_transaction import generate_transaction
9
10
 
10
11
  __all__ = [
12
+ 'generate_external_models',
11
13
  'generate_frontend_config',
12
14
  'generate_hook',
13
15
  'generate_model',
@@ -0,0 +1,365 @@
1
+ """Generate ExternalModel classes from external database connections."""
2
+
3
+ from pathlib import Path
4
+ from typing import TYPE_CHECKING
5
+ from typing import Any
6
+
7
+ import typer
8
+
9
+ from amsdal_cli.commands.generate.app import sub_app
10
+
11
+ if TYPE_CHECKING:
12
+ from amsdal_cli.utils.cli_config import CliConfig
13
+
14
+
15
+ @sub_app.command(name='external-models, ext-models, em')
16
+ def generate_external_models(
17
+ ctx: typer.Context,
18
+ connection_name: str = typer.Argument(
19
+ ...,
20
+ help='The name of the external connection configured in config',
21
+ ),
22
+ output_dir: Path = typer.Option( # noqa: B008
23
+ None,
24
+ '--output',
25
+ '-o',
26
+ help='Output directory for generated models (defaults to models/external/)',
27
+ ),
28
+ tables: list[str] = typer.Option( # noqa: B008
29
+ None,
30
+ '--table',
31
+ '-t',
32
+ help='Specific table names to generate models for (generates all if not specified)',
33
+ ),
34
+ format_type: str = typer.Option( # noqa: B008
35
+ 'python',
36
+ '--format',
37
+ '-f',
38
+ help='Output format: "python" or "json"',
39
+ ),
40
+ schema: str | None = typer.Option( # noqa: B008, ARG001
41
+ None,
42
+ '--schema',
43
+ '-s',
44
+ help='Database schema name (for databases that support schemas like PostgreSQL)',
45
+ ),
46
+ ) -> None:
47
+ """Generate ExternalModel classes from external database connections.
48
+
49
+ This command introspects an external database connection and generates
50
+ ExternalModel classes for the tables. The generated models can be used
51
+ immediately to query the external database.
52
+
53
+ **Examples:**
54
+
55
+ Generate models for all tables in an external connection:
56
+
57
+ ```bash
58
+ amsdal generate external-models my_external_db
59
+ ```
60
+
61
+ Generate models for specific tables only:
62
+
63
+ ```bash
64
+ amsdal generate external-models my_external_db -t users -t posts -t comments
65
+ ```
66
+
67
+ Generate models in JSON format:
68
+
69
+ ```bash
70
+ amsdal generate external-models my_external_db --format json
71
+ ```
72
+
73
+ Specify custom output directory:
74
+
75
+ ```bash
76
+ amsdal generate external-models my_external_db -o src/external_models
77
+ ```
78
+
79
+ Generate models for a specific PostgreSQL schema:
80
+
81
+ ```bash
82
+ amsdal generate external-models pg_db --schema public
83
+ ```
84
+
85
+ **Prerequisites:**
86
+
87
+ 1. The external connection must be configured in your AMSDAL config
88
+ 2. The connection must support schema introspection (SQLite, PostgreSQL)
89
+ 3. The ExternalConnectionManager must be properly set up
90
+
91
+ **Generated Output:**
92
+
93
+ For Python format:
94
+ - Creates a module for each model: `models/external/{table_name}.py`
95
+ - Each module contains an ExternalModel class ready to use
96
+
97
+ For JSON format:
98
+ - Creates JSON schema files: `models/external/{table_name}/model.json`
99
+ - Can be loaded dynamically by AMSDAL framework
100
+ """
101
+ from amsdal.services.external_connections import ExternalConnectionManager
102
+ from amsdal.services.external_model_generator import ExternalModelGenerator
103
+ from amsdal_data.application import DataApplication
104
+ from amsdal_utils.config.manager import AmsdalConfigManager
105
+ from amsdal_utils.utils.text import to_snake_case
106
+
107
+ from amsdal_cli.utils.cli_config import CliConfig
108
+
109
+ cli_config: CliConfig = ctx.meta['config']
110
+
111
+ # Validate format
112
+ if format_type not in ('python', 'json'):
113
+ typer.echo(f"Error: Invalid format '{format_type}'. Must be 'python' or 'json'.", err=True)
114
+ raise typer.Exit(1)
115
+
116
+ # Set default output directory
117
+ if output_dir is None:
118
+ output_dir = Path.cwd() / 'models' / 'external'
119
+
120
+ # Ensure output directory exists
121
+ output_dir.mkdir(parents=True, exist_ok=True)
122
+
123
+ # Initialize AMSDAL components
124
+ config_manager = AmsdalConfigManager()
125
+ config = config_manager.get_config()
126
+
127
+ # Verify connection exists in config
128
+ if connection_name not in config.connections:
129
+ typer.echo(
130
+ f"Error: Connection '{connection_name}' not found in configuration.\n"
131
+ f'Available connections: {", ".join(config.connections.keys())}',
132
+ err=True,
133
+ )
134
+ raise typer.Exit(1)
135
+
136
+ # Initialize DataApplication
137
+ app = DataApplication()
138
+ app.setup(config)
139
+
140
+ # Initialize ExternalConnectionManager
141
+ manager = ExternalConnectionManager()
142
+ manager.setup(data_application=app)
143
+
144
+ # Initialize ExternalModelGenerator
145
+ generator = ExternalModelGenerator()
146
+
147
+ try:
148
+ # Generate models
149
+ typer.echo(f"Generating external models from connection '{connection_name}'...")
150
+
151
+ if tables:
152
+ typer.echo(f'Tables: {", ".join(tables)}')
153
+ else:
154
+ typer.echo('Generating models for all tables...')
155
+
156
+ models_dict = generator.generate_models_for_connection(
157
+ connection_name=connection_name,
158
+ table_names=tables if tables else None,
159
+ )
160
+
161
+ if not models_dict:
162
+ typer.echo('No tables found or no models generated.', err=True)
163
+ raise typer.Exit(1)
164
+
165
+ typer.echo(f'Successfully generated {len(models_dict)} model(s)')
166
+
167
+ # Write models to files
168
+ if format_type == 'python':
169
+ _write_python_models(models_dict, output_dir, cli_config)
170
+ else:
171
+ _write_json_models(models_dict, output_dir, cli_config, connection_name)
172
+
173
+ typer.echo(f'\nGenerated models written to: {output_dir}')
174
+ typer.echo('\nYou can now import and use these models:')
175
+ typer.echo('```python')
176
+ first_model = next(iter(models_dict.keys()))
177
+ typer.echo(f'from models.external.{to_snake_case(first_model)} import {first_model}')
178
+ typer.echo(f'{first_model}.objects.all().execute()')
179
+ typer.echo('```')
180
+
181
+ except ValueError as e:
182
+ typer.echo(f'Error: {e}', err=True)
183
+ raise typer.Exit(1) from e
184
+ except ConnectionError as e:
185
+ typer.echo(f'Connection error: {e}', err=True)
186
+ raise typer.Exit(1) from e
187
+ except Exception as e:
188
+ typer.echo(f'Unexpected error: {e}', err=True)
189
+ raise typer.Exit(1) from e
190
+ finally:
191
+ # Clean up
192
+ app.teardown()
193
+ ExternalConnectionManager.invalidate()
194
+ AmsdalConfigManager.invalidate()
195
+ DataApplication.invalidate()
196
+
197
+
198
+ def _write_python_models(
199
+ models_dict: dict[str, type],
200
+ output_dir: Path,
201
+ cli_config: 'CliConfig', # noqa: F821
202
+ ) -> None:
203
+ """Write generated models as Python files."""
204
+ from amsdal_utils.utils.text import to_snake_case
205
+
206
+ # Create __init__.py for the package
207
+ init_file = output_dir / '__init__.py'
208
+ init_file.touch(exist_ok=True)
209
+
210
+ # Write each model to a separate file
211
+ for model_name, model_class in models_dict.items():
212
+ module_name = to_snake_case(model_name)
213
+ file_path = output_dir / f'{module_name}.py'
214
+
215
+ # Generate the model file content
216
+ content = _generate_python_model_content(model_class, cli_config)
217
+
218
+ # Write to file
219
+ file_path.write_text(content)
220
+ typer.echo(f' ✓ {module_name}.py')
221
+
222
+
223
+ def _generate_python_model_content(model_class: type, cli_config: 'CliConfig') -> str: # noqa: F821
224
+ """Generate Python code for an ExternalModel class."""
225
+ model_name = model_class.__name__
226
+ table_name = model_class.__table_name__ # type: ignore[attr-defined]
227
+ connection = model_class.__connection__ # type: ignore[attr-defined]
228
+
229
+ # Get annotations
230
+ annotations = getattr(model_class, '__annotations__', {})
231
+
232
+ # Build imports
233
+ imports = {'from amsdal_models.classes.external_model import ExternalModel'}
234
+
235
+ # Build field definitions
236
+ field_lines = []
237
+ indent = ' ' * cli_config.indent
238
+
239
+ for field_name, field_type in annotations.items():
240
+ type_str = _get_type_annotation(field_type)
241
+ field_lines.append(f'{indent}{field_name}: {type_str}')
242
+
243
+ # Build class definition
244
+ lines = [
245
+ '"""',
246
+ f'External model for {table_name} table.',
247
+ '',
248
+ f'Generated from external connection: {connection}',
249
+ '"""',
250
+ '',
251
+ *sorted(imports),
252
+ '',
253
+ '',
254
+ f'class {model_name}(ExternalModel):',
255
+ f'{indent}"""External model for {table_name}."""',
256
+ '',
257
+ f"{indent}__table_name__ = '{table_name}'",
258
+ f"{indent}__connection__ = '{connection}'",
259
+ ]
260
+
261
+ # Add primary key if present
262
+ if hasattr(model_class, '__primary_key__'):
263
+ pk = model_class.__primary_key__
264
+ if isinstance(pk, list):
265
+ lines.append(f'{indent}__primary_key__ = {pk!r}')
266
+ else:
267
+ lines.append(f"{indent}__primary_key__ = '{pk}'")
268
+
269
+ # Add field definitions
270
+ if field_lines:
271
+ lines.append('')
272
+ lines.extend(field_lines)
273
+
274
+ return '\n'.join(lines) + '\n'
275
+
276
+
277
+ def _get_type_annotation(python_type: type) -> str:
278
+ """Convert Python type to string annotation."""
279
+ type_mapping = {
280
+ str: 'str',
281
+ int: 'int',
282
+ float: 'float',
283
+ bool: 'bool',
284
+ bytes: 'bytes',
285
+ list: 'list',
286
+ dict: 'dict',
287
+ }
288
+
289
+ return type_mapping.get(python_type, 'str')
290
+
291
+
292
+ def _write_json_models(
293
+ models_dict: dict[str, type],
294
+ output_dir: Path,
295
+ cli_config: 'CliConfig', # noqa: F821
296
+ connection_name: str,
297
+ ) -> None:
298
+ """Write generated models as JSON schema files."""
299
+ import json
300
+
301
+ from amsdal_utils.utils.text import to_snake_case
302
+
303
+ for model_name, model_class in models_dict.items():
304
+ module_name = to_snake_case(model_name)
305
+ model_dir = output_dir / module_name
306
+ model_dir.mkdir(exist_ok=True, parents=True)
307
+
308
+ json_file = model_dir / 'model.json'
309
+
310
+ # Build JSON schema
311
+ schema = _generate_json_schema(model_class, connection_name)
312
+
313
+ # Write to file
314
+ json_file.write_text(json.dumps(schema, indent=cli_config.indent, ensure_ascii=False))
315
+ typer.echo(f' ✓ {module_name}/model.json')
316
+
317
+
318
+ def _generate_json_schema(model_class: type, connection_name: str) -> dict[str, Any]:
319
+ """Generate JSON schema for an ExternalModel class."""
320
+ model_name = model_class.__name__
321
+ table_name = model_class.__table_name__ # type: ignore[attr-defined]
322
+ annotations = getattr(model_class, '__annotations__', {})
323
+
324
+ # Build properties
325
+ properties = {}
326
+ for field_name, field_type in annotations.items():
327
+ properties[field_name] = {
328
+ 'type': _python_type_to_json_type(field_type),
329
+ 'title': field_name,
330
+ }
331
+
332
+ schema: dict[str, Any] = {
333
+ 'title': model_name,
334
+ 'type': 'object',
335
+ 'properties': properties,
336
+ '__table_name__': table_name,
337
+ '__connection__': connection_name,
338
+ }
339
+
340
+ # Add primary key if present
341
+ if hasattr(model_class, '__primary_key__'):
342
+ pk = model_class.__primary_key__
343
+ if isinstance(pk, str):
344
+ schema['__primary_key__'] = [pk]
345
+ else:
346
+ schema['__primary_key__'] = list(pk)
347
+
348
+ return schema
349
+
350
+
351
+ def _python_type_to_json_type(python_type: type) -> str:
352
+ """Convert Python type to JSON schema type string."""
353
+ from amsdal_utils.models.data_models.enums import CoreTypes
354
+
355
+ type_mapping = {
356
+ str: CoreTypes.STRING.value,
357
+ int: CoreTypes.INTEGER.value,
358
+ float: CoreTypes.NUMBER.value,
359
+ bool: CoreTypes.BOOLEAN.value,
360
+ bytes: CoreTypes.BINARY.value,
361
+ list: CoreTypes.ARRAY.value,
362
+ dict: CoreTypes.DICTIONARY.value,
363
+ }
364
+
365
+ return type_mapping.get(python_type, CoreTypes.STRING.value)
@@ -75,7 +75,6 @@ def generate_model(
75
75
  from amsdal_utils.utils.text import to_snake_case
76
76
 
77
77
  from amsdal_cli.commands.generate.enums import MODEL_JSON_FILE
78
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
79
78
  from amsdal_cli.commands.generate.utils.model_attributes import parse_attributes
80
79
  from amsdal_cli.utils.cli_config import CliConfig
81
80
  from amsdal_cli.utils.cli_config import ModelsFormat
@@ -122,7 +121,7 @@ def generate_model(
122
121
  json_schema['properties'][attr.name] = property_info
123
122
 
124
123
  if cli_config.models_format == ModelsFormat.JSON:
125
- output_path = cli_config.app_directory / SOURCES_DIR / 'models' / name
124
+ output_path = cli_config.app_directory / cli_config.src_dir / 'models' / name
126
125
 
127
126
  write_file(
128
127
  json.dumps(json_schema, indent=cli_config.indent),
@@ -138,11 +137,11 @@ def generate_model(
138
137
 
139
138
  from amsdal_cli.utils.schema_repository import build_schema_repository
140
139
 
141
- output_path = cli_config.app_directory / SOURCES_DIR / 'models'
140
+ output_path = cli_config.app_directory / cli_config.src_dir / 'models'
142
141
  output_path.mkdir(exist_ok=True, parents=True)
143
142
  (output_path / '__init__.py').touch(exist_ok=True)
144
143
 
145
- sys.path.insert(0, str((cli_config.app_directory / SOURCES_DIR).absolute()))
144
+ sys.path.insert(0, str((cli_config.app_directory / cli_config.src_dir).absolute()))
146
145
 
147
146
  schema_repository = build_schema_repository(cli_config=cli_config)
148
147
  class_builder = ClassBuilder()
@@ -24,7 +24,6 @@ def generate_permission(
24
24
  from amsdal_utils.utils.text import to_snake_case
25
25
 
26
26
  from amsdal_cli.commands.generate.enums import FIXTURES
27
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
28
27
  from amsdal_cli.utils.cli_config import CliConfig
29
28
  from amsdal_cli.utils.copier import write_file
30
29
 
@@ -57,7 +56,7 @@ def generate_permission(
57
56
  }
58
57
  )
59
58
 
60
- base_path = cli_config.app_directory / SOURCES_DIR
59
+ base_path = cli_config.app_directory / cli_config.src_dir
61
60
  (base_path / FIXTURES).mkdir(parents=True, exist_ok=True)
62
61
  permissions_file = base_path / FIXTURES / f'{model_snake_case}_permissions.json'
63
62
 
@@ -68,7 +68,6 @@ async def _generate_tests(
68
68
  from amsdal.manager import AmsdalManager
69
69
  from amsdal.manager import AsyncAmsdalManager
70
70
 
71
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
72
71
  from amsdal_cli.commands.generate.utils.tests.conftest_utils import create_conftest_if_not_exist
73
72
  from amsdal_cli.commands.generate.utils.tests.unit import generate_and_save_unit_tests
74
73
  from amsdal_cli.commands.serve.utils import async_build_app_and_check_migrations
@@ -88,7 +87,7 @@ async def _generate_tests(
88
87
  config_manager.load_config(config_path)
89
88
 
90
89
  create_conftest_if_not_exist(cli_config)
91
- app_source_path = cli_config.app_directory / SOURCES_DIR
90
+ app_source_path = cli_config.app_directory / cli_config.src_dir
92
91
 
93
92
  manager: AmsdalManager | AsyncAmsdalManager
94
93
  if config_manager.get_config().async_mode:
@@ -21,14 +21,13 @@ def generate_transaction(
21
21
  from amsdal_utils.utils.text import classify
22
22
  from amsdal_utils.utils.text import to_snake_case
23
23
 
24
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
25
24
  from amsdal_cli.utils.cli_config import CliConfig
26
25
  from amsdal_cli.utils.copier import copy_blueprint
27
26
 
28
27
  cli_config: CliConfig = ctx.meta['config']
29
28
  config_path = cli_config.config_path
30
29
  name = to_snake_case(transaction_name)
31
- output_path = cli_config.app_directory / SOURCES_DIR / 'transactions'
30
+ output_path = cli_config.app_directory / cli_config.src_dir / 'transactions'
32
31
  config_manager = AmsdalConfigManager()
33
32
  config_manager.load_config(config_path)
34
33
 
@@ -3,7 +3,6 @@ from pathlib import Path
3
3
  import typer
4
4
  from rich import print as rprint
5
5
 
6
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
7
6
  from amsdal_cli.utils.cli_config import CliConfig
8
7
  from amsdal_cli.utils.text import rich_error
9
8
 
@@ -23,7 +22,7 @@ def build_model_base_path(ctx: typer.Context, model_name: str) -> Path:
23
22
 
24
23
  cli_config: CliConfig = ctx.meta['config']
25
24
  model = to_snake_case(model_name)
26
- model_path = cli_config.app_directory / SOURCES_DIR / 'models' / model
25
+ model_path = cli_config.app_directory / cli_config.src_dir / 'models' / model
27
26
 
28
27
  if cli_config.check_model_exists and not (
29
28
  (model_path / 'model.json').exists() or (model_path / 'model.py').exists()
@@ -2,14 +2,13 @@ from pathlib import Path
2
2
 
3
3
  from amsdal_utils.config.manager import AmsdalConfigManager
4
4
 
5
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
6
5
  from amsdal_cli.utils.cli_config import CliConfig
7
6
 
8
7
  CURRENT_DIR = Path(__file__).parent
9
8
 
10
9
 
11
10
  def create_conftest_if_not_exist(cli_config: CliConfig) -> None:
12
- test_dir = cli_config.app_directory / SOURCES_DIR / 'tests'
11
+ test_dir = cli_config.app_directory / cli_config.src_dir / 'tests'
13
12
  test_dir.mkdir(parents=True, exist_ok=True)
14
13
  conftest_file_path = test_dir / 'conftest.py'
15
14
 
@@ -11,7 +11,6 @@ from amsdal_utils.utils.text import classify
11
11
  from amsdal_utils.utils.text import to_snake_case
12
12
  from black.mode import TargetVersion
13
13
 
14
- from amsdal_cli.commands.generate.enums import SOURCES_DIR
15
14
  from amsdal_cli.commands.generate.enums import TestDataType
16
15
  from amsdal_cli.commands.generate.utils.tests.async_mode_utils import maybe_await
17
16
  from amsdal_cli.commands.generate.utils.tests.function_utils import test_function_arguments
@@ -581,7 +580,7 @@ def generate_unit_tests(
581
580
  cli_config: CliConfig,
582
581
  test_data_type: TestDataType,
583
582
  ) -> str:
584
- models_dir = cli_config.app_directory / SOURCES_DIR / 'models'
583
+ models_dir = cli_config.app_directory / cli_config.src_dir / 'models'
585
584
 
586
585
  object_schema = get_class_schema(models_dir, model_name, cli_config)
587
586
 
@@ -661,7 +660,7 @@ def generate_and_save_unit_tests(
661
660
  model_name = classify(model_name)
662
661
  model_name_snake_case = to_snake_case(model_name)
663
662
 
664
- unit_test_dir = cli_config.app_directory / SOURCES_DIR / 'tests' / 'unit'
663
+ unit_test_dir = cli_config.app_directory / cli_config.src_dir / 'tests' / 'unit'
665
664
  unit_test_dir.mkdir(parents=True, exist_ok=True)
666
665
 
667
666
  filename = f'test_{model_name_snake_case}.py'