fastapi-startkit 0.34.0__tar.gz → 0.40.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 (370) hide show
  1. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/PKG-INFO +5 -1
  2. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/pyproject.toml +7 -1
  3. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/__init__.py +31 -0
  4. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/agent.py +498 -0
  5. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/config.py +48 -0
  6. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/decorators.py +73 -0
  7. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/document.py +43 -0
  8. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/providers/__init__.py +3 -0
  9. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/providers/ai_provider.py +30 -0
  10. fastapi_startkit-0.40.0/src/fastapi_startkit/ai/response.py +92 -0
  11. fastapi_startkit-0.40.0/src/fastapi_startkit/facades/AI.py +5 -0
  12. fastapi_startkit-0.40.0/src/fastapi_startkit/facades/AI.pyi +19 -0
  13. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/collection/Collection.py +1 -1
  14. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/builder.py +16 -0
  15. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/model.py +16 -0
  16. fastapi_startkit-0.40.0/src/fastapi_startkit/process/__init__.py +4 -0
  17. fastapi_startkit-0.40.0/src/fastapi_startkit/process/exception.py +12 -0
  18. fastapi_startkit-0.40.0/src/fastapi_startkit/process/fake.py +31 -0
  19. fastapi_startkit-0.40.0/src/fastapi_startkit/process/process.py +680 -0
  20. fastapi_startkit-0.40.0/src/fastapi_startkit/process/result.py +61 -0
  21. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/storage.py +1 -1
  22. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/.DS_Store +0 -0
  23. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/__init__.py +0 -0
  24. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/application.py +0 -0
  25. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/__init__.py +0 -0
  26. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/channels.py +0 -0
  27. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/config.py +0 -0
  28. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/drivers/__init__.py +0 -0
  29. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/drivers/log_driver.py +0 -0
  30. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/drivers/reverb_driver.py +0 -0
  31. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/event.py +0 -0
  32. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/helpers.py +0 -0
  33. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/manager.py +0 -0
  34. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/provider.py +0 -0
  35. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/reverb/__init__.py +0 -0
  36. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/reverb/channel_manager.py +0 -0
  37. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/reverb/connection.py +0 -0
  38. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/broadcasting/reverb/server.py +0 -0
  39. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/carbon/__init__.py +0 -0
  40. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/carbon/carbon.py +0 -0
  41. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/config/__init__.py +0 -0
  42. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/config/app.py +0 -0
  43. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/configuration/Configuration.py +0 -0
  44. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/configuration/__init__.py +0 -0
  45. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/configuration/config.py +0 -0
  46. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/configuration/helpers.py +0 -0
  47. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/configuration/providers/ConfigurationProvider.py +0 -0
  48. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/configuration/providers/__init__.py +0 -0
  49. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/console/__init__.py +0 -0
  50. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/console/application.py +0 -0
  51. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/console/can_override_config.py +0 -0
  52. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/console/can_override_default_options.py +0 -0
  53. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/console/command.py +0 -0
  54. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/console/publish_command.py +0 -0
  55. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/container/__init__.py +0 -0
  56. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/container/container.py +0 -0
  57. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/environment/__init__.py +0 -0
  58. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/environment/environment.py +0 -0
  59. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/exceptions/__init__.py +0 -0
  60. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/exceptions/exceptions.py +0 -0
  61. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/exceptions/handler.py +0 -0
  62. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Broadcast.py +0 -0
  63. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Broadcast.pyi +0 -0
  64. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Cache.py +0 -0
  65. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Config.py +0 -0
  66. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Config.pyi +0 -0
  67. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Dump.py +0 -0
  68. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Dump.pyi +0 -0
  69. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Facade.py +0 -0
  70. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Gate.py +0 -0
  71. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Gate.pyi +0 -0
  72. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Hash.py +0 -0
  73. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Hash.pyi +0 -0
  74. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Loader.py +0 -0
  75. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Loader.pyi +0 -0
  76. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Mail.py +0 -0
  77. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Mail.pyi +0 -0
  78. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Notification.py +0 -0
  79. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Notification.pyi +0 -0
  80. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Queue.py +0 -0
  81. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Queue.pyi +0 -0
  82. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/RateLimiter.py +0 -0
  83. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/RateLimiter.pyi +0 -0
  84. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Request.py +0 -0
  85. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Request.pyi +0 -0
  86. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Response.py +0 -0
  87. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Response.pyi +0 -0
  88. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Session.py +0 -0
  89. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Session.pyi +0 -0
  90. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Url.py +0 -0
  91. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Url.pyi +0 -0
  92. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/View.py +0 -0
  93. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/View.pyi +0 -0
  94. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Vite.py +0 -0
  95. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/Vite.pyi +0 -0
  96. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/facades/__init__.py +0 -0
  97. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/__init__.py +0 -0
  98. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/commands/__init__.py +0 -0
  99. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/commands/serve_command.py +0 -0
  100. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/config/__init__.py +0 -0
  101. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/config/fastapi.py +0 -0
  102. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/exceptions.py +0 -0
  103. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +0 -0
  104. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/requests/model.py +0 -0
  105. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/routers/router.py +0 -0
  106. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/testing/__init__.py +0 -0
  107. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/fastapi/testing/test_case.py +0 -0
  108. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/helpers/app.py +0 -0
  109. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/helpers/dataclass.py +0 -0
  110. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/__init__.py +0 -0
  111. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/constant.py +0 -0
  112. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/context.py +0 -0
  113. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/inertia.py +0 -0
  114. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/middleware.py +0 -0
  115. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/props/props.py +0 -0
  116. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/inertia/provider.py +0 -0
  117. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/jsonapi/__init__.py +0 -0
  118. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/jsonapi/response.py +0 -0
  119. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/loader/Loader.py +0 -0
  120. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/loader/__init__.py +0 -0
  121. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/ChannelFactory.py +0 -0
  122. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/__init__.py +0 -0
  123. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/BaseChannel.py +0 -0
  124. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/DailyChannel.py +0 -0
  125. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/MultiBaseChannel.py +0 -0
  126. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/SingleChannel.py +0 -0
  127. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/SlackChannel.py +0 -0
  128. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/StackChannel.py +0 -0
  129. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/SyslogChannel.py +0 -0
  130. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/TerminalChannel.py +0 -0
  131. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/channels/__init__.py +0 -0
  132. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/config/__init__.py +0 -0
  133. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/config/channels.py +0 -0
  134. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/config/logging.py +0 -0
  135. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/drivers/BaseDriver.py +0 -0
  136. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/drivers/LogSingleDriver.py +0 -0
  137. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/drivers/LogSlackDriver.py +0 -0
  138. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/drivers/LogSyslogDriver.py +0 -0
  139. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/drivers/LogTerminalDriver.py +0 -0
  140. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/drivers/__init__.py +0 -0
  141. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/factory.py +0 -0
  142. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/file.py +0 -0
  143. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/handler.py +0 -0
  144. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/listeners.py +0 -0
  145. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/logger.py +0 -0
  146. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/managers/LoggingManager.py +0 -0
  147. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/managers/__init__.py +0 -0
  148. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/providers/__init__.py +0 -0
  149. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/logging/providers/log_provider.py +0 -0
  150. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/__init__.py +0 -0
  151. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/collection/__init__.py +0 -0
  152. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/DBMigrateCommand.py +0 -0
  153. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/DBSeedCommand.py +0 -0
  154. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MakeMigrationCommand.py +0 -0
  155. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelCommand.py +0 -0
  156. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelDocstringCommand.py +0 -0
  157. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MakeObserverCommand.py +0 -0
  158. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MakeSeedCommand.py +0 -0
  159. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MigrateFreshCommand.py +0 -0
  160. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRefreshCommand.py +0 -0
  161. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MigrateResetCommand.py +0 -0
  162. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRollbackCommand.py +0 -0
  163. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/MigrateStatusCommand.py +0 -0
  164. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/ShellCommand.py +0 -0
  165. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/__init__.py +0 -0
  166. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_migration.stub +0 -0
  167. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_seed.stub +0 -0
  168. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/stubs/model.stub +0 -0
  169. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/stubs/observer.stub +0 -0
  170. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/commands/stubs/table_migration.stub +0 -0
  171. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/config/__init__.py +0 -0
  172. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/config/config.py +0 -0
  173. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/config/database.py +0 -0
  174. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/connections/connection.py +0 -0
  175. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/connections/factory.py +0 -0
  176. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/connections/manager.py +0 -0
  177. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/connections/mysql_connection.py +0 -0
  178. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/connections/postgres_connection.py +0 -0
  179. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/connections/sqlite_connection.py +0 -0
  180. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/exceptions.py +0 -0
  181. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/expressions/__init__.py +0 -0
  182. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/expressions/expressions.py +0 -0
  183. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/facades/DB.py +0 -0
  184. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/facades/Schema.py +0 -0
  185. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/facades/__init__.py +0 -0
  186. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/factory/__init__.py +0 -0
  187. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/factory/factory.py +0 -0
  188. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/helpers/__init__.py +0 -0
  189. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/helpers/misc.py +0 -0
  190. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/migrations/Migration.py +0 -0
  191. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/migrations/Migrator.py +0 -0
  192. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/migrations/__init__.py +0 -0
  193. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/MigrationModel.py +0 -0
  194. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/__init__.py +0 -0
  195. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/attribute.py +0 -0
  196. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/caster.py +0 -0
  197. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/fields.py +0 -0
  198. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/observer.py +0 -0
  199. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/pivot.py +0 -0
  200. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/registry.py +0 -0
  201. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/models/relationship.py +0 -0
  202. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/observers/ObservesEvents.py +0 -0
  203. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/observers/__init__.py +0 -0
  204. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/pagination/BasePaginator.py +0 -0
  205. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/pagination/LengthAwarePaginator.py +0 -0
  206. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/pagination/SimplePaginator.py +0 -0
  207. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/pagination/__init__.py +0 -0
  208. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/providers/DatabaseProvider.py +0 -0
  209. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/providers/__init__.py +0 -0
  210. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/EagerLoadMixin.py +0 -0
  211. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/EagerRelation.py +0 -0
  212. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/__init__.py +0 -0
  213. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/grammars/BaseGrammar.py +0 -0
  214. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/grammars/MSSQLGrammar.py +0 -0
  215. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/grammars/MySQLGrammar.py +0 -0
  216. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/grammars/PostgresGrammar.py +0 -0
  217. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/grammars/SQLiteGrammar.py +0 -0
  218. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/grammars/__init__.py +0 -0
  219. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/processors/MSSQLPostProcessor.py +0 -0
  220. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/processors/MySQLPostProcessor.py +0 -0
  221. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/processors/PostgresPostProcessor.py +0 -0
  222. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/processors/SQLitePostProcessor.py +0 -0
  223. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/processors/__init__.py +0 -0
  224. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/query/support.py +0 -0
  225. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/BaseRelationship.py +0 -0
  226. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsTo.py +0 -0
  227. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsToMany.py +0 -0
  228. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/HasMany.py +0 -0
  229. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/HasManyThrough.py +0 -0
  230. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/HasOne.py +0 -0
  231. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/HasOneThrough.py +0 -0
  232. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/MorphMany.py +0 -0
  233. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/MorphOne.py +0 -0
  234. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/MorphTo.py +0 -0
  235. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/MorphToMany.py +0 -0
  236. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/relationships/__init__.py +0 -0
  237. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/Blueprint.py +0 -0
  238. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/Column.py +0 -0
  239. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/ColumnDiff.py +0 -0
  240. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/Constraint.py +0 -0
  241. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/ForeignKeyConstraint.py +0 -0
  242. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/Index.py +0 -0
  243. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/Table.py +0 -0
  244. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/TableDiff.py +0 -0
  245. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/__init__.py +0 -0
  246. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MSSQLPlatform.py +0 -0
  247. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MySQLPlatform.py +0 -0
  248. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/platforms/Platform.py +0 -0
  249. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/platforms/PostgresPlatform.py +0 -0
  250. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/platforms/SQLitePlatform.py +0 -0
  251. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/platforms/__init__.py +0 -0
  252. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/schema/schema.py +0 -0
  253. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/seeds/Seeder.py +0 -0
  254. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/seeds/__init__.py +0 -0
  255. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/stubs/create-migration.html +0 -0
  256. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/stubs/table-migration.html +0 -0
  257. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/testing/__init__.py +0 -0
  258. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm/testing/transaction.py +0 -0
  259. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/.gitignore +0 -0
  260. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/CACHEDIR.TAG +0 -0
  261. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/README.md +0 -0
  262. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/v/cache/lastfailed +0 -0
  263. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/.pytest_cache/v/cache/nodeids +0 -0
  264. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/__init__.py +0 -0
  265. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/config/database.py +0 -0
  266. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/config.py +0 -0
  267. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/exceptions.py +0 -0
  268. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/factories/Factory.py +0 -0
  269. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/factories/__init__.py +0 -0
  270. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/schema/Schema.py +0 -0
  271. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/BaseScope.py +0 -0
  272. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/SoftDeleteScope.py +0 -0
  273. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/SoftDeletesMixin.py +0 -0
  274. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/UUIDPrimaryKeyMixin.py +0 -0
  275. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/UUIDPrimaryKeyScope.py +0 -0
  276. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/__init__.py +0 -0
  277. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/scopes/scope.py +0 -0
  278. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/testing/BaseTestCaseSelectGrammar.py +0 -0
  279. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/testing/Database.py +0 -0
  280. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/testing/TestCase.py +0 -0
  281. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/testing/__init__.py +0 -0
  282. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/User.py +0 -0
  283. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/connections/test_base_connections.py +0 -0
  284. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/eagers/test_eager.py +0 -0
  285. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/models/test_models.py +0 -0
  286. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/builder/test_mssql_query_builder.py +0 -0
  287. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/builder/test_mssql_query_builder_relationships.py +0 -0
  288. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_delete_grammar.py +0 -0
  289. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_insert_grammar.py +0 -0
  290. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_qmark.py +0 -0
  291. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_select_grammar.py +0 -0
  292. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/grammar/test_mssql_update_grammar.py +0 -0
  293. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/schema/test_mssql_schema_builder.py +0 -0
  294. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mssql/schema/test_mssql_schema_builder_alter.py +0 -0
  295. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_mysql_builder_transaction.py +0 -0
  296. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_query_builder.py +0 -0
  297. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_query_builder_scopes.py +0 -0
  298. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/builder/test_transactions.py +0 -0
  299. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/connections/test_mysql_connection_selects.py +0 -0
  300. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_delete_grammar.py +0 -0
  301. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_insert_grammar.py +0 -0
  302. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_qmark.py +0 -0
  303. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_select_grammar.py +0 -0
  304. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/grammar/test_mysql_update_grammar.py +0 -0
  305. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/model/test_accessors_and_mutators.py +0 -0
  306. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/model/test_model.py +0 -0
  307. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_belongs_to_many.py +0 -0
  308. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_has_many_through.py +0 -0
  309. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_has_one_through.py +0 -0
  310. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/relationships/test_relationships.py +0 -0
  311. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/schema/test_mysql_schema_builder.py +0 -0
  312. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/schema/test_mysql_schema_builder_alter.py +0 -0
  313. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_can_use_global_scopes.py +0 -0
  314. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_can_use_scopes.py +0 -0
  315. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/mysql/scopes/test_soft_delete.py +0 -0
  316. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/builder/test_postgres_query_builder.py +0 -0
  317. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/builder/test_postgres_transaction.py +0 -0
  318. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_delete_grammar.py +0 -0
  319. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_insert_grammar.py +0 -0
  320. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_select_grammar.py +0 -0
  321. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/grammar/test_update_grammar.py +0 -0
  322. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/relationships/test_postgres_relationships.py +0 -0
  323. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/schema/test_postgres_schema_builder.py +0 -0
  324. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/postgres/schema/test_postgres_schema_builder_alter.py +0 -0
  325. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/scopes/test_default_global_scopes.py +0 -0
  326. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/seeds/test_seeds.py +0 -0
  327. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/masoniteorm.backup/tests/utils.py +0 -0
  328. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/__init__.py +0 -0
  329. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/argument.py +0 -0
  330. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/prompt.py +0 -0
  331. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/protocol.py +0 -0
  332. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/providers/__init__.py +0 -0
  333. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/providers/mcp_provider.py +0 -0
  334. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/request.py +0 -0
  335. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/resource.py +0 -0
  336. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/response.py +0 -0
  337. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/server.py +0 -0
  338. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/mcp/tool.py +0 -0
  339. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/providers/Provider.py +0 -0
  340. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/providers/__init__.py +0 -0
  341. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/providers/app_provider.py +0 -0
  342. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/__init__.py +0 -0
  343. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/config/__init__.py +0 -0
  344. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/config/storage.py +0 -0
  345. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/data/mime.types +0 -0
  346. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/drivers/__init__.py +0 -0
  347. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/drivers/fake.py +0 -0
  348. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/drivers/local.py +0 -0
  349. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/drivers/s3.py +0 -0
  350. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/file.py +0 -0
  351. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/filestream.py +0 -0
  352. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/helper.py +0 -0
  353. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/storage/providers/provider.py +0 -0
  354. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/support/__init__.py +0 -0
  355. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/support/collection.py +0 -0
  356. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/support/string.py +0 -0
  357. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/testing/__init__.py +0 -0
  358. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/testing/test_case.py +0 -0
  359. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/utils/structures.py +0 -0
  360. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/__init__.py +0 -0
  361. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/config/vite.py +0 -0
  362. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/exceptions.py +0 -0
  363. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/providers/provider.py +0 -0
  364. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/stubs/package.json +0 -0
  365. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/stubs/resources/css/app.css +0 -0
  366. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/stubs/resources/js/app.ts +0 -0
  367. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/stubs/templates/index.html +0 -0
  368. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/stubs/tsconfig.json +0 -0
  369. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/stubs/vite.config.ts +0 -0
  370. {fastapi_startkit-0.34.0 → fastapi_startkit-0.40.0}/src/fastapi_startkit/vite/vite.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fastapi-startkit
3
- Version: 0.34.0
3
+ Version: 0.40.0
4
4
  Summary: Fastapi Starter kit components
5
5
  Author: Bedram Tamang
6
6
  Author-email: Bedram Tamang <tmgbedu@gmail.com>
@@ -11,6 +11,9 @@ Requires-Dist: requests>=2.32.5,<3.0.0
11
11
  Requires-Dist: cleo>=2.1.0,<3.0.0
12
12
  Requires-Dist: dotenv>=0.9.9
13
13
  Requires-Dist: pydantic>=2.12.5
14
+ Requires-Dist: anthropic>=0.49.0 ; extra == 'ai'
15
+ Requires-Dist: openai>=1.0.0 ; extra == 'ai'
16
+ Requires-Dist: google-generativeai>=0.8.0 ; extra == 'ai'
14
17
  Requires-Dist: faker>=40.13.0 ; extra == 'database'
15
18
  Requires-Dist: sqlalchemy[asyncio]>=2.0.38 ; extra == 'database'
16
19
  Requires-Dist: fastapi[standard]>=0.124.4,<0.125.0 ; extra == 'fastapi'
@@ -22,6 +25,7 @@ Requires-Dist: asyncpg>=0.29.0 ; extra == 'postgres'
22
25
  Requires-Dist: aiosqlite>=0.22.1 ; extra == 'sqlite'
23
26
  Requires-Dist: jinja2>=3.1 ; extra == 'vite'
24
27
  Requires-Python: >=3.12, <4.0
28
+ Provides-Extra: ai
25
29
  Provides-Extra: database
26
30
  Provides-Extra: fastapi
27
31
  Provides-Extra: inertia
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fastapi-startkit"
3
- version = "0.34.0"
3
+ version = "0.40.0"
4
4
  description = "Fastapi Starter kit components"
5
5
  authors = [
6
6
  {name = "Bedram Tamang", email = "tmgbedu@gmail.com"}
@@ -47,6 +47,12 @@ inertia = [
47
47
  "markupsafe>=2.0",
48
48
  ]
49
49
 
50
+ ai = [
51
+ "anthropic>=0.49.0",
52
+ "openai>=1.0.0",
53
+ "google-generativeai>=0.8.0",
54
+ ]
55
+
50
56
  [dependency-groups]
51
57
  dev = [
52
58
  "dumpdie>=1.5.0",
@@ -0,0 +1,31 @@
1
+ """FastAPI Startkit AI module.
2
+
3
+ Provides a LangGraph-powered declarative API for building AI agents backed
4
+ by Anthropic, OpenAI, or Google provider SDKs.
5
+ """
6
+
7
+ from .agent import Agent
8
+ from .config import AIConfig, AnthropicConfig, GoogleConfig, OpenAIConfig
9
+ from .decorators import max_steps, max_tokens, memory, model, provider, timeout, top_p
10
+ from .document import Document
11
+ from .providers.ai_provider import AIProvider
12
+ from .response import AgentResponse, AgentSnapshot
13
+
14
+ __all__ = [
15
+ "Agent",
16
+ "AgentResponse",
17
+ "AgentSnapshot",
18
+ "AIConfig",
19
+ "AIProvider",
20
+ "AnthropicConfig",
21
+ "Document",
22
+ "GoogleConfig",
23
+ "OpenAIConfig",
24
+ "max_steps",
25
+ "max_tokens",
26
+ "memory",
27
+ "model",
28
+ "provider",
29
+ "timeout",
30
+ "top_p",
31
+ ]
@@ -0,0 +1,498 @@
1
+ """Agent base class — subclass this and apply decorators to build an AI agent."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import fnmatch
6
+ from typing import Any, Callable, Iterator, Optional, Type
7
+
8
+ from .document import Document
9
+ from .response import AgentResponse, AgentSnapshot
10
+
11
+
12
+ class Agent:
13
+ """
14
+ Base class for all agents. Subclass this and override lifecycle methods.
15
+
16
+ Class-level configuration (set via decorators or subclass attributes)::
17
+
18
+ _provider = "anthropic" # LLM provider
19
+ _model = "" # model ID (empty = provider default)
20
+ _max_steps = 10 # max agentic loop iterations
21
+ _max_tokens = 4096 # max output tokens
22
+ _timeout = 30.0 # request timeout in seconds
23
+ _top_p = 1.0 # top-p nucleus sampling
24
+ _memory_backend = "" # memory backend name (reserved)
25
+ """
26
+
27
+ _provider: str = "anthropic"
28
+ _model: str = ""
29
+ _max_steps: int = 10
30
+ _max_tokens: int = 4096
31
+ _timeout: float = 30.0
32
+ _top_p: float = 1.0
33
+ _memory_backend: str = ""
34
+
35
+ _DEFAULT_MODELS: dict[str, str] = {
36
+ "anthropic": "claude-sonnet-4-6",
37
+ "openai": "gpt-4o",
38
+ "google": "gemini-2.0-flash",
39
+ }
40
+
41
+ def __init__(self):
42
+ self._fakes: dict[str, AgentResponse | AgentSnapshot] = {}
43
+ self._call_log: list[dict] = []
44
+
45
+ # ── Lifecycle — override in subclasses ──────────────────────────────────
46
+
47
+ def messages(self) -> list[dict]:
48
+ """Return initial messages / few-shot examples."""
49
+ return []
50
+
51
+ def schema(self) -> Optional[Type]:
52
+ """Return a Pydantic model class for structured output, or None for plain text."""
53
+ return None
54
+
55
+ def tools(self) -> list[Callable]:
56
+ """Return a list of callable tools the agent may invoke."""
57
+ return []
58
+
59
+ def middleware(self) -> list[Callable]:
60
+ """Return middleware callables that wrap each LLM request."""
61
+ return []
62
+
63
+ def provider_options(self) -> dict:
64
+ """Return provider-specific options keyed by provider name."""
65
+ return {}
66
+
67
+ def before(self, message: str) -> str:
68
+ """Called before the message is sent. Return the (possibly modified) message."""
69
+ return message
70
+
71
+ def after(self, response: AgentResponse) -> AgentResponse:
72
+ """Called after the LLM responds. Return the (possibly modified) response."""
73
+ return response
74
+
75
+ # ── Public API ──────────────────────────────────────────────────────────
76
+
77
+ def prompt(
78
+ self,
79
+ message: str,
80
+ *,
81
+ system: str | None = None,
82
+ model: str | None = None,
83
+ messages: list[dict] | None = None,
84
+ attachments: list[Document] | None = None,
85
+ provider_options: dict | None = None,
86
+ ) -> AgentResponse:
87
+ """Send a prompt and return an AgentResponse."""
88
+ message = self.before(message)
89
+
90
+ _run_kwargs = dict(
91
+ system=system,
92
+ model=model,
93
+ extra_messages=messages,
94
+ attachments=attachments,
95
+ provider_options=provider_options,
96
+ )
97
+
98
+ match = self._match_fake(message)
99
+ if match is not None:
100
+ if isinstance(match, AgentSnapshot):
101
+ response = match.resolve(self, message, **_run_kwargs)
102
+ else:
103
+ response = match
104
+ self._log_call("prompt", message)
105
+ return self.after(response)
106
+
107
+ def _call(msg: str) -> AgentResponse:
108
+ return self._run(msg, **_run_kwargs)
109
+
110
+ response = self._apply_middleware(message, _call)
111
+ self._log_call("prompt", message)
112
+ return self.after(response)
113
+
114
+ def stream(
115
+ self,
116
+ message: str,
117
+ *,
118
+ system: str | None = None,
119
+ model: str | None = None,
120
+ provider_options: dict | None = None,
121
+ ) -> Iterator[str]:
122
+ """Stream a response token by token."""
123
+ message = self.before(message)
124
+ self._log_call("stream", message)
125
+ fake = self._match_fake(message)
126
+ if fake is not None:
127
+ if isinstance(fake, AgentSnapshot):
128
+ response = fake.resolve(self, message)
129
+ else:
130
+ response = fake
131
+ yield response.content
132
+ return
133
+ yield from self._stream(message, system=system, model=model, provider_options=provider_options)
134
+
135
+ def fake(self, patterns: dict[str, AgentResponse | AgentSnapshot]) -> "Agent":
136
+ """Register fake responses for testing. Keys are glob patterns."""
137
+ for pattern, value in patterns.items():
138
+ self._fakes[pattern] = value
139
+ return self
140
+
141
+ def assert_prompted(self, times: int | None = None) -> None:
142
+ """Assert that prompt() or stream() was called."""
143
+ calls = [c for c in self._call_log if c["method"] in ("prompt", "stream")]
144
+ if times is not None:
145
+ assert len(calls) == times, f"Expected {times} prompt call(s), got {len(calls)}"
146
+ else:
147
+ assert len(calls) > 0, "Expected at least one prompt() or stream() call, but none were made"
148
+
149
+ def assert_not_prompted(self) -> None:
150
+ """Assert that prompt() and stream() were never called."""
151
+ self.assert_prompted(times=0)
152
+
153
+ def reset(self) -> "Agent":
154
+ """Clear fakes and call log. Useful between test cases."""
155
+ self._fakes.clear()
156
+ self._call_log.clear()
157
+ return self
158
+
159
+ # ── Internal helpers ────────────────────────────────────────────────────
160
+
161
+ def _match_fake(self, message: str) -> Optional[AgentResponse | AgentSnapshot]:
162
+ for pattern, value in self._fakes.items():
163
+ if fnmatch.fnmatch(message.lower(), pattern.lower()):
164
+ return value
165
+ return None
166
+
167
+ def _log_call(self, method: str, message: str) -> None:
168
+ self._call_log.append({"method": method, "message": message})
169
+
170
+ def _apply_middleware(self, message: str, final: Callable[[str], AgentResponse]) -> AgentResponse:
171
+ """Build a left-to-right middleware chain and invoke it."""
172
+ chain = list(self.middleware())
173
+
174
+ def build(mw_list: list, fn: Callable) -> Callable:
175
+ if not mw_list:
176
+ return fn
177
+ head, *tail = mw_list
178
+ next_fn = build(tail, fn)
179
+ return lambda msg: head(msg, next_fn)
180
+
181
+ return build(chain, final)(message)
182
+
183
+ def _execute_tool(self, name: str, inputs: dict) -> Any:
184
+ """Find a tool by function name and call it with the given inputs."""
185
+ for tool in self.tools():
186
+ if callable(tool) and tool.__name__ == name:
187
+ return tool(**inputs)
188
+ raise ValueError(f"Tool {name!r} not found")
189
+
190
+ def _resolve_model(self, override: str | None = None) -> str:
191
+ if override:
192
+ return override
193
+ if self._model:
194
+ return self._model
195
+ return self._DEFAULT_MODELS.get(self._provider, "")
196
+
197
+ def _get_provider_options(self, override: dict | None = None) -> dict:
198
+ options = dict(self.provider_options().get(self._provider, {}))
199
+ if override:
200
+ provider_specific = override.get(self._provider, override)
201
+ if isinstance(provider_specific, dict):
202
+ options.update(provider_specific)
203
+ return options
204
+
205
+ def _build_messages(
206
+ self,
207
+ message: str,
208
+ system: str | None = None,
209
+ extra_messages: list[dict] | None = None,
210
+ attachments: list[Document] | None = None,
211
+ ) -> tuple[str | None, list[dict]]:
212
+ base = self.messages()
213
+
214
+ resolved_system = system
215
+ if resolved_system is None:
216
+ sys_entries = [m for m in base if m.get("role") == "system"]
217
+ if sys_entries:
218
+ resolved_system = sys_entries[0]["content"]
219
+
220
+ history = [m for m in base if m.get("role") != "system"]
221
+ if extra_messages:
222
+ history.extend(extra_messages)
223
+
224
+ if attachments:
225
+ content: Any = [{"type": "text", "text": message}]
226
+ for doc in attachments:
227
+ if self._provider == "anthropic":
228
+ content.append(doc.to_anthropic_block())
229
+ else:
230
+ content.append(doc.to_openai_block())
231
+ history.append({"role": "user", "content": content})
232
+ else:
233
+ history.append({"role": "user", "content": message})
234
+
235
+ return resolved_system, history
236
+
237
+ def _run(
238
+ self,
239
+ message: str,
240
+ system: str | None = None,
241
+ model: str | None = None,
242
+ extra_messages: list[dict] | None = None,
243
+ attachments: list[Document] | None = None,
244
+ provider_options: dict | None = None,
245
+ ) -> AgentResponse:
246
+ resolved_system, messages = self._build_messages(message, system, extra_messages, attachments)
247
+ resolved_model = self._resolve_model(model)
248
+ options = self._get_provider_options(provider_options)
249
+
250
+ if self._provider == "anthropic":
251
+ return self._run_anthropic(resolved_system, messages, resolved_model, options)
252
+ if self._provider == "openai":
253
+ return self._run_openai(resolved_system, messages, resolved_model, options)
254
+ if self._provider == "google":
255
+ return self._run_google(resolved_system, messages, resolved_model, options)
256
+ raise ValueError(f"Unsupported provider: {self._provider!r}. Use 'anthropic', 'openai', or 'google'.")
257
+
258
+ def _stream(
259
+ self,
260
+ message: str,
261
+ system: str | None = None,
262
+ model: str | None = None,
263
+ provider_options: dict | None = None,
264
+ ) -> Iterator[str]:
265
+ resolved_system, messages = self._build_messages(message, system)
266
+ resolved_model = self._resolve_model(model)
267
+ options = self._get_provider_options(provider_options)
268
+
269
+ if self._provider == "anthropic":
270
+ yield from self._stream_anthropic(resolved_system, messages, resolved_model, options)
271
+ elif self._provider == "openai":
272
+ yield from self._stream_openai(resolved_system, messages, resolved_model, options)
273
+ elif self._provider == "google":
274
+ yield from self._stream_google(resolved_system, messages, resolved_model, options)
275
+ else:
276
+ raise ValueError(f"Unsupported provider: {self._provider!r}. Use 'anthropic', 'openai', or 'google'.")
277
+
278
+ # ── Anthropic ──────────────────────────────────────────────────────────
279
+
280
+ def _run_anthropic(
281
+ self,
282
+ system: str | None,
283
+ messages: list[dict],
284
+ model: str,
285
+ options: dict,
286
+ ) -> AgentResponse:
287
+ from anthropic import Anthropic # noqa: PLC0415
288
+
289
+ api_key = self._resolve_api_key("anthropic")
290
+ client = Anthropic(api_key=api_key)
291
+ params: dict[str, Any] = {
292
+ "model": model,
293
+ "max_tokens": self._max_tokens,
294
+ "messages": messages,
295
+ **options,
296
+ }
297
+ if system:
298
+ params["system"] = system
299
+
300
+ resp = client.messages.create(**params)
301
+ content = "".join(b.text for b in resp.content if hasattr(b, "text"))
302
+ return AgentResponse(
303
+ content=content,
304
+ usage={"input": resp.usage.input_tokens, "output": resp.usage.output_tokens},
305
+ raw=resp,
306
+ )
307
+
308
+ def _stream_anthropic(
309
+ self,
310
+ system: str | None,
311
+ messages: list[dict],
312
+ model: str,
313
+ options: dict,
314
+ ) -> Iterator[str]:
315
+ from anthropic import Anthropic # noqa: PLC0415
316
+
317
+ api_key = self._resolve_api_key("anthropic")
318
+ client = Anthropic(api_key=api_key)
319
+ params: dict[str, Any] = {
320
+ "model": model,
321
+ "max_tokens": self._max_tokens,
322
+ "messages": messages,
323
+ **options,
324
+ }
325
+ if system:
326
+ params["system"] = system
327
+
328
+ with client.messages.stream(**params) as stream:
329
+ for text in stream.text_stream:
330
+ yield text
331
+
332
+ # ── OpenAI ─────────────────────────────────────────────────────────────
333
+
334
+ def _run_openai(
335
+ self,
336
+ system: str | None,
337
+ messages: list[dict],
338
+ model: str,
339
+ options: dict,
340
+ ) -> AgentResponse:
341
+ from openai import OpenAI # noqa: PLC0415
342
+
343
+ api_key = self._resolve_api_key("openai")
344
+ client = OpenAI(api_key=api_key)
345
+ all_messages: list[dict] = []
346
+ if system:
347
+ all_messages.append({"role": "system", "content": system})
348
+ all_messages.extend(messages)
349
+
350
+ params: dict[str, Any] = {
351
+ "model": model,
352
+ "max_tokens": self._max_tokens,
353
+ "messages": all_messages,
354
+ **options,
355
+ }
356
+ resp = client.chat.completions.create(**params)
357
+ content = resp.choices[0].message.content or ""
358
+ return AgentResponse(
359
+ content=content,
360
+ usage={
361
+ "input": resp.usage.prompt_tokens if resp.usage else 0,
362
+ "output": resp.usage.completion_tokens if resp.usage else 0,
363
+ },
364
+ raw=resp,
365
+ )
366
+
367
+ def _stream_openai(
368
+ self,
369
+ system: str | None,
370
+ messages: list[dict],
371
+ model: str,
372
+ options: dict,
373
+ ) -> Iterator[str]:
374
+ from openai import OpenAI # noqa: PLC0415
375
+
376
+ api_key = self._resolve_api_key("openai")
377
+ client = OpenAI(api_key=api_key)
378
+ all_messages: list[dict] = []
379
+ if system:
380
+ all_messages.append({"role": "system", "content": system})
381
+ all_messages.extend(messages)
382
+
383
+ params: dict[str, Any] = {
384
+ "model": model,
385
+ "max_tokens": self._max_tokens,
386
+ "messages": all_messages,
387
+ "stream": True,
388
+ **options,
389
+ }
390
+ for chunk in client.chat.completions.create(**params):
391
+ delta = chunk.choices[0].delta.content
392
+ if delta:
393
+ yield delta
394
+
395
+ def _resolve_api_key(self, provider_name: str) -> str | None:
396
+ """Try Config.get("ai") first, fallback to None (SDK reads env var)."""
397
+ try:
398
+ from fastapi_startkit.facades.Config import Config # noqa: PLC0415
399
+
400
+ ai_config = Config.get("ai")
401
+ return ai_config.providers[provider_name].key or None
402
+ except Exception:
403
+ return None
404
+
405
+ # ── Google ─────────────────────────────────────────────────────────────
406
+
407
+ def _run_google(
408
+ self,
409
+ system: str | None,
410
+ messages: list[dict],
411
+ model: str,
412
+ options: dict,
413
+ ) -> AgentResponse:
414
+ import google.generativeai as genai # noqa: PLC0415
415
+
416
+ api_key = self._resolve_api_key("google")
417
+ if api_key:
418
+ genai.configure(api_key=api_key)
419
+
420
+ generation_config: dict[str, Any] = {}
421
+ if self._max_tokens:
422
+ generation_config["max_output_tokens"] = self._max_tokens
423
+ if self._top_p != 1.0:
424
+ generation_config["top_p"] = self._top_p
425
+ generation_config.update(options)
426
+
427
+ google_model = genai.GenerativeModel(
428
+ model_name=model,
429
+ system_instruction=system,
430
+ generation_config=generation_config if generation_config else None,
431
+ )
432
+
433
+ google_messages = _to_google_messages(messages)
434
+ response = google_model.generate_content(google_messages)
435
+ content = response.text if hasattr(response, "text") else ""
436
+ usage: dict[str, Any] = {}
437
+ if hasattr(response, "usage_metadata"):
438
+ meta = response.usage_metadata
439
+ usage = {
440
+ "input": getattr(meta, "prompt_token_count", 0),
441
+ "output": getattr(meta, "candidates_token_count", 0),
442
+ }
443
+ return AgentResponse(content=content, usage=usage, raw=response)
444
+
445
+ def _stream_google(
446
+ self,
447
+ system: str | None,
448
+ messages: list[dict],
449
+ model: str,
450
+ options: dict,
451
+ ) -> Iterator[str]:
452
+ import google.generativeai as genai # noqa: PLC0415
453
+
454
+ api_key = self._resolve_api_key("google")
455
+ if api_key:
456
+ genai.configure(api_key=api_key)
457
+
458
+ generation_config: dict[str, Any] = {}
459
+ if self._max_tokens:
460
+ generation_config["max_output_tokens"] = self._max_tokens
461
+ if self._top_p != 1.0:
462
+ generation_config["top_p"] = self._top_p
463
+ generation_config.update(options)
464
+
465
+ google_model = genai.GenerativeModel(
466
+ model_name=model,
467
+ system_instruction=system,
468
+ generation_config=generation_config if generation_config else None,
469
+ )
470
+
471
+ google_messages = _to_google_messages(messages)
472
+ for chunk in google_model.generate_content(google_messages, stream=True):
473
+ if chunk.text:
474
+ yield chunk.text
475
+
476
+
477
+ # ─── Utilities ─────────────────────────────────────────────────────────────────
478
+
479
+
480
+ def _to_google_messages(messages: list[dict]) -> list[dict]:
481
+ """
482
+ Convert OpenAI-style messages to Google GenerativeAI content format.
483
+ Maps 'assistant' role → 'model'; omits 'system' (handled via system_instruction).
484
+ """
485
+ result = []
486
+ for msg in messages:
487
+ role = msg.get("role", "user")
488
+ content = msg.get("content", "")
489
+ if role == "system":
490
+ continue # system_instruction is set at model-construction level
491
+ google_role = "model" if role == "assistant" else "user"
492
+ if isinstance(content, list):
493
+ # Multi-part content — extract text parts only
494
+ text = " ".join(p.get("text", "") for p in content if isinstance(p, dict) and "text" in p)
495
+ result.append({"role": google_role, "parts": [{"text": text}]})
496
+ else:
497
+ result.append({"role": google_role, "parts": [{"text": str(content)}]})
498
+ return result
@@ -0,0 +1,48 @@
1
+ """AI configuration dataclasses for the FastAPI Startkit AI module."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+ from fastapi_startkit.environment import env
8
+
9
+
10
+ @dataclass
11
+ class AnthropicConfig:
12
+ """Configuration for the Anthropic provider."""
13
+
14
+ driver: str = "anthropic"
15
+ key: str = field(default_factory=lambda: env("ANTHROPIC_API_KEY", ""))
16
+ url: str = field(default_factory=lambda: env("ANTHROPIC_BASE_URL", "https://api.anthropic.com"))
17
+
18
+
19
+ @dataclass
20
+ class OpenAIConfig:
21
+ """Configuration for the OpenAI provider."""
22
+
23
+ driver: str = "openai"
24
+ key: str = field(default_factory=lambda: env("OPENAI_API_KEY", ""))
25
+ url: str = field(default_factory=lambda: env("OPENAI_BASE_URL", "https://api.openai.com/v1"))
26
+
27
+
28
+ @dataclass
29
+ class GoogleConfig:
30
+ """Configuration for the Google / Gemini provider."""
31
+
32
+ driver: str = "google"
33
+ key: str = field(default_factory=lambda: env("GEMINI_API_KEY", "") or env("GOOGLE_API_KEY", ""))
34
+
35
+
36
+ @dataclass
37
+ class AIConfig:
38
+ """Top-level AI configuration — selects the default provider and holds per-provider configs."""
39
+
40
+ default: str = field(default_factory=lambda: env("AI_PROVIDER", "google"))
41
+
42
+ providers: dict = field(
43
+ default_factory=lambda: {
44
+ "openai": OpenAIConfig(),
45
+ "anthropic": AnthropicConfig(),
46
+ "google": GoogleConfig(),
47
+ }
48
+ )
@@ -0,0 +1,73 @@
1
+ """Declarative class decorators for Agent configuration."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ def provider(name: str):
7
+ """Set the LLM provider: 'anthropic', 'openai', 'google', etc."""
8
+
9
+ def decorator(cls):
10
+ cls._provider = name
11
+ return cls
12
+
13
+ return decorator
14
+
15
+
16
+ def model(name: str = ""):
17
+ """Set the model identifier (e.g. 'claude-sonnet-4-6', 'gpt-4o')."""
18
+
19
+ def decorator(cls):
20
+ cls._model = name
21
+ return cls
22
+
23
+ return decorator
24
+
25
+
26
+ def max_steps(n: int = 10):
27
+ """Maximum agentic loop iterations before stopping."""
28
+
29
+ def decorator(cls):
30
+ cls._max_steps = n
31
+ return cls
32
+
33
+ return decorator
34
+
35
+
36
+ def max_tokens(n: int = 4096):
37
+ """Maximum output tokens per response."""
38
+
39
+ def decorator(cls):
40
+ cls._max_tokens = n
41
+ return cls
42
+
43
+ return decorator
44
+
45
+
46
+ def timeout(seconds: float = 30.0):
47
+ """Request timeout in seconds."""
48
+
49
+ def decorator(cls):
50
+ cls._timeout = seconds
51
+ return cls
52
+
53
+ return decorator
54
+
55
+
56
+ def top_p(value: float = 1.0):
57
+ """Top-p nucleus sampling parameter."""
58
+
59
+ def decorator(cls):
60
+ cls._top_p = value
61
+ return cls
62
+
63
+ return decorator
64
+
65
+
66
+ def memory(backend: str = ""):
67
+ """Attach a named memory backend to this agent."""
68
+
69
+ def decorator(cls):
70
+ cls._memory_backend = backend
71
+ return cls
72
+
73
+ return decorator