Skip to content

Conversation

@cofin
Copy link
Member

@cofin cofin commented Dec 18, 2025

Summary

  • Adds a compatibility layer (advanced_alchemy/utils/cli_tools.py) that provides click alias support across all environments
  • The aliases parameter in click groups is a rich-click 1.9+ feature that causes TypeError when users have plain click or older rich-click
  • Implements AliasedGroup class that mimics rich-click's alias handling for plain click
  • Updates all CLI modules to use the new compatibility layer

Problem

Users encounter failures when using the CLI in these scenarios:

Scenario A: Plain click (no rich-click)

TypeError: __init__() got an unexpected keyword argument 'aliases'

Scenario B: Old rich-click (< 1.9.0)

TypeError: __init__() got an unexpected keyword argument 'aliases'

Solution

Created advanced_alchemy/utils/cli_tools.py with:

  • AliasedGroup class that implements alias resolution for plain click
  • group() and command() wrapper decorators that auto-select the appropriate class
  • Detection constants (_RICH_CLICK_AVAILABLE, _RICH_CLICK_ALIASES_SUPPORTED)

Changes

File Change
advanced_alchemy/utils/cli_tools.py New compatibility module
tests/unit/test_utils/test_click.py Unit tests for the module
advanced_alchemy/cli.py Updated to use compatibility layer
advanced_alchemy/extensions/fastapi/cli.py Updated to use compatibility layer
advanced_alchemy/extensions/flask/cli.py Updated to use compatibility layer
advanced_alchemy/extensions/litestar/cli.py Updated to use compatibility layer

Test plan

  • Unit tests for AliasedGroup class
  • Tests with mocked plain click (no rich-click)
  • Tests with mocked old rich-click (< 1.9.0)
  • Tests with new rich-click >= 1.9.0
  • Type checking passes (mypy/pyright)
  • Linting passes (ruff/pre-commit)

@codecov-commenter
Copy link

codecov-commenter commented Dec 18, 2025

Codecov Report

❌ Patch coverage is 90.65421% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.56%. Comparing base (05a4b80) to head (9a71c60).

Files with missing lines Patch % Lines
advanced_alchemy/utils/cli_tools.py 90.09% 6 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #645      +/-   ##
==========================================
+ Coverage   80.42%   80.56%   +0.14%     
==========================================
  Files          87       88       +1     
  Lines        6431     6531     +100     
  Branches      838      850      +12     
==========================================
+ Hits         5172     5262      +90     
- Misses        995     1001       +6     
- Partials      264      268       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The `aliases` parameter in click groups is a rich-click 1.9+ feature
that causes failures when users have only plain click installed or
older rich-click versions. This commit introduces a compatibility
layer that provides alias support across all environments.

Changes:
- Add `advanced_alchemy/utils/cli_tools.py` with:
  - `AliasedGroup` class that mimics rich-click's alias handling
  - `group()` and `command()` wrappers that auto-select the right class
  - Detection constants for rich-click availability and alias support
- Update all CLI modules to use the compatibility layer:
  - `advanced_alchemy/cli.py`
  - `advanced_alchemy/extensions/fastapi/cli.py`
  - `advanced_alchemy/extensions/flask/cli.py`
  - `advanced_alchemy/extensions/litestar/cli.py`
- Add comprehensive unit tests for the compatibility layer

The CLI now works correctly with:
- Plain click (no rich-click)
- Old rich-click (< 1.9.0)
- New rich-click (>= 1.9.0)
@Harshal6927
Copy link
Member

import datetime

from litestar import Litestar
from litestar.handlers.http_handlers.decorators import get
from sqlalchemy.orm import Mapped

from advanced_alchemy.base import UUIDBase
from advanced_alchemy.config import AsyncSessionConfig
from advanced_alchemy.extensions.litestar.plugins import SQLAlchemyAsyncConfig, SQLAlchemyPlugin


@get("/test")
async def test_handler() -> dict[str, str]:
    return {"message": "test"}


class AuthorModel(UUIDBase):
    __tablename__ = "author"
    name: Mapped[str]
    dob: Mapped[datetime.date]


session_config = AsyncSessionConfig(expire_on_commit=False)
alchemy_config = SQLAlchemyAsyncConfig(
    connection_string="sqlite+aiosqlite:///test.sqlite",
    session_config=session_config,
    create_all=True,
)


app = Litestar(
    route_handlers=[test_handler],
    plugins=[SQLAlchemyPlugin(config=alchemy_config)],
)
advanced-alchemy on  fix/cli-alias [$?] is 📦 v1.8.2 via 🐍 v3.10.18 (advanced-alchemy) 
❯ litestar db -h
Using Litestar app from app:app
                                                                                                                        
 Usage: litestar [OPTIONS] COMMAND [ARGS]...                                                                            
                                                                                                                        
╭─ Error ──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ No such command 'db'.                                                                                                │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
advanced-alchemy on  fix/cli-alias [$?] is 📦 v1.8.2 via 🐍 v3.10.18 (advanced-alchemy) 
❯ litestar database -h
Using Litestar app from app:app
                                                                                                                        
 Usage: litestar database [OPTIONS] COMMAND [ARGS]...                                                                   
                                                                                                                        
 Manage SQLAlchemy database components.                                                                                 
 Aliases: db                                                                                                            
                                                                                                                        
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help  -h  Show this message and exit.                                                                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ branches                    Show current branch points in the migration history                                      │
│ check                       Check if the target database is up to date                                               │
│ downgrade                   Downgrade database to a specific revision.                                               │
│ drop-all                    Drop all tables from the database.                                                       │
│ dump-data                   Dump specified tables from the database to JSON files.                                   │
│ edit                        Edit a revision file using $EDITOR                                                       │
│ ensure-version              Create the alembic version table if it doesn't exist                                     │
│ heads                       Show current available heads in the script directory                                     │
│ history                     List changeset scripts in chronological order                                            │
│ init                        Initialize migrations for the project.                                                   │
│ list-templates              List available Alembic migration templates                                               │
│ make-migrations             Create a new migration revision.                                                         │
│ merge                       Merge two revisions together, creating a new migration file                              │
│ show                        Show the revision denoted by the given symbol                                            │
│ show-current-revision       Shows the current revision for the database.                                             │
│ stamp                       Stamp the revision table with the given revision; don't run any migrations               │
│ upgrade                     Upgrade database to a specific revision.                                                 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

@Harshal6927
Copy link
Member

Its says Aliases: db but it is not working

@cofin
Copy link
Member Author

cofin commented Dec 20, 2025

@Harshal6927 Give it another look now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants