You may want to take a look at the ShiningPanda Plugin.
It allows running a build step inside a particular python virtual environment, created automatically if it doesn't exist or reused if it already exists. The virtual environment is located outside the workspace, but it can be named and made to appear as a directory with that name inside the workspace.
To address the dependencies you just have to insert a build step performing the desired
pip install -r requirements.txt variant after pulling the workspace (which will probably bring in your
requirements.txt file) but before any other build step that would need to use the virtual environment.
The same virtual environment can be used in multiple steps of the same build (by name) and a build can have multiple virtual environments if needed. But AFAIK you can't reuse the same virtual environment in different builds, each build will have its own copy.
The Plugin has a configuration to clear/wipe the environment at any build step using it, if/when needed. Obviously you wouldn't want this always enabled as it would void reusability.
IMHO it works best with
requirements.txt files with pinned package versions (like those produced by pip-tools).
Update: I recently ran into an issue with the plugin on Windows: I had several jobs in different Jenkins folders but with the same job names and same plugin configs (notably the non-empty
Name in the
Advanced section). Turns out all jobs were actually sharing a single environment (and stepping over each-other), I had to switch to unique values for
Name across the jobs. Apparently the 2 names are used to generate the 2 hashes from the virtual environment path, so same names -> same path:
So, if you have the same job names, you actually can share the same environment if you really want to :)