fastapi-startkit 0.56.0__tar.gz → 0.58.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 (348) hide show
  1. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/PKG-INFO +1 -1
  2. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/pyproject.toml +8 -2
  3. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/audio_factory.py +7 -4
  4. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/config/config.py +6 -4
  5. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/image_factory.py +7 -4
  6. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/pipeline.py +1 -1
  7. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/testing.py +33 -18
  8. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/application.py +13 -11
  9. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/provider.py +3 -0
  10. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/configuration/Configuration.py +5 -1
  11. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/console/can_override_default_options.py +2 -1
  12. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/console/publish_command.py +7 -5
  13. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/container/container.py +19 -6
  14. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/environment/environment.py +14 -6
  15. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/events/dispatcher.py +6 -2
  16. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Dump.pyi +12 -7
  17. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Gate.pyi +18 -3
  18. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Hash.pyi +14 -7
  19. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Loader.pyi +17 -11
  20. fastapi_startkit-0.58.0/src/fastapi_startkit/facades/Mail.pyi +19 -0
  21. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Notification.pyi +8 -3
  22. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Queue.pyi +7 -0
  23. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/RateLimiter.pyi +23 -13
  24. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Request.pyi +30 -7
  25. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Response.pyi +31 -13
  26. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Session.pyi +25 -7
  27. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Url.pyi +6 -1
  28. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/View.pyi +22 -5
  29. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/commands/serve_command.py +8 -3
  30. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/exceptions.py +7 -1
  31. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/routers/router.py +2 -7
  32. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/testing/assertable_json.py +2 -2
  33. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/jsonapi/response.py +7 -5
  34. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/loader/Loader.py +7 -3
  35. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/BaseChannel.py +31 -1
  36. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/DailyChannel.py +1 -2
  37. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/MultiBaseChannel.py +4 -0
  38. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/SingleChannel.py +1 -2
  39. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/SlackChannel.py +1 -4
  40. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/StackChannel.py +3 -2
  41. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/SyslogChannel.py +1 -2
  42. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/TerminalChannel.py +1 -2
  43. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/config/channels.py +1 -1
  44. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/drivers/LogSingleDriver.py +3 -3
  45. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/drivers/LogSlackDriver.py +4 -0
  46. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/drivers/LogSyslogDriver.py +2 -3
  47. fastapi_startkit-0.58.0/src/fastapi_startkit/logging/managers/LoggingManager.py +25 -0
  48. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/collection/Collection.py +3 -2
  49. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/DBMigrateCommand.py +4 -3
  50. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/DBSeedCommand.py +3 -2
  51. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MakeMigrationCommand.py +2 -1
  52. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelCommand.py +4 -2
  53. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MakeObserverCommand.py +3 -2
  54. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MakeSeedCommand.py +4 -2
  55. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MigrateFreshCommand.py +4 -3
  56. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRefreshCommand.py +4 -3
  57. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MigrateResetCommand.py +4 -3
  58. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRollbackCommand.py +4 -3
  59. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/MigrateStatusCommand.py +4 -3
  60. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/ShellCommand.py +32 -14
  61. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/config/config.py +6 -6
  62. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/config/database.py +4 -4
  63. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/connections/connection.py +14 -5
  64. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/connections/factory.py +5 -2
  65. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/connections/mysql_connection.py +2 -2
  66. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/connections/postgres_connection.py +2 -2
  67. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/connections/sqlite_connection.py +2 -2
  68. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/expressions/expressions.py +10 -6
  69. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/facades/Schema.py +1 -1
  70. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/factory/factory.py +3 -1
  71. fastapi_startkit-0.58.0/src/fastapi_startkit/masoniteorm/models/__init__.py +6 -0
  72. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/attribute.py +9 -8
  73. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/builder.py +63 -12
  74. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/caster.py +37 -13
  75. fastapi_startkit-0.58.0/src/fastapi_startkit/masoniteorm/models/fields.py +160 -0
  76. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/model.py +56 -14
  77. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/registry.py +6 -0
  78. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/observers/ObservesEvents.py +6 -0
  79. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/pagination/BasePaginator.py +5 -0
  80. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/grammars/BaseGrammar.py +84 -13
  81. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/grammars/MSSQLGrammar.py +1 -1
  82. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/grammars/MySQLGrammar.py +1 -1
  83. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/grammars/PostgresGrammar.py +4 -1
  84. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/grammars/SQLiteGrammar.py +4 -1
  85. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsTo.py +3 -1
  86. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsToMany.py +15 -12
  87. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/HasManyThrough.py +15 -51
  88. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/HasOneThrough.py +16 -52
  89. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/MorphMany.py +5 -5
  90. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/MorphOne.py +22 -11
  91. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/MorphTo.py +6 -6
  92. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/MorphToMany.py +20 -9
  93. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/Blueprint.py +66 -52
  94. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/Column.py +0 -14
  95. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/TableDiff.py +5 -1
  96. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MSSQLPlatform.py +2 -2
  97. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MySQLPlatform.py +5 -5
  98. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/platforms/Platform.py +39 -3
  99. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/platforms/PostgresPlatform.py +3 -3
  100. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/platforms/SQLitePlatform.py +41 -11
  101. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/seeders/Seeder.py +6 -2
  102. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/testing/transaction.py +8 -2
  103. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/process/process.py +3 -2
  104. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/drivers/local.py +2 -0
  105. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/drivers/s3.py +4 -4
  106. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/file.py +8 -3
  107. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/storage.py +5 -6
  108. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/collection.py +7 -7
  109. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/providers/provider.py +8 -6
  110. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/structures.py +3 -1
  111. fastapi_startkit-0.58.0/src/fastapi_startkit/testing/test_case.py +36 -0
  112. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/vite.py +2 -2
  113. fastapi_startkit-0.56.0/src/fastapi_startkit/facades/Mail.pyi +0 -14
  114. fastapi_startkit-0.56.0/src/fastapi_startkit/logging/managers/LoggingManager.py +0 -14
  115. fastapi_startkit-0.56.0/src/fastapi_startkit/masoniteorm/commands/MakeModelDocstringCommand.py +0 -53
  116. fastapi_startkit-0.56.0/src/fastapi_startkit/masoniteorm/models/__init__.py +0 -3
  117. fastapi_startkit-0.56.0/src/fastapi_startkit/masoniteorm/models/fields.py +0 -108
  118. fastapi_startkit-0.56.0/src/fastapi_startkit/testing/test_case.py +0 -32
  119. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/README.md +0 -0
  120. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/.DS_Store +0 -0
  121. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/__init__.py +0 -0
  122. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/__init__.py +0 -0
  123. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/agent.py +0 -0
  124. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/ai.py +0 -0
  125. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/audio.py +0 -0
  126. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/config/ai.py +0 -0
  127. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/decorators.py +0 -0
  128. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/document.py +0 -0
  129. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/image.py +0 -0
  130. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/judge.py +0 -0
  131. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/lab.py +0 -0
  132. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/providers/__init__.py +0 -0
  133. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/providers/ai_provider.py +0 -0
  134. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/recording.py +0 -0
  135. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/runner.py +0 -0
  136. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/state.py +0 -0
  137. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/tinker.py +0 -0
  138. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/ai/types.py +0 -0
  139. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/__init__.py +0 -0
  140. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/auth.py +0 -0
  141. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/channels.py +0 -0
  142. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/config.py +0 -0
  143. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/drivers/__init__.py +0 -0
  144. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/drivers/log_driver.py +0 -0
  145. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/drivers/reverb_driver.py +0 -0
  146. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/event.py +0 -0
  147. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/helpers.py +0 -0
  148. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/manager.py +0 -0
  149. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/reverb/__init__.py +0 -0
  150. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/reverb/channel_manager.py +0 -0
  151. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/reverb/connection.py +0 -0
  152. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/reverb/server.py +0 -0
  153. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/stubs/__init__.py +0 -0
  154. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/broadcasting/stubs/channels.py +0 -0
  155. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/carbon/__init__.py +0 -0
  156. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/carbon/carbon.py +0 -0
  157. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/config/__init__.py +0 -0
  158. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/config/app.py +0 -0
  159. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/configuration/__init__.py +0 -0
  160. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/configuration/config.py +0 -0
  161. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/configuration/helpers.py +0 -0
  162. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/configuration/providers/ConfigurationProvider.py +0 -0
  163. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/configuration/providers/__init__.py +0 -0
  164. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/console/__init__.py +0 -0
  165. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/console/application.py +0 -0
  166. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/console/can_override_config.py +0 -0
  167. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/console/command.py +0 -0
  168. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/container/__init__.py +0 -0
  169. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/environment/__init__.py +0 -0
  170. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/events/__init__.py +0 -0
  171. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/events/fake.py +0 -0
  172. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/events/helpers.py +0 -0
  173. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/events/listener.py +0 -0
  174. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/events/provider.py +0 -0
  175. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/exceptions/__init__.py +0 -0
  176. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/exceptions/exceptions.py +0 -0
  177. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/exceptions/handler.py +0 -0
  178. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/AI.py +0 -0
  179. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/AI.pyi +0 -0
  180. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Cache.py +0 -0
  181. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Config.py +0 -0
  182. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Config.pyi +0 -0
  183. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Dump.py +0 -0
  184. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Event.py +0 -0
  185. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Event.pyi +0 -0
  186. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Facade.py +0 -0
  187. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Gate.py +0 -0
  188. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Hash.py +0 -0
  189. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Loader.py +0 -0
  190. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Mail.py +0 -0
  191. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Notification.py +0 -0
  192. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Queue.py +0 -0
  193. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/RateLimiter.py +0 -0
  194. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Request.py +0 -0
  195. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Response.py +0 -0
  196. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Session.py +0 -0
  197. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Url.py +0 -0
  198. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/View.py +0 -0
  199. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Vite.py +0 -0
  200. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/Vite.pyi +0 -0
  201. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/facades/__init__.py +0 -0
  202. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/__init__.py +0 -0
  203. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/commands/__init__.py +0 -0
  204. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/config/__init__.py +0 -0
  205. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/config/fastapi.py +0 -0
  206. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/events.py +0 -0
  207. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/middleware.py +0 -0
  208. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +0 -0
  209. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/requests/model.py +0 -0
  210. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/testing/__init__.py +0 -0
  211. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/testing/test_case.py +0 -0
  212. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/fastapi/testing/test_response.py +0 -0
  213. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/foundation/app_provider.py +0 -0
  214. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/__init__.py +0 -0
  215. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/constant.py +0 -0
  216. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/context.py +0 -0
  217. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/inertia.py +0 -0
  218. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/middleware.py +0 -0
  219. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/props/props.py +0 -0
  220. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/inertia/provider.py +0 -0
  221. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/jsonapi/__init__.py +0 -0
  222. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/loader/__init__.py +0 -0
  223. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/ChannelFactory.py +0 -0
  224. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/__init__.py +0 -0
  225. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/channels/__init__.py +0 -0
  226. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/config/__init__.py +0 -0
  227. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/config/logging.py +0 -0
  228. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/drivers/BaseDriver.py +0 -0
  229. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/drivers/LogTerminalDriver.py +0 -0
  230. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/drivers/__init__.py +0 -0
  231. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/factory.py +0 -0
  232. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/file.py +0 -0
  233. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/handler.py +0 -0
  234. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/listeners.py +0 -0
  235. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/logger.py +0 -0
  236. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/managers/__init__.py +0 -0
  237. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/providers/__init__.py +0 -0
  238. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/logging/providers/log_provider.py +0 -0
  239. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/__init__.py +0 -0
  240. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/collection/__init__.py +0 -0
  241. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/__init__.py +0 -0
  242. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_migration.stub +0 -0
  243. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_seed.stub +0 -0
  244. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/stubs/model.stub +0 -0
  245. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/stubs/observer.stub +0 -0
  246. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/commands/stubs/table_migration.stub +0 -0
  247. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/config/__init__.py +0 -0
  248. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/connections/manager.py +0 -0
  249. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/exceptions.py +0 -0
  250. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/expressions/__init__.py +0 -0
  251. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/facades/DB.py +0 -0
  252. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/facades/__init__.py +0 -0
  253. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/factory/__init__.py +0 -0
  254. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/helpers/__init__.py +0 -0
  255. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/helpers/misc.py +0 -0
  256. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/migrations/Migration.py +0 -0
  257. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/migrations/Migrator.py +0 -0
  258. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/migrations/__init__.py +0 -0
  259. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/MigrationModel.py +0 -0
  260. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/observer.py +0 -0
  261. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/pivot.py +0 -0
  262. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/models/relationship.py +0 -0
  263. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/observers/__init__.py +0 -0
  264. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/pagination/LengthAwarePaginator.py +0 -0
  265. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/pagination/SimplePaginator.py +0 -0
  266. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/pagination/__init__.py +0 -0
  267. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/providers/DatabaseProvider.py +0 -0
  268. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/providers/__init__.py +0 -0
  269. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/EagerLoadMixin.py +0 -0
  270. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/EagerRelation.py +0 -0
  271. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/__init__.py +0 -0
  272. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/grammars/__init__.py +0 -0
  273. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/processors/MSSQLPostProcessor.py +0 -0
  274. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/processors/MySQLPostProcessor.py +0 -0
  275. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/processors/PostgresPostProcessor.py +0 -0
  276. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/processors/SQLitePostProcessor.py +0 -0
  277. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/processors/__init__.py +0 -0
  278. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/query/support.py +0 -0
  279. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/BaseRelationship.py +0 -0
  280. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/HasMany.py +0 -0
  281. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/HasOne.py +0 -0
  282. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/relationships/__init__.py +0 -0
  283. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/ColumnDiff.py +0 -0
  284. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/Constraint.py +0 -0
  285. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/ForeignKeyConstraint.py +0 -0
  286. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/Index.py +0 -0
  287. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/Table.py +0 -0
  288. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/__init__.py +0 -0
  289. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/platforms/__init__.py +0 -0
  290. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/schema/schema.py +0 -0
  291. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/seeders/__init__.py +0 -0
  292. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/stubs/create-migration.html +0 -0
  293. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/stubs/table-migration.html +0 -0
  294. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/masoniteorm/testing/__init__.py +0 -0
  295. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/__init__.py +0 -0
  296. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/argument.py +0 -0
  297. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/prompt.py +0 -0
  298. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/protocol.py +0 -0
  299. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/providers/__init__.py +0 -0
  300. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/providers/mcp_provider.py +0 -0
  301. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/request.py +0 -0
  302. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/resource.py +0 -0
  303. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/response.py +0 -0
  304. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/server.py +0 -0
  305. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/mcp/tool.py +0 -0
  306. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/process/__init__.py +0 -0
  307. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/process/exception.py +0 -0
  308. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/process/fake.py +0 -0
  309. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/process/result.py +0 -0
  310. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/py.typed +0 -0
  311. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/__init__.py +0 -0
  312. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/adapters/__init__.py +0 -0
  313. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/adapters/base.py +0 -0
  314. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/adapters/claude.py +0 -0
  315. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/adapters/gemini.py +0 -0
  316. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/commands/__init__.py +0 -0
  317. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/commands/skills.py +0 -0
  318. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/parser.py +0 -0
  319. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/provider.py +0 -0
  320. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/registry.py +0 -0
  321. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/database/SKILL.md +0 -0
  322. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/fastapi/SKILL.md +0 -0
  323. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/inertia/SKILL.md +0 -0
  324. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/__init__.py +0 -0
  325. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/config/__init__.py +0 -0
  326. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/config/storage.py +0 -0
  327. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/data/mime.types +0 -0
  328. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/drivers/__init__.py +0 -0
  329. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/drivers/fake.py +0 -0
  330. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/filestream.py +0 -0
  331. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/helper.py +0 -0
  332. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/storage/providers/provider.py +0 -0
  333. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/__init__.py +0 -0
  334. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/dataclass.py +0 -0
  335. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/providers/__init__.py +0 -0
  336. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/string.py +0 -0
  337. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/support/uri.py +0 -0
  338. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/testing/__init__.py +0 -0
  339. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/__init__.py +0 -0
  340. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/config/vite.py +0 -0
  341. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/exceptions.py +0 -0
  342. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/providers/provider.py +0 -0
  343. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/stubs/package.json +0 -0
  344. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/stubs/resources/css/app.css +0 -0
  345. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/stubs/resources/js/app.ts +0 -0
  346. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/stubs/resources/templates/index.html +0 -0
  347. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/stubs/tsconfig.json +0 -0
  348. {fastapi_startkit-0.56.0 → fastapi_startkit-0.58.0}/src/fastapi_startkit/vite/stubs/vite.config.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: fastapi-startkit
3
- Version: 0.56.0
3
+ Version: 0.58.0
4
4
  Summary: A modular, provider-driven framework for building async Python web applications with FastAPI — bundling a service container, configuration system, an async-first ORM, facades, and a Cleo-powered console.
5
5
  Keywords: fastapi,framework,async,web,asgi,orm,sqlalchemy,pydantic,ioc-container,dependency-injection,service-provider,cli,console,configuration,microservices,starter-kit,boilerplate
6
6
  Author: Bedram Tamang
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fastapi-startkit"
3
- version = "0.56.0"
3
+ version = "0.58.0"
4
4
  description = "A modular, provider-driven framework for building async Python web applications with FastAPI — bundling a service container, configuration system, an async-first ORM, facades, and a Cleo-powered console."
5
5
  readme = "README.md"
6
6
  keywords = [
@@ -107,7 +107,9 @@ dev = [
107
107
  "faker>=40.13.0",
108
108
  "langchain>=1.0.0",
109
109
  "langchain-core>=1.0.0",
110
+ "basedpyright>=1.31.4",
110
111
  "pyright>=1.1.411",
112
+ "pytest-benchmark>=5.2.3",
111
113
  ]
112
114
 
113
115
 
@@ -121,7 +123,7 @@ fixable = ["F401"]
121
123
  [tool.ruff.lint.per-file-ignores]
122
124
  "__init__.py" = ["F401"]
123
125
 
124
- [tool.pyright]
126
+ [tool.basedpyright]
125
127
  include = ["src/fastapi_startkit"]
126
128
  exclude = [
127
129
  "**/tests",
@@ -137,6 +139,10 @@ pythonVersion = "3.12"
137
139
  [tool.pytest.ini_options]
138
140
  asyncio_mode = "auto"
139
141
  norecursedirs = [".venv", "dist", "build", "__pycache__"]
142
+ markers = [
143
+ "benchmark: performance benchmark, excluded by default (run with -m benchmark)",
144
+ ]
145
+ addopts = "-m 'not benchmark'"
140
146
 
141
147
  [tool.coverage.run]
142
148
  source = ["src/fastapi_startkit"]
@@ -18,6 +18,9 @@ import asyncio
18
18
  import struct
19
19
  from abc import ABC, abstractmethod
20
20
 
21
+ # Provider SDKs are optional extras imported lazily per backend, so they are
22
+ # absent from the type-check environment; the pyright ignores below cover only that.
23
+
21
24
 
22
25
  class AudioFactory(ABC):
23
26
  """Abstract base for text-to-speech backends."""
@@ -53,7 +56,7 @@ class OpenAIAudioFactory(AudioFactory):
53
56
  speed: float,
54
57
  fmt: str,
55
58
  ) -> bytes:
56
- from openai import AsyncOpenAI # noqa: PLC0415
59
+ from openai import AsyncOpenAI # noqa: PLC0415 # pyright: ignore[reportMissingImports]
57
60
 
58
61
  client = AsyncOpenAI(api_key=self._api_key, base_url=self._base_url)
59
62
  response = await client.audio.speech.create(
@@ -126,8 +129,8 @@ class GoogleAudioFactory(AudioFactory):
126
129
  The ``speed`` parameter is accepted for API compatibility but is
127
130
  not currently supported by the Gemini TTS API.
128
131
  """
129
- from google import genai # noqa: PLC0415
130
- from google.genai import types # noqa: PLC0415
132
+ from google import genai # noqa: PLC0415 # pyright: ignore[reportAttributeAccessIssue]
133
+ from google.genai import types # noqa: PLC0415 # pyright: ignore[reportMissingImports]
131
134
 
132
135
  client = genai.Client(api_key=self._api_key)
133
136
  google_voice = self._VOICE_MAP.get(voice, voice)
@@ -205,7 +208,7 @@ class ElevenLabsAudioFactory(AudioFactory):
205
208
  speed: float,
206
209
  fmt: str,
207
210
  ) -> bytes:
208
- from elevenlabs.client import ElevenLabs # noqa: PLC0415
211
+ from elevenlabs.client import ElevenLabs # noqa: PLC0415 # pyright: ignore[reportMissingImports]
209
212
 
210
213
  voice_id = self._VOICE_MAP.get(voice, voice)
211
214
  client = ElevenLabs(api_key=self._api_key)
@@ -10,7 +10,7 @@ class AnthropicConfig:
10
10
  """Configuration for the Anthropic provider."""
11
11
 
12
12
  driver: str = "anthropic"
13
- key: str = field(default_factory=lambda: env("ANTHROPIC_API_KEY", ""))
13
+ key: str = field(default_factory=lambda: env("ANTHROPIC_API_KEY", "", cast=False))
14
14
  url: str = field(default_factory=lambda: env("ANTHROPIC_BASE_URL", "https://api.anthropic.com"))
15
15
 
16
16
  models: dict = field(
@@ -25,7 +25,7 @@ class OpenAIConfig:
25
25
  """Configuration for the OpenAI provider."""
26
26
 
27
27
  driver: str = "openai"
28
- key: str = field(default_factory=lambda: env("OPENAI_API_KEY", ""))
28
+ key: str = field(default_factory=lambda: env("OPENAI_API_KEY", "", cast=False))
29
29
  url: str = field(default_factory=lambda: env("OPENAI_BASE_URL", "https://api.openai.com/v1"))
30
30
 
31
31
  models: dict = field(
@@ -41,7 +41,9 @@ class GoogleConfig:
41
41
  """Configuration for the Google / Gemini provider."""
42
42
 
43
43
  driver: str = "google"
44
- key: str = field(default_factory=lambda: env("GEMINI_API_KEY", "") or env("GOOGLE_API_KEY", ""))
44
+ key: str = field(
45
+ default_factory=lambda: env("GEMINI_API_KEY", "", cast=False) or env("GOOGLE_API_KEY", "", cast=False)
46
+ )
45
47
 
46
48
  models: dict = field(
47
49
  default_factory=lambda: {
@@ -56,7 +58,7 @@ class ElevenLabsConfig:
56
58
  """Configuration for the ElevenLabs provider."""
57
59
 
58
60
  driver: str = "elevenlabs"
59
- key: str = field(default_factory=lambda: env("ELEVENLABS_API_KEY", ""))
61
+ key: str = field(default_factory=lambda: env("ELEVENLABS_API_KEY", "", cast=False))
60
62
 
61
63
  models: dict = field(
62
64
  default_factory=lambda: {
@@ -18,6 +18,9 @@ import asyncio
18
18
  import base64
19
19
  from abc import ABC, abstractmethod
20
20
 
21
+ # Provider SDKs are optional extras imported lazily per backend, so they are
22
+ # absent from the type-check environment; the pyright ignores below cover only that.
23
+
21
24
 
22
25
  class ImageFactory(ABC):
23
26
  """Abstract base for image generation backends."""
@@ -43,7 +46,7 @@ class OpenAIImageFactory(ImageFactory):
43
46
  self._base_url = base_url
44
47
 
45
48
  async def generate(self, prompt: str, size: str, model: str, quality: str) -> bytes:
46
- from openai import AsyncOpenAI # noqa: PLC0415
49
+ from openai import AsyncOpenAI # noqa: PLC0415 # pyright: ignore[reportMissingImports]
47
50
 
48
51
  client = AsyncOpenAI(api_key=self._api_key, base_url=self._base_url)
49
52
  params: dict = {
@@ -62,7 +65,7 @@ class OpenAIImageFactory(ImageFactory):
62
65
  async def edit(self, prompt: str, image_bytes: bytes, size: str) -> bytes:
63
66
  import io # noqa: PLC0415
64
67
 
65
- from openai import AsyncOpenAI # noqa: PLC0415
68
+ from openai import AsyncOpenAI # noqa: PLC0415 # pyright: ignore[reportMissingImports]
66
69
 
67
70
  client = AsyncOpenAI(api_key=self._api_key, base_url=self._base_url)
68
71
  image_file = io.BytesIO(image_bytes)
@@ -118,8 +121,8 @@ class GoogleImageFactory(ImageFactory):
118
121
 
119
122
  async def generate(self, prompt: str, size: str, model: str, quality: str) -> bytes:
120
123
  """Generate an image via Imagen 3 and return raw PNG bytes."""
121
- from google import genai # noqa: PLC0415
122
- from google.genai import types # noqa: PLC0415
124
+ from google import genai # noqa: PLC0415 # pyright: ignore[reportAttributeAccessIssue]
125
+ from google.genai import types # noqa: PLC0415 # pyright: ignore[reportMissingImports]
123
126
 
124
127
  client = genai.Client(api_key=self._api_key)
125
128
  aspect_ratio = self._ASPECT_MAP.get(size, "1:1")
@@ -102,7 +102,7 @@ def build_pipeline(middlewares: list[Callable], core: Callable) -> Callable:
102
102
  for mw in reversed(middlewares):
103
103
  nxt = handler
104
104
  instance = mw() if isinstance(mw, type) else mw
105
- call = instance.handle if hasattr(instance, "handle") else instance
105
+ call = instance.handle if isinstance(instance, Middleware) else instance
106
106
 
107
107
  def layer(model: Any, call: Callable = call, nxt: Callable = nxt) -> Response:
108
108
  async def _source() -> AsyncIterator:
@@ -142,27 +142,35 @@ class AgentFake:
142
142
  return False
143
143
 
144
144
  async def prompt(
145
- self, message: str, *, attachments: list[Document] | None = None, config: dict | None = None
145
+ self,
146
+ message: str,
147
+ *,
148
+ model: str | None = None,
149
+ attachments: list[Document] | None = None,
150
+ provider_options: dict | None = None,
146
151
  ) -> dict:
147
152
  start = time.monotonic()
148
- extra = {"config": config} if config is not None else {}
149
- self._last_response = await self._agent.prompt(message, attachments=attachments, **extra)
153
+ self._last_response = await self._agent.prompt(
154
+ message, model=model, attachments=attachments, provider_options=provider_options
155
+ )
150
156
  self.last_elapsed = time.monotonic() - start
151
157
  self._remember(message, self._last_response)
152
158
  return self._last_response
153
159
 
154
- async def stream(self, message: str, *, config: dict | None = None) -> AsyncIterator[dict]:
160
+ async def stream(
161
+ self, message: str, *, model: str | None = None, provider_options: dict | None = None
162
+ ) -> AsyncIterator[dict]:
155
163
  chunks: list[str] = []
156
- extra = {"config": config} if config is not None else {}
157
164
  # Drive the runner directly so we can read the structured response it
158
165
  # captures while streaming (content + tool_calls), not just joined text.
159
166
  runner = self._agent.runner()
160
- async for frame in runner.stream(message, **extra):
167
+ async for frame in runner.stream(message, model=model, provider_options=provider_options):
161
168
  if text := _frame_text(frame):
162
169
  chunks.append(text)
163
170
  yield frame
164
- self._last_response = getattr(runner, "last_response", None) or _text_state("".join(chunks))
165
- self._remember(message, self._last_response)
171
+ state = getattr(runner, "last_response", None) or _text_state("".join(chunks))
172
+ self._last_response = state
173
+ self._remember(message, state)
166
174
 
167
175
  def _remember(self, message: str, state: dict) -> None:
168
176
  self._accumulate_tokens(state)
@@ -347,7 +355,7 @@ class AgentFake:
347
355
 
348
356
  async def _judge(
349
357
  self,
350
- model: str,
358
+ model: str | None,
351
359
  expectation: str,
352
360
  content: str,
353
361
  provider: str | None = None,
@@ -356,7 +364,7 @@ class AgentFake:
356
364
  ) -> dict:
357
365
  return await self._judge_live(model, expectation, content, provider)
358
366
 
359
- async def _judge_live(self, model: str, expectation: str, content: str, provider: str | None = None) -> dict:
367
+ async def _judge_live(self, model: str | None, expectation: str, content: str, provider: str | None = None) -> dict:
360
368
  from .judge import JudgeAgent # noqa: PLC0415
361
369
 
362
370
  judge = JudgeAgent()
@@ -473,7 +481,12 @@ class AgentRecordFake(AgentFake):
473
481
  self._records.append(turn)
474
482
 
475
483
  async def prompt(
476
- self, message: str, *, attachments: list[Document] | None = None, config: dict | None = None
484
+ self,
485
+ message: str,
486
+ *,
487
+ model: str | None = None,
488
+ attachments: list[Document] | None = None,
489
+ provider_options: dict | None = None,
477
490
  ) -> dict:
478
491
  cassette, store = self._load()
479
492
  key = self._key(message, attachments)
@@ -481,8 +494,9 @@ class AgentRecordFake(AgentFake):
481
494
  if key in store:
482
495
  state = self._state_from_cache(store[key])
483
496
  else:
484
- extra = {"config": config} if config is not None else {}
485
- state = await self._real.prompt(message, attachments=attachments, **extra)
497
+ state = await self._real.prompt(
498
+ message, model=model, attachments=attachments, provider_options=provider_options
499
+ )
486
500
  self._save(cassette, store, key, self._turn(message, state))
487
501
  state = self._real.runner()._apply_schema(state)
488
502
  self.last_elapsed = time.monotonic() - start
@@ -490,7 +504,9 @@ class AgentRecordFake(AgentFake):
490
504
  self._remember_turn(message, state)
491
505
  return state
492
506
 
493
- async def stream(self, message: str, *, config: dict | None = None) -> AsyncIterator[dict]:
507
+ async def stream(
508
+ self, message: str, *, model: str | None = None, provider_options: dict | None = None
509
+ ) -> AsyncIterator[dict]:
494
510
  cassette, store = self._load()
495
511
  key = self._key(message, None)
496
512
  if key in store:
@@ -507,12 +523,11 @@ class AgentRecordFake(AgentFake):
507
523
  for chunk in chunks:
508
524
  yield _chunk_event(chunk)
509
525
  else:
510
- extra = {"config": config} if config is not None else {}
511
526
  # Drive the runner directly to capture the structured state
512
527
  # (messages + chunks) it records while streaming.
513
528
  runner = self._real.runner()
514
529
  chunks = []
515
- async for frame in runner.stream(message, **extra):
530
+ async for frame in runner.stream(message, model=model, provider_options=provider_options):
516
531
  if text := _frame_text(frame):
517
532
  chunks.append(text)
518
533
  yield frame
@@ -534,7 +549,7 @@ class AgentRecordFake(AgentFake):
534
549
 
535
550
  async def _judge(
536
551
  self,
537
- model: str,
552
+ model: str | None,
538
553
  expectation: str,
539
554
  content: str,
540
555
  provider: str | None = None,
@@ -554,7 +569,7 @@ class AgentRecordFake(AgentFake):
554
569
  return verdict
555
570
 
556
571
  @staticmethod
557
- def _judge_key(model: str, expectation: str, content: str, provider: str | None = None) -> str:
572
+ def _judge_key(model: str | None, expectation: str, content: str, provider: str | None = None) -> str:
558
573
  payload = json.dumps(
559
574
  {"judge_model": model, "judge_provider": provider, "expectation": expectation, "content": content},
560
575
  sort_keys=True,
@@ -34,8 +34,8 @@ class Application(Container, Generic[TConfig]):
34
34
 
35
35
  def __init__(
36
36
  self,
37
- base_path: str | Path = None,
38
- env=None,
37
+ base_path: str | Path | None = None,
38
+ env: str | None = None,
39
39
  providers=None,
40
40
  config: Type[TConfig] | None = None,
41
41
  exception_handler: Type[ExceptionHandler] | None = None,
@@ -43,7 +43,7 @@ class Application(Container, Generic[TConfig]):
43
43
  super().__init__()
44
44
 
45
45
  self.base_path: Path = Path(base_path) if base_path else Path(os.getcwd())
46
- self.env = env
46
+ self.env: str | None = env
47
47
  self.providers = self.DEFAULT_PROVIDERS + (providers or [])
48
48
  self.published_resources = {}
49
49
  self.commands = []
@@ -72,12 +72,14 @@ class Application(Container, Generic[TConfig]):
72
72
 
73
73
  def load_environment(self):
74
74
  """Reload environment variables for the current self.env."""
75
+ # resolve_environment() runs during __init__, so env is always set here.
76
+ assert self.env is not None
75
77
  Environment.load_base(base_path=self.base_path)
76
78
  Environment.load(self.env, base_path=self.base_path)
77
79
  return self
78
80
 
79
81
  def configure_exception_handler(self):
80
- self.exception_manager: ExceptionHandler = self._exception_handler_class(application=self)
82
+ self.exception_manager = self._exception_handler_class(application=self)
81
83
  self.exception_manager.register()
82
84
  self.exception_manager.install()
83
85
  self.bind("exception_manager", self.exception_manager)
@@ -138,10 +140,10 @@ class Application(Container, Generic[TConfig]):
138
140
  return self.fastapi.options(path, **kwargs)
139
141
 
140
142
  def head(self, path: str, **kwargs) -> Callable:
141
- return self._fastapi.head(path, **kwargs)
143
+ return self.fastapi.head(path, **kwargs)
142
144
 
143
145
  def trace(self, path: str, **kwargs) -> Callable:
144
- return self._fastapi.trace(path, **kwargs)
146
+ return self.fastapi.trace(path, **kwargs)
145
147
 
146
148
  # Include routers
147
149
  def include_router(self, router: "APIRouter", **kwargs):
@@ -150,7 +152,7 @@ class Application(Container, Generic[TConfig]):
150
152
 
151
153
  # Add middleware
152
154
  def add_middleware(self, middleware_class: Type["BaseHTTPMiddleware"], **options):
153
- self._fastapi.add_middleware(middleware_class, **options)
155
+ self.fastapi.add_middleware(middleware_class, **options)
154
156
  return self
155
157
 
156
158
  # Add event handlers (startup/shutdown)
@@ -160,12 +162,12 @@ class Application(Container, Generic[TConfig]):
160
162
 
161
163
  # Mount sub-apps
162
164
  def mount(self, path: str, app_instance: "FastAPI", **kwargs):
163
- self._fastapi.mount(path, app_instance, **kwargs)
165
+ self.fastapi.mount(path, app_instance, **kwargs)
164
166
  return self
165
167
 
166
168
  # Add custom exception handlers
167
169
  def add_exception_handler(self, exc_class_or_status_code: Any, handler: Callable[..., Any]):
168
- self._fastapi.add_exception_handler(exc_class_or_status_code, handler)
170
+ self.fastapi.add_exception_handler(exc_class_or_status_code, handler)
169
171
  return self
170
172
 
171
173
  @property
@@ -210,12 +212,12 @@ class Application(Container, Generic[TConfig]):
210
212
  def configure_paths(self):
211
213
  self.bind("config.location", self.base_path / "config")
212
214
 
213
- def use_config_path(self, path: str = None):
215
+ def use_config_path(self, path: str | None = None):
214
216
  self.bind("config.location", path)
215
217
 
216
218
  return self
217
219
 
218
- def use_storage_path(self, path: str = None):
220
+ def use_storage_path(self, path: str | None = None):
219
221
  self.bind("storage.location", path)
220
222
 
221
223
  return self
@@ -143,6 +143,9 @@ class ReverbProvider(Provider):
143
143
  form = await request.form()
144
144
  channel_name = form.get("channel_name", "")
145
145
 
146
+ if not isinstance(channel_name, str):
147
+ return JSONResponse({"error": "channel_name must be a string"}, status_code=422)
148
+
146
149
  # Resolve authenticated user.
147
150
  # Prefer request.state.user (set by auth middleware), then fall
148
151
  # back to the container's "auth" service.
@@ -1,3 +1,6 @@
1
+ from collections.abc import Mapping
2
+ from typing import Any, cast
3
+
1
4
  from fastapi_startkit.loader import Loader
2
5
  from ..support.structures import data
3
6
  from ..exceptions import InvalidConfigurationSetup
@@ -47,7 +50,8 @@ class Configuration:
47
50
  else:
48
51
  params = external_config
49
52
  base_config = {name.lower(): value for name, value in params.items()}
50
- merged_config = {**base_config, **self.get(path, {})}
53
+ project_config = cast("Mapping[str, Any]", self._config.get(path, {}))
54
+ merged_config = {**base_config, **project_config}
51
55
  self.set(path, merged_config)
52
56
 
53
57
  def set(self, path, value):
@@ -1,7 +1,8 @@
1
+ from cleo.commands.command import Command
1
2
  from inflection import underscore
2
3
 
3
4
 
4
- class CanOverrideOptionsDefault:
5
+ class CanOverrideOptionsDefault(Command):
5
6
  """Command mixin to allow to override optional argument default values when instantiating the
6
7
  command.
7
8
  Example: SomeCommand(app, option1="other/default").
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import shutil
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, cast
4
4
 
5
5
  from fastapi_startkit.console import Command
6
6
  from cleo.helpers import option
@@ -23,14 +23,14 @@ class PublishCommand(Command):
23
23
  ),
24
24
  ]
25
25
 
26
- def handle(self):
26
+ def handle(self) -> int:
27
27
  from fastapi_startkit.application import app
28
28
 
29
- application: "Application" = app()
29
+ application = cast("Application", app())
30
30
 
31
31
  if not application.published_resources:
32
32
  self.line("<comment>Nothing to publish.</comment>")
33
- return
33
+ return 0
34
34
 
35
35
  provider_arg = self.option("provider")
36
36
 
@@ -41,7 +41,7 @@ class PublishCommand(Command):
41
41
  }
42
42
  if not resources:
43
43
  self.line(f"<error>No provider found matching '{provider_arg}'.</error>")
44
- return
44
+ return 0
45
45
  else:
46
46
  resources = application.published_resources
47
47
 
@@ -61,3 +61,5 @@ class PublishCommand(Command):
61
61
  os.makedirs(os.path.dirname(dest_path), exist_ok=True)
62
62
  shutil.copy2(source, dest_path)
63
63
  self.line(f" [{provider_key}] Published <info>{destination}</info>")
64
+
65
+ return 0
@@ -1,7 +1,7 @@
1
1
  """Core of the IOC Container."""
2
2
 
3
3
  import inspect
4
- from typing import Any
4
+ from typing import Any, ClassVar, TypeVar, overload
5
5
 
6
6
  from ..exceptions import (
7
7
  ContainerError,
@@ -9,6 +9,8 @@ from ..exceptions import (
9
9
  StrictContainerException,
10
10
  )
11
11
 
12
+ T = TypeVar("T")
13
+
12
14
 
13
15
  class Container:
14
16
  """Core of the Service Container.
@@ -16,14 +18,14 @@ class Container:
16
18
  Performs bindings and resolving of objects to and from the container.
17
19
  """
18
20
 
19
- _instance = None
21
+ _instance: ClassVar["Container | None"] = None
20
22
 
21
23
  @classmethod
22
- def set_instance(cls, instance):
24
+ def set_instance(cls, instance: "Container") -> None:
23
25
  cls._instance = instance
24
26
 
25
27
  @classmethod
26
- def instance(cls):
28
+ def instance(cls) -> "Container":
27
29
  if cls._instance is None:
28
30
  raise RuntimeError("Container not initialized")
29
31
  return cls._instance
@@ -103,11 +105,22 @@ class Container:
103
105
  obj = self.resolve(class_obj)
104
106
  self.bind(name, obj)
105
107
 
106
- def make(self, name, *arguments):
108
+ @overload
109
+ def make(self, name: type[T], *arguments: Any) -> T: ...
110
+
111
+ @overload
112
+ def make(self, name: str, *arguments: Any) -> Any: ...
113
+
114
+ def make(self, name: type[T] | str, *arguments: Any) -> Any:
107
115
  """Retrieve a class from the container by key.
108
116
 
117
+ A class key resolves to an instance of that class, so `make(Foo)` is
118
+ typed as `Foo`. A string key carries no static type information, so it
119
+ stays `Any` and callers annotate the binding themselves. The return is
120
+ never `None`: a missing key raises instead.
121
+
109
122
  Arguments:
110
- name {string} -- Key in the container that you want to get.
123
+ name {string | type} -- Key in the container that you want to get.
111
124
 
112
125
  Raises:
113
126
  MissingContainerBindingNotFound -- Raised if the key is not in the container.
@@ -2,6 +2,7 @@
2
2
 
3
3
  import os
4
4
  import sys
5
+ from pathlib import Path
5
6
  from typing import Any, Literal, TypeVar, overload
6
7
 
7
8
  from dotenv import load_dotenv
@@ -13,7 +14,7 @@ EnvValue = str | int | bool
13
14
 
14
15
  class Environment:
15
16
  @staticmethod
16
- def resolve_environment(base_path=None, env: str | None = None):
17
+ def resolve_environment(base_path: Path | None = None, env: str | None = None):
17
18
  Environment.resolve_environment_from_argument()
18
19
 
19
20
  if "PYTEST_CURRENT_TEST" in os.environ:
@@ -26,7 +27,7 @@ class Environment:
26
27
  if os.environ.get("APP_ENV"):
27
28
  return os.environ["APP_ENV"]
28
29
 
29
- path = base_path / ".env"
30
+ path = Environment._require_base_path(base_path) / ".env"
30
31
  if not path.exists():
31
32
  raise ValueError("Unable to determine environment.")
32
33
 
@@ -39,15 +40,22 @@ class Environment:
39
40
  return env
40
41
 
41
42
  @staticmethod
42
- def load_base(base_path=None):
43
+ def _require_base_path(base_path: Path | None) -> Path:
44
+ # Keeps the TypeError the old unguarded `None / ".env"` raised, with a clearer message.
45
+ if base_path is None:
46
+ raise TypeError("base_path is required to locate .env files")
47
+ return base_path
48
+
49
+ @staticmethod
50
+ def load_base(base_path: Path | None = None):
43
51
  """Load the base .env file, resetting vars to their default values."""
44
- path = base_path / ".env"
52
+ path = Environment._require_base_path(base_path) / ".env"
45
53
  if path.exists():
46
54
  load_dotenv(path, override=True)
47
55
 
48
56
  @staticmethod
49
- def load(env: str, override=True, only=None, base_path=None):
50
- path = base_path / f".env.{env}"
57
+ def load(env: str, override=True, only=None, base_path: Path | None = None):
58
+ path = Environment._require_base_path(base_path) / f".env.{env}"
51
59
  if not path.exists():
52
60
  return
53
61
  load_dotenv(path, override=override)
@@ -7,13 +7,17 @@ coroutine listeners are supported — coroutine results are awaited transparentl
7
7
 
8
8
  import inspect
9
9
  from fnmatch import fnmatchcase
10
- from typing import TYPE_CHECKING, Any, Callable, cast, overload
10
+ from typing import TYPE_CHECKING, Any, Callable, Protocol, cast, overload
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from ..container import Container
14
14
  from .fake import EventFake
15
15
 
16
16
 
17
+ class _ClassListener(Protocol):
18
+ def handle(self, *args: Any) -> Any: ...
19
+
20
+
17
21
  class Dispatcher:
18
22
  def __init__(self, container: "Container | None" = None):
19
23
  self._container = container
@@ -132,7 +136,7 @@ class Dispatcher:
132
136
 
133
137
  def _resolve_listener(self, listener: Callable) -> Callable:
134
138
  if inspect.isclass(listener):
135
- return self._make(listener).handle
139
+ return cast(_ClassListener, self._make(listener)).handle
136
140
  return listener
137
141
 
138
142
  def _make(self, cls):
@@ -1,26 +1,31 @@
1
- from typing import Any, List, TYPE_CHECKING
1
+ from typing import Any, List
2
2
 
3
- if TYPE_CHECKING:
4
- from ..dumps import Dump as DumpObject
3
+ DumpObject = Any
5
4
 
6
5
  class Dump:
7
6
  """Dumper facade."""
8
7
 
9
- def clear(self) -> "Dump":
8
+ @staticmethod
9
+ def clear() -> "Dump":
10
10
  """Clear all dumped data"""
11
11
  ...
12
- def dd(*objects: List[Any]):
12
+ @staticmethod
13
+ def dd(*objects: Any):
13
14
  """Dump all provided args and die, raising a DumpException."""
14
15
  ...
15
- def dump(*objects: List[Any]):
16
+ @staticmethod
17
+ def dump(*objects: Any):
16
18
  """Dump all provided args and continue code execution. This does not raise a DumpException."""
17
19
  ...
20
+ @staticmethod
18
21
  def get_dumps(ascending: bool = False) -> List[DumpObject]:
19
22
  """Get all dumps as Dump objects. If ascending is True, get dumps from oldest to most recents."""
20
23
  ...
21
- def last(self) -> DumpObject:
24
+ @staticmethod
25
+ def last() -> DumpObject:
22
26
  """Return last added dump."""
23
27
  ...
28
+ @staticmethod
24
29
  def get_serialized_dumps(ascending: bool = False) -> List[dict]:
25
30
  """Get all dumps as dict. If ascending is True, sort dumps from oldest to most recents."""
26
31
  ...