简体   繁体   中英

Using the rubypython gem in ruby on rails, how do you call a python script from the lib folder?

I know ruby pretty well, but I've never used python before.

There's this great python script called colorific . I've checked this script out in the lib folder in my rails app and installed the rubypython gem.

I was wondering how I now import this sciprt into the app, so far I've got this:

RubyPython.start # start the Python interpreter
test = RubyPython.import("#{Rails.root}/lib/colorific/setup.py")
RubyPython.stop # stop the Python interpreter

However it's throwing the error…

RubyPython::PythonError: ImportError: Import by filename is not supported.

I was wondering how do I import this script and start using it's methods?

colorific is a command-line utility. It doesn't appear to provide an API to import. I'd not use a Ruby-to-Python bridge here, just run the tool using the Ruby equivalent of the Python subprocess module; as a separate process. (Martijin Pieters)

The colorific test suite itself imports colorific, and there is a file called setup.py, so colorific looks like a standard python module distribution.

test = RubyPython.import("#{Rails.root}/lib/colorific/setup.py")

The setup.py file in a python module distribution is for installing the module at a specific location in the filesystem. Typically, you install a python module like this:

$ python setup.py install

Then you import the file into a python program like this:

import colorific

Or if you have a module name as a string, you can do the import like this:

import importlib
importlib.import_module('colorific')

However, python looks in specific directories for the modules you import. The list of directories that python searches for the modules you import is given by sys.path:

import sys
print sys.path

sys.path is a python list, and it can be modified.

I suggest you first build the colorific module in some directory: create an empty colorific directory somewhere, eg /Users/YourUserName/colorific, then cd into the directory that contains setup.py and do this:

$ python setup.py install --home=/Users/YourUserName/colorific

After the install, move the colorific directory into your rails app somewhere, eg /your_app/lib.

Then in RubyPython do this:

RubyPython.start # start the Python interpreter

sys = RubyPython.import("sys")
sys.path.append("#{Rails.root}/lib")

colorific = RubyPython.import('colorific')


RubyPython.stop

You might also want to print out sys.path to see where the rubypython gem is set up to look for modules.

====

When I tried:

$ python setup.py install --home=/Users/YourUserName/colorific

I got the error:

error: bad install directory or PYTHONPATH

So I just installed colorific like I usually install a python module:

$ python setup.py install 

which installs the module in the system dependent default directory, which on a Mac is:

/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages

See here for other systems:

http://docs.python.org/2/install/#how-installation-works

The colorific install created a directory in site-packages called:

colorific-0.2.1-py2.7.egg/

I moved that directory into my app's lib directory:

$ mv /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/colorific-0.2.1-py2.7.egg /Users/7stud/rails_projects/my_app/lib

Then I used the following code to import the module, and call a function in colorific:

RubyPython.start # start the Python interpreter

logger.debug "hello " + "world"

sys = RubyPython.import('sys')
logger.debug sys.path
sys.path.append("#{Rails.root}/lib/colorific-0.2.1-py2.7.egg/")

colorific = RubyPython.import('colorific')
logger.debug colorific.hex_to_rgb("#ffffff")

RubyPython.stop

I put that code in an action. Here was the output in log/development.log:

hello world
[<Lots of paths here>, '/Users/7stud/rails_projects/test_postgres/lib/colorific-0.2.1-py2.7.egg/']
(255, 255, 255)

I found that RubyPython constantly crashed the $ rails server (WEBrick):

/Users/7stud/.rvm/gems/ruby-2.0.0-p247@railstutorial_rails_4_0/gems/rubypython-0.6.3/lib/rubypython.rb:106: [BUG] Segmentation fault
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin10.8.0]

-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:
     * ~/Library/Logs/CrashReporter
     * /Library/Logs/CrashReporter
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   the more detail of.


<1000+ lines of traceback omitted>

And even though I could write this:

logger.debug "hello " + "world"

This would not work:

logger.debug "******" + colorific.hex_to_rgb("#ffffff")

nor this:

logger.debug "*********" + colorific.hex_to_rgb("#ffffff").rubify

As is typical for anything ruby, the docs for RubyPython are horrible. However, in this case they found an equal match in the python colorific docs.

Your original code needed a few extra lines:

RubyPython.start # start the Python interpreter
sys = RubyPython.import("sys") # (add) method used to search for a directory
sys.path.append('./lib/colorific') # (add) execute search in directory
RubyPython.import("setup") # (add) call on setup.py in the directory
RubyPython.stop # stop the Python interpreter

I have a Ruby environment already setup as a template here that does what you are trying to do.

I know Python pretty well, but I've hardly ever used Ruby...

There are several things wrong here:

  • Python imports are done for module names ; you are trying to import a filename instead.

    Normally, you'd add the directory to the #{Rails.root}/lib directory to the Python module search path (either with the PYTHONPATH environment variable or by manipulating the sys.modules list from Python code), but you are trying to import the setup script here.

    You'd run python setup.py install to install the library. Or, much better, use pip or easy_install to install the package for you.

  • colorific is a command-line utility. It doesn't appear to provide an API to import. I'd not use a Ruby-to-Python bridge here, just run the tool using the Ruby equivalent of the Python subprocess module; as a separate process.

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