Mikalai Saskavets, Software Engineer, iTechArt
Mikalai Saskavets
Проблематика |
Pipenv как решение |
DataScience? |
echo celery > requirements.txt
virtualenv .venv
source .venv/bin/activate
pip install -U -r requirements.txt
pip freeze
amqp==2.4.0
billiard==3.5.0.5
celery==4.2.1
kombu==4.2.2.post1
pytz==2018.9
vine==1.2.0
↖ зависимости тянут за собой свои зависимости
echo celery > requirements.txt
pip install -U -r requirements.txt
echo celery > requirements.txt
pip install -U -r requirements.txt
amqp==2.3.2 | amqp==2.4.0 billiard==3.5.0.5 | billiard==3.5.0.5 celery==4.2.1 | celery==4.2.1 kombu==4.2.2 | kombu==4.2.2.post1 pytz==2018.7 | pytz==2018.9 vine==1.1.4 | vine==1.2.0
amqp==2.3.2 | amqp==2.4.0 billiard==3.5.0.5 | billiard==3.5.0.5 celery==4.2.1 | celery==4.2.1 kombu==4.2.2 | kombu==4.2.2.post1 pytz==2018.7 | pytz==2018.9 vine==1.1.4 | vine==1.2.0
amqp==2.4.0 | amqp==2.4.1 billiard==3.5.0.5 | billiard==3.5.0.5 celery==4.2.1 | celery==4.2.1 kombu==4.2.2.post1 | kombu==4.3.0 pytz==2018.9 | pytz==2018.9 vine==1.2.0 | vine==1.2.0
cat ~/celery/requirements/default.txt
pytz>dev billiard>=3.5.0.2,<3.6.0 kombu>=4.2.0,<5.0
1 +-- 15 lines: amqp==2.4.0 + 1 +-- 15 lines: amqp==2.4.0 16 coreschema==0.0.4 16 coreschema==0.0.4 17 coverage==4.5.2 17 coverage==4.5.2 18 cryptography==2.4.2 18 cryptography==2.5 19 decorator==4.3.2 19 decorator==4.3.2 20 Django==2.1.5 20 Django==2.1.5 21 +-- 7 lines: django-bulk-up + 21 +-- 7 lines: django-bulk-u 28 django-timezone-field==3.0 28 django-timezone-field==3.0 29 djangorestframework==3.9.1 29 djangorestframework==3.9.1 30 docker==3.6.0 30 docker==3.7.0 31 docker-pycreds==0.4.0 31 docker-pycreds==0.4.0 32 docutils==0.14 32 docutils==0.14 33 ecdsa==0.13 33 ecdsa==0.13 ---------------------------- 34 entrypoints==0.3 34 factory-boy==2.11.1 35 factory-boy==2.11.1 35 Faker==1.0.1 36 Faker==1.0.2 36 flake8==3.6.0 37 flake8==3.7.3 37 flake8-quotes==1.0.0 38 flake8-quotes==1.0.0 38 +-- 12 lines: flower==0.9.2 + 39 +-- 12 lines: flower==0.9.2 50 Jinja2==2.10 51 Jinja2==2.10 51 jmespath==0.9.3 52 jmespath==0.9.3 52 jsondiff==1.1.1 53 jsondiff==1.1.1 53 jsonpickle==1.0 54 jsonpickle==1.1 54 kombu==4.2.2.post1 55 kombu==4.2.2.post1 55 MarkupSafe==1.1.0 56 MarkupSafe==1.1.0 56 mccabe==0.6.1 57 mccabe==0.6.1 57 mock==2.0.0 58 mock==2.0.0 58 moto==1.3.7 59 moto==1.3.7 59 openapi-codec==1.3.2 60 openapi-codec==1.3.2 60 opentracing==1.3.0 61 opentracing==1.3.0 61 opentracing-instrumentation> 62 opentracing-instrumentatio> 62 parameterized==0.6.3 63 parameterized==0.6.3 63 parso==0.3.2 64 parso==0.3.2 64 pbr==5.1.1 65 pbr==5.1.2 65 pexpect==4.6.0 66 pexpect==4.6.0 66 pickleshare==0.7.5 67 pickleshare==0.7.5 67 prompt-toolkit==2.0.8 68 prompt-toolkit==2.0.8 68 psycopg2==2.7.7 69 psycopg2==2.7.7 69 ptyprocess==0.6.0 70 ptyprocess==0.6.0 70 pyaml==18.11.0 71 pyaml==18.11.0 71 pycodestyle==2.4.0 72 pycodestyle==2.5.0 72 pycountry==18.12.8 73 pycountry==18.12.8 73 pycparser==2.19 74 pycparser==2.19 74 pycryptodome==3.7.2 75 pycryptodome==3.7.3 75 pyflakes==2.0.0 76 pyflakes==2.1.0
Пихаем выхлоп pip freeze
в requirements.txt
!
pip install celery
pip freeze > requirements.txt
...
pip install -r requirements.txt
echo 'celery'>requirements.in
pip install -U -r requirements.in
pip freeze > requirements.txt
pip install -r requirements.txt
pip freeze | diff requirements.txt - && echo 'Идентичны!'
Идентичны!Последовательность команд для обновления «запиненных» зависимостей
cat requirements.in
celery>=4.2.1,<4.3
virtualenv ./temp-venv
./temp-venv/bin/python -m pip install -r requirements.in
./temp-venv/bin/python -m pip freeze > requirements.txt
rm -rf ./temp-venv
./.venv/bin/python -m pip install -r requirements.txt
Pipenv is a tool that aims to bring the best of all packaging worlds to the Python world.
Pipfile.lock
— содержит «запиненные», все зависимости, необходимые для запуска и работы проекта. Генерируется на основе Pipfile.Pipfile
— содержит только зависимости проекта и мета-информацию о зависимостях.Список необходимых для установки пакетов декларируется в файле Pipfile, вместо привычного всем requirements.txt
.
Pipfile:
[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] celery = "*" [dev-packages] "flake8" = "*" [requires] python_version = "3.6"
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
celery = "*"
[dev-packages]
"flake8" = "*"
[requires]
python_version = "3.6"
...
[dev-packages]
"flake8" = "*"
[requires]
python_version = "3.6"
... [packages] django = "*" celery = "*" elasticsearch = "<6.0.0,>=5.0.0" [dev-packages] "flake8" = "*" moto = "==1.3.4" [requires] python_version = "3.6"
...
[packages]
django = "*"
celery = "*"
elasticsearch = "<6.0.0,>=5.0.0"
api_client = {git =
"ssh://git@gitlab.com/something/api-client.git",
ref = "v1.0.2"}
[dev-packages]
"flake8" = "*"
moto = "==1.3.4"
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
celery = "*"
[dev-packages]
"flake8" = "*"
[requires]
python_version = "3.6"
[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [[source]] url = "http://pypi.famous.org/simple" verify_ssl = false name = "famous"
[packages] celery = { version="*", index="pypi"} api_base_client = { version="*", index="famous"} api_client = { git="ssh://git@gitlab.com/something/api-client.git", ref = "v1.0.2"}
{ "_meta": { "hash": { "sha256": "415dfdcb118dd9bdfef17671cb7dcd78dbd69b6ae7d4f39e8b44e71d60ca72e7" }, "pipfile-spec": 6, "requires": { "python_version": "3.6" }, "sources": [ { "name": "pypi", "url": "https://pypi.org/simple", "verify_ssl": true } ] }, "default": {}, "develop": {} }
{ "_meta": {
"hash": { "sha256": "415dfdcb118dd9bdfef17671cb7dcd78dbd69b6ae7d4f39e8b44e71d60ca72e7" },
"pipfile-spec": 6,
"requires": { "python_version": "3.6" },
"sources": [
{ "name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {},
"develop": {}
}
{ "_meta": {
"hash": { "sha256": "415dfdcb118dd9bdfef17671cb7dcd78dbd69b6ae7d4f39e8b44e71d60ca72e7" },
"pipfile-spec": 6,
"requires": { "python_version": "3.6" },
"sources": [
{ "name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {},
"develop": {}
}
{ "_meta": {
"hash": { "sha256": "415dfdcb118dd9bdfef17671cb7dcd78dbd69b6ae7d4f39e8b44e71d60ca72e7" },
"pipfile-spec": 6,
"requires": { "python_version": "3.6" },
"sources": [
{ "name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {},
"develop": {}
}
"default": { "amqp": { "hashes": [ "sha256:9f181e4aef6562e6f9f45660578fc1556150ca06e836ecb9e733e6ea10b48464", "sha256:c3d7126bfbc640d076a01f1f4f6e609c0e4348508150c1f61336b0d83c738d2b" ], "version": "==2.4.0" }, "billiard": { "hashes": [ "sha256:42d9a227401ac4fba892918bba0a0c409def5435c4b483267ebfe821afaaba0e" ], "version": "==3.5.0.5" }, "celery": { "hashes": [ "sha256:77dab4677e24dc654d42dfbdfed65fa760455b6bb563a0877ecc35f4cfcfc678", "sha256:ad7a7411772b80a4d6c64f2f7f723200e39fb66cf614a7fdfab76d345acc7b13" ], "index": "pypi", "version": "==4.2.1" }, "kombu": { "hashes": [ "sha256:1ef049243aa05f29e988ab33444ec7f514375540eaa8e0b2e1f5255e81c5e56d", "sha256:3c9dca2338c5d893f30c151f5d29bfb81196748ab426d33c362ab51f1e8dbf78" ], "version": "==4.2.2.post1" }, "pytz": { "hashes": [ "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" ], "version": "==2018.9" }, "vine": { "hashes": [ "sha256:3cd505dcf980223cfaf13423d371f2e7ff99247e38d5985a01ec8264e4f2aca1", "sha256:ee4813e915d0e1a54e5c1963fde0855337f82655678540a6bc5996bca4165f76" ], "version": "==1.2.0" } },
"default": { "amqp": { "hashes": [ "sha256:9f181e4aef6562e6f9f45660578fc1556150ca06e836ecb9e733e6ea10b48464", "sha256:c3d7126bfbc640d076a01f1f4f6e609c0e4348508150c1f61336b0d83c738d2b" ], "version": "==2.4.0" }, "billiard": { "hashes": [ "sha256:42d9a227401ac4fba892918bba0a0c409def5435c4b483267ebfe821afaaba0e" ], "version": "==3.5.0.5" }, "celery": { "hashes": [ "sha256:77dab4677e24dc654d42dfbdfed65fa760455b6bb563a0877ecc35f4cfcfc678", "sha256:ad7a7411772b80a4d6c64f2f7f723200e39fb66cf614a7fdfab76d345acc7b13" ], "index": "pypi", "version": "==4.2.1" }, "kombu": { "hashes": [ "sha256:1ef049243aa05f29e988ab33444ec7f514375540eaa8e0b2e1f5255e81c5e56d", "sha256:3c9dca2338c5d893f30c151f5d29bfb81196748ab426d33c362ab51f1e8dbf78" ], "version": "==4.2.2.post1" }, "pytz": { "hashes": [ "sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9", "sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c" ], "version": "==2018.9" }, "vine": { "hashes": [ "sha256:3cd505dcf980223cfaf13423d371f2e7ff99247e38d5985a01ec8264e4f2aca1", "sha256:ee4813e915d0e1a54e5c1963fde0855337f82655678540a6bc5996bca4165f76" ], "version": "==1.2.0" } },
pipenv --help | только-интересные
install Installs provided packages and adds them to Pipfile, or (if none is given), installs all packages. graph Displays currently-installed dependency graph information. uninstall Un-installs a provided package and removes it from Pipfile. clean Uninstalls all packages not specified in Pipfile.lock. lock Generates Pipfile.lock. update Runs lock, then sync. sync Installs all packages specified in Pipfile.lock.
pipenv install celery
... Installing celery… ✔ Installation Succeeded Pipfile.lock (c07081) out of date, updating to (ca72e7)… Locking [dev-packages] dependencies… Locking [packages] dependencies… ✔ Success! Updated Pipfile.lock (c07081)! Installing dependencies from Pipfile.lock (c07081)… 🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 6/6 — 00:00:01
pipenv install celery
Pipfile
Pipfile.lock
pipenv install
Pipfile
Pipfile.lock
pipenv uninstall celery
Uninstalling celery… Uninstalling celery-4.2.1: Successfully uninstalled celery-4.2.1
pipenv run pip freeze
amqp==2.4.0 billiard==3.5.0.5 kombu==4.2.2.post1 pytz==2018.9 vine==1.2.0
pipenv uninstall celery
Uninstalling celery… Uninstalling celery-4.2.1: Successfully uninstalled celery-4.2.1
pipenv clean
Uninstalling vine… Uninstalling pytz… Uninstalling kombu… Uninstalling billiard… Uninstalling amqp…
pipenv run pip freeze
pipenv graph
celery==4.2.1 - billiard [required: >=3.5.0.2,<3.6.0, installed: 3.5.0.5] - kombu [required: >=4.2.0,<5.0, installed: 4.2.2.post1] - amqp [required: >=2.1.4,<3.0, installed: 2.4.0] - vine [required: >=1.1.3, installed: 1.2.0] - pytz [required: >dev, installed: 2018.9]
pipenv install factory-boy python-slugify==2.0.0
pipenv graph | grep -iE 'unidecode|'
factory-boy==2.11.1
- Faker [required: >=0.7.0, installed: 1.0.2]
- python-dateutil [required: >=2.4, installed: 2.7.5]
- six [required: >=1.5, installed: 1.12.0]
- six [required: >=1.10, installed: 1.12.0]
- text-unidecode [required: ==1.2, installed: 1.2]
python-slugify==2.0.0
pipenv lock
— генерация Pipfile.lockpipenv update
— обновление версий запиненных пакетов в Pipfile.lockpipenv sync
— установка пакетов, указанных в Pipfile.lock
pipenv sync
—
(игнорирует Pipfile, может быть полезно для прода)~/.virtualenvs/
.
export WORKON_HOME=~/.venvs
export PIPENV_VENV_IN_PROJECT=True
.venv
внутри каталога проекта)
run
🤔
shell
Единоразовое выполнение: pipenv run %SOMETHING%
pipenv run какой-то--скрипт.py
pipenv run pip freeze
pipenv run env
Интерактивный режим: pipenv shell
pipenv shell
какой-то--скрипт.py
pip freeze
env
pipenv run one.sh | pipenv run two.py | pipenv run ./three.py
pipenv shell
one.sh | two.py | ./three.py
conda create -n venv
conda activate venv
conda install pandas
или
conda install -m -n venv2 pandas
conda env export > environment.yml
cat environment.yml
name: venv channels: - defaults dependencies: - blas=1.0=mkl - ca-certificates=2019.1.23=0 - certifi=2018.11.29=py37_0 - intel-openmp=2019.1=144 - libedit=3.1.20181209=hc058e9b_0 - libffi=3.2.1=hd88cf55_4 - libgcc-ng=8.2.0=hdf63c60_1 - libgfortran-ng=7.3.0=hdf63c60_0 - libstdcxx-ng=8.2.0=hdf63c60_1 - mkl=2019.1=144 - mkl_fft=1.0.10=py37ha843d7b_0 - mkl_random=1.0.2=py37hd81dba3_0 - ncurses=6.1=he6710b0_1 - numpy=1.15.4=py37h7e9f1db_0 - numpy-base=1.15.4=py37hde5b4d6_0 - openssl=1.1.1a=h7b6447c_0 - pandas=0.24.1=py37he6710b0_0 - pip=19.0.1=py37_0 - python=3.7.2=h0371630_0 - python-dateutil=2.7.5=py37_0 - pytz=2018.9=py37_0 - readline=7.0=h7b6447c_5 - setuptools=40.7.3=py37_0 - six=1.12.0=py37_0 - sqlite=3.26.0=h7b6447c_0 - tk=8.6.8=hbc83047_0 - wheel=0.32.3=py37_0 - xz=5.2.4=h14c3975_4 - zlib=1.2.11=h7b6447c_3 - pip: - amqp==2.4.1 - billiard==3.5.0.5 - celery==4.2.1 - kombu==4.3.0 - vine==1.2.0 prefix: /opt/conda/envs/venv
conda install -m -n venv2 celery
Solving environment: failed
- celery
...
conda install -m -n venv pip
conda activate venv
pip install celery
↖ но зачем нам celery?
conda env export | tail -n 9
- xz=5.2.4=h14c3975_4 - zlib=1.2.11=h7b6447c_3 - pip: - amqp==2.4.1 - billiard==3.5.0.5 - celery==4.2.1 - kombu==4.3.0 - vine==1.2.0 prefix: /opt/conda/envs/venv
conda env export > v1.yml
conda env create -f v1.yml
CondaValueError: prefix already exists: /opt/conda/envs/venvconda env export > v1.yml
head -1 v1.yml && tail -n 1 v1.yml
name: venvconda env create -f v1.yml -n venv2
💪 Попробуйте сегодня Pipenv
🔭 Anaconda + Conda + Pip — путь датасаентистов