Configure PyPI with Nexus
Configure your PyPI clients to connect to and authenticate to a Nexus PyPI repository. Create a PyPI repository in Nexus before you configure your clients. Refer to Create a PyPI Repository for more details.
PyPI can be configured through the following methods:
Configuration method | Client or file | Best for |
|---|---|---|
pip configuration |
| Install and search packages from a group, proxy, or hosted repository |
uv configuration |
| Install packages and sync project dependencies through Nexus |
Poetry configuration |
| Install dependencies and configure publish targets |
Twine configuration |
| Publish packages to a hosted repository |
Configure pip
Use this configuration method when you want pip to install or search packages through Nexus Repository. Create a pip.conf file on Unix or a pip.ini file on Windows.
[global] index-url = http://<authentication>@<NEXUS_URL>:<port>/repository/<REPO_NAME>/simple trusted-host = <NEXUS_HOST>
Where,
<NEXUS_URL>- Your Nexus instance URL.<REPO_NAME>- Name of the target repository in Nexus. Use a group repository when you want one endpoint for proxy and hosted content.<NEXUS_HOST>- Nexus host name used bypipwhen the repository is not served over SSL.
Example with basic authentication:
[global] index-url = http://adminuser:[email protected]:8081/repository/pypi-all/simple trusted-host=example.nexus.com
Example with environmental variables:
export PIP_INDEX_URL=http://example.nexus.com:8081/repository/pypi-all/simple export PIP_TRUSTED_HOST=example.nexus.com
Example for multiple repositories:
[global]
index-url = http://nexus.example.com:8081/repository/pypi-all/simple
extra-index-url =
http://nexus.example.com:8081/repository/pypi-hosted/simple
http://nexus.example.com:8081/repository/pypi-proxy/simple
trusted-host=example.nexus.com
Example with usertoken:
PIP_INDEX_URL=http://build-user:[email protected]:8081/repository/pypi-all/simple PIP_TRUSTED_HOST=example.nexus.com
To verify your configuration, run:
pip config list -v
Note
When you use pip, Sonatype recommends serving Nexus Repository over SSL. Otherwise, add --trusted-host to your requests or configure pip to trust your Nexus Repository host.
You can also configure pip with PIP_INDEX_URL and PIP_TRUSTED_HOST or pass --index-url on the command line. To use more than one repository, add extra-index-url entries.
Configure uv
Use this configuration method when you want uv to install packages and sync project dependencies through Nexus Repository.
[[tool.uv.index]] name = "<INDEX_NAME>" url = "http://<NEXUS_URL>:<port>/repository/<REPO_NAME>/simple" default = true
Where,
<INDEX_NAME>- Name of the index entry in yourpyproject.tomlfile.<NEXUS_URL>- Your Nexus instance URL.<REPO_NAME>- Name of the target repository in Nexus.
Example with basic authentication:
[[tool.uv.index]] name = "nexus" url = "http://adminusername:[email protected]:8081/repository/pypi-all/simple" default = true
Example with environmental variables:
export UV_INDEX_URL=http://example.nexus.com:8081/repository/pypi-all/simple
Example for multiple repositories:
[[tool.uv.index]] name = "nexus-all" url = "http://example.nexus.com:8081/repository/pypi-all/simple" default = true [[tool.uv.index]] name = "nexus-hosted" url = "http://example.nexus.com:8081/repository/pypi-hosted/simple" [[tool.uv.index]] name = "nexus-proxy" url = "http://example.nexus.com:8081/repository/pypi-proxy/simple"
Example with usertoken:
uv pip install requests --index-url http://username:[email protected]:8081/repository/pypi-all/simple
Note
You can also configure uv with UV_INDEX_URL, pass --index-url on the command line, or add multiple [[tool.uv.index]] entries when you need more than one repository. To embed basic authentication, include credentials in the index URL.
Configure Poetry
Use this configuration method when you want Poetry to install dependencies through Nexus Repository and publish packages to a hosted repository.
Using poetry config:
poetry source add --priority=primary <SOURCE_NAME> http://<NEXUS_URL>/repository/<REPO_NAME>/simple poetry config http-basic.<SOURCE_NAME> <USERNAME> <PASSWORD>
Where,
<SOURCE_NAME>- Source name used by Poetry.<NEXUS_URL>- Your Nexus instance URL.<REPO_NAME>- Name of the target repository in Nexus.<USERNAME>- Your Nexus username.<PASSWORD>- Your Nexus password or user token.
Example using poetry config:
poetry source add --priority=primary nexus http://example.nexus.com/repository/pypi-all/simple poetry config http-basic.nexus admin admin123
Using pyproject.toml:
[[tool.poetry.source]] name = "nexus" url = "http://localhost:8081/repository/pypi-all/simple" priority = "primary"
Store the authentication in poetry config:
poetry config http-basic.nexus username password
Note
The source add command writes the source entry to pyproject.toml. You can also define the source directly in pyproject.toml.
Example with environmental variables:
export POETRY_REPOSITORIES_NEXUS_URL=http://nexus.example.com:8081/repository/pypi-all/simple export POETRY_HTTP_BASIC_NEXUS_USERNAME=username export POETRY_HTTP_BASIC_NEXUS_PASSWORD=password
Example for multiple repositories:
[[tool.poetry.source]] name = "nexus-all" url = "http://nexus.example.com:8081/repository/pypi-all/simple" priority = "primary" [[tool.poetry.source]] name = "nexus-hosted" url = "http://nexus.example.com:8081/repository/pypi-hosted/simple" priority = "supplemental" [[tool.poetry.source]] name = "pypi" priority = "supplemental" # Configure authentication for each source poetry config http-basic.nexus-all username password poetry config http-basic.nexus-hosted username password
Example with usertoken:
[[tool.poetry.source]]
name = "nexus"
url = "http://example.nexus.com:8081/repository/pypi-all/simple"
priority = "primary"
# Store the authentication in poetry config
poetry config http-basic.nexus adminusername NX_TOKEN_VALUEConfigure twine
Use this configuration method when you want to publish packages to a PyPI hosted repository. The .pypirc file stores the repository endpoint and credentials used for uploads.
[distutils]
index-servers =
<REPOSITORY_ALIAS>
[<REPOSITORY_ALIAS>]
repository: https://<NEXUS_URL>/repository/<REPO_NAME>/
username: <USERNAME>
password: <PASSWORD>Where,
<REPOSITORY_ALIAS>- Name used bytwineto select the target repository entry, for examplepypi<NEXUS_URL>- URL of your Nexus instance, for exampleexample.nexus.com<REPO_NAME>- Name of the target hosted repository in Nexus, for examplepypi-internal<USERNAME>- Your Nexus username user token name code<PASSWORD>- Your Nexus password or usertoken pass code
Example:
[distutils]
index-servers =
pypi
[pypi]
repository: https://example.nexus.com/repository/pypi-internal/
username: admin
password: admin123If you have multiple hosted repositories, add one named entry per hosted repository.
Authenticate using .netrc
You can store credentials in a .netrc file so that supported clients authenticate automatically without embedding credentials in repository URLs.
Add an entry for your Nexus host in
~/.netrcin Linux or macOS and%HOME%\_netrcon Windows.machine <NEXUS_HOST> login <USERNAME> password <PASSWORD>
Where,
<NEXUS_HOST>- Your Nexus instance<USERNAME>- Your Nexus username or usertoken name code<PASSWORD>- Your Nexus password or user token passcode
Set secure file permissions. The
.netrcfile is ignored if it is world-readable:chmod 600 ~/.netrc
Client Support
pip: Reads
~/.netrcautomatically through the underlying HTTP library. Works for both hosted and proxy repositories.twine: Does not support
.netrc. Use--usernameand--passwordflags or configure~/.pypircfor uploads.curl: Requires the
.netrcoption to use.netrccredentials.Ensure that the hostname in
.netrcexactly matches the repository URL host.
SSL Usage for PyPI Repositories
Use HTTPS with proxy, hosted, and group repositories to ensure a secure connection with a self-signed certificate. To set up the repository manager to serve HTTPS, see Configuring SSL.
After Nexus Repository is configured to serve HTTPS, verify the certificate before updating pip.
openssl verify <CERTIFICATE_FILE>
Where,
<CERTIFICATE_FILE>is the certificate file you want to verify beforepipuses it.
Example:
openssl verify nexus.pem
For pip, update pip.conf or pip.ini when the certificate is valid.
[global] index-url = https://<NEXUS_URL>/repository/<REPO_NAME>/simple cert = <CERTIFICATE_FILE>
For uv, use the following codeblock:
export UV_INDEX_URL=https://<NEXUS_URL>/repository/<REPO_NAME>/simple export SSL_CERT_FILE=<CA_BUNDLE_FILE>
For Poetry, use the following codeblock:
poetry config certificates.<SOURCE_NAME>.cert <CA_BUNDLE_FILE>
Example for pip:
[global] index = https://example.nexus.com/repository/pypi-all/pypi index-url = https://example.nexus.com/repository/pypi-all/simple cert = nexus.pem
PEP 658, PEP 691 and PEP 700 Support for PyPI
Nexus Repository supports the following Python packaging standards for PyPI:
New in 3.93 PEP 658: Provides package metadata in the Simple API through the
data-dist-info-metadataattribute.New in 3.93 PEP 691: Provides JSON-based Simple API through content negotiation.
New in 3.94 PEP 700: Adds package version, file size, and upload time metadata to JSON Simple API responses.
New in 3.95 When you upgrade to Nexus Repository 3.95.0, Nexus Repository automatically repairs the stored
Content-Typefor previously cached PyPI.whl.metadataassets.No administrator action is required. The repair runs automatically during the upgrade and applies to PyPI hosted and proxy repositories. PyPI group repositories are unaffected because they do not store local assets.
In High Availability deployments using a rolling upgrade, the repair completes after all nodes are are upgraded. If the repair timeout is reached before all nodes are upgraded, the repair is retried on the next node startup.
The following are the Python clients that support PEP 658, PEP 691 and PEP 700:
pip 23.1and lateruv 0.1.0and laterPoetry 1.8and later. For PEP 700, usePoetry 2.xto leverage upload-time for audit workflows.
To test PEP 658 and PEP 691 features, use:
curl http://example.nexus.com/repository/pypi-all/simple/requests/ | grep data-dist-info-metadata curl -H "Accept: application/vnd.pypi.simple.v1+json" http://example.nexus.com/repository/pypi-all/simple/requests/
Python clients that do not support PEP 658 or PEP 691 continue to receive the legacy 503 response.
PEP 700 adds the following fields to JSON package detail responses:
Field | Description | Notes |
|---|---|---|
| Identifies the Simple API version used by the JSON response. | Package detail responses use |
| Lists the versions published for the package. | Nexus Repository sorts versions by PEP 440 when it emits the field. |
| Shows the package file size in bytes. | Required for Simple API v1.1 package detail responses. |
| Shows the package upload time as an ISO 8601 UTC timestamp. | Included when upload time metadata is available. For proxy repository, it displays the time when it was uploaded to the upstream and for hosted repositories, it displays the ingest time. |
Run Repair - Rebuild PyPI Repository Metadata task to add PEP 700 fields to existing hosted repository packages.
To test PEP 700 feature, use:
curl -H "Accept: application/vnd.pypi.simple.v1+json" \ https://<nexus-url>/repository/<repository-name>/simple/<package-name>/
Policy-Compliant Component Selection for PyPI
Policy-compliant component selection for PyPI requires IQ Server version 167 and later. This functionality requires integration with Sonatype Repository Firewall and a Firewall license.
When a user requests a PyPI package without explicitly specifying a version, the PyPI client relies on the package metadata to select a version that satisfies the version constraints. If the selected version has policy violations and is quarantined by the Sonatype Repository Firewall, it will cause a build failure that requires a manual fix of the root cause.
By enabling this option, the Repository Firewall removes quarantined versions from the PyPI package metadata to prevent you from selecting a version with policy violations.
Perform the following steps to enable this behaviour:
Enable the Firewall Audit and Quarantine capability on the proxy repository.
Select Remove Quarantined Versions in Sonatype Nexus Repository settings.