Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:00:18 +08:00
commit 765529cd13
69 changed files with 18291 additions and 0 deletions

View File

@@ -0,0 +1,391 @@
# PEP 723: Inline Script Metadata Specification
Complete reference for PEP 723 inline script metadata format used by uv.
## Overview
PEP 723 defines a standardized way to embed dependency and configuration metadata directly within Python script files. This eliminates the need for separate `requirements.txt` files and enables self-contained, reproducible scripts.
## Basic Format
```python
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "package-name>=1.0.0",
# ]
# ///
```
**Key Requirements:**
- Must appear as comments (`#`)
- Must use `# /// script` as opening marker
- Must use `# ///` as closing marker
- Must be valid TOML syntax
- Recommended placement: After shebang, before module docstring
## Complete Specification
### Required Fields
#### requires-python
Specifies minimum Python version:
```python
# /// script
# requires-python = ">=3.11"
# ///
```
**Formats:**
```python
requires-python = ">=3.11" # Minimum version
requires-python = ">=3.11,<3.13" # Version range
requires-python = "==3.12" # Exact version
```
#### dependencies
Lists required packages:
```python
# /// script
# dependencies = [
# "httpx>=0.27.0",
# "rich>=13.0.0",
# "typer~=0.9.0",
# ]
# ///
```
**Version Specifiers:**
```python
"package" # Any version
"package>=1.0" # Minimum version
"package>=1.0,<2.0" # Version range
"package~=1.2.3" # Compatible release (1.2.x)
"package==1.2.3" # Exact version
```
### Optional Fields
#### [tool.uv] Section
uv-specific configuration:
```python
# /// script
# requires-python = ">=3.11"
# dependencies = []
#
# [tool.uv]
# exclude-newer = "2024-10-01T00:00:00Z"
# index-url = "https://pypi.org/simple"
# ///
```
**Available options:**
- `exclude-newer`: Only use packages published before this date
- `index-url`: Alternative PyPI index
- `extra-index-url`: Additional package indexes
- `find-links`: Additional package sources
- `no-index`: Ignore PyPI entirely
#### [tool.uv.sources]
Custom package sources:
```python
# /// script
# dependencies = ["my-package"]
#
# [tool.uv.sources]
# my-package = { git = "https://github.com/user/repo", tag = "v1.0" }
# ///
```
#### Valid [tool.uv] Fields
Additional uv-specific configuration (optional):
```python
# /// script
# requires-python = ">=3.11"
# dependencies = []
#
# [tool.uv]
# exclude-newer = "2025-01-01T00:00:00Z" # Reproducibility constraint
# ///
```
**Note**: For custom metadata like purpose, team, author, use Python docstrings instead:
```python
# /// script
# requires-python = ">=3.11"
# dependencies = []
# ///
"""
Purpose: cluster-monitoring
Team: infrastructure
Author: devops@example.com
Created: 2024-10-20
"""
```
## Complete Examples
### Minimal Script
```python
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = []
# ///
"""Simple script with no dependencies"""
print("Hello, world!")
```
### Production Script
```python
#!/usr/bin/env -S uv run --script --quiet
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx>=0.27.0",
# "rich>=13.0.0",
# "typer>=0.9.0",
# ]
#
# [tool.uv]
# exclude-newer = "2025-01-01T00:00:00Z"
# ///
"""
API client for Proxmox cluster monitoring
Purpose: api-client
Team: infrastructure
Author: devops@spaceships.work
Usage:
check_cluster.py [--node NODE] [--json]
"""
import typer
import httpx
from rich import print
```
### With Git Dependencies
```python
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "my-internal-lib",
# ]
#
# [tool.uv.sources]
# my-internal-lib = { git = "https://github.com/org/lib.git", tag = "v1.2.3" }
# ///
```
### With Local Dependencies
```python
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "my-local-package",
# ]
#
# [tool.uv.sources]
# my-local-package = { path = "../my-package", editable = true }
# ///
```
## Placement Guidelines
### Correct Placement
```python
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = []
# ///
"""Module docstring comes after metadata"""
import sys
def main():
pass
if __name__ == "__main__":
main()
```
### Multiple Metadata Blocks (Invalid)
```python
# ❌ INVALID - Only one metadata block allowed
# /// script
# requires-python = ">=3.11"
# ///
# /// script
# dependencies = ["httpx"]
# ///
```
## Validation
### Valid Metadata
```python
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx>=0.27.0", # Comments allowed in arrays
# "rich",
# ]
# ///
```
### Invalid Metadata
```python
# ❌ Missing closing marker
# /// script
# requires-python = ">=3.11"
# ❌ Invalid TOML syntax
# /// script
# dependencies = httpx # Missing quotes
# ///
# ❌ Not in comments
/// script
requires-python = ">=3.11"
///
```
## Creating Metadata
### Manual Creation
Add metadata block manually:
```python
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx>=0.27.0",
# ]
# ///
import httpx
```
### Using uv init
Generate script with metadata:
```bash
uv init --script my_script.py --python 3.11
```
### Using uv add
Add dependencies to existing script:
```bash
uv add --script my_script.py httpx rich typer
```
## Validation Tools
### Check Metadata Validity
```bash
# Parse metadata
uv run --script my_script.py --dry-run
# Validate with custom tool
python tools/validate_script.py my_script.py
```
### Extract Metadata
```python
import re
import tomllib
def extract_metadata(script_path: str) -> dict:
"""Extract PEP 723 metadata from script"""
with open(script_path) as f:
content = f.read()
# Find metadata block
pattern = r'# /// script\n((?:# .*\n)+)# ///'
match = re.search(pattern, content)
if not match:
return {}
# Parse TOML (remove leading # from each line)
toml_lines = match.group(1).split('\n')
toml_content = '\n'.join(line[2:] for line in toml_lines if line.startswith('# '))
return tomllib.loads(toml_content)
```
## Compatibility
### PEP 723 Support
- ✅ uv (native support)
- ✅ pip (via `pip-run`)
- ✅ pipx (v1.4.0+)
- ⚠️ Other tools (check documentation)
### Fallback for Non-Supporting Tools
```python
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.11"
# dependencies = ["httpx"]
# ///
"""
Fallback installation for non-PEP-723 tools:
pip install httpx
python script.py
"""
```
## Best Practices
1. **Always include requires-python** - Prevents compatibility issues
2. **Pin major versions** - `>=X.Y.Z` for stability
3. **Add metadata section** - Document purpose and ownership
4. **Keep dependencies minimal** - Only what's necessary
5. **Document fallbacks** - Help non-uv users
6. **Validate syntax** - Use validation tools
7. **Version consistently** - Match project conventions
## References
- [PEP 723 Specification](https://peps.python.org/pep-0723/)
- [uv Documentation](https://docs.astral.sh/uv/)
- [TOML Specification](https://toml.io/)
- [Python Version Specifiers](https://peps.python.org/pep-0440/)