Related resources:
- How should I manage my group license for multiple users? (FAQ)
- Distributing Python Code (PyXLL User Guide)
There are various ways to distribute a PyXLL add-in, typically:
1. Sharing Python code on a network drive
3. Using a standalone zip file
See also Updating your deployed PyXLL add-in for details of how to keep your add-in up to date once it's been deployed.
1. Sharing Python code on a network drive
This is the simplest option as it allows your Python code to be deployed centrally, ensuring that all users see the same code at all times.
As long as a user can read from the network drive, PyXLL can be configured to read Python modules from there. This ensures that you don’t need to copy code around and that all users are always referencing the same version of your code.
The PyXLL configuration can be shared by using the external_config option in the pyxll.cfg file. You can list multiple external configs which will get merged together when PyXLL loads.
The PyXLL config file itself can also be on a network drive. The environment variable PYXLL_CONFIG_FILE can be set to tell PyXLL to load a config file from somewhere other than the default location. You can use environment variables inside the config file so that logging gets written to the user’s local storage.
When deploying code on a network drive you will want to make the folder read-only to your users to ensure no accidental updates occur.
To update the Python code, rather than updating in-place it is good practice to create a new folder with the updated code and then change the pythonpath in the shared config file to that new folder. This way if there are any problems then you can quickly revert to the previous folder, and it also avoids problems with certain files (e.g. dll and pyd files) becoming locked while users have then open.
A typical structure for this shared folder would be (with the folder names changed to suit your requirements):
- Modules{version} / Folder containing your Python code
- Python{version} / [Optional] Folder containing your Python environment
- shared_pyxll.cfg [this would specify pythonpath="./Modules{version}", your modules list, any other shared settings, and optionally "executable=./Python{version}/pythonw.exe"]
In your main pyxll.cfg file you would include the shared_pyxll.cfg file using "external_config=X:\network\folders\pyxll\shared_pyxll.cfg".
You would choose whether or not to include the Python environment on the shared folder or not depending on whether or not each user would already have a suitable local Python environment and how fast your network drive is. Loading Python from a slow network drive can slow down starting Excel, in which case one of the options below may be more suitable.
To install the PyXLL add-in you can either load the pyxll.xll add-in manually into Excel, or your could script it using the "pyxll activate" command.
(Note: You can use "X:\path\to\python.exe -m pyxll activate" instead of "pyxll activate")
2. Building an installer
This is useful when you need to deploy to PCs that might not have fast or reliable access to your network, and so accessing a shared drive or a deployment server is not feasible. The Python runtime can be bundled with PyXLL into a single standalone installer.
Depending on your use case, this may be a good solution for deploying a PyXLL based add-in to multiple users.
For detailed instructions and an example project for building an MSI installer, see https://github.com/pyxll/pyxll-installer.
Once installed, updates can be made using a startup script. See the section below for more information about that.
3. Using a standalone zip file
Similarly to putting everything on a network drive, as above, you can combine everything into a single zip archive for distribution to your users. You can include everything, including a Python environment and pre-configure PyXLL to reference it using a relative path.
To install the PyXLL add-in you would unzip the archive on the PC where you want it to be installed and then load the PyXLL add-in in Excel. This can be scripted, and you can script the step of adding PyXLL to Excel using the "pyxll activate" command (see PyXLL Command Line Tool).
Once installed, updates can be made using a startup script. See the section below for more information about that.
A typical structure for this zip file would be (chaging the folder names to suit your requirements):
- Python / Folder containing your Python environment
- Modules / Folder containing your Python code
- pyxll.xll
- pyxll.cfg [this would specify "executable=./Python/pythonw.exe" and "pythonpath=./Modules"]
For example, your install script would do the following:
a. Copy and unzip your_pyxll_archive.zip to C:\Your\Local\PyXLL\Install
b. Run "C:\Your\Local\PyXLL\Install\Python\python.exe -m pyxll activate --non-interactive C:\Your\Local\PyXLL\Install"
(Note: "python.exe -m pyxll" is equivalent to running "pyxll", but doesn't need the Python environment to be active or on the system PATH)
Updating your deployed PyXLL add-in
New in PyXLL 4.4: Use a startup script to configure PyXLL and download or update Python code from a central location (e.g. a shared folder) or web server.
Once you have decided how to distribute your Python code to the client PCs (either using one of the methods above or another method of your own) you can configure PyXLL to download updates automatically when starting.
PyXLL can be configured to run a startup script using the "startup_script" configuration setting in the pyxll.cfg file. This script can be a .bat or .ps1 file and will be run each time the PyXLL add-in is opened. It runs before Python is loaded, and so you can use this script to download and apply updates to the Python environment and to your Python modules.
The startup script can set options in the PyXLL configuration, in addition to what is set in the pyxll.cfg file. This can be used to dynamically configure PyXLL without needing to make changes to the pyxll.cfg file.
When you configure the startup script you can use a network location so that to deploy updates, all you need to do is to update the script at that location.
An example auto-updating script would look as follows:
SET VERSION=v1
SET PYTHON_FOLDER=.\python-code-%VERSION%
REM No need to download anything if we already have the latest
IF EXIST %PYTHON_FOLDER% THEN GOTO END
REM Download and unzip the latest code
wget https://intranet/pyxll/python-code-%VERSION%.tar.gz
tar -xzf python-code-%VERSION%.tar.gz --directory %PYTHON_FOLDER%
ECHO Latest code has been downloaded to .\python-code-%VERSION%
:END
REM Add our PYTHON_FOLDER to the "pythonpath"
ECHO pyxll-set-option PYTHON pythonpath %PYTHON_FOLDER%
And in the deployed pyxll.cfg file you would configure the startup script as follows:
[PYXLL]
; This can be either a path or a url
startup_script = https://intranet/pyxll/startup-script.cmd