fastapi-startkit 0.58.0__tar.gz → 0.60.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.
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/PKG-INFO +1 -1
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/pyproject.toml +1 -1
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/commands/serve_command.py +20 -1
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/config/fastapi.py +2 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/config/logging.py +1 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/handler.py +6 -2
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/managers/LoggingManager.py +4 -3
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/providers/log_provider.py +1 -1
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/config/config.py +4 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/connections/factory.py +1 -1
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/builder.py +116 -56
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/model.py +62 -60
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/grammars/BaseGrammar.py +1 -1
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsToMany.py +2 -2
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/README.md +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/.DS_Store +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/agent.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/ai.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/audio.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/audio_factory.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/config/ai.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/config/config.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/decorators.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/document.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/image.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/image_factory.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/judge.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/lab.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/pipeline.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/providers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/providers/ai_provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/recording.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/runner.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/state.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/testing.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/tinker.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/ai/types.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/application.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/auth.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/channels.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/config.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/drivers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/drivers/log_driver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/drivers/reverb_driver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/event.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/helpers.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/manager.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/reverb/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/reverb/channel_manager.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/reverb/connection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/reverb/server.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/stubs/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/broadcasting/stubs/channels.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/carbon/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/carbon/carbon.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/config/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/config/app.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/configuration/Configuration.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/configuration/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/configuration/config.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/configuration/helpers.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/configuration/providers/ConfigurationProvider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/configuration/providers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/console/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/console/application.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/console/can_override_config.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/console/can_override_default_options.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/console/command.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/console/publish_command.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/container/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/container/container.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/environment/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/environment/environment.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/events/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/events/dispatcher.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/events/fake.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/events/helpers.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/events/listener.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/events/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/exceptions/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/exceptions/exceptions.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/exceptions/handler.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/AI.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/AI.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Cache.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Config.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Config.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Dump.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Dump.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Event.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Event.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Facade.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Gate.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Gate.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Hash.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Hash.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Loader.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Loader.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Mail.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Mail.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Notification.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Notification.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Queue.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Queue.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/RateLimiter.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/RateLimiter.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Request.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Request.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Response.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Response.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Session.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Session.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Url.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Url.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/View.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/View.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Vite.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/Vite.pyi +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/facades/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/commands/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/config/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/events.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/exceptions.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/middleware.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/requests/model.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/routers/router.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/testing/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/testing/assertable_json.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/testing/test_case.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/testing/test_response.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/foundation/app_provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/constant.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/context.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/inertia.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/middleware.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/props/props.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/inertia/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/jsonapi/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/jsonapi/response.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/loader/Loader.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/loader/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/ChannelFactory.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/BaseChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/DailyChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/MultiBaseChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/SingleChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/SlackChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/StackChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/SyslogChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/TerminalChannel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/channels/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/config/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/config/channels.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/drivers/BaseDriver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/drivers/LogSingleDriver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/drivers/LogSlackDriver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/drivers/LogSyslogDriver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/drivers/LogTerminalDriver.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/drivers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/factory.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/file.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/listeners.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/logger.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/managers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/providers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/collection/Collection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/collection/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/DBMigrateCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/DBSeedCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MakeMigrationCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MakeModelCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MakeObserverCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MakeSeedCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MigrateFreshCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRefreshCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MigrateResetCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MigrateRollbackCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/MigrateStatusCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/ShellCommand.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_migration.stub +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/stubs/create_seed.stub +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/stubs/model.stub +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/stubs/observer.stub +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/commands/stubs/table_migration.stub +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/config/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/config/database.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/connections/connection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/connections/manager.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/connections/mysql_connection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/connections/postgres_connection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/connections/sqlite_connection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/exceptions.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/expressions/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/expressions/expressions.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/facades/DB.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/facades/Schema.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/facades/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/factory/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/factory/factory.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/helpers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/helpers/misc.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/migrations/Migration.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/migrations/Migrator.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/migrations/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/MigrationModel.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/attribute.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/caster.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/fields.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/observer.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/pivot.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/registry.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/models/relationship.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/observers/ObservesEvents.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/observers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/pagination/BasePaginator.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/pagination/LengthAwarePaginator.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/pagination/SimplePaginator.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/pagination/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/providers/DatabaseProvider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/providers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/EagerLoadMixin.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/EagerRelation.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/grammars/MSSQLGrammar.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/grammars/MySQLGrammar.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/grammars/PostgresGrammar.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/grammars/SQLiteGrammar.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/grammars/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/processors/MSSQLPostProcessor.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/processors/MySQLPostProcessor.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/processors/PostgresPostProcessor.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/processors/SQLitePostProcessor.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/processors/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/query/support.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/BaseRelationship.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/BelongsTo.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/HasMany.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/HasManyThrough.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/HasOne.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/HasOneThrough.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/MorphMany.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/MorphOne.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/MorphTo.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/MorphToMany.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/relationships/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/Blueprint.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/Column.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/ColumnDiff.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/Constraint.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/ForeignKeyConstraint.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/Index.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/Table.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/TableDiff.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MSSQLPlatform.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/platforms/MySQLPlatform.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/platforms/Platform.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/platforms/PostgresPlatform.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/platforms/SQLitePlatform.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/platforms/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/schema/schema.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/seeders/Seeder.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/seeders/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/stubs/create-migration.html +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/stubs/table-migration.html +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/testing/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/masoniteorm/testing/transaction.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/argument.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/prompt.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/protocol.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/providers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/providers/mcp_provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/request.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/resource.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/response.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/server.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/mcp/tool.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/process/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/process/exception.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/process/fake.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/process/process.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/process/result.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/py.typed +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/adapters/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/adapters/base.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/adapters/claude.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/adapters/gemini.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/commands/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/commands/skills.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/parser.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/registry.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/database/SKILL.md +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/fastapi/SKILL.md +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/skills/stubs/.ai/fastapi-startkit/inertia/SKILL.md +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/config/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/config/storage.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/data/mime.types +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/drivers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/drivers/fake.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/drivers/local.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/drivers/s3.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/file.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/filestream.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/helper.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/providers/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/storage/storage.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/collection.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/dataclass.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/providers/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/providers/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/string.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/structures.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/support/uri.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/testing/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/testing/test_case.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/__init__.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/config/vite.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/exceptions.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/providers/provider.py +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/stubs/package.json +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/stubs/resources/css/app.css +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/stubs/resources/js/app.ts +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/stubs/resources/templates/index.html +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/stubs/tsconfig.json +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/vite/stubs/vite.config.ts +0 -0
- {fastapi_startkit-0.58.0 → fastapi_startkit-0.60.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.
|
|
3
|
+
Version: 0.60.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.
|
|
3
|
+
version = "0.60.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 = [
|
|
@@ -11,6 +11,9 @@ from fastapi_startkit.support import Uri, Uriable
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from fastapi_startkit.application import Application
|
|
13
13
|
|
|
14
|
+
# Values accepted by uvicorn's `ws` setting.
|
|
15
|
+
WS_BACKENDS = ("auto", "none", "websockets", "websockets-sansio", "wsproto")
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
class ServeCommand(Command):
|
|
16
19
|
name = "serve"
|
|
@@ -45,6 +48,13 @@ class ServeCommand(Command):
|
|
|
45
48
|
default=None,
|
|
46
49
|
description="The application to serve (overrides fastapi config)",
|
|
47
50
|
),
|
|
51
|
+
option(
|
|
52
|
+
"ws",
|
|
53
|
+
None,
|
|
54
|
+
flag=False,
|
|
55
|
+
default=None,
|
|
56
|
+
description=f"The uvicorn WebSocket backend: {', '.join(WS_BACKENDS)} (overrides fastapi config)",
|
|
57
|
+
),
|
|
48
58
|
]
|
|
49
59
|
|
|
50
60
|
def config_value(self, key: str) -> Any:
|
|
@@ -72,11 +82,20 @@ class ServeCommand(Command):
|
|
|
72
82
|
|
|
73
83
|
return uri.with_port(port) if port else uri
|
|
74
84
|
|
|
85
|
+
def resolve_ws(self) -> str:
|
|
86
|
+
"""CLI flag > fastapi config > FastAPIConfig default ('auto')."""
|
|
87
|
+
return str(self.option("ws") or self.config_value("ws"))
|
|
88
|
+
|
|
75
89
|
def handle(self) -> int:
|
|
76
90
|
import uvicorn
|
|
77
91
|
|
|
78
92
|
from fastapi_startkit.container import Container
|
|
79
93
|
|
|
94
|
+
ws = self.resolve_ws()
|
|
95
|
+
if ws not in WS_BACKENDS:
|
|
96
|
+
self.line_error(f"Invalid --ws backend '{ws}'. Allowed values: {', '.join(WS_BACKENDS)}.", style="error")
|
|
97
|
+
return 1
|
|
98
|
+
|
|
80
99
|
url = self.resolve_url()
|
|
81
100
|
reload = self.resolve_option("reload")
|
|
82
101
|
app = self.resolve_option("app")
|
|
@@ -85,7 +104,7 @@ class ServeCommand(Command):
|
|
|
85
104
|
"host": url.host(),
|
|
86
105
|
"port": url.port(),
|
|
87
106
|
"reload": reload,
|
|
88
|
-
"ws":
|
|
107
|
+
"ws": ws,
|
|
89
108
|
}
|
|
90
109
|
|
|
91
110
|
if self.is_app_exist(app):
|
{fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/fastapi/config/fastapi.py
RENAMED
|
@@ -8,6 +8,8 @@ class FastAPIConfig:
|
|
|
8
8
|
app_url: str = dataclasses.field(default_factory=lambda: env("APP_URL", "http://127.0.0.1:8000"))
|
|
9
9
|
app: str = "bootstrap.application:app"
|
|
10
10
|
reload: bool = dataclasses.field(default_factory=lambda: env("APP_RELOAD", True))
|
|
11
|
+
# 'auto' keeps the optional `websockets` package from being required at startup.
|
|
12
|
+
ws: str = dataclasses.field(default_factory=lambda: env("APP_WS", "auto"))
|
|
11
13
|
reload_dirs: list | None = None
|
|
12
14
|
reload_excludes: list = dataclasses.field(
|
|
13
15
|
default_factory=lambda: [
|
{fastapi_startkit-0.58.0 → fastapi_startkit-0.60.0}/src/fastapi_startkit/logging/config/logging.py
RENAMED
|
@@ -7,6 +7,7 @@ from fastapi_startkit.logging.config import StackChannel, DailyChannel, Terminal
|
|
|
7
7
|
@dataclasses.dataclass
|
|
8
8
|
class LoggingConfig:
|
|
9
9
|
default: str = dataclasses.field(default_factory=lambda: env("LOG_CHANNEL", "stack"))
|
|
10
|
+
level: str = dataclasses.field(default_factory=lambda: env("LOG_LEVEL", "info"))
|
|
10
11
|
|
|
11
12
|
channels: dict = dataclasses.field(
|
|
12
13
|
default_factory=lambda: {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
+
# Framework-only severities have no stdlib equivalent; map them to the nearest one.
|
|
4
|
+
_STDLIB_LEVELS = {"notice": "INFO", "alert": "CRITICAL", "emergency": "CRITICAL"}
|
|
5
|
+
|
|
3
6
|
|
|
4
7
|
class LoggingHandler(logging.Handler):
|
|
5
8
|
def emit(self, record: logging.LogRecord) -> None:
|
|
@@ -8,8 +11,9 @@ class LoggingHandler(logging.Handler):
|
|
|
8
11
|
Logger.log(record.levelname, self.format(record))
|
|
9
12
|
|
|
10
13
|
@staticmethod
|
|
11
|
-
def install():
|
|
14
|
+
def install(level: str | None = None):
|
|
12
15
|
root_logger = logging.getLogger()
|
|
13
16
|
if not any(isinstance(h, LoggingHandler) for h in root_logger.handlers):
|
|
14
17
|
root_logger.addHandler(LoggingHandler())
|
|
15
|
-
|
|
18
|
+
if level:
|
|
19
|
+
root_logger.setLevel(_STDLIB_LEVELS.get(level.lower(), level.upper()))
|
|
@@ -7,10 +7,11 @@ class LoggingManager:
|
|
|
7
7
|
self,
|
|
8
8
|
channel_factory: type[ChannelFactory] = ChannelFactory,
|
|
9
9
|
driver_factory: type[DriverFactory] = DriverFactory,
|
|
10
|
+
level: str | None = None,
|
|
10
11
|
):
|
|
11
12
|
self.channel_factory = channel_factory
|
|
12
13
|
self.driver_factory = driver_factory
|
|
13
|
-
self.configure_python_logging()
|
|
14
|
+
self.configure_python_logging(level)
|
|
14
15
|
|
|
15
16
|
def channel(self, channel: str):
|
|
16
17
|
channel_class = self.channel_factory.make(channel)
|
|
@@ -19,7 +20,7 @@ class LoggingManager:
|
|
|
19
20
|
return channel_class()
|
|
20
21
|
|
|
21
22
|
@classmethod
|
|
22
|
-
def configure_python_logging(cls):
|
|
23
|
+
def configure_python_logging(cls, level: str | None = None):
|
|
23
24
|
from ..handler import LoggingHandler
|
|
24
25
|
|
|
25
|
-
LoggingHandler.install()
|
|
26
|
+
LoggingHandler.install(level)
|
|
@@ -17,7 +17,7 @@ class LogProvider(Provider):
|
|
|
17
17
|
|
|
18
18
|
self.app.bind("LogChannelFactory", ChannelFactory)
|
|
19
19
|
self.app.bind("LogDriverFactory", DriverFactory)
|
|
20
|
-
self.app.bind("LoggingManager", LoggingManager(ChannelFactory, DriverFactory))
|
|
20
|
+
self.app.bind("LoggingManager", LoggingManager(ChannelFactory, DriverFactory, config.get("level")))
|
|
21
21
|
|
|
22
22
|
def boot(self):
|
|
23
23
|
self.publishes({Path(__file__).resolve().parent.parent.joinpath("config/logging.py"): "config/logging.py"})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from typing import Optional, Dict, Any
|
|
2
2
|
from pydantic.dataclasses import dataclass
|
|
3
|
+
from pydantic.fields import Field
|
|
3
4
|
from fastapi_startkit.environment.environment import env
|
|
4
5
|
|
|
5
6
|
|
|
@@ -8,6 +9,7 @@ class SQLiteConfig:
|
|
|
8
9
|
driver: str = "sqlite"
|
|
9
10
|
url: Optional[str] = env("DB_URL", None, cast=False)
|
|
10
11
|
database: str = env("DB_DATABASE", "database.sqlite")
|
|
12
|
+
echo: bool = Field(default_factory=lambda: env("DB_ECHO", False))
|
|
11
13
|
options: Optional[Dict[str, Any]] = None
|
|
12
14
|
|
|
13
15
|
|
|
@@ -23,6 +25,7 @@ class MySQLConfig:
|
|
|
23
25
|
unix_socket: str = env("DB_SOCKET", "", cast=False)
|
|
24
26
|
charset: str = env("DB_CHARSET", "utf8mb4")
|
|
25
27
|
collation: str = env("DB_COLLATION", "utf8mb4_unicode_ci")
|
|
28
|
+
echo: bool = Field(default_factory=lambda: env("DB_ECHO", False))
|
|
26
29
|
options: Optional[Dict[str, Any]] = None
|
|
27
30
|
|
|
28
31
|
|
|
@@ -37,4 +40,5 @@ class PostgresConfig:
|
|
|
37
40
|
password: str = env("DB_PASSWORD", "", cast=False)
|
|
38
41
|
charset: str = env("DB_CHARSET", "utf8")
|
|
39
42
|
sslmode: str = env("DB_SSLMODE", "prefer")
|
|
43
|
+
echo: bool = Field(default_factory=lambda: env("DB_ECHO", False))
|
|
40
44
|
options: Optional[Dict[str, Any]] = None
|
|
@@ -64,7 +64,7 @@ class ConnectionFactory:
|
|
|
64
64
|
@classmethod
|
|
65
65
|
def create_engine(cls, cfg: dict) -> AsyncEngine:
|
|
66
66
|
url = cls.build_url(cfg)
|
|
67
|
-
kwargs: dict[str, Any] = {"echo":
|
|
67
|
+
kwargs: dict[str, Any] = {"echo": bool(cfg.get("echo", False))}
|
|
68
68
|
from fastapi_startkit.application import app
|
|
69
69
|
|
|
70
70
|
if cast("Application", app()).is_testing():
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
from collections.abc import Callable
|
|
2
|
+
from collections.abc import Callable, Iterable
|
|
3
3
|
from typing import TYPE_CHECKING, Any, Generic, Self, TypeVar, overload
|
|
4
4
|
|
|
5
5
|
from fastapi_startkit.masoniteorm.expressions.expressions import (
|
|
@@ -29,6 +29,11 @@ TModel = TypeVar("TModel", bound="Model")
|
|
|
29
29
|
# returns it, which the parent renders as a parenthesised subgroup.
|
|
30
30
|
type WhereGroup[M: "Model"] = Callable[["QueryBuilder[M]"], "QueryBuilder[M]"]
|
|
31
31
|
|
|
32
|
+
# select_sub()/add_select() subquery source: a builder, or a callable that
|
|
33
|
+
# receives a fresh builder and returns the subquery.
|
|
34
|
+
type Subquery = "QueryBuilder[Any] | Callable[[QueryBuilder[Any]], QueryBuilder[Any]]"
|
|
35
|
+
type SelectEntry = "str | dict[str, str | Subquery]"
|
|
36
|
+
|
|
32
37
|
|
|
33
38
|
class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
34
39
|
operators = [
|
|
@@ -67,13 +72,13 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
67
72
|
"!~~*",
|
|
68
73
|
]
|
|
69
74
|
|
|
70
|
-
def __init__(self, connection: "Connection", grammar, processor):
|
|
75
|
+
def __init__(self, connection: "Connection", grammar: Any, processor: Any):
|
|
71
76
|
super().__init__()
|
|
72
77
|
self.connection = connection
|
|
73
78
|
self.grammar = grammar
|
|
74
79
|
self.processor = processor
|
|
75
80
|
|
|
76
|
-
self._columns = []
|
|
81
|
+
self._columns: list[Any] = []
|
|
77
82
|
self._table = ""
|
|
78
83
|
self._limit = False
|
|
79
84
|
self._offset = False
|
|
@@ -91,35 +96,35 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
91
96
|
self._global_scopes = {}
|
|
92
97
|
self._action = "select"
|
|
93
98
|
|
|
94
|
-
def set_action(self, action: str) -> "
|
|
99
|
+
def set_action(self, action: str) -> "Self":
|
|
95
100
|
self._action = action
|
|
96
101
|
return self
|
|
97
102
|
|
|
98
|
-
def set_model(self, model) -> "
|
|
103
|
+
def set_model(self, model: "TModel") -> "Self":
|
|
99
104
|
self._model = model
|
|
100
105
|
self._table = model.get_table_name()
|
|
101
106
|
self._global_scopes = model._global_scopes
|
|
102
107
|
return self
|
|
103
108
|
|
|
104
|
-
def with_(self, *eagers) -> "
|
|
109
|
+
def with_(self, *eagers) -> "Self":
|
|
105
110
|
self._eager_relation.register(eagers)
|
|
106
111
|
return self
|
|
107
112
|
|
|
108
113
|
def get_table_name(self) -> str:
|
|
109
114
|
return self._table
|
|
110
115
|
|
|
111
|
-
def table(self, table: str) -> "
|
|
116
|
+
def table(self, table: str) -> "Self":
|
|
112
117
|
self._table = table
|
|
113
118
|
return self
|
|
114
119
|
|
|
115
|
-
def where_in(self, column: str, values) -> "
|
|
120
|
+
def where_in(self, column: str, values: Iterable[Any]) -> "Self":
|
|
116
121
|
if hasattr(values, "_items"):
|
|
117
|
-
values = values
|
|
122
|
+
values = getattr(values, "_items")
|
|
118
123
|
values = list(values) if not isinstance(values, list) else values
|
|
119
124
|
self._wheres.append(QueryExpression(column, "IN", values))
|
|
120
125
|
return self
|
|
121
126
|
|
|
122
|
-
def select(self, *args) -> "
|
|
127
|
+
def select(self, *args: "str | list[str]") -> "Self":
|
|
123
128
|
for arg in args:
|
|
124
129
|
if isinstance(arg, list):
|
|
125
130
|
for column in arg:
|
|
@@ -129,14 +134,67 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
129
134
|
self._columns += (SelectExpression(column),)
|
|
130
135
|
return self
|
|
131
136
|
|
|
132
|
-
def
|
|
137
|
+
def select_sub(self, subquery: "Subquery", alias: str) -> "Self":
|
|
138
|
+
"""Add ``(subquery) AS alias`` to the selection.
|
|
139
|
+
|
|
140
|
+
``subquery`` is a builder, or a callable that receives a fresh table-less
|
|
141
|
+
builder and returns one.
|
|
142
|
+
"""
|
|
143
|
+
if not isinstance(subquery, QueryBuilder) and callable(subquery):
|
|
144
|
+
subquery = subquery(QueryBuilder(self.connection, self.grammar, self.processor))
|
|
145
|
+
if not isinstance(subquery, QueryBuilder):
|
|
146
|
+
raise TypeError("select_sub() expects a QueryBuilder subquery or a callable returning one.")
|
|
147
|
+
self._columns.append(SubGroupExpression(subquery, alias))
|
|
148
|
+
return self
|
|
149
|
+
|
|
150
|
+
def add_select(self, *columns: "SelectEntry | list[SelectEntry]") -> "Self":
|
|
151
|
+
"""Append columns to the current selection without replacing it.
|
|
152
|
+
|
|
153
|
+
Plain string columns are appended once. A ``{alias: subquery}`` entry
|
|
154
|
+
adds a correlated column via :meth:`select_sub`, first selecting
|
|
155
|
+
``{table}.*`` when nothing is selected yet so the base columns survive.
|
|
156
|
+
A string value under a string key is still a plain column.
|
|
157
|
+
"""
|
|
158
|
+
entries: list[SelectEntry] = []
|
|
159
|
+
for column in columns:
|
|
160
|
+
if isinstance(column, list):
|
|
161
|
+
entries.extend(column)
|
|
162
|
+
else:
|
|
163
|
+
entries.append(column)
|
|
164
|
+
|
|
165
|
+
for entry in entries:
|
|
166
|
+
pairs: Iterable[tuple[str | None, str | Subquery]] = (
|
|
167
|
+
entry.items() if isinstance(entry, dict) else [(None, entry)]
|
|
168
|
+
)
|
|
169
|
+
for alias, value in pairs:
|
|
170
|
+
if isinstance(value, str):
|
|
171
|
+
if not self._is_selected(value):
|
|
172
|
+
self._columns.append(SelectExpression(value))
|
|
173
|
+
continue
|
|
174
|
+
if alias is None:
|
|
175
|
+
raise TypeError(
|
|
176
|
+
"add_select() received a subquery without a string alias; "
|
|
177
|
+
"pass {alias: subquery} or use select_sub(subquery, alias)."
|
|
178
|
+
)
|
|
179
|
+
if not self._columns:
|
|
180
|
+
self.select(f"{self._table}.*")
|
|
181
|
+
self.select_sub(value, alias)
|
|
182
|
+
return self
|
|
183
|
+
|
|
184
|
+
def _is_selected(self, column: str) -> bool:
|
|
185
|
+
return any(
|
|
186
|
+
isinstance(existing, SelectExpression) and existing.alias is None and existing.column == column
|
|
187
|
+
for existing in self._columns
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
def limit(self, limit: int) -> "Self":
|
|
133
191
|
self._limit = limit
|
|
134
192
|
return self
|
|
135
193
|
|
|
136
|
-
async def find(self, primary_key: str | int, columns=None) -> "TModel | None":
|
|
194
|
+
async def find(self, primary_key: str | int, columns: "list[str] | str | None" = None) -> "TModel | None":
|
|
137
195
|
return await self.where(self._model.__primary_key__, primary_key).first(columns)
|
|
138
196
|
|
|
139
|
-
async def find_or_fail(self, primary_key: str | int, columns=None) -> "TModel":
|
|
197
|
+
async def find_or_fail(self, primary_key: str | int, columns: "list[str] | str | None" = None) -> "TModel":
|
|
140
198
|
"""Return the record matching ``primary_key``.
|
|
141
199
|
|
|
142
200
|
Raises:
|
|
@@ -149,7 +207,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
149
207
|
raise ModelNotFoundException(f"{type(self._model).__name__} with primary key {primary_key!r} not found.")
|
|
150
208
|
return result
|
|
151
209
|
|
|
152
|
-
async def first_or_fail(self, columns=None) -> "TModel":
|
|
210
|
+
async def first_or_fail(self, columns: "list[str] | str | None" = None) -> "TModel":
|
|
153
211
|
from fastapi_startkit.masoniteorm.exceptions import ModelNotFoundException
|
|
154
212
|
|
|
155
213
|
result = await self.first(columns)
|
|
@@ -157,7 +215,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
157
215
|
raise ModelNotFoundException(f"{type(self._model).__name__} not found.")
|
|
158
216
|
return result
|
|
159
217
|
|
|
160
|
-
async def first(self, columns=None) -> "TModel | None":
|
|
218
|
+
async def first(self, columns: "list[str] | str | None" = None) -> "TModel | None":
|
|
161
219
|
if not columns:
|
|
162
220
|
columns = []
|
|
163
221
|
|
|
@@ -170,7 +228,9 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
170
228
|
columns = []
|
|
171
229
|
return await self.get_models(columns)
|
|
172
230
|
|
|
173
|
-
async def get_models(self, columns=None):
|
|
231
|
+
async def get_models(self, columns: "list[str] | str | None" = None) -> "Collection[TModel]":
|
|
232
|
+
if not columns:
|
|
233
|
+
columns = []
|
|
174
234
|
self.select(columns)
|
|
175
235
|
models = await self.connection.select(self.to_qmark(), list(self.get_bindings()))
|
|
176
236
|
collection = self._model.hydrate(models)
|
|
@@ -180,15 +240,15 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
180
240
|
|
|
181
241
|
return collection
|
|
182
242
|
|
|
183
|
-
def get_bindings(self) -> tuple:
|
|
243
|
+
def get_bindings(self) -> tuple[Any, ...]:
|
|
184
244
|
return self._bindings
|
|
185
245
|
|
|
186
|
-
def run_scopes(self) -> "
|
|
246
|
+
def run_scopes(self) -> "Self":
|
|
187
247
|
for name, scope in self._global_scopes.get(self._action, {}).items():
|
|
188
248
|
scope(self)
|
|
189
249
|
return self
|
|
190
250
|
|
|
191
|
-
def without_global_scopes(self) -> "
|
|
251
|
+
def without_global_scopes(self) -> "Self":
|
|
192
252
|
self._global_scopes = {}
|
|
193
253
|
return self
|
|
194
254
|
|
|
@@ -218,11 +278,11 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
218
278
|
self.run_scopes()
|
|
219
279
|
return self.get_grammar().compile(self._action).to_sql()
|
|
220
280
|
|
|
221
|
-
def offset(self, offset: int) -> "
|
|
281
|
+
def offset(self, offset: int) -> "Self":
|
|
222
282
|
self._offset = offset
|
|
223
283
|
return self
|
|
224
284
|
|
|
225
|
-
def order_by(self, column, direction: str = "asc") -> "
|
|
285
|
+
def order_by(self, column: "str | QueryBuilder[Any]", direction: str = "asc") -> "Self":
|
|
226
286
|
direction = direction.upper()
|
|
227
287
|
if isinstance(column, QueryBuilder):
|
|
228
288
|
self._order_by += (OrderByExpression(None, direction, builder=column),)
|
|
@@ -232,67 +292,67 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
232
292
|
self._order_by += (OrderByExpression(col, direction),)
|
|
233
293
|
return self
|
|
234
294
|
|
|
235
|
-
def order_by_raw(self, expression: str) -> "
|
|
295
|
+
def order_by_raw(self, expression: str) -> "Self":
|
|
236
296
|
self._order_by += (OrderByExpression(expression, raw=True),)
|
|
237
297
|
return self
|
|
238
298
|
|
|
239
|
-
def latest(self, column: str = "created_at") -> "
|
|
299
|
+
def latest(self, column: str = "created_at") -> "Self":
|
|
240
300
|
return self.order_by(column, "desc")
|
|
241
301
|
|
|
242
|
-
def oldest(self, column: str = "created_at") -> "
|
|
302
|
+
def oldest(self, column: str = "created_at") -> "Self":
|
|
243
303
|
return self.order_by(column, "asc")
|
|
244
304
|
|
|
245
|
-
def group_by(self, column: str) -> "
|
|
305
|
+
def group_by(self, column: str) -> "Self":
|
|
246
306
|
for col in column.split(","):
|
|
247
307
|
col = col.strip()
|
|
248
308
|
self._group_by += (GroupByExpression(col),)
|
|
249
309
|
return self
|
|
250
310
|
|
|
251
|
-
def group_by_raw(self, expression: str) -> "
|
|
311
|
+
def group_by_raw(self, expression: str) -> "Self":
|
|
252
312
|
self._group_by += (GroupByExpression(expression, raw=True),)
|
|
253
313
|
return self
|
|
254
314
|
|
|
255
|
-
def having(self, column: str, equality: str, value) -> "
|
|
315
|
+
def having(self, column: str, equality: str, value: Any) -> "Self":
|
|
256
316
|
self._having += (HavingExpression(column, equality, value),)
|
|
257
317
|
return self
|
|
258
318
|
|
|
259
|
-
def where_null(self, column: str) -> "
|
|
319
|
+
def where_null(self, column: str) -> "Self":
|
|
260
320
|
self._wheres += (QueryExpression(column, "=", None, "NULL"),)
|
|
261
321
|
return self
|
|
262
322
|
|
|
263
|
-
def where_not_null(self, column: str) -> "
|
|
323
|
+
def where_not_null(self, column: str) -> "Self":
|
|
264
324
|
self._wheres += (QueryExpression(column, "=", None, "NOT NULL"),)
|
|
265
325
|
return self
|
|
266
326
|
|
|
267
|
-
def or_where_null(self, column: str) -> "
|
|
327
|
+
def or_where_null(self, column: str) -> "Self":
|
|
268
328
|
self._wheres += (QueryExpression(column, "=", None, "NULL", keyword="or"),)
|
|
269
329
|
return self
|
|
270
330
|
|
|
271
|
-
def or_where_not_null(self, column: str) -> "
|
|
331
|
+
def or_where_not_null(self, column: str) -> "Self":
|
|
272
332
|
self._wheres += (QueryExpression(column, "=", None, "NOT NULL", keyword="or"),)
|
|
273
333
|
return self
|
|
274
334
|
|
|
275
|
-
def where_not_in(self, column: str, values) -> "
|
|
335
|
+
def where_not_in(self, column: str, values: Iterable[Any]) -> "Self":
|
|
276
336
|
values = list(values) if not isinstance(values, list) else values
|
|
277
337
|
self._wheres.append(QueryExpression(column, "NOT IN", values))
|
|
278
338
|
return self
|
|
279
339
|
|
|
280
|
-
def between(self, column: str, low, high) -> "
|
|
340
|
+
def between(self, column: str, low: Any, high: Any) -> "Self":
|
|
281
341
|
self._wheres += (BetweenExpression(column, low, high, "BETWEEN"),)
|
|
282
342
|
return self
|
|
283
343
|
|
|
284
|
-
def not_between(self, column: str, low, high) -> "
|
|
344
|
+
def not_between(self, column: str, low: Any, high: Any) -> "Self":
|
|
285
345
|
self._wheres += (BetweenExpression(column, low, high, "NOT BETWEEN"),)
|
|
286
346
|
return self
|
|
287
347
|
|
|
288
|
-
def left_join(self, table: str, column1: str, equality: str, column2: str) -> "
|
|
348
|
+
def left_join(self, table: str, column1: str, equality: str, column2: str) -> "Self":
|
|
289
349
|
return self.join(table, column1, equality, column2, clause="left")
|
|
290
350
|
|
|
291
|
-
def right_join(self, table: str, column1: str, equality: str, column2: str) -> "
|
|
351
|
+
def right_join(self, table: str, column1: str, equality: str, column2: str) -> "Self":
|
|
292
352
|
# SQLite doesn't support RIGHT JOIN — use left join as fallback
|
|
293
353
|
return self.join(table, column1, equality, column2, clause="right")
|
|
294
354
|
|
|
295
|
-
def distinct(self) -> "
|
|
355
|
+
def distinct(self) -> "Self":
|
|
296
356
|
self._distinct = True
|
|
297
357
|
return self
|
|
298
358
|
|
|
@@ -322,27 +382,27 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
322
382
|
async def avg(self, column: str):
|
|
323
383
|
return await self.aggregate("AVG", column)
|
|
324
384
|
|
|
325
|
-
async def delete(self, column=None, value=None):
|
|
385
|
+
async def delete(self, column: str | None = None, value: Any = None):
|
|
326
386
|
if column is not None:
|
|
327
387
|
self.where(column, value)
|
|
328
388
|
self.set_action("delete")
|
|
329
389
|
sql = self.to_qmark()
|
|
330
390
|
return await self.connection.delete(sql, list(self.get_bindings()))
|
|
331
391
|
|
|
332
|
-
async def create(self, attributes: dict):
|
|
392
|
+
async def create(self, attributes: dict[str, Any]) -> "TModel":
|
|
333
393
|
model = self._model.new_model_instance(attributes)
|
|
334
394
|
await model.save()
|
|
335
395
|
|
|
336
396
|
return model
|
|
337
397
|
|
|
338
|
-
async def first_or_create(self, search: dict, attributes: dict | None = None):
|
|
398
|
+
async def first_or_create(self, search: dict[str, Any], attributes: dict[str, Any] | None = None) -> "TModel":
|
|
339
399
|
instance = await self.where(search).first()
|
|
340
400
|
if instance is not None:
|
|
341
401
|
return instance
|
|
342
402
|
|
|
343
403
|
return await self.create({**(attributes or {}), **search})
|
|
344
404
|
|
|
345
|
-
async def update_or_create(self, search: dict, attributes: dict | None = None):
|
|
405
|
+
async def update_or_create(self, search: dict[str, Any], attributes: dict[str, Any] | None = None) -> "TModel":
|
|
346
406
|
instance = await self.where(search).first()
|
|
347
407
|
if instance is not None:
|
|
348
408
|
if attributes:
|
|
@@ -351,7 +411,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
351
411
|
|
|
352
412
|
return await self.create({**(attributes or {}), **search})
|
|
353
413
|
|
|
354
|
-
async def insert(self, values: dict | list) -> int | None:
|
|
414
|
+
async def insert(self, values: dict[str, Any] | list[dict[str, Any]]) -> int | None:
|
|
355
415
|
self.set_action("bulk_create")
|
|
356
416
|
|
|
357
417
|
if not values:
|
|
@@ -379,7 +439,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
379
439
|
|
|
380
440
|
return await self.connection.insert_get_id(sql, bindings)
|
|
381
441
|
|
|
382
|
-
async def update(self, values: dict) -> int:
|
|
442
|
+
async def update(self, values: dict[str, Any]) -> int:
|
|
383
443
|
updates = [UpdateQueryExpression(col, val) for col, val in values.items()]
|
|
384
444
|
grammar = self.grammar()
|
|
385
445
|
sql = grammar._compile_update(query=self, values=updates, qmark=True).to_sql()
|
|
@@ -492,7 +552,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
492
552
|
# with .table(...) as usual.
|
|
493
553
|
return self.connection.query().table(self._table)
|
|
494
554
|
|
|
495
|
-
def invalid_operator(self, operator):
|
|
555
|
+
def invalid_operator(self, operator: Any) -> bool:
|
|
496
556
|
"""Determine whether an operator is not supported by the builder."""
|
|
497
557
|
return not isinstance(operator, str) or operator.lower() not in self.operators
|
|
498
558
|
|
|
@@ -538,20 +598,20 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
538
598
|
self._wheres += ((QueryExpression(column, operator, value, "value")),)
|
|
539
599
|
return self
|
|
540
600
|
|
|
541
|
-
def or_where(self, column, *args) -> "
|
|
601
|
+
def or_where(self, column: str, *args: Any) -> "Self":
|
|
542
602
|
operator, value = self._extract_operator_value(*args)
|
|
543
603
|
self._wheres += ((QueryExpression(column, operator, value, "value", keyword="or")),)
|
|
544
604
|
return self
|
|
545
605
|
|
|
546
|
-
def where_raw(self, expression: str, bindings=()) -> "
|
|
606
|
+
def where_raw(self, expression: str, bindings: tuple[Any, ...] = ()) -> "Self":
|
|
547
607
|
self._wheres += (QueryExpression(expression, "=", None, raw=True, bindings=bindings),)
|
|
548
608
|
return self
|
|
549
609
|
|
|
550
|
-
def or_where_raw(self, expression: str, bindings=()) -> "
|
|
610
|
+
def or_where_raw(self, expression: str, bindings: tuple[Any, ...] = ()) -> "Self":
|
|
551
611
|
self._wheres += (QueryExpression(expression, "=", None, raw=True, keyword="or", bindings=bindings),)
|
|
552
612
|
return self
|
|
553
613
|
|
|
554
|
-
def join(self, table: str, column1: str, equality: str, column2: str, clause: str = "join") -> "
|
|
614
|
+
def join(self, table: str, column1: str, equality: str, column2: str, clause: str = "join") -> "Self":
|
|
555
615
|
join_clause = JoinClause(table, clause=clause)
|
|
556
616
|
join_clause.on(column1, equality, column2)
|
|
557
617
|
self._joins += (join_clause,)
|
|
@@ -574,32 +634,32 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
574
634
|
)
|
|
575
635
|
return operator, column2
|
|
576
636
|
|
|
577
|
-
def where_column(self, column1: str, operator: str, column2: str | None = None) -> "
|
|
637
|
+
def where_column(self, column1: str, operator: str, column2: str | None = None) -> "Self":
|
|
578
638
|
"""Compare two columns (identifiers, never bound values), joined with AND."""
|
|
579
639
|
operator, column2 = self._normalize_where_column(operator, column2)
|
|
580
640
|
self._wheres += (QueryExpression(column1, operator, column2, "value_equals"),)
|
|
581
641
|
return self
|
|
582
642
|
|
|
583
|
-
def or_where_column(self, column1: str, operator: str, column2: str | None = None) -> "
|
|
643
|
+
def or_where_column(self, column1: str, operator: str, column2: str | None = None) -> "Self":
|
|
584
644
|
"""Compare two columns (identifiers, never bound values), joined with OR."""
|
|
585
645
|
operator, column2 = self._normalize_where_column(operator, column2)
|
|
586
646
|
self._wheres += (QueryExpression(column1, operator, column2, "value_equals", keyword="or"),)
|
|
587
647
|
return self
|
|
588
648
|
|
|
589
|
-
def when(self, condition, callback) -> "
|
|
649
|
+
def when(self, condition: Any, callback: Callable[["Self"], Any]) -> "Self":
|
|
590
650
|
if condition:
|
|
591
651
|
callback(self)
|
|
592
652
|
return self
|
|
593
653
|
|
|
594
|
-
def where_exists(self, builder: "QueryBuilder") -> "
|
|
654
|
+
def where_exists(self, builder: "QueryBuilder[Any]") -> "Self":
|
|
595
655
|
self._wheres += (QueryExpression(None, "EXISTS", SubSelectExpression(builder)),)
|
|
596
656
|
return self
|
|
597
657
|
|
|
598
|
-
def or_where_exists(self, builder: "QueryBuilder") -> "
|
|
658
|
+
def or_where_exists(self, builder: "QueryBuilder[Any]") -> "Self":
|
|
599
659
|
self._wheres += (QueryExpression(None, "EXISTS", SubSelectExpression(builder), keyword="or"),)
|
|
600
660
|
return self
|
|
601
661
|
|
|
602
|
-
def where_has(self, relation: str, callback=None) -> "
|
|
662
|
+
def where_has(self, relation: str, callback: Callable[..., Any] | None = None) -> "Self":
|
|
603
663
|
related = getattr(self._model.__class__, relation)
|
|
604
664
|
if callback:
|
|
605
665
|
related.query_where_exists(self, callback, method="where_exists")
|
|
@@ -607,7 +667,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
607
667
|
related.query_has(self, method="where_exists")
|
|
608
668
|
return self
|
|
609
669
|
|
|
610
|
-
def or_where_has(self, relation: str, callback=None) -> "
|
|
670
|
+
def or_where_has(self, relation: str, callback: Callable[..., Any] | None = None) -> "Self":
|
|
611
671
|
related = getattr(self._model.__class__, relation)
|
|
612
672
|
if callback:
|
|
613
673
|
related.query_where_exists(self, callback, method="or_where_exists")
|
|
@@ -616,7 +676,7 @@ class QueryBuilder(EagerLoadMixin, SupportMixin, Generic[TModel]):
|
|
|
616
676
|
return self
|
|
617
677
|
|
|
618
678
|
@classmethod
|
|
619
|
-
def clean_bindings(cls, values):
|
|
679
|
+
def clean_bindings(cls, values: dict[str, Any] | list[dict[str, Any]]) -> list[Any]:
|
|
620
680
|
if isinstance(values, dict):
|
|
621
681
|
values = [values]
|
|
622
682
|
return [val for row in values for val in row.values()]
|