From Zero to a Reproducible Python Project in Seconds.
Stop fighting with broken environments, outdated requirements.txt files, and the "it works on my machine" curse. pyuvstarter is an opinionated script that automates the creation of a robust, modern, and production-ready Python project foundation using uv, the blazing-fast package manager from Astral.
Whether you are starting a new application or modernizing a years-old codebase, pyuvstarter handles the tedious boilerplate of project setup, so you can start writing code that matters.
Watch pyuvstarter rescue a legacy ML project by discovering dependencies from .py files and Jupyter notebooks (including those from !pip install cells), fixing incorrect package names, and creating a modern reproducible environment - all in under 30 seconds.
pyuvstarter is designed to be a valuable assistant for any Python developer, whether you're building from scratch or upgrading an existing codebase.
-
For Modernizing Existing Projects: Do you have an old project with a messy
requirements.txt? Runpyuvstarterin its directory. It handles real-world requirements files (inline comments, package extras likerequests[security]), discovers dependencies in your code and notebooks, and builds a fresh environment managed bypyproject.toml. -
For Starting New Projects: Get a new web app, CLI, or data analysis project off the ground instantly.
pyuvstarterprovides a clean slate with apyproject.toml, a virtual environment, and all the necessary configurations, so you can start coding immediately. -
For Data Scientists & ML Engineers: Stop wrestling with notebook-only
!pip installcells.pyuvstarterdetects these installations, adds them to a centralpyproject.toml, and helps make your analysis environment more robust and reproducible for yourself, your team, and your production pipeline.
pyuvstarter is opinionated to promote modern best practices:
pyproject.tomlis the Single Source of Truth: All dependencies and project metadata should live here.pyuvstarterhelps you get everything into this file.- Environments Must Be Isolated: Every project gets its own
.venvdirectory. - Dependencies Should Be Explicit: The script helps you find what you're actually using and add it to your project configuration.
- Automation Should Be Transparent: Every action
pyuvstartertakes is logged topyuvstarter_setup_log.jsonfor full visibility.
You absolutely can! uv is a powerful low-level tool. pyuvstarter acts as a higher-level orchestrator that chains uv commands together with other best-practice tools like pipreqs and ruff. It automates the workflow of discovery, migration, and configuration that you would otherwise have to perform manually.
When you run pyuvstarter on a new or existing project directory, it performs this setup sequence:
-
Establishes a Modern Foundation: It checks for a
pyproject.tomlfile. If one doesn't exist,pyuvstarterrunsuv initto create it. If one does exist, it uses it as the foundation. -
Creates an Isolated, High-Speed Environment: It runs
uv venvto create a local.venvdirectory. -
Discovers Dependencies:
pyuvstarterscans your project to find imported packages.- For
.pyfiles, it usespipreqsto analyzeimportstatements. - For Jupyter Notebooks (
.ipynb), it uses a two-stage process:- Primary Method: Uses
jupyter nbconvertto convert notebooks to Python scripts for analysis. - Fallback Method: If
jupyterisn't available, parses the raw notebook file using AST forimportstatements and regex for!pip installcommands.
- Primary Method: Uses
- For
-
Manages and Installs Your Full Dependency Tree:
- It migrates packages from a legacy
requirements.txtfile based on your chosen strategy. - It adds all discovered dependencies to your
pyproject.tomlusinguv add. - It installs necessary notebook execution tools like
ipykernelandjupyterif notebooks are present. - Finally, it runs
uv syncto install the complete, resolved set of packages into your.venvand creates auv.lockfile for byte-for-byte reproducibility.
- It migrates packages from a legacy
-
Configures and Cleans Your Tooling:
- It runs
ruffto detect and warn you about unused imports. - It creates or updates
.gitignorewith common Python project patterns. - It configures VS Code by creating or updating
.vscode/settings.jsonand.vscode/launch.json.
- It runs
- Python 3: Requires 3.11 or newer.
uv: The script will attempt to installuvif it's not found. This requires:- macOS: Homebrew (
brew) is preferred, orcurl. - Linux:
curl. - Windows: PowerShell.
- macOS: Homebrew (
- Git: Required to install
pyuvstarterfrom its repository.
Want to try pyuvstarter without installing? Use uvx to run it directly:
# Run pyuvstarter directly from GitHub
uvx --from git+https://github.com/ahundt/pyuvstarter.git pyuvstarterThis downloads and runs pyuvstarter in an isolated environment without permanently installing it.
For regular use, we recommend installing pyuvstarter as a command-line tool via uv.
-
Ensure
uvis installed. If not, you can install it from astral.sh. -
Install the tool. Before running, check the project's GitHub page for the latest version tag to ensure you're installing a stable release.
# Replace vX.Y.Z with the latest stable version tag from the repository uv tool install git+https://github.com/ahundt/pyuvstarter.git@vX.Y.Z -
Ensure
uv's tool directory is in yourPATH. If thepyuvstartercommand isn't found, runuv tool update-shell, then restart your terminal.
# 1. Clone the repository (if you haven't already)
git clone https://github.com/ahundt/pyuvstarter.git
cd pyuvstarter
# 2. Install pyuvstarter as a uv tool
uv tool install .
# 3. (Optional) Force reinstall if you want to overwrite an existing install
uv tool install . --forceuv tool uninstall pyuvstarter
uv pip uninstall pyuvstarter- If installed as a tool: Navigate to your project's root directory and run:
pyuvstarter
- If running from a local clone: Navigate to the cloned pyuvstarter directory and run:
uv run pyuvstarter
pyuvstarter [project_dir] [options]-
project_dirProject directory to operate on. Defaults to current directory if not specified. -
--versionShow installed version and exit. -
--verbose, -vShow detailed technical output for debugging and learning.
--dependency-migration {auto,all-requirements,only-imported,skip-requirements}Strategy for handling existingrequirements.txtfiles:'auto'(default): Migratesrequirements.txtentries only if actively imported, plus all discovered imports'all-requirements': Migrates everyrequirements.txtentry, plus discovered imports'only-imported': Migrates onlyrequirements.txtentries that are imported, plus discovered imports'skip-requirements': Ignoresrequirements.txt, uses only discovered imports
-
--venv-name <name>Name of virtual environment directory (default:.venv) -
--log-file-name <name>Name of JSON log file (default:pyuvstarter_setup_log.json) -
--config-file <path>, -c <path>Path to JSON configuration file with option presets
-
--no-gitignoreDisable all.gitignoreoperations -
--full-gitignore-overwriteReplace existing.gitignorecompletely instead of merging -
--gitignore-name <name>Name of gitignore file (default:.gitignore) -
--ignore-pattern <pattern>, -i <pattern>Additional gitignore patterns to add (can be specified multiple times)
# Run in current directory (most common)
pyuvstarter
# Run in specific directory
pyuvstarter /path/to/your/project
# Show detailed output for debugging
pyuvstarter --verbose
# Migrate all requirements.txt entries, even if unused
pyuvstarter --dependency-migration all-requirements
# Custom virtual environment name
pyuvstarter --venv-name my_venv
# Add custom patterns to .gitignore
pyuvstarter --ignore-pattern "*.tmp" --ignore-pattern "cache/"
# Completely replace existing .gitignore
pyuvstarter --full-gitignore-overwriteAfter pyuvstarter finishes, your project is not just configured—it's ready for immediate development.
- Open the project in VS Code and see that it automatically detects and uses the new
.venv/Python interpreter. - Get intelligent code completion, linting, and formatting from
ruffand other Python extensions, because the environment is set up correctly. - Run and debug your code immediately. You can open a Python file and use the default
F5key (or the "Run and Debug" panel) to execute it. - Activate and use the terminal (
source .venv/bin/activate) for any additional commands. - Trust your dependency list, as
pyproject.tomlwill accurately reflect the packages your project actually uses.
The script achieves this by creating or modifying the following files in your project directory:
pyproject.toml: The central configuration file for your project's dependencies..venv/: The directory containing your isolated Python virtual environment.uv.lock: The lock file that guarantees reproducible installations..gitignore: A file configured to ignore the virtual environment, logs, and other common artifacts..vscode/settings.json: Configures VS Code to use the correct Python interpreter..vscode/launch.json: Provides a default debug configuration.pyuvstarter_setup_log.json: A detailed log of all actions the script performed.
- Reload VS Code: If the project was already open, reload the window (
Ctrl+Shift+P> "Developer: Reload Window"). - Activate Virtual Environment:
- Linux/macOS:
source .venv/bin/activate - Windows (PowerShell):
.\.venv\Scripts\activate
- Linux/macOS:
- Review & Test: Examine
pyproject.tomland run your application or tests. - Commit to Version Control: Commit
pyproject.toml,uv.lock,.gitignore, and your source code. Do NOT commit.venv/.
Contributions are welcome! Please feel free to open an issue to report a bug or suggest a feature, or open a pull request to propose a change. See the project's issue tracker for ideas.
Critical Failures (script stops):
uvinstallation fails → Installuvmanually from docs.astral.sh/uvpyproject.tomlcreation fails → Check write permissions, resolve conflicts- Virtual environment creation fails → Run
uv venvmanually for diagnostic output - File permission errors → Adjust with
chmodor use directory you control
Partial Success (script continues):
- Some packages fail → Installs successful packages; check
pyuvstarter_setup_log.json→failed_packagesfor reasons - Dependency discovery issues → Skips unparseable files; manually add missing packages with
uv add <package> - Notebook parsing failures → Skips corrupt notebooks; fix format or add dependencies manually
- Import fixing failures → Reports issues; manually fix complex relative imports
Check diagnostic log:
# View errors
cat pyuvstarter_setup_log.json | grep -A 5 '"status": "ERROR"'
# Check overall status: SUCCESS | COMPLETED_WITH_ERRORS | CRITICAL_FAILURE
grep '"overall_status"' pyuvstarter_setup_log.jsonCommon package failure reasons:
- "no Python 3.14 wheel" → Package not yet compatible; use older Python version
- "version conflict" → Adjust version constraints in
pyproject.toml - "package not found" → Verify package name spelling on PyPI
- If
uvor other tools fail to install, check the console output for hints. - If
pipreqsmisidentifies a dependency, manually editpyproject.tomland runuv syncto apply changes, or useuv remove <incorrect-package>to remove it. - For notebook issues: The most reliable detection requires
jupyter. If missing,pyuvstarteruses a fallback parser that may miss some dependencies. Install withuv pip install jupyterfor best results. - Always check the
pyuvstarter_setup_log.jsonfile for detailed error messages and specific failure reasons.
Issue: "command not found: pyuvstarter" or pyuvstarter creates files in the wrong directory.
Background: pyuvstarter can be run in several ways, each with different implications for where it's available and which directory it operates on:
-
As a globally installed tool (Recommended)
# Install globally uv tool install git+https://github.com/ahundt/pyuvstarter.git # Run in any directory pyuvstarter .
-
Using uvx (Quick try without installation)
# Run directly without installing uvx --from git+https://github.com/ahundt/pyuvstarter.git pyuvstarter .
-
From within the pyuvstarter project directory
# If you've cloned pyuvstarter cd /path/to/pyuvstarter uv run pyuvstarter /path/to/your/project
Important: When using uv run --directory <dir>, be aware that this changes the working directory before executing the command. For example:
uv run --directory .. pyuvstarterruns pyuvstarter with the parent directory as the working directoryuv run --directory .. pyuvstarter .still operates on the parent directory (not the original directory)- To specify the target directory explicitly:
uv run --directory .. pyuvstarter "$(pwd)"
Solution: For most use cases, install pyuvstarter as a global tool (option 1) or use uvx (option 2) to avoid directory context issues.
Before running tests, ensure pyuvstarter is installed:
# Install pyuvstarter as a global tool
uv tool install .
# Verify installation
which pyuvstarterPython Test Suite (tests/*.py):
test_configuration.py- Configuration management and CLI argumentstest_cross_platform.py- Cross-platform compatibility (Windows, macOS, Linux)test_dependency_migration.py- Requirements.txt migration strategiestest_error_handling.py- Error detection and graceful degradationtest_extraction_fix.py- Package name extraction and canonicalizationtest_import_fixing.py- Import statement detection and relative import handlingtest_jupyter_pipeline.py- Jupyter notebook dependency discoverytest_mixed_package_availability.py- Package availability edge casestest_project_structure.py- Flat vs src-layout project structure detectiontest_utils.py- Core utility functions and helperstest_wheel_unavailability.py- Python 3.14+ wheel unavailability handling
Shell Test Scripts (tests/*.sh):
run_all_tests.sh- Main test runner for all integration teststest_new_project.sh- Empty project initializationtest_legacy_migration.sh- Requirements.txt migration
Comprehensive Test Suites:
create_demo.sh --unit-test- Comprehensive test suite including notebook parsingcreate_demo2.sh --unit-test- Extended tests with edge cases
# Run Python test suite (pytest)
./tests/run_all_tests.sh
# Run specific Python test modules
python -m pytest tests/test_jupyter_pipeline.py -v
python -m pytest tests/test_import_fixing.py -v
python -m pytest tests/test_wheel_unavailability.py -v
# Run shell-based integration tests
./tests/test_new_project.sh
./tests/test_legacy_migration.sh
# Run comprehensive test suites (recommended for full validation)
./create_demo.sh --unit-test
./create_demo2.sh --unit-testCheck workflow syntax before pushing:
# Install actionlint
brew install actionlint # macOS/Linux with Homebrew
# Other platforms: https://github.com/rhysd/actionlint
# Validate workflows
actionlint # Basic check
actionlint -shellcheck # With shell script validation- Check logs: Look for
pyuvstarter_setup_log.jsonin the test directory - Run verbose: Set
PYUVSTARTER_LOG_LEVEL=DEBUGbefore running tests - Test isolation: Tests create temporary directories to avoid conflicts
- Common issues:
- Missing dependencies: Run
uv syncin the project root - Tool not found: Ensure
~/.local/binis in your PATH
- Missing dependencies: Run
This project (pyuvstarter) is licensed under the Apache License, Version 2.0 and Copyright 2025 Andrew Hundt.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use pyuvstarter` except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
