# PyPI

---

## Overview

Your private Python packages and public dependencies from PyPI, all managed through one registry.

---

## Supported Clients

JFrog Fly supports Python packages with:

- **Twine** (`twine upload`) - The official tool for publishing packages to PyPI

- **pip** (`pip install`) - The standard package installer for Python

- **Pipenv** (`pipenv install`) - Package installer with virtual environment management

- **Poetry** (`poetry publish`, `poetry install`) - Dependency management and packaging tool

---

## Upload / Publish Package

### With Fly App

Activate your Python tools in the Fly App. Fly detects your installed tools and configures them automatically. Once activated, publish your package:

#### Twine

```bash
twine upload dist/*
```

#### Poetry

```bash
poetry publish
```

### Manual Configuration

**1. Generate an access token** in Fly Token Management

#### Twine

**2.** Create `~/.pypirc`:

```ini
[distutils]
index-servers = pypi

[pypi]
repository = https://<your-fly-subdomain>.jfrog.io/artifactory/api/pypi/pypi
username = <your-fly-username>
password = <your-fly-token>
```

> [!TIP]
> Using `pypi` as the section name makes it the default repository for Twine, so you don't need to specify `-r` when uploading.

**3.** Upload:

```bash
twine upload dist/*
```

#### Poetry

**2.** Configure the repository:

```bash
poetry config repositories.pypi https://<your-fly-subdomain>.jfrog.io/artifactory/api/pypi/pypi
poetry config http-basic.pypi <your-fly-username> <your-fly-token>
```

**3.** Publish:

```bash
poetry publish -r pypi
```

> [!IMPORTANT]
> You cannot publish a package version that already exists. Increment the version before publishing again.

---

## Download / Install Package

### With Fly App

Activate your Python tools in the Fly App. Fly detects your installed tools and configures them automatically. Once activated, install packages as usual:

#### pip

```bash
pip install <package-name>
```

#### Pipenv

```bash
pipenv install <package-name>
```

#### Poetry

```bash
poetry add <package-name>
```

### Manual Configuration

**1. Generate an access token** in Fly Token Management

#### pip / Pipenv

**2.** Create `~/.config/pip/pip.conf` (Linux/macOS) or `%APPDATA%\pip\pip.ini` (Windows):

```ini
[global]
index-url = https://<your-fly-username>:<your-fly-token>@<your-fly-subdomain>.jfrog.io/artifactory/api/pypi/pypi/simple
```

**3.** Install:

```bash
pip install <package-name>
```

Pipenv uses the same pip configuration, so `pipenv install <package-name>` works automatically.

#### Poetry

**2.** Add Fly as a source in your `pyproject.toml`:

```toml
[[tool.poetry.source]]
name = "fly"
url = "https://<your-fly-subdomain>.jfrog.io/artifactory/api/pypi/pypi/simple"
priority = "primary"
```

**3.** Configure authentication:

```bash
poetry config http-basic.fly <your-fly-username> <your-fly-token>
```

**4.** Install:

```bash
poetry add <package-name>
```

### From Public Registry

When you install a package that isn't in your Fly Registry, JFrog Fly automatically fetches it from PyPI and caches it for future use. Just install as usual -- for example, `pip install requests`, `pipenv install requests`, or `poetry add requests`.

---

## Publish/Install Packages with CI

To publish and install Python packages with CI, update your GitHub Actions workflow to include the Fly action.

Simply ask your coding agent: **"Configure my workflows with Fly"** and Fly MCP will configure your GitHub Actions workflow yml file, as follows:

**1. Add permissions** (top level, after `on:`):
```yaml
permissions:
  contents: read
  id-token: write
```

**2. Add Fly Action** (after `actions/setup-python`, before pip/twine commands):
```yaml
- uses: jfrog/fly-action@v1              # Setup Fly package managers
```

### GitHub Action Example

```yaml
name: Build and Publish Python Package

on:
  push:
    branches: [main]

permissions:
  contents: read
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - uses: jfrog/fly-action@v1              # Setup Fly package managers

      - run: pip install build twine           # Dependencies from Fly registry

      - run: python -m build

      - run: twine upload dist/*               # Publish to Fly registry
```

---

*Back to [Package Managers →](../)*
