# Source to installation ## Build an sdist - Inputs - Source - Build backend - Dependencies - Environment - Output - sdist Go from source to an sdist. ## Build a wheel - Inputs - sdist - Build backend - Dependencies - Environment - Output - wheel Use an sdist to build a wheel. ## Upload to PyPI - Inputs - sdist - wheels - Access token - Environment - Metadata - Output - N/A ## Download from an index - Inputs - Installer - Metadata - File names - Environment - Output - File to install Resolve what to download and download it. ## Install - Inputs - Installer - wheel - sdist - Build backend - Dependencies - Environment - Output - Files on disk Take what you downloaded and install it. # Mitigations - [[Reproducible builds]] - [Better defaults](https://nesbitt.io/2026/03/31/npms-defaults-are-bad.html) - Opt into using anything other than wheels - Cooldown - Implicitly update lock files - Lock files - Cooldown - Attestations - Trusted Publishing - Staged uploads w/ 2FA - External hash verification - CVEs