# Is there a way to lock the version of python packages

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784>\
**Category:** Julia at Scale\
**Created:** [March 10, 2020, 5:23am UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784 "2020-03-10T05:23:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shih\_Shen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shih_shen/32/13319_2.png) [@Shih\_Shen](https://discourse.julialang.org/u/Shih_Shen)\
**Post date:** [March 10, 2020, 5:23am UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784/1 "2020-03-10T05:23:42Z")

</div>

Julia has provided a way to lock the version of Julia packages which is great. However, I found I still need python packages to finish my works sometimes. And in order to use Julia in production, locking the version of dependencies is essential. And so far, I haven’t found any way to lock the version of python packages. Does anyone have some ideas about this?

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [March 10, 2020, 5:40am UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784/2 "2020-03-10T05:40:48Z")

</div>

If you are OK with re-compiling PyCall everytime you switch the project/environment, you can simply point `ENV["PYTHON"]` to a python binary in virtualenv/venv: [GitHub - JuliaPy/PyCall.jl: Package to call Python functions from the Julia language](https://github.com/JuliaPy/PyCall.jl#specifying-the-python-version)

If you want to quickly switch virtualenv/venv, the closest approximation is to use `PYCALL_JL_RUNTIME_PYTHON`: [GitHub - JuliaPy/PyCall.jl: Package to call Python functions from the Julia language](https://github.com/JuliaPy/PyCall.jl#python-virtual-environments). But it has the restriction that you need to use the same `libpython` with which PyCall is built.

---

<div class="post-metadata">

**Author:** ![Shih\_Shen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shih_shen/32/13319_2.png) [@Shih\_Shen](https://discourse.julialang.org/u/Shih_Shen)\
**Post date:** [March 12, 2020, 6:41am UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784/3 "2020-03-12T06:41:51Z")

</div>

The ENV[“PYTHON”] does help to lock the python version, and virtualenv can be switch by defining PYCALL\_JL\_RUNTIME\_PYTHON. However, none of them help to lock the version of python packages. For example, ODBC.jl is too buggy so I have to use pyodbc, but I can’t specific the version of pyodbc anywhere in my julia module.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [March 12, 2020, 2:15pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784/4 "2020-03-12T14:15:19Z")

</div>

> [@Shih\_Shen](#):
>
> The ENV[“PYTHON”] does help to lock the python version, and virtualenv can be switch by defining PYCALL\_JL\_RUNTIME\_PYTHON.

What do you mean? Combining `poetry` or `pipenv` with `PYCALL_JL_RUNTIME_PYTHON` seems to do exactly what you are talking about. For a concrete example, see:

> <https://github.com/JuliaPy/PyCall.jl/pull/578>
>
> This PR grew out of a small feature addition to a patch that includes a few more…. Here is a new summary:
> 
> \* Main feature addition: Control Python environment at run-time by the environment variables \`PYCALL\_JL\_RUNTIME\_PYTHON\` (and \`PYCALL\_JL\_RUNTIME\_PYTHONHOME\`).
> \* fix #410: Support building Pycall against a Python executable generated by \`python -m venv\`.
> \* Refactoring: I merged how \`Py\_SetPythonHome\` and \`Py\_SetProgramName\` are \`ccall\`ed with and without \`PYCALL\_JL\_RUNTIME\_PYTHON\`. \`wpyprogramname\` and \`wPYTHONHOME\` are removed.
> 
> \---
> 
> Original summary:
> 
> I suggest to let users control Python environment at runtime by (say) \`ENV\["PYCALL\_JL\_RUNTIME\_PYTHON"\]\` (and \`ENV\["PYCALL\_JL\_RUNTIME\_PYTHONHOME"\]\`). This can be used to make sure that Julia and Python environments for a project are fully reproducible. Combining \`Pkg3.jl\` and \`pipenv\`, a typical usage would be very simple:
> 
> \`\`\`console
> $ ls
> activate.jl Manifest.toml Pipfile Pipfile.lock Project.toml
> $ cat activate.jl
> import Pkg
> Pkg.activate(@\_\_DIR\_\_)
> ENV\["PYCALL\_JL\_RUNTIME\_PYTHON"\] = strip(read(setenv(\`pipenv --py\`, dir=@\_\_DIR\_\_), String))
> $ julia -i activate.jl
> julia\> using PyCall
> julia\> pyimport("numpy") # loads numpy specified by Pipfile
> \`\`\`

---

<div class="post-metadata">

**Author:** ![Shih\_Shen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shih_shen/32/13319_2.png) [@Shih\_Shen](https://discourse.julialang.org/u/Shih_Shen)\
**Post date:** [March 17, 2020, 5:22am UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784/5 "2020-03-17T05:22:17Z")

</div>

Thank you so much for the example. I see how it works now. I was hoping I can specify the versions of python packages in Project.toml or another toml file and PyCall can set up the conda or pip virtual environment for me whether I have conda or pip installed.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [March 1, 2021, 6:42am UTC](https://discourse.julialang.org/t/is-there-a-way-to-lock-the-version-of-python-packages/35784/6 "2021-03-01T06:42:30Z")

</div>

[Poetry](http://python-poetry.org/) locks Python packages.
