lang.python #
Python Environment Management with UV
This module provides modern Python environment management using uv
- a fast Python package installer and resolver written in Rust.
Features
- Modern Tooling: Uses
uv
instead of legacy pip for fast package management - Template-Based: Generates
pyproject.toml
,env.sh
, andinstall.sh
from templates - No Database Dependencies: Relies on Python's native package management instead of manual state tracking
- Backward Compatible: Legacy
pip()
methods still work but useuv
under the hood - Project-Based: Each environment is a proper Python project with
pyproject.toml
Quick Start
import incubaid.herolib.lang.python
// Create a new Python environment
py := python.new(
name: 'my_project'
dependencies: ['requests', 'click', 'pydantic']
dev_dependencies: ['pytest', 'black', 'mypy']
python_version: '3.11'
)!
// Add more dependencies
py.add_dependencies(['fastapi'], false)! // production dependency
py.add_dependencies(['pytest-asyncio'], true)! // dev dependency
// Execute Python code
result := py.exec(cmd: '''
import requests
response = requests.get("https://api.github.com")
print("==RESULT==")
print(response.status_code)
''')!
println('Status code: ${result}')
Environment Structure
Each Python environment creates:
~/hero/python/{name}/
├── .venv/ # Virtual environment (created by uv)
├── pyproject.toml # Project configuration
├── uv.lock # Dependency lock file
├── env.sh # Environment activation script
├── install.sh # Installation script
└── README.md # Project documentation
API Reference
Creating Environments
// Basic environment
py := python.new()! // Creates 'default' environment
// Custom environment with dependencies
py := python.new(
name: 'web_scraper'
dependencies: ['requests', 'beautifulsoup4', 'lxml']
dev_dependencies: ['pytest', 'black']
python_version: '3.11'
description: 'Web scraping project'
reset: true // Force recreation
)!
Package Management
// Add production dependencies
py.add_dependencies(['numpy', 'pandas'], false)!
// Add development dependencies
py.add_dependencies(['jupyter', 'matplotlib'], true)!
// Remove dependencies
py.remove_dependencies(['old_package'], false)!
// Legacy methods (still work)
py.pip('requests,click')! // Comma-separated
py.pip_uninstall('old_package')!
// Update all dependencies
py.update()!
// Sync dependencies (install from pyproject.toml)
py.sync()!
Environment Information
// Check if environment exists
if py.exists() {
println('Environment is ready')
}
// List installed packages
packages := py.list_packages()!
for package in packages {
println(package)
}
Freeze/Export Functionality
// Export current environment
requirements := py.freeze()!
py.freeze_to_file('requirements.txt')!
// Export with exact versions (from uv.lock)
lock_content := py.export_lock()!
py.export_lock_to_file('requirements-lock.txt')!
// Install from requirements
py.install_from_requirements('requirements.txt')!
// Restore exact environment from lock
py.restore_from_lock()!
Shell Access
// Open interactive shell in environment
py.shell()!
// Open Python REPL
py.python_shell()!
// Open IPython (if available)
py.ipython_shell()!
// Run Python script
result := py.run_script('my_script.py')!
// Run any command in environment
result := py.run('python -m pytest')!
// Run uv commands
result := py.uv_run('add --dev mypy')!
Python Code Execution
// Execute Python code with result capture
result := py.exec(
cmd: '''
import json
data = {"hello": "world"}
print("==RESULT==")
print(json.dumps(data))
'''
)!
// Execute with custom delimiters
result := py.exec(
cmd: 'print("Hello World")'
result_delimiter: '==OUTPUT=='
ok_delimiter: '==DONE=='
)!
// Save script to file in environment
py.exec(
cmd: 'print("Hello World")'
python_script_name: 'hello' // Saves as hello.py
)!
Migration from Old Implementation
Before (Database-based)
py := python.new(name: 'test')!
py.update()! // Manual pip upgrade
py.pip('requests')! // Manual package tracking
After (UV-based)
py := python.new(
name: 'test'
dependencies: ['requests']
)! // Automatic setup with uv
Key Changes
- No Database: Removed all
dbfs.DB
usage - Automatic Setup: Environment initialization is automatic
- Modern Tools: Uses
uv
instead ofpip
- Project Files: Generates proper Python project structure
- Faster:
uv
is significantly faster than pip - Better Dependency Resolution:
uv
has superior dependency resolution
Shell Script Usage
Each environment generates shell scripts for manual use:
##cd ~/hero/python/my_project
source env.sh
##./install.sh
Requirements
- uv: Install with
curl -LsSf https://astral.sh/uv/install.sh | sh
- Python 3.11+: Recommended Python version
Examples
See examples/lang/python/
for complete working examples.
Performance Notes
uv
is 10-100x faster than pip for most operations- Dependency resolution is significantly improved
- Lock files ensure reproducible environments
- No manual state tracking reduces complexity and errors
fn new #
fn new(args_ PythonEnvArgs) !PythonEnv
struct PythonEnv #
struct PythonEnv {
pub mut:
name string
path pathlib.Path
}
fn (PythonEnv) add_dependencies #
fn (py PythonEnv) add_dependencies(packages []string, dev bool) !
Add dependencies to the project
fn (PythonEnv) exec #
fn (py PythonEnv) exec(args PythonExecArgs) !string
fn (PythonEnv) exists #
fn (py PythonEnv) exists() bool
Check if the Python environment exists and is properly configured
fn (PythonEnv) export_lock #
fn (py PythonEnv) export_lock() !string
Export current lock state (equivalent to uv.lock)
fn (PythonEnv) export_lock_to_file #
fn (mut py PythonEnv) export_lock_to_file(filename string) !
Export lock state to file
fn (PythonEnv) freeze #
fn (py PythonEnv) freeze() !string
Export current environment dependencies to requirements.txt
fn (PythonEnv) freeze_to_file #
fn (mut py PythonEnv) freeze_to_file(filename string) !
Export dependencies to a requirements.txt file
fn (PythonEnv) generate_all_templates #
fn (mut py PythonEnv) generate_all_templates(args TemplateArgs) !
generate_all_templates creates all template files for the Python environment
fn (PythonEnv) generate_env_script #
fn (mut py PythonEnv) generate_env_script(args TemplateArgs) !
generate_env_script creates an env.sh script from template
fn (PythonEnv) generate_install_script #
fn (mut py PythonEnv) generate_install_script(args TemplateArgs) !
generate_install_script creates an install.sh script from template
fn (PythonEnv) generate_pyproject_toml #
fn (mut py PythonEnv) generate_pyproject_toml(args TemplateArgs) !
generate_pyproject_toml creates a pyproject.toml file from template
fn (PythonEnv) generate_readme #
fn (mut py PythonEnv) generate_readme(args TemplateArgs) !
generate_readme creates a basic README.md file
fn (PythonEnv) init_env #
fn (mut py PythonEnv) init_env(args PythonEnvArgs) !
Initialize the Python environment using uv
fn (PythonEnv) install_from_requirements #
fn (py PythonEnv) install_from_requirements(filename string) !
Install dependencies from requirements.txt file
fn (PythonEnv) ipython_shell #
fn (py PythonEnv) ipython_shell() !
Open IPython if available, fallback to regular Python
fn (PythonEnv) list_packages #
fn (py PythonEnv) list_packages() ![]string
Get list of installed packages
fn (PythonEnv) pip #
fn (py PythonEnv) pip(packages string) !
Legacy pip method for backward compatibility - now uses uv add
fn (PythonEnv) pip_uninstall #
fn (py PythonEnv) pip_uninstall(packages string) !
Legacy pip_uninstall method for backward compatibility - now uses uv remove
fn (PythonEnv) python_shell #
fn (py PythonEnv) python_shell() !
Open a Python REPL in the environment
fn (PythonEnv) remove_dependencies #
fn (py PythonEnv) remove_dependencies(packages []string, dev bool) !
Remove dependencies from the project
fn (PythonEnv) restore_from_lock #
fn (py PythonEnv) restore_from_lock() !
Restore environment from lock file
fn (PythonEnv) run #
fn (py PythonEnv) run(command string) !osal.Job
Run a command in the Python environment
fn (PythonEnv) run_script #
fn (py PythonEnv) run_script(script_path string) !osal.Job
Run a specific Python script in the environment
fn (PythonEnv) shell #
fn (py PythonEnv) shell() !
Open an interactive shell in the Python environment
fn (PythonEnv) sync #
fn (py PythonEnv) sync() !
Sync dependencies using uv
fn (PythonEnv) update #
fn (py PythonEnv) update() !
Update all dependencies
fn (PythonEnv) uv_run #
fn (py PythonEnv) uv_run(command string) !osal.Job
Run a uv command in the environment context
struct PythonEnvArgs #
struct PythonEnvArgs {
pub mut:
name string = 'default'
reset bool
python_version string = '3.11'
dependencies []string
dev_dependencies []string
description string = 'A Python project managed by Herolib'
}
struct PythonExecArgs #
struct PythonExecArgs {
pub mut:
cmd string @[required]
result_delimiter string = '==RESULT=='
ok_delimiter string = '==OK=='
python_script_name string // if used will put it in root of the sandbox under that name
stdout bool = true
}
struct TemplateArgs #
struct TemplateArgs {
pub mut:
name string = 'herolib-python-project'
version string = '0.1.0'
description string = 'A Python project managed by Herolib'
python_version string = '3.11'
dependencies []string
dev_dependencies []string
scripts map[string]string
}
- README
- fn new
- struct PythonEnv
- fn add_dependencies
- fn exec
- fn exists
- fn export_lock
- fn export_lock_to_file
- fn freeze
- fn freeze_to_file
- fn generate_all_templates
- fn generate_env_script
- fn generate_install_script
- fn generate_pyproject_toml
- fn generate_readme
- fn init_env
- fn install_from_requirements
- fn ipython_shell
- fn list_packages
- fn pip
- fn pip_uninstall
- fn python_shell
- fn remove_dependencies
- fn restore_from_lock
- fn run
- fn run_script
- fn shell
- fn sync
- fn update
- fn uv_run
- struct PythonEnvArgs
- struct PythonExecArgs
- struct TemplateArgs