Лучшая практика установки зависимости пакета, недоступной в pypi

Мой пакет python зависит от частного пакета, которого нет в pypi. Вы можете предположить, что структура приватного пакета эта.

Цель: сохранить сторонний частный пакет где-нибудь в моем собственном пакете таким образом, чтобы при запуске pip install -r requirements.txt (или, что еще лучше, pip install <my_pkg_name>) устанавливалась сторонняя зависимость. Это должно работать в Windows и Linux.

Возможный обходной путь: не устанавливайте сторонний модуль. Вместо этого поместите его в основной каталог пакетов как есть и import его модули.

/my_pkg
    /non_pypi_pkg
    /my_pkg
        module.py

Где module.py умеет import non_pypi_pkg без установки non_pypi_pkg.

Вопрос. Что рекомендуется для достижения цели? Можем ли мы сделать лучше, чем мой обходной путь?


person MLguy    schedule 27.03.2018    source источник
comment
не уверен в контексте, но можно настроить собственное локальное зеркало pypi и размещать там свой собственный контент. возможно, см. stackoverflow.com/questions/1235331/ как-свернуть-мой-собственный-pypi   -  person Corley Brigman    schedule 27.03.2018
comment
Хорошая точка зрения. В прошлом я уже поддерживал локальное зеркало pypi, но в этом случае я хотел бы использовать более простое решение.   -  person MLguy    schedule 27.03.2018
comment
Независимо от того, какой вариант вы выберете, вам нужно написать setup.py для частного пакета. Затем одним из вариантов является настройка частного репозитория PyPI, другим может быть установка с URL-адреса через dependency_links или даже установка непосредственно из VCS, опять же через dependency_links. pip также может обрабатывать URL-адреса VCS, то есть pip install git+https://github.com/user/project@branch.   -  person hoefling    schedule 27.03.2018


Ответы (1)


Когда я работаю со сторонними пакетами, я часто использую один из следующих методов, используя setuptools.

1. Установить напрямую с указанием пути URL в setup.py.

Имеет следующую структуру:

/my_pkg
├── /my_pkg
│   ├── __init__.py
│   └── module.py
├── setup.py

setup.py

setup(
    name="my_pkg",
    version="0.0.0",
    packages=find_packages(),
    install_requires=['flask', 
        'non_pypi_pkg @ https://github.com/<user>/non_pypi_pkg/archive/main.zip#egg=non_pypi_pkg-0.0.1',
        ]
)

Когда репозиторий является частным, я использую токен личного доступа (by github), в том же примере может быть pkg @ https://<token>@github.com/<user>/pkg/...

  • Затем pip install -e my_pkg

2. Работа с монорепозиторием с несколькими пакетами для обеспечения разделения уровней Python.

Имеет следующую структуру:

/
├── my_pkg
│   ├── my_pkg
│   │   ├── __init__.py
│   │   └── module.py
│   └── setup.py
├── non_pypi_pkg
│   ├── non_pypi_pkg
│   │   ├── __init__.py
│   │   └── module_b.py
│   └── setup.py

/non_pypi_pkg/setup.py

setup(
    name="non_pypi_pkg",
    version="0.0.1",
    packages=find_packages(),
    install_requires=[]
)

/my_pkg/setup.py

setup(
    name="my_pkg",
    version="0.0.0",
    packages=find_packages(),
    install_requires=['flask', 'non_pypi_pkg']
)
  • Здесь надо устанавливать в порядке зависимости. Например:

     pip install -e non_pypi_pkg; pip install -e my_pkg;
    

Я предпочитаю использовать скрипт в качестве Makefile для этих задач, но также возможно использовать скрипт bash или power-shell, как показано ниже:

#!/bin/bash
libraries=(non_pypi_pkg my_pkg)

for dirname in $(ls); do
    if [ -d "$dirname" ] && [ -e "$dirname/setup.py" ]; then
        pip install -e $dirname
    fi
done
person Henry Palacios    schedule 16.10.2020