venv-bat-gen
Generate project-local venv helper scripts for Python projects — Windows, WSL, macOS, and Linux.
venv-bat-gen solves a specific Windows pain point: activating a virtual environment manually is annoying, error-prone, and breaks in scripts. The correct approach is to call .venv\Scripts\python.exe directly — but writing those helper scripts by hand every time is tedious.
This tool generates a complete set of project-local helper scripts in seconds, from a polished GUI or a single CLI command.
What it generates
For every project, venv-bat-gen writes up to 12 scripts (.bat for Windows, .sh for POSIX):
| Script | Purpose |
|---|---|
run.bat / run.sh |
Run your project — file, module, or runner mode |
pip.bat / pip.sh |
Project-local pip (or uv pip) wrapper |
shell.bat / shell.sh |
Open an activated shell session |
sync.bat / sync.sh |
Install / sync dependencies |
doctor.bat / doctor.sh |
Environment health check |
test.bat / test.sh |
Run pytest via the local venv |
Every script calls .venv\Scripts\python.exe (or .venv/bin/python) directly — no manual activation required, and no PATH pollution.
Installation
Via pip:
pip install venv-bat-gen
Via uv (recommended):
uv pip install venv-bat-gen
Via uv tool (globally, isolated):
uv tool install venv-bat-gen
From source:
git clone https://github.com/keystoneai/venv-bat-gen
cd venv-bat-gen
pip install -e .
Note: The GUI requires PyQt6. If you only need the CLI, PyQt6 is still installed as a dependency — a headless CLI-only mode may be added in a future release.
Usage
GUI
# Launch the GUI
venv-bat-gen-gui
# Or
python -m venv_bat_gen
The GUI provides:
- Presets — built-in templates for FastAPI, PyQt6, CLI scripts, Streamlit, and uv projects. Save your own.
- Folder auto-detect — browse to a project folder and the scanner reads
pyproject.toml,uv.lock,requirements.txt, and common entry files to suggest settings automatically. - Live preview — see the generated scripts before writing them, with syntax highlighting.
- Configure / Log tabs — settings scroll freely on any screen size; the activity log switches automatically on generate.
CLI
# Basic usage
venv-bat-gen generate C:\projects\myapi --runner --entry uvicorn \
--runner-args "app.main:app --host 0.0.0.0 --port 8000 --reload"
# Load a preset as defaults, then override
venv-bat-gen generate C:\projects\myapp --preset "FastAPI / Uvicorn" --name MyApp
# Use uv + generate POSIX .sh scripts too
venv-bat-gen generate ~/projects/mytool --module --entry mytool --uv --posix
# Dry run — see what would be written
venv-bat-gen generate C:\projects\myapp --preset "PyQt6 Desktop App" --dry-run
# Scan a folder for auto-detection hints
venv-bat-gen scan C:\projects\existing
# List available presets
venv-bat-gen presets
venv-bat-gen presets --detail
Entry modes
| Flag | Generated command | Use when |
|---|---|---|
--file |
python main.py |
Single entry file |
--module |
python -m mypackage |
Proper package with __main__.py |
--runner |
python -m uvicorn app.main:app ... |
Tools like uvicorn, streamlit, flask |
uv support
Pass --uv (CLI) or check "Use uv" (GUI) to generate uv-native scripts:
sync.bat/sh— runsuv sync(withuv.lock/pyproject.tomldetection) or falls back touv pip install -r requirements.txtpip.bat/sh— wrapsuv pip --python .venv/...doctor.bat/sh— checksuvis on PATH and shows its versioncreate_venv— runsuv venvinstead ofpython -m venv, with graceful fallback if uv isn't installed
The "uv Project" built-in preset configures all of this automatically.
Cross-platform (POSIX) scripts
Pass --posix (CLI) or check "Generate POSIX .sh scripts" (GUI) to also write .sh equivalents of every script. Shell scripts are written with:
- Unix LF line endings
#!/usr/bin/env bashshebangchmod +xset automatically on generate.venv/bin/pythoninstead of.venv\Scripts\python.exe
The "CLI Script (Cross-Platform)" preset generates both .bat and .sh by default.
Presets
Built-in presets (read-only):
| Preset | Mode | Entry | uv | POSIX |
|---|---|---|---|---|
| FastAPI / Uvicorn | runner | uvicorn | — | — |
| PyQt6 Desktop App | file | main.py | — | — |
| CLI Script | module | app | — | — |
| CLI Script (Cross-Platform) | module | app | — | ✔ |
| Streamlit App | runner | streamlit | — | — |
| uv Project | module | app | ✔ | — |
User presets are saved to ~/.keystoneai/venv_generator_presets.json and persist across sessions.
Project structure
venv_bat_gen/
├── __init__.py # version
├── __main__.py # python -m venv_bat_gen entry point
├── core.py # GeneratorConfig, all template generators, scanner, presets
├── cli.py # argparse CLI — no Qt dependency
└── gui.py # PyQt6 GUI — imports from core
core.py has zero Qt imports and is safe to use headlessly from scripts or other tools:
from venv_bat_gen.core import GeneratorConfig, generate_files
cfg = GeneratorConfig(
project_dir=Path("C:/projects/myapi"),
project_name="MyAPI",
venv_dir=".venv",
entry_mode="runner",
app_entry="uvicorn",
runner_args="app.main:app --host 0.0.0.0 --port 8000 --reload",
overwrite_existing=False,
create_requirements=True,
include_webengine_check=False,
pause_on_exit=False,
create_venv_now=False,
include_test_bat=True,
use_uv=False,
include_posix=False,
)
written = generate_files(cfg)
Requirements
- Python 3.11+
- PyQt6 6.4+ (GUI)
- uv (optional — only needed if using
--uv/ "Use uv" mode)
Why not just activate the venv?
Activation works fine interactively. It breaks when:
- You run scripts from task schedulers, CI, or other tools that don't inherit your shell state
- You have multiple projects open and activation leaks across terminals
- You want a double-clickable launcher that just works
Calling .venv\Scripts\python.exe directly avoids all of this. The generated scripts are readable, editable, and self-documenting — they're not magic wrappers.
Contributing
Issues and PRs welcome. The codebase is intentionally simple:
- Add a new template → add
make_<name>_bat()andmake_<name>_sh()tocore.py, register inbuild_previews() - Add a new preset → add an entry to
_BUILTIN_PRESETSincore.py - Add a CLI flag →
_build_generate_parser()incli.py, wire through_cmd_generate() - Add a GUI option →
_build_options_group()ingui.py, wire through_read_config()
License
MIT — see LICENSE.
Metadata
Release files for venv-bat-gen 3.3.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| venv_bat_gen-3.3.4.tar.gz | 27.2 kB | Without provenance | Details for venv_bat_gen-3.3.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| venv_bat_gen-3.3.4-py3-none-any.whl | Python 3 | none | any | Details for venv_bat_gen-3.3.4-py3-none-any.whl |
Total release size: 56.5 kB
Release files / venv_bat_gen-3.3.4.tar.gz
| Download URL | venv_bat_gen-3.3.4.tar.gz |
|---|---|
| Size | 27.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5f8a62110776e425cd0ee73267aaae4490bf55c9e9d38e4b10c195fc89ea1f71
|
|
BLAKE2b-256 checksum How to use checksums |
7149c969d3cd1ce37ee1c67079d2b35596195d306927267d271ac12639ae054b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.5
|
Release files / venv_bat_gen-3.3.4-py3-none-any.whl
| Download URL | venv_bat_gen-3.3.4-py3-none-any.whl |
|---|---|
| Size | 29.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5bc06d6c65caf803a24c712c880ba4189422959d61076ab3be3b790446e2fbfa
|
|
BLAKE2b-256 checksum How to use checksums |
bd6779b4c5490dafbcb8efc8e9441358b6dc9d49aa638682a0d81e0fc6ce1a3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.5
|
Security for venv-bat-gen 3.3.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.