| name | python-uv-scripts |
| description | Python single-file script development using uv and PEP 723 inline metadata, preventing invalid patterns like [tool.uv.metadata].
|
| when_to_use | Use when creating standalone Python utilities, converting scripts to uv format, managing script dependencies, implementing script testing, or establishing team standards for script development.
|
Python Single-File Scripts with uv
Expert guidance for creating production-ready, self-contained Python scripts using uv's inline dependency management
(PEP 723).
Quick Start
Create Your First uv Script
import httpx
from rich import print
response = httpx.get("https://api.github.com")
print(f"[green]Status: {response.status_code}[/green]")
Make it executable:
chmod +x script.py
./script.py
Convert Existing Script
./tools/convert_to_uv.py existing_script.py
./tools/validate_script.py script.py
Core Concepts
What is PEP 723?
PEP 723 defines inline script metadata for Python files:
Benefits:
- ✅ Dependencies live with the code
- ✅ No separate
requirements.txt
- ✅ Reproducible execution
- ✅ Version constraints included
- ✅ Self-documenting
uv Script Execution Modes
Mode 1: Inline Dependencies (Recommended for utilities)
Mode 2: Project Mode (For larger scripts)
uv run script.py
Mode 3: No Dependencies
Critical Anti-Patterns: What NOT to Do
❌ NEVER Use [tool.uv.metadata]
WRONG - This will cause errors:
Error:
error: TOML parse error at line 3, column 7
unknown field `metadata`
Why: [tool.uv.metadata] is not part of PEP 723 and is not supported by uv.
CORRECT - Use Python docstrings for metadata:
"""
Purpose: Testing automation
Team: DevOps
Author: team@example.com
"""
Valid tool.uv fields (if needed):
Real-World Examples from This Repository
Example 1: Cluster Health Checker
See examples/03-production-ready/check_cluster_health_enhanced.py
Current version (basic):
import subprocess
Enhanced with uv (production-ready):
"""
Purpose: Cluster health monitoring
Team: Infrastructure
"""
import typer
from rich.console import Console
from rich.table import Table
Example 2: CEPH Health Monitor
See examples/03-production-ready/ceph_health.py
Pattern: JSON API interaction with structured output
Best Practices from This Repository
1. Security Patterns
See reference/security-patterns.md for complete security guide including:
- Secrets management (environment variables, keyring, Infisical)
- Input validation
- Dependency security
- File operations security
- Command execution security
2. Version Pinning Strategy
Following this repository's approach (from pyproject.toml):
Pinning levels:
>=X.Y.Z - Minimum version (most flexible)
~=X.Y.Z - Compatible release (patch updates only)
==X.Y.Z - Exact version (most strict)
See reference/dependency-management.md.
3. Team Standards
File naming:
check_cluster_health.py
validate_template.py
cluster.py
Shebang pattern:
Documentation template:
"""
Check Proxmox cluster health
Purpose: cluster-monitoring
Team: infrastructure
Author: devops@spaceships.work
Usage:
python check_cluster_health.py [--node NODE] [--json]
Examples:
python check_cluster_health.py --node foxtrot
python check_cluster_health.py --json
"""
4. Error Handling Patterns
Following Ansible best practices from this repository:
import sys
import subprocess
def run_command(cmd: str) -> str:
"""Execute command with proper error handling"""
try:
result = subprocess.run(
cmd.split(),
capture_output=True,
text=True,
check=True
)
return result.stdout
except subprocess.CalledProcessError as e:
print(f"Error: Command failed: {cmd}", file=sys.stderr)
print(f" {e.stderr}", file=sys.stderr)
sys.exit(1)
except FileNotFoundError:
print(f"Error: Command not found: {cmd.split()[0]}", file=sys.stderr)
sys.exit(1)
See patterns/error-handling.md.
5. Testing Patterns
Inline testing (for simple scripts):
def validate_ip(ip: str) -> bool:
"""Validate IP address format"""
import re
pattern = r'^(\d{1,3}\.){3}\d{1,3}$'
return bool(re.match(pattern, ip))
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == "--test":
assert validate_ip("192.168.1.1") == True
assert validate_ip("256.1.1.1") == False
print("All tests passed!")
sys.exit(0)
print(validate_ip("192.168.3.5"))
See workflows/testing-strategies.md.
When NOT to Use Single-File Scripts
See anti-patterns/when-not-to-use.md for details.
Use a proper project instead when:
- ❌ Script exceeds 500 lines
- ❌ Multiple modules/files needed
- ❌ Complex configuration management
- ❌ Requires packaging/distribution
- ❌ Shared library code across multiple scripts
- ❌ Web applications or long-running services
Example - Too Complex for Single File:
Common Patterns
See pattern guides for complete examples:
CI/CD Integration
GitHub Actions
name: Run Health Checks
on:
schedule:
- cron: '0 */6 * * *'
jobs:
health-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Check cluster health
run: |
uv run --script tools/check_cluster_health.py --json
env:
PROXMOX_TOKEN: ${{ secrets.PROXMOX_TOKEN }}
GitLab CI
cluster-health:
image: ghcr.io/astral-sh/uv:python3.11-bookworm-slim
script:
- uv run --script tools/check_cluster_health.py
only:
- schedules
See workflows/ci-cd-integration.md.
Tools Available
Script Validation
./tools/validate_script.py script.py
Script Conversion
./tools/convert_to_uv.py old_script.py
Progressive Disclosure
For deeper knowledge:
Reference Documentation
Pattern Guides
Note: See Common Patterns section above for quick access to these guides.
Working Examples
- NetBox API Client - Production-ready API client with Infisical, validation, error handling, and Rich output
- Cluster Health Checker - Production-ready monitoring script with Typer, Rich, and JSON output
Anti-Patterns
Workflows
Related Skills
- Ansible Best Practices - Many Ansible modules could be standalone uv scripts
- Proxmox Infrastructure - Validation tools use this pattern
- NetBox + PowerDNS Integration - API interaction scripts
Quick Reference
Shebang Options
Common Dependencies
"typer>=0.9.0"
"click>=8.0.0"
"rich>=13.0.0"
"httpx>=0.27.0"
"requests>=2.31.0"
"polars>=0.20.0"
"pandas>=2.0.0"
"ansible>=11.1.0"
"infisical-python>=2.3.3"
"psutil>=5.9.0"
Metadata Template
"""
One-line description
Purpose: describe-purpose
Team: team-name
Author: email@example.com
Usage:
python script.py [OPTIONS]
Examples:
python script.py --help
"""
Best Practices Summary
- Always specify Python version -
requires-python = ">=3.11"
- Pin dependencies appropriately - Use
>=X.Y.Z for utilities
- Add metadata in docstrings - Put team info, purpose, and author in module docstring
- Include comprehensive docstrings - Document purpose, usage, and examples
- Handle errors gracefully - Use try/except with clear messages
- Validate inputs - Check arguments before processing
- Use quiet mode -
--quiet flag for production scripts
- Keep it focused - Single file, single purpose
- Test inline - Add
--test flag for simple validation
- Secure secrets - Never hardcode, use env vars or keyring