-
-
Notifications
You must be signed in to change notification settings - Fork 258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to extend PATH with additional console scripts #1097
Comments
This makes sense. To be clear though, on the surface its not as trivial as it may sound. Since a PEX is a zipfile, you can't add items within it to the Digging deeper, more problems surface. Pretend this is all implemented and consider a typical gunicorn script that will now be on the $ cat /home/jsirois/.pex/installed_wheels/5b9580f6c90af9b2d97488e3d17143cca0b6de2a/gunicorn-20.0.4-py2.py3-none-any.whl/bin/gunicorn
#!/usr/bin/python3.8
# -*- coding: utf-8 -*-
import re
import sys
from gunicorn.app.wsgiapp import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(run()) That shebang will be a problem for a multiplatform PEX. Say the PEX was built with |
Thanks for pointing out these difficulties. My first idea was to just add the existing scripts to PATH, but as you showed, this will not work for multiplatform PEX. Another approach would be to expose the scripts in a central Regarding the extraction: Are the contents of a PEX file always exposed under |
You may have missed the significance of the shebang in scripts. Those shebangs are pinned to one interpreter - python3.8 in the gunicorn example above. That's fine if you've built a single-interpreter PEX but many folks use PEX to produce multi-interpreter / multi-platform PEXes. In that case the script will only work for one of the targeted interpreters. If the PEX is shipped to a machine without that interpreter but with another compatible interpreter the PEX will work up until user code tries to run that script at which point it will fail.
No, only PEX files created with |
So basically, if I understand this correctly, the |
You indeed don't understand correctly. When you build a PEX file using -c, that script is validated to exist and then the script name is stored in the PEX file (in PEX-INFO). When the PEX file is executed, it first reads PEX-INFO and learns it should hand control to a script. It then finds that script and executes it by reading the script contents and then executing that via effectively python N.B.: Since the script code is directly executed in the runtime interpreter, the shebang is discarded since it's just a comment at the top of the python script file. The key difference here is Pex executes the script from -c in-process whereas it sounds like you want to execute additional scripts via user or 3rdparty code via subprocess (i.e.: via the os which requires the shebang). |
Thanks for the clarification. I just dug into the code and found the two functions you quoted. So PEX makes sure all scripts work as expected. My proposal from above is to execute the designated additional scripts either by wrapping them in a shell script that actually calls the PEX or directly using PEX mechanics (maybe similar to the As far as I know, executables on the PATH must be files. Thus, there is no way around representing the scripts as such. Now, I think rendering a shell script for each additional script that just calls PEX is a simple and good solution. The question is, where to put these scripts. For additional scripts that are specified at build time, we could have a bin directory under
Then we extend the PATH with this directory. But what happens if you specify additional scripts at runtime, like So, to make this fly, I need to provide for:
And of course we could extend this feature to additional Does this sound reasonable to you? |
@jsirois From my point of view the new pex-tools venv feature covers the requirements outlined in this issue. Sorry, I couldn't give more feedback on that PR. I see you kept this issue on the release docket - do you think this feature is still relevant now? Or shall we close this issue? |
I don't consider the |
The new --venv execution mode builds a PEX file that includes pex.tools and extracts itself into a venv under PEX_ROOT upon 1st execution or any execution that might select a diffrent interpreter than the default. In order to speed up the local build and execute case, --seed mode is added to seed the PEX_ROOT caches that will be used at runtime. This is important for --venv mode since venv seeding depends on the selected interpreter and one is already selected during the PEX file build process. Fixes #962 Fixes #1097 Fixes #1115
Background
I deploy apache airflow as a PEX file with
-c airflow
. Now, when I runairflow.pex webserver
I getFileNotFoundError: [Errno 2] No such file or directory: 'gunicorn': 'gunicorn'
. That's because theairflow webserver
command callsgunicorn
to start the webserver. Asgunicorn
is part of the PEX, I can call it withPEX_SCRIPT=gunicorn airflow.pex
, but it is not in the PATH.Workaround
My current solution is to have a script called
gunicorn
:Adding this script to PATH before running
airflow webserver
works.Proposal
It would come in handy to have an option for PEX to add additional console scripts contained in the PEX to the PATH. Creating the PEX file could look like this:
And of course a related runtime environment variable would make sense too.
What's your opinion on this? I'd be happy to contribute this feature!
The text was updated successfully, but these errors were encountered: