简体   繁体   中英

How to distribute and or package a python file with all dependencies pre-downloaded without building an executable

I have written a python script which depends on paramiko to work. The system that will run my script has the following limitations:

  1. No internet connectivity (so it can't download dependencies on the fly).
  2. Volumes are mounted with 'noexec' (so I cannot run my code as a binary file generated with something like 'pyInstaller')
  3. End-user cannot be expected to install any dependencies.
  4. Vanilla python is installed (without paramiko)
  5. Python version is 2.7.5
  6. Pip is not installed either and cannot be installed on the box

I however, have access to pip on my development box (if that helps in any way).

So, what is the way to deploy my script so that I am able to provide it to the end-user with the required dependencies, ie paramiko (and sub-dependencies of paramiko), so that the user is able to run the script out-of-the-box?

I have already tried the pyinstaller 'one folder' approach but then faced the 'noexec' issue. I have also tried to directly copy paramiko (and sub-dependencies of paramiko) to a place from where my script is able to find it with no success.

pip is usually installed with python installation. You could use it to install the dependencies on the machine as follows:

    import os, sys

    def selfInstallParamiko():
        # assuming paramiko tar-ball/wheel is under the current working directory
        currentDir = os.path.abspath(os.path.dirname(__file__))

        # paramikoFileName: name of the already downloaded paramiko tar-ball, 
        # which you'll have to ship with your scripts
        paramikoPath = os.path.join(currentDir, paramikoFileName) 

        print("\nInstalling {} ...".format(paramikoPath))

        # To check for which pip to use (pip for python2, pip3 for python3)
        pipName = "pip"
        if sys.version_info[0] >= 3:
            pipName = "pip3"

        p = subprocess.Popen("{} install --user {}".format(pipName, paramikoPath).split())
        out, err= p.communicate("")

        if err or p.returncode != 0:
            print("Unable to self-install {}\n".format(paramikoFileName))
            sys.exit(1)

        # Needed, because sometimes windows command shell does not pick up changes so good
        print("\n\nPython paramiko module installed successfully.\n"
              "Please start the script again from a new command shell\n\n")
        sys.exit()

You can invoke it when your script starts and an ImportError occurs:

      # Try to self install on import failure:
      try:
          import paramiko
      except ImportError:
          selfInstallParamiko()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM