Skip to content

[RELEASE, DOCS, FIX] Fix fastkit init flow, address security advisories & review findings#40

Merged
bnbong merged 7 commits intomainfrom
dev
Apr 17, 2026
Merged

[RELEASE, DOCS, FIX] Fix fastkit init flow, address security advisories & review findings#40
bnbong merged 7 commits intomainfrom
dev

Conversation

@bnbong
Copy link
Copy Markdown
Owner

@bnbong bnbong commented Apr 17, 2026

Requesting Merging

Description

Fix a batch of review findings in the interactive fastkit init flow and related generators.
The P1 items include two data-loss bugs (workspace deletion on in-place init failure; INI content overwriting tests/conftest.py) and invalid Poetry TOML output for dependencies with extras.
P2/P3 items round out correctness for generated projects (async SQLite engine, Docker exec-form CMD, single-module template placeholder).
Also updates the FAQ to match actual interactive-mode behavior.

Type of Change

  • BUG FIX
  • ADDING NEW TEMPLATE
  • FEATURE ADDED/UPDATED
  • HOTFIX
  • DELETING UNNECESSARY FEATURES
  • DOCUMENTATION & DEVOPS
  • Etc..

Test Environment

  • macOS (Darwin 25.3.0), zsh
  • Python 3.12, uv for test/runtime
  • uv run pytest tests/ — full suite
  • uv run mkdocs build — docs build

Major Changes

[P1] Prevent workspace deletion on init failure

  • src/fastapi_fastkit/cli.py
  • Replaced raw shutil.rmtree(project_dir, ignore_errors=True) in both the interactive and non-interactive init except blocks with a new _cleanup_failed_project() helper.
  • Helper no-ops for in-place deploys (create_project_folder=False) and refuses to remove a path equal to USER_WORKSPACE, so only a freshly created project folder is cleaned up.

[P1] Write generated pytest config to pytest.ini (not tests/conftest.py)

  • src/fastapi_fastkit/cli.py
  • The interactive flow was writing INI content ([pytest] …) into tests/conftest.py, overwriting the template fixture module with invalid Python. The generator output now lands in pytest.ini at the project root and the template conftest.py is preserved.

[P1] Emit valid Poetry TOML for dependencies with extras

  • src/fastapi_fastkit/backend/package_managers/poetry_manager.py
  • redis[hiredis], python-jose[cryptography], fastapi-users[sqlalchemy] and similar specs are now converted to Poetry's inline-table form, e.g. redis = {version = "*", extras = ["hiredis"]}. Previously these were emitted as bare keys, which produced invalid TOML and broke poetry install.

[P2] Include aiosqlite in the SQLite interactive stack

  • src/fastapi_fastkit/core/settings.py
  • PACKAGE_CATALOG["database"]["SQLite"] now includes aiosqlite so generated projects can actually create the sqlite+aiosqlite:///./app.db async engine the generator emits.

[P2] Use valid exec-form CMD in generated Dockerfiles

  • src/fastapi_fastkit/backend/project_builder/config_generator.py
  • Switched the generated CMD from single quotes (Docker shell form) to double quotes so it is valid JSON exec form:
    CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"].

[P3] Replace <project_name> in single-module template main.py

  • src/fastapi_fastkit/backend/main.py
  • inject_project_metadata() now also processes the template main.py via a new _process_main_file() helper, substituting the <project_name> placeholder. Single-module generated projects no longer keep the literal <project_name> in the FastAPI app title.

Docs: FAQ — interactive-mode generation claims

  • docs/en/reference/faq.md
  • Bullets under "the interactive mode automatically generates" rewritten to be conditionally accurate:
    • Database/auth config files are generated only for options that support code generation (PostgreSQL/MySQL/SQLite/MongoDB; JWT/FastAPI-Users); other options install packages only.
    • Deployment files match the selected deployment option (Dockerfile for Docker, docker-compose.yml for docker-compose).
    • Test configuration depends on the selected testing option (coverage included only for Coverage / Advanced).

Tests

  • tests/test_backends/test_package_managers.pytest_generate_dependency_file_with_extras_is_valid_toml parses the generated pyproject.toml with tomllib and asserts inline-table form for extras.
  • tests/test_backends/test_project_builder_config_generator.py — new TestGenerateDockerFiles::test_generated_dockerfile_uses_exec_form_cmd parses the CMD line as a JSON array.
  • tests/test_backends/test_main.pytest_inject_project_metadata_replaces_placeholder_in_main covers the single-module title substitution.
  • tests/test_core.pytest_settings_sqlite_stack_includes_aiosqlite guards the SQLite catalog entry.
  • tests/test_cli_operations/test_cli_extended.py — new TestCleanupFailedProject class with 3 cases covering in-place workspace safety, folder-mode cleanup, and a defensive workspace-equals-project guard.
  • tests/test_cli_operations/test_cli_interactive_integration.py — extended to assert pytest.ini exists and tests/conftest.py (if present) does not contain INI content.

Results

  • uv run pytest tests/ → 520 passed (495 core + 25 template suites).
  • uv run mkdocs build → built successfully across all language variants.
  • uv run ruff check src/fastapi_fastkit/cli.py → clean (E402 / F541 warnings on the edited file fixed).

Screenshots (optional)

N/A

Etc

  • Minor pre-existing Ruff warnings on cli.py were cleaned up as part of the edit (import ordering for __version__; stray f-prefix on literals without placeholders) — behavior-preserving.
  • No template behavior changed beyond main.py placeholder substitution and the default destination for the generated pytest config.

@bnbong bnbong requested a review from Copilot April 17, 2026 05:50
@bnbong bnbong self-assigned this Apr 17, 2026
@bnbong bnbong added bug Something isn't working template Add or editing a FastAPI template fix Fix or improve source codes dependencies Pull requests that update a dependency file python Pull requests that update python code labels Apr 17, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 17, 2026

Codecov Report

❌ Patch coverage is 97.29730% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...fastkit/backend/package_managers/poetry_manager.py 97.61% 1 Missing ⚠️
src/fastapi_fastkit/cli.py 92.85% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses multiple correctness and safety issues in the fastkit init interactive flow and related generators, including preventing destructive cleanup on failures and fixing generated output formats/config files that could break downstream tooling.

Changes:

  • Adds safer failed-init cleanup logic and fixes where pytest configuration is written during interactive init.
  • Fixes generators/output: Poetry TOML emission for dependencies with extras, SQLite stack deps, Dockerfile CMD, and single-module main.py placeholder substitution.
  • Updates documentation and bumps dev/docs dependency floors/locks; adds/extends regression tests for the above behaviors.

Reviewed changes

Copilot reviewed 20 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
uv.lock Updates locked dependency versions and adds new dev/docs dependencies.
pyproject.toml Updates optional dependency minimums (security floors) for dev/docs/translation extras.
requirements.txt Updates generated dev requirements pins.
requirements-docs.txt Updates generated docs requirements pins.
src/fastapi_fastkit/init.py Bumps package version to 1.2.1.
src/fastapi_fastkit/cli.py Introduces _cleanup_failed_project() and writes generated pytest config to pytest.ini.
src/fastapi_fastkit/core/settings.py Adds aiosqlite to SQLite interactive package catalog.
src/fastapi_fastkit/backend/package_managers/poetry_manager.py Emits Poetry inline-table dependencies for extras.
src/fastapi_fastkit/backend/project_builder/config_generator.py Generates Dockerfile CMD in JSON exec form.
src/fastapi_fastkit/backend/main.py Processes main.py to replace <project_name> placeholder in single-module templates.
tests/test_core.py Adds test guarding aiosqlite presence in SQLite catalog.
tests/test_utils.py Reformats test fixture string writing.
tests/test_cli_operations/test_cli_interactive_integration.py Asserts pytest config lands in pytest.ini and doesn’t overwrite tests/conftest.py.
tests/test_cli_operations/test_cli_extended.py Adds regression tests for safe cleanup on init failure; reformats fixture strings.
tests/test_backends/test_project_builder_config_generator.py Adds Dockerfile CMD exec-form test.
tests/test_backends/test_package_managers.py Adds TOML parsing test for Poetry deps with extras.
tests/test_backends/test_main.py Adds test for <project_name> replacement in main.py; reformats fixture strings.
docs/en/reference/faq.md Updates interactive-mode FAQ claims and CLI usage examples.
docs/en/contributing/development-setup.md Updates development setup instructions and formatting.
docs/en/contributing/translation-guide.md Clarifies “Approve and Merge” section is for maintainers.
docs/en/contributing/template-creation-guide.md Improves admonition formatting and minor wording.
docs/en/contributing/code-guidelines.md Updates example class naming and adds import-organization note.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/fastapi_fastkit/backend/package_managers/poetry_manager.py Outdated
Comment thread docs/en/contributing/development-setup.md
bnbong and others added 2 commits April 17, 2026 15:05
Add regression tests for the three uncovered patch regions reported by Codecov:
_process_main_file OSError handling, _cleanup_failed_project nonexistent-path
branch, and the interactive init except block that invokes the cleanup helper.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…_file

The previous implementation only handled pinned (`==`) versions; other pip
specifiers (`>=`, `~=`, `<=`, `<`, `>`, `!=`, `===`) and environment markers
(`; sys_platform != 'win32'`) were concatenated into the TOML key, producing
invalid `pyproject.toml` that `poetry install` could not parse.

Introduce `_parse_pip_requirement` to split name, extras, version specifier,
and environment marker, and emit Poetry-compatible TOML — inline tables when
extras or markers are present, bare version strings otherwise.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@bnbong bnbong changed the title Dev [DOCS, FIX] Fix fastkit init flow, address security advisories & review findings Apr 17, 2026
@bnbong bnbong requested a review from Copilot April 17, 2026 06:13
@bnbong bnbong changed the title [DOCS, FIX] Fix fastkit init flow, address security advisories & review findings [RELEASE, DOCS, FIX] Fix fastkit init flow, address security advisories & review findings Apr 17, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 23 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 500 to 507
# Generate test configuration if testing selected
testing_type = config.get("testing", "None")
if testing_type != "None":
test_config_content = generator.generate_test_config()
if test_config_content:
test_config_path = os.path.join(project_dir, "tests", "conftest.py")
os.makedirs(os.path.dirname(test_config_path), exist_ok=True)
test_config_path = os.path.join(project_dir, "pytest.ini")
with open(test_config_path, "w") as f:
f.write(test_config_content)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generator.generate_test_config() can include a [coverage:run] section, but writing that content into pytest.ini won’t be picked up by coverage.py / pytest-cov by default (coverage reads .coveragerc, setup.cfg, tox.ini, or pyproject.toml). If you want the generated omit/source settings to take effect, consider emitting a separate .coveragerc (or [tool.coverage.*] in pyproject.toml) and keep pytest.ini limited to [pytest] settings.

Copilot uses AI. Check for mistakes.

**What This Means for You:**
- 🚀 **No Additional Test Files**: Your template is tested automatically
- 🚀 **No Additional Test Files at `FastAPI-fastkit`'s main source testcases**: Your template is tested automatically
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor wording issue: “testcases” should be “test cases”.

Suggested change
- 🚀 **No Additional Test Files at `FastAPI-fastkit`'s main source testcases**: Your template is tested automatically
- 🚀 **No Additional Test Files at `FastAPI-fastkit`'s main source test cases**: Your template is tested automatically

Copilot uses AI. Check for mistakes.
Comment on lines +235 to +242
if not version_spec:
version_str = "*"
elif version_spec.startswith("=="):
# Poetry treats a bare version as a pin; keep the old
# formatting to avoid churn in generated files.
version_str = version_spec[2:].strip()
else:
version_str = version_spec
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_dependency_file() treats any version spec starting with == as a pinned version and strips only two leading =. This breaks PEP 440 === requirements (e.g. pkg===1.2.3 becomes =1.2.3) despite _PEP440_OPERATORS explicitly including ===. Handle === separately (don’t strip) so triple-equals requirements round-trip correctly.

Copilot uses AI. Check for mistakes.
@bnbong bnbong merged commit f914c70 into main Apr 17, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working dependencies Pull requests that update a dependency file fix Fix or improve source codes python Pull requests that update python code template Add or editing a FastAPI template

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants