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