Reputation: 1639
My system administrator will not allow global installation of python packages.
I'm writing a script that people will invoke to perform certain actions for them. The script I'm writing needs certain libraries like sqlalchemy
and coloredlogs
. I am however allowed to install python libs any local folder. i.e not site-packages.
How would I go about installing the libs in the same folder as the script so that the script has access to them?
My folder hierarchy is like so
script_to_invoke.py
scriptpack/
bin/
coloredlogs
coloredlogs.egg
...
utils/
util1.py
util2.py
(all the folders indicated have an __init__.py
)
What I've tried so far:
within script_to_invoke.py
I use
from scriptpack.utils invoke util1 # no problem here
from scriptpack.bin import coloredlogs # fails to find the import
I've looked at some other SO answers abut I'm not sure how to correlate them with my problem.
Upvotes: 1
Views: 3480
Reputation: 155363
If you might want to try packaging up everything as a zipapp
. Doing so makes a single zip file that acts as a Python script, but can contain a whole multitude of embedded packages. The steps to make it are:
testapp
in my example)__main__.py
and put it in that folderpip
, install the required packages to the folder with --target=/path/to/testapp
python3 -mzipapp testapp -p='/usr/bin/env python3'
(providing the shebang line is optional; without it, users will need to run the package with python3 testapp.pyz
, while with the shebag, they can just do ./testapp.pyz
)That creates a zip file with all your requirements embedded in it alongside your script, that doesn't even need to be unpacked to run (Python knows how to run zip apps natively). As a trivial example:
$ mkdir testapp
$ echo -e '#!/usr/bin/python3\nimport sqlalchemy\nprint(sqlalchemy)' > __main__.py
$ pip3 install --target=./testapp sqlalchemy
$ python3 -mzipapp testapp -p='/usr/bin/env python3'
$ ./testapp.pyz
<module 'sqlalchemy' from './testapp.pyz/sqlalchemy/__init__.py'>
showing how the simple main was able to access sqlalchemy
from within the same zipapp. It's also smaller (thanks to the zipping) that distributing the uncompressed modules:
$ du -s -h testapp*
13M testapp
8.1M testapp.pyz
Upvotes: 1
Reputation: 1639
I figured it out!
Python had to be directed to find the .egg
files
This can be done by either
PYTHONPATH
var BEFORE the interpreter is started (or)Code Below:
import sys
for entry in [<list of full path to egg files in bin dir>]:
sys.path.append(str(entry))
# Proceed with local imports
Upvotes: 2
Reputation: 660
You can install these packages in a non-global location (generally in ~/.local/lib/python<x.y>
) using the --user
flag, e.g.:
pip install --user sqlalchemy coloredlogs
That way you don't have to worry about changing how imports work, and you're still compliant with your sysadmins policies.
Upvotes: 0