# FastEntry
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
```bash
pip install fastentry
```
## Usage
### For CLI Maintainers
#### Command Line Interface
```bash
# 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
```python
from fastentry import enable_fast_completion
# Generate lightweight entrypoint
output_path = enable_fast_completion('mycli.py')
print(f'Generated: {output_path}')
```
#### Update Package Configuration
```toml
# 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)
```python
#!/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)
```python
#!/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](https://black.readthedocs.io/en/stable/) for code formatting and [Flake8](https://flake8.pycqa.org/en/latest/) for linting. Both tools are configured via `pyproject.toml` (no separate config files).
To format code:
```bash
black .
```
To lint code:
```bash
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
Raw data
{
"_id": null,
"home_page": null,
"name": "fastentry",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "cli, completion, argparse, argcomplete, tab-completion, performance",
"author": null,
"author_email": "Uday Ayyagari <ayyagari.uday@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/2c/b8/faf89097e0faf7d629dbaf9cbf51d590639a8ac9938d33a9ced6aa65c49c/fastentry-0.1.4.tar.gz",
"platform": null,
"description": "# FastEntry\n\nAccelerate Python CLI tab completion with automatic snapshot-based entrypoint generation.\n\n## Problem\n\nPython 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.\n\n## Solution\n\nFastEntry automatically generates lightweight completion entrypoints for existing CLI applications, providing super fast completion without requiring any code changes from CLI maintainers.\n\n## How It Works\n\n1. **CLI maintainer runs**: `fastentry enable mycli.py`\n2. **FastEntry automatically generates**:\n - `mycli_completion.py` (lightweight entrypoint with minimal imports)\n - `mycli_snapshot.json` (parser structure for fast completion)\n3. **CLI maintainer updates** `pyproject.toml` to point to the new entrypoint\n4. **Users get fast completion** without any code changes\n\n## Installation\n\n```bash\npip install fastentry\n```\n\n## Usage\n\n### For CLI Maintainers\n\n#### Command Line Interface\n\n```bash\n# Enable fast completion for a CLI file\nfastentry enable mycli.py\n\n# This generates:\n# - mycli_completion.py (lightweight entrypoint)\n# - mycli_snapshot.json (parser structure)\n```\n\n#### Programmatic API\n\n```python\nfrom fastentry import enable_fast_completion\n\n# Generate lightweight entrypoint\noutput_path = enable_fast_completion('mycli.py')\nprint(f'Generated: {output_path}')\n```\n\n#### Update Package Configuration\n\n```toml\n# pyproject.toml\n[project.scripts]\nmycli = \"mycli_completion:main\" # Point to lightweight entrypoint\n```\n\n### For Users\n\nNo changes required! Users get fast completion automatically after CLI maintainers adopt FastEntry.\n\n## Example\n\n### Original CLI (mycli.py)\n\n```python\n#!/usr/bin/env python\n# PYTHON_ARGCOMPLETE_OK\n\n# Heavy imports at module level (the problem!)\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport requests\n\nimport argparse\nimport argcomplete\n\ndef main():\n parser = argparse.ArgumentParser()\n # ... parser setup\n argcomplete.autocomplete(parser)\n args = parser.parse_args()\n # ... CLI logic\n\nif __name__ == \"__main__\":\n main()\n```\n\n### Generated Entrypoint (mycli_completion.py)\n\n```python\n#!/usr/bin/env python\n# PYTHON_ARGCOMPLETE_OK\n\"\"\"\nLightweight completion entrypoint for mycli.py\nGenerated by FastEntry - DO NOT EDIT MANUALLY\n\"\"\"\n\nimport os\nimport sys\nimport json\nfrom pathlib import Path\n\ndef is_completion_request():\n return os.environ.get('_ARGCOMPLETE') == '1'\n\ndef handle_completion_fast():\n \"\"\"Handle completion requests with minimal imports\"\"\"\n try:\n # Try to use snapshot first\n snapshot_path = Path(__file__).parent / \"mycli_snapshot.json\"\n if snapshot_path.exists():\n from fastentry import FastEntry\n fast_entry = FastEntry(str(snapshot_path))\n # ... snapshot-based completion\n return\n\n # Fallback to regular argcomplete\n import argcomplete\n # ... regular completion\n\n except Exception as e:\n # Final fallback: import the original CLI (slow but works)\n import mycli\n mycli.main()\n\ndef main():\n if is_completion_request():\n handle_completion_fast()\n return\n\n # Import and run the original CLI\n import mycli\n mycli.main()\n\nif __name__ == \"__main__\":\n main()\n```\n\n## Key Features\n\n- \u2705 **No Code Changes**: CLI maintainers don't need to refactor their code\n- \u2705 **Automatic Generation**: Library handles all the complexity\n- \u2705 **Fast Completion**: Minimal imports during completion requests\n- \u2705 **Robust Fallback**: Always works, even if snapshot fails\n- \u2705 **Backward Compatible**: Existing CLIs work unchanged\n- \u2705 **Library-Based**: Easy to adopt and integrate\n\n## Limitations / Cons\n\n- \u274c **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.\n- \u274c **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.\n\n## Error Handling\n\nThe system has multiple fallback levels:\n\n1. **Snapshot-based completion** (fastest)\n2. **Regular argcomplete** (medium speed)\n3. **Import original CLI** (slow but works)\n\nThis ensures completion always works, even if the snapshot is missing or corrupted.\n\n## Development\n\n### Code Formatting\n\nThis project uses [Black](https://black.readthedocs.io/en/stable/) for code formatting and [Flake8](https://flake8.pycqa.org/en/latest/) for linting. Both tools are configured via `pyproject.toml` (no separate config files).\n\nTo format code:\n```bash\nblack .\n```\n\nTo lint code:\n```bash\nflake8 .\n```\n\n### Testing\n\n`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.\n\n### Contributing\n",
"bugtrack_url": null,
"license": null,
"summary": "Accelerate Python CLI tab completion with automatic snapshot-based entrypoint generation",
"version": "0.1.4",
"project_urls": {
"Homepage": "https://github.com/uayyagari/fastentry",
"Issues": "https://github.com/uayyagari/fastentry/issues",
"Repository": "https://github.com/uayyagari/fastentry"
},
"split_keywords": [
"cli",
" completion",
" argparse",
" argcomplete",
" tab-completion",
" performance"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5180f3ee757e75cccfe466244e3483190c6687e6b3025692a35c482b5ceda864",
"md5": "a99030177a2698272ec9602fde468bde",
"sha256": "1bb94c0979b1b69ec465068b59dfbda91a5680ed62057827b920e8dddf572f64"
},
"downloads": -1,
"filename": "fastentry-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a99030177a2698272ec9602fde468bde",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 14956,
"upload_time": "2025-07-21T12:34:38",
"upload_time_iso_8601": "2025-07-21T12:34:38.587127Z",
"url": "https://files.pythonhosted.org/packages/51/80/f3ee757e75cccfe466244e3483190c6687e6b3025692a35c482b5ceda864/fastentry-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "2cb8faf89097e0faf7d629dbaf9cbf51d590639a8ac9938d33a9ced6aa65c49c",
"md5": "530fc08f4efd8b4cdc54178f51c35313",
"sha256": "70ca29d9d5efea206690d149d7b9352d5627ec3e986614d13a871c618c1a8ad0"
},
"downloads": -1,
"filename": "fastentry-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "530fc08f4efd8b4cdc54178f51c35313",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 15071,
"upload_time": "2025-07-21T12:34:39",
"upload_time_iso_8601": "2025-07-21T12:34:39.971402Z",
"url": "https://files.pythonhosted.org/packages/2c/b8/faf89097e0faf7d629dbaf9cbf51d590639a8ac9938d33a9ced6aa65c49c/fastentry-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-21 12:34:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "uayyagari",
"github_project": "fastentry",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "fastentry"
}