بستههای پایتون را با pip، uv یا Poetry از راه زرین نصب کنید، بستههای خودتان را منتشر کنید، خود پایتون را نصب کنید و بستههای خصوصی را خصوصی نگه دارید. یک فهرست برای پروژههای شما و pypi.org، در امان از بستههای همنام. هر قدم توضیح داده شده.
نصبکنندههای پایتون (**pip**، **uv**، **Poetry**) بستهها را از یک *فهرست* (index) دانلود میکنند. زرین یک فهرست برای همه چیز به شما میدهد:
- **پروژههای خودتان** که در زرین منتشر کردهاید، عمومی یا خصوصی.
- **همهٔ pypi.org**، از راه آینهٔ زرین: هر فایل پیش از نگه داشتن با sha256 فهرست pypi.org سنجیده میشود، و pip دوباره میسنجدش.
- **در امان از بستههای همنام.** نامی که در زرین هست همیشه از زرین میآید؛ پس کسی نمیتواند بستهای همنام در pypi.org منتشر کند و آن را وارد نصبهای شما کند (به این *dependency confusion* میگویند). و نام تازه در زرین نمیتواند نامی باشد که pypi.org از قبل دارد؛ پس از آن طرف هم ممکن نیست.
نشانی فهرست:
```text
https://api.zaryn.xyz/v1/packages/pypi/all/simple/
```
## نصب بستهها از راه زرین
### pip
یک بار برای هر رایانه:
```bash
pip config set global.index-url https://api.zaryn.xyz/v1/packages/pypi/all/simple/
```
همین: `pip install requests` حالا از راه زرین میرود. یا فقط برای یک دستور:
```bash
pip install --index-url https://api.zaryn.xyz/v1/packages/pypi/all/simple/ requests
```
### uv
برای همهٔ پروژههای این رایانه، در فایل شروع شل (`~/.bashrc` یا مشابه) بگذارید:
```bash
export UV_DEFAULT_INDEX=https://api.zaryn.xyz/v1/packages/pypi/all/simple/
```
یا برای یک پروژه، در `pyproject.toml` آن:
```toml
[[tool.uv.index]]
name = "zaryn"
url = "https://api.zaryn.xyz/v1/packages/pypi/all/simple/"
default = true
```
از آن به بعد `uv add`، `uv sync` و `uv pip install` از زرین استفاده میکنند.
### Poetry
```bash
poetry source add --priority=primary zaryn https://api.zaryn.xyz/v1/packages/pypi/all/simple/
```
### همه با هم
اگر دستور `zev` را دارید، `zev mirror on pip uv` تنظیمات pip و uv را برایتان مینویسد و `zev mirror off pip uv` پاکشان میکند. [آینهها](/docs/fa/package-mirrors#همه-با-هم-zev-mirror) را ببینید.
## نصب خود پایتون (uv)
uv میتواند خود پایتون را هم دانلود کند (`uv python install 3.13`، یا خودکار وقتی پروژهای لازمش دارد). این دانلودها از گیتهاب میآیند؛ برای گرفتنشان از راه زرین:
```bash
export UV_PYTHON_INSTALL_MIRROR=https://api.zaryn.xyz/v1/packages/python/-/standalone
uv python install 3.13
```
هر ساخت پیش از نگه داشتن با SHA256SUMS انتشارش سنجیده میشود، و uv آن را با چکسامی که در خودش دارد میسنجد.
## انتشار بستهٔ خودتان
### ساختن
از پوشهای که `pyproject.toml` دارد:
```bash
python -m pip install build twine
python -m build
```
این یک wheel (`.whl`) و یک آرشیو منبع (`.tar.gz`) در `dist/` میگذارد.
### بارگذاری
در [بستهها](/packages) توکن بسازید (**ساخت توکن انتشار**). سپس با twine:
```bash
twine upload --repository-url https://api.zaryn.xyz/v1/packages/pypi/ \
-u __token__ -p YOUR_TOKEN dist/*
```
- `-u __token__` همینطور نوشته میشود: به زرین میگوید رمز، توکن است.
- برای اینکه هر بار تایپش نکنید، این را در `~/.pypirc` بگذارید و `twine upload -r zaryn dist/*` را اجرا کنید:
```ini
[distutils]
index-servers = zaryn
[zaryn]
repository = https://api.zaryn.xyz/v1/packages/pypi/
username = __token__
password = YOUR_TOKEN
```
یا با uv یا Poetry:
```bash
uv publish --publish-url https://api.zaryn.xyz/v1/packages/pypi/ --username __token__ --password YOUR_TOKEN
poetry config repositories.zaryn https://api.zaryn.xyz/v1/packages/pypi/
poetry publish -r zaryn --username __token__ --password YOUR_TOKEN
```
نسخهای که بارگذاری شده جایگزین نمیشود: برای اصلاح، نسخه را در `pyproject.toml` بالا ببرید.
### انتخاب نام
نام **تازه** نباید در pypi.org وجود داشته باشد؛ زرین در اولین بارگذاری بررسی میکند. اگر آنجا گرفته شده، نام دیگری انتخاب کنید، مثلاً با پیشوند تیمتان (`acme-utils`). همین است که فهرست واحد را برای همه امن نگه میدارد.
### نصب
با فهرستی که بالا تنظیم شد، فقط `pip install your-package` یا `uv add your-package`. وابستگیهایش از pypi.org هم از همان فهرست میآیند.
## نصب مستقیم از یک مخزن زرین
هر commit مخزنی که `pyproject.toml` (یا `setup.py`) دارد بدون انتشار هم نصبشدنی است: مخزن را باز کنید، زبانهٔ **نصب** کنار دستورهای clone را بزنید و خط را کپی کنید. این شکلی است:
```bash
pip install https://zaryn.xyz/api/v1/repos/<owner>/<repo>/branches/main/archive/<commit>.tar.gz
```
نشانی به یک commit بسته است، پس همیشه دقیقاً همان کد را نصب میکند. در `pyproject.toml` هم بهعنوان وابستگی کار میکند: `"mytool @ https://zaryn.xyz/api/v1/repos/…/archive/<commit>.tar.gz"`. مخزن باید عمومی باشد (یا توکنتان را در نشانی به pip بدهید).
## بستههای خصوصی (پریمیوم)
بسته را در صفحهاش خصوصی کنید (**خصوصی کردن**). فقط شما، یا اعضای سازمانی که مالکش است، میتوانند ببینند یا نصبش کنند. آن وقت نصبکنندهها به توکنتان در نشانی فهرست نیاز دارند:
```bash
pip install --index-url https://__token__:$ZARYN_TOKEN@api.zaryn.xyz/v1/packages/pypi/all/simple/ your-package
```
برای uv، `UV_INDEX_ZARYN_USERNAME=__token__` و `UV_INDEX_ZARYN_PASSWORD=$ZARYN_TOKEN` را تنظیم کنید (با فهرست `zaryn` در `pyproject.toml` بالا).
## وقتی چیزی درست کار نمیکند
| میبینید | یعنی | راهحل |
|---|---|---|
| `403` با "… is a project on pypi.org" هنگام بارگذاری | نام تازه نمیتواند نامی باشد که pypi.org دارد | نام دیگری انتخاب کنید |
| `403` با "this token can't publish packages" | توکن مجوز `package:write` ندارد | در [بستهها](/packages) توکن بسازید |
| `403` با "this package name belongs to someone else" | حساب دیگری زودتر این نام را بارگذاری کرده | نام دیگری انتخاب کنید |
| `409` | این فایل قبلاً بارگذاری شده | نسخه را بالا ببرید |
| `503` با "couldn't check that this name is free on pypi.org" | pypi.org هنگام بارگذاری نام تازه پاسخ نداد | یک دقیقهٔ دیگر دوباره امتحان کنید |
| pip: "No matching distribution" | نشانی فهرست اشتباه است، یا بستهٔ خصوصی بدون توکن | بررسی کنید نشانی با `/all/simple/` تمام شود |
| pip: "not a trusted or secure host" | نشانی با `http://` شروع میشود | نشانی `https://` را به کار ببرید |
## پشت صحنه
هر فهرستی که زرین میدهد به هر دو قالبی که نصبکنندهها به کار میبرند پاسخ میدهد: صفحهٔ HTML کلاسیک (PEP 503) و JSON (PEP 691)، هر کدام را که نصبکننده بخواهد. metadata هر wheel را هم به شکل یک فایل کوچک جدا میدهد (PEP 658)، تا pip و uv بدون دانلود کل wheel بفهمند کدام نسخهها جور میشوند؛ این حل وابستگیها را محسوس سریعتر میکند. فایلها با SHA-256 نگه داشته میشوند و فهرست همان را دارد، پس نصبکننده هر دانلود را میسنجد. نامها مثل PyPI یکسانسازی میشوند: `My_Package` و `my-package` یک ناماند.
نشانیها، اگر جدا لازمشان دارید: `/v1/packages/pypi/simple/` فقط پروژههای شما در زرین است، `/v1/packages/pypi/mirror/simple/` فقط pypi.org، و `/v1/packages/pypi/all/simple/` هر دو.
نصبکنندههای پایتون (pip، uv، Poetry) بستهها را از یک فهرست (index) دانلود میکنند. زرین یک فهرست برای همه چیز به شما میدهد:
پروژههای خودتان که در زرین منتشر کردهاید، عمومی یا خصوصی.
همهٔ pypi.org، از راه آینهٔ زرین: هر فایل پیش از نگه داشتن با sha256 فهرست pypi.org سنجیده میشود، و pip دوباره میسنجدش.
در امان از بستههای همنام. نامی که در زرین هست همیشه از زرین میآید؛ پس کسی نمیتواند بستهای همنام در pypi.org منتشر کند و آن را وارد نصبهای شما کند (به این dependency confusion میگویند). و نام تازه در زرین نمیتواند نامی باشد که pypi.org از قبل دارد؛ پس از آن طرف هم ممکن نیست.
uv میتواند خود پایتون را هم دانلود کند (uv python install 3.13، یا خودکار وقتی پروژهای لازمش دارد). این دانلودها از گیتهاب میآیند؛ برای گرفتنشان از راه زرین:
نام تازه نباید در pypi.org وجود داشته باشد؛ زرین در اولین بارگذاری بررسی میکند. اگر آنجا گرفته شده، نام دیگری انتخاب کنید، مثلاً با پیشوند تیمتان (acme-utils). همین است که فهرست واحد را برای همه امن نگه میدارد.
هر commit مخزنی که pyproject.toml (یا setup.py) دارد بدون انتشار هم نصبشدنی است: مخزن را باز کنید، زبانهٔ نصب کنار دستورهای clone را بزنید و خط را کپی کنید. این شکلی است:
نشانی به یک commit بسته است، پس همیشه دقیقاً همان کد را نصب میکند. در pyproject.toml هم بهعنوان وابستگی کار میکند: "mytool @ https://zaryn.xyz/api/v1/repos/…/archive/<commit>.tar.gz". مخزن باید عمومی باشد (یا توکنتان را در نشانی به pip بدهید).
بسته را در صفحهاش خصوصی کنید (خصوصی کردن). فقط شما، یا اعضای سازمانی که مالکش است، میتوانند ببینند یا نصبش کنند. آن وقت نصبکنندهها به توکنتان در نشانی فهرست نیاز دارند:
هر فهرستی که زرین میدهد به هر دو قالبی که نصبکنندهها به کار میبرند پاسخ میدهد: صفحهٔ HTML کلاسیک (PEP 503) و JSON (PEP 691)، هر کدام را که نصبکننده بخواهد. metadata هر wheel را هم به شکل یک فایل کوچک جدا میدهد (PEP 658)، تا pip و uv بدون دانلود کل wheel بفهمند کدام نسخهها جور میشوند؛ این حل وابستگیها را محسوس سریعتر میکند. فایلها با SHA-256 نگه داشته میشوند و فهرست همان را دارد، پس نصبکننده هر دانلود را میسنجد. نامها مثل PyPI یکسانسازی میشوند: My_Package و my-package یک ناماند.
نشانیها، اگر جدا لازمشان دارید: /v1/packages/pypi/simple/ فقط پروژههای شما در زرین است، /v1/packages/pypi/mirror/simple/ فقط pypi.org، و /v1/packages/pypi/all/simple/ هر دو.