This guide explains how to publish and validate the QuickFix Python package to PyPI (Python Package Index).
-
Install required tools:
pip install twine build
-
Set up PyPI accounts:
- Test PyPI: https://test.pypi.org/account/register/
- Production PyPI: https://pypi.org/account/register/
-
Configure authentication (recommended):
Create a
~/.pypircfile with API tokens:[distutils] index-servers = pypi testpypi [pypi] username = __token__ password = pypi-YOUR-PRODUCTION-TOKEN [testpypi] username = __token__ password = pypi-YOUR-TEST-TOKEN
To generate tokens:
- Test PyPI: https://test.pypi.org/manage/account/#api-tokens
- Production PyPI: https://pypi.org/manage/account/#api-tokens
Use the standalone publish script:
./publish-test-pypi.shThis script:
- Cleans previous builds
- Builds the package from the prepared
quickfix-python/directory - Runs quality checks with
twine check - Uploads to Test PyPI
Note: You must run ./package-python.sh --build-only first to prepare the package files.
Use the enhanced package-python.sh script that handles both packaging and publishing:
# Build and upload to Test PyPI (default)
./package-python.sh
# Or explicitly specify Test PyPI
./package-python.sh --test-pypi
# Build and upload to Production PyPI
./package-python.sh --pypi
# Only build, don't upload
./package-python.sh --build-onlyThis script:
- Copies files from the main
quickfix/repository - Prepares the
quickfix-python/directory - Builds the distribution
- Optionally uploads based on the mode
Before validating, you can inspect what's actually included in your distribution package:
./inspect-package.shOr inspect a specific distribution file:
./inspect-package.sh quickfix-python/dist/quickfix-0.0.1.tar.gzThis script shows:
- Directory structure of the package
- Presence of key directories (C++, swig, spec, etc.)
- File counts by type (.h, .cpp, .py, .xml)
- Contents of the swig directory
- Include directories referenced in setup.py
This is useful for quickly verifying that all necessary files (especially swig headers) are included before running full validation tests.
Recommended: Test your locally built package before uploading to any PyPI repository:
./validate-local-python-build.shOr specify a specific distribution file:
./validate-local-python-build.sh quickfix-python/dist/quickfix-1.15.1.tar.gzThe local validation script:
- Finds the most recent built package (or uses the specified file)
- Runs
twine checkfor package quality validation - Creates a fresh Python virtual environment
- Installs the package from the local file
- Runs comprehensive tests:
- Module import test (all FIX version modules)
- Core classes availability check
- FIX specification files check
- Message creation test (FIX 4.2, 4.4, 5.0)
- SessionSettings configuration test
- Reports success or failure
After publishing to Test PyPI, validate that the package works correctly when installed by users:
./validate-test-pypi.shOr validate a specific version:
./validate-test-pypi.sh 1.15.1The Test PyPI validation script:
- Creates a fresh Python virtual environment
- Installs the package from Test PyPI (simulating a real user installation)
- Runs the following tests:
- Module import test
- Version check
- Core classes availability check
- FIX specification files check
- Basic message creation test
- Reports success or failure
Successful validation will show:
✓ Successfully imported quickfix
✓ Installed version: 1.15.1
✓ All core classes are available
✓ FIX specification files are installed
✓ Basic FIX message creation successful
✓ All validation tests passed!
# Step 1: Prepare and package
./package-python.sh --build-only
# Step 2: Inspect package contents (optional but recommended)
./inspect-package.sh
# Step 3: Validate the local build
./validate-local-python-build.sh
# Step 4: Publish to Test PyPI (only if local validation passed)
./publish-test-pypi.sh
# Step 5: Validate the published package
./validate-test-pypi.sh# Step 1: Test everything on Test PyPI first (see above)
# Step 2: Build for production
./package-python.sh --build-only
# Step 3: Inspect package contents (verify swig and other files)
./inspect-package.sh
# Step 4: Validate the local build one more time
./validate-local-python-build.sh
# Step 5: Publish to Production PyPI (only if validation passed)
./package-python.sh --pypi
# Step 6: Validate from production
# Install in a new environment and test:
python3 -m venv prod_test
source prod_test/bin/activate
pip install quickfix
python -c "import quickfix; print('Success!')"
deactivateIf you get authentication errors:
-
Using API tokens (recommended):
- Ensure your
~/.pypircfile is correctly configured - Username should be
__token__ - Password should be your full API token (starts with
pypi-)
- Ensure your
-
Using username/password:
- You'll be prompted during upload
- For Test PyPI, use your test.pypi.org credentials
- For Production, use your pypi.org credentials
If the package fails to build:
- Ensure you've cloned the quickfix repository first
- Check that all required C++ source files exist
- Verify Python development headers are installed
- Check the build logs in
quickfix-python/build/
If files (like swig headers) are missing from the distribution:
- Inspect the package first: Run
./inspect-package.shto see what's included - Check MANIFEST.in: Ensure
quickfix-python/MANIFEST.inincludes all necessary directories - Rebuild: After fixing MANIFEST.in, rebuild with
./package-python.sh --build-only - Verify: Run
./inspect-package.shagain to confirm files are now included
If validation fails:
- Import errors: The C++ extension may not have compiled correctly
- Missing classes: Check the package version and source
- Missing spec files: Verify
MANIFEST.inincludes the spec files - Header file issues: Use
./inspect-package.shto verify swig and C++ headers are included
PyPI does not allow re-uploading the same version. If you need to fix something:
- Test PyPI: You can delete the release and re-upload
- Production PyPI: You must increment the version number in
setup.py
- Inspect package contents - Run
./inspect-package.shto verify all files (especially swig headers) are included - Always validate locally first - Run
./validate-local-python-build.shbefore uploading anywhere - Always test on Test PyPI first before publishing to production
- Run validation after publishing - Verify the package works when installed by users
- Increment version numbers in
setup.pybefore publishing - Tag releases in git to track published versions
- Keep credentials secure - never commit
.pypircto git
| Command | Purpose |
|---|---|
./package-python.sh --build-only |
Build package only |
./package-python.sh --test-pypi |
Build and upload to Test PyPI |
./package-python.sh --pypi |
Build and upload to Production PyPI |
./publish-test-pypi.sh |
Upload pre-built package to Test PyPI |
./inspect-package.sh |
Inspect contents of built package |
./inspect-package.sh FILE |
Inspect specific distribution file |
./validate-local-python-build.sh |
Validate locally built package before uploading |
./validate-local-python-build.sh FILE |
Validate specific local distribution file |
./validate-test-pypi.sh |
Validate package from Test PyPI |
./validate-test-pypi.sh VERSION |
Validate specific version from Test PyPI |
- Test PyPI: https://test.pypi.org/
- Production PyPI: https://pypi.org/
- Twine documentation: https://twine.readthedocs.io/
- Python packaging guide: https://packaging.python.org/