pypirc
PyPIRC Playbook: Secure Credential Management for Python Packaging
Key Takeaways
- PyPIRC stores PyPI credentials in
~/.pypircwith strict file permissions (600) - Always use API tokens instead of plaintext passwords for PyPI uploads
- Configure multiple repository indexes (TestPyPI, private repos) in a single file
- Verify configuration with
twine checkbefore uploading packages - Never commit .pypirc to version control; add to .gitignore
What is a .pypirc File?
The .pypirc file is a configuration file used by Python packaging tools (pip, twine, setuptools) to store authentication credentials and repository URLs for Python Package Index (PyPI) and other package repositories. Located in your home directory at ~/.pypirc, this file follows INI format and enables seamless package publishing without repeatedly entering credentials.
Creating Your .pypirc File
Step-by-Step Setup
- Generate a PyPI API token from your PyPI account settings
- Create the file with restrictive permissions:
touch ~/.pypirc && chmod 600 ~/.pypirc - Edit the file with a secure text editor
- Add repository configurations and credentials
- Verify file permissions:
ls -la ~/.pypirc
Basic Configuration Template
[pypi]
username = __token__
password = pypi-your-api-token-here
[distutils]
index-servers =
pypi
testpypi
Advanced Repository Configurations
Multiple Index Support
[distutils]
index-servers =
pypi
testpypi
private-repo
[pypi]
repository = https://upload.pypi.org/legacy/
username = __token__
password = pypi-your-production-token
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-your-test-token
[private-repo]
repository = https://your-private-pypi.com/simple/
username = your-username
password = your-password
Per-Project Overrides
Create a local .pypirc in project root for project-specific credentials. Use TWINE_REPOSITORY_FILE environment variable to specify custom paths:
export TWINE_REPOSITORY_FILE=/path/to/custom.pypirc
Security Best Practices Checklist
- Set file permissions to 600 (
chmod 600 ~/.pypirc) - Use API tokens instead of account passwords
- Add
.pypircto.gitignore - Rotate API tokens every 90 days
- Use separate tokens for TestPyPI and production PyPI
- Store tokens with minimal required scopes
- Never share .pypirc files via email or chat
- Audit token usage through PyPI dashboard
Troubleshooting Common Issues
Error: "InvalidConfiguration: Source distribution list"
Ensure [distutils] section lists all index servers correctly with proper indentation (no tabs, consistent spaces).
Error: "403 Client Error: Invalid or non-existent authentication information"
- Verify API token format starts with
pypi- - Check token hasn't expired or been revoked
- Confirm
username = __token__is set exactly
Error: "Could not detect required program: twine"
Install Twine: pip install twine
Comparison Table: PyPIRC vs Environment Variables
| Feature | .pypirc File | Environment Variables |
|---|---|---|
| Storage Location | Home directory | Shell/environment |
| Version Control Risk | High (if not ignored) | None |
| Multiple Repositories | Native support | Requires separate vars |
| CI/CD Integration | Less secure | Better with secrets |
| Portability | Manual transfer | Easy with CI systems |
| Recommended For | Local development | Production/CI environments |
Testing Your Configuration
- Run
twine check dist/*to validate package metadata - Test upload to TestPyPI:
twine upload --repository testpypi dist/* - Verify credentials work:
twine upload --repository pypi --skip-existing dist/*
FAQs
Can I store multiple API tokens in .pypirc?
Yes. Define separate sections like [pypi], [testpypi], and custom repository names. Each section holds its own credentials. Use --repository flag with twine to select which configuration to use.
How do I rotate a compromised API token?
Immediately revoke the token in your PyPI account settings, generate a new one, update ~/.pypirc with the new token, verify file permissions, then run twine check to confirm the new credentials work before uploading.
Is .pypirc compatible with CI/CD pipelines?
For CI/CD, prefer environment variables (TWINE_USERNAME, TWINE_PASSWORD) over committing .pypirc. Use your CI system's secret management features. If required, create the file dynamically during pipeline execution with proper cleanup.