Last active
May 8, 2024 06:23
-
-
Save wmachert/133b26abdf39f219042c6024b0dde5d6 to your computer and use it in GitHub Desktop.
Portable Windows Python Setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
:: Portable Windows Python Setup | |
:: Downloads and installs a portable Python runtime as well as all requirements. | |
:: | |
:: Usage: setup.bat [INSTALL-LOCATION] [PYTHON-VERSION] | |
:: INSTALL-LOCATION - python installation folder, default: .\rt | |
:: PYTHON-VERSION - major Python version, supported: 35 - 312, default: 312 | |
:: | |
:: To install python 3.12, pip, and all dependencies from the current directory into the directory .\python: | |
:: > setup.bat python 312 | |
setlocal enabledelayedexpansion | |
:: arg 1: install location | |
if [%1] == [] ( | |
:: default install location is .\rt | |
set PYTHON_HOME=%~dp0rt | |
) else ( | |
set PYTHON_HOME=%~f1 | |
) | |
:: arg 2: python version and download urls | |
if [%2] == [35] ( | |
set PYTHON_VERSION=35 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.5.4/python-3.5.4-embed-amd64.zip | |
) else ( | |
if [%2] == [36] ( | |
set PYTHON_VERSION=36 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.6.8/python-3.6.8-embed-amd64.zip | |
) else ( | |
if [%2] == [37] ( | |
set PYTHON_VERSION=37 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.7.9/python-3.7.9-embed-amd64.zip | |
) else ( | |
if [%2] == [38] ( | |
set PYTHON_VERSION=38 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.8.10/python-3.8.10-embed-amd64.zip | |
) else ( | |
if [%2] == [39] ( | |
set PYTHON_VERSION=39 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.9.13/python-3.9.13-embed-amd64.zip | |
) else ( | |
if [%2] == [310] ( | |
set PYTHON_VERSION=310 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip | |
) else ( | |
if [%2] == [311] ( | |
set PYTHON_VERSION=311 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.11.9/python-3.11.9-embed-amd64.zip | |
) else ( | |
:: default python version | |
set PYTHON_VERSION=312 | |
set PYTHON_URL=https://www.python.org/ftp/python/3.12.3/python-3.12.3-embed-amd64.zip | |
))))))) | |
:: install python runtime | |
call :install_python %PYTHON_VERSION% %PYTHON_URL% | |
call :unpack_lib2to3 %PYTHON_VERSION% | |
:: install pip and requirements | |
call :install_pip %PYTHON_VERSION% | |
call :install_requirements | |
goto :eof | |
:: ensure installed python - arguments: <python-major-version> <embedded-python-url> | |
:install_python | |
if not exist "%PYTHON_HOME%\python.exe" ( | |
echo Downloading Python %1... | |
if not exist "%PYTHON_HOME%" mkdir "%PYTHON_HOME%" | |
if not exist "%PYTHON_HOME%\python-download.zip" curl -sL %2 -o "%PYTHON_HOME%\python-download.zip" | |
:: unzip python archive | |
powershell -Command "Expand-Archive '%PYTHON_HOME%\python-download.zip' -DestinationPath '%PYTHON_HOME%'" | |
del "%PYTHON_HOME%\python-download.zip" | |
:: add parent directory to default path | |
echo .\..>> "%PYTHON_HOME%\python%1._pth" | |
) | |
exit /b | |
:: ensure accessible lib2to3 grammar files - arguments: <python-major-version> | |
:unpack_lib2to3 | |
if not exist "%PYTHON_HOME%\lib\lib2to3" ( | |
echo Extracting lib2to3 and repacking base library... | |
"%PYTHON_HOME%\python.exe" -c "import os; import zipfile; pythonhome=os.environ['PYTHON_HOME'].replace('\\', '/'); i=zipfile.ZipFile(pythonhome + '/python%1.zip'); o=zipfile.ZipFile(pythonhome + '/python%1.zip.tmp', 'w'); [i.extract(f.filename, pythonhome + '/lib') if f.filename.startswith('lib2to3/') else o.writestr(f, i.read(f.filename)) for f in i.infolist()]; o.close();" | |
del "%PYTHON_HOME%\python%1.zip" | |
rename "%PYTHON_HOME%\python%1.zip.tmp" "python%1.zip" | |
) | |
exit /b | |
:: ensure pip installation - arguments: <python-major-version> | |
:install_pip | |
"%PYTHON_HOME%\python.exe" -c "from importlib.util import find_spec; import sys; sys.exit(1 if find_spec('pip') is None else 0)" >nul 2>nul | |
if [%ERRORLEVEL%] == [1] ( | |
:: enable library path loading | |
echo lib>> "%PYTHON_HOME%\python%1._pth" | |
echo lib\site-packages>> "%PYTHON_HOME%\python%1._pth" | |
echo Installing pip... | |
:: handle legacy python versions | |
if [%1] == [35] (set PIP_URL=https://bootstrap.pypa.io/pip/3.5/get-pip.py) else ( | |
if [%1] == [36] (set PIP_URL=https://bootstrap.pypa.io/pip/3.6/get-pip.py) else ( | |
:: pip installer for current python versions | |
set PIP_URL=https://bootstrap.pypa.io/get-pip.py | |
) | |
) | |
:: install pip | |
"%PYTHON_HOME%\python.exe" -c "from urllib.request import urlretrieve; import os; urlretrieve('!PIP_URL!', os.environ['PYTHON_HOME'].replace('\\', '/') + '/get-pip.py')" && "%PYTHON_HOME%\python.exe" "%PYTHON_HOME%\get-pip.py" --no-warn-script-location && del "%PYTHON_HOME%\get-pip.py" | |
) | |
exit /b | |
:: install requirements | |
:install_requirements | |
:: requirements from pyproject | |
if exist "%~dp0pyproject.toml" ( | |
"%PYTHON_HOME%\python.exe" -m pip install --no-warn-script-location "%~dp0." | |
) | |
:: requirements from requirements.txt | |
if exist "%~dp0requirements.txt" ( | |
"%PYTHON_HOME%\python.exe" -m pip install --no-warn-script-location -r "%~dp0requirements.txt" | |
) | |
exit /b | |
endlocal |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
curl -sL https://gist.githubusercontent.com/wmachert/133b26abdf39f219042c6024b0dde5d6/raw/python-setup.bat -o setup.bat && setup