aury-boot 0.0.15__tar.gz → 0.0.18__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 (199) hide show
  1. {aury_boot-0.0.15 → aury_boot-0.0.18}/PKG-INFO +1 -1
  2. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/_version.py +2 -2
  3. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/app/components.py +50 -3
  4. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/app/startup.py +1 -1
  5. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/config/settings.py +31 -0
  6. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/AGENTS.md.tpl +12 -0
  7. aury_boot-0.0.18/aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +178 -0
  8. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/99-cli.md.tpl +1 -1
  9. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/modules/schedules.py.tpl +4 -1
  10. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/cache/manager.py +5 -1
  11. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/scheduler/manager.py +125 -128
  12. aury_boot-0.0.15/aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +0 -32
  13. {aury_boot-0.0.15 → aury_boot-0.0.18}/.gitignore +0 -0
  14. {aury_boot-0.0.15 → aury_boot-0.0.18}/README.md +0 -0
  15. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/__init__.py +0 -0
  16. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/__init__.py +0 -0
  17. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/adapter/__init__.py +0 -0
  18. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/adapter/base.py +0 -0
  19. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/adapter/config.py +0 -0
  20. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/adapter/decorators.py +0 -0
  21. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/adapter/exceptions.py +0 -0
  22. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/adapter/http.py +0 -0
  23. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/app/__init__.py +0 -0
  24. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/app/base.py +0 -0
  25. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/app/middlewares.py +0 -0
  26. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/config/__init__.py +0 -0
  27. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/config/multi_instance.py +0 -0
  28. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/constants/__init__.py +0 -0
  29. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/constants/components.py +0 -0
  30. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/constants/scheduler.py +0 -0
  31. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/constants/service.py +0 -0
  32. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/errors/__init__.py +0 -0
  33. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/errors/chain.py +0 -0
  34. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/errors/codes.py +0 -0
  35. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/errors/exceptions.py +0 -0
  36. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/errors/handlers.py +0 -0
  37. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/errors/response.py +0 -0
  38. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/interfaces/__init__.py +0 -0
  39. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/interfaces/egress.py +0 -0
  40. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/interfaces/ingress.py +0 -0
  41. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/middleware/__init__.py +0 -0
  42. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/middleware/logging.py +0 -0
  43. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/migrations/__init__.py +0 -0
  44. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/migrations/manager.py +0 -0
  45. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/migrations/setup.py +0 -0
  46. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/rpc/__init__.py +0 -0
  47. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/rpc/base.py +0 -0
  48. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/rpc/client.py +0 -0
  49. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/rpc/discovery.py +0 -0
  50. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/scheduler/__init__.py +0 -0
  51. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/scheduler/runner.py +0 -0
  52. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/application/server/__init__.py +0 -0
  53. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/__init__.py +0 -0
  54. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/add.py +0 -0
  55. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/app.py +0 -0
  56. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/config.py +0 -0
  57. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/docker.py +0 -0
  58. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/docs.py +0 -0
  59. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/generate.py +0 -0
  60. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/init.py +0 -0
  61. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/migrate/__init__.py +0 -0
  62. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/migrate/app.py +0 -0
  63. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/migrate/commands.py +0 -0
  64. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/pkg.py +0 -0
  65. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/scheduler.py +0 -0
  66. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/server/__init__.py +0 -0
  67. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/server/app.py +0 -0
  68. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/generate/api.py.tpl +0 -0
  69. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/generate/model.py.tpl +0 -0
  70. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/generate/repository.py.tpl +0 -0
  71. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/generate/schema.py.tpl +0 -0
  72. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/generate/service.py.tpl +0 -0
  73. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/README.md.tpl +0 -0
  74. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/admin_console_init.py.tpl +0 -0
  75. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +0 -0
  76. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +0 -0
  77. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +0 -0
  78. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +0 -0
  79. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +0 -0
  80. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +0 -0
  81. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +0 -0
  82. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +0 -0
  83. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +0 -0
  84. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +0 -0
  85. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +0 -0
  86. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +0 -0
  87. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +0 -0
  88. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +0 -0
  89. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +0 -0
  90. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl +0 -0
  91. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/config.py.tpl +0 -0
  92. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/conftest.py.tpl +0 -0
  93. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/_header.tpl +0 -0
  94. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/admin.tpl +0 -0
  95. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/cache.tpl +0 -0
  96. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/database.tpl +0 -0
  97. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/log.tpl +0 -0
  98. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/messaging.tpl +0 -0
  99. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/rpc.tpl +0 -0
  100. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/scheduler.tpl +0 -0
  101. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/service.tpl +0 -0
  102. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/storage.tpl +0 -0
  103. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/env_templates/third_party.tpl +0 -0
  104. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/gitignore.tpl +0 -0
  105. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/main.py.tpl +0 -0
  106. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/modules/api.py.tpl +0 -0
  107. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/modules/exceptions.py.tpl +0 -0
  108. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/templates/project/modules/tasks.py.tpl +0 -0
  109. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/commands/worker.py +0 -0
  110. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/__init__.py +0 -0
  111. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/exceptions/__init__.py +0 -0
  112. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/i18n/__init__.py +0 -0
  113. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/i18n/translator.py +0 -0
  114. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/logging/__init__.py +0 -0
  115. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/logging/context.py +0 -0
  116. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/logging/decorators.py +0 -0
  117. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/logging/format.py +0 -0
  118. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/common/logging/setup.py +0 -0
  119. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/contrib/__init__.py +0 -0
  120. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/contrib/admin_console/__init__.py +0 -0
  121. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/contrib/admin_console/auth.py +0 -0
  122. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/contrib/admin_console/discovery.py +0 -0
  123. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/contrib/admin_console/install.py +0 -0
  124. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/contrib/admin_console/utils.py +0 -0
  125. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/__init__.py +0 -0
  126. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/exceptions/__init__.py +0 -0
  127. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/models/__init__.py +0 -0
  128. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/models/base.py +0 -0
  129. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/models/mixins.py +0 -0
  130. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/models/models.py +0 -0
  131. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/pagination/__init__.py +0 -0
  132. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/repository/__init__.py +0 -0
  133. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/repository/impl.py +0 -0
  134. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/repository/interceptors.py +0 -0
  135. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/repository/interface.py +0 -0
  136. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/repository/query_builder.py +0 -0
  137. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/service/__init__.py +0 -0
  138. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/service/base.py +0 -0
  139. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/domain/transaction/__init__.py +0 -0
  140. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/__init__.py +0 -0
  141. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/cache/__init__.py +0 -0
  142. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/cache/backends.py +0 -0
  143. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/cache/base.py +0 -0
  144. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/cache/exceptions.py +0 -0
  145. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/cache/factory.py +0 -0
  146. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/channel/__init__.py +0 -0
  147. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/channel/backends/__init__.py +0 -0
  148. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/channel/backends/memory.py +0 -0
  149. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/channel/backends/redis.py +0 -0
  150. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/channel/base.py +0 -0
  151. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/channel/manager.py +0 -0
  152. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/__init__.py +0 -0
  153. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/rabbitmq/__init__.py +0 -0
  154. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/rabbitmq/config.py +0 -0
  155. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/rabbitmq/manager.py +0 -0
  156. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/redis/__init__.py +0 -0
  157. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/redis/config.py +0 -0
  158. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/clients/redis/manager.py +0 -0
  159. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/database/__init__.py +0 -0
  160. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/database/config.py +0 -0
  161. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/database/exceptions.py +0 -0
  162. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/database/manager.py +0 -0
  163. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/database/query_tools/__init__.py +0 -0
  164. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/database/strategies/__init__.py +0 -0
  165. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/di/__init__.py +0 -0
  166. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/di/container.py +0 -0
  167. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/__init__.py +0 -0
  168. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/backends/__init__.py +0 -0
  169. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/backends/memory.py +0 -0
  170. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/backends/rabbitmq.py +0 -0
  171. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/backends/redis.py +0 -0
  172. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/base.py +0 -0
  173. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/manager.py +0 -0
  174. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/events/middleware.py +0 -0
  175. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/monitoring/__init__.py +0 -0
  176. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/mq/__init__.py +0 -0
  177. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/mq/backends/__init__.py +0 -0
  178. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/mq/backends/rabbitmq.py +0 -0
  179. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/mq/backends/redis.py +0 -0
  180. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/mq/base.py +0 -0
  181. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/mq/manager.py +0 -0
  182. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/scheduler/__init__.py +0 -0
  183. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/scheduler/exceptions.py +0 -0
  184. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/storage/__init__.py +0 -0
  185. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/storage/base.py +0 -0
  186. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/storage/exceptions.py +0 -0
  187. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/storage/factory.py +0 -0
  188. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/tasks/__init__.py +0 -0
  189. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/tasks/config.py +0 -0
  190. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/tasks/constants.py +0 -0
  191. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/tasks/exceptions.py +0 -0
  192. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/infrastructure/tasks/manager.py +0 -0
  193. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/testing/__init__.py +0 -0
  194. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/testing/base.py +0 -0
  195. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/testing/client.py +0 -0
  196. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/testing/factory.py +0 -0
  197. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/toolkit/__init__.py +0 -0
  198. {aury_boot-0.0.15 → aury_boot-0.0.18}/aury/boot/toolkit/http/__init__.py +0 -0
  199. {aury_boot-0.0.15 → aury_boot-0.0.18}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aury-boot
3
- Version: 0.0.15
3
+ Version: 0.0.18
4
4
  Summary: Aury Boot - 基于 FastAPI 生态的企业级 API 开发框架
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: alembic>=1.17.2
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.15'
32
- __version_tuple__ = version_tuple = (0, 0, 15)
31
+ __version__ = version = '0.0.18'
32
+ __version_tuple__ = version_tuple = (0, 0, 18)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -281,18 +281,65 @@ class SchedulerComponent(Component):
281
281
  except Exception as e:
282
282
  logger.warning(f"加载定时任务模块失败 ({module_name}): {e}")
283
283
 
284
+ def _build_scheduler_config(self, config: BaseConfig) -> dict:
285
+ """根据配置构建 APScheduler 初始化参数。"""
286
+ scheduler_kwargs: dict = {}
287
+ scheduler_config = config.scheduler
288
+
289
+ # jobstores: 根据 URL 自动选择存储后端
290
+ if scheduler_config.jobstore_url:
291
+ url = scheduler_config.jobstore_url
292
+ if url.startswith("redis://"):
293
+ try:
294
+ from apscheduler.jobstores.redis import RedisJobStore
295
+ scheduler_kwargs["jobstores"] = {
296
+ "default": RedisJobStore.from_url(url)
297
+ }
298
+ logger.info(f"调度器使用 Redis 存储: {url.split('@')[-1]}")
299
+ except ImportError:
300
+ logger.warning("Redis jobstore 需要安装 redis: pip install redis")
301
+ else:
302
+ # SQLAlchemy 存储 (sqlite/postgresql/mysql)
303
+ try:
304
+ from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
305
+ scheduler_kwargs["jobstores"] = {
306
+ "default": SQLAlchemyJobStore(url=url)
307
+ }
308
+ logger.info("调度器使用 SQLAlchemy 存储")
309
+ except ImportError:
310
+ logger.warning("SQLAlchemy jobstore 需要安装 sqlalchemy")
311
+
312
+ # timezone
313
+ if scheduler_config.timezone:
314
+ scheduler_kwargs["timezone"] = scheduler_config.timezone
315
+
316
+ # job_defaults
317
+ scheduler_kwargs["job_defaults"] = {
318
+ "coalesce": scheduler_config.coalesce,
319
+ "max_instances": scheduler_config.max_instances,
320
+ "misfire_grace_time": scheduler_config.misfire_grace_time,
321
+ }
322
+
323
+ return scheduler_kwargs
324
+
284
325
  async def setup(self, app: FoundationApp, config: BaseConfig) -> None:
285
326
  """启动调度器。
286
327
 
287
- 1. 自动发现并加载定时任务模块
288
- 2. 启动调度器(注册装饰器收集的任务)
328
+ 1. 根据配置初始化调度器(jobstore/timezone/job_defaults)
329
+ 2. 自动发现并加载定时任务模块
330
+ 3. 启动调度器(注册装饰器收集的任务)
289
331
  """
290
332
  try:
333
+ # 构建配置
334
+ scheduler_kwargs = self._build_scheduler_config(config)
335
+
336
+ # 获取/创建调度器实例
337
+ scheduler = SchedulerManager.get_instance("default", **scheduler_kwargs)
338
+
291
339
  # 自动发现并加载定时任务模块
292
340
  self._autodiscover_schedules(app, config)
293
341
 
294
342
  # 启动调度器
295
- scheduler = SchedulerManager.get_instance()
296
343
  scheduler.start()
297
344
  except Exception as e:
298
345
  logger.warning(f"调度器启动失败(非关键): {e}")
@@ -152,7 +152,7 @@ def collect_component_status() -> list[ComponentStatus]:
152
152
  name="Cache" if name == "default" else f"Cache [{name}]",
153
153
  status="ok",
154
154
  backend=instance.backend_type,
155
- url=instance._config.get("CACHE_URL") if instance._config else None,
155
+ url=(instance._config or {}).get("CACHE_URL"),
156
156
  )
157
157
  )
158
158
 
@@ -416,6 +416,10 @@ class SchedulerSettings(BaseModel):
416
416
  - SCHEDULER__ENABLED=false: 只运行 API,不启动调度器
417
417
 
418
418
  独立调度器通过 `aury scheduler` 命令运行,不需要此配置。
419
+
420
+ 分布式调度:
421
+ - 配置 SCHEDULER__JOBSTORE_URL 使用 Redis/SQLAlchemy 存储
422
+ - 多节点部署时共享任务状态
419
423
  """
420
424
 
421
425
  enabled: bool = Field(
@@ -426,6 +430,33 @@ class SchedulerSettings(BaseModel):
426
430
  default_factory=list,
427
431
  description="定时任务模块列表。为空时自动发现 schedules 模块"
428
432
  )
433
+ # APScheduler 配置
434
+ jobstore_url: str | None = Field(
435
+ default=None,
436
+ description=(
437
+ "任务存储 URL。支持:\n"
438
+ "- redis://localhost:6379/0(Redis 存储)\n"
439
+ "- sqlite:///jobs.db(SQLite 存储)\n"
440
+ "- postgresql://user:pass@host/db(PostgreSQL 存储)\n"
441
+ "- 不配置则使用内存存储"
442
+ )
443
+ )
444
+ timezone: str | None = Field(
445
+ default=None,
446
+ description="调度器时区,如 Asia/Shanghai、UTC"
447
+ )
448
+ coalesce: bool = Field(
449
+ default=True,
450
+ description="是否合并错过的任务执行(多次错过只执行一次)"
451
+ )
452
+ max_instances: int = Field(
453
+ default=1,
454
+ description="同一任务的最大并发实例数"
455
+ )
456
+ misfire_grace_time: int = Field(
457
+ default=60,
458
+ description="任务错过容忍时间(秒),超过此时间则跳过"
459
+ )
429
460
 
430
461
 
431
462
  class TaskSettings(BaseModel):
@@ -122,6 +122,8 @@ mypy {package_name}/
122
122
 
123
123
  ## 代码规范
124
124
 
125
+ > 项目所有业务配置请通过应用 `settings`/配置对象获取,**不要**直接使用 `os.environ` 在业务代码中读环境变量。
126
+
125
127
  ### Model 规范
126
128
 
127
129
  - **必须**继承框架预定义基类,**不要**直接继承 `Base`
@@ -129,6 +131,16 @@ mypy {package_name}/
129
131
  - 软删除模型**必须**使用复合唯一约束(包含 `deleted_at`),不能单独使用 `unique=True`
130
132
  - **不建议**使用数据库外键(`ForeignKey`),通过程序控制关系,便于分库分表和微服务拆分
131
133
 
134
+ **重要:软删除机制**
135
+
136
+ 框架采用「默认 0」策略,而非 IS NULL:
137
+ - `deleted_at = 0`:未删除
138
+ - `deleted_at > 0`:已删除(Unix 时间戳)
139
+
140
+ 查询未删除记录时,使用 `WHERE deleted_at = 0`,不是 `WHERE deleted_at IS NULL`。
141
+
142
+ BaseRepository 已自动处理软删除过滤,无需手动添加条件。
143
+
132
144
  ```python
133
145
  # ✅ 正确
134
146
  from aury.boot.domain.models import AuditableStateModel
@@ -0,0 +1,178 @@
1
+ # 定时任务(Scheduler)
2
+
3
+ 基于 APScheduler,完全透传原生 API。
4
+
5
+ ## 基本用法
6
+
7
+ **文件**: `{package_name}/schedules/__init__.py`
8
+
9
+ ```python
10
+ """定时任务模块。"""
11
+
12
+ from apscheduler.triggers.cron import CronTrigger
13
+ from apscheduler.triggers.interval import IntervalTrigger
14
+
15
+ from aury.boot.common.logging import logger
16
+ from aury.boot.infrastructure.scheduler import SchedulerManager
17
+
18
+ scheduler = SchedulerManager.get_instance()
19
+
20
+
21
+ @scheduler.scheduled_job(IntervalTrigger(seconds=60))
22
+ async def every_minute():
23
+ """每 60 秒执行。"""
24
+ logger.info("定时任务执行中...")
25
+
26
+
27
+ @scheduler.scheduled_job(CronTrigger(hour=0, minute=0))
28
+ async def daily_task():
29
+ """每天凌晨执行。"""
30
+ logger.info("每日任务执行中...")
31
+
32
+
33
+ @scheduler.scheduled_job(CronTrigger(day_of_week="mon", hour=9))
34
+ async def weekly_report():
35
+ """每周一 9 点执行。"""
36
+ logger.info("周报任务执行中...")
37
+ ```
38
+
39
+ 启用方式:配置 `SCHEDULER__ENABLED=true`,框架自动加载 `{package_name}/schedules/` 模块。
40
+
41
+ ## 配置项
42
+
43
+ ```bash
44
+ # .env
45
+ SCHEDULER__ENABLED=true # 是否启用
46
+ SCHEDULER__TIMEZONE=Asia/Shanghai # 时区
47
+ SCHEDULER__COALESCE=true # 合并错过的任务
48
+ SCHEDULER__MAX_INSTANCES=1 # 同一任务最大并发数
49
+ SCHEDULER__MISFIRE_GRACE_TIME=60 # 错过容忍时间(秒)
50
+ SCHEDULER__JOBSTORE_URL=redis://localhost:6379/0 # 分布式存储(可选)
51
+ ```
52
+
53
+ ## 触发器类型
54
+
55
+ ### CronTrigger - 定时触发
56
+
57
+ ```python
58
+ from apscheduler.triggers.cron import CronTrigger
59
+
60
+ # 每天凌晨 2:30
61
+ CronTrigger(hour=2, minute=30)
62
+
63
+ # 每小时整点
64
+ CronTrigger(hour="*", minute=0)
65
+
66
+ # 工作日 9:00
67
+ CronTrigger(day_of_week="mon-fri", hour=9)
68
+
69
+ # 每月 1 号
70
+ CronTrigger(day=1, hour=0)
71
+
72
+ # 使用 crontab 表达式
73
+ CronTrigger.from_crontab("0 2 * * *") # 每天 2:00
74
+ ```
75
+
76
+ ### IntervalTrigger - 间隔触发
77
+
78
+ ```python
79
+ from apscheduler.triggers.interval import IntervalTrigger
80
+
81
+ IntervalTrigger(seconds=30) # 每 30 秒
82
+ IntervalTrigger(minutes=5) # 每 5 分钟
83
+ IntervalTrigger(hours=1) # 每小时
84
+ IntervalTrigger(days=1) # 每天
85
+ ```
86
+
87
+ ### DateTrigger - 一次性触发
88
+
89
+ ```python
90
+ from apscheduler.triggers.date import DateTrigger
91
+ from datetime import datetime, timedelta
92
+
93
+ # 10 秒后执行
94
+ DateTrigger(run_date=datetime.now() + timedelta(seconds=10))
95
+ ```
96
+
97
+ ## 多实例支持
98
+
99
+ 支持不同业务线使用独立的调度器实例:
100
+
101
+ ```python
102
+ # 默认实例
103
+ scheduler = SchedulerManager.get_instance()
104
+
105
+ # 命名实例
106
+ report_scheduler = SchedulerManager.get_instance("report")
107
+ cleanup_scheduler = SchedulerManager.get_instance("cleanup")
108
+ ```
109
+
110
+ ## 分布式调度
111
+
112
+ 多节点部署时,配置相同的 `SCHEDULER__JOBSTORE_URL`,所有节点共享任务状态:
113
+
114
+ ```bash
115
+ # 所有节点使用相同配置
116
+ SCHEDULER__JOBSTORE_URL=redis://redis:6379/0
117
+ ```
118
+
119
+ APScheduler 自动协调防止重复执行。
120
+
121
+ ### 代码方式配置(高级)
122
+
123
+ ```python
124
+ from apscheduler.jobstores.redis import RedisJobStore
125
+ from apscheduler.executors.asyncio import AsyncIOExecutor
126
+
127
+ scheduler = SchedulerManager.get_instance(
128
+ "distributed",
129
+ jobstores={{"default": RedisJobStore(host="localhost", port=6379)}},
130
+ executors={{"default": AsyncIOExecutor()}},
131
+ job_defaults={{"coalesce": True, "max_instances": 1}},
132
+ timezone="Asia/Shanghai",
133
+ )
134
+ ```
135
+
136
+ ## 任务管理
137
+
138
+ ```python
139
+ # 添加任务
140
+ scheduler.add_job(my_task, CronTrigger(hour=2), id="my_task")
141
+
142
+ # 获取任务
143
+ job = scheduler.get_job("my_task")
144
+ jobs = scheduler.get_jobs()
145
+
146
+ # 暂停/恢复
147
+ scheduler.pause_job("my_task")
148
+ scheduler.resume_job("my_task")
149
+
150
+ # 移除
151
+ scheduler.remove_job("my_task")
152
+
153
+ # 重新调度
154
+ scheduler.reschedule_job("my_task", CronTrigger(hour=3))
155
+ ```
156
+
157
+ ## 监听器(高级)
158
+
159
+ 通过底层 APScheduler 实例访问:
160
+
161
+ ```python
162
+ from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR
163
+
164
+ def job_listener(event):
165
+ if event.exception:
166
+ logger.error(f"任务失败: {event.job_id}")
167
+ else:
168
+ logger.info(f"任务完成: {event.job_id}")
169
+
170
+ scheduler.scheduler.add_listener(job_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
171
+ ```
172
+
173
+ ## 实践建议
174
+
175
+ 1. **使用明确的 ID**:便于管理和调试
176
+ 2. **合理设置间隔**:避免太频繁的任务
177
+ 3. **异常处理**:在任务函数内捕获异常,避免影响调度器
178
+ 4. **超时保护**:长运行任务使用 `asyncio.wait_for`
@@ -153,7 +153,7 @@ register_commands(app)
153
153
  @app.command()
154
154
  async def hello(name: str = "world") -> None:
155
155
  """示例:项目自定义命令。"""
156
- print(f"Hello, {name} from {project_name_snake}!")
156
+ print(f"Hello, {{name}} from {project_name_snake}!")
157
157
  ```
158
158
 
159
159
  > 注意:这里的 `app` 是 Typer 应用实例,`register_commands` 会把所有内置的 `init/generate/server/...` 等命令挂到你自己的 CLI 下。
@@ -6,13 +6,16 @@
6
6
  也可通过 SCHEDULER_SCHEDULE_MODULES 环境变量指定自定义模块。
7
7
  """
8
8
 
9
+ # from apscheduler.triggers.cron import CronTrigger
10
+ # from apscheduler.triggers.interval import IntervalTrigger
11
+ #
9
12
  # from aury.boot.common.logging import logger
10
13
  # from aury.boot.infrastructure.scheduler import SchedulerManager
11
14
  #
12
15
  # scheduler = SchedulerManager.get_instance()
13
16
  #
14
17
  #
15
- # @scheduler.scheduled_job("interval", seconds=60)
18
+ # @scheduler.scheduled_job(IntervalTrigger(seconds=60))
16
19
  # async def example_job():
17
20
  # """示例定时任务,每 60 秒执行一次。"""
18
21
  # logger.info("定时任务执行中...")
@@ -110,13 +110,15 @@ class CacheManager:
110
110
  supported = ", ".join(b.value for b in CacheBackend)
111
111
  raise ValueError(f"不支持的缓存后端: {backend}。支持: {supported}")
112
112
 
113
- # 保存配置
113
+ # 保存配置(用于启动横幅等场景展示)
114
114
  self._config = {"CACHE_TYPE": backend.value}
115
115
 
116
116
  # 根据后端类型构建配置并创建后端
117
117
  if backend == CacheBackend.REDIS:
118
118
  if not url:
119
119
  raise ValueError("Redis 缓存需要提供 url 参数")
120
+ # 记录 URL 以便在启动横幅中展示(会通过 mask_url 脱敏)
121
+ self._config["CACHE_URL"] = url
120
122
  self._backend = await CacheFactory.create(
121
123
  "redis", url=url, serializer=serializer
122
124
  )
@@ -128,6 +130,8 @@ class CacheManager:
128
130
  cache_url = url or (servers[0] if servers else None)
129
131
  if not cache_url:
130
132
  raise ValueError("Memcached 缓存需要提供 url 参数")
133
+ # 同样记录 URL,便于在启动横幅中展示
134
+ self._config["CACHE_URL"] = cache_url
131
135
  self._backend = await CacheFactory.create(
132
136
  "memcached", servers=cache_url
133
137
  )