amsdal_cli 0.5.2__tar.gz → 0.5.4__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 (239) hide show
  1. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/.gitignore +1 -0
  2. amsdal_cli-0.5.4/.junie/guidelines.md +102 -0
  3. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/PKG-INFO +2 -1
  4. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/change-logs.md +12 -0
  5. amsdal_cli-0.5.4/latest-changelogs.md +5 -0
  6. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/pyproject.toml +49 -40
  7. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/__about__.py +1 -1
  8. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/command.py +118 -0
  9. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/config.py +192 -0
  10. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/data_classes.py +13 -0
  11. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/operation_log.py +78 -0
  12. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/services/comparison.py +47 -0
  13. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/services/data_factory.py +158 -0
  14. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/services/loader.py +11 -0
  15. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/services/runner.py +499 -0
  16. amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/services/storage.py +12 -0
  17. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/services/mixin.py +2 -2
  18. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/callbacks.py +1 -1
  19. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/type_utils.py +3 -3
  20. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/sub_commands/__init__.py +2 -0
  21. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/sub_commands/apply.py +6 -44
  22. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/sub_commands/list.py +26 -25
  23. amsdal_cli-0.5.4/src/amsdal_cli/commands/migrations/sub_commands/make_contrib.py +179 -0
  24. amsdal_cli-0.5.4/src/amsdal_cli/commands/migrations/utils.py +86 -0
  25. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/command.py +149 -0
  26. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/.amsdal-cli +10 -0
  27. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/README.md +49 -0
  28. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/plugin.yml +20 -0
  29. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/requirements.txt +1 -0
  30. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/src/models/__init__.py +1 -0
  31. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/src/transactions/__init__.py +1 -0
  32. amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin/templates/src/transactions/example_transaction.py +47 -0
  33. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/serve/utils.py +1 -1
  34. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/worker/sub_commands/run.py +2 -2
  35. amsdal_cli-0.5.4/src/amsdal_cli/config/__init__.py +0 -0
  36. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/config/main.py +2 -0
  37. amsdal_cli-0.5.4/src/amsdal_cli/py.typed +0 -0
  38. amsdal_cli-0.5.4/src/amsdal_cli/utils/__init__.py +0 -0
  39. amsdal_cli-0.5.4/uv.lock +1854 -0
  40. amsdal_cli-0.5.2/latest-changelogs.md +0 -5
  41. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/.editorconfig +0 -0
  42. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/CONTRIBUTING.md +0 -0
  43. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/LICENSE.txt +0 -0
  44. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/README.md +0 -0
  45. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/license_check.py +0 -0
  46. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/release_notes/.gitkeep +0 -0
  47. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/scripts/release.sh +0 -0
  48. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/scripts/tag_check.sh +0 -0
  49. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/Third-Party Materials - AMSDAL Dependencies - License Notices.md +0 -0
  50. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/__init__.py +0 -0
  51. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/app.py +0 -0
  52. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/__init__.py +0 -0
  53. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build → amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check}/__init__.py +0 -0
  54. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/schemas → amsdal_cli-0.5.4/src/amsdal_cli/commands/api_check/services}/__init__.py +0 -0
  55. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/schemas/data_models → amsdal_cli-0.5.4/src/amsdal_cli/commands/build}/__init__.py +0 -0
  56. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/command.py +0 -0
  57. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/constants.py +0 -0
  58. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/schemas/extenders → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/schemas}/__init__.py +0 -0
  59. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/schemas/loaders → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/schemas/data_models}/__init__.py +0 -0
  60. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/data_models/custom_code.py +0 -0
  61. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/data_models/options.py +0 -0
  62. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/data_models/schemas_directory.py +0 -0
  63. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/schemas/mixins → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/schemas/extenders}/__init__.py +0 -0
  64. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/extenders/custom_code_extender.py +0 -0
  65. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/extenders/options_extender.py +0 -0
  66. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/schemas/utils → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/schemas/loaders}/__init__.py +0 -0
  67. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/base.py +0 -0
  68. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/cli_custom_code_loader.py +0 -0
  69. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/cli_loader.py +0 -0
  70. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/cli_options_loader.py +0 -0
  71. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/cli_statics_loader.py +0 -0
  72. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/cli_transactions_loader.py +0 -0
  73. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/loaders/utils.py +0 -0
  74. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build/services → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/schemas/mixins}/__init__.py +0 -0
  75. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/mixins/enrich_schemas_mixin.py +0 -0
  76. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/schema_json_loader.py +0 -0
  77. {amsdal_cli-0.5.2/src/amsdal_cli/commands/build → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/schemas}/utils/__init__.py +0 -0
  78. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/schemas/utils/merger.py +0 -0
  79. {amsdal_cli-0.5.2/src/amsdal_cli/commands/ci_cd → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/services}/__init__.py +0 -0
  80. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/services/builder.py +0 -0
  81. {amsdal_cli-0.5.2/src/amsdal_cli/commands/clean → amsdal_cli-0.5.4/src/amsdal_cli/commands/build/utils}/__init__.py +0 -0
  82. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/build/utils/build_config_file.py +0 -0
  83. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud → amsdal_cli-0.5.4/src/amsdal_cli/commands/ci_cd}/__init__.py +0 -0
  84. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/ci_cd/command.py +0 -0
  85. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/ci_cd/constants.py +0 -0
  86. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/ci_cd/templates/github.yml +0 -0
  87. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/dependency → amsdal_cli-0.5.4/src/amsdal_cli/commands/clean}/__init__.py +0 -0
  88. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/clean/command.py +0 -0
  89. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/deploy → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud}/__init__.py +0 -0
  90. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/app.py +0 -0
  91. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/command.py +0 -0
  92. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/environments → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/dependency}/__init__.py +0 -0
  93. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/dependency/app.py +0 -0
  94. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/dependency/command.py +0 -0
  95. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/dependency/sub_commands/__init__.py +0 -0
  96. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/dependency/sub_commands/dependency_delete.py +0 -0
  97. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/dependency/sub_commands/dependency_list.py +0 -0
  98. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/dependency/sub_commands/dependency_new.py +0 -0
  99. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/secret → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/deploy}/__init__.py +0 -0
  100. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/deploy/app.py +0 -0
  101. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/deploy/command.py +0 -0
  102. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/deploy/sub_commands/__init__.py +0 -0
  103. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/deploy/sub_commands/deploy_delete.py +0 -0
  104. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/deploy/sub_commands/deploy_list.py +0 -0
  105. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/deploy/sub_commands/deploy_new.py +0 -0
  106. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/enums.py +0 -0
  107. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/security → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/environments}/__init__.py +0 -0
  108. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/app.py +0 -0
  109. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/command.py +0 -0
  110. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/constants.py +0 -0
  111. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/sub_commands/__init__.py +0 -0
  112. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_checkout.py +0 -0
  113. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_delete.py +0 -0
  114. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_list.py +0 -0
  115. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/sub_commands/env_new.py +0 -0
  116. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/environments/utils.py +0 -0
  117. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/security/allowlist → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/secret}/__init__.py +0 -0
  118. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/app.py +0 -0
  119. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/command.py +0 -0
  120. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/constants.py +0 -0
  121. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/sub_commands/__init__.py +0 -0
  122. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/sub_commands/secret_delete.py +0 -0
  123. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/sub_commands/secret_list.py +0 -0
  124. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/secret/sub_commands/secret_new.py +0 -0
  125. {amsdal_cli-0.5.2/src/amsdal_cli/commands/cloud/security/basic_auth → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/security}/__init__.py +0 -0
  126. {amsdal_cli-0.5.2/src/amsdal_cli/commands/generate → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/security/allowlist}/__init__.py +0 -0
  127. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/allowlist/app.py +0 -0
  128. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/allowlist/command.py +0 -0
  129. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/allowlist/sub_commands/__init__.py +0 -0
  130. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/allowlist/sub_commands/allowlist_delete.py +0 -0
  131. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/allowlist/sub_commands/allowlist_new.py +0 -0
  132. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/app.py +0 -0
  133. {amsdal_cli-0.5.2/src/amsdal_cli/commands/generate/utils → amsdal_cli-0.5.4/src/amsdal_cli/commands/cloud/security/basic_auth}/__init__.py +0 -0
  134. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/basic_auth/app.py +0 -0
  135. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/basic_auth/command.py +0 -0
  136. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/__init__.py +0 -0
  137. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/basic_auth_delete.py +0 -0
  138. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/basic_auth_new.py +0 -0
  139. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/basic_auth/sub_commands/basic_auth_retrieve.py +0 -0
  140. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/security/command.py +0 -0
  141. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/sub_commands/__init__.py +0 -0
  142. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/sub_commands/expose_db.py +0 -0
  143. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/sub_commands/get_monitoring_info.py +0 -0
  144. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/cloud/sub_commands/sync_db.py +0 -0
  145. {amsdal_cli-0.5.2/src/amsdal_cli/commands/generate/utils/tests → amsdal_cli-0.5.4/src/amsdal_cli/commands/generate}/__init__.py +0 -0
  146. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/app.py +0 -0
  147. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/command.py +0 -0
  148. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/enums.py +0 -0
  149. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/__init__.py +0 -0
  150. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_frontend_config.py +0 -0
  151. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_hook.py +0 -0
  152. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_model.py +0 -0
  153. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_modifier.py +0 -0
  154. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_permission.py +0 -0
  155. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_property.py +0 -0
  156. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_tests.py +0 -0
  157. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/sub_commands/generate_transaction.py +0 -0
  158. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/async_transaction.pyt +0 -0
  159. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/hook.pyt +0 -0
  160. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/modifier/constructor.pyt +0 -0
  161. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/modifier/display_name.pyt +0 -0
  162. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/modifier/version_name.pyt +0 -0
  163. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/property.pyt +0 -0
  164. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/templates/transaction.pyt +0 -0
  165. {amsdal_cli-0.5.2/src/amsdal_cli/commands/migrations → amsdal_cli-0.5.4/src/amsdal_cli/commands/generate/utils}/__init__.py +0 -0
  166. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/build_base_path.py +0 -0
  167. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/cast_to_attribute_type.py +0 -0
  168. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/model_attributes.py +0 -0
  169. {amsdal_cli-0.5.2/src/amsdal_cli/commands/new → amsdal_cli-0.5.4/src/amsdal_cli/commands/generate/utils/tests}/__init__.py +0 -0
  170. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/async_mode_utils.py +0 -0
  171. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/conftest_utils.py +0 -0
  172. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/function_utils.py +0 -0
  173. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/model_utils.py +0 -0
  174. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/templates/async/conftest.py +0 -0
  175. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/templates/sync/conftest.py +0 -0
  176. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/generate/utils/tests/unit.py +0 -0
  177. {amsdal_cli-0.5.2/src/amsdal_cli/commands/register_connection → amsdal_cli-0.5.4/src/amsdal_cli/commands/migrations}/__init__.py +0 -0
  178. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/app.py +0 -0
  179. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/command.py +0 -0
  180. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/constants.py +0 -0
  181. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/migrations/sub_commands/make.py +0 -0
  182. {amsdal_cli-0.5.2/src/amsdal_cli/commands/register_connection/utils → amsdal_cli-0.5.4/src/amsdal_cli/commands/new}/__init__.py +0 -0
  183. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/command.py +0 -0
  184. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/.amsdal/.dependencies +0 -0
  185. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/.amsdal/.environment +0 -0
  186. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/.amsdal/.secrets +0 -0
  187. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/.amsdal-cli +0 -0
  188. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/.gitignore +0 -0
  189. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/README.md +0 -0
  190. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/config.yml +0 -0
  191. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/new/templates/requirements.txt +0 -0
  192. {amsdal_cli-0.5.2/src/amsdal_cli/commands/restore → amsdal_cli-0.5.4/src/amsdal_cli/commands/plugin}/__init__.py +0 -0
  193. {amsdal_cli-0.5.2/src/amsdal_cli/commands/serve → amsdal_cli-0.5.4/src/amsdal_cli/commands/register_connection}/__init__.py +0 -0
  194. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/command.py +0 -0
  195. {amsdal_cli-0.5.2/src/amsdal_cli/commands/serve/filters → amsdal_cli-0.5.4/src/amsdal_cli/commands/register_connection/utils}/__init__.py +0 -0
  196. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/build.py +0 -0
  197. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/config_updater.py +0 -0
  198. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/credentials.py +0 -0
  199. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/initialize.py +0 -0
  200. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/meta.py +0 -0
  201. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/migrate_models.py +0 -0
  202. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/model_generator.py +0 -0
  203. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/register_connection/utils/tables.py +0 -0
  204. {amsdal_cli-0.5.2/src/amsdal_cli/commands/serve/services → amsdal_cli-0.5.4/src/amsdal_cli/commands/restore}/__init__.py +0 -0
  205. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/restore/command.py +0 -0
  206. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/restore/enums.py +0 -0
  207. {amsdal_cli-0.5.2/src/amsdal_cli/commands/tests → amsdal_cli-0.5.4/src/amsdal_cli/commands/serve}/__init__.py +0 -0
  208. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/serve/command.py +0 -0
  209. {amsdal_cli-0.5.2/src/amsdal_cli/commands/verify → amsdal_cli-0.5.4/src/amsdal_cli/commands/serve/filters}/__init__.py +0 -0
  210. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/serve/filters/models_watch_filter.py +0 -0
  211. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/serve/filters/static_files_watch_filter.py +0 -0
  212. {amsdal_cli-0.5.2/src/amsdal_cli/commands/verify/utils → amsdal_cli-0.5.4/src/amsdal_cli/commands/serve/services}/__init__.py +0 -0
  213. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/serve/services/supervisor.py +0 -0
  214. {amsdal_cli-0.5.2/src/amsdal_cli/commands/worker → amsdal_cli-0.5.4/src/amsdal_cli/commands/tests}/__init__.py +0 -0
  215. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/tests/command.py +0 -0
  216. {amsdal_cli-0.5.2/src/amsdal_cli/config → amsdal_cli-0.5.4/src/amsdal_cli/commands/verify}/__init__.py +0 -0
  217. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/verify/command.py +0 -0
  218. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/verify/models.py +0 -0
  219. {amsdal_cli-0.5.2/src/amsdal_cli → amsdal_cli-0.5.4/src/amsdal_cli/commands/verify}/utils/__init__.py +0 -0
  220. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/verify/utils/verify_json_model.py +0 -0
  221. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/verify/utils/verify_python_file.py +0 -0
  222. /amsdal_cli-0.5.2/src/amsdal_cli/py.typed → /amsdal_cli-0.5.4/src/amsdal_cli/commands/worker/__init__.py +0 -0
  223. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/worker/app.py +0 -0
  224. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/worker/command.py +0 -0
  225. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/commands/worker/sub_commands/__init__.py +0 -0
  226. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/main.py +0 -0
  227. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/alias_group.py +0 -0
  228. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/check_versions.py +0 -0
  229. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/cli_config.py +0 -0
  230. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/copier.py +0 -0
  231. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/markdown_patch.py +0 -0
  232. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/render_template.py +0 -0
  233. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/schema_repository.py +0 -0
  234. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/text.py +0 -0
  235. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/vcs/__init__.py +0 -0
  236. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/vcs/base.py +0 -0
  237. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/vcs/dummy.py +0 -0
  238. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/vcs/enums.py +0 -0
  239. {amsdal_cli-0.5.2 → amsdal_cli-0.5.4}/src/amsdal_cli/utils/vcs/git.py +0 -0
@@ -2,6 +2,7 @@
2
2
  /.vscode
3
3
  /.env*
4
4
  venv
5
+ .venv
5
6
  coverage.*
6
7
  .coverage*
7
8
  .mypy_cache
@@ -0,0 +1,102 @@
1
+ # Project Guidelines
2
+
3
+ ## Project Overview
4
+
5
+ AMSDAL CLI is a command-line interface for the AMSDAL (A. Michael Salem Data Access Layer) framework. It provides tools for managing AMSDAL applications, including:
6
+
7
+ - Generating code from models
8
+ - Running a development server
9
+ - Managing migrations
10
+ - Testing and verification
11
+ - Cloud integration
12
+
13
+ The project is structured as follows:
14
+
15
+ - `src/amsdal_cli/` - Main source code
16
+ - `commands/` - CLI commands implementation
17
+ - `config/` - Configuration management
18
+ - `utils/` - Utility functions and helpers
19
+ - `tests/` - Test suite
20
+ - `async/` - Asynchronous tests
21
+ - `e2e/` - End-to-end tests
22
+ - `fixtures/` - Test fixtures
23
+ - `sync/` - Synchronous tests
24
+
25
+ The CLI is built using Typer and follows a command-based structure with subcommands organized in modules.
26
+
27
+ ## Code Style Guide
28
+
29
+ ### Python Version
30
+ - Target Python version: 3.11+
31
+ - Code should be compatible with Python 3.10+ for development
32
+
33
+ ### Formatting
34
+ - Line length: 120 characters
35
+ - Use Black for code formatting
36
+ - Use single quotes for strings, except for docstrings which use double quotes
37
+ - Imports should be on separate lines (no multi-imports)
38
+ - Imports should be ordered by type (standard library, third-party, first-party)
39
+
40
+ ### Type Annotations
41
+ - All code must use type annotations
42
+ - Use `typing.TYPE_CHECKING` for import-only type dependencies
43
+ - Follow strict mypy rules:
44
+ - No implicit reexports
45
+ - Disallow untyped definitions
46
+ - Disallow any generics
47
+ - Check untyped definitions
48
+
49
+ ### Linting
50
+ - Use Ruff for linting with the following rule sets enabled:
51
+ - A: flake8-builtins
52
+ - ARG: flake8-unused-arguments
53
+ - B: flake8-bugbear
54
+ - C: flake8-comprehensions
55
+ - DTZ: flake8-datetimez
56
+ - E: pycodestyle errors
57
+ - EM: flake8-errmsg
58
+ - F: pyflakes
59
+ - FBT: flake8-boolean-trap
60
+ - I: isort
61
+ - ICN: flake8-import-conventions
62
+ - ISC: flake8-implicit-str-concat
63
+ - N: pep8-naming
64
+ - PLC, PLE, PLR, PLW: pylint
65
+ - Q: flake8-quotes
66
+ - RUF: Ruff-specific rules
67
+ - S: flake8-bandit
68
+ - T: flake8-debugger
69
+ - TID: flake8-tidy-imports
70
+ - UP: pyupgrade
71
+ - W: pycodestyle warnings
72
+ - YTT: flake8-2020
73
+
74
+ ### Imports
75
+ - No relative imports
76
+ - Group imports by source (standard library, third-party, first-party)
77
+ - Known first-party modules: amsdal_cli
78
+
79
+ ### Documentation
80
+ - Use docstrings for functions, classes, and modules
81
+ - Use markdown formatting in docstrings
82
+ - Include help text for CLI commands and options
83
+
84
+ ### Testing
85
+ - Write tests for all functionality
86
+ - Use pytest for testing
87
+ - Include both synchronous and asynchronous tests where appropriate
88
+ - Use fixtures for test data
89
+ - Aim for high test coverage
90
+
91
+ ### Error Handling
92
+ - Use appropriate exception handling with try/except/finally blocks
93
+ - Properly clean up resources in finally blocks
94
+
95
+ ### Asynchronous Code
96
+ - Support both synchronous and asynchronous execution paths where needed
97
+ - Use asyncio for asynchronous code
98
+ - Follow asyncio best practices
99
+
100
+ ### Version Control
101
+ - Use towncrier for managing release notes
102
+ - Organize changes by type (security, removed, deprecated, added, changed, fixed, performance)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amsdal_cli
3
- Version: 0.5.2
3
+ Version: 0.5.4
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/
@@ -125,6 +125,7 @@ Requires-Dist: amsdal-server==0.5.*
125
125
  Requires-Dist: click<8.2.0
126
126
  Requires-Dist: faker==27.*
127
127
  Requires-Dist: gitpython~=3.1
128
+ Requires-Dist: httpx==0.28.*
128
129
  Requires-Dist: jinja2~=3.1
129
130
  Requires-Dist: pydantic-settings~=2.2
130
131
  Requires-Dist: pydantic~=2.3
@@ -1,3 +1,15 @@
1
+ ## [v0.5.4](https://pypi.org/project/amsdal_cli/0.5.4/) - 2025-08-14
2
+
3
+ ### Added
4
+
5
+ - Plugin commands
6
+
7
+ ## [v0.5.3](https://pypi.org/project/amsdal_cli/0.5.3/) - 2025-08-01
8
+
9
+ ### Changed
10
+
11
+ - Switched to use `uv` package manager
12
+
1
13
  ## [v0.5.2](https://pypi.org/project/amsdal_cli/0.5.2/) - 2025-07-11
2
14
 
3
15
  ### Added
@@ -0,0 +1,5 @@
1
+ ## [v0.5.4](https://pypi.org/project/amsdal_cli/0.5.4/) - 2025-08-14
2
+
3
+ ### Added
4
+
5
+ - Plugin commands
@@ -41,6 +41,32 @@ dependencies = [
41
41
  "GitPython~=3.1",
42
42
  "amsdal-server==0.5.*",
43
43
  "faker==27.*",
44
+ "httpx==0.28.*",
45
+ ]
46
+
47
+ [dependency-groups]
48
+ dev = [
49
+ "amsdal[async-sqlite]",
50
+ "amsdal[postgres-binary]",
51
+ "coverage[toml]>=7.4",
52
+ "pytest-cov>=6.0.0",
53
+ "pytest==8.4.1",
54
+ "pytest-mock==3.14.1",
55
+ "pytest-asyncio>=1.1.0",
56
+ "pytest-xdist[psutil]>=3.8.0",
57
+ "black>=24.3.0",
58
+ "mypy>=1.17.0",
59
+ "ruff>=0.12.4",
60
+ "towncrier==23.11.0",
61
+ "types-ujson",
62
+ "types-PyYAML",
63
+ "types-pytz",
64
+ "types-pexpect",
65
+ "types-docutils",
66
+ "types-defusedxml",
67
+ "types-colorama",
68
+ "types-Pygments",
69
+ "pandas-stubs",
44
70
  ]
45
71
 
46
72
  [tool.hatch.envs.default.env-vars]
@@ -61,25 +87,16 @@ allow-direct-references = true
61
87
  path = "src/amsdal_cli/__about__.py"
62
88
 
63
89
  [[tool.hatch.envs.all.matrix]]
64
- python = ["3.10", "3.11", "3.12"]
90
+ python = ["3.11", "3.12"]
65
91
 
66
92
  [tool.hatch.envs.default]
67
- path = "../.venv/amsdal_cli"
68
- dependencies = [
69
- "coverage[toml]>=7.4",
70
- "pytest-cov>=6.0.0",
71
- "pytest==8.3.4",
72
- "pytest-mock==3.14.0",
73
- "pytest-asyncio>=0.25.3",
74
- "pytest-xdist[psutil]>=3.6.1",
75
- "black>=24.3.0",
76
- "mypy>=1.15.0",
77
- "ruff>=0.11.0",
78
- "towncrier==23.11.0",
79
- "aiosqlite",
80
- ]
93
+ installer = "uv"
94
+ path = ".venv"
81
95
 
82
96
  [tool.hatch.envs.default.scripts]
97
+ sync = "uv sync --group dev"
98
+ lock = "uv lock"
99
+ lock-upgrade = "uv lock --upgrade"
83
100
  test = "pytest -n auto {args:tests}"
84
101
  test-single = "pytest -vvv {args:tests}"
85
102
  test-cov = "pytest -n auto --cov=src {args:tests}"
@@ -107,31 +124,23 @@ release = "rm latest-changelogs.md && towncrier build --yes --version {args:vers
107
124
  COLUMNS = "200"
108
125
 
109
126
  [tool.hatch.envs.local]
110
- template = "local"
111
- path = "../.venv/amsdal_cli_local"
112
- dependencies = [
113
- "pytest-cov>=6.0.0",
114
- "pytest==8.3.4",
115
- "pytest-mock==3.14.0",
116
- "pytest-asyncio>=0.25.3",
117
- "pytest-xdist[psutil]>=3.6.1",
118
- "black>=24.3.0",
119
- "mypy>=1.15.0",
120
- "ruff>=0.11.0",
121
- "aiosqlite",
122
- ]
127
+ installer = "uv"
128
+ path = ".venv"
123
129
  pre-install-commands = [
124
- "pip install -e ../amsdal-glue/libs/core/",
125
- "pip install -e ../amsdal-glue/libs/connections/[postgres-binary]",
126
- "pip install -e ../amsdal-glue/libs/amsdal-glue/",
127
- "pip install -e ../amsdal_utils/",
128
- "pip install -e ../amsdal_data/",
129
- "pip install -e ../amsdal_models/",
130
- "pip install -e ../amsdal_framework/",
131
- "pip install -e ../amsdal_server/",
130
+ "uv pip install -e ../amsdal-glue/libs/core/",
131
+ "uv pip install -e ../amsdal-glue/libs/connections/",
132
+ "uv pip install -e ../amsdal-glue/libs/amsdal-glue/",
133
+ "uv pip install -e ../amsdal_utils/",
134
+ "uv pip install -e ../amsdal_data/",
135
+ "uv pip install -e ../amsdal_models/",
136
+ "uv pip install -e ../amsdal_framework/",
137
+ "uv pip install -e ../amsdal_server/",
132
138
  ]
133
139
 
134
140
  [tool.hatch.envs.local.scripts]
141
+ sync = "uv sync --group dev"
142
+ lock = "uv lock"
143
+ lock-upgrade = "uv lock --upgrade"
135
144
  test = "pytest -n auto {args:tests}"
136
145
  test-single = "pytest -vvv {args:tests}"
137
146
  test-cov = "pytest -n auto --cov=src {args:tests}"
@@ -155,10 +164,10 @@ all = [
155
164
 
156
165
 
157
166
  [tool.black]
158
- target-version = ["py310"]
167
+ target-version = ["py311"]
159
168
  line-length = 120
160
169
  skip-string-normalization = true
161
- exclude = "tests/fixtures/*"
170
+ exclude = "tests/fixtures/*|.venv|src/amsdal_cli/commands/plugin/templates/*"
162
171
 
163
172
  [tool.mypy]
164
173
  plugins = ["pydantic.mypy"]
@@ -168,7 +177,7 @@ warn_unused_ignores = true
168
177
  disallow_any_generics = true
169
178
  check_untyped_defs = true
170
179
  no_implicit_reexport = true
171
- exclude = "tests/fixtures/*"
180
+ exclude = "tests/fixtures/*|src/amsdal_cli/commands/plugin/templates/*"
172
181
 
173
182
  # for strict mypy: (this is the tricky one :-))
174
183
  disallow_untyped_defs = true
@@ -190,7 +199,7 @@ warn_required_dynamic_aliases = true
190
199
  [tool.ruff]
191
200
  target-version = "py310"
192
201
  line-length = 120
193
- exclude = ["tests/fixtures/"]
202
+ exclude = ["tests/fixtures/", "src/amsdal_cli/commands/plugin/templates/"]
194
203
 
195
204
  [tool.ruff.lint]
196
205
  select = [
@@ -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.2'
4
+ __version__ = '0.5.4'
@@ -0,0 +1,118 @@
1
+ from pathlib import Path
2
+ from typing import Optional
3
+
4
+ import typer
5
+
6
+ from amsdal_cli.app import app
7
+ from amsdal_cli.commands.api_check.config import ApiCheckConfig
8
+ from amsdal_cli.commands.api_check.services.comparison import check
9
+ from amsdal_cli.commands.api_check.services.loader import load_operation_logs
10
+ from amsdal_cli.commands.api_check.services.runner import ApiRunner
11
+ from amsdal_cli.commands.api_check.services.storage import save
12
+
13
+
14
+ @app.command(name='api-check')
15
+ def api_check(
16
+ target_url: str = typer.Argument( # noqa: B008
17
+ ...,
18
+ help='Target API base URL to test',
19
+ ),
20
+ config_file: Path = typer.Option( # noqa: B008
21
+ Path('api-check-config.json'),
22
+ '--config',
23
+ '-c',
24
+ help='Path to configuration file (YAML or JSON) with test cases and auth settings',
25
+ exists=True,
26
+ ),
27
+ compare_url: Optional[str] = typer.Option( # noqa: B008
28
+ None,
29
+ '--compare-url',
30
+ help='Second API base URL to compare against',
31
+ ),
32
+ compare_logs: Optional[Path] = typer.Option( # noqa: B008
33
+ None,
34
+ '--compare-logs',
35
+ help='Path to existing logs file to compare against',
36
+ exists=True,
37
+ ),
38
+ output_logs: Optional[Path] = typer.Option( # noqa: B008
39
+ None,
40
+ '--output',
41
+ '-o',
42
+ help='Path to save output logs',
43
+ ),
44
+ ) -> None:
45
+ """
46
+ Run API tests against target URL and compare results with another endpoint or saved logs.
47
+
48
+ The command requires a configuration file (in YAML or JSON format) that defines:
49
+ - Test cases with inputs and expected outputs
50
+ - Authentication settings
51
+ - Endpoints to test
52
+
53
+ Authentication can be configured using environment variables:
54
+ - AMSDAL_API_CHECK_AUTHORIZATION: Authorization token
55
+ - AMSDAL_API_CHECK_EMAIL: Email for authentication
56
+ - AMSDAL_API_CHECK_PASSWORD: Password for authentication
57
+
58
+ If the token is invalid and no credentials are provided, the command will exit with an error.
59
+
60
+ Examples:
61
+
62
+ 1. Save logs to a file without comparison:
63
+ ```
64
+ amsdal api-check https://api.example.com --compare-url https://api.example.com --output logs.json
65
+ ```
66
+ This uses the same URL for both target and comparison, which skips the comparison
67
+ but still runs the API checks and saves the logs.
68
+
69
+ 2. Compare a URL with previously saved logs:
70
+ ```
71
+ amsdal api-check https://api.example.com --compare-logs previous-logs.json
72
+ ```
73
+ This runs API checks against the target URL and compares the results with
74
+ the logs stored in previous-logs.json.
75
+
76
+ 3. Compare two different URLs:
77
+ ```
78
+ amsdal api-check https://api-prod.example.com --compare-url https://api-staging.example.com
79
+ ```
80
+ This runs API checks against both URLs and compares the results.
81
+
82
+ You can combine these options as needed:
83
+ ```
84
+ amsdal api-check https://api-prod.example.com --compare-url https://api-staging.example.com \
85
+ --output comparison.json
86
+ ```
87
+ This compares the two URLs and also saves the logs from the target URL.
88
+ """
89
+ if not compare_url and not compare_logs:
90
+ msg = 'Either --compare-url or --compare-logs must be provided'
91
+ raise typer.BadParameter(msg)
92
+
93
+ if compare_url and compare_logs:
94
+ msg = 'Cannot use both --compare-url and --compare-logs simultaneously'
95
+ raise typer.BadParameter(msg)
96
+
97
+ # Load configuration using the class method
98
+ config = ApiCheckConfig.load_from_file(config_file)
99
+
100
+ # Create runner with the loaded config
101
+ target_runner = ApiRunner(target_url, config)
102
+ target_logs_data = target_runner.run()
103
+ has_errors = False
104
+
105
+ if compare_url != target_url:
106
+ if compare_url:
107
+ compare_runner = ApiRunner(compare_url, config)
108
+ compare_logs_data = compare_runner.run()
109
+ else:
110
+ compare_logs_data = load_operation_logs(compare_logs) # type: ignore[arg-type]
111
+
112
+ has_errors = check(target_logs_data, compare_logs_data)
113
+
114
+ if output_logs:
115
+ save(target_logs_data, destination=output_logs)
116
+
117
+ if has_errors:
118
+ raise typer.Exit(code=1)
@@ -0,0 +1,192 @@
1
+ import json
2
+ import logging
3
+ import os
4
+ from collections.abc import Callable
5
+ from pathlib import Path
6
+ from typing import Any
7
+ from typing import ClassVar
8
+ from typing import Literal
9
+ from typing import Optional
10
+
11
+ import yaml
12
+ from pydantic import BaseModel
13
+ from pydantic import Field
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class TransactionData(BaseModel):
19
+ transaction_name: str
20
+ input_params: dict[str, Any] = Field(default_factory=dict)
21
+ expected_response: Any = None
22
+
23
+
24
+ class ApiCheckConfig(BaseModel):
25
+ # Class variable to store the config file path
26
+ _config_file: ClassVar[Optional[Path]] = None
27
+
28
+ items_per_list: tuple[int, int, int] = (5, 5, 5)
29
+ headers: dict[str, str] = Field(default_factory=dict)
30
+ auth_headers: dict[str, str] = Field(default_factory=dict)
31
+ request_timeout: int = 600
32
+ extend_output: bool = True
33
+
34
+ # Authentication
35
+ email: Optional[str] = None
36
+ password: Optional[str] = None
37
+
38
+ @property
39
+ def token(self) -> Optional[str]:
40
+ """
41
+ Get the token from auth_headers.
42
+
43
+ Returns:
44
+ Optional[str]: The token or None if not set
45
+ """
46
+ if not self.auth_headers or 'Authorization' not in self.auth_headers:
47
+ return None
48
+
49
+ return self.auth_headers['Authorization']
50
+
51
+ @token.setter
52
+ def token(self, value: Optional[str]) -> None:
53
+ """
54
+ Set the token in auth_headers.
55
+
56
+ Args:
57
+ value: The token value
58
+ """
59
+ if value is None:
60
+ if 'Authorization' in self.auth_headers:
61
+ del self.auth_headers['Authorization']
62
+ else:
63
+ self.auth_headers['Authorization'] = value
64
+
65
+ @property
66
+ def token_expiry(self) -> Optional[int]:
67
+ """
68
+ Get the token expiry from the token.
69
+
70
+ Returns:
71
+ Optional[int]: The token expiry timestamp, or None if not available
72
+ """
73
+ if not self.token:
74
+ return None
75
+
76
+ try:
77
+ import jwt
78
+
79
+ decoded = jwt.decode(self.token, options={'verify_signature': False})
80
+ return decoded.get('exp')
81
+ except Exception as e:
82
+ logger.warning(f'Failed to decode token: {e}')
83
+ return None
84
+
85
+ @property
86
+ def env_authorization(self) -> Optional[str]:
87
+ """Get authorization token from environment variable."""
88
+ return os.environ.get('AMSDAL_API_CHECK_AUTHORIZATION')
89
+
90
+ @property
91
+ def env_email(self) -> Optional[str]:
92
+ """Get email from environment variable."""
93
+ return os.environ.get('AMSDAL_API_CHECK_EMAIL')
94
+
95
+ @property
96
+ def env_password(self) -> Optional[str]:
97
+ """Get password from environment variable."""
98
+ return os.environ.get('AMSDAL_API_CHECK_PASSWORD')
99
+
100
+ @classmethod
101
+ def load_from_file(cls, config_file: str | Path) -> 'ApiCheckConfig':
102
+ """
103
+ Load configuration from a file.
104
+
105
+ Args:
106
+ config_file: Path to the configuration file (YAML or JSON)
107
+
108
+ Returns:
109
+ ApiCheckConfig: The loaded configuration
110
+ """
111
+ config_path = Path(config_file)
112
+
113
+ try:
114
+ with open(config_path) as f:
115
+ # Determine file format based on extension
116
+ if config_path.suffix.lower() in ['.yaml', '.yml']:
117
+ config_raw = yaml.safe_load(f)
118
+ elif config_path.suffix.lower() == '.json':
119
+ config_raw = json.load(f)
120
+ else:
121
+ # Default to YAML if extension is not recognized
122
+ config_raw = yaml.safe_load(f)
123
+
124
+ # Create config instance
125
+ config = cls(**config_raw)
126
+ # Store the config file path
127
+ cls._config_file = config_path
128
+
129
+ logger.info(f'Configuration loaded from {config_path}')
130
+ return config
131
+ except Exception as e:
132
+ logger.error(f'Failed to load configuration from {config_path}: {e}')
133
+ raise
134
+
135
+ def save(self, config_file: Optional[str | Path] = None) -> None:
136
+ """
137
+ Save the current configuration to a file.
138
+
139
+ Email and password values provided through environment variables
140
+ (AMSDAL_API_CHECK_EMAIL, AMSDAL_API_CHECK_PASSWORD) will not be saved to the file.
141
+ Only the token and other configuration values will be persisted.
142
+
143
+ Args:
144
+ config_file: Path to save the configuration to. If not provided,
145
+ uses the path from which the config was loaded.
146
+ """
147
+ # Use provided path or fall back to the stored path
148
+ save_path = Path(config_file) if config_file else self.__class__._config_file
149
+
150
+ if not save_path:
151
+ logger.warning('No config file specified, cannot save configuration')
152
+ return
153
+
154
+ try:
155
+ # Convert config to dict
156
+ config_dict = self.model_dump()
157
+
158
+ # Don't save email and password if they were provided through environment variables
159
+ if self.env_email and self.email == self.env_email:
160
+ config_dict.pop('email', None)
161
+
162
+ if self.env_password and self.password == self.env_password:
163
+ config_dict.pop('password', None)
164
+
165
+ # No need to handle token and token_expiry as they are now properties
166
+ # and not included in the model_dump()
167
+
168
+ # Write to file
169
+ with open(save_path, 'w') as f:
170
+ json.dump(config_dict, f, indent=2)
171
+
172
+ logger.info(f'Configuration saved to {save_path}')
173
+ except Exception as e:
174
+ logger.error(f'Failed to save configuration: {e}')
175
+
176
+ # classes
177
+ exclude_classes: list[str] | Literal['ALL'] = Field(default_factory=list)
178
+
179
+ # objects
180
+ exclude_objects_for_classes: list[str] = Field(default_factory=list)
181
+ objects_list_params_options: list[dict[str, Any]] = Field(default_factory=list)
182
+ object_detail_params_options: list[dict[str, Any]] = Field(default_factory=list)
183
+ object_write_operations_enabled: bool = Field(default=False)
184
+ exclude_object_write_operations_for_classes: list[str] = Field(default_factory=list)
185
+ pre_object_create_hook: Callable[[dict[str, Any]], dict[str, Any]] | dict[str, Any] = Field(default_factory=dict)
186
+ pre_object_update_hook: Callable[[dict[str, Any]], dict[str, Any]] | dict[str, Any] = Field(default_factory=dict)
187
+
188
+ # transactions
189
+ ignore_transaction_execution_errors: bool = Field(default=True)
190
+ exclude_transactions: list[str] | Literal['ALL'] = Field(default_factory=list)
191
+ exclude_execute_transactions: list[str] | Literal['ALL'] = Field(default_factory=list)
192
+ transactions_data: list[TransactionData] = Field(default_factory=list)
@@ -0,0 +1,13 @@
1
+ from typing import Any
2
+
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class ClassItem(BaseModel):
7
+ class_name: str
8
+ properties: list[dict[str, Any]]
9
+
10
+
11
+ class Transaction(BaseModel):
12
+ title: str
13
+ properties: dict[str, Any]