Fast Bash completion artifacts for import-heavy argparse and argcomplete CLIs.
Project description
argcomplete-snapshot
What
Generate fast Bash completion artifacts for import-heavy Python CLIs built with argparse and argcomplete.
Why
Default argcomplete runs the target Python CLI on every completion request. For SDK-backed CLIs that means paying for:
- Python startup
- heavy imports
- parser construction
- completion logic
That can easily turn <TAB> into a 200-600+ ms operation.
How
argcomplete-snapshot extracts a lightweight completion model once and writes shell-native cache artifacts:
snapshot-v1.jsoncompletion-v1.bashversion-stamp
Steady-state completion stays in Bash. Python only runs when:
- artifacts are missing
- the CLI changed after upgrade
- a maintainer explicitly routes a dynamic resolver through a fallback command
Why Not Just Use Something Else?
argcomplete: good dynamic behavior, but slow because it starts Python on every completionshtab: fast for static completion scripts, but not built around lazy self-refresh afterpip install -U ...or explicit dynamic fallback contracts
This package is for the middle ground:
- your CLI is too heavy for default
argcomplete - you still need more lifecycle support than a pure static script
Requirements
- Python
3.13+ - Bash
4+
Bash 4+ is required because the generated runtime uses associative arrays.
Dynamic resolvers require an explicit fallback command. They are not inferred automatically.
Install
Install from PyPI:
pip install argcomplete-snapshot
Install benchmark extras from a checkout:
pip install ".[bench]"
Usage
1. Build a lightweight parser
import argparse
from argcomplete_snapshot import CompletionKind, set_completion
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="mycli")
parser.add_argument("--output", choices=["json", "yaml", "text"])
profile = parser.add_argument("--profile")
set_completion(profile, resolver="config_profiles")
path = parser.add_argument("--path")
set_completion(path, kind=CompletionKind.FILE)
return parser
2. Generate artifacts
acs-refresh refresh \
--factory mypackage.cli:build_parser \
--cli-name mycli \
--distribution mycli
3. Print the activation snippet
acs-refresh print-activation \
--factory mypackage.cli:build_parser \
--cli-name mycli \
--distribution mycli
4. Add dynamic fallback only when needed
acs-refresh print-activation \
--factory mypackage.cli:build_parser \
--cli-name mycli \
--distribution mycli \
--fallback-command "mycli --resolver-fallback"
Use fallback only for genuinely dynamic completions. Static options and choices should stay on the Bash hot path.
Cache Layout
~/.cache/argcomplete-snapshot/<cli-name>/
snapshot-v1.json
completion-v1.bash
version-stamp
Benchmarks
Results:
- benchmarks/results/README.md
- benchmarks/results/benchmark-results.json
- benchmarks/results/hot-path-comparison.png
- benchmarks/results/spawned-comparison.png
Hot path:
Spawned shell:
Current published medians:
| Case | argcomplete |
snapshot |
shtab |
|---|---|---|---|
| Static hot path | 491.10 ms | 1.77 ms | 23.46 ms |
| Static spawned shell | 647.65 ms | 165.43 ms | 95.86 ms |
Read those numbers carefully:
hot pathis the relevant steady-state completion metricspawned shellincludes shell startup and sourcing overhead- dynamic fallback cases are slower because they intentionally call runtime logic
Benchmark environment for the published results:
- macOS
26.3.1 - MacBook Pro
MacBookPro17,1 8CPU cores (4performance +4efficiency)16 GBmemory- Python
3.13.12underuv - benchmark fixtures simulate heavy CLIs by importing
requestsand sleeping for200 ms - benchmark strategy uses
5spawned-shell samples and15hot-path samples per case and implementation
Run locally:
make benchmark
Development
pip install -e ".[dev,bench]"
make check
make benchmark
Status
Early release.
Implemented:
- typed snapshot model
argparseextraction- Bash artifact emission
- lazy cache refresh
- activation snippet generation
- explicit dynamic fallback contract
- benchmark fixtures and comparisons
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file argcomplete_snapshot-1.0.0.tar.gz.
File metadata
- Download URL: argcomplete_snapshot-1.0.0.tar.gz
- Upload date:
- Size: 322.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fc01013a56c32577320b76cfd3098d530b1b47994a3327369f4a12297cc1e28
|
|
| MD5 |
17ca93eef0cfa7857bd2b9b0d9b0ab84
|
|
| BLAKE2b-256 |
bd7f2f43dba8163a867541e605dc4ccac37b9d1b6e01fb8befdab1c8d33c0b6f
|
Provenance
The following attestation bundles were made for argcomplete_snapshot-1.0.0.tar.gz:
Publisher:
publish.yaml on zelnkup/argcomplete-snapshot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
argcomplete_snapshot-1.0.0.tar.gz -
Subject digest:
7fc01013a56c32577320b76cfd3098d530b1b47994a3327369f4a12297cc1e28 - Sigstore transparency entry: 1340731750
- Sigstore integration time:
-
Permalink:
zelnkup/argcomplete-snapshot@bfae70d1dc6af33ec3ce26fd1153240fa5504689 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/zelnkup
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@bfae70d1dc6af33ec3ce26fd1153240fa5504689 -
Trigger Event:
push
-
Statement type:
File details
Details for the file argcomplete_snapshot-1.0.0-py3-none-any.whl.
File metadata
- Download URL: argcomplete_snapshot-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46e52a685ca12a3f06472e8f1cbd718836a712bb2681ce9632361abcc8abecd0
|
|
| MD5 |
af7e7796365972aef9ca3ed418cc7d5e
|
|
| BLAKE2b-256 |
07091949ca8b47160c62a4a956e1b8508a1f0b7f674f56fb2c59a29213264736
|
Provenance
The following attestation bundles were made for argcomplete_snapshot-1.0.0-py3-none-any.whl:
Publisher:
publish.yaml on zelnkup/argcomplete-snapshot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
argcomplete_snapshot-1.0.0-py3-none-any.whl -
Subject digest:
46e52a685ca12a3f06472e8f1cbd718836a712bb2681ce9632361abcc8abecd0 - Sigstore transparency entry: 1340731791
- Sigstore integration time:
-
Permalink:
zelnkup/argcomplete-snapshot@bfae70d1dc6af33ec3ce26fd1153240fa5504689 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/zelnkup
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@bfae70d1dc6af33ec3ce26fd1153240fa5504689 -
Trigger Event:
push
-
Statement type: