Metadata-Version: 2.4
Name: fastpluggy-pypi-registry
Version: 0.1.9
Summary: PyPI Registry plugin for FastPluggy — private package hosting and plugin discovery
Author: FastPluggy Team
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: FastPluggy>=0.4.33
Requires-Dist: fastpluggy-auth-user>=0.1.1
Requires-Dist: fastpluggy-metrics>=0.1.0
Requires-Dist: fastapi
Requires-Dist: uvicorn[standard]
Requires-Dist: psycopg2-binary
Requires-Dist: packaging
Requires-Dist: twine==6.2.0
Requires-Dist: pkginfo
Requires-Dist: readme-renderer
Requires-Dist: requests
Requires-Dist: limits>=3.0
Requires-Dist: markdown
Requires-Dist: tomli
Requires-Dist: toml
Provides-Extra: sentry
Requires-Dist: sentry-sdk; extra == "sentry"
Provides-Extra: tests
Requires-Dist: pytest>=7.0; extra == "tests"
Requires-Dist: pytest-cov>=4.0; extra == "tests"
Requires-Dist: pytest-asyncio>=0.21; extra == "tests"
Requires-Dist: httpx; extra == "tests"
Requires-Dist: testcontainers; extra == "tests"
Requires-Dist: requests; extra == "tests"
Provides-Extra: e2e
Requires-Dist: fastpluggy-cli; extra == "e2e"
Requires-Dist: uvicorn[standard]; extra == "e2e"

# fastpluggy-pypi-registry

![PyPI Registry](https://img.shields.io/badge/FastPluggy-PyPI%20Registry-blue)
[![Release](https://gitlab.ggcorp.fr/open/fastpluggy/plugins/pypi_registry/-/badges/release.svg)](https://gitlab.ggcorp.fr/open/fastpluggy/plugins/pypi_registry/-/releases)
[![Pipeline Status](https://gitlab.ggcorp.fr/open/fastpluggy/plugins/pypi_registry/badges/main/pipeline.svg?key_text=CI)](https://gitlab.ggcorp.fr/open/fastpluggy/plugins/pypi_registry/-/pipelines?ignore_skipped=true)
[![Coverage](https://gitlab.ggcorp.fr/open/fastpluggy/plugins/pypi_registry/badges/main/coverage.svg)](https://gitlab.ggcorp.fr/open/fastpluggy/plugins/pypi_registry/-/pipelines)

Private PyPI-compatible package registry and plugin discovery hub for FastPluggy.

## Requirements

- **PostgreSQL** (required) — uses `ARRAY(Integer)` computed columns for version sorting. SQLite is not supported.
- `fastpluggy-auth-user` — provides authentication
- `fastpluggy-metrics` — aggregates registry metrics via MetricsProvider capability

## Features

- PyPI-compatible package upload/download (`pip install --index-url`)
- Simple API (`/pypi/simple/`) for pip/uv compatibility
- Package browsing and search UI
- Admin dashboard with package management
- Audit logging for uploads and deletions
- Plugin screenshot gallery (CI-uploaded e2e screenshots with dark/light theme toggle)
- Security scanning (pip-audit, bandit)
- Grafana dashboard for monitoring
- MetricsProvider for Prometheus export

## Configuration

Environment variables (via `RegistryConfig`):

| Variable | Default | Description |
|----------|---------|-------------|
| `DATABASE_URL` | (required) | PostgreSQL connection string |
| `URL_REGISTRY` | `registry.fastpluggy.xyz` | Public registry URL |
| `PATH_REGISTRY` | `/pypi/simple/` | PyPI simple index path |
| `REQUIRE_AUTH` | `false` | Require auth for uploads |
| `ALLOWED_ORIGINS` | `*` | CORS allowed origins |
| `MAX_UPLOAD_SIZE_MB` | `100` | Max upload file size |

## Package Visibility

Packages have two visibility flags managed via the **Admin > Packages** page:

- **Official** — curated packages shown on the homepage
- **Private** — hidden from unauthenticated users on all PyPI endpoints

On fresh deployments, all packages default to public and non-official.

### Package Settings Page

Each package has a dedicated settings page at **Admin > Packages > (settings icon)**. From this page you can edit:

- **Metadata** — description, author, license, git URL
- **Discovery** — categories and keywords (tag-based editor)
- **Visibility** — official, private, show on home page

Fields edited by an admin are marked as "Manually set" and will not be overwritten when a new version is uploaded via `twine`. Use the reset button next to each field to revert to auto-populated behavior.

Private packages require authentication for access via `pip`:

```bash
pip install --index-url https://user:password@registry.fastpluggy.xyz/pypi/simple/ my-private-pkg
```

## Rate Limiting

Upload and delete endpoints are rate-limited to prevent abuse. Limits are per-user (authenticated) or per-IP (anonymous).

| Variable | Default | Description |
|----------|---------|-------------|
| `RATE_LIMIT_ENABLED` | `true` | Enable/disable rate limiting |
| `RATE_LIMIT_UPLOAD` | `10/minute;60/hour` | Upload endpoint limits |
| `RATE_LIMIT_DELETE` | `10/hour` | Delete endpoint limits |
| `RATE_LIMIT_STORAGE_URI` | `memory://` | Storage backend (`memory://` or `redis://host:6379`) |

For multi-worker deployments, use Redis as the storage backend to share counters across workers. See [docs/rate-limiting.md](docs/rate-limiting.md) for details.

## Development

```bash
# Install in development mode
pip install -e ".[tests]"

# Run tests (requires Docker for PostgreSQL testcontainer)
pytest tests/

# Run e2e tests
cd e2e && npx playwright test
```

