From 9baaf3c5a5a8c51d892a08c59f5b24abef02846b Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:34:40 -0700 Subject: [PATCH 01/10] feat: add FastAPIConfig for server settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce FastAPIConfig dataclass with host, port, reload, reload_dirs, and reload_excludes fields — all env-var backed. FastAPIProvider registers the config automatically; ServeCommand resolves settings via CLI flag > config > built-in default. Co-Authored-By: Claude Sonnet 4.6 --- .../src/fastapi_startkit/fastapi/__init__.py | 3 +- .../fastapi/commands/serve_command.py | 31 ++++++++++++------- .../fastapi/config/__init__.py | 3 ++ .../fastapi/config/fastapi.py | 22 +++++++++++++ .../fastapi/providers/fastapi_provider.py | 6 ++++ fastapi_startkit/uv.lock | 2 +- 6 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 fastapi_startkit/src/fastapi_startkit/fastapi/config/__init__.py create mode 100644 fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/__init__.py b/fastapi_startkit/src/fastapi_startkit/fastapi/__init__.py index b19ad15c..254b5130 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/__init__.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/__init__.py @@ -1,5 +1,6 @@ from .providers.fastapi_provider import FastAPIProvider from .routers.router import Router from .requests.model import RequestModel +from .config import FastAPIConfig -__all__ = ["FastAPIProvider", "Router", "RequestModel"] +__all__ = ["FastAPIProvider", "Router", "RequestModel", "FastAPIConfig"] diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py b/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py index 9ba13166..e42127cd 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py @@ -11,22 +11,22 @@ class ServeCommand(Command): "port", "p", flag=False, - default="8000", - description="The port to serve the application on", + default=None, + description="The port to serve the application on (overrides fastapi config)", ), option( "host", None, flag=False, - default="127.0.0.1", - description="The host to bind to", + default=None, + description="The host to bind to (overrides fastapi config)", ), option( "reload", "r", flag=False, - default=True, - description="Enable auto-reload on code changes", + default=None, + description="Enable auto-reload on code changes (overrides fastapi config)", ), option( "app", @@ -39,12 +39,20 @@ class ServeCommand(Command): def handle(self): import uvicorn + from fastapi_startkit.configuration.config import Config from fastapi_startkit.container import Container - port = int(self.option("port")) - host = self.option("host") + # Resolve server settings: CLI flag > fastapi config > built-in defaults + cfg_host = Config.get("fastapi.host", "127.0.0.1") + cfg_port = Config.get("fastapi.port", 8000) + cfg_reload = Config.get("fastapi.reload", True) + cfg_reload_dirs = Config.get("fastapi.reload_dirs", []) or [] + cfg_reload_excludes = Config.get("fastapi.reload_excludes", ["*.log", "tests/*"]) or [] + + host = self.option("host") or cfg_host + port = int(self.option("port") or cfg_port) + reload = cfg_reload if self.option("reload") is None else self.option("reload") app = self.option("app") - reload = self.option("reload") exist = self.is_app_exist() @@ -59,11 +67,12 @@ def handle(self): kwargs.update( { "app": app, - "reload": reload, "factory": True, - "reload_excludes": ["*.log", "tests/*"], + "reload_excludes": cfg_reload_excludes, } ) + if cfg_reload_dirs: + kwargs["reload_dirs"] = cfg_reload_dirs self.line( f"Starting Uvicorn server on {host}:{port} [{app}]..." diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/config/__init__.py b/fastapi_startkit/src/fastapi_startkit/fastapi/config/__init__.py new file mode 100644 index 00000000..6ba558e7 --- /dev/null +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/config/__init__.py @@ -0,0 +1,3 @@ +from .fastapi import FastAPIConfig + +__all__ = ["FastAPIConfig"] diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py b/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py new file mode 100644 index 00000000..1ae81dd6 --- /dev/null +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py @@ -0,0 +1,22 @@ +import dataclasses + +from fastapi_startkit.environment import env + + +@dataclasses.dataclass +class FastAPIConfig: + """Server configuration for the uvicorn/FastAPI serve command. + + All fields can be overridden via environment variables or by publishing a + ``config/fastapi.py`` file in the application root. + """ + + host: str = dataclasses.field(default_factory=lambda: env("APP_HOST", "127.0.0.1")) + port: int = dataclasses.field(default_factory=lambda: env("APP_PORT", 8000)) + reload: bool = dataclasses.field(default_factory=lambda: env("APP_RELOAD", True)) + reload_dirs: list = dataclasses.field( + default_factory=lambda: [] + ) + reload_excludes: list = dataclasses.field( + default_factory=lambda: ["*.log", "tests/*"] + ) diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py b/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py index 2f062e06..a723c005 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py @@ -2,12 +2,18 @@ from fastapi import FastAPI from fastapi_startkit.fastapi.commands import ServeCommand +from fastapi_startkit.fastapi.config import FastAPIConfig from fastapi_startkit.providers import Provider class FastAPIProvider(Provider): def register(self) -> None: """Create a FastAPI instance and register routers.""" + # Register default FastAPI server config if not already set by user config + config = self.app.make("config") + if not config.has("fastapi"): + config.set("fastapi", FastAPIConfig()) + fastapi = FastAPI( title="Jobins AI Agent (LangChain)", version="1.0.0", diff --git a/fastapi_startkit/uv.lock b/fastapi_startkit/uv.lock index 2065bd39..c6d946a1 100644 --- a/fastapi_startkit/uv.lock +++ b/fastapi_startkit/uv.lock @@ -443,7 +443,7 @@ wheels = [ [[package]] name = "fastapi-startkit" -version = "0.21.0" +version = "0.22.0" source = { editable = "." } dependencies = [ { name = "cleo" }, From 87fdb24ae43050f36439d45889c2b32f551c1af5 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:37:32 -0700 Subject: [PATCH 02/10] feat: publish FastAPIConfig via provider:publish Register config/fastapi.py as a publishable resource so users can run `artisan provider:publish --provider=fastapi` to scaffold a customisable config file in their application root. Co-Authored-By: Claude Sonnet 4.6 --- .../fastapi_startkit/fastapi/providers/fastapi_provider.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py b/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py index a723c005..ebf1619e 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py @@ -22,9 +22,16 @@ def register(self) -> None: self.app.use_fastapi(fastapi) def boot(self): + import os + self.commands([ServeCommand]) self._register_exception_handlers() + source = os.path.abspath( + os.path.join(os.path.dirname(__file__), "../config/fastapi.py") + ) + self.publishes({source: "config/fastapi.py"}) + def _register_exception_handlers(self): """Wire exception_manager as a catch-all handler for all exceptions.""" from fastapi import HTTPException From a0ac320a01c8b71f09f327397943456ed1e05cf0 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:40:04 -0700 Subject: [PATCH 03/10] feat: typo fix --- fastapi_startkit/src/fastapi_startkit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi_startkit/src/fastapi_startkit/__init__.py b/fastapi_startkit/src/fastapi_startkit/__init__.py index 892fc268..9660424d 100644 --- a/fastapi_startkit/src/fastapi_startkit/__init__.py +++ b/fastapi_startkit/src/fastapi_startkit/__init__.py @@ -2,4 +2,4 @@ from .console import ConsoleApplication from .configuration.config import Config -__all__ = ["Application", "Config"] +__all__ = ["Application", "ConsoleApplication", "Config"] From ecc2a30d94ce02014d9e9726ff475e6c2bf4b370 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:50:15 -0700 Subject: [PATCH 04/10] fix: exclude logs and node_modules from reload watcher by default Log file writes were triggering uvicorn reloads on every request. Add node_modules/*, logs/*, and storage/logs/* to the default reload_excludes so only real source changes trigger a restart. Co-Authored-By: Claude Sonnet 4.6 --- example/fastapi-app/config/fastapi.py | 22 +++++++++++++++++++ .../fastapi/config/fastapi.py | 8 ++++++- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 example/fastapi-app/config/fastapi.py diff --git a/example/fastapi-app/config/fastapi.py b/example/fastapi-app/config/fastapi.py new file mode 100644 index 00000000..79fb21b6 --- /dev/null +++ b/example/fastapi-app/config/fastapi.py @@ -0,0 +1,22 @@ +import dataclasses + +from fastapi_startkit.environment import env + + +@dataclasses.dataclass +class FastAPIConfig: + host: str = dataclasses.field(default_factory=lambda: env("APP_HOST", "127.0.0.1")) + port: int = dataclasses.field(default_factory=lambda: env("APP_PORT", 8000)) + reload: bool = dataclasses.field(default_factory=lambda: env("APP_RELOAD", True)) + reload_dirs: list = dataclasses.field( + default_factory=lambda: [] + ) + reload_excludes: list = dataclasses.field( + default_factory=lambda: [ + "*.log", + "tests/*", + "node_modules/*", + "logs/*", + "storage/logs/*", + ] + ) diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py b/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py index 1ae81dd6..f277de10 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py @@ -18,5 +18,11 @@ class FastAPIConfig: default_factory=lambda: [] ) reload_excludes: list = dataclasses.field( - default_factory=lambda: ["*.log", "tests/*"] + default_factory=lambda: [ + "*.log", + "tests/*", + "node_modules/*", + "logs/*", + "storage/logs/*", + ] ) From 6d5b1e777b48e28d97d5eb9719c1b8d15b4a09da Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:51:26 -0700 Subject: [PATCH 05/10] fix: merge outer FastAPIConfig via resolve_config like ViteProvider The manual config.has/config.set approach ignored self.config entirely, so user-provided config passed as (FastAPIProvider, FastAPIConfig) had no effect. Now uses resolve_config + merge_config_from with provider_key = "fastapi", matching the ViteProvider pattern. Co-Authored-By: Claude Sonnet 4.6 --- .../fastapi/providers/fastapi_provider.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py b/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py index ebf1619e..79eadab5 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/providers/fastapi_provider.py @@ -7,12 +7,12 @@ class FastAPIProvider(Provider): + provider_key = "fastapi" + def register(self) -> None: """Create a FastAPI instance and register routers.""" - # Register default FastAPI server config if not already set by user config - config = self.app.make("config") - if not config.has("fastapi"): - config.set("fastapi", FastAPIConfig()) + config = self.resolve_config(FastAPIConfig) + self.merge_config_from(config, self.provider_key) fastapi = FastAPI( title="Jobins AI Agent (LangChain)", From 60734a1d37bdb26cbbf5d46a9a91affe1c2632ca Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:53:57 -0700 Subject: [PATCH 06/10] chore: sync example reload_excludes to use *.log glob MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Matches the framework default — *.log covers all log files regardless of location, cleaner than listing specific directories. Co-Authored-By: Claude Sonnet 4.6 --- example/fastapi-app/config/fastapi.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/fastapi-app/config/fastapi.py b/example/fastapi-app/config/fastapi.py index 79fb21b6..7c027f2c 100644 --- a/example/fastapi-app/config/fastapi.py +++ b/example/fastapi-app/config/fastapi.py @@ -16,7 +16,5 @@ class FastAPIConfig: "*.log", "tests/*", "node_modules/*", - "logs/*", - "storage/logs/*", ] ) From 2bde34d0618d940636f91aa1d92f2985a59d3a84 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:56:16 -0700 Subject: [PATCH 07/10] refactor: use None fallback for reload_dirs/excludes in ServeCommand FastAPIConfig is the single source of truth for defaults. Config.get() fallbacks now return None so uvicorn uses its own defaults when nothing is configured, rather than duplicating hardcoded values in the command. Co-Authored-By: Claude Sonnet 4.6 --- .../fastapi/commands/serve_command.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py b/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py index e42127cd..e69befe3 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py @@ -1,3 +1,4 @@ +from dumpdie import dd from fastapi_startkit.console.command import Command from cleo.helpers import option @@ -39,15 +40,15 @@ class ServeCommand(Command): def handle(self): import uvicorn - from fastapi_startkit.configuration.config import Config + from fastapi_startkit import Config from fastapi_startkit.container import Container - # Resolve server settings: CLI flag > fastapi config > built-in defaults + # Resolve server settings: CLI flag > fastapi config > uvicorn default (None) cfg_host = Config.get("fastapi.host", "127.0.0.1") cfg_port = Config.get("fastapi.port", 8000) cfg_reload = Config.get("fastapi.reload", True) - cfg_reload_dirs = Config.get("fastapi.reload_dirs", []) or [] - cfg_reload_excludes = Config.get("fastapi.reload_excludes", ["*.log", "tests/*"]) or [] + cfg_reload_dirs = Config.get("fastapi.reload_dirs") or None + cfg_reload_excludes = Config.get("fastapi.reload_excludes") or None host = self.option("host") or cfg_host port = int(self.option("port") or cfg_port) @@ -68,11 +69,12 @@ def handle(self): { "app": app, "factory": True, - "reload_excludes": cfg_reload_excludes, } ) - if cfg_reload_dirs: + if cfg_reload_dirs is not None: kwargs["reload_dirs"] = cfg_reload_dirs + if cfg_reload_excludes is not None: + kwargs["reload_excludes"] = cfg_reload_excludes self.line( f"Starting Uvicorn server on {host}:{port} [{app}]..." From 5461101535050d122b5b3e03885da34a9aa54e94 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:57:47 -0700 Subject: [PATCH 08/10] fix: default reload_dirs to None so uvicorn watches all directories An empty list was preventing uvicorn from watching anything useful. None lets uvicorn apply its own default (current working directory), consistent with the None-fallback pattern in ServeCommand. Co-Authored-By: Claude Sonnet 4.6 --- example/fastapi-app/config/fastapi.py | 4 +--- .../src/fastapi_startkit/fastapi/config/fastapi.py | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/example/fastapi-app/config/fastapi.py b/example/fastapi-app/config/fastapi.py index 7c027f2c..ea734791 100644 --- a/example/fastapi-app/config/fastapi.py +++ b/example/fastapi-app/config/fastapi.py @@ -8,9 +8,7 @@ class FastAPIConfig: host: str = dataclasses.field(default_factory=lambda: env("APP_HOST", "127.0.0.1")) port: int = dataclasses.field(default_factory=lambda: env("APP_PORT", 8000)) reload: bool = dataclasses.field(default_factory=lambda: env("APP_RELOAD", True)) - reload_dirs: list = dataclasses.field( - default_factory=lambda: [] - ) + reload_dirs: list | None = None reload_excludes: list = dataclasses.field( default_factory=lambda: [ "*.log", diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py b/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py index f277de10..f85534c4 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/config/fastapi.py @@ -14,15 +14,11 @@ class FastAPIConfig: host: str = dataclasses.field(default_factory=lambda: env("APP_HOST", "127.0.0.1")) port: int = dataclasses.field(default_factory=lambda: env("APP_PORT", 8000)) reload: bool = dataclasses.field(default_factory=lambda: env("APP_RELOAD", True)) - reload_dirs: list = dataclasses.field( - default_factory=lambda: [] - ) + reload_dirs: list | None = None reload_excludes: list = dataclasses.field( default_factory=lambda: [ "*.log", "tests/*", "node_modules/*", - "logs/*", - "storage/logs/*", ] ) From e23e976155d73099910abd6de5a2a09078abe2c8 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 16:59:00 -0700 Subject: [PATCH 09/10] feat: imrovements --- example/fastapi-app/bootstrap/application.py | 3 +- example/fastapi-app/pyproject.toml | 5 +++ example/fastapi-app/routes/api.py | 2 +- example/fastapi-app/uv.lock | 36 +++++++++++++++++-- .../fastapi/commands/serve_command.py | 1 - 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/example/fastapi-app/bootstrap/application.py b/example/fastapi-app/bootstrap/application.py index 3d4555ba..deda77d9 100644 --- a/example/fastapi-app/bootstrap/application.py +++ b/example/fastapi-app/bootstrap/application.py @@ -3,11 +3,12 @@ from fastapi_startkit import Application from fastapi_startkit.logging import LogProvider from providers.fastapi_provider import FastAPIProvider +from config.fastapi import FastAPIConfig app: Application = Application( base_path=str(Path.cwd()), # This always gives path relative to the execution. providers=[ LogProvider, - FastAPIProvider, + (FastAPIProvider, FastAPIConfig), ] ) diff --git a/example/fastapi-app/pyproject.toml b/example/fastapi-app/pyproject.toml index ba316274..5334f80d 100644 --- a/example/fastapi-app/pyproject.toml +++ b/example/fastapi-app/pyproject.toml @@ -10,3 +10,8 @@ dependencies = [ [tool.uv.sources] fastapi-startkit = { path = "../../fastapi_startkit", editable = true } + +[dependency-groups] +dev = [ + "dumpdie>=1.5.0", +] diff --git a/example/fastapi-app/routes/api.py b/example/fastapi-app/routes/api.py index 84716814..149ed599 100644 --- a/example/fastapi-app/routes/api.py +++ b/example/fastapi-app/routes/api.py @@ -9,7 +9,7 @@ async def index(): Logger.info("Welcome to FastAPI StartKit!") Logger.info("Version: 1.0.0") Logger.info("Docs: /docs") - Logger.log("debug", "Debugging the application.") + Logger.log("debug", "Debugging the application!") return { "message": "Welcome to FastAPI StartKit!", "version": "1.0.0", diff --git a/example/fastapi-app/uv.lock b/example/fastapi-app/uv.lock index 99d33bc5..4565ce5f 100644 --- a/example/fastapi-app/uv.lock +++ b/example/fastapi-app/uv.lock @@ -192,6 +192,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/91/e0d457ee03ec33d79ee2cd8d212debb1bc21dfb99728ae35efdb5832dc22/dotty_dict-1.3.1-py3-none-any.whl", hash = "sha256:5022d234d9922f13aa711b4950372a06a6d64cb6d6db9ba43d0ba133ebfce31f", size = 7014, upload-time = "2022-07-09T18:50:55.058Z" }, ] +[[package]] +name = "dumpdie" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/61/7ea2d95d55806d9e812e6a38880a479adb40a874c95c745a3a896e844998/dumpdie-1.5.0.tar.gz", hash = "sha256:0267fc9409a10fb0c3e023ba95b109df2108b72f5fb7f98e3cc68a3f825a3d46", size = 88462, upload-time = "2026-03-19T00:39:54.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/40/e7937be0300078626ff929e1d7856ebe3237aa03ad338d0c077c6cda301d/dumpdie-1.5.0-py3-none-any.whl", hash = "sha256:df487693dacfbe38fb2a3229e4734479e046c2485cb7ba723f3e7e5012da1087", size = 3369, upload-time = "2026-03-19T00:39:53.436Z" }, +] + [[package]] name = "email-validator" version = "2.3.0" @@ -238,9 +247,17 @@ dependencies = [ { name = "fastapi-startkit", extra = ["fastapi"] }, ] +[package.dev-dependencies] +dev = [ + { name = "dumpdie" }, +] + [package.metadata] requires-dist = [{ name = "fastapi-startkit", extras = ["fastapi"], editable = "../../fastapi_startkit" }] +[package.metadata.requires-dev] +dev = [{ name = "dumpdie", specifier = ">=1.5.0" }] + [[package]] name = "fastapi-cli" version = "0.0.24" @@ -282,7 +299,7 @@ wheels = [ [[package]] name = "fastapi-startkit" -version = "0.13.6" +version = "0.22.0" source = { editable = "../../fastapi_startkit" } dependencies = [ { name = "cleo" }, @@ -297,6 +314,7 @@ dependencies = [ [package.optional-dependencies] fastapi = [ { name = "fastapi", extra = ["standard"] }, + { name = "itsdangerous" }, ] [package.metadata] @@ -310,19 +328,24 @@ requires-dist = [ { name = "faker", marker = "extra == 'database'", specifier = ">=40.13.0" }, { name = "fastapi", extras = ["standard"], marker = "extra == 'fastapi'", specifier = ">=0.124.4,<0.125.0" }, { name = "inflection", specifier = ">=0.5.1" }, + { name = "itsdangerous", marker = "extra == 'fastapi'", specifier = ">=2.2.0" }, + { name = "jinja2", marker = "extra == 'inertia'", specifier = ">=3.1" }, { name = "jinja2", marker = "extra == 'vite'", specifier = ">=3.1" }, + { name = "markupsafe", marker = "extra == 'inertia'", specifier = ">=2.0" }, { name = "pendulum", specifier = ">=3.1.0,<4.0.0" }, { name = "pydantic", specifier = ">=2.12.5" }, { name = "requests", specifier = ">=2.32.5,<3.0.0" }, { name = "sqlalchemy", extras = ["asyncio"], marker = "extra == 'database'", specifier = ">=2.0.38" }, ] -provides-extras = ["fastapi", "database", "sqlite", "postgres", "mysql", "vite"] +provides-extras = ["fastapi", "database", "sqlite", "postgres", "mysql", "vite", "inertia"] [package.metadata.requires-dev] dev = [ { name = "dumpdie", specifier = ">=1.5.0" }, + { name = "itsdangerous", specifier = ">=2.2.0" }, { name = "pytest", specifier = ">=9.0.3" }, { name = "pytest-asyncio", specifier = ">=1.3.0" }, + { name = "ruff", specifier = ">=0.9.0" }, { name = "twine", specifier = ">=6.2.0" }, ] @@ -482,6 +505,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/91/aa6bde563e0085a02a435aa99b49ef75b0a4b062635e606dab23ce18d720/inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2", size = 9454, upload-time = "2020-08-22T08:16:27.816Z" }, ] +[[package]] +name = "itsdangerous" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, +] + [[package]] name = "jinja2" version = "3.1.6" diff --git a/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py b/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py index e69befe3..d24f9e69 100644 --- a/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py +++ b/fastapi_startkit/src/fastapi_startkit/fastapi/commands/serve_command.py @@ -1,4 +1,3 @@ -from dumpdie import dd from fastapi_startkit.console.command import Command from cleo.helpers import option From 573e1a2a02943ed37649760e70bc2b999b8d6bd3 Mon Sep 17 00:00:00 2001 From: Bedram Tamang Date: Sat, 16 May 2026 17:03:39 -0700 Subject: [PATCH 10/10] feat: fastapi configurations --- bin/test.sh | 3 ++- example/config-app/uv.lock | 2 +- example/database-app/uv.lock | 2 +- fastapi_startkit/pyproject.toml | 2 +- fastapi_startkit/uv.lock | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bin/test.sh b/bin/test.sh index 7cfbdece..c2286ba2 100755 --- a/bin/test.sh +++ b/bin/test.sh @@ -5,10 +5,11 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # ── Start MySQL via Docker Compose ──────────────────────────────────────────── echo "Starting test services..." +docker compose -f "$ROOT/docker-compose.yml" down --remove-orphans docker compose -f "$ROOT/docker-compose.yml" up -d --wait # Ensure MySQL is torn down on exit (even if tests fail) -trap 'echo "Stopping test services..."; docker compose -f "$ROOT/docker-compose.test.yml" down' EXIT +trap 'echo "Stopping test services..."; docker compose -f "$ROOT/docker-compose.yml" down' EXIT # ── Common DB env vars (match docker-compose.test.yml) ─────────────────────── export DB_HOST=127.0.0.1 diff --git a/example/config-app/uv.lock b/example/config-app/uv.lock index e2c55a3d..b5ded1c8 100644 --- a/example/config-app/uv.lock +++ b/example/config-app/uv.lock @@ -162,7 +162,7 @@ wheels = [ [[package]] name = "fastapi-startkit" -version = "0.21.0" +version = "0.23.0" source = { editable = "../../fastapi_startkit" } dependencies = [ { name = "cleo" }, diff --git a/example/database-app/uv.lock b/example/database-app/uv.lock index 5a426a93..79b46c58 100644 --- a/example/database-app/uv.lock +++ b/example/database-app/uv.lock @@ -498,7 +498,7 @@ wheels = [ [[package]] name = "fastapi-startkit" -version = "0.21.0" +version = "0.23.0" source = { editable = "../../fastapi_startkit" } dependencies = [ { name = "cleo" }, diff --git a/fastapi_startkit/pyproject.toml b/fastapi_startkit/pyproject.toml index d2fca816..26f9079c 100644 --- a/fastapi_startkit/pyproject.toml +++ b/fastapi_startkit/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "fastapi-startkit" -version = "0.22.0" +version = "0.23.0" description = "Fastapi Starter kit components" authors = [ {name = "Bedram Tamang", email = "tmgbedu@gmail.com"} diff --git a/fastapi_startkit/uv.lock b/fastapi_startkit/uv.lock index c6d946a1..f2d3b028 100644 --- a/fastapi_startkit/uv.lock +++ b/fastapi_startkit/uv.lock @@ -443,7 +443,7 @@ wheels = [ [[package]] name = "fastapi-startkit" -version = "0.22.0" +version = "0.23.0" source = { editable = "." } dependencies = [ { name = "cleo" },