This guide explains how to publish python-emc2305 to the Python Package Index (PyPI).
- Create account at https://pypi.org/account/register/
- Verify your email address
- Set up Two-Factor Authentication (2FA) - REQUIRED for publishing
- Create account at https://test.pypi.org/account/register/
- This is separate from the main PyPI account
pip install --upgrade build twineGenerate API tokens instead of using passwords:
For PyPI:
- Go to https://pypi.org/manage/account/token/
- Create a token with scope limited to
python-emc2305(after first upload) - Save token securely (you'll only see it once)
For TestPyPI:
- Go to https://test.pypi.org/manage/account/token/
- Create a token
- Save token securely
Create ~/.pypirc:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-YOUR-API-TOKEN-HERE
[testpypi]
username = __token__
password = pypi-YOUR-TEST-API-TOKEN-HEREImportant: Set restrictive permissions:
chmod 600 ~/.pypircBefore publishing, ensure:
- Version number updated in:
-
setup.py -
pyproject.toml -
emc2305/__init__.py
-
-
CHANGELOG.mdupdated with release notes - All tests passing:
pytest tests/ -v - Code quality checks passing:
-
black --check emc2305/ tests/ -
isort --check-only emc2305/ tests/ -
ruff check emc2305/
-
- Documentation up to date
- Git tag created:
git tag -a v0.1.0 -m "Release 0.1.0" - Changes committed and pushed to GitHub
- GitHub CI/CD passing
rm -rf build/ dist/ *.egg-infopython -m buildThis creates:
dist/microchip-emc2305-0.1.0.tar.gz(source distribution)dist/microchip_emc2305-0.1.0-py3-none-any.whl(wheel distribution)
# Check tarball contents
tar -tzf dist/microchip-emc2305-0.1.0.tar.gz
# Check wheel contents
unzip -l dist/microchip_emc2305-0.1.0-py3-none-any.whltwine check dist/*Expected output:
Checking dist/microchip-emc2305-0.1.0.tar.gz: PASSED
Checking dist/microchip_emc2305-0.1.0-py3-none-any.whl: PASSED
Always test on TestPyPI before publishing to production PyPI!
twine upload --repository testpypi dist/*Or with explicit URL:
twine upload --repository-url https://test.pypi.org/legacy/ dist/*# Create fresh virtual environment
python3 -m venv test-env
source test-env/bin/activate
# Install from TestPyPI
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ microchip-emc2305
# Note: --extra-index-url allows dependencies to be installed from main PyPIpython3 << 'EOF'
import emc2305
print(f"Version: {emc2305.__version__}")
print(f"Author: {emc2305.__author__}")
# Test imports
from emc2305 import FanController, EMC2305, I2CBus
from emc2305 import ControlMode, FanStatus
print("All imports successful!")
EOF# Test basic functionality
PYTHONPATH=. python3 examples/python/test_fan_control.py- TestPyPI installation successful
- All imports working
- Version number is correct
- CHANGELOG.md is up to date
- Git tag pushed:
git push origin v0.1.0
twine upload dist/*- Check PyPI page: https://pypi.org/project/microchip-emc2305/
- Verify metadata, description, links
- Check that badges work in README
# Fresh virtual environment
python3 -m venv prod-test-env
source prod-test-env/bin/activate
# Install from PyPI
pip install microchip-emc2305
# Verify
python3 -c "import emc2305; print(emc2305.__version__)"- Go to https://github.com/moffa90/python-emc2305/releases
- Click "Draft a new release"
- Select tag:
v0.1.0 - Title:
v0.1.0 - Initial Release - Copy release notes from
CHANGELOG.md - Attach distribution files (optional)
- Publish release
- Announce release on GitHub Discussions
- Update documentation if needed
- Respond to any issues that arise
- Monitor PyPI download statistics
Follow Semantic Versioning (semver):
MAJOR.MINOR.PATCH(e.g.,1.2.3)- MAJOR: Breaking changes
- MINOR: New features, backwards compatible
- PATCH: Bug fixes, backwards compatible
- Alpha:
0.1.0a1,0.1.0a2 - Beta:
0.1.0b1,0.1.0b2 - Release Candidate:
0.1.0rc1,0.1.0rc2
You cannot overwrite a published version. You must:
- Delete files from TestPyPI (if testing)
- Increment version number
- Rebuild and re-upload
- Ensure you're using
__token__as username - Verify API token is correct
- Check token hasn't expired or been revoked
- Project name may be taken
- You may not have permissions
- 2FA may be required
Ensure long_description_content_type="text/markdown" in setup.py.
Check MANIFEST.in includes all necessary files.
- Make bug fixes
- Update version numbers
- Update CHANGELOG.md
- Create git tag
- Build and publish
- Add new features
- Update version numbers
- Update CHANGELOG.md
- Update documentation
- Create git tag
- Build and publish
- Finalize breaking changes
- Update all documentation
- Update migration guide
- Update version numbers
- Update CHANGELOG.md
- Create git tag
- Build and publish
- Announce widely
Consider automating releases with GitHub Actions:
# .github/workflows/publish.yml
name: Publish to PyPI
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install build twine
- name: Build package
run: python -m build
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload dist/*- Never commit API tokens to git
- Use API tokens, not passwords
- Enable 2FA on PyPI account
- Use scoped tokens (project-specific)
- Rotate tokens periodically
- Use
.pypircwith restricted permissions (600)
- PyPI: https://pypi.org/
- TestPyPI: https://test.pypi.org/
- Packaging Guide: https://packaging.python.org/
- Twine Documentation: https://twine.readthedocs.io/
- PEP 517 (Build): https://peps.python.org/pep-0517/
- PEP 621 (pyproject.toml): https://peps.python.org/pep-0621/
# Complete release workflow
VERSION="0.1.0"
# 1. Update version numbers
vim setup.py pyproject.toml emc2305/__init__.py CHANGELOG.md
# 2. Run tests
pytest tests/ -v
black --check emc2305/ tests/
ruff check emc2305/
# 3. Commit and tag
git add -A
git commit -m "chore: prepare release v${VERSION}"
git tag -a "v${VERSION}" -m "Release ${VERSION}"
git push origin main --tags
# 4. Build
rm -rf build/ dist/ *.egg-info
python -m build
twine check dist/*
# 5. Test on TestPyPI
twine upload --repository testpypi dist/*
# 6. Verify TestPyPI installation
python3 -m venv test-env && source test-env/bin/activate
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ microchip-emc2305
# 7. Publish to PyPI
twine upload dist/*
# 8. Verify PyPI installation
deactivate
python3 -m venv prod-env && source prod-env/bin/activate
pip install microchip-emc2305
python3 -c "import emc2305; print(emc2305.__version__)"Ready to publish? Follow the checklist above and publish with confidence!