instant-python 0.20.0__tar.gz → 0.21.0__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 (342) hide show
  1. {instant_python-0.20.0 → instant_python-0.21.0}/.pre-commit-config.yaml +1 -1
  2. {instant_python-0.20.0 → instant_python-0.21.0}/CHANGELOG.md +197 -0
  3. {instant_python-0.20.0 → instant_python-0.21.0}/PKG-INFO +21 -8
  4. {instant_python-0.20.0 → instant_python-0.21.0}/README.md +18 -7
  5. instant_python-0.21.0/docs/getting_started/privacy_and_metrics.md +137 -0
  6. {instant_python-0.20.0 → instant_python-0.21.0}/docs/home/index.md +2 -0
  7. instant_python-0.21.0/instant_python/__init__.py +1 -0
  8. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/cli/cli.py +3 -2
  9. instant_python-0.21.0/instant_python/metrics/application/config_snapshot_creator.py +22 -0
  10. instant_python-0.21.0/instant_python/metrics/application/usage_metrics_sender.py +41 -0
  11. instant_python-0.21.0/instant_python/metrics/delivery/metrics_middleware.py +88 -0
  12. instant_python-0.21.0/instant_python/metrics/domain/config_snapshot.py +61 -0
  13. instant_python-0.21.0/instant_python/metrics/domain/error_metrics_event.py +13 -0
  14. instant_python-0.21.0/instant_python/metrics/domain/metrics_reporter.py +14 -0
  15. instant_python-0.21.0/instant_python/metrics/domain/usage_metrics_data.py +15 -0
  16. instant_python-0.21.0/instant_python/metrics/infra/post_hog_config.py +16 -0
  17. instant_python-0.21.0/instant_python/metrics/infra/post_hog_metrics_reporter.py +46 -0
  18. instant_python-0.21.0/instant_python/metrics/infra/user_identity_manager.py +54 -0
  19. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/domain/config_schema.py +8 -0
  20. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/infra/persistence/yaml_config_repository.py +2 -2
  21. {instant_python-0.20.0 → instant_python-0.21.0}/mkdocs.yml +1 -0
  22. {instant_python-0.20.0 → instant_python-0.21.0}/pyproject.toml +4 -1
  23. instant_python-0.21.0/test/initialize/infra/writer/__init__.py +0 -0
  24. instant_python-0.21.0/test/metrics/__init__.py +0 -0
  25. instant_python-0.21.0/test/metrics/application/__init__.py +0 -0
  26. instant_python-0.21.0/test/metrics/application/test_config_snapshot_creator.py +34 -0
  27. instant_python-0.21.0/test/metrics/application/test_usage_metrics_sender.py +30 -0
  28. instant_python-0.21.0/test/metrics/domain/__init__.py +0 -0
  29. instant_python-0.21.0/test/metrics/domain/config_snapshot_mother.py +19 -0
  30. instant_python-0.21.0/test/metrics/domain/error_metrics_event_mother.py +13 -0
  31. instant_python-0.21.0/test/metrics/domain/usage_metrics_event_mother.py +15 -0
  32. instant_python-0.21.0/test/metrics/infra/__init__.py +0 -0
  33. instant_python-0.21.0/test/metrics/infra/cassettes/error_posthog_reporter.yml +336 -0
  34. instant_python-0.21.0/test/metrics/infra/cassettes/success_posthog_reporter.yml +51 -0
  35. instant_python-0.21.0/test/metrics/infra/test_post_hog_config.py +47 -0
  36. instant_python-0.21.0/test/metrics/infra/test_post_hog_metrics_reporter.py +51 -0
  37. instant_python-0.21.0/test/metrics/infra/test_user_identity_manager.py +71 -0
  38. instant_python-0.21.0/test/shared/__init__.py +0 -0
  39. instant_python-0.21.0/test/shared/domain/__init__.py +0 -0
  40. instant_python-0.21.0/test/shared/domain/mothers/__init__.py +0 -0
  41. instant_python-0.21.0/test/shared/persistence/__init__.py +0 -0
  42. instant_python-0.21.0/uv.lock +3207 -0
  43. instant_python-0.20.0/instant_python/__init__.py +0 -1
  44. instant_python-0.20.0/uv.lock +0 -2167
  45. {instant_python-0.20.0 → instant_python-0.21.0}/.github/FUNDING.yml +0 -0
  46. {instant_python-0.20.0 → instant_python-0.21.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  47. {instant_python-0.20.0 → instant_python-0.21.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  48. {instant_python-0.20.0 → instant_python-0.21.0}/.github/actions/python_setup/action.yml +0 -0
  49. {instant_python-0.20.0 → instant_python-0.21.0}/.github/pull_request_template.md +0 -0
  50. {instant_python-0.20.0 → instant_python-0.21.0}/.github/workflows/ci.yml +0 -0
  51. {instant_python-0.20.0 → instant_python-0.21.0}/.github/workflows/pages.yml +0 -0
  52. {instant_python-0.20.0 → instant_python-0.21.0}/.github/workflows/release.yml +0 -0
  53. {instant_python-0.20.0 → instant_python-0.21.0}/.gitignore +0 -0
  54. {instant_python-0.20.0 → instant_python-0.21.0}/.python-version +0 -0
  55. {instant_python-0.20.0 → instant_python-0.21.0}/CITATION.cff +0 -0
  56. {instant_python-0.20.0 → instant_python-0.21.0}/LICENSE +0 -0
  57. {instant_python-0.20.0 → instant_python-0.21.0}/SECURITY.md +0 -0
  58. {instant_python-0.20.0 → instant_python-0.21.0}/codeql-config.yml +0 -0
  59. {instant_python-0.20.0 → instant_python-0.21.0}/docs/assets/favicon.svg +0 -0
  60. {instant_python-0.20.0 → instant_python-0.21.0}/docs/assets/logo.svg +0 -0
  61. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/changelog_header.md.j2 +0 -0
  62. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/changelog_init.md.j2 +0 -0
  63. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/changelog_update.md.j2 +0 -0
  64. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/changes.md.j2 +0 -0
  65. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/first_release.md.j2 +0 -0
  66. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/macros.md.j2 +0 -0
  67. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.components/versioned_changes.md.j2 +0 -0
  68. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/.release_notes.md.j2 +0 -0
  69. {instant_python-0.20.0 → instant_python-0.21.0}/docs/changelog/CHANGELOG.md.j2 +0 -0
  70. {instant_python-0.20.0 → instant_python-0.21.0}/docs/development/contributing.md +0 -0
  71. {instant_python-0.20.0 → instant_python-0.21.0}/docs/development/releases.md +0 -0
  72. {instant_python-0.20.0 → instant_python-0.21.0}/docs/development/security.md +0 -0
  73. {instant_python-0.20.0 → instant_python-0.21.0}/docs/downloads_macro.py +0 -0
  74. {instant_python-0.20.0 → instant_python-0.21.0}/docs/getting_started/first_steps.md +0 -0
  75. {instant_python-0.20.0 → instant_python-0.21.0}/docs/getting_started/installation.md +0 -0
  76. {instant_python-0.20.0 → instant_python-0.21.0}/docs/guide/command_config.md +0 -0
  77. {instant_python-0.20.0 → instant_python-0.21.0}/docs/guide/command_init.md +0 -0
  78. {instant_python-0.20.0 → instant_python-0.21.0}/docs/guide/custom_projects.md +0 -0
  79. {instant_python-0.20.0 → instant_python-0.21.0}/docs/guide/default_features.md +0 -0
  80. {instant_python-0.20.0 → instant_python-0.21.0}/docs/guide/index.md +0 -0
  81. {instant_python-0.20.0 → instant_python-0.21.0}/docs/guide/template_reference.md +0 -0
  82. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/cli/__init__.py +0 -0
  83. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/cli/instant_python_typer.py +0 -0
  84. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/__init__.py +0 -0
  85. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/application/__init__.py +0 -0
  86. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/application/config_generator.py +0 -0
  87. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/delivery/__init__.py +0 -0
  88. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/delivery/cli.py +0 -0
  89. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/domain/__init__.py +0 -0
  90. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/domain/question_wizard.py +0 -0
  91. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/__init__.py +0 -0
  92. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/__init__.py +0 -0
  93. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/questionary_console_wizard.py +0 -0
  94. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/__init__.py +0 -0
  95. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/dependencies_step.py +0 -0
  96. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/general_step.py +0 -0
  97. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/git_step.py +0 -0
  98. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/questionary.py +0 -0
  99. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/steps.py +0 -0
  100. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/config/infra/question_wizard/step/template_step.py +0 -0
  101. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/__init__.py +0 -0
  102. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/application/__init__.py +0 -0
  103. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/application/project_initializer.py +0 -0
  104. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/delivery/__init__.py +0 -0
  105. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/delivery/cli.py +0 -0
  106. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/__init__.py +0 -0
  107. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/env_manager.py +0 -0
  108. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/node.py +0 -0
  109. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/project_formatter.py +0 -0
  110. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/project_renderer.py +0 -0
  111. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/project_structure.py +0 -0
  112. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/project_writer.py +0 -0
  113. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/domain/version_control_configurer.py +0 -0
  114. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/__init__.py +0 -0
  115. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/env_manager/__init__.py +0 -0
  116. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/env_manager/env_manager_factory.py +0 -0
  117. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/env_manager/pdm_env_manager.py +0 -0
  118. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/env_manager/system_console.py +0 -0
  119. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/env_manager/uv_env_manager.py +0 -0
  120. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/formatter/__init__.py +0 -0
  121. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/formatter/ruff_project_formatter.py +0 -0
  122. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/renderer/__init__.py +0 -0
  123. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/renderer/jinja_environment.py +0 -0
  124. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/renderer/jinja_project_renderer.py +0 -0
  125. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/version_control/__init__.py +0 -0
  126. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/version_control/git_configurer.py +0 -0
  127. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/writer/__init__.py +0 -0
  128. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/initialize/infra/writer/file_system_project_writer.py +0 -0
  129. {instant_python-0.20.0/instant_python/shared → instant_python-0.21.0/instant_python/metrics}/__init__.py +0 -0
  130. {instant_python-0.20.0/instant_python/shared/domain → instant_python-0.21.0/instant_python/metrics/application}/__init__.py +0 -0
  131. {instant_python-0.20.0/instant_python/shared/infra → instant_python-0.21.0/instant_python/metrics/delivery}/__init__.py +0 -0
  132. {instant_python-0.20.0/instant_python/shared/infra/persistence → instant_python-0.21.0/instant_python/metrics/domain}/__init__.py +0 -0
  133. {instant_python-0.20.0/instant_python/templates/boilerplate/event_bus → instant_python-0.21.0/instant_python/metrics/infra}/__init__.py +0 -0
  134. {instant_python-0.20.0/instant_python/templates/boilerplate/exceptions → instant_python-0.21.0/instant_python/shared}/__init__.py +0 -0
  135. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/application_error.py +0 -0
  136. {instant_python-0.20.0/instant_python/templates/boilerplate/fastapi → instant_python-0.21.0/instant_python/shared/domain}/__init__.py +0 -0
  137. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/domain/config_repository.py +0 -0
  138. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/domain/dependency_config.py +0 -0
  139. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/domain/general_config.py +0 -0
  140. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/domain/git_config.py +0 -0
  141. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/domain/template_config.py +0 -0
  142. {instant_python-0.20.0/instant_python/templates/boilerplate/logger → instant_python-0.21.0/instant_python/shared/infra}/__init__.py +0 -0
  143. {instant_python-0.20.0/instant_python/templates/boilerplate → instant_python-0.21.0/instant_python/shared/infra}/persistence/__init__.py +0 -0
  144. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/supported_built_in_features.py +0 -0
  145. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/supported_licenses.py +0 -0
  146. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/supported_managers.py +0 -0
  147. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/supported_python_versions.py +0 -0
  148. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/shared/supported_templates.py +0 -0
  149. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/.gitignore +0 -0
  150. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/.pre-commit-config.yml +0 -0
  151. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/.python-version +0 -0
  152. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/CITATION.cff +0 -0
  153. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/LICENSE +0 -0
  154. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/README.md +0 -0
  155. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/SECURITY.md +0 -0
  156. {instant_python-0.20.0/instant_python/templates/boilerplate/persistence/async → instant_python-0.21.0/instant_python/templates/boilerplate/event_bus}/__init__.py +0 -0
  157. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/domain_event.py +0 -0
  158. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/domain_event_json_deserializer.py +0 -0
  159. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/domain_event_json_serializer.py +0 -0
  160. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/domain_event_subscriber.py +0 -0
  161. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/event_aggregate.py +0 -0
  162. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/event_bus.py +0 -0
  163. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/exchange_type.py +0 -0
  164. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/mock_event_bus.py +0 -0
  165. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/rabbit_mq_configurer.py +0 -0
  166. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/rabbit_mq_connection.py +0 -0
  167. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/rabbit_mq_consumer.py +0 -0
  168. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/rabbit_mq_event_bus.py +0 -0
  169. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/rabbit_mq_queue_formatter.py +0 -0
  170. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/event_bus/rabbit_mq_settings.py +0 -0
  171. {instant_python-0.20.0/instant_python/templates/boilerplate/persistence/synchronous → instant_python-0.21.0/instant_python/templates/boilerplate/exceptions}/__init__.py +0 -0
  172. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/exceptions/base_error.py +0 -0
  173. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/exceptions/domain_error.py +0 -0
  174. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/exceptions/domain_event_type_not_found_error.py +0 -0
  175. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/exceptions/rabbit_mq_connection_not_established_error.py +0 -0
  176. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/exceptions/required_value_error.py +0 -0
  177. {instant_python-0.20.0/test → instant_python-0.21.0/instant_python/templates/boilerplate/fastapi}/__init__.py +0 -0
  178. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/fastapi/application.py +0 -0
  179. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/fastapi/error_handlers.py +0 -0
  180. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/fastapi/error_response.py +0 -0
  181. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/fastapi/fastapi_log_middleware.py +0 -0
  182. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/fastapi/lifespan.py +0 -0
  183. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/fastapi/success_response.py +0 -0
  184. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/github/action.yml +0 -0
  185. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/github/bug_report.yml +0 -0
  186. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/github/ci.yml +0 -0
  187. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/github/feature_request.yml +0 -0
  188. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/github/release.yml +0 -0
  189. {instant_python-0.20.0/test/cli → instant_python-0.21.0/instant_python/templates/boilerplate/logger}/__init__.py +0 -0
  190. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/logger/file_logger.py +0 -0
  191. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/logger/file_rotating_handler.py +0 -0
  192. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/logger/json_formatter.py +0 -0
  193. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/mypy.ini +0 -0
  194. {instant_python-0.20.0/test/config → instant_python-0.21.0/instant_python/templates/boilerplate/persistence}/__init__.py +0 -0
  195. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/alembic_migrator.py +0 -0
  196. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/README.md +0 -0
  197. {instant_python-0.20.0/test/config/application → instant_python-0.21.0/instant_python/templates/boilerplate/persistence/async}/__init__.py +0 -0
  198. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/alembic.ini +0 -0
  199. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/async_engine_fixture.py +0 -0
  200. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/async_session.py +0 -0
  201. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/env.py +0 -0
  202. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/models_metadata.py +0 -0
  203. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/postgres_settings.py +0 -0
  204. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/script.py.mako +0 -0
  205. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/async/sqlalchemy_repository.py +0 -0
  206. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/base.py +0 -0
  207. {instant_python-0.20.0/test/initialize → instant_python-0.21.0/instant_python/templates/boilerplate/persistence/synchronous}/__init__.py +0 -0
  208. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/synchronous/session_maker.py +0 -0
  209. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/persistence/synchronous/sqlalchemy_repository.py +0 -0
  210. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/pyproject.toml +0 -0
  211. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/pytest.ini +0 -0
  212. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/add_dependency.py +0 -0
  213. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/create_aggregate.py +0 -0
  214. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/insert_template.py +0 -0
  215. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/integration.sh +0 -0
  216. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/local_setup.py +0 -0
  217. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/makefile +0 -0
  218. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/post-merge.py +0 -0
  219. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/pre-commit.py +0 -0
  220. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/pre-push.py +0 -0
  221. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/remove_dependency.py +0 -0
  222. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/boilerplate/scripts/unit.sh +0 -0
  223. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/application.yml +0 -0
  224. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/delivery.yml +0 -0
  225. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/domain.yml +0 -0
  226. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/infra.yml +0 -0
  227. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/test_application.yml +0 -0
  228. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/test_delivery.yml +0 -0
  229. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/test_domain.yml +0 -0
  230. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/layers/test_infra.yml +0 -0
  231. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/main_structure.yml +0 -0
  232. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/source.yml +0 -0
  233. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/clean_architecture/test.yml +0 -0
  234. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/config_files/gitignore.yml +0 -0
  235. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/config_files/mypy.yml +0 -0
  236. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/config_files/pyproject.yml +0 -0
  237. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/config_files/pytest.yml +0 -0
  238. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/config_files/python_version.yml +0 -0
  239. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/documentation/citation.yml +0 -0
  240. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/documentation/license.yml +0 -0
  241. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/documentation/readme.yml +0 -0
  242. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/documentation/security.yml +0 -0
  243. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/bounded_context.yml +0 -0
  244. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/delivery.yml +0 -0
  245. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/shared.yml +0 -0
  246. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/shared_domain.yml +0 -0
  247. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/shared_infra.yml +0 -0
  248. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/test_shared.yml +0 -0
  249. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/test_shared_delivery.yml +0 -0
  250. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/test_shared_domain.yml +0 -0
  251. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/layers/test_shared_infra.yml +0 -0
  252. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/main_structure.yml +0 -0
  253. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/source.yml +0 -0
  254. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/domain_driven_design/test.yml +0 -0
  255. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/errors.yml +0 -0
  256. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/events/event_bus_domain.yml +0 -0
  257. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/events/event_bus_infra.yml +0 -0
  258. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/events/mock_event_bus.yml +0 -0
  259. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/fastapi/fastapi_app.yml +0 -0
  260. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/fastapi/fastapi_domain.yml +0 -0
  261. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/fastapi/fastapi_infra.yml +0 -0
  262. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/github/github_action.yml +0 -0
  263. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/github/github_issues_template.yml +0 -0
  264. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/github/makefile.yml +0 -0
  265. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/github/precommit_hook.yml +0 -0
  266. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/logger.yml +0 -0
  267. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/macros.j2 +0 -0
  268. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/persistence/alembic_migrator.yml +0 -0
  269. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/persistence/async_alembic.yml +0 -0
  270. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/persistence/async_engine_conftest.yml +0 -0
  271. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/persistence/async_sqlalchemy.yml +0 -0
  272. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/persistence/persistence.yml +0 -0
  273. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/persistence/synchronous_sqlalchemy.yml +0 -0
  274. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/standard_project/layers/source_features.yml +0 -0
  275. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/standard_project/layers/test_event_bus.yml +0 -0
  276. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/standard_project/layers/test_features.yml +0 -0
  277. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/standard_project/main_structure.yml +0 -0
  278. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/standard_project/source.yml +0 -0
  279. {instant_python-0.20.0 → instant_python-0.21.0}/instant_python/templates/project_structure/standard_project/test.yml +0 -0
  280. {instant_python-0.20.0 → instant_python-0.21.0}/makefile +0 -0
  281. {instant_python-0.20.0 → instant_python-0.21.0}/mypy.ini +0 -0
  282. {instant_python-0.20.0 → instant_python-0.21.0}/schemas/ipy-schema.json +0 -0
  283. {instant_python-0.20.0 → instant_python-0.21.0}/schemas/main-structure-schema.json +0 -0
  284. {instant_python-0.20.0/test/initialize/application → instant_python-0.21.0/test}/__init__.py +0 -0
  285. {instant_python-0.20.0/test/initialize/delivery → instant_python-0.21.0/test/cli}/__init__.py +0 -0
  286. {instant_python-0.20.0 → instant_python-0.21.0}/test/cli/test_version_command.py +0 -0
  287. {instant_python-0.20.0/test/initialize/domain → instant_python-0.21.0/test/config}/__init__.py +0 -0
  288. {instant_python-0.20.0/test/initialize/domain/mothers → instant_python-0.21.0/test/config/application}/__init__.py +0 -0
  289. {instant_python-0.20.0 → instant_python-0.21.0}/test/config/application/test_config_generator.py +0 -0
  290. {instant_python-0.20.0/test/initialize/infra → instant_python-0.21.0/test/initialize}/__init__.py +0 -0
  291. {instant_python-0.20.0/test/initialize/infra/env_manager → instant_python-0.21.0/test/initialize/application}/__init__.py +0 -0
  292. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/application/test_project_initializer.py +0 -0
  293. {instant_python-0.20.0/test/initialize/infra/env_manager/mother → instant_python-0.21.0/test/initialize/delivery}/__init__.py +0 -0
  294. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/approvaltests_config.json +0 -0
  295. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_custom_project_structure.approved.txt +0 -0
  296. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_general_section_combinations.approved.txt +0 -0
  297. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_git_section_combinations.approved.txt +0 -0
  298. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_predefined_dependencies_and_different_managers.approved.txt +0 -0
  299. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/approved_files/TestInitCli.test_should_initialize_project_with_template_section_combinations.approved.txt +0 -0
  300. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/delivery/test_init_cli.py +0 -0
  301. {instant_python-0.20.0/test/initialize/infra/formatter → instant_python-0.21.0/test/initialize/domain}/__init__.py +0 -0
  302. {instant_python-0.20.0/test/initialize/infra/renderer → instant_python-0.21.0/test/initialize/domain/mothers}/__init__.py +0 -0
  303. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/domain/mothers/node_mother.py +0 -0
  304. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/domain/mothers/project_structure_mother.py +0 -0
  305. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/domain/test_node.py +0 -0
  306. {instant_python-0.20.0/test/initialize/infra/version_control → instant_python-0.21.0/test/initialize/infra}/__init__.py +0 -0
  307. {instant_python-0.20.0/test/initialize/infra/writer → instant_python-0.21.0/test/initialize/infra/env_manager}/__init__.py +0 -0
  308. {instant_python-0.20.0/test/shared → instant_python-0.21.0/test/initialize/infra/env_manager/mother}/__init__.py +0 -0
  309. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/env_manager/mother/command_execution_result_mother.py +0 -0
  310. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/env_manager/test_pdm_env_manager.py +0 -0
  311. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/env_manager/test_system_console.py +0 -0
  312. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/env_manager/test_uv_env_manager.py +0 -0
  313. {instant_python-0.20.0/test/shared/domain → instant_python-0.21.0/test/initialize/infra/formatter}/__init__.py +0 -0
  314. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/formatter/test_ruff_project_formatter.py +0 -0
  315. {instant_python-0.20.0/test/shared/domain/mothers → instant_python-0.21.0/test/initialize/infra/renderer}/__init__.py +0 -0
  316. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/renderer/test_jinja_environment.py +0 -0
  317. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/renderer/test_jinja_project_renderer.py +0 -0
  318. {instant_python-0.20.0/test/shared/persistence → instant_python-0.21.0/test/initialize/infra/version_control}/__init__.py +0 -0
  319. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/version_control/test_git_configurer.py +0 -0
  320. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/writer/TestFileSystemProjectWriter.test_should_create_file_in_file_system.approved.txt +0 -0
  321. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/writer/TestFileSystemProjectWriter.test_should_create_python_module_in_file_system.approved.txt +0 -0
  322. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/writer/TestFileSystemProjectWriter.test_should_create_standard_directory_in_file_system.approved.txt +0 -0
  323. {instant_python-0.20.0 → instant_python-0.21.0}/test/initialize/infra/writer/test_file_system_project_writer.py +0 -0
  324. {instant_python-0.20.0 → instant_python-0.21.0}/test/random_generator.py +0 -0
  325. {instant_python-0.20.0 → instant_python-0.21.0}/test/resources/base_ipy_config.yml +0 -0
  326. {instant_python-0.20.0 → instant_python-0.21.0}/test/resources/domain_error_template.py +0 -0
  327. {instant_python-0.20.0 → instant_python-0.21.0}/test/resources/hello_world.j2 +0 -0
  328. {instant_python-0.20.0 → instant_python-0.21.0}/test/resources/main_structure.yml +0 -0
  329. {instant_python-0.20.0 → instant_python-0.21.0}/test/resources/standard_project/main_structure.yml +0 -0
  330. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/mothers/config_schema_mother.py +0 -0
  331. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/mothers/dependency_config_mother.py +0 -0
  332. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/mothers/general_config_mother.py +0 -0
  333. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/mothers/git_config_mother.py +0 -0
  334. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/mothers/template_config_mother.py +0 -0
  335. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/test_config_schema.py +0 -0
  336. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/test_dependency_config.py +0 -0
  337. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/test_general_config.py +0 -0
  338. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/test_git_config.py +0 -0
  339. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/domain/test_template_configuration.py +0 -0
  340. {instant_python-0.20.0 → instant_python-0.21.0}/test/shared/persistence/test_yaml_config_repository.py +0 -0
  341. {instant_python-0.20.0 → instant_python-0.21.0}/test/utils.py +0 -0
  342. {instant_python-0.20.0 → instant_python-0.21.0}/tox.ini +0 -0
@@ -44,7 +44,7 @@ repos:
44
44
  hooks:
45
45
  - id: gitleaks
46
46
  name: 🔍 Secrets Checker
47
- entry: gitleaks detect --no-git --redact --verbose
47
+ entry: gitleaks detect --redact --verbose
48
48
  stages:
49
49
  - pre-commit
50
50
 
@@ -2,6 +2,203 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v0.21.0 (2025-12-12)
6
+
7
+ ### ✨ Features
8
+
9
+ - **metrics**: Set default values for api_key and host in PostHogConfig
10
+ ([`8cfd3c2`](https://github.com/dimanu-py/instant-python/commit/8cfd3c23ebe08ec54bb06d8ed7f646a7d8105a13))
11
+
12
+ - **metrics**: Add metrics disabled check in PostHogMetricsReporter to prevent sending metrics when
13
+ disabled
14
+ ([`11e3cd3`](https://github.com/dimanu-py/instant-python/commit/11e3cd3f8a5e97065e54bf2d101647fb59d913a8))
15
+
16
+ - **config**: Add metrics_enabled field to configuration for controlling metrics collection
17
+ ([`841cd9f`](https://github.com/dimanu-py/instant-python/commit/841cd9f73a8d6aa779a05f48cc160fe5f33d0123))
18
+
19
+ - **metrics**: Add error metrics handling in metrics middleware for improved exception tracking
20
+ ([`7192e88`](https://github.com/dimanu-py/instant-python/commit/7192e88fc6c294065bd2c4d74223f0de552c0d6b))
21
+
22
+ - **metrics**: Implement error handling in send_error method for capturing exceptions
23
+ ([`49d227f`](https://github.com/dimanu-py/instant-python/commit/49d227f700de0a550e7849a169f146df7fc33cde))
24
+
25
+ - **metrics**: Add error handling for command failures in usage metrics sender
26
+ ([`364a731`](https://github.com/dimanu-py/instant-python/commit/364a7317b0ed8c08a29d7525f98366eae7715835))
27
+
28
+ - **metrics**: Create class to store all data related to error event
29
+ ([`8174b3f`](https://github.com/dimanu-py/instant-python/commit/8174b3fc9f975cd338aeefcc0b28fb0cad86c180))
30
+
31
+ - **metrics**: Add send_error method to metrics reporter for error handling
32
+ ([`c3e2cdb`](https://github.com/dimanu-py/instant-python/commit/c3e2cdb6676c23c8476cb222f7d37c0de1b05a84))
33
+
34
+ - **metrics**: Add ConfigSnapshotPrimitives type and to_primitives method
35
+ ([`eb28115`](https://github.com/dimanu-py/instant-python/commit/eb28115bd5a3a62c3996d03fdc5f4fc3daadd168))
36
+
37
+ - **metrics**: Add snapshot creator instance inside metrics middleware
38
+ ([`a7f4984`](https://github.com/dimanu-py/instant-python/commit/a7f498437b503bf956ed9f40b95f1c6ebf9deaf2))
39
+
40
+ - **metrics**: Add method to create unknown ConfigSnapshot and handle missing config file
41
+ ([`4e17a87`](https://github.com/dimanu-py/instant-python/commit/4e17a8750b2c3d292da8d3280a4f25a4f521abda))
42
+
43
+ - **metrics**: Implement method to be able to compare two snapshots
44
+ ([`ec00d47`](https://github.com/dimanu-py/instant-python/commit/ec00d47167a5a47bb34394ce02a2fc663f542fb9))
45
+
46
+ - **metrics**: Implement 'is_unknown' method in config snapshot class to determine if it has been
47
+ properly read or not
48
+ ([`910c8d1`](https://github.com/dimanu-py/instant-python/commit/910c8d1502fa076167092ecad57dfd93314a9ccf))
49
+
50
+ - **metrics**: Implement use case to create a snapshot of the configuration file
51
+ ([`4ab1892`](https://github.com/dimanu-py/instant-python/commit/4ab18922bb15f5e73353ee646baa8be339445494))
52
+
53
+ - **shared**: Add 'for_metrics' method in config schema to be able to get only the data I need for
54
+ metrics and not need to access all the internals of the class
55
+ ([`feb27b7`](https://github.com/dimanu-py/instant-python/commit/feb27b77e9feab6c4a2b37bc5c790fb83544a2a2))
56
+
57
+ - **metrics**: Inject config repository to snapshot creator to be able to read an existing
58
+ configuration file
59
+ ([`e10e26c`](https://github.com/dimanu-py/instant-python/commit/e10e26cc0d46c46895cd4551897994a88f64008e))
60
+
61
+ - **metrics**: Create config snapshot class to store all the data related to the config file that
62
+ will be sent to metrics
63
+ ([`32db003`](https://github.com/dimanu-py/instant-python/commit/32db00308a09cecf12aa202574ad9e1a3f945d3b))
64
+
65
+ - **metrics**: Integrate MetricsMiddleware into InstantPythonTyper for enhanced command execution
66
+ metrics
67
+ ([`2b9db62`](https://github.com/dimanu-py/instant-python/commit/2b9db621867a196018afd6348c78e2b2adf0559a))
68
+
69
+ - **metrics**: Add MetricsMiddleware to handle command execution and send usage metrics data after
70
+ command execution has finished
71
+ ([`bdbbe00`](https://github.com/dimanu-py/instant-python/commit/bdbbe000e191ab72ca5c0eda97ba8a364346b5b4))
72
+
73
+ - **metrics**: Implement execute method in metrics sender use case to send usage metrics data
74
+ ([`2fbecb8`](https://github.com/dimanu-py/instant-python/commit/2fbecb804c15b95228df6612abaadc5a74e50ef1))
75
+
76
+ - **metrics**: Validate distinct ID format when loading from metrics file
77
+ ([`007c9d2`](https://github.com/dimanu-py/instant-python/commit/007c9d2958082d4b15d96eb0f5c0a4666153e24a))
78
+
79
+ - **metrics**: Handle JSON decoding errors and missing distinct ID in metrics file
80
+ ([`c2e6be6`](https://github.com/dimanu-py/instant-python/commit/c2e6be60a8191b710402356daddac43c6cb8f30b))
81
+
82
+ - **metrics**: Retrieve distinct ID from metrics.json if it exists so an existing user does not
83
+ generate a new id
84
+ ([`9b52f46`](https://github.com/dimanu-py/instant-python/commit/9b52f469598ee8b197448693e4a94e91f8396ab1))
85
+
86
+ - **metrics**: Store distinct ID in metrics.json on first execution
87
+ ([`da050c9`](https://github.com/dimanu-py/instant-python/commit/da050c94e57653fe56ad09e5aee3704d6e3638fb))
88
+
89
+ - **metrics**: Add UserIdentityManager to generate distinct user IDs
90
+ ([`36ef740`](https://github.com/dimanu-py/instant-python/commit/36ef7401467d4b20502e0c6d19cc80ffe8e0c588))
91
+
92
+ - **metrics**: Implement fire-and-forget strategy for metric sending
93
+ ([`6cc0761`](https://github.com/dimanu-py/instant-python/commit/6cc0761a8ca86d15472448f03724105cdb4e47e2))
94
+
95
+ - **metrics**: Enable sync mode for PostHog client initialization
96
+ ([`51c52bc`](https://github.com/dimanu-py/instant-python/commit/51c52bc235f16a70c5f646d3445fecc889063d78))
97
+
98
+ - **metrics**: Capture event to be sent to posthog using a temporary distinct_id
99
+ ([`db27119`](https://github.com/dimanu-py/instant-python/commit/db27119b567f438caf5444b0cc91e0a7872d85f1))
100
+
101
+ - **metrics**: Create posthog client inside reporter to be able to send metrics
102
+ ([`59aa393`](https://github.com/dimanu-py/instant-python/commit/59aa3938c5c9c29af31b5f52f21245c5d0a058c5))
103
+
104
+ - **metrics**: Create post hog config class to handle env variables related with post hog
105
+ ([`95a4516`](https://github.com/dimanu-py/instant-python/commit/95a4516df3defeb2f0b528b1a08d4f0426586869))
106
+
107
+ - **metrics**: Create dataclass to store all data related to usage metrics that will be send to
108
+ posthog
109
+ ([`0368a98`](https://github.com/dimanu-py/instant-python/commit/0368a98c71f82ab96db4e4bcb23e6142f6c3703a))
110
+
111
+ ### ⚙️ Build System
112
+
113
+ - **pyproject**: Add platformdirs as production dependency as it's not built-in with all supported
114
+ python versions
115
+ ([`ef5dcf3`](https://github.com/dimanu-py/instant-python/commit/ef5dcf34c9b1b9c6f16e6a0e83f29d67898a6694))
116
+
117
+ - **pyproject**: Update dependencies to remove vulnerability
118
+ ([`c858003`](https://github.com/dimanu-py/instant-python/commit/c858003272d4516a6b13e11f478a2cb9f2de895b))
119
+
120
+ - **pyproject**: Add vcr dependency to run posthog integration test without affecting current
121
+ project
122
+ ([`ccc11f0`](https://github.com/dimanu-py/instant-python/commit/ccc11f011ffe615c3b581c89de68db774c353033))
123
+
124
+ - **pyproject**: Add pydantic settings dependency to handle env variables gracefully
125
+ ([`0b8b19f`](https://github.com/dimanu-py/instant-python/commit/0b8b19fd7c315403f134c08272ca5ad9f0d0813f))
126
+
127
+ ### ♻️ Refactoring
128
+
129
+ - **metrics**: Streamline success metrics handling in metrics middleware
130
+ ([`65962b6`](https://github.com/dimanu-py/instant-python/commit/65962b630f2b049b0aec1336991dc79cf4757587))
131
+
132
+ - **metrics**: Update send_error method to include error parameter
133
+ ([`61210ac`](https://github.com/dimanu-py/instant-python/commit/61210acf4724a307a3b838821a59e00c06b97e87))
134
+
135
+ - **metrics**: Rename send method to send_success in metrics reporter
136
+ ([`462db4c`](https://github.com/dimanu-py/instant-python/commit/462db4c55778647dc82fe7095cb20a5712083951))
137
+
138
+ - **metrics**: Rename execute method to execute_on_success
139
+ ([`ac34809`](https://github.com/dimanu-py/instant-python/commit/ac34809dc85437768c9db23e429ddf44e2b622b5))
140
+
141
+ - **metrics**: Modify metrics middleware to take config snapshots to avoid errors when init command
142
+ finished its execution and config file is moved
143
+ ([`0716f62`](https://github.com/dimanu-py/instant-python/commit/0716f62fc01aaf4c598e3580714110fcb9807fbd))
144
+
145
+ - **metrics**: Enhance UsageMetricsEvent with dependency_manager and adjust built_in_features
146
+ initialization
147
+ ([`0281909`](https://github.com/dimanu-py/instant-python/commit/0281909b089a0bbfab5dc46dc8d0088e7ab0e59d))
148
+
149
+ - **metrics**: Update execute method to accept config_snapshot parameter and not need to read
150
+ configuration file
151
+ ([`ee03fc9`](https://github.com/dimanu-py/instant-python/commit/ee03fc9cb1e1c391caf0d650dbbe9514eaef9131))
152
+
153
+ - **metrics**: Rename UsageMetricsData to UsageMetricsEvent for clarity
154
+ ([`24a47ab`](https://github.com/dimanu-py/instant-python/commit/24a47ab97fc30bd7f9ad43a4acbb6a3573b1dacc))
155
+
156
+ - **metrics**: Simplify UsageMetricsSender initialization by removing repository parameter
157
+ ([`e5d5917`](https://github.com/dimanu-py/instant-python/commit/e5d5917df1044368f709183b0d5fa0a2c0bf41aa))
158
+
159
+ - **metrics**: Rename method to improve clarity in config reading
160
+ ([`9468e1a`](https://github.com/dimanu-py/instant-python/commit/9468e1a4ed7d96ef69c4eae1b4a52f712fdb37b9))
161
+
162
+ - **metrics**: Update ConfigSnapshotCreator to utilize for_metrics method for improved config
163
+ handling
164
+ ([`2ce0140`](https://github.com/dimanu-py/instant-python/commit/2ce0140eda8234fdcf722b7d0ef3c48ee612ce59))
165
+
166
+ - **config**: Improve error handling in configuration file loading
167
+ ([`1114c17`](https://github.com/dimanu-py/instant-python/commit/1114c17d570b989d85245dd0a032aeaf2a9af9f5))
168
+
169
+ - **metrics**: Extract configuration data handling into a separate method and streamline metrics
170
+ data creation
171
+ ([`e316523`](https://github.com/dimanu-py/instant-python/commit/e31652391e93f7da8c254a4e8283792eeb62f63e))
172
+
173
+ - **metrics**: Simplify execute method by removing success and error message parameters now that it
174
+ will be handled automatically by posthog reporter
175
+ ([`77469a9`](https://github.com/dimanu-py/instant-python/commit/77469a93fb411ef5ce6c8d000b25da1d2c9bc700))
176
+
177
+ - **metrics**: Rename get_distinct_id method to get_or_create_distinct_id for clarity
178
+ ([`0a068c7`](https://github.com/dimanu-py/instant-python/commit/0a068c7e6903e00a590d76b058510627108be592))
179
+
180
+ - **metrics**: Rename metric reporter classes for consistency
181
+ ([`15f122f`](https://github.com/dimanu-py/instant-python/commit/15f122f472c3e270e2ec3461be626c9b874eb12d))
182
+
183
+ - **metrics**: Remove success an error message data from metrics object as posthog is configured to
184
+ report errors automatically
185
+ ([`0f4eb0b`](https://github.com/dimanu-py/instant-python/commit/0f4eb0b94f5fbe63477a8da6586ad39d74219125))
186
+
187
+ - **metrics**: Update post hog metric reporter to use user identity manager and create consistent
188
+ distinct ids
189
+ ([`b5ad406`](https://github.com/dimanu-py/instant-python/commit/b5ad406236641adaad3590a767245caad610427f))
190
+
191
+ - **metrics**: Set config dir to be the .config folder of user system if is not passed and extract
192
+ named variables to improve readability
193
+ ([`2e54e8e`](https://github.com/dimanu-py/instant-python/commit/2e54e8edc72ca118f47222302d4fa6c2c2e94556))
194
+
195
+ - **metrics**: Modify distinct ID handling to improve readability and maintainability
196
+ ([`aa8d52b`](https://github.com/dimanu-py/instant-python/commit/aa8d52b462f486c47a72a3c33cc2d392ae726249))
197
+
198
+ - **metrics**: Use usage metrics data class for send method in metric reporter
199
+ ([`96393c2`](https://github.com/dimanu-py/instant-python/commit/96393c27088fbfb691b9c0fbb205bdd31f609ad2))
200
+
201
+
5
202
  ## v0.20.0 (2025-12-05)
6
203
 
7
204
  ### ✨ Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: instant-python
3
- Version: 0.20.0
3
+ Version: 0.21.0
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/
@@ -220,7 +220,9 @@ Classifier: Topic :: System :: Installation/Setup
220
220
  Classifier: Topic :: System :: Shells
221
221
  Requires-Python: >=3.9
222
222
  Requires-Dist: jinja2>=3.1.6
223
+ Requires-Dist: platformdirs>=4.4.0
223
224
  Requires-Dist: posthog>=6.9.3
225
+ Requires-Dist: pydantic-settings>=2.11.0
224
226
  Requires-Dist: pyyaml>=6.0.2
225
227
  Requires-Dist: questionary>=2.1.0
226
228
  Requires-Dist: typer>=0.15.1
@@ -281,10 +283,12 @@ so can quickly find what you need.
281
283
 
282
284
  - [Installation]: begin by learning how to install `instant-python`.
283
285
  - [First Steps]: get started with the basic features of `instant-python`.
286
+ - [Privacy & Metrics]: learn about the anonymous usage data we collect and how to opt out.
284
287
  - [Advanced Usage and Customization]: explore advanced features and customization options.
285
288
 
286
289
  [Installation]: https://dimanu-py.github.io/instant-python/getting_started/installation/
287
290
  [First Steps]: https://dimanu-py.github.io/instant-python/getting_started/first_steps/
291
+ [Privacy & Metrics]: https://dimanu-py.github.io/instant-python/getting_started/privacy_and_metrics/
288
292
  [Advanced Usage and Customization]: https://dimanu-py.github.io/instant-python/guide/
289
293
 
290
294
  ### For Developers
@@ -305,14 +309,23 @@ so can quickly find what you need.
305
309
  [GitHub Discussions]: https://github.com/dimanu-py/instant-python/discussions
306
310
  [GitHub Issues]: https://github.com/dimanu-py/instant-python/issues
307
311
 
308
- [//]: # (### Do Not Track)
312
+ ## 🔒 Privacy & Usage Metrics
309
313
 
310
- [//]: # ()
311
- [//]: # (In order to get better insights about the usage of the library, we collect anonymous usage data. The only)
314
+ To improve `instant-python` and provide a better experience, we collect **anonymous usage metrics**.
315
+ No personal or sensitive information is collected.
312
316
 
313
- [//]: # (data we collect is the commands you run. No personal data is collected as part of this request.)
317
+ **What we collect:**
318
+ - Command executed and IPY version
319
+ - Operating system type
320
+ - Python version, dependency manager, and template choices
321
+ - Error types (when commands fail)
314
322
 
315
- [//]: # ()
316
- [//]: # (You can disable this feature by setting the environment variable `INSTANT_PYTHON_NO_TRACK` to `1` or )
323
+ **What we DON'T collect:**
324
+ - No file paths, project names, or code content
325
+ - No personal information or IP addresses
326
+
327
+ **How to opt out:**
328
+ Set the environment variable `IPY_METRICS_ENABLE=false`
329
+
330
+ For complete details, see our [Privacy & Metrics documentation](https://dimanu-py.github.io/instant-python/getting_started/privacy_and_metrics/).
317
331
 
318
- [//]: # (passing the `--no-track` option to any command.)
@@ -51,10 +51,12 @@ so can quickly find what you need.
51
51
 
52
52
  - [Installation]: begin by learning how to install `instant-python`.
53
53
  - [First Steps]: get started with the basic features of `instant-python`.
54
+ - [Privacy & Metrics]: learn about the anonymous usage data we collect and how to opt out.
54
55
  - [Advanced Usage and Customization]: explore advanced features and customization options.
55
56
 
56
57
  [Installation]: https://dimanu-py.github.io/instant-python/getting_started/installation/
57
58
  [First Steps]: https://dimanu-py.github.io/instant-python/getting_started/first_steps/
59
+ [Privacy & Metrics]: https://dimanu-py.github.io/instant-python/getting_started/privacy_and_metrics/
58
60
  [Advanced Usage and Customization]: https://dimanu-py.github.io/instant-python/guide/
59
61
 
60
62
  ### For Developers
@@ -75,14 +77,23 @@ so can quickly find what you need.
75
77
  [GitHub Discussions]: https://github.com/dimanu-py/instant-python/discussions
76
78
  [GitHub Issues]: https://github.com/dimanu-py/instant-python/issues
77
79
 
78
- [//]: # (### Do Not Track)
80
+ ## 🔒 Privacy & Usage Metrics
79
81
 
80
- [//]: # ()
81
- [//]: # (In order to get better insights about the usage of the library, we collect anonymous usage data. The only)
82
+ To improve `instant-python` and provide a better experience, we collect **anonymous usage metrics**.
83
+ No personal or sensitive information is collected.
82
84
 
83
- [//]: # (data we collect is the commands you run. No personal data is collected as part of this request.)
85
+ **What we collect:**
86
+ - Command executed and IPY version
87
+ - Operating system type
88
+ - Python version, dependency manager, and template choices
89
+ - Error types (when commands fail)
84
90
 
85
- [//]: # ()
86
- [//]: # (You can disable this feature by setting the environment variable `INSTANT_PYTHON_NO_TRACK` to `1` or )
91
+ **What we DON'T collect:**
92
+ - No file paths, project names, or code content
93
+ - No personal information or IP addresses
94
+
95
+ **How to opt out:**
96
+ Set the environment variable `IPY_METRICS_ENABLE=false`
97
+
98
+ For complete details, see our [Privacy & Metrics documentation](https://dimanu-py.github.io/instant-python/getting_started/privacy_and_metrics/).
87
99
 
88
- [//]: # (passing the `--no-track` option to any command.)
@@ -0,0 +1,137 @@
1
+ # Privacy and Usage Metrics
2
+
3
+ !!! info "Anonymous Usage Data"
4
+ To improve `instant-python` and provide a better experience to all users, we collect **anonymous usage metrics**.
5
+ No personal or sensitive information is collected.
6
+
7
+ This page explains what data we collect, why we collect it, and how to disable it if you prefer.
8
+
9
+ ## Why We Collect Metrics
10
+
11
+ We collect anonymous usage data to:
12
+
13
+ - 📊 **Understand which features are most used** - This helps us prioritize improvements and new features
14
+ - 🐛 **Identify common errors** - We can proactively fix bugs that users encounter
15
+ - 🚀 **Improve user experience** - By understanding how people use the tool, we can make it better
16
+ - 📈 **Make data-driven decisions** - We can focus our efforts on what matters most to the community
17
+
18
+ **Your privacy is important to us.** We only collect the minimum data necessary to achieve these goals,
19
+ and we never collect personal information like file paths, project names, or any code content.
20
+
21
+ ## What Data We Collect
22
+
23
+ ### On Successful Command Execution
24
+
25
+ When you successfully run an `ipy` command, we collect:
26
+
27
+ | Data Field | Description | Example |
28
+ |------------|-------------|----------------------------------------------|
29
+ | `ipy_version` | The version of instant-python you're using | `0.20.0` |
30
+ | `operating_system` | Your operating system | `Linux`, `Darwin`, `Windows` |
31
+ | `command` | The command you executed | `config`, `init` |
32
+ | `python_version` | The Python version you configured | `3.12` |
33
+ | `dependency_manager` | The package manager you selected | `pdm`, `uv` |
34
+ | `template` | The project template you chose | `domain_driven_design`, `clean_architecture` |
35
+ | `built_in_features` | List of features you enabled | `["makefile", "value_objects"]` |
36
+
37
+ ### On Command Errors
38
+
39
+ When a command fails with an error, we collect:
40
+
41
+ | Data Field | Description | Example |
42
+ |------------|-------------|---------|
43
+ | `ipy_version` | The version of instant-python you're using | `1.2.3` |
44
+ | `operating_system` | Your operating system | `Linux`, `Darwin`, `Windows` |
45
+ | `command` | The command that failed | `config`, `init` |
46
+ | `error_type` | The type of error that occurred | `FileNotFoundError`, `ValueError` |
47
+ | `error_message` | The error message | `Configuration file not found` |
48
+
49
+ ## What We DON'T Collect
50
+
51
+ We want to be transparent about what we **do not** collect:
52
+
53
+ - ❌ **No personal information** - We don't collect your name, email, IP address, or any identifiable information
54
+ - ❌ **No file paths** - We never collect the paths where you create projects
55
+ - ❌ **No project names** - Your project names remain completely private
56
+ - ❌ **No code content** - We never collect any of your code or file contents
57
+ - ❌ **No environment variables** - Except for the opt-out flag, we don't read your environment
58
+
59
+ ## How to Disable Metrics Collection
60
+
61
+ If you prefer not to send usage metrics, you can easily disable this feature.
62
+
63
+ Set the `IPY_METRICS_ENABLE` environment variable to `false` or `0`:
64
+
65
+ ### Linux/macOS
66
+
67
+ - Bash/Zsh:
68
+
69
+ For a single command run:
70
+
71
+ ```bash
72
+ IPY_METRICS_ENABLE=false ipy config
73
+ ```
74
+
75
+ Permanently in your shell profile (_~/.bashrc_, _~/.zshrc_, etc.)
76
+
77
+ ```bash
78
+ export IPY_METRICS_ENABLE=false
79
+ ```
80
+
81
+ - Fish:
82
+
83
+ For a single command run:
84
+
85
+ ```bash
86
+ env IPY_METRICS_ENABLE=false ipy config
87
+ ```
88
+
89
+ Permanently in your shell profile (_~/.config/fish/config.fish_)
90
+
91
+ ```fish
92
+ set -Ux IPY_METRICS_ENABLE false
93
+ ```
94
+
95
+ ### Windows
96
+
97
+ - PowerShell
98
+
99
+ For a single command:
100
+
101
+ ```powershell
102
+ $env:IPY_METRICS_ENABLE="false"; ipy config
103
+ ```
104
+
105
+ Permanently for the current user:
106
+
107
+ ```powershell
108
+ [Environment]::SetEnvironmentVariable("IPY_METRICS_ENABLE", "false", "User")
109
+ ```
110
+
111
+ - CMD
112
+
113
+ For a single command
114
+ ```cmd
115
+ set IPY_METRICS_ENABLE=false && ipy config
116
+ ```
117
+
118
+ Permanently for the current user:
119
+
120
+ ```cmd
121
+ setx IPY_METRICS_ENABLE "false"
122
+ ```
123
+
124
+ ## Questions or Concerns?
125
+
126
+ If you have any questions or concerns about our data collection practices:
127
+
128
+ - 💬 Start a discussion on [GitHub Discussions]
129
+ - 🐛 Report issues on [GitHub Issues]
130
+ - 🔒 For security concerns, see our [Security Policy]
131
+
132
+ We're committed to transparency and respect for your privacy. Thank you for helping us improve `instant-python`!
133
+
134
+ [GitHub Discussions]: https://github.com/dimanu-py/instant-python/discussions
135
+ [GitHub Issues]: https://github.com/dimanu-py/instant-python/issues
136
+ [Security Policy]: ../development/security.md
137
+
@@ -33,10 +33,12 @@ so can quickly find what you need.
33
33
 
34
34
  - [Installation]: begin by learning how to install `instant-python`.
35
35
  - [First Steps]: get started with the basic features of `instant-python`.
36
+ - [Privacy & Metrics]: learn about the anonymous usage data we collect and how to opt out.
36
37
  - [Advanced Usage and Customization]: explore advanced features and customization options.
37
38
 
38
39
  [Installation]: ../getting_started/installation.md
39
40
  [First Steps]: ../getting_started/first_steps.md
41
+ [Privacy & Metrics]: ../getting_started/privacy_and_metrics.md
40
42
  [Advanced Usage and Customization]: ../guide/index.md
41
43
 
42
44
  ### For Developers
@@ -0,0 +1 @@
1
+ __version__ = "0.21.0"
@@ -5,12 +5,13 @@ from rich.console import Console
5
5
  from rich.panel import Panel
6
6
 
7
7
  from instant_python import __version__
8
+ from instant_python.cli.instant_python_typer import InstantPythonTyper
8
9
  from instant_python.config.delivery import cli as config
9
10
  from instant_python.initialize.delivery import cli as init
11
+ from instant_python.metrics.delivery.metrics_middleware import MetricsMiddleware
10
12
  from instant_python.shared.application_error import ApplicationError
11
- from instant_python.cli.instant_python_typer import InstantPythonTyper
12
13
 
13
- app = InstantPythonTyper()
14
+ app = InstantPythonTyper(cls=MetricsMiddleware)
14
15
  console = Console()
15
16
 
16
17
 
@@ -0,0 +1,22 @@
1
+ from pathlib import Path
2
+ from typing import Any
3
+
4
+ from instant_python.metrics.domain.config_snapshot import ConfigSnapshot
5
+ from instant_python.shared.domain.config_repository import ConfigRepository
6
+ from instant_python.shared.domain.config_schema import ConfigSchema
7
+ from instant_python.shared.infra.persistence.yaml_config_repository import ConfigurationFileNotFound
8
+
9
+
10
+ class ConfigSnapshotCreator:
11
+ def __init__(self, repository: ConfigRepository) -> None:
12
+ self._repository = repository
13
+
14
+ def execute(self, config_path: Path) -> Any:
15
+ try:
16
+ config = self._read_config_from(config_path)
17
+ except ConfigurationFileNotFound:
18
+ return ConfigSnapshot.unknown()
19
+ return ConfigSnapshot(**config.for_metrics())
20
+
21
+ def _read_config_from(self, config_path: Path) -> ConfigSchema:
22
+ return self._repository.read(config_path)
@@ -0,0 +1,41 @@
1
+ import platform
2
+
3
+ from instant_python import __version__
4
+ from instant_python.metrics.domain.config_snapshot import ConfigSnapshot
5
+ from instant_python.metrics.domain.error_metrics_event import ErrorMetricsEvent
6
+ from instant_python.metrics.domain.metrics_reporter import MetricsReporter
7
+ from instant_python.metrics.domain.usage_metrics_data import UsageMetricsEvent
8
+
9
+
10
+ class UsageMetricsSender:
11
+ def __init__(self, reporter: MetricsReporter) -> None:
12
+ self._reporter = reporter
13
+
14
+ def execute_on_success(self, command_name: str, config_snapshot: ConfigSnapshot) -> None:
15
+ config = config_snapshot.to_primitives()
16
+ metrics_event = UsageMetricsEvent(
17
+ ipy_version=__version__,
18
+ operating_system=platform.system(),
19
+ command=command_name,
20
+ python_version=config["python_version"],
21
+ dependency_manager=config["dependency_manager"],
22
+ template=config["template_type"],
23
+ built_in_features=config["built_in_features"],
24
+ )
25
+ self._send_metrics_report(metrics_event)
26
+
27
+ def execute_on_failure(self, command_name: str, error: Exception) -> None:
28
+ error_event = ErrorMetricsEvent(
29
+ ipy_version=__version__,
30
+ operating_system=platform.system(),
31
+ command=command_name,
32
+ error_type=type(error).__name__,
33
+ error_message=str(error),
34
+ )
35
+ self._send_error_report(error, error_event)
36
+
37
+ def _send_metrics_report(self, metrics_data: UsageMetricsEvent) -> None:
38
+ self._reporter.send_success(metrics_data)
39
+
40
+ def _send_error_report(self, error: Exception, error_event: ErrorMetricsEvent) -> None:
41
+ self._reporter.send_error(error, error_event)
@@ -0,0 +1,88 @@
1
+ import threading
2
+ from pathlib import Path
3
+ from typing import Any
4
+
5
+ from click import Context
6
+ from typer.core import TyperGroup
7
+
8
+ from instant_python.metrics.application.config_snapshot_creator import ConfigSnapshotCreator
9
+ from instant_python.metrics.application.usage_metrics_sender import UsageMetricsSender
10
+ from instant_python.metrics.domain.config_snapshot import ConfigSnapshot
11
+ from instant_python.metrics.infra.post_hog_config import PostHogConfig
12
+ from instant_python.metrics.infra.post_hog_metrics_reporter import PostHogMetricsReporter
13
+ from instant_python.metrics.infra.user_identity_manager import UserIdentityManager
14
+ from instant_python.shared.infra.persistence.yaml_config_repository import YamlConfigRepository
15
+
16
+
17
+ class MetricsMiddleware(TyperGroup):
18
+ def __init__(self, *args, **kwargs) -> None:
19
+ super().__init__(*args, **kwargs)
20
+ self._config_snapshot_creator = ConfigSnapshotCreator(repository=YamlConfigRepository())
21
+ self._metrics_sender = UsageMetricsSender(
22
+ reporter=PostHogMetricsReporter(
23
+ config=PostHogConfig(),
24
+ user_identity_manager=UserIdentityManager(),
25
+ ),
26
+ )
27
+
28
+ def invoke(self, ctx: Context) -> Any:
29
+ config_path = self._extract_config_path(ctx)
30
+ config_snapshot = self._take_first_config_snapshot(config_path)
31
+ try:
32
+ self._execute_command(ctx)
33
+ except Exception as exception:
34
+ self._send_error_metrics(ctx, exception)
35
+ raise exception
36
+ self._send_success_metrics(config_path, config_snapshot, ctx)
37
+
38
+ def _send_success_metrics(self, config_path: Path, config_snapshot: ConfigSnapshot, ctx: Context) -> None:
39
+ config_snapshot = self._retake_config_snapshot_if_needed(config_snapshot, config_path)
40
+ command = self._extract_executed_command(ctx)
41
+ self._send_metrics_data(command, config_snapshot)
42
+
43
+ def _send_error_metrics(self, ctx: Context, exception: Exception) -> None:
44
+ command = self._extract_executed_command(ctx)
45
+ self._send_error_data(command, exception)
46
+
47
+ def _execute_command(self, ctx: Context) -> None:
48
+ super().invoke(ctx)
49
+
50
+ @staticmethod
51
+ def _extract_executed_command(ctx: Context) -> str:
52
+ return ctx.invoked_subcommand
53
+
54
+ @staticmethod
55
+ def _extract_config_path(ctx: Context) -> Path:
56
+ if ctx.args and ["--config", "-c"] in ctx.args:
57
+ return (
58
+ Path(ctx.args[ctx.args.index("--config") + 1])
59
+ if "--config" in ctx.args
60
+ else Path(ctx.args[ctx.args.index("-c") + 1])
61
+ )
62
+ return Path("ipy.yml")
63
+
64
+ def _take_first_config_snapshot(self, config_path: Path) -> ConfigSnapshot:
65
+ return self._config_snapshot_creator.execute(config_path)
66
+
67
+ def _retake_config_snapshot_if_needed(self, config_snapshot: ConfigSnapshot, config_path: Path) -> ConfigSnapshot:
68
+ if config_snapshot.is_unknown():
69
+ return self._config_snapshot_creator.execute(config_path)
70
+ return config_snapshot
71
+
72
+ def _send_metrics_data(self, command: str, config_snapshot: ConfigSnapshot) -> None:
73
+ thread = threading.Thread(
74
+ target=self._metrics_sender.execute_on_success,
75
+ args=(command, config_snapshot),
76
+ daemon=True,
77
+ )
78
+ thread.start()
79
+ thread.join(timeout=5.0)
80
+
81
+ def _send_error_data(self, command: str, exception: Exception) -> None:
82
+ thread = threading.Thread(
83
+ target=self._metrics_sender.execute_on_failure,
84
+ args=(command, exception),
85
+ daemon=True,
86
+ )
87
+ thread.start()
88
+ thread.join(timeout=5.0)