Registry / devops / twine
library7.0.0pypypi✓ verified 27d ago

Twine is a utility for publishing Python packages to PyPI and other repositories. It provides build system independent uploads of source and binary distribution artifacts, enhancing security and testability compared to older methods. The current version is 6.2.0, released on September 4, 2025, and it is actively maintained with frequent updates.

pip install twine
INSTALL
IMPORT
SIG · TWINE
T
twine
devopspythonv7.0.0
Install
5.6s avg
Import
Disk
61MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v7.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 62.4MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 5.6s · import 0.000s · 62MB
61MB installed
● package 61MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

twine (CLI)
twine upload dist/*
Twine is primarily a command-line utility for package publishing. Direct programmatic import of its core upload functionality is not the common or recommended usage pattern for end-users.

This quickstart guides you through building your Python package distributions (sdist and wheel), checking them for common issues, and then uploading them to TestPyPI for verification before a final upload to the official PyPI. It emphasizes using API tokens for authentication via environment variables for security.

# 1. Ensure your distribution files (wheels, sdists) are built: # (Use `python -m build` as a modern alternative to `python setup.py sdist bdist_wheel`) python -m build # 2. (Optional but recommended) Check your package metadata and README rendering: twine check dist/* # 3. (Optional but recommended) Upload to TestPyPI first to verify: # Set TWINE_USERNAME and TWINE_PASSWORD environment variables with your TestPyPI API token # For example, in bash: # export TWINE_USERNAME="__token__" # export TWINE_PASSWORD="pypi-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Or, you will be prompted for credentials. # Replace 'your_test_pypi_api_token' with your actual TestPyPI API token import os os.environ['TWINE_USERNAME'] = os.environ.get('TEST_PYPI_USERNAME', '__token__') os.environ['TWINE_PASSWORD'] = os.environ.get('TEST_PYPI_PASSWORD', 'pypi-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') print("Uploading to TestPyPI...") # This command will be run via subprocess in a real application # For quickstart, it implies running directly in shell: # !twine upload --repository testpypi dist/* # In a Python context, you'd use subprocess.run() # 4. Upload to PyPI (after successful TestPyPI verification): # Set TWINE_USERNAME and TWINE_PASSWORD environment variables with your PyPI API token # For example, in bash: # export TWINE_USERNAME="__token__" # export TWINE_PASSWORD="pypi-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" # Or, you will be prompted for credentials. # Replace 'your_pypi_api_token' with your actual PyPI API token os.environ['TWINE_USERNAME'] = os.environ.get('PYPI_USERNAME', '__token__') os.environ['TWINE_PASSWORD'] = os.environ.get('PYPI_PASSWORD', 'pypi-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY') print("Uploading to PyPI...") # !twine upload dist/*
twine --version
Debug
Known issues
breakingThe `python setup.py upload` command is deprecated and insecure. Twine is the official, secure, and recommended tool for uploading packages to PyPI.
fix
Always use `twine upload` instead of `python setup.py upload`. Ensure you build your distribution artifacts first using `python -m build`.
affects: < 4.0.0 (and continued deprecation warnings in newer Python versions)
breakingSince Twine 5.0.0, only `__token__` is supported as a username when uploading to PyPI and TestPyPI. Supplying any other username will cause the upload to fail.
fix
When using API tokens, always set the username to `__token__`. Your API token should be used as the password. This applies whether using environment variables (`TWINE_USERNAME`, `TWINE_PASSWORD`), `.pypirc`, or `keyring`.
affects: >= 5.0.0
breakingTwine 6.0.0 changed the default username behavior for PyPI/TestPyPI. It now defaults to `__token__` and no longer overrides a username configured via environment variables or command line if that username is *not* `__token__`. Workflows that implicitly relied on Twine overriding a non-`__token__` username will now fail.
fix
Explicitly set `TWINE_USERNAME='__token__'` (or use `--username __token__` on the CLI) if you intend to use an API token. Do not rely on previous implicit override behavior.
affects: >= 6.0.0
deprecatedThe `--skip-existing` flag is no longer supported for non-PyPI upload targets (e.g., custom package indexes). It also no longer submits `md5_digest` field as it's deprecated on PyPI.
fix
Remove `--skip-existing` when uploading to non-PyPI repositories. For PyPI, the flag will still work but consider the implications. The `md5_digest` removal is automatic and requires no user action.
affects: >= 6.2.0
gotcha`twine check dist/*` may fail if your `README` file is not named exactly `README` and you are using the dynamic `readme` option in `pyproject.toml`.
fix
Ensure your `README` file is named `README` (e.g., `README.md`) if using `dynamic = ["readme"]` in `pyproject.toml` for metadata. Despite the check failure, the package might still upload successfully, but it's best to resolve the warning for proper rendering.
affects: All versions (with `pyproject.toml` dynamic readme)
gotchaUsing `twine upload dist/*` can inadvertently upload older or incorrect distribution files if your `dist/` directory contains multiple versions or unwanted artifacts.
fix
Always ensure your `dist/` directory contains only the desired distribution files for the current upload. Consider clearing the `dist/` directory before building new distributions or being more specific with the file path, e.g., `twine upload dist/my_package-1.2.3-*`.
affects: All versions
breakingAttempting to execute shell commands like `python -m build` directly as statements within a Python script will result in a `SyntaxError`. These are shell commands, not valid Python syntax.
fix
To execute shell commands from within a Python script, use the `subprocess` module (e.g., `import subprocess; subprocess.run(['python', '-m', 'build'], check=True)`). Alternatively, ensure the script containing such commands is intended to be a shell script and is executed directly by the shell, not by the Python interpreter.
affects: All Python versions
breakingPlacing shell commands, such as `python -m build`, directly into a Python script will cause a `SyntaxError` when the script is executed by the Python interpreter.
fix
Shell commands must be run in a shell environment (e.g., a `.sh` script, directly in the terminal, or by using `subprocess.run()` if called from Python code). Do not include them directly as lines of code in a `.py` file.
affects: All Python versions
Upgrade
Version history
7.0.0latest on PyPI · released Jul 27, 2026
Audit
Dependencies
keyringoptionalUsed for secure storage of PyPI credentials; highly recommended for production environments.
readme-rendererrequiredUsed by `twine check` to validate how your package's long description will render on PyPI.
requestsrequiredCore HTTP library for making authenticated uploads.
Agent activity
24 hits · last 30 days
node
20
Amazon
1
OpenAI (training)
1
Resources
twine — pip install twine · libregistry