Skip to content

uayyagari/fastentry

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FastEntry

PyPI Downloads

Accelerate Python CLI tab completion with automatic snapshot-based entrypoint generation.

Problem

Python CLI applications using argparse and argcomplete often suffer from slow tab completion due to high import times. Many modern Python SDKs, when exposed through CLIs, have import times exceeding 500ms (e.g., import requests alone is 100ms). This leads to a poor user experience, as every tab completion can trigger a full Python process startup and import, resulting in noticeable delays.

Solution

FastEntry automatically generates lightweight completion entrypoints for existing CLI applications, providing super fast completion without requiring any code changes from CLI maintainers.

How It Works

  1. CLI maintainer runs: fastentry enable mycli.py
  2. FastEntry automatically generates:
    • mycli_completion.py (lightweight entrypoint with minimal imports)
    • mycli_snapshot.json (parser structure for fast completion)
  3. CLI maintainer updates pyproject.toml to point to the new entrypoint
  4. Users get fast completion without any code changes

Installation

pip install fastentry

Usage

For CLI Maintainers

Command Line Interface

# Enable fast completion for a CLI file
fastentry enable mycli.py

# This generates:
# - mycli_completion.py (lightweight entrypoint)
# - mycli_snapshot.json (parser structure)

Programmatic API

from fastentry import enable_fast_completion

# Generate lightweight entrypoint
output_path = enable_fast_completion('mycli.py')
print(f'Generated: {output_path}')

Update Package Configuration

# pyproject.toml
[project.scripts]
mycli = "mycli_completion:main"  # Point to lightweight entrypoint

For Users

No changes required! Users get fast completion automatically after CLI maintainers adopt FastEntry.

Example

Original CLI (mycli.py)

#!/usr/bin/env python
# PYTHON_ARGCOMPLETE_OK

# Heavy imports at module level (the problem!)
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import requests

import argparse
import argcomplete

def main():
    parser = argparse.ArgumentParser()
    # ... parser setup
    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    # ... CLI logic

if __name__ == "__main__":
    main()

Generated Entrypoint (mycli_completion.py)

#!/usr/bin/env python
# PYTHON_ARGCOMPLETE_OK
"""
Lightweight completion entrypoint for mycli.py
Generated by FastEntry - DO NOT EDIT MANUALLY
"""

import os
import sys
import json
from pathlib import Path

def is_completion_request():
    return os.environ.get('_ARGCOMPLETE') == '1'

def handle_completion_fast():
    """Handle completion requests with minimal imports"""
    try:
        # Try to use snapshot first
        snapshot_path = Path(__file__).parent / "mycli_snapshot.json"
        if snapshot_path.exists():
            from fastentry import FastEntry
            fast_entry = FastEntry(str(snapshot_path))
            # ... snapshot-based completion
            return

        # Fallback to regular argcomplete
        import argcomplete
        # ... regular completion

    except Exception as e:
        # Final fallback: import the original CLI (slow but works)
        import mycli
        mycli.main()

def main():
    if is_completion_request():
        handle_completion_fast()
        return

    # Import and run the original CLI
    import mycli
    mycli.main()

if __name__ == "__main__":
    main()

Key Features

  • No Code Changes: CLI maintainers don't need to refactor their code
  • Automatic Generation: Library handles all the complexity
  • Fast Completion: Minimal imports during completion requests
  • Robust Fallback: Always works, even if snapshot fails
  • Backward Compatible: Existing CLIs work unchanged
  • Library-Based: Easy to adopt and integrate

Limitations / Cons

  • Dynamic Completions Not Captured: If your CLI uses dynamic completions (e.g., choices that depend on runtime data, environment variables, or external resources), these cannot be fully represented in the static snapshot.json generated at build time. In such cases, FastEntry will fall back to the original script for those completions, which may be slower.
  • Snapshot Must Be Regenerated on CLI Changes: If you update your CLI's arguments or completion logic, you need to re-run fastentry enable to regenerate the snapshot and entrypoint. This is a one-time cost, but it's a cost nonetheless.

Error Handling

The system has multiple fallback levels:

  1. Snapshot-based completion (fastest)
  2. Regular argcomplete (medium speed)
  3. Import original CLI (slow but works)

This ensures completion always works, even if the snapshot is missing or corrupted.

Development

Code Formatting

This project uses Black for code formatting and Flake8 for linting. Both tools are configured via pyproject.toml (no separate config files).

To format code:

black .

To lint code:

flake8 .

Testing

pytest is included as a development dependency, but there is currently no tests/ folder or test suite in this project. You may add your own tests as needed.

Contributing

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages