Installing your Python package on a Windows machine that does not have internet access
Suppose you’ve developed a Python package called MyPackage
on Linux, with specific package requirements, and need to install it on a Windows machine that lacks internet access, on which you may not have any specific priviledges. This blog post will show you one way to do that, which involves downloading Wheel files on a similar Windows machine with internet access, then transferring them to the isolated machine and install them in a virtual environment.
On a machine that has internet access
Begin by preparing your working environment.
- Create a Main Directory
On your internet-connected Windows machine, open PowerShell and create a main directory for your installation:
PS C:\Users\Francois> mkdir MyPackageFolder
PS C:\Users\Francois> cd MyPackageFolder
- Download Python
Download the Python embedded package from the official Python Python web site. Specifically, choose the “Windows embeddable package (64-bit)” from this link. The file size is about 10.7 MB for Python 3.11. Once downloaded, copy the zip archive (python-3.11.6-embed-amd64.zip
) into your directory, extract and delete it:
PS C:\Users\Francois\MyPackageFolder> ls
Directory: C:\Users\Francois\MyPackageFolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/1/2023 8:03 PM python-3.11.6-embed-amd64
- Add Your Python Package
Copy your Python package folder (named MyPackage
) into this directory, excluding any hidden or useless folders like .git
, .github
, __pycache__
, .ruff_cache
…
- Get pip
To install packages, you’ll need pip. Download get-pip.py
from https://bootstrap.pypa.io/ and place it in your Python folder python-3.11.6-embed-amd64\
. Then, install pip with the following command:
PS C:\Users\Francois\MyPackageFolder> cd .\python-3.11.6-embed-amd64\
PS C:\Users\Francois\MyPackageFolder\python-3.11.6-embed-amd64> .\python.exe .\get-pip.py
You can confirm the installation by checking the Scripts
folder within your Python directory:
PS C:\Users\Francois\MyPackageFolder\python-3.11.6-embed-amd64> ls .\Scripts\
Directory: C:\Users\Francois\MyPackageFolder\python-3.11.6-embed-amd64\Scripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/1/2023 8:13 PM 108424 pip.exe
-a---- 11/1/2023 8:13 PM 108424 pip3.11.exe
-a---- 11/1/2023 8:13 PM 108424 pip3.exe
-a---- 11/1/2023 8:13 PM 108411 wheel.exe
- Update the
python37._pth
File
Open the python37._pth
file and uncomment the following line by removing the ‘#’ symbol:
#import site
- Create a Wheelhouse Directory
Wheel is a built distribution format: a wheel file is a zipped archive with the .whl
extension, usually containing a pre-built binary package.
In the root folder, create a directory named wheelhouse
to store all the wheel files:
PS C:\Users\Francois\MyPackageFolder\python-3.11.6-embed-amd64> cd ..
PS C:\Users\Francois\MyPackageFolder> mkdir wheelhouse
Directory: C:\Users\Francois\MyPackageFolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/1/2023 8:24 PM wheelhouse
- Download Required Packages
Use your internet-connected Windows machine to download all the required packages and save them into the wheelhouse
folder. You can do this by running the following commands:
PS C:\Users\Francois\MyPackageFolder> .\python-3.11.6-embed-amd64\python.exe -m pip download -r .\MyPackage\requirements.txt -d .\wheelhouse
Repeat the process for any other requirements, such as for virtual environments, with a similar command:
PS C:\Users\Francois\MyPackageFolder> .\python-3.11.6-embed-amd64\python.exe -m pip download -r .\MyPackage\requirements_venv.txt -d .\wheelhouse
These virtual environment requirements are the following ones in our case:
virtualenv
distlib<1,>=0.3.7
filelock<4,>=3.12.2
platformdirs<4,>=3.9.1
Verify that the downloaded wheels are in the “wheelhouse” directory:
PS C:\Users\Francois\MyPackageFolder> ls .\wheelhouse\
Directory: C:\Users\Francois\MyPackageFolder\wheelhouse
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/1/2023 8:27 PM 181495 cffi-1.16.0-cp311-cp311-win_amd64.whl
-a---- 11/1/2023 8:27 PM 25335 colorama-0.4.6-py2.py3-none-any.whl
-a---- 11/1/2023 8:27 PM 13277 contextlib2-21.6.0-py2.py3-none-any.whl
-a---- 11/1/2023 8:27 PM 2669522 cryptography-41.0.5-cp37-abi3-win_amd64.whl
-a---- 11/1/2023 8:28 PM 468869 distlib-0.3.7-py2.py3-none-any.whl
-a---- 11/1/2023 8:28 PM 11740 filelock-3.13.1-py3-none-any.whl
-a---- 11/1/2023 8:27 PM 288398 greenlet-3.0.1-cp311-cp311-win_amd64.whl
-a---- 11/1/2023 8:27 PM 62549 loguru-0.7.2-py3-none-any.whl
-a---- 11/1/2023 8:27 PM 15799803 numpy-1.26.1-cp311-cp311-win_amd64.whl
-a---- 11/1/2023 8:27 PM 10647686 pandas-2.1.2-cp311-cp311-win_amd64.whl
-a---- 11/1/2023 8:28 PM 17579 platformdirs-3.11.0-py3-none-any.whl
-a---- 11/1/2023 8:27 PM 1163579 psycopg2-2.9.9-cp311-cp311-win_amd64.whl
-a---- 11/1/2023 8:27 PM 118697 pycparser-2.21-py2.py3-none-any.whl
-a---- 11/1/2023 8:27 PM 1978695 pymssql-2.2.10-cp311-cp311-win_amd64.whl
-a---- 11/1/2023 8:27 PM 247702 python_dateutil-2.8.2-py2.py3-none-any.whl
-a---- 11/1/2023 8:27 PM 502454 pytz-2023.3.post1-py2.py3-none-any.whl
-a---- 11/1/2023 8:27 PM 5924 scramp-1.1.0-py3-none-any.whl
-a---- 11/1/2023 8:27 PM 11053 six-1.16.0-py2.py3-none-any.whl
-a---- 11/1/2023 8:27 PM 31584 typing_extensions-4.8.0-py3-none-any.whl
-a---- 11/1/2023 8:27 PM 341835 tzdata-2023.3-py2.py3-none-any.whl
-a---- 11/1/2023 8:28 PM 3768405 virtualenv-20.24.6-py3-none-any.whl
-a---- 11/1/2023 8:27 PM 3604 win32_setctime-1.1.0-py3-none-any.whl
Note that you could also include your own package in this wheelhouse
folder, or a package you edited. In the case of a pure python package, here is the process:
PS C:\Users\Francois\MyPackageFolder> cd ..\MyOwnRequiredPackage\
PS C:\Users\Francois\MyOwnRequiredPackage> python setup.py bdist_wheel
PS C:\Users\Francois\MyOwnRequiredPackage> cp .\dist\myownrequiredpackage-1.0-py3-none-any.whl ..\wheelhouse\
- Zip and Transfer
Now, zip the entire MyPackageFolder
folder and move it to the machine without internet access.
With this zipped package in hand, you can install your Python package and its dependencies on the isolated Windows machine.
On a machine that does not have internet access
- Extract the zipped folder wherever you want and navigate into this directory using PowerShell. In the following, the same path as above is used:
PS C:\Users\Francois\MyPackageFolder> ls
Directory: C:\Users\Francois\MyPackageFolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/1/2023 8:43 PM MyPackage
d----- 11/1/2023 8:43 PM python-3.11.6-embed-amd64
d----- 11/1/2023 8:43 PM wheelhouse
- install virtualenv:
PS C:\Users\Francois\MyPackageFolder> .\python-3.11.6-embed-amd64\python.exe -m pip install virtualenv --no-index --find-links .\wheelhouse
- create a virtualenv, e.g.
testenv
:
PS C:\Users\Francois\MyPackageFolder> .\python-3.11.6-embed-amd64\python.exe -m virtualenv testenv
You can verify that a new subfolder, testenv
, has been created:
PS C:\Users\Francois\MyPackageFolder> ls
Directory: C:\Users\Francois\MyPackageFolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/1/2023 8:43 PM MyPackage
d----- 11/1/2023 8:43 PM python-3.11.6-embed-amd64
d----- 11/1/2023 8:49 PM testenv
d----- 11/1/2023 8:43 PM wheelhouse
- activate the virtualenv:
PS C:\Users\Francois\MyPackageFolder> .\testenv\Scripts\activate.ps1
- install all the package requirements
(testenv) PS C:\Users\Francois\MyPackageFolder> python -m pip install -r .\MyPackage\requirements.txt --no-index --find-links .\wheelhouse
- now we can install our package:
(testenv) PS C:\Users\Francois\MyPackageFolder> python -m pip install -e .\MyPackage\ --no-build-isolation
Here you go! Note that the package is installed in editable mode in this case with the -e
option.
(testenv) PS C:\Users\Francois\MyPackageFolder> python
Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import MyPackage
>>> quit()
Additionally, you can verify that a command line entry point myentrypoint
(that does nothing here) is available in the shell:
(testenv) PS C:\Users\Francois\MyPackageFolder> myentrypoint
(testenv) PS C:\Users\Francois\MyPackageFolder> deactivate
PS C:\Users\Francois\MyPackageFolder>
The entry point has been defined has follows in a module names cli.py
:
def myentrypoint():
pass
and in setup.py
:
setup(
entry_points={
"console_scripts": [
"myentrypoint=mypackage.cli:myentrypoint",
],
},
)
Now, your Python package is successfully installed and ready to use.
In summary, this post shows how to install your Python package in a virtual environment on a Windows machine without internet access, using the embedded Python version, which does not require any special privileges.