instant-python 0.17.0__tar.gz → 0.18.1__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 (312) hide show
  1. {instant_python-0.17.0 → instant_python-0.18.1}/CHANGELOG.md +43 -0
  2. {instant_python-0.17.0 → instant_python-0.18.1}/PKG-INFO +14 -6
  3. {instant_python-0.17.0 → instant_python-0.18.1}/README.md +13 -5
  4. {instant_python-0.17.0 → instant_python-0.18.1}/docs/guide/default_features.md +31 -280
  5. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/persistence/yaml_config_repository.py +5 -1
  6. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/application.py +10 -1
  7. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/error_handlers.py +28 -1
  8. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/pyproject.toml +3 -3
  9. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/clean_architecture/test.yml.j2 +2 -11
  10. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/domain_driven_design/test.yml.j2 +5 -10
  11. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/standard_project/test.yml.j2 +3 -8
  12. instant_python-0.18.1/instant_python/templates/project_structure/value_objects.yml.j2 +12 -0
  13. {instant_python-0.17.0 → instant_python-0.18.1}/pyproject.toml +1 -1
  14. {instant_python-0.17.0 → instant_python-0.18.1}/uv.lock +1 -1
  15. instant_python-0.17.0/instant_python/templates/boilerplate/exceptions/incorrect_value_type_error.py +0 -10
  16. instant_python-0.17.0/instant_python/templates/boilerplate/exceptions/invalid_id_format_error.py +0 -6
  17. instant_python-0.17.0/instant_python/templates/boilerplate/exceptions/invalid_negative_value_error.py +0 -6
  18. instant_python-0.17.0/instant_python/templates/boilerplate/random_generator.py +0 -18
  19. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/aggregate.py +0 -98
  20. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/int_primitives_mother.py +0 -7
  21. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/int_value_object.py +0 -22
  22. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/string_primitives_mother.py +0 -7
  23. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/string_value_object.py +0 -16
  24. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/test_int_value_object.py +0 -84
  25. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/test_string_value_object.py +0 -74
  26. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/test_uuid_value_object.py +0 -87
  27. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/uuid.py +0 -26
  28. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/uuid_primitives_mother.py +0 -11
  29. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/validation.py +0 -7
  30. instant_python-0.17.0/instant_python/templates/boilerplate/value_object/value_object.py +0 -127
  31. instant_python-0.17.0/instant_python/templates/project_structure/test_value_objects.yml.j2 +0 -32
  32. instant_python-0.17.0/instant_python/templates/project_structure/value_objects.yml.j2 +0 -64
  33. instant_python-0.17.0/test/shared/domain/mothers/__init__.py +0 -0
  34. {instant_python-0.17.0 → instant_python-0.18.1}/.github/FUNDING.yml +0 -0
  35. {instant_python-0.17.0 → instant_python-0.18.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  36. {instant_python-0.17.0 → instant_python-0.18.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  37. {instant_python-0.17.0 → instant_python-0.18.1}/.github/actions/python_setup/action.yml +0 -0
  38. {instant_python-0.17.0 → instant_python-0.18.1}/.github/pull_request_template.md +0 -0
  39. {instant_python-0.17.0 → instant_python-0.18.1}/.github/workflows/ci.yml +0 -0
  40. {instant_python-0.17.0 → instant_python-0.18.1}/.github/workflows/pages.yml +0 -0
  41. {instant_python-0.17.0 → instant_python-0.18.1}/.github/workflows/release.yml +0 -0
  42. {instant_python-0.17.0 → instant_python-0.18.1}/.gitignore +0 -0
  43. {instant_python-0.17.0 → instant_python-0.18.1}/.pre-commit-config.yaml +0 -0
  44. {instant_python-0.17.0 → instant_python-0.18.1}/.python-version +0 -0
  45. {instant_python-0.17.0 → instant_python-0.18.1}/CITATION.cff +0 -0
  46. {instant_python-0.17.0 → instant_python-0.18.1}/LICENSE +0 -0
  47. {instant_python-0.17.0 → instant_python-0.18.1}/SECURITY.md +0 -0
  48. {instant_python-0.17.0 → instant_python-0.18.1}/codeql-config.yml +0 -0
  49. {instant_python-0.17.0 → instant_python-0.18.1}/docs/assets/favicon.svg +0 -0
  50. {instant_python-0.17.0 → instant_python-0.18.1}/docs/assets/logo.svg +0 -0
  51. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/changelog_header.md.j2 +0 -0
  52. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/changelog_init.md.j2 +0 -0
  53. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/changelog_update.md.j2 +0 -0
  54. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/changes.md.j2 +0 -0
  55. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/first_release.md.j2 +0 -0
  56. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/macros.md.j2 +0 -0
  57. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.components/versioned_changes.md.j2 +0 -0
  58. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/.release_notes.md.j2 +0 -0
  59. {instant_python-0.17.0 → instant_python-0.18.1}/docs/changelog/CHANGELOG.md.j2 +0 -0
  60. {instant_python-0.17.0 → instant_python-0.18.1}/docs/development/contributing.md +0 -0
  61. {instant_python-0.17.0 → instant_python-0.18.1}/docs/development/releases.md +0 -0
  62. {instant_python-0.17.0 → instant_python-0.18.1}/docs/development/security.md +0 -0
  63. {instant_python-0.17.0 → instant_python-0.18.1}/docs/downloads_macro.py +0 -0
  64. {instant_python-0.17.0 → instant_python-0.18.1}/docs/getting_started/first_steps.md +0 -0
  65. {instant_python-0.17.0 → instant_python-0.18.1}/docs/getting_started/installation.md +0 -0
  66. {instant_python-0.17.0 → instant_python-0.18.1}/docs/guide/command_config.md +0 -0
  67. {instant_python-0.17.0 → instant_python-0.18.1}/docs/guide/command_init.md +0 -0
  68. {instant_python-0.17.0 → instant_python-0.18.1}/docs/guide/custom_projects.md +0 -0
  69. {instant_python-0.17.0 → instant_python-0.18.1}/docs/guide/index.md +0 -0
  70. {instant_python-0.17.0 → instant_python-0.18.1}/docs/home/index.md +0 -0
  71. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/__init__.py +0 -0
  72. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/cli/__init__.py +0 -0
  73. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/cli/cli.py +0 -0
  74. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/cli/instant_python_typer.py +0 -0
  75. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/__init__.py +0 -0
  76. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/application/__init__.py +0 -0
  77. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/application/config_generator.py +0 -0
  78. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/delivery/__init__.py +0 -0
  79. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/delivery/cli.py +0 -0
  80. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/domain/__init__.py +0 -0
  81. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/domain/config_writer.py +0 -0
  82. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/domain/question_wizard.py +0 -0
  83. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/__init__.py +0 -0
  84. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/__init__.py +0 -0
  85. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/questionary_console_wizard.py +0 -0
  86. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/__init__.py +0 -0
  87. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/dependencies_step.py +0 -0
  88. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/general_step.py +0 -0
  89. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/git_step.py +0 -0
  90. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/questionary.py +0 -0
  91. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/steps.py +0 -0
  92. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/question_wizard/step/template_step.py +0 -0
  93. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/writer/__init__.py +0 -0
  94. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/config/infra/writer/yaml_config_writer.py +0 -0
  95. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/__init__.py +0 -0
  96. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/application/__init__.py +0 -0
  97. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/application/project_initializer.py +0 -0
  98. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/delivery/__init__.py +0 -0
  99. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/delivery/cli.py +0 -0
  100. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/__init__.py +0 -0
  101. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/config_repository.py +0 -0
  102. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/env_manager.py +0 -0
  103. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/node.py +0 -0
  104. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/project_formatter.py +0 -0
  105. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/project_renderer.py +0 -0
  106. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/project_structure.py +0 -0
  107. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/project_writer.py +0 -0
  108. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/domain/version_control_configurer.py +0 -0
  109. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/__init__.py +0 -0
  110. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/env_manager/__init__.py +0 -0
  111. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/env_manager/env_manager_factory.py +0 -0
  112. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/env_manager/pdm_env_manager.py +0 -0
  113. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/env_manager/system_console.py +0 -0
  114. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/env_manager/uv_env_manager.py +0 -0
  115. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/formatter/__init__.py +0 -0
  116. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/formatter/ruff_project_formatter.py +0 -0
  117. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/persistence/__init__.py +0 -0
  118. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/renderer/__init__.py +0 -0
  119. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/renderer/jinja_environment.py +0 -0
  120. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/renderer/jinja_project_renderer.py +0 -0
  121. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/version_control/__init__.py +0 -0
  122. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/version_control/git_configurer.py +0 -0
  123. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/writer/__init__.py +0 -0
  124. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/initialize/infra/writer/file_system_project_writer.py +0 -0
  125. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/__init__.py +0 -0
  126. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/application_error.py +0 -0
  127. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/domain/__init__.py +0 -0
  128. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/domain/config_schema.py +0 -0
  129. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/domain/dependency_config.py +0 -0
  130. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/domain/general_config.py +0 -0
  131. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/domain/git_config.py +0 -0
  132. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/domain/template_config.py +0 -0
  133. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/supported_built_in_features.py +0 -0
  134. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/supported_licenses.py +0 -0
  135. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/supported_managers.py +0 -0
  136. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/supported_python_versions.py +0 -0
  137. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/shared/supported_templates.py +0 -0
  138. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/.gitignore +0 -0
  139. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/.pre-commit-config.yml +0 -0
  140. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/.python-version +0 -0
  141. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/CITATION.cff +0 -0
  142. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/LICENSE +0 -0
  143. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/README.md +0 -0
  144. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/SECURITY.md +0 -0
  145. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/__init__.py +0 -0
  146. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/domain_event.py +0 -0
  147. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/domain_event_json_deserializer.py +0 -0
  148. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/domain_event_json_serializer.py +0 -0
  149. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/domain_event_subscriber.py +0 -0
  150. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/event_aggregate.py +0 -0
  151. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/event_bus.py +0 -0
  152. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/exchange_type.py +0 -0
  153. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/mock_event_bus.py +0 -0
  154. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/rabbit_mq_configurer.py +0 -0
  155. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/rabbit_mq_connection.py +0 -0
  156. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/rabbit_mq_consumer.py +0 -0
  157. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/rabbit_mq_event_bus.py +0 -0
  158. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/rabbit_mq_queue_formatter.py +0 -0
  159. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/event_bus/rabbit_mq_settings.py +0 -0
  160. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/exceptions/__init__.py +0 -0
  161. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/exceptions/base_error.py +0 -0
  162. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/exceptions/domain_error.py +0 -0
  163. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/exceptions/domain_event_type_not_found_error.py +0 -0
  164. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/exceptions/rabbit_mq_connection_not_established_error.py +0 -0
  165. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/exceptions/required_value_error.py +0 -0
  166. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/__init__.py +0 -0
  167. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/error_response.py +0 -0
  168. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/fastapi_log_middleware.py +0 -0
  169. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/lifespan.py +0 -0
  170. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/fastapi/success_response.py +0 -0
  171. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/github/action.yml +0 -0
  172. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/github/bug_report.yml +0 -0
  173. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/github/ci.yml +0 -0
  174. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/github/feature_request.yml +0 -0
  175. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/github/release.yml +0 -0
  176. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/logger/__init__.py +0 -0
  177. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/logger/file_logger.py +0 -0
  178. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/logger/file_rotating_handler.py +0 -0
  179. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/logger/json_formatter.py +0 -0
  180. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/mypy.ini +0 -0
  181. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/__init__.py +0 -0
  182. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/alembic_migrator.py +0 -0
  183. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/README.md +0 -0
  184. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/__init__.py +0 -0
  185. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/alembic.ini +0 -0
  186. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/async_engine_fixture.py +0 -0
  187. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/async_session.py +0 -0
  188. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/env.py +0 -0
  189. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/models_metadata.py +0 -0
  190. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/postgres_settings.py +0 -0
  191. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/script.py.mako +0 -0
  192. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/async/sqlalchemy_repository.py +0 -0
  193. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/base.py +0 -0
  194. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/synchronous/__init__.py +0 -0
  195. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/synchronous/session_maker.py +0 -0
  196. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/persistence/synchronous/sqlalchemy_repository.py +0 -0
  197. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/pytest.ini +0 -0
  198. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/add_dependency.py +0 -0
  199. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/create_aggregate.py +0 -0
  200. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/insert_template.py +0 -0
  201. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/integration.sh +0 -0
  202. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/local_setup.py +0 -0
  203. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/makefile +0 -0
  204. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/post-merge.py +0 -0
  205. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/pre-commit.py +0 -0
  206. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/pre-push.py +0 -0
  207. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/remove_dependency.py +0 -0
  208. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/boilerplate/scripts/unit.sh +0 -0
  209. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/alembic_migrator.yml.j2 +0 -0
  210. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/async_alembic.yml.j2 +0 -0
  211. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/async_sqlalchemy.yml.j2 +0 -0
  212. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/citation.yml.j2 +0 -0
  213. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/clean_architecture/main_structure.yml.j2 +0 -0
  214. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/clean_architecture/source.yml.j2 +0 -0
  215. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/domain_driven_design/bounded_context.yml.j2 +0 -0
  216. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/domain_driven_design/main_structure.yml.j2 +0 -0
  217. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/domain_driven_design/source.yml.j2 +0 -0
  218. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/event_bus_domain.yml.j2 +0 -0
  219. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/event_bus_infra.yml.j2 +0 -0
  220. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/fastapi_app.yml.j2 +0 -0
  221. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/fastapi_domain.yml.j2 +0 -0
  222. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/fastapi_infra.yml.j2 +0 -0
  223. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/github_action.yml.j2 +0 -0
  224. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/github_issues_template.yml.j2 +0 -0
  225. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/gitignore.yml.j2 +0 -0
  226. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/license.yml.j2 +0 -0
  227. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/logger.yml.j2 +0 -0
  228. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/macros.j2 +0 -0
  229. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/makefile.yml.j2 +0 -0
  230. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/mypy.yml.j2 +0 -0
  231. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/persistence.yml.j2 +0 -0
  232. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/precommit_hook.yml.j2 +0 -0
  233. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/pyproject.yml.j2 +0 -0
  234. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/pytest.yml.j2 +0 -0
  235. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/python_version.yml.j2 +0 -0
  236. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/readme.yml.j2 +0 -0
  237. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/security.yml.j2 +0 -0
  238. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/standard_project/main_structure.yml.j2 +0 -0
  239. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/standard_project/source.yml.j2 +0 -0
  240. {instant_python-0.17.0 → instant_python-0.18.1}/instant_python/templates/project_structure/synchronous_sqlalchemy.yml.j2 +0 -0
  241. {instant_python-0.17.0 → instant_python-0.18.1}/makefile +0 -0
  242. {instant_python-0.17.0 → instant_python-0.18.1}/mkdocs.yml +0 -0
  243. {instant_python-0.17.0 → instant_python-0.18.1}/mypy.ini +0 -0
  244. {instant_python-0.17.0 → instant_python-0.18.1}/scripts/add_dependency.py +0 -0
  245. {instant_python-0.17.0 → instant_python-0.18.1}/scripts/remove_dependency.py +0 -0
  246. {instant_python-0.17.0/instant_python/templates/boilerplate/value_object → instant_python-0.18.1/test}/__init__.py +0 -0
  247. {instant_python-0.17.0/test → instant_python-0.18.1/test/config}/__init__.py +0 -0
  248. {instant_python-0.17.0/test/config → instant_python-0.18.1/test/config/application}/__init__.py +0 -0
  249. {instant_python-0.17.0 → instant_python-0.18.1}/test/config/application/test_config_generator.py +0 -0
  250. {instant_python-0.17.0/test/config/application → instant_python-0.18.1/test/config/infra}/__init__.py +0 -0
  251. {instant_python-0.17.0/test/config/infra → instant_python-0.18.1/test/config/infra/writer}/__init__.py +0 -0
  252. {instant_python-0.17.0 → instant_python-0.18.1}/test/config/infra/writer/test_yaml_config_writer.py +0 -0
  253. {instant_python-0.17.0/test/config/infra/writer → instant_python-0.18.1/test/initialize}/__init__.py +0 -0
  254. {instant_python-0.17.0/test/initialize → instant_python-0.18.1/test/initialize/application}/__init__.py +0 -0
  255. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/application/test_project_initializer.py +0 -0
  256. {instant_python-0.17.0/test/initialize/application → instant_python-0.18.1/test/initialize/delivery}/__init__.py +0 -0
  257. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/approvaltests_config.json +0 -0
  258. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_custom_project_structure.approved.txt +0 -0
  259. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_general_section_combinations.approved.txt +0 -0
  260. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_git_section_combinations.approved.txt +0 -0
  261. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_predefined_dependencies_and_different_managers.approved.txt +0 -0
  262. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_template_section_combinations.approved.txt +0 -0
  263. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/delivery/test_init_cli.py +0 -0
  264. {instant_python-0.17.0/test/initialize/delivery → instant_python-0.18.1/test/initialize/domain}/__init__.py +0 -0
  265. {instant_python-0.17.0/test/initialize/domain → instant_python-0.18.1/test/initialize/domain/mothers}/__init__.py +0 -0
  266. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/domain/mothers/node_mother.py +0 -0
  267. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/domain/mothers/project_structure_mother.py +0 -0
  268. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/domain/test_node.py +0 -0
  269. {instant_python-0.17.0/test/initialize/domain/mothers → instant_python-0.18.1/test/initialize/infra}/__init__.py +0 -0
  270. {instant_python-0.17.0/test/initialize/infra → instant_python-0.18.1/test/initialize/infra/env_manager}/__init__.py +0 -0
  271. {instant_python-0.17.0/test/initialize/infra/env_manager → instant_python-0.18.1/test/initialize/infra/env_manager/mother}/__init__.py +0 -0
  272. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/env_manager/mother/command_execution_result_mother.py +0 -0
  273. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/env_manager/test_pdm_env_manager.py +0 -0
  274. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/env_manager/test_system_console.py +0 -0
  275. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/env_manager/test_uv_env_manager.py +0 -0
  276. {instant_python-0.17.0/test/initialize/infra/env_manager/mother → instant_python-0.18.1/test/initialize/infra/formatter}/__init__.py +0 -0
  277. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/formatter/test_ruff_project_formatter.py +0 -0
  278. {instant_python-0.17.0/test/initialize/infra/formatter → instant_python-0.18.1/test/initialize/infra/persistence}/__init__.py +0 -0
  279. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/persistence/approvaltests_config.json +0 -0
  280. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/persistence/approved_files/TestYamlConfigRepository.test_should_read_existing_config_file.approved.txt +0 -0
  281. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/persistence/test_yaml_config_repository.py +0 -0
  282. {instant_python-0.17.0/test/initialize/infra/persistence → instant_python-0.18.1/test/initialize/infra/renderer}/__init__.py +0 -0
  283. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/renderer/test_jinja_environment.py +0 -0
  284. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/renderer/test_jinja_project_renderer.py +0 -0
  285. {instant_python-0.17.0/test/initialize/infra/renderer → instant_python-0.18.1/test/initialize/infra/version_control}/__init__.py +0 -0
  286. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/version_control/test_git_configurer.py +0 -0
  287. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/writer/TestFileSystemProjectWriter.test_should_create_file_in_file_system.approved.txt +0 -0
  288. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/writer/TestFileSystemProjectWriter.test_should_create_python_module_in_file_system.approved.txt +0 -0
  289. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/writer/TestFileSystemProjectWriter.test_should_create_standard_directory_in_file_system.approved.txt +0 -0
  290. {instant_python-0.17.0/test/initialize/infra/version_control → instant_python-0.18.1/test/initialize/infra/writer}/__init__.py +0 -0
  291. {instant_python-0.17.0 → instant_python-0.18.1}/test/initialize/infra/writer/test_file_system_project_writer.py +0 -0
  292. {instant_python-0.17.0 → instant_python-0.18.1}/test/random_generator.py +0 -0
  293. {instant_python-0.17.0 → instant_python-0.18.1}/test/resources/base_ipy_config.yml +0 -0
  294. {instant_python-0.17.0 → instant_python-0.18.1}/test/resources/domain_error_template.py +0 -0
  295. {instant_python-0.17.0 → instant_python-0.18.1}/test/resources/hello_world.j2 +0 -0
  296. {instant_python-0.17.0 → instant_python-0.18.1}/test/resources/main_structure.yml.j2 +0 -0
  297. {instant_python-0.17.0 → instant_python-0.18.1}/test/resources/standard_project/main_structure.yml.j2 +0 -0
  298. {instant_python-0.17.0/test/initialize/infra/writer → instant_python-0.18.1/test/shared}/__init__.py +0 -0
  299. {instant_python-0.17.0/test/shared → instant_python-0.18.1/test/shared/domain}/__init__.py +0 -0
  300. {instant_python-0.17.0/test/shared/domain → instant_python-0.18.1/test/shared/domain/mothers}/__init__.py +0 -0
  301. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/mothers/config_schema_mother.py +0 -0
  302. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/mothers/dependency_config_mother.py +0 -0
  303. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/mothers/general_config_mother.py +0 -0
  304. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/mothers/git_config_mother.py +0 -0
  305. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/mothers/template_config_mother.py +0 -0
  306. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/test_config_schema.py +0 -0
  307. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/test_dependency_config.py +0 -0
  308. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/test_general_config.py +0 -0
  309. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/test_git_config.py +0 -0
  310. {instant_python-0.17.0 → instant_python-0.18.1}/test/shared/domain/test_template_configuration.py +0 -0
  311. {instant_python-0.17.0 → instant_python-0.18.1}/test/utils.py +0 -0
  312. {instant_python-0.17.0 → instant_python-0.18.1}/tox.ini +0 -0
@@ -2,6 +2,49 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v0.18.1 (2025-11-19)
6
+
7
+ ### ♻️ Refactoring
8
+
9
+ - **initialize**: Improve error message when configuration file is not found
10
+ ([`851f725`](https://github.com/dimanu-py/instant-python/commit/851f725e91482bc3a5d40aa96a7cd522955909ca))
11
+
12
+
13
+ ## v0.18.0 (2025-11-17)
14
+
15
+ ### ✨ Features
16
+
17
+ - **templates**: Add sindri value objects error handler for fastapi application if value objects
18
+ feature is selected
19
+ ([`8ac4773`](https://github.com/dimanu-py/instant-python/commit/8ac47733f7e33932a23be3bb5665275209d2ab50))
20
+
21
+ - **templates**: Remove value object folders from project structure templates
22
+ ([`6029ca6`](https://github.com/dimanu-py/instant-python/commit/6029ca6fcb5fc565040bbdcf9bdb151787b15361))
23
+
24
+ - **templates**: Remove value object implementation templates now that this feature is provided by
25
+ sindripy
26
+ ([`1164d85`](https://github.com/dimanu-py/instant-python/commit/1164d85d5a0e5410f492b6e6f327946cde20345b))
27
+
28
+ - **templates**: Add sindripy to value_objects dependencies
29
+ ([`b563be5`](https://github.com/dimanu-py/instant-python/commit/b563be513465603f45966b33e57bdb5b535c30b6))
30
+
31
+ ### ♻️ Refactoring
32
+
33
+ - **templates**: Remove faker and random generator as it's not need it
34
+ ([`0ba348b`](https://github.com/dimanu-py/instant-python/commit/0ba348bc5cd36ebb64c653f4ff32e1b8b17f76a5))
35
+
36
+ - **templates**: Stop including pytest if value objects feature is selected as it doesn't include
37
+ tests anymore
38
+ ([`c747731`](https://github.com/dimanu-py/instant-python/commit/c74773198cc939996e5e166e755a90e22865393a))
39
+
40
+ - **templates**: Include random generator template only if value objects feature is not selected
41
+ ([`2ad49c3`](https://github.com/dimanu-py/instant-python/commit/2ad49c323f9596b854e85b46094d343f202f9de3))
42
+
43
+ - **templates**: Remove test value object templates from project structures now that it has been
44
+ substituted by sindripy library
45
+ ([`9e27b5b`](https://github.com/dimanu-py/instant-python/commit/9e27b5b792a9f2b28d1f582451d044f7c0195152))
46
+
47
+
5
48
  ## v0.17.0 (2025-11-12)
6
49
 
7
50
  ### ✨ Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: instant-python
3
- Version: 0.17.0
3
+ Version: 0.18.1
4
4
  Summary: Instant boilerplate generation for Python projects
5
5
  Project-URL: documentation, https://dimanu-py.github.io/instant-python/
6
6
  Project-URL: repository, https://github.com/dimanu-py/instant-python/
@@ -258,6 +258,19 @@ commands like `ng new` or `create-react-app`, but for Python projects.
258
258
 
259
259
  </td></tr></table></div>
260
260
 
261
+ ## ✨ NEW ✨ Create Fully Customized Projects
262
+
263
+ Take full control of your project generation! With **custom templates**, you can:
264
+
265
+ - 🎨 Design your own project structure that matches your architectural patterns (like Hexagonal Architecture)
266
+ - 📝 Create reusable file templates with your standardized code and best practices
267
+ - 🔄 Enforce consistency across all your Python projects
268
+ - ⚡ Eliminate repetitive boilerplate and setup tasks
269
+
270
+ Whether you have a standardized project structure you always use or specific architectural patterns you want to enforce,
271
+ custom templates let you generate projects exactly the way you want them.
272
+ [Learn how to create your first custom template](https://dimanu-py.github.io/instant-python/guide/custom_projects/) and level up your project generation workflow!
273
+
261
274
  ## Navigation Guide
262
275
 
263
276
  This section provides a high-level overview of the `instant-python` documentation
@@ -302,8 +315,3 @@ so can quickly find what you need.
302
315
  [//]: # (You can disable this feature by setting the environment variable `INSTANT_PYTHON_NO_TRACK` to `1` or )
303
316
 
304
317
  [//]: # (passing the `--no-track` option to any command.)
305
-
306
- ## Contributing
307
-
308
- We welcome contributions to `instant-python`! If you have ideas, suggestions, or improvements, please check out our
309
- [contributing guide](https://dimanu-py.github.io/instant-python/home/contributing/) for details on how to get involved.
@@ -29,6 +29,19 @@ commands like `ng new` or `create-react-app`, but for Python projects.
29
29
 
30
30
  </td></tr></table></div>
31
31
 
32
+ ## ✨ NEW ✨ Create Fully Customized Projects
33
+
34
+ Take full control of your project generation! With **custom templates**, you can:
35
+
36
+ - 🎨 Design your own project structure that matches your architectural patterns (like Hexagonal Architecture)
37
+ - 📝 Create reusable file templates with your standardized code and best practices
38
+ - 🔄 Enforce consistency across all your Python projects
39
+ - ⚡ Eliminate repetitive boilerplate and setup tasks
40
+
41
+ Whether you have a standardized project structure you always use or specific architectural patterns you want to enforce,
42
+ custom templates let you generate projects exactly the way you want them.
43
+ [Learn how to create your first custom template](https://dimanu-py.github.io/instant-python/guide/custom_projects/) and level up your project generation workflow!
44
+
32
45
  ## Navigation Guide
33
46
 
34
47
  This section provides a high-level overview of the `instant-python` documentation
@@ -73,8 +86,3 @@ so can quickly find what you need.
73
86
  [//]: # (You can disable this feature by setting the environment variable `INSTANT_PYTHON_NO_TRACK` to `1` or )
74
87
 
75
88
  [//]: # (passing the `--no-track` option to any command.)
76
-
77
- ## Contributing
78
-
79
- We welcome contributions to `instant-python`! If you have ideas, suggestions, or improvements, please check out our
80
- [contributing guide](https://dimanu-py.github.io/instant-python/home/contributing/) for details on how to get involved.
@@ -255,297 +255,48 @@ needed to configure the migrations and run them asynchronously.
255
255
 
256
256
  ### Value objects and exceptions
257
257
 
258
- Value objects are a common pattern to encapsulate primitives and encapsulate domain logic. If
259
- you choose this option, it will include the following value objects:
258
+ Value object pattern is a design pattern that emphasizes the use of immutable objects to represent values in a system. It encourages the creation of small, focused classes that encapsulate domain logic.
260
259
 
261
- A base class for all aggregates of your project with some common methods and utilities.
260
+ They act as behavior magnets and try to avoid the code smells of anemic domain models and primitive obsession among others.
262
261
 
263
- ???+ example "Aggregate"
262
+ Value objects are characterized by:
264
263
 
265
- ```python
266
- class Aggregate(ABC):
267
- @abstractmethod
268
- def __init__(self) -> None:
269
- raise NotImplementedError
270
-
271
- @override
272
- def __repr__(self) -> str:
273
- attributes = []
274
- for key, value in sorted(self._to_dict().items()):
275
- attributes.append(f"{key}={value!r}")
276
-
277
- return f"{self.__class__.__name__}({', '.join(attributes)})"
278
-
279
- @override
280
- def __eq__(self, other: Self) -> bool:
281
- if not isinstance(other, self.__class__):
282
- return NotImplemented
283
-
284
- return self._to_dict() == other._to_dict()
285
-
286
- def _to_dict(self, *, ignore_private: bool = True) -> dict[str, Any]:
287
- dictionary: dict[str, Any] = {}
288
- for key, value in self.__dict__.items():
289
- if ignore_private and key.startswith(f"_{self.__class__.__name__}__"):
290
- continue # ignore private attributes
291
-
292
- key = key.replace(f"_{self.__class__.__name__}__", "")
293
-
294
- if key.startswith("_"):
295
- key = key[1:]
296
-
297
- dictionary[key] = value
298
-
299
- return dictionary
300
-
301
- @classmethod
302
- def from_primitives(cls, primitives: dict[str, Any]) -> Self:
303
- if not isinstance(primitives, dict) or not all(
304
- isinstance(key, str) for key in primitives
305
- ):
306
- raise TypeError(f'{cls.__name__} primitives <<<{primitives}>>> must be a dictionary of strings. Got <<<{type(primitives).__name__}>>> type.') # noqa: E501 # fmt: skip
307
-
308
- constructor_signature = signature(obj=cls.__init__)
309
- parameters: dict[str, Parameter] = {parameter.name: parameter for parameter in constructor_signature.parameters.values() if parameter.name != 'self'} # noqa: E501 # fmt: skip
310
- missing = {name for name, parameter in parameters.items() if parameter.default is _empty and name not in primitives} # noqa: E501 # fmt: skip
311
- extra = set(primitives) - parameters.keys()
312
-
313
- if missing or extra:
314
- cls._raise_value_constructor_parameters_mismatch(
315
- primitives=set(primitives), missing=missing, extra=extra
316
- )
317
-
318
- return cls(**primitives)
319
-
320
- @classmethod
321
- def _raise_value_constructor_parameters_mismatch(
322
- cls,
323
- primitives: set[str],
324
- missing: set[str],
325
- extra: set[str],
326
- ) -> None:
327
- primitives_names = ", ".join(sorted(primitives))
328
- missing_names = ", ".join(sorted(missing))
329
- extra_names = ", ".join(sorted(extra))
330
-
331
- raise ValueError(f'{cls.__name__} primitives <<<{primitives_names}>>> must contain all constructor parameters. Missing parameters: <<<{missing_names}>> and extra parameters: <<<{extra_names}>>>.') # noqa: E501 # fmt: skip
332
-
333
- def to_primitives(self) -> dict[str, Any]:
334
- primitives = self._to_dict()
335
- for key, value in primitives.items():
336
- if isinstance(value, Aggregate) or hasattr(value, "to_primitives"):
337
- value = value.to_primitives()
338
-
339
- elif isinstance(value, Enum):
340
- value = value.value
341
-
342
- elif isinstance(value, ValueObject) or hasattr(value, "value"):
343
- value = value.value
344
-
345
- if isinstance(value, Enum):
346
- value = value.value
347
-
348
- primitives[key] = value
349
-
350
- return primitives
351
- ```
264
+ - Immutability: Once created, a value object's state cannot be changed
265
+ - Value equality: Two value objects are equal if their values are equal, regardless of identity
266
+ - Self-validation: Value objects validate their state upon construction
267
+ - Domain semantics: They represent meaningful concepts in the domain rather than primitive types
352
268
 
353
- A base value object class that will automatically be able to gather all methods decorated with `@validate` to be able
354
- to validate any pre-condition of the value object. This class is also configured to be immutable, meaning that once
355
- initialized, the value cannot be changed.
269
+ !!! info "New versions use `sindripy`"
270
+ `instant-python` versions previous to 0.18.0 implemented value objects directly in the generated project.
271
+ All these implementations have been moved to the [`sindripy`](https://pypi.org/project/sindripy/) library
272
+ to promote reusability and better maintenance.
273
+ When selecting this feature, the generated project will include `sindripy` as a dependency.
356
274
 
357
- ???+ example "Base ValueObject"
275
+ Along with `sindripy` to model value objects, this feature will include:
358
276
 
359
- ```python
360
- class ValueObject[T](ABC):
361
- __slots__ = ("_value",)
362
- __match_args__ = ("_value",)
363
-
364
- _value: T
365
-
366
- def __init__(self, value: T) -> None:
367
- self._validate(value)
368
- object.__setattr__(self, "_value", value)
369
-
370
- def _validate(self, value: T) -> None:
371
- """Gets all methods decorated with @validate and calls them to validate all domain conditions."""
372
- validators: list[Callable[[T], None]] = []
373
- for cls in reversed(self.__class__.__mro__):
374
- if cls is object:
375
- continue
376
- for name, member in cls.__dict__.items():
377
- if getattr(member, "_is_validator", False):
378
- validators.append(getattr(self, name))
379
-
380
- for validator in validators:
381
- validator(value)
382
-
383
- @property
384
- def value(self) -> T:
385
- return self._value
386
-
387
- @override
388
- def __eq__(self, other: Self) -> bool:
389
- return self.value == other.value
390
-
391
- @override
392
- def __repr__(self) -> str:
393
- return f"{self.__class__.__name__}({self._value!r})"
394
-
395
- @override
396
- def __str__(self) -> str:
397
- return str(self._value)
398
-
399
- @override
400
- def __setattr__(self, name: str, value: T) -> None:
401
- """Prevents modification of the value after initialization."""
402
- if name in self.__slots__:
403
- raise AttributeError("Cannot modify the value of a ValueObject")
404
-
405
- public_name = name.replace("_", "")
406
- public_slots = [slot.replace("_", "") for slot in self.__slots__]
407
- if public_name in public_slots:
408
- raise AttributeError("Cannot modify the value of a ValueObject")
409
-
410
- raise AttributeError(
411
- f"Class {self.__class__.__name__} object has no attribute '{name}'"
412
- )
413
- ```
414
-
415
- Some common value objects that will be placed at _usables_ folder.
416
-
417
- ???+ example "UUID"
277
+ 1. A base exception class that you can use to create your own exceptions:
418
278
 
419
- ```python
420
- class Uuid(ValueObject[str]):
421
- @validate
422
- def _ensure_has_value(self, value: str) -> None:
423
- if value is None:
424
- raise RequiredValueError
425
-
426
- @validate
427
- def _ensure_value_is_string(self, value: str) -> None:
428
- if not isinstance(value, str):
429
- raise IncorrectValueTypeError(value)
430
-
431
- @validate
432
- def _ensure_value_has_valid_uuid_format(self, value: str) -> None:
433
- try:
434
- UUID(value)
435
- except ValueError:
436
- raise InvalidIdFormatError
437
- ```
438
-
439
- ???+ example "StringValueObject"
440
-
441
- ```python
442
- class StringValueObject(ValueObject[str]):
443
- @validate
444
- def _ensure_has_value(self, value: str) -> None:
445
- if value is None:
446
- raise RequiredValueError
447
-
448
- @validate
449
- def _ensure_is_string(self, value: str) -> None:
450
- if not isinstance(value, str):
451
- raise IncorrectValueTypeError(value)
452
- ```
453
- ???+ example "IntValueObject"
454
-
455
- ```python
456
- class IntValueObject(ValueObject[int]):
457
- @validate
458
- def _ensure_has_value(self, value: int) -> None:
459
- if value is None:
460
- raise RequiredValueError
279
+ ???+ example "Implementation"
461
280
 
462
- @validate
463
- def _ensure_value_is_integer(self, value: int) -> None:
464
- if not isinstance(value, int):
465
- raise IncorrectValueTypeError(value)
466
-
467
- @validate
468
- def _ensure_value_is_positive(self, value: int) -> None:
469
- if value < 0:
470
- raise InvalidNegativeValueError(value)
471
- ```
472
-
473
- Along with these value objects, it will include a base exception class that you can use to create your own exceptions and
474
- some common exceptions that you can use in your project:
475
-
476
- ???+ example "Base Error"
477
-
478
- ```python
479
- class Error(Exception, ABC):
480
- def __init__(self, message: str, error_type: str) -> None:
481
- self._message = message
482
- self._type = error_type
483
- super().__init__(self._message)
484
-
485
- @property
486
- def type(self) -> str:
487
- return self._type
488
-
489
- @property
490
- def message(self) -> str:
491
- return self._message
492
-
493
- def to_primitives(self) -> dict[str, str]:
494
- return {
495
- "type": self.type,
496
- "message": self.message,
497
- }
498
- ```
499
-
500
- ???+ example "Domain Error"
501
-
502
- ```python
503
- class DomainError(Error):
504
- ...
505
- ```
281
+ ```python
282
+ class BaseError(Exception, ABC):
283
+ def __init__(self, message: str) -> None:
284
+ self._message = message
285
+ super().__init__(self._message)
286
+
287
+ @property
288
+ def message(self) -> str:
289
+ return self._message
290
+ ```
506
291
 
507
- ???+ example "IncorrectValueTypeError"
292
+ 2. A `DomainError` class that extends the base exception class. You can use this class to raise domain errors in your application.
508
293
 
509
- ```python
510
- T = TypeVar("T")
294
+ ???+ example "Implementation"
511
295
 
512
-
513
- class IncorrectValueTypeError(DomainError):
514
- def __init__(self, value: T) -> None:
515
- self._message = f"Value '{value}' is not of type {type(value).__name__}"
516
- self._type = "incorrect_value_type"
517
- super().__init__(message=self._message, error_type=self._type)
518
- ```
519
-
520
- ???+ example "InvalidIdFormatError"
521
-
522
- ```python
523
- class InvalidIdFormatError(DomainError):
524
- def __init__(self) -> None:
525
- self._message = "User id must be a valid UUID"
526
- self._type = "invalid_id_format"
527
- super().__init__(message=self._message, error_type=self._type)
528
- ```
529
-
530
- ???+ example "InvalidNegativeValueError"
531
-
532
- ```python
533
- class InvalidNegativeValueError(DomainError):
534
- def __init__(self, value: int) -> None:
535
- self._message = f"Invalid negative value: {value}"
536
- self._type = "invalid_negative_value"
537
- super().__init__(message=self._message, error_type=self._type)
538
- ```
539
-
540
- ???+ example "RequiredValueError"
541
-
542
- ```python
543
- class RequiredValueError(DomainError):
544
- def __init__(self) -> None:
545
- self._message = "Value is required, can't be None"
546
- self._type = "required_value"
547
- super().__init__(message=self._message, error_type=self._type)
548
- ```
296
+ ```python
297
+ class DomainError(BaseError):
298
+ ...
299
+ ```
549
300
 
550
301
  ### Event bus
551
302
 
@@ -27,4 +27,8 @@ class YamlConfigRepository(ConfigRepository):
27
27
 
28
28
  class ConfigurationFileNotFound(ApplicationError):
29
29
  def __init__(self, path: str) -> None:
30
- super().__init__(message=f"Configuration file not found at '{path}'.")
30
+ super().__init__(
31
+ message=f"Configuration file not found at '{path}'. To create a project, you first"
32
+ f" need a configuration file. Please, run 'ipy config' command to create one.\n"
33
+ f"If you have the configuration file in another location, use the '-c' flag.",
34
+ )
@@ -2,18 +2,22 @@ from fastapi import FastAPI
2
2
  {% if "logger" in template.built_in_features %}
3
3
  from fastapi.errors import RequestValidationError
4
4
  {% endif %}
5
-
5
+ {% if "value_objects" in template.built_in_features %}
6
+ from sindripy.value_objects import SindriValidationError
7
+ {% endif %}
6
8
  {% if template.name == template_types.STANDARD %}
7
9
  {% if "logger" in template.built_in_features %}
8
10
  from {{ general.source_name }}.api.handlers.error_handlers import (
9
11
  unexpected_exception_handler,
10
12
  domain_error_handler,
11
13
  validation_error_handler,
14
+ {% if "value_objects" in template.built_in_features %}sindri_validation_error_handler,{% endif %}
12
15
  )
13
16
  {% else %}
14
17
  from {{ general.source_name }}.api.handlers.error_handlers import (
15
18
  unexpected_exception_handler,
16
19
  domain_error_handler,
20
+ {% if "value_objects" in template.built_in_features %}sindri_validation_error_handler,{% endif %}
17
21
  )
18
22
  {% endif %}
19
23
  {% else %}
@@ -22,11 +26,13 @@ from {{ general.source_name }}.delivery.api.handlers.error_handlers import (
22
26
  unexpected_exception_handler,
23
27
  domain_error_handler,
24
28
  validation_error_handler,
29
+ {% if "value_objects" in template.built_in_features %}sindri_validation_error_handler,{% endif %}
25
30
  )
26
31
  {% else %}
27
32
  from {{ general.source_name }}.delivery.api.handlers.error_handlers import (
28
33
  unexpected_exception_handler,
29
34
  domain_error_handler,
35
+ {% if "value_objects" in template.built_in_features %}sindri_validation_error_handler,{% endif %}
30
36
  )
31
37
  {% endif %}
32
38
  {% endif %}
@@ -61,5 +67,8 @@ logger = create_file_logger(name="{{ general.slug }}")
61
67
  app.add_middleware(FastapiLogMiddleware, logger=logger)
62
68
  app.add_exception_handler(RequestValidationError, validation_error_handler)
63
69
  {% endif %}
70
+ {% if "value_objects" in template.built_in_features %}
71
+ app.add_exception_handler(SindriValidationError, sindri_validation_error_handler)
72
+ {% endif %}
64
73
  app.add_exception_handler(Exception, unexpected_exception_handler)
65
74
  app.add_exception_handler(DomainError, domain_error_handler)
@@ -7,7 +7,9 @@ from {{ general.source_name }}{{ "shared.infra.logger.file_logger" | resolve_imp
7
7
  {% endif %}
8
8
  from {{ general.source_name }}{{ "shared.infra.http.error_response" | resolve_import_path(template.name) }} import InternalServerError, UnprocessableEntityError
9
9
  from {{ general.source_name }}{{ "shared.domain.errors.domain_error" | resolve_import_path(template.name) }} import DomainError
10
-
10
+ {% if "value_objects" in template.built_in_features %}
11
+ from sindripy.value_objects import SindriValidationError
12
+ {% endif %}
11
13
 
12
14
  {% if "logger" in template.built_in_features %}
13
15
  logger = create_file_logger(name="{{ general.slug }}")
@@ -51,6 +53,22 @@ async def validation_error_handler(
51
53
  },
52
54
  )
53
55
  return await request_validation_exception_handler(request, exc)
56
+
57
+ {% if "value_objects" in template.built_in_features %}
58
+ async def sindri_validation_error_handler(
59
+ request: Request,
60
+ exc: SindriValidationError,
61
+ ) -> JSONResponse:
62
+ logger.error(
63
+ message=f"error - {request.url.path}",
64
+ details={
65
+ "error": {"message": str(exc)},
66
+ "method": request.method,
67
+ "source": request.url.path,
68
+ },
69
+ )
70
+ return UnprocessableEntityError().as_json()
71
+ {% endif %}
54
72
  {% else %}
55
73
  async def unexpected_exception_handler(_: Request, __: Exception) -> JSONResponse:
56
74
  return InternalServerError().as_json()
@@ -58,4 +76,13 @@ async def unexpected_exception_handler(_: Request, __: Exception) -> JSONRespons
58
76
 
59
77
  async def domain_error_handler(_: Request, __: DomainError) -> JSONResponse:
60
78
  return UnprocessableEntityError().as_json()
79
+
80
+
81
+ {% if "value_objects" in template.built_in_features %}
82
+ async def sindri_validation_error_handler(
83
+ _: Request,
84
+ __: SindriValidationError,
85
+ ) -> JSONResponse:
86
+ return UnprocessableEntityError().as_json()
87
+ {% endif %}
61
88
  {% endif %}
@@ -2,7 +2,8 @@
2
2
  "async_sqlalchemy": ["sqlalchemy", "asyncpg", "psycopg2-binary", "pydantic", "pydantic-settings"],
3
3
  "async_alembic": ["alembic", "pydantic", "pydantic-settings"],
4
4
  "event_bus": ["pika"],
5
- "fastapi_application": ["fastapi[standard]"]
5
+ "fastapi_application": ["fastapi[standard]"],
6
+ "value_objects": ["sindripy"]
6
7
  } %}
7
8
  {% macro get_main_dependencies() -%}
8
9
  {%- set deps = [] -%}
@@ -27,8 +28,7 @@
27
28
  "pre-commit": ["precommit_hook"]
28
29
  },
29
30
  "test": {
30
- "faker": [],
31
- "pytest": ["github_actions", "makefile", "precommit_hook", "value_objects"],
31
+ "pytest": ["github_actions", "makefile", "precommit_hook"],
32
32
  "pytest-asyncio": ["async_alembic", "async_sqlalchemy"]
33
33
  }
34
34
  } %}
@@ -6,18 +6,13 @@
6
6
  - name: domain
7
7
  type: directory
8
8
  python: True
9
- {% if ["value_objects", "event_bus"] | is_in(template.built_in_features) %}
10
- children:
11
- {% if "value_objects" in template.built_in_features %}
12
- {{ macros.include_and_indent("test_value_objects.yml.j2", 8) }}
13
- {% endif %}
14
9
  {% if "event_bus" in template.built_in_features %}
10
+ children:
15
11
  - name: mock_event_bus
16
12
  type: file
17
13
  extension: .py
18
14
  template: event_bus/mock_event_bus.py
19
15
  {% endif %}
20
- {% endif %}
21
16
  - name: infra
22
17
  type: directory
23
18
  python: True
@@ -38,8 +33,4 @@
38
33
  {% endif %}
39
34
  - name: delivery
40
35
  type: directory
41
- python: True
42
- - name: random_generator
43
- type: file
44
- extension: .py
45
- template: random_generator.py
36
+ python: True
@@ -7,21 +7,16 @@
7
7
  type: directory
8
8
  python: True
9
9
  children:
10
+ - name: delivery
11
+ type: directory
12
+ python: True
10
13
  - name: domain
11
14
  type: directory
12
15
  python: True
13
- children:
14
- - name: random_generator
15
- type: file
16
- extension: .py
17
- template: random_generator.py
18
- {% if "value_objects" in template.built_in_features %}
19
- {{ macros.include_and_indent("test_value_objects.yml.j2", 12) }}
20
- {% endif %}
21
- {% if ["event_bus", "async_sqlalchemy"] | is_in(template.built_in_features) %}
22
16
  - name: infra
23
17
  type: directory
24
18
  python: True
19
+ {% if ["event_bus", "async_sqlalchemy"] | is_in(template.built_in_features) %}
25
20
  children:
26
21
  {% if "event_bus" in template.built_in_features %}
27
22
  - name: mock_event_bus
@@ -35,7 +30,7 @@
35
30
  extension: .py
36
31
  template: persistence/async/async_engine_fixture.py
37
32
  {% endif %}
38
- {% endif %}
33
+ {% endif %}
39
34
  {% if template.specify_bounded_context %}
40
35
  {{ macros.include_and_indent("domain_driven_design/bounded_context.yml.j2", 4) }}
41
36
  {% endif %}
@@ -2,14 +2,8 @@
2
2
  - name: test
3
3
  type: directory
4
4
  python: True
5
+ {% if ["async_sqlalchemy", "event_bus"] | is_in(template.built_in_features) %}
5
6
  children:
6
- - name: random_generator
7
- type: file
8
- extension: .py
9
- template: random_generator.py
10
- {% if "value_objects" in template.built_in_features %}
11
- {{ macros.include_and_indent("test_value_objects.yml.j2", 4) }}
12
- {% endif %}
13
7
  {% if "async_sqlalchemy" in template.built_in_features %}
14
8
  - name: conftest
15
9
  type: file
@@ -25,4 +19,5 @@
25
19
  type: file
26
20
  extension: .py
27
21
  template: event_bus/mock_event_bus.py
28
- {% endif %}
22
+ {% endif %}
23
+ {% endif %}
@@ -0,0 +1,12 @@
1
+ - name: errors
2
+ type: directory
3
+ python: True
4
+ children:
5
+ - name: base_error
6
+ type: file
7
+ extension: .py
8
+ template: exceptions/base_error.py
9
+ - name: domain_error
10
+ type: file
11
+ extension: .py
12
+ template: exceptions/domain_error.py