Переносимый офлайн-менеджер Python-пакетов
Я написал CLI-утилиту, которая решает сразу несколько задач. Она позволяет создать локальный архив с портативными версиями Python и любыми пакетами из PyPI. А затем — мгновенно разворачивать проекты без единого запроса в интернет. Также утилита работает из коробки, не требуя сложной настройки серверов — то есть ровно то, что нужно хобби-разработчикам, новичкам и небольшим командам. Хочу поделиться ей здесь, так как думаю, что она может быть полезна кому-то ещё кроме меня.
В конце статьи есть gif с демонстрацией приложения.
Содержание
Зачем я это сделал (и почему это полезно прямо сейчас)
Идея родилась из личного опыта. Как разработчик, я часто сталкиваюсь с ситуациями, когда интернет недоступен или работает плохо:
Поездка за город, где связь ловится через раз.
Работа в коворкинге или кафе с перегруженным Wi-Fi.
Необходимость быстро развернуть проект на новой машине, где нет доступа к сети.
Просто желание держать под рукой “слепок” окружения для версионности.
Существующие решения для офлайн-работы с Python-пакетами (devpi, bandersnatch) требуют настройки целого сервера. Это как стрелять из пушки по воробьям. Мне нужен был простой инструмент, который работает как обычная CLI-утилита, имеет uv подобный интерфейс и работает полностью оффлайн (с предварительно загруженными ресурсами). Так родился PyOffline2 — «чемоданчик с инструментами» для Python-разработки.
Стоит упомянуть и возможный “страховочный” сценарий. Этот инструмент может пригодиться не только в поездках, но и в случае, если доступ к зарубежным ресурсам (включая PyPI) станет нестабильным или проблематичным. Это не основной сценарий, и я не драматизирую его, но как дополнительный аргумент — почему бы и нет. Ведь люди покупают страховки, хотя не собираются становиться объектами страховых случаев.
Что умеет проект
Скачивать Python — портативные сборки с python-build-standalone через
getpybs(командаget-python)Создавать виртуальные окружения на целевой машине:
init -pv 3.12Скачивать пакеты с PyPI и распределять их по версиям Python:
get fastapi uvicornилиget-from requirements.txtУстанавливать пакеты в целевой проект
add fastapi uvicornилиadd passlib[argon2](работает сpyproject.toml)Обновлять уже скачанные пакеты
updateа если добавить флагkeep, то старые версии будут удаляться, останется только указанное число последних версий не раздувая архив.Удалять пакеты из целевого проекта с очисткой зависимостей-сирот — аналог
uv remove, только полностью офлайн. Удаляет то, что больше не используется ни одним другим пакетомВести структурированный (машиночитаемый) лог о выполненных операциях корневая папка logs команда
folder, чтобы открыть корневую папку приложения.
Кому подойдёт
Хобби- и соло-разработчики
Небольшие команды
Все, кто не хочет поднимать промышленные серверные решения ради сохранения набора любимых библиотек
Как это устроено
Весь проект строится вокруг простой идеи: есть Архив (папка resources), который вы один раз наполняете, и есть ваши Проекты, которые используют этот архив.
Архив (resources/) — это ваше главное хранилище. В нём лежат:
python_storage/ — портативные версии Python (например, 3.10, 3.12), скачанные командой pyoff get-python. Они не требуют установки в систему.
packages_storage/ — пакеты из PyPI (например, fastapi, requests), распределённые по версиям Python. Загружаются командой pyoff get сразу для всех версий, которые есть в python_storage/.
Проект — это ваша рабочая папка с кодом. Когда вы создаёте новый проект (pyoff init -pv 3.12), утилита:
Берёт портативный Python из Архива. Создаёт на его базе виртуальное окружение (.venv) в вашем проекте. При добавлении пакетов (pyoff add fastapi) копирует их из packages_storage. В итоге, вы получаете полностью изолированное окружение, которое работает без единого запроса в интернет.
Схема ниже наглядно это показывает:

Быстрый старт
Скачать Релиз для своей ОС (win/linux), прописать папку с бинарником в PATH переменных. Затем:
windows:
# базовый кейс (после того как приложение было прописано в системных переменных): pyoff get-python 3.10 # скачать портативный python в архив (один раз) pyoff get fastapi, pydantic # скачать пакеты в архив (для всех python доступных в архиве) mkdir my-project # создать папку проекта если её ещё нет cd my-project # перейти в папку целевого проекта (здесь для примера такой путь, у вас своя папка) pyoff init -pv 3.12 # инициализировать проект создав виртуальное окружение .venv\Scripts\activate # войти в виртуальное окружение проекта (не обязательно) pyoff project # посмотреть информацию о проекте pyoff add fastapi, pydantic # установить пакеты в проект (были скачаны заранее через pyoff get) pyoff project # посмотреть информацию о проекте pip list # проверка что пакеты реально установились pyoff remove fastapi # Удаление fastapi с очисткой "сирот" pyoff project # посмотреть информацию о проекте pip list # проверка что fastapi удалился корректно, но pydantic не пострадал
linux:
# базовый кейс (после того как приложение было прописано в системных переменных): pyoff get-python 3.10 # скачать портативный python в архив (один раз) pyoff get fastapi, pydantic # скачать пакеты в архив (для всех python доступных в архиве) mkdir my-project # создать папку проекта если её ещё нет cd my-project # перейти в папку целевого проекта (здесь для примера такой путь, у вас своя папка) pyoff init -pv 3.12 # инициализировать проект создав виртуальное окружение source .venv/bin/activate # войти в виртуальное окружение проекта (не обязательно) pyoff project # посмотреть информацию о проекте pyoff add fastapi, pydantic # установить пакеты в проект (были скачаны заранее через pyoff get) pyoff project # посмотреть информацию о проекте pip list # проверка что пакеты реально установились pyoff remove fastapi # Удаление fastapi с очисткой "сирот" pyoff project # посмотреть информацию о проекте pip list # проверка что fastapi удалился корректно, но pydantic не пострадал
Где хранить архив
Единственное, что вам нужно решить — где будет лежать папка с приложением (вместе с архивом resources/). Это может быть:
Внешний SSD или флешка (берите с собой в поездки)
Общая сетевая папка в офисе (для всей команды)
Облачный диск (всё равно не понадобится интернет для установки, только для пополнения)
Никаких настроек серверов, баз данных и Docker-контейнеров. Всего лишь прописать папку с приложением в path переменных.
Итоги
PyOffline2 — это простой, прозрачный и бесплатный open-source инструмент. Он не заменяет uv или pip, а дополняет их. Код открыт, лицензия MIT. Буду рад вашим звездочкам на GitHub, пул-реквестам и любой обратной связи. Ссылки:
❕ Дополнительно
Работа приложения на windows:

Работа приложения на linux:

orki
Я уверен что это было интересно писать, но как девопс, ставящий пайтон приложи в том числе и оффлайн - не вижу смысла в еще одной тулзе, я или поднимаю локальный devpi, где необходимые пакеты уже отзеркалены или сразу собираю пакет/бинарь со всеми зависимостями.